# URDF를 통한 로봇 모델링

#### URDF(Universal Robot Description Format) 개요

URDF는 XML 형식의 파일로, 로봇의 물리적 구조를 정의하는 데 사용된다. 로봇의 링크(link), 조인트(joint), 그리고 센서 등의 구성 요소를 기술할 수 있다. URDF 파일은 ROS에서 로봇의 시뮬레이션, 시각화, 제어에 중요한 역할을 하며, 특히 Gazebo와 같은 시뮬레이션 툴과 rviz에서 로봇의 모델을 시각화하는 데 활용된다.

URDF의 주요 목적은 로봇의 **구조적 구성 요소**를 정의하고, 로봇의 **물리적 특성**을 모델링하는 것이다.

#### URDF 파일의 기본 구조

URDF 파일은 로봇의 구성 요소를 표현하기 위해 \*\*링크(link)\*\*와 \*\*조인트(joint)\*\*라는 두 가지 주요 요소를 사용한다. 링크는 로봇의 몸체나 팔, 다리 같은 구조적인 부분을 나타내고, 조인트는 각 링크가 서로 어떻게 연결되어 움직이는지를 정의한다.

**링크 정의**

링크는 로봇의 각 구성 요소의 물리적 특성을 정의한다. 링크에는 질량, 관성, 모양, 재질 등의 정보가 포함된다. URDF에서의 링크 정의는 다음과 같다:

```xml
<link name="base_link">
  <visual>
    <geometry>
      <box size="1 1 1"/>
    </geometry>
    <material name="red"/>
  </visual>
  <inertial>
    <mass value="1.0"/>
    <inertia ixx="0.1" iyy="0.1" izz="0.1" />
  </inertial>
</link>
```

위 코드는 로봇의 베이스 링크를 정의하며, 크기, 재질, 질량, 관성 모멘트를 포함하고 있다.

**조인트 정의**

조인트는 로봇의 링크 간의 관계를 정의하며, 조인트의 종류에 따라 회전하거나 이동하는 방식이 다르다. 주요 조인트 종류로는 **revolute**(회전형), **prismatic**(이동형), **fixed**(고정형)이 있다. 조인트의 예시는 다음과 같다:

```xml
<joint name="joint1" type="revolute">
  <parent link="base_link"/>
  <child link="arm_link"/>
  <axis xyz="0 0 1"/>
  <limit lower="-1.57" upper="1.57" effort="1000" velocity="1.0"/>
</joint>
```

이 코드는 로봇의 **베이스 링크**와 **팔 링크**를 연결하는 회전형 조인트를 정의한다.

#### 링크와 조인트의 수학적 표현

URDF에서 정의된 로봇의 구조를 수학적으로 표현할 수 있다. 각 링크의 위치와 방향은 로봇의 기준 좌표계에 의해 정의된다. 이를 위해 우리는 각 링크의 위치를 나타내는 **변환 행렬**을 사용한다. 링크의 좌표계 변환은 일반적으로 다음과 같은 형태로 표현된다:

$$
\mathbf{T}*\text{link} = \begin{bmatrix} \mathbf{R}*\text{link} & \mathbf{p}\_\text{link} \ \mathbf{0}^T & 1 \end{bmatrix}
$$

여기서:

* $\mathbf{R}\_\text{link}$는 링크의 회전 행렬이다.
* $\mathbf{p}\_\text{link}$는 링크의 위치 벡터이다.

조인트의 회전 또는 이동에 의해 링크 간의 변환이 발생하며, 이러한 변환은 다음과 같이 표현된다:

$$
\mathbf{T}*\text{joint} = \begin{bmatrix} \mathbf{R}*\text{joint} & \mathbf{p}\_\text{joint} \ \mathbf{0}^T & 1 \end{bmatrix}
$$

각 조인트는 회전형일 경우, 회전축을 기준으로 변환되며, 회전 각도 $\theta$에 따라 회전 행렬 $\mathbf{R}\_\text{joint}$는 다음과 같이 정의된다:

$$
\mathbf{R}\_\text{joint}(\theta) = \begin{bmatrix} \cos \theta & -\sin \theta & 0 \ \sin \theta & \cos \theta & 0 \ 0 & 0 & 1 \end{bmatrix}
$$

URDF 모델에서 이러한 변환 행렬들은 로봇의 전체 구조를 나타내는 데 중요한 역할을 하며, 특히 다중 링크와 조인트가 연결된 로봇에서는 각 링크 간의 관계를 이해하는 데 필수적이다.

#### 관성 모멘트와 질량의 수학적 정의

로봇의 물리적 특성 중 하나는 각 링크의 **질량**과 **관성 모멘트**이다. URDF에서는 각 링크의 질량을 정의하고, 관성 행렬을 사용하여 각 링크의 관성을 표현한다.

**질량**

질량은 링크의 무게를 나타내며, URDF에서 단순히 하나의 숫자로 정의된다. 예를 들어, URDF에서 링크의 질량을 정의하는 부분은 다음과 같다:

