URDF와 ROS의 상호작용

ROS(Robot Operating System)는 로봇 시스템을 개발하기 위한 강력한 툴셋을 제공하며, URDF는 로봇의 물리적 모델을 기술하는 XML 기반의 포맷이다. URDF 파일을 통해 로봇의 구조, 조인트, 링크, 센서 등을 정의할 수 있으며, 이 정보를 ROS와 통합하여 시뮬레이션 또는 실제 로봇 제어에 활용할 수 있다.

ROS와 URDF의 통합을 위해 중요한 요소는 ROS 패키지 구조와 ROS가 제공하는 다양한 도구들이다. 이 섹션에서는 URDF 파일을 ROS 내에서 어떻게 사용하는지, 그리고 ROS가 제공하는 시뮬레이션 및 시각화 도구와 URDF 파일을 어떻게 연동할 수 있는지 설명한다.

URDF 파일 로드

ROS에서 URDF 파일을 로드하는 가장 일반적인 방법은 robot_description 파라미터 서버에 URDF 모델을 업로드하는 것이다. 이를 위해 ROS 패키지 내에서 urdf 파일을 생성하고 이를 파라미터 서버에 업로드해야 한다.

rosparam set /robot_description -t my_robot.urdf

이 명령을 통해 ROS 노드는 /robot_description 네임스페이스에 URDF 데이터를 로드하게 된다. 이 데이터를 기반으로 시뮬레이션에서 로봇 모델이 구동되거나 시각화 도구에서 로봇 구조가 표현된다.

RViz를 이용한 URDF 시각화

URDF 파일을 시각화하기 위한 도구로 가장 많이 사용되는 것이 RViz이다. RViz는 ROS에서 제공하는 3D 시각화 도구로, 로봇의 상태, 센서 데이터, 그리고 시뮬레이션 결과를 실시간으로 확인할 수 있다. robot_state_publisher 노드는 URDF 모델에서 정의된 로봇 구조를 바탕으로 각 링크와 조인트의 상태를 퍼블리시하며, RViz는 이 정보를 사용하여 로봇을 시각적으로 표현한다.

roslaunch my_robot_display.launch

위 명령은 URDF 파일을 기반으로 RViz에서 로봇의 구조를 시각화할 수 있는 환경을 제공한다.

TF를 통한 링크 및 조인트 정보 제공

URDF와 ROS의 중요한 통합 요소 중 하나는 TF 변환 프레임워크이다. URDF에서 정의된 링크와 조인트 정보는 ROS에서 TF를 통해 각 링크 간의 위치 및 회전 정보를 실시간으로 제공하는 데 사용된다.

링크 \mathbf{l}_i\mathbf{l}_j 사이의 변환 행렬은 다음과 같이 표현된다:

\mathbf{T}_{ij} = \begin{bmatrix} \mathbf{R}_{ij} & \mathbf{d}_{ij} \\ 0 & 1 \end{bmatrix}

여기서 \mathbf{R}_{ij} 는 회전 행렬, \mathbf{d}_{ij} 는 변위 벡터이다. 이 변환 행렬은 URDF에서 정의된 링크 및 조인트 정보를 통해 계산되며, TF는 이를 퍼블리시하여 ROS에서 다른 노드들이 해당 데이터를 활용할 수 있도록 한다.

robot_state_publisher와 joint_state_publisher

robot_state_publisherjoint_state_publisher는 ROS와 URDF 통합에서 중요한 역할을 한다. 이 두 노드는 URDF 모델에서 정의된 링크와 조인트의 상태를 관리하고 퍼블리시한다.

joint_state_publisher

joint_state_publisher는 로봇의 조인트 상태를 퍼블리시하는 노드이다. 조인트 상태는 로봇의 조인트 위치, 속도, 가속도 등으로 표현되며, 이를 통해 로봇의 각 링크들이 어떻게 이동하는지를 알 수 있다. URDF 파일에서 정의된 조인트들에 대한 상태 정보를 퍼블리시하여 ROS의 다른 노드들이 이를 구독하고 로봇의 상태를 실시간으로 파악할 수 있다.

예를 들어, 로봇의 조인트 \theta_i 가 특정 시간에 q_i(t) 값으로 정의된다면, 이 값은 다음과 같이 퍼블리시된다:

q_i(t) = \text{joint position of } i \text{-th joint}

조인트 상태를 ROS의 /joint_states 토픽에 퍼블리시하면, RViz와 같은 시각화 도구 또는 시뮬레이션 노드가 이를 사용하여 로봇의 조인트 운동을 처리할 수 있다.

robot_state_publisher

robot_state_publisher는 URDF 모델에서 정의된 로봇의 링크와 조인트 정보를 사용하여 각 링크 간의 변환 상태를 계산하고, 이를 ROS의 TF 프레임워크에 퍼블리시하는 역할을 한다. 이 노드는 URDF에서 정의된 로봇의 운동학적 정보를 바탕으로 조인트 상태를 받아 각 링크 간의 상대적인 위치와 회전을 계산한다.

각 링크 간의 변환은 URDF 파일에서 정의된 조인트 회전 각도 \theta_i, 변위 \mathbf{d}_i 를 바탕으로 다음과 같이 계산된다:

\mathbf{T}_i = \begin{bmatrix} \cos(\theta_i) & -\sin(\theta_i) & 0 & d_{ix} \\ \sin(\theta_i) & \cos(\theta_i) & 0 & d_{iy} \\ 0 & 0 & 1 & d_{iz} \\ 0 & 0 & 0 & 1 \end{bmatrix}

여기서 \mathbf{T}_ii-번째 링크의 변환 행렬을 나타내며, 이 값은 ROS의 TF 트리에서 각 링크의 상대적인 위치와 회전으로 표현된다.

