Gazebo에서 로봇 시뮬레이션을 시작하기 위해서는 먼저 URDF나 SDF 파일을 불러와야 한다. 이 파일들은 로봇의 구조와 특성, 물리적 속성, 그리고 센서나 액추에이터 등의 모델을 정의한 XML 형식의 파일이다. 파일 불러오기를 잘 이해하는 것은 Gazebo에서 로봇을 정확하게 시뮬레이션하는 첫걸음이다.

URDF 파일 불러오기

URDF 파일을 불러오기 위해서는 ROS(Robot Operating System)를 사용하는 것이 일반적이다. URDF 파일은 ROS의 urdf 패키지를 통해 로드될 수 있다. 다음은 URDF 파일을 Gazebo에서 불러오는 방법에 대한 설명이다.

  1. URDF 파일 경로 설정

ROS 패키지에 저장된 URDF 파일 경로를 설정해야 한다. roslaunch 명령을 사용할 경우 URDF 파일을 지정할 수 있다. 예를 들어, robot_description 파라미터를 통해 URDF 파일을 로드할 수 있다.

bash roslaunch my_robot my_robot_gazebo.launch

  1. Gazebo와의 통합

URDF 파일은 ROS와 Gazebo 사이에서 통합되어야 한다. 이를 위해 gazebo_ros 패키지가 필요하다. 이 패키지를 이용해 URDF에서 정의된 로봇 모델을 Gazebo에 로드할 수 있다. 예를 들어, gazebo_ros_control을 통해 로봇 제어도 가능하다.

  1. URDF 모델의 파라미터 로드

ROS에서 URDF 파일을 파라미터로 로드하기 위해 rosparam을 사용한다. 아래와 같은 명령어로 URDF 파일을 파라미터 서버에 올릴 수 있다.

bash rosparam load my_robot.urdf

robot_description이라는 파라미터에 URDF 파일의 내용을 로드하게 된다.

SDF 파일 불러오기

SDF 파일은 URDF와 달리 Gazebo에서 기본적으로 지원되는 파일 형식이다. SDF 파일을 직접 Gazebo에서 불러오기 위한 몇 가지 절차가 있다.

  1. SDF 파일 경로 설정

Gazebo는 기본적으로 SDF 파일을 직접 로드할 수 있다. 이를 위해 Gazebo GUI에서 파일을 불러오거나, 터미널 명령어를 통해 SDF 파일을 로드할 수 있다.

bash gazebo my_robot.sdf

  1. Gazebo 플러그인을 통한 로드

SDF 파일을 Gazebo 플러그인과 연동할 수 있다. 이를 통해 SDF에서 정의된 로봇 모델을 더욱 정교하게 제어하거나 센서와 상호작용할 수 있다. SDF 파일 내에서 플러그인을 설정하고 로봇의 동작을 제어할 수 있다.

수학적 표현

URDF/SDF 파일을 통해 로봇의 시뮬레이션을 할 때 중요한 부분 중 하나는 링크(link)와 조인트(joint) 사이의 관계를 수학적으로 표현하는 것이다. 이들은 각각 변환 행렬로 표현되며, 로봇의 구조를 정의하는 중요한 요소들이다.

로봇의 각 링크 간의 변환은 일반적으로 다음과 같이 표현된다.

\mathbf{T}_{i}^{i-1} = \begin{bmatrix} \mathbf{R}_{i}^{i-1} & \mathbf{d}_{i}^{i-1} \\ \mathbf{0}^{T} & 1 \end{bmatrix}

여기서: - \mathbf{T}_{i}^{i-1}은 링크 i-1에서 링크 i로의 변환 행렬이다. - \mathbf{R}_{i}^{i-1}은 링크 i-1에서 링크 i로의 회전 행렬이다. - \mathbf{d}_{i}^{i-1}은 링크 i-1에서 링크 i로의 변위 벡터이다.

로봇의 각 조인트는 회전 또는 선형 이동을 정의하며, 조인트 변위는 아래와 같은 일반적인 수식을 따른다.

\theta_i = f(q_i)

여기서: - \theta_i는 조인트 i의 회전 각도이다. - q_i는 조인트 i의 상태를 나타내는 변수이다.

SDF 파일에서 이 변환 행렬을 설정할 때는 URDF와 비슷한 방식으로 링크 간의 관계를 정의한다. 그러나, SDF는 더 복잡한 물리 엔진 설정을 지원하므로 각 링크의 물리적 특성도 더 정밀하게 설정해야 한다.