```xml
<inertial>
  <mass value="2.0"/>
</inertial>
```

이는 링크의 질량이 2.0 kg이라는 것을 의미한다.

**관성 모멘트**

관성 모멘트는 링크의 회전에 대한 저항을 나타내는 물리량이다. URDF에서는 관성 행렬 $\mathbf{I}$을 사용하여 정의되며, 각 성분은 회전축에 대한 관성 모멘트를 나타낸다. 관성 행렬은 대칭 행렬로 다음과 같이 정의된다:

$$
\mathbf{I} = \begin{bmatrix} I\_{xx} & I\_{xy} & I\_{xz} \ I\_{yx} & I\_{yy} & I\_{yz} \ I\_{zx} & I\_{zy} & I\_{zz} \end{bmatrix}
$$

URDF에서의 관성 모멘트 정의는 다음과 같다:

```xml
<inertia ixx="0.1" iyy="0.1" izz="0.1" ixy="0" ixz="0" iyz="0"/>
```

이는 대각 성분을 중심으로 하는 관성 모멘트를 나타내며, 링크가 균질한 물체라고 가정했을 때 대칭적인 형태의 관성 행렬을 갖는다.

#### 링크 간의 상호작용과 역학 모델

URDF 파일은 로봇의 정적 모델만을 제공하지만, 이를 기반으로 동적 모델을 유도할 수 있다. 동적 모델은 로봇의 움직임과 힘을 계산하는 데 중요한 역할을 한다. 로봇의 동역학은 일반적으로 **뉴턴-오일러 공식**이나 **라그랑지안 역학**으로 표현된다.

**뉴턴-오일러 공식**

로봇의 각 링크에 작용하는 힘과 토크를 계산하기 위해 뉴턴-오일러 공식을 사용할 수 있다. 이 공식은 다음과 같이 표현된다:

$$
\mathbf{F}\_i = m\_i \mathbf{a}\_i
$$

$$
\mathbf{\tau}\_i = \mathbf{I}\_i \mathbf{\alpha}\_i + \mathbf{\omega}\_i \times (\mathbf{I}\_i \mathbf{\omega}\_i)
$$

여기서:

* $\mathbf{F}\_i$는 링크 $i$에 작용하는 힘이다.
* $m\_i$는 링크 $i$의 질량이다.
* $\mathbf{a}\_i$는 링크 $i$의 선형 가속도이다.
* $\mathbf{\tau}\_i$는 링크 $i$에 작용하는 토크이다.
* $\mathbf{\alpha}\_i$는 링크 $i$의 각가속도이다.
* $\mathbf{\omega}\_i$는 링크 $i$의 각속도이다.
* $\mathbf{I}\_i$는 링크 $i$의 관성 행렬이다.

이 공식을 통해 각 링크에 작용하는 힘과 토크를 계산할 수 있으며, 로봇의 움직임을 예측할 수 있다.

**라그랑지안 역학**

라그랑지안 역학은 로봇의 전체 에너지를 기반으로 동작을 예측하는 방법이다. 로봇의 운동 에너지를 $T$, 위치 에너지를 $V$라고 할 때, 라그랑지안은 다음과 같이 정의된다:

$$
L = T - V
$$

라그랑지안 방정식은 다음과 같이 표현된다:

$$
\frac{d}{dt} \left( \frac{\partial L}{\partial \dot{q}} \right) - \frac{\partial L}{\partial q} = \tau
$$

여기서:

* $q$는 일반화된 좌표이다.
* $\dot{q}$는 일반화된 속도이다.
* $\tau$는 외부에서 가해지는 힘(토크)을 나타낸다.

라그랑지안 방정식을 풀어 각 링크의 동작을 계산할 수 있다.

#### URDF에서 좌표계와 변환

URDF에서 로봇의 각 링크와 조인트는 특정 좌표계를 기준으로 정의된다. 좌표계는 **기준 좌표계**(base coordinate frame)와 **상대 좌표계**(relative coordinate frame)로 구분되며, 각각의 링크와 조인트는 이 좌표계를 사용하여 자신의 위치와 방향을 표현한다.

**좌표계 변환**

로봇의 링크나 조인트 간의 좌표계 변환은 주로 **동차 좌표계**(homogeneous coordinates)로 표현된다. 동차 좌표계는 3차원 공간에서의 위치와 회전을 하나의 행렬로 나타내며, 다음과 같은 형태로 정의된다:

$$
\mathbf{T} = \begin{bmatrix} \mathbf{R} & \mathbf{p} \ \mathbf{0}^T & 1 \end{bmatrix}
$$

여기서:

* $\mathbf{R}$은 회전 행렬 (3x3)이다.
* $\mathbf{p}$는 위치 벡터 (3x1)이다.

예를 들어, URDF에서 특정 링크가 부모 링크에 대해 어떤 위치에 있는지 정의할 때, **원점**(origin) 태그를 사용하여 위치와 회전 정보를 제공한다.

