# URDF/SDF 파일 불러오기

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
   ```
2. **Gazebo와의 통합**

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

```xml
<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
   ```
2. **Gazebo GUI에서 확인**

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

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

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

```bash
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 파일을 불러올 수도 있다.
2. **SDF와 Gazebo의 통합**

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

```bash
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 파일을 실행할 수 있다.

* URDF 실행 예시:

  ```bash
  roslaunch my_robot my_robot_gazebo.launch
  ```
* SDF 실행 예시:

  ```bash
  gazebo my_robot.sdf
  ```

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

#### URDF/SDF 파일의 상호작용

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

**물리적 특성 정의**

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

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

```xml
<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에서 물리적 특성을 정의하는 예:

```xml
<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 센서를 정의하는 예이다.

```xml
<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 파일에서 카메라 센서를 정의하는 예이다.

```xml
<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}$로 구성된다.

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