Home [데브코스] 4주차 - ROS 3d modeling of Car based on urdf
Post
Cancel
Preview Image

[데브코스] 4주차 - ROS 3d modeling of Car based on urdf


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의 동작 표현
      1. fixed : 고정
      2. revolute : 작동 범위 제한
      3. continuous : 연속 회전


예시

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에서 회전막대 모델 시각화하기

  1. URDF 파일(xml 형식)로 회전막대 모델링
  2. ROS 패키지 생성 : 패키지 생성, 패키지 이름은 ex_urdf
  3. /urdf 폴더 생성 : .urdf파일 만들기
  4. /launch 폴더 생성 : .launch파일 만들기
  5. 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
    
  • 서브 폴더 생성
    1. /urdf 폴더 생성
    2. pan_tilt.urdf 파일 작성
    3. /launch 폴더 생성
    4. 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 파일이 생성될 것이다.

참고 자료

This post is licensed under CC BY 4.0 by the author.