Gazebo에서 URDF 파일 불러오기

URDF 파일을 Gazebo로 불러오려면 ROS와 통합된 방식으로 이루어진다. Gazebo는 기본적으로 URDF 파일을 직접적으로 불러올 수 없기 때문에, ROS 패키지를 통해 URDF 파일을 Gazebo에 적용해야 한다. 이를 위해 gazebo_ros 패키지가 필수적으로 사용된다.

Launch 파일 설정

URDF 파일을 Gazebo로 불러오기 위해서는 ROS의 launch 파일을 사용하여 로봇 모델을 설정할 수 있다. launch 파일은 ROS 노드들의 실행과 URDF 파일의 로드, Gazebo 시뮬레이션 시작 등을 일괄적으로 처리해주는 XML 파일이다. 다음과 같은 launch 파일을 사용해 URDF 파일을 Gazebo에 로드할 수 있다.

<launch>
  <!-- 로봇 모델 로드 -->
  <param name="robot_description" command="$(find xacro)/xacro '$(find my_robot)/urdf/my_robot.urdf.xacro'" />

  <!-- Gazebo 시작 -->
  <node name="gazebo" pkg="gazebo_ros" type="gazebo" args="-urdf -model robot" output="screen">
    <param name="robot_description" command="$(find xacro)/xacro '$(find my_robot)/urdf/my_robot.urdf.xacro'" />
  </node>
</launch>

여기서 xacro는 URDF 파일을 더 간단하고 유연하게 작성할 수 있도록 도와주는 도구이며, robot_description은 URDF 파일의 내용을 담고 있는 ROS 파라미터이다.

Gazebo에서 URDF 파일 적용

Gazebo에서 로봇 시뮬레이션을 시작하기 위해서는 gazebo_ros 패키지를 이용해 URDF 파일을 로드한 후 Gazebo와 통합해야 한다. 이 과정에서 URDF 파일의 링크, 조인트, 그리고 센서 정보가 모두 Gazebo에 적용되어 로봇이 시뮬레이션될 수 있다.

  1. URDF 파일 실행

로봇 모델을 Gazebo로 로드하고 실행하기 위해서는 roslaunch 명령어를 사용할 수 있다. 예를 들어, my_robot_gazebo.launch 파일을 실행하면 URDF 모델이 Gazebo에 로드되고 시뮬레이션이 시작된다.

bash roslaunch my_robot my_robot_gazebo.launch

  1. Gazebo GUI에서 확인

Gazebo의 그래픽 사용자 인터페이스(GUI)에서 로봇 모델을 확인할 수 있다. 로봇이 정상적으로 시뮬레이션에 로드되었다면, 링크와 조인트를 기반으로 한 물리적 움직임과 센서 데이터 출력 등이 모두 가능해진다.

ROS 토픽을 통한 로봇 상태 확인

Gazebo와 ROS가 통합된 후, URDF로 정의된 로봇의 상태를 ROS 토픽을 통해 실시간으로 확인할 수 있다. 예를 들어, 로봇의 링크 위치나 조인트 상태는 ROS의 /joint_states 토픽을 통해 접근할 수 있다.

rostopic echo /joint_states

이 명령어를 실행하면 로봇의 각 조인트에 대한 상태를 실시간으로 확인할 수 있다. 여기에는 각 조인트의 각도 \theta_i와 속도 \dot{\theta}_i 등의 값이 포함된다.

SDF 파일 불러오기

SDF 파일은 URDF보다 더 복잡한 기능을 지원하며, Gazebo에서 직접적으로 사용 가능한 파일 포맷이다. SDF 파일을 불러오려면 다음과 같은 절차를 따른다.

  1. SDF 파일 경로 지정

Gazebo는 SDF 파일을 직접적으로 불러올 수 있다. 이를 위해 터미널에서 SDF 파일을 경로와 함께 지정해주면 된다. 예를 들어, 아래 명령어를 사용해 SDF 파일을 불러올 수 있다.

bash gazebo my_robot.sdf

또는 Gazebo GUI에서 직접적으로 SDF 파일을 불러올 수도 있다.

  1. SDF와 Gazebo의 통합

SDF 파일은 URDF와는 달리 Gazebo에서 기본적으로 지원하는 포맷이기 때문에, 별도의 ROS 설정 없이도 Gazebo에서 로봇 모델을 시뮬레이션할 수 있다. SDF 파일은 보다 복잡한 물리적 속성, 센서 설정, 그리고 환경 모델링 등을 포함할 수 있다.

  1. SDF의 물리 엔진 설정

