
URDF에서 사용하는 각도는 우리가 많이 사용하는 60분법이 아닌 라디안(radian, 호도법)을 사용한다. 라디안은 반지름 r 과 호의 길이가 r과 같을 때의 각을 1라디안이라고 정의한다.
(360º 는 2ᅲ 가 되고 180º 는 ᅲ 이다.)

URDF로 로봇을 좌표계에 표현은 2가지로 표현을 한다.
첫번째는 직교 좌표계를 통해서 3차원 공간에 로봇이 어디에 있는지 알 수 있다. 직교 좌표계로만 로봇을 표현하면 로봇이 어느 방향을 향하고 있는지 알 수 없다.
두 번째는 오일러 각을 통해서 로봇이 x축에 대해서 회전(roll), y축에 대해서 회전(pitch), z축에 대해서 회전(yaw)을 통해 로봇을 표현하면 3차원 공간에서 완벽하게 로봇을 표현 할 수 있다.
URDF는 “Unified Robot Description Format”의 줄임말로 로봇모델에 대한 정보들을 명세해놓은 규격서라고 볼수 있다. URDF는 ROS에서 로봇 모델을 XML로 설명한다. ROS는 gazebo와 연동을 하여 로봇을 만들기 전에 URDF로 로봇 모델을 정의하여 시뮬레이션 할 수 있다.
로봇 개발에 필요한 로봇 모델 정보들을 여기에 기록해두고, 해당 정보를 필요로 하는 다른 패키지, 노드에서 활용하게 된다.
URDF를 더 잘 이해하기 위해서는 TF를 알고 있으면 좋기 때문에 이후 TF에 관한 이야기도 작성할 예정이다.
URDF에서 로봇을 설명하기 위한 루트로써 반드시 포함되어야 하며 로봇의 이름을 정의힌다.
<robot name="manipulator">
<!-- manipulator robot links and joints and more -->
</robot>

링크(link)를 설명하기 위해서는 강체(rigid body)에 대해 먼저 설명을 해야 한다. 물리 시간에 강체에 대한 정의는 외부의 힘을 받아도 그 크기와 모양이 변하지 않은 이상적인 고체를 강체라고 한다. 우리가 주위에서 볼 수 있는 쇠구슬을 보통 강체라고 한다.
URDF에서 자동차 로봇이라면 차체도 강체가 되며, 바퀴도 강체로써 모두 링크(link)로 설명 된다.
원점 좌표(origin)
좌표는 직교 좌표계를 통해 로봇의 위치를 3차원 공간 상에서 표현을 하고 오일러 각을 통해 로봇의 방향을 표현 한다. 직교 좌표계의 단위는 미터(meter)를 사용하고 오일러 각은 라디안(radian)으로 정의 한다.
<origin xyz="0 0 0.5" rpy="0 0 0"/>
링크는 크게 물리적 특성(inertial), 시각적 특성(visual), 물리적 충돌(collison)을 갖고 있으며, 각각 다른 위치 값을 갖을 수 있다.
물리적 특성(inertial)
강체의 물리적 특성은 질량과 관성이 있다.
ixx ixy ixz
ixy iyy iyz
ixz iyz izz
<mass value="1"/>
<inertia ixx="100" ixy="0" ixz="0" iyy="100" iyz="0" izz="100" />
시각적 형태(visual)
시각적 형체는 2가지 방법으로 표현을 할 수 있다. 지오메트리(geometry)와 메쉬(mesh)가 있다.
지오메트리(geometry)
박스(box): 상자로써 크기는 세 변 길이 가로(width), 세로(length), 높이(height) 이다.
<geometry>
<box size="0.1 0.1 1" />
</geometry>
<geometry>
<cylinder length="0.6" radius="0.2"/>
</geometry>
<geometry>
<sphere radius="0.2"/>
</geometry>
<geometry>
<mesh filename="package://meshes/example.stl"/>
</geometry>
<color rgba="1.0 1.0 0.0 1.0" />
물리적 충돌(collison)
실제 로봇이 벽이나 다른 물체와 충돌하면 로봇이 더 이상 움직이지 못하는 것처럼 링크(link,강체)의 물리적 충돌(collison)영역을 정의 한다. 시각적 형체의 지오메트리(geometry)와 같게 설정하면 된다.
다음은 링크(link)의 예이다.
<link name="my_link">
<inertial>
<origin xyz="0 0 0.5" rpy="0 0 0"/>
<mass value="1"/>
<inertia ixx="100" ixy="0" ixz="0" iyy="100" iyz="0" izz="100" />
</inertial>
<visual>
<origin xyz="0 0 0" rpy="0 0 0" />
<geometry>
<box size="1 1 1" />
</geometry>
<material name="Cyan">
<color rgba="0 1.0 1.0 1.0"/>
</material>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<cylinder radius="1" length="0.5"/>
</geometry>
</collision>
</link>