```xml
<origin xyz="0 0 1" rpy="0 0 1.57"/>
```

위의 URDF 코드는 링크가 부모 링크에 대해 **x, y, z** 축으로 1미터 떨어진 위치에 있으며, **롤, 피치, 요**(RPY) 각도로 1.57 라디안 만큼 회전한 상태를 나타낸다.

**회전 행렬과 회전벡터**

URDF에서 회전은 **RPY (Roll, Pitch, Yaw)** 형식으로 표현되며, 이를 회전 행렬로 변환할 수 있다. RPY는 각각 x, y, z 축을 기준으로 회전하는 각도를 나타낸다.

회전 행렬은 각 축에 대한 회전 행렬의 곱으로 나타낼 수 있으며, 각각의 회전은 다음과 같은 행렬로 표현된다:

$$
\mathbf{R}\_x(\alpha) = \begin{bmatrix} 1 & 0 & 0 \ 0 & \cos \alpha & -\sin \alpha \ 0 & \sin \alpha & \cos \alpha \end{bmatrix}
$$

$$
\mathbf{R}\_y(\beta) = \begin{bmatrix} \cos \beta & 0 & \sin \beta \ 0 & 1 & 0 \ -\sin \beta & 0 & \cos \beta \end{bmatrix}
$$

$$
\mathbf{R}\_z(\gamma) = \begin{bmatrix} \cos \gamma & -\sin \gamma & 0 \ \sin \gamma & \cos \gamma & 0 \ 0 & 0 & 1 \end{bmatrix}
$$

RPY 값이 주어졌을 때, 회전 행렬 $\mathbf{R}$는 다음과 같은 곱으로 표현된다:

$$
\mathbf{R} = \mathbf{R}\_z(\gamma) \mathbf{R}\_y(\beta) \mathbf{R}\_x(\alpha)
$$

이러한 회전 행렬을 사용하여 로봇의 링크가 부모 링크에 대해 어떻게 배치되는지 계산할 수 있다.

#### URDF 파일에서 고정 좌표와 동적 좌표

URDF 파일에서 로봇의 좌표계는 고정적일 수도 있고, 동적으로 변경될 수도 있다. 링크 사이의 관계는 조인트에 의해 결정되며, 조인트는 회전하거나 직선 운동을 할 수 있다. 이러한 동적 좌표계를 표현하기 위해서는 조인트의 상태 변화에 따른 변환 행렬을 계산해야 한다.

**동적 좌표계 변환**

동적 좌표계 변환은 조인트의 각도나 위치에 따라 변한다. 예를 들어, 조인트가 회전형(revolute)일 경우, 회전 각도 $\theta$에 따라 변환 행렬이 달라진다. 이때 변환 행렬은 다음과 같이 표현된다:

$$
\mathbf{T}\_\text{joint}(\theta) = \begin{bmatrix} \cos \theta & -\sin \theta & 0 & x \ \sin \theta & \cos \theta & 0 & y \ 0 & 0 & 1 & z \ 0 & 0 & 0 & 1 \end{bmatrix}
$$

이 변환 행렬을 통해 링크와 링크 간의 위치 관계를 동적으로 계산할 수 있으며, 로봇의 각 조인트가 회전하거나 이동할 때마다 변환 행렬이 갱신된다.

#### URDF에서의 로봇 모델링 최적화

로봇의 URDF 파일이 복잡해질수록 성능에 미치는 영향이 커지므로, URDF 모델을 최적화하는 것이 중요하다. URDF 최적화를 위해 고려해야 할 사항은 다음과 같다:

1. **중복 제거**: 동일한 링크나 조인트의 정의가 여러 곳에서 반복되지 않도록 해야 한다. URDF는 XACRO와 같은 매크로 확장을 지원하므로, 이를 통해 중복 코드를 줄일 수 있다.
2. **관성 정보의 정확한 정의**: 관성 모멘트와 질량 중심의 정확한 정의는 시뮬레이션 성능에 큰 영향을 미친다. 잘못된 관성 정보는 로봇의 움직임을 왜곡시키고 불필요한 계산을 유발할 수 있다.
3. **단순화된 충돌 모델 사용**: 시뮬레이션에서의 충돌 계산은 많은 자원을 소모한다. 따라서, 충돌 모델을 단순한 형태로 정의하여 계산량을 줄일 수 있다.
4. **필요한 정보만 포함**: 시뮬레이션에서 필요하지 않은 시각적 정보나 물리적 속성을 제거하여 URDF 파일의 크기를 줄일 수 있다. 예를 들어, 디버깅 용도로만 필요한 메시지를 제거하거나 간단한 모델을 사용하여 성능을 최적화할 수 있다.

이러한 최적화 기법을 통해 URDF 파일의 효율성을 높이고, 시뮬레이션 환경에서의 성능을 개선할 수 있다.