SDF 파일을 통해 로봇의 물리 엔진 설정도 가능하다. 예를 들어, SDF 파일에서 링크 간의 충돌 모델이나 마찰 계수 등을 설정할 수 있으며, 이러한 설정들은 Gazebo의 물리 엔진을 통해 적용된다. 다음은 SDF 파일 내에서 물리 엔진을 설정하는 예이다.

xml <physics name="default_physics" type="ode"> <gravity>0 0 -9.8</gravity> <max_step_size>0.001</max_step_size> <real_time_factor>1.0</real_time_factor> </physics>

이와 같이 SDF 파일은 보다 세부적으로 로봇의 물리적 특성과 움직임을 정의할 수 있다.

수학적 표현

SDF 파일에서 로봇의 링크와 조인트를 정의하는 과정에서도 변환 행렬은 중요한 역할을 한다. 각 링크 간의 변환 행렬은 로봇의 3D 위치와 방향을 계산하는 데 사용된다. 이러한 변환 행렬은 다음과 같이 정의된다.

\mathbf{T}_{global} = \mathbf{T}_{1}^{0} \cdot \mathbf{T}_{2}^{1} \cdot \cdot \cdot \mathbf{T}_{n}^{n-1}

여기서: - \mathbf{T}_{global}은 전체 로봇의 전역 좌표계에서의 위치 및 방향을 나타내는 변환 행렬이다. - \mathbf{T}_{i}^{i-1}은 링크 i-1에서 링크 i로의 변환 행렬이다.

이와 같은 변환 행렬을 통해 URDF 또는 SDF 파일에서 정의된 링크와 조인트 사이의 관계를 수학적으로 설명할 수 있다. 각 조인트의 회전 각도는 다음과 같이 나타낼 수 있다.

\theta_i = q_i

이때 q_i는 조인트 i의 회전 각도를 나타내는 변수이며, 각 링크 간의 변환은 회전 행렬과 병렬적으로 적용된다.

URDF와 SDF의 통합

Gazebo에서 URDF와 SDF 파일을 로드한 후, 이 두 파일을 사용하여 로봇 시뮬레이션을 설정할 수 있다. URDF는 ROS와의 긴밀한 통합을 통해 주로 로봇의 기본 구조와 링크, 조인트를 정의하는 데 사용되며, SDF는 Gazebo에서 보다 복잡한 물리적 상호작용과 환경 설정을 위해 사용된다.

URDF에서 SDF로 변환

Gazebo에서 URDF 파일을 사용하는 경우, 기본적으로 URDF 파일은 내부적으로 SDF 형식으로 변환된다. 따라서 사용자가 URDF 파일을 로드하면 Gazebo는 이 파일을 SDF로 변환한 후 시뮬레이션에 적용한다. 이러한 변환 과정을 통해 URDF 파일의 한계점을 극복하고, Gazebo의 강력한 기능을 활용할 수 있다.

gz sdf -p my_robot.urdf > my_robot.sdf

위 명령어를 사용하면 URDF 파일을 SDF 형식으로 변환할 수 있다. 변환된 SDF 파일은 Gazebo에서 직접 로드하여 사용하거나, 추가적으로 수정을 가하여 로봇 시뮬레이션에 적용할 수 있다.

Gazebo의 URDF/SDF 불러오기 예시

URDF나 SDF 파일을 불러와 Gazebo에서 로봇 시뮬레이션을 시작하려면, ROS 명령어나 Gazebo 명령어를 사용하여 해당 파일을 실행할 수 있다. 예를 들어, roslaunch를 통해 URDF 파일을 실행하거나 Gazebo 터미널 명령어를 통해 SDF 파일을 실행할 수 있다.

bash roslaunch my_robot my_robot_gazebo.launch

bash gazebo my_robot.sdf

두 방식 모두 Gazebo에서 로봇의 동작과 센서 출력을 시뮬레이션할 수 있으며, 이는 물리 엔진을 통해 시뮬레이션된다.

URDF/SDF 파일의 상호작용

URDF와 SDF 파일은 각각 고유의 역할을 가진다. URDF는 주로 로봇의 기초적인 모델링과 ROS와의 통합을 위해 사용되며, SDF는 Gazebo에서 로봇의 물리적 상호작용과 센서 시뮬레이션을 위한 더 세부적인 설정을 제공한다. 따라서 복잡한 로봇 시뮬레이션의 경우, URDF와 SDF의 기능을 모두 활용하여 시뮬레이션을 진행하는 것이 바람직하다.