※ vscode의 urdf preview로 확인할 수 있음
링크 태그의 속성
< link > : 링크의 시각화와 충돌 그리고 관성 정보 설정
< collision > : 링크의 충돌 계산을 위한 정보 설정
< visual > : 링크의 시각화 정보 설정
< inertial > : 링크의 관성 정보 설정
< mass > : 링크의 무게(단위: kg) 설정
< inertia > : 관성 텐서(inertia tensor) 설정
< origin > : 링크의 상대 좌표계를 기준으로 이동과 회전 설정
< geometry > : 모델의 모양 입력, box, cylinder, sphere 형태를 기본 제공한다.
< material > : 링크의 색상과 텍스처 설정
로봇은 여러개의 관절(joint)로 이루어져 있으며 관절(joint)는 링크(강체)가 연결을 한다. 모든 링크는 한 개 이상의 관절로 연결되어야 한다.
URDF에서 로봇이 표현할 수 있는 모든 관절을 포함하지는 않지만 중요한 관절은 모두 지원한다.

관절의 종류는 많지만 대부분 사용하는 관절은 고정관절(fixed joint), 회전 관절(revolute joint), 연속 회전(continuous joint)를 사용 한다.
모든 관절에는 부모 링크를 가져야 한다.
모든 관절에는 자식 링크를 가져야 한다.
관절의 축을 표현한다.
관절의 물리적 동역학 특성을 설정 한다.
관절의 제한은 회전 관절(revolute joint)와 프리즘 관절(prismatic joint)에서만 정의 할 수 있다. 180도의 서보모터와 같이 서보모터는 0도에서 180도 까지의 범위를 정의할 때 사용한다.
다음은 조인트와 링크의 예이다.
<robot name="test" >
<joint name="my_joint" type="revolute">
<origin xyz="0 0 0.5" rpy="0 1.5 0"/>
<parent link="my_link1"/>
<child link="my_link2"/>
<calibration rising="0.0"/>
<dynamics damping="0.0" friction="0.0"/>
<limit effort="30" velocity="1.0" lower="-2.2" upper="0.7" />
<safety_controller k_velocity="10" k_position="15" soft_lower_limit="-2.0" soft_upper_limit="0.5" />
</joint>
<link name="my_link1">
<inertial>
<origin xyz="0 0 0.5" rpy="0 0 0"/>
<mass value="1"/>
<inertia ixx="100" ixy="0" ixz="0" iyy="100" iyz="0" izz="100" />
</inertial>
<visual>
<origin xyz="0 0 0" rpy="0 0 0" />
<geometry>
<box size="0.1 0.1 1" />
</geometry>
<material name="Cyan">
<color rgba="0 1.0 1.0 1.0"/>
</material>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<cylinder radius="1" length="0.5"/>
</geometry>
</collision>
</link>
<link name="my_link2">
<inertial>
<origin xyz="0 0 0.5" rpy="0 0 0"/>
<mass value="1"/>
<inertia ixx="100" ixy="0" ixz="0" iyy="100" iyz="0" izz="100" />
</inertial>
<visual>
<origin xyz="0 0 0" rpy="0 0 0" />
<geometry>
<box size="0.1 0.1 1" />
</geometry>
<material name="Cyan">
<color rgba="0 1.0 1.0 1.0"/>
</material>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<cylinder radius="1" length="0.5"/>
</geometry>
</collision>
</link>
</robot>

관절 태그의 속성
< joint > : 링크와의 관계와 관절 형태 설정
< parent > : 관절의 부모 링크
< child > : 관절의 자식 링크
< origin > : 부모 링크 좌표계를 자식 링크 좌표계로 변환
< axis > : 회전 축 설정
< limit > : 관절의 속도, 힘, 반경을 설정(관절이 revolute 혹은 prismatic 일 때만 적용