URDF와 ROS 제어

ROS에서 URDF와 통합된 로봇을 제어하려면 ros_control과 같은 패키지를 활용하여 로봇의 각 조인트를 제어할 수 있다. URDF 파일에서 정의된 각 조인트에 대해 제어기(controller)를 설정하고 이를 통해 로봇의 모터, 조인트 등을 제어할 수 있다. ROS 제어는 URDF의 운동학적 정보와 연계되어, 로봇의 조인트를 실시간으로 제어하고 그 상태를 다시 퍼블리시하는 방식으로 작동한다.

예를 들어, 조인트 \theta_i 에 대한 PID 제어기를 사용하여 원하는 조인트 위치 \theta_i^{\text{desired}} 에 도달하도록 제어할 수 있다. PID 제어기의 일반적인 수식은 다음과 같다:

u(t) = K_p e(t) + K_i \int e(t) \, dt + K_d \frac{de(t)}{dt}

여기서 e(t) = \theta_i^{\text{desired}} - \theta_i(t) 는 현재 조인트 위치와 목표 위치의 오차를 나타낸다. 이 제어기를 통해 로봇의 각 조인트를 원하는 위치로 이동시키는 것이 가능한다.

URDF와 ROS의 통합을 위한 launch 파일

ROS에서 URDF 모델을 제대로 활용하기 위해서는 launch 파일을 사용하여 노드와 URDF 모델을 쉽게 실행할 수 있다. launch 파일은 ROS 시스템에서 여러 노드와 파라미터들을 동시에 설정하고 실행할 수 있게 해주는 XML 기반의 파일이다. URDF 파일을 ROS 환경에 로드하고 다양한 시뮬레이션 및 제어 노드를 설정하기 위해 launch 파일을 자주 사용한다.

예를 들어, URDF 파일을 로드하고 RViz에서 로봇을 시각화하는 기본적인 launch 파일은 다음과 같다:

<launch>
  <!-- 로봇 URDF 파일을 파라미터 서버에 업로드 -->
  <param name="robot_description" command="$(find xacro)/xacro.py '$(find my_robot)/urdf/my_robot.urdf.xacro'" />

  <!-- robot_state_publisher 노드 실행 -->
  <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" output="screen">
    <param name="publish_frequency" type="double" value="30.0" />
  </node>

  <!-- RViz 실행 -->
  <node name="rviz" pkg="rviz" type="rviz" args="-d $(find my_robot)/rviz/my_robot.rviz" />
</launch>

launch 파일은 ROS 파라미터 서버에 URDF 데이터를 업로드하고, robot_state_publisher 노드를 실행하여 로봇의 상태를 퍼블리시하며, RViz를 실행하여 로봇을 시각화한다.

URDF와 ROS Control 통합

ROS에서 로봇을 제어하기 위해 사용되는 중요한 도구는 ros_control이다. ros_control은 로봇의 각 조인트에 대해 제어기를 설정하여 로봇의 동작을 제어할 수 있게 해준다. 이를 위해서는 URDF 파일에서 조인트와 관련된 제어기 설정을 추가해야 하며, ROS Control을 이용하여 각 조인트의 목표 위치, 속도, 힘 등을 설정할 수 있다.

URDF 파일에 제어기 설정을 추가하는 예시는 다음과 같다:

<transmission name="transmission1">
  <type>transmission_interface/SimpleTransmission</type>
  <joint name="joint1">
    <hardwareInterface>EffortJointInterface</hardwareInterface>
  </joint>
  <actuator name="motor1">
    <mechanicalReduction>1</mechanicalReduction>
  </actuator>
</transmission>

이 설정은 로봇의 특정 조인트에 대한 제어기 인터페이스를 정의하는 것으로, EffortJointInterface는 조인트에 힘을 제어하는 인터페이스를 나타낸다.

ros_control과 조인트 제어

ros_control 프레임워크를 사용하여 조인트의 제어를 관리할 수 있다. 이를 위해 URDF 파일에 제어기 설정을 추가한 후, controller_manager를 사용하여 제어기를 로드하고 실행한다. 예를 들어, PID 제어기를 로드하는 launch 파일 설정은 다음과 같다:

<launch>
  <!-- controller_manager 노드 실행 -->
  <node name="controller_spawner" pkg="controller_manager" type="spawner" args="joint1_position_controller" />
</launch>

이제 joint1_position_controller는 ROS에서 해당 조인트를 제어하게 되며, 제어 명령은 ROS의 /controller/command 토픽을 통해 전달된다.

URDF와 Gazebo 통합

URDF와 Gazebo 시뮬레이터를 통합하여 로봇을 시뮬레이션할 수 있다. Gazebo는 물리 엔진을 포함한 강력한 시뮬레이션 도구로, URDF 파일을 기반으로 로봇의 물리적 행동을 시뮬레이션할 수 있다. URDF 파일에서 로봇의 링크, 조인트, 그리고 물리적 특성(질량, 마찰, 관성 등)을 정의하면, Gazebo에서 이를 사용하여 실제와 유사한 로봇의 동작을 구현할 수 있다.

예를 들어, URDF 파일에서 다음과 같이 Gazebo 플러그인을 정의할 수 있다:

<gazebo>
  <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
    <robotNamespace>/my_robot</robotNamespace>
  </plugin>
</gazebo>

이 플러그인은 Gazebo 시뮬레이션 내에서 ROS의 ros_control을 사용할 수 있게 해준다. 이를 통해 로봇의 물리적 특성과 제어기를 결합하여 시뮬레이션 환경에서 제어할 수 있다.