물리적 특성 정의

URDF와 SDF에서 로봇의 링크 및 조인트 간의 관계를 정의할 때, 물리적 특성 또한 중요한 역할을 한다. 물리적 특성에는 질량, 관성, 마찰 계수 등이 포함되며, 이러한 값들은 로봇의 움직임을 시뮬레이션하는 데 필수적이다. URDF와 SDF 모두 이러한 물리적 특성을 정의하는 방법을 제공하지만, SDF는 더 세부적인 설정을 허용한다.

URDF에서 물리적 특성을 정의하는 예:

<link name="base_link">
  <inertial>
    <mass value="5.0"/>
    <inertia>
      <ixx value="0.1"/>
      <iyy value="0.1"/>
      <izz value="0.1"/>
    </inertia>
  </inertial>
</link>

SDF에서 물리적 특성을 정의하는 예:

<link name="base_link">
  <inertial>
    <mass>5.0</mass>
    <inertia>
      <ixx>0.1</ixx>
      <iyy>0.1</iyy>
      <izz>0.1</izz>
    </inertia>
  </inertial>
  <collision>
    <geometry>
      <box>
        <size>1 1 1</size>
      </box>
    </geometry>
  </collision>
</link>

SDF는 URDF와 달리 충돌 모델 및 기타 물리적 상호작용 요소들을 더 세부적으로 설정할 수 있으며, 이를 통해 보다 정교한 시뮬레이션을 구현할 수 있다.

센서 정의

URDF와 SDF 모두 로봇의 센서를 정의할 수 있다. 특히 SDF는 센서의 종류와 설정을 보다 정밀하게 제어할 수 있으며, 이를 통해 시뮬레이션에서 로봇의 환경 인식을 더 정확하게 반영할 수 있다.

URDF에서 센서 정의

URDF에서는 주로 gazebo_ros 플러그인을 사용하여 센서를 정의하고 이를 Gazebo와 통합한다. 다음은 URDF 파일에서 LIDAR 센서를 정의하는 예이다.

<gazebo>
  <sensor type="ray" name="laser">
    <pose>0 0 0 0 0 0</pose>
    <ray>
      <scan>
        <horizontal>
          <samples>720</samples>
          <resolution>1</resolution>
          <min_angle>-1.5708</min_angle>
          <max_angle>1.5708</max_angle>
        </horizontal>
      </scan>
      <range>
        <min>0.1</min>
        <max>30.0</max>
      </range>
    </ray>
  </sensor>
</gazebo>

SDF에서 센서 정의

SDF에서는 센서를 더 정밀하게 설정할 수 있다. SDF 파일 내에서 센서의 모든 특성, 동작 방식, 그리고 환경과의 상호작용까지 정의할 수 있다. 다음은 SDF 파일에서 카메라 센서를 정의하는 예이다.

<sensor name="camera" type="camera">
  <pose>0 0 1 0 0 0</pose>
  <camera>
    <horizontal_fov>1.047</horizontal_fov>
    <image>
      <width>640</width>
      <height>480</height>
    </image>
  </camera>
  <plugin name="camera_controller" filename="libgazebo_ros_camera.so">
    <robotNamespace>/my_robot</robotNamespace>
  </plugin>
</sensor>

수학적 표현

URDF와 SDF에서 정의된 센서와 링크의 물리적 상호작용은 수학적 모델을 기반으로 동작한다. 특히 로봇의 링크와 조인트 사이의 변환 행렬은 각 링크의 위치와 방향을 계산하는 데 중요한 역할을 한다.

각 링크 i의 위치 \mathbf{p}_i는 다음과 같은 변환 행렬을 사용하여 구할 수 있다.

\mathbf{p}_i = \mathbf{T}_{i}^{i-1} \cdot \mathbf{p}_{i-1}

여기서 \mathbf{T}_{i}^{i-1}는 링크 i-1에서 링크 i로의 변환 행렬이며, 각 링크 간의 변환은 회전 행렬 \mathbf{R}과 병진 벡터 \mathbf{d}로 구성된다.

이와 같은 변환 행렬은 로봇의 각 링크 간의 위치와 방향을 계산하는 데 사용되며, 이는 센서의 위치 및 방향을 결정하는 데도 활용된다.