URDF란?
URDF (Unified Robot Description Format) 란 로봇의 3D 형상 및 외관, 관성 등 물리적 특성 등을 XML 언어로 정의하는 것을 말한다. URDF로 정의된 로봇 모델은 RVIZ에서 3차원으로 보거나 Gazebo에서 물리 시뮬레이션이 가능하다.
URDF 좌표계 및 단위
좌표계
- 위치나 크기를 표현하기 위해 데카르트 좌표계 x,y,z를 사용한다.
- 회전을 표현하기 위해 오일러각도 roll, pitch, yaw를 사용한다.
단위
- 길이 : meter
- 각도 : radian
- 1라디안 = 180도/π = 57.3도
- π라디안 = 1라디안 x π = 180도/π x π = 180도
- 질량 : kg
- 속도 : m/s (병진/직진)
- 각속도 : radian/s (회전)
URDF 형상 표현
형상 표현
- cylinder 원통
- box 상자
- sphere 공
색상 표현
- RGB 3원색과 투과율 A(0~1)의 숫자로 정의한다.
URDF 기구 표현
기구 표현
- base : 고정 부분 (땅에 붙은 곳)
- link : 관절에 연결되는 로봇 팔의 부분
- joint : 링크를 연결하는 부위로 보통 모터의 회전을 통해 움직임을 만듦
- joint의 동작 표현
- fixed : 고정
- revolute : 작동 범위 제한
- continuous : 연속 회전
- joint의 동작 표현
예시
robot 태그 안에 link가 3개, joint가 2개로 이루어져 있고, 맨 밑에 있는 link를 base_link라 하는 것 처럼 각각의 이름을 지정해줄 수 있다. type을 통해 동작을 표현해줄 수 있다.
연결되는 2개의 link에서 각각을 parent, child link라고 할 수 있다.
<visual> : 시각화를 위해 형상과 위치를 정의
- <geometry> : 형상 및 크기 정의 (원통, 상자, 공)
- <origin> : 고정축을 기준으로 얼마나 회전되어 있는지에 대한 link 형상의 roll, pitch, yaw 값을 라디안으로 나타내고 x,y,z 좌표 위치를 미터 단위로 지정
- <material> : 형상의 컬러값을 지정
<parent> : child frame과 연결하기 위해 parent frame의 이름을 지정
<child> : parent frame과 연결하기 위해 child frame의 이름을 지정
<origin> : 고정축을 기준으로 얼마나 회전되어 있는지에 대한 형상의 roll,pitch,yaw 값을 라디안으로 나타내고, x,y,z 좌표 위치를 미터 단위로 지정, joint는 parent의 origin을, child는 joint의 origin을 고정축으로 정한다.
<limit> : joint의 운동범위에 대한 제한값을 지정한다. 이를 지정하지 않으면 제한없이 360도 돌아가는 것을 말한다.
- lower: revolute type의 joint에서 최저 각을 라디안으로 지정
- upper: revolute type의 joint에서 최대 각을 라디안으로 지정
- effort: N 단위로 힘의 최대값을 지정
- velocity: radian/s 단위로 최대속도를 지정
RVIZ에서 회전막대 모델 시각화하기
- URDF 파일(xml 형식)로 회전막대 모델링
- ROS 패키지 생성 : 패키지 생성, 패키지 이름은 ex_urdf
- /urdf 폴더 생성 : .urdf파일 만들기
- /launch 폴더 생성 : .launch파일 만들기
- RVIZ 실행
패키지 생성
1
2
3
4
5
6
7
8
9
xycar_ws
⊢ build
⊢ devel
∟ src
∟ ex_urdf
⊢ launch
∟ view_pan_tilt_urdf.launch
∟ urdf
∟ pan_tilt.urdf
- ex_urdf 패키지 만들기
1
~/xycar_ws/src$ catkin_create_pkg ex_urdf roscpp tf geometry_msgs urdf rviz xacro
- 서브 폴더 생성
- /urdf 폴더 생성
- pan_tilt.urdf 파일 작성
- /launch 폴더 생성
- view_pan_tilt_urdf.launch 파일 작성
pan_tilt.urdf
- base link
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<?xml version="1.-"?>
<robot name="ex_urdf_pan_tilt">
<!-- base link -->
<link name="base_link">
<visual>
<geometry>
<!-- 원판 모양의 base link, 높이 1cm, 반지름 20cm 의 원통-->
<cylinder length="0.01" radius="0.2"/> <!-- 시작 위치는 0센치 -->
</geometry>
<origin rpy="0 0 0" xyz="0 0 0"/>
<material name="yellow">
<color rgba="1 1 0 1"/>
</material>
</visual>
<collision>
<geometry>
<cylinder length="0.03" radius="0.2"/>
</geometry>
<origin rpy="0 0 0" xyz="0 0 0"/>
</collision>
<inertial>
<mass value="1"/>
<inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0"/>
</inertial>
</link>
<!-- pan_joint -->
<joint name="pan_joint" type="revolute">
<parent link="base_link"/>
<child link="pan_link"/>
<origin xyz="0 0 0.1"/> <!-- joint위치는 base_link 0에서 10을 더해 10cm -->
<axis xyz="0 0 1"/>
<limit effort="300" velocity="0.1" lower="-3.14" upper="3.14"/>
<dynamics damping="50" friction="1"/>
</joint>
<!-- pan link -->
<link name="pan_link">
<visual>
<geometry>
<!-- 원판 모양의 pan link, 높이 40cm, 반지름 4cm 의 원통-->
<cylinder length="0.4" radius="0.04"/>
</geometry>
<origin rpy="0 0 0" xyz="0 0 0.09"/> <!-- 실린더 중앙점의 위치는 pan_joint 10 + 9 = 19cm -->
<material name="red">
<color rgba="0 0 1 1"/>
</material>
</visual>
<collision>
<geometry>
<cylinder length="0.4" radius="0.06"/>
</geometry>
<origin rpy="0 0 0" xyz="0 0 0.09"/>
</collision>
<inertial>
<mass value="1"/>
<inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0"/>
</inertial>
</link>
<!-- tilt joint -->
<joint name="tilt_joint" type="revolute">
<parent link="pan_link"/>
<child link="tilt_link"/>
<origin xyz="0 0 0.2"/> <!-- joint위치는 pan_joint 10 + 20 = 30cm -->
<axis xyz="0 1 0"/>
<limit effort="300" velocity="0.1" lower="-4.71239" upper="-1.570796"/> <!-- -270도 ~ -90도 == 90 ~ 90 -->
<dynamics damping="50" friction="1"/>
</joint>
<!-- tilt link -->
<link name="tilt_link">
<visual>
<geometry>
<!-- 원판 모양의 tilt link, 높이 40cm, 반지름 4cm 의 원통-->
<cylinder length="0.4" radius="0.04"/>
</geometry>
<origin rpy="0 1.570796 0" xyz="0 0 0"/> <!-- 실린더 중앙점 위치는 tilt_joint 30 + 0 = 30cm, 가로로 되어 있기 때문에 0 -->
<material name="green">
<color rgba="1 0 0 1"/>
</material>
</visual>
<collision>
<geometry>
<cylinder length="0.4" radius="0.06"/>
</geometry>
<origin rpy="0 1.570796 0" xyz="0 0 0"/>
</collision>
<inertial>
<mass value="1"/>
<inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0"/>
</inertial>
</link>
- pan_tilt_urdf.launch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<launch>
<arg name="model" />
<param name="robot_description" textfile="$(find ex_urdf)/urdf/pan_tilt.urdf" />
<!-- setting gui parameter to true for display joint slider -->
<param name="use_gui" value="true" />
<!-- starting joint state publisher node which will publish the joint values -->
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
<!-- starting robot state publish which will publish tf -->
<node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
<!-- Launch visualization in rviz -->
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find ex_urdf)/urdf.rviz" required="True" />
</launch>
실행
1
2
3
4
5
6
7
8
$ cm
$ cd src/ex_urdf/urdf
작성된 urdf 파일에 문법적인 오류가 있는지 확인해주는 코드
$ check_urdf pan_tilt.urdf
link와 joint 관계도를 pdf 파일로 만들어줌
$ urdf_to_graphiz pan_tilt.urdf
1
2
패키지 설치
$ sudo apt install ros-kinetic-joint-state-publisher-gui
이 패키지는 urdf 파일로 모델링된 로봇의 joint부분을 움직이기 위한 윈도우 기반의 GUI 도구이다.
1
2
실행
$ roslaunch ex_urdf view_pan_tilt_urdf.launch
그러나 실행해도 아무 표시가 되지 않는다. 이유는 rviz설정이 아직 안된 것이다. add를 눌러 robotmodel을 눌러 추가하고, fixed frame에 map이 아닌 base_link를 넣어야 한다.
모델이 나오면 마우스를 통해 회전, 이동할 수 있다. 실행하고나면 그리드화면 이외에 위의 publisher_gui 창이 하나 더 나올 것이다. 이를 사용하여 joint를 움직일 수 있다.
또, 중요한 것은 종료할 때 save를 해야 원래 불러오려던 rviz파일안에 저장이 되는 것이다. 이를 저장하면 ex_urdf 폴더에 urdf.rviz 파일이 생성될 것이다.