Study/[ROS] URDF

URDF for Robot Modeling(1. Building the Visual Robot Model with URDF)

soohwan_justin 2021. 9. 2. 16:13

이번 포스트는 https://app.theconstructsim.com/의 URDF for Robot Modeling course를 참조하였습니다.

 

 

 

이번 course에서는 가상의 시각 모델을 만드는 법에 대해 알아봅니다. 만약 우리가 실제 로봇을 갖고 있고, ROS 기반의 시스템을 사용하고 싶다면, 우리는 로봇이 시각적으로 어떻게 생겼는지, 각각의 센서는 로봇의 어디에 위치해 있는지에 대한 virtual description이 필요합니다.

 

Create your first URDF Model 

이번 단계에서 해볼 것은 다음과 같습니다.

  • URDF creation tolls를 사용하는 방법을 알고, 로봇 모델을 만들어보기
  • 우리가 사용하려고 하는 로봇의 morphology에 대해 알기
  • 올바른 format의 3D models를 얻기
  • link와 joint structure를 생성하기
  • joint의 움직임을 테스트하기 

 

 

1. Learn how to use the URDF creation tools and the creation procedure

 

 

먼저, 우리가 만들 각각의 로봇에 대해 ROS 패키지를 생성합니다. mira 라는 이름의 로봇을 만들 것이므로, "my_mira_description"이라는 이름의 패키지를 만듭니다. 

 

$ cd ~/catkin_ws/src

$ catkin_create_pkg my_mira_description rospy rviz controller_manager gazebo_ros joint_state_publisher robot_state_publisher

 

위와 같이 패키지를 생성하면, 우리는 다음과 같은 디렉토리가 필요합니다. 

  • launch
  • models
  • rviz_config
  • config
  • urdf
  • worlds

 

따라서, 다음과 같이 디렉토리를 만들어줍니다.

 

$ cd ~/catkin_ws/src/my_mira_description

$ mkdir launch models rviz_config config urdf worlds

 

이제, urdf 디렉토리에 다음과 같이 파일을 만듭니다.

 

$ cd ~/catkin_ws/src/my_mira_description

$ gedit mira_simple.urdf

<?xml version="1.0"?>
<robot name="mira">
    <link name="base_link">
        <visual>
        <origin rpy="0 0 0" xyz="0 0 0"/>
        <geometry>
            <cylinder radius="0.06" length="0.09"/>
        </geometry>
        </visual>
    </link>
 
    <link name="roll_M1_link">
        <visual>
            <origin rpy="0 0 0" xyz="0 0 0"/>
            <geometry>
                <cylinder radius="0.06" length="0.09"/>
            </geometry>
        </visual>
    </link>
 
    <joint name="roll_joint" type="revolute">
        <parent link="base_link"/>
        <child link="roll_M1_link"/>
        <origin xyz="0.0023 0 -0.0005" rpy="0 0 0"/>
        <limit lower="-0.2" upper="0.2" effort="0.1" velocity="0.005"/>
        <axis xyz="1 0 0"/>
    </joint>
 
</robot>

 

1. URDF의 모든 측정값은 국제 단위계를 사용합니다. 길이는 미터, 각도는 라디안, 무게는 킬로그램입니다.

2. box, cylinder, sphere 이렇게 3개의 기하학적 형상을 사용할 수 있습니다. 각 형상의 description은 다음과 같습니다.

<cylinder radius="0.06" length="0.09"/>
<box size="0.0005 0.0005 0.0005"/> 
<sphere radius="0.06"/>

 

2. Links and Joints

 

mira_simple.urdf에서는 joint에 의해 연결된 2개의 cylinders가 있습니다. joints는 모터같이 움직이거나 회전하는 로봇의 요소를 말합니다. 즉, 로봇의 관절입니다.

 

joint에서 정의되는 주요 요소들은 다음과 같습니다.

 

  • Type : revolute, continuous, prismatic, fixed, floating, plannar가 있습니다. 이들은 로봇이 물리적으로 어떻게 움직이느냐에 따라 결정됩니다. 자세한 내용은 ROS wiki를 참조하세요
  • Parent and Child : 연결할 link들을 의미합니다
  • Origin : 모든 좌표값 및 rpy는 Parent axis를 reference frame으로 해서 나타냅니다. Child link는 joint의 origin에 대한 좌표로 정의됩니다.
  • Limit : joint의 최대 및 최소값을 설정합니다.
  • Axis : Child link가 회전할 때, 그 축을 설정해줍니다. fixed joint같이 회전하지  않는 축은 이 태그를 사용하지 않습니다. 이는 revolute joints의 회전 축, prismatic joints의 translation 축, planar joints의 법선입니다.

 

3. See the URDF

 

이제 launch 디렉토리에 urdf_visualize.launch 파일을 만들고, 위의 결과를 확인해보겠습니다.

 

$ cd ~/catkin_ws/src/my_mira_description/launch

 

urdf_visualize.launch

<launch>
 
  <!-- USE: roslaunch my_mira_description urdf_visualize.launch model:='$(find myrobot_package)/urdf/myrobot.urdf' -->
  <arg name="model" default=""/>
 
 
  <param name="robot_description" command="cat $(arg model)" />
 
  <!-- send fake joint values -->
  <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher">
    <param name="use_gui" value="TRUE"/>
  </node>
 
 
  <!-- Combine joint values -->
  <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher"/>
 
  <!-- Show in Rviz   -->
  <!--<node name="rviz" pkg="rviz" type="rviz" args="-d $(find my_mira_description)/rviz_config/urdf.rviz"/>-->
  <node name="rviz" pkg="rviz" type="rviz" args=""/>
 
</launch>

 

<param name="robot_description" command="cat $(arg model)" />

robot_description이라고 불리는 파라미터 서버 변수를 호출하는 URDF 파일을 불러옵니다. 만약 둘 이상의 로봇을 불러온다면, robot1_description, robot2_description 이런 식으로 다른 변수들을 사용하여 불러올 것입니다.

 

<!-- send fake joint values -->
  <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher">
    <param name="use_gui" value="TRUE"/>
  </node>
 
  <!-- Combine joint values -->
  <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher"/>

 

joint_state_publisher와 robot_state_publisher를 실행합니다. 이 node들은 로봇의 links와 joints의 URDF의 TFs를 publish합니다.

 

<!-- Show in Rviz   -->
  <!--<node name="rviz" pkg="rviz" type="rviz" args="-d $(find my_mira_description)/rviz_config/urdf.rviz"/>-->
  <node name="rviz" pkg="rviz" type="rviz" args=""/>

 

RViz를 실행합니다. 첫 실행 후, rviz_config 디렉토리에 rviz config를 저장해두면, 다음 실행부터는 플러그인이 추가된 상태를 그대로 불러올 수 있습니다.

 

RViz실행 후, 아래와 같이 RobotMode과 TF 플러그인을 추가해봅니다. 

 

 

그 후, File - Save Config를 클릭하여 rviz_config 디렉토리에 저장합니다. 

 

그리고, RViz 말고도 스크롤이 있는 창을 볼 수 있는데, 저 창은 JointStatePublisher Gui입니다. 해당 스크롤을 움직여서 joint의 값을 조절할 수 있습니다. 이는 joints가 URDF에서 제대로 설정되었는지 확인하기 위해 필수적입니다. 또한, joints의 limits가 제대로 정해졌는지도 확인할 수 있습니다.

 

Link-Joint structure는 urdf_to_graphiz tool을 사용하여 확인할 수 있습니다.

 

$ roscd my_mira_description/urdf

$ urdf_to_graphiz mira_simple.urdf

 

 


연습 1.

 

다음과 같이 URDF 파일을 수정해봅니다.

 

  • 기하학적 형태 바꾸기
  • link 안의 다른 link가 보일 수 있는지 확인하기 위해 크기를 조절해보기
  • 다른 links의 위치와 방향을 바꾸기
  • Y축 또는 Z축을 기준으로 회전하도록 축을 바꿔보기
  • continuous 타입 joint로 바꿔보기. 이 경우에는 각도의 limits는 없지만, 속도 limits가 있습니다.
  • base_link 색을 주황색으로 바꾸고, roll_M1_link를 초록색으로 바꾸기(URDF는 rgba를 사용하며, 0~255를 0~1로 스케일한 값을 사용합니다)

 

 

 

다음과 같이 수정 시, 기하학적 모양을 바꿀 수 있으며, 다른 링크도 확인이 가능합니다.

    <link name="base_link">
        <visual>
        <origin rpy="0 0 0" xyz="0 0 0"/>
        <geometry>
            <box size="0.4 0.05 0.03"/>
        </geometry>
        </visual>
    </link>

 

다음과 같이 수정 시, 좌표 및 방향을 수정할 수 있습니다.

        <visual>
            <origin rpy="0 1.57 0" xyz="-0.215 0 0"/>
            <geometry>
                <box size="0.2 0.05 0.03" />
            </geometry>
        </visual>
    </link></pre>

 

 

다음과 같이 수정 시, 회전축을 바꿀 수 있습니다.

    <link name="roll_M1_link">
        <visual>
            <origin rpy="0 1.57 0" xyz="0 0.05 0"/>
            <geometry>
                <box size="0.2 0.05 0.03" />
            </geometry>
        </visual>
    </link>
 
    <joint name="roll_joint" type="revolute">
        <parent link="base_link"/>
        <child link="roll_M1_link"/>
        <origin xyz="-0.2 0 0" rpy="0 0 0"/>
        <limit lower="-3.14" upper="3.14" effort="0.0" velocity="0.005"/>
        <axis xyz="0 1 0"/>
    </joint>    <link name="roll_M1_link">
        <visual>
            <origin rpy="0 1.57 0" xyz="0 0.05 0"/>
            <geometry>
                <box size="0.2 0.05 0.03" />
            </geometry>
        </visual>
    </link>
 
    <joint name="roll_joint" type="revolute">
        <parent link="base_link"/>
        <child link="roll_M1_link"/>
        <origin xyz="-0.2 0 0" rpy="0 0 0"/>
        <limit lower="-3.14" upper="3.14" effort="0.0" velocity="0.005"/>
        <axis xyz="0 1 0"/>
    </joint>

 

다음과 같이 link의 색을 바꿀 수 있습니다.

    <material name="orange">
        <color rgba="0.99 0.52 0.043 1"/>
    </material>
 
    <material name="green">
        <color rgba="0 1 0 1"/>
    </material>
 
    <link name="base_link">
        <visual>
        <origin rpy="0 0 0" xyz="0 0 0"/>
        <geometry>
            <box size="0.4 0.05 0.03"/>
        </geometry>
        <material name="orange"/>
        </visual>
    </link>
 
    <link name="roll_M1_link">
        <visual>
            <origin rpy="0 1.57 0" xyz="0 0.05 0"/>
            <geometry>
                <box size="0.2 0.05 0.03" />
            </geometry>
            <material name="green"/>
        </visual>
    </link>

 

- 연습 1. 끝

 


 

4. Learn About the Morphology of your Robot

 

URDF를 만들 때 가장 중요한 단계는 실제 로봇이 어떻게 움직이는지 아는 것입니다. 우리는 어떤 타입의 joint를 갖고있고, 각 부분들이 어떻게 연결될지를 결정해야 합니다. 시뮬레이션에서는 단순화해서 나타내기 때문에 실제 물리적 제한이나 로봇이 어떻게 동작하는지를 항상 정확하게 따라할 필요는 없습니다.

 

Mira Robot의 경우를 보겠습니다.

 

먼저 해야할 것은, 이 로봇이 어떻게 움직이는지 보는 것입니다. YouTube 영상을 확인해보세요.

 

Mira의 구조는다음과 같습니다.

 

https://app.theconstructsim.com/

 

위 구조를 보니, 우리는 다음과 같은 links가 필요한 것 같습니다.

 

  • Base_link
  • Head_link
  • Left_eye_link, Right_eye_link
  • Camera_link
  • RPY_System_link

 

이제, URDF파일로 위 로봇을 만들어볼 것인데, 위에서 말했듯이 3개의 기하학적 형상만 가능하기 때문에, 이들을 사용하여 links를 나타내 보세요

 


연습 2.

 

다음 조건들을 사용하여 URDF파일을 만들어보세요.

 

  • Joints는 다음과 같이 정의합니다

1. roll_joint(base_link와 roll_M1_link를 연결)

2. pitch_joint(roll_M1_link와 pitch_M2_link를 연결)

3. yaw_joint(pitch_M2_link와 yaw_M3_link를 연결)

4. base_head_joint(yaw_M3_link와 head_link를 연결)

5. head_lefteye_joint(head_link와 left_eye_link를 연결)

6. head_righteye_joint(head_link와 right_eye_link를 연결)

7. head_camera_joint(head_link와 camera_link를 연결)

 

  • Joint의 타입을 결정하기 위해, 이들이 움직여야할지 또는 고정되어야할지, 회전 각도에 제한을 둬야할 것인지 또는 그러지 않아도 될 것인지를 생각해보세요. joint의 위치 및 rpy는 최종 코드를 참고하세요 

 

  • links의 형태는 다음과 같이 정의합니다

1. base_link --> cylinder radius="0.06" length="0.09"
2. roll_M1_link --> cylinder length="0.005" radius="0.01"
3. pitch_M2_link --> cylinder length="0.005" radius="0.01"
4. yaw_M3_link --> cylinder length="0.005" radius="0.01"
5. head_link --> sphere radius="0.06"
6. left_eye_link --> cylinder radius="0.00525" length="0.00525"
7. right_eye_link --> cylinder radius="0.00525" length="0.00525"
8. camera_link --> box size="0.0005 0.0005 0.0005"

 

  • links의 색은 다음을 참고하세요
    <material name="blue">
        <color rgba="0 0 0.8 1"/>
    </material>
    <material name="red">
        <color rgba="0.8 0 0 1"/>
    </material>
    <material name="green">
        <color rgba="0 0.8 0 1"/>
    </material>
    <material name="grey">
        <color rgba="0.75 0.75 0.75 1"/>
    </material>
    <material name="white">
        <color rgba="1.0 1.0 1.0 1"/>
    </material>
    <material name="black">
        <color rgba="0 0 0 1"/>
    </material>

 

최종 코드는 다음과 같습니다.

<?xml version="1.0"?>
<robot name="mira">
 
    <material name="blue">
        <color rgba="0 0 0.8 1"/>
    </material>
    <material name="red">
        <color rgba="0.8 0 0 1"/>
    </material>
    <material name="green">
        <color rgba="0 0.8 0 1"/>
    </material>
    <material name="grey">
        <color rgba="0.75 0.75 0.75 1"/>
    </material>
    <material name="white">
        <color rgba="1.0 1.0 1.0 1"/>
    </material>
    <material name="black">
        <color rgba="0 0 0 1"/>
    </material>
 
 <!-- * * * Link Definitions * * * -->
    <link name="base_link">
 
        <visual>
            <origin rpy="0.0 0 0" xyz="0 0 0"/>
            <geometry>
                <cylinder radius="0.06" length="0.09"/>
            </geometry>
            <material name="grey"/>
        </visual>
 </link>
 
 
 
    <link name="roll_M1_link">
 
        <visual>
            <origin rpy="0 0 0" xyz="0 0 0"/>
            <geometry>
                <cylinder length="0.005" radius="0.01"/>
            </geometry>
            <material name="red"/>
        </visual>
    </link>
 
    <joint name="roll_joint" type="revolute">
     <parent link="base_link"/>
     <child link="roll_M1_link"/>
        <origin xyz="0.0023 0 -0.0005" rpy="0 0 0"/>
        <limit lower="-0.2" upper="0.2" effort="0.1" velocity="0.005"/>
        <axis xyz="1 0 0"/>
 </joint>
 
 
 
    <link name="pitch_M2_link">
 
        <visual>
            <origin rpy="0 0 0" xyz="0 0 0"/>
            <geometry>
                <cylinder length="0.005" radius="0.01"/>
            </geometry>
            <material name="green"/>
        </visual>
    </link>
 
 
    <joint name="pitch_joint" type="revolute">
     <parent link="roll_M1_link"/>
     <child link="pitch_M2_link"/>
     <origin xyz="0 0 0" rpy="0 -1.5708 0"/>
        <limit lower="0" upper="0.44" effort="0.1" velocity="0.005"/>
        <axis xyz="0 1 0"/>
 </joint>
 
 
    <link name="yaw_M3_link">
 
        <visual>
            <origin rpy="0 0 0" xyz="0 0 0"/>
            <geometry>
                <cylinder length="0.005" radius="0.01"/>
            </geometry>
            <material name="blue"/>
        </visual>
    </link>
 
    <joint name="yaw_joint" type="continuous">
     <parent link="pitch_M2_link"/>
     <child link="yaw_M3_link"/>
        <origin xyz="0.01 0 0" rpy="0 1.5708 0"/>
        <limit effort="0.1" velocity="0.01"/>
        <axis xyz="0 0 1"/>
 </joint>
 
 
    <link name="head_link">
 
  <visual>
            <origin rpy="0.0 0 0" xyz="0 0 0"/>
            <geometry>
                <sphere radius="0.06"/>
            </geometry>
            <material name="white"/>
        </visual>
 </link>
 
 
    <joint name="base_head_joint" type="fixed">
     <parent link="yaw_M3_link"/>
     <child link="head_link"/>
     <origin xyz="0 0 0.06" rpy="0 0 0"/>
 </joint>
 
    <link name="left_eye_link">
 
  <visual>
            <origin rpy="0.0 0 0" xyz="0 0 0"/>
            <geometry>
                <cylinder radius="0.00525" length="0.00525"/>
            </geometry>
            <material name="black"/>
        </visual>
 </link>
 
    <link name="right_eye_link">
 
  <visual>
            <origin rpy="0.0 0 0" xyz="0 0 0"/>
            <geometry>
                <cylinder radius="0.00525" length="0.00525"/>
            </geometry>
            <material name="black"/>
        </visual>
 </link>
 
    <joint name="head_lefteye_joint" type="fixed">
        <parent link="head_link"/>
        <child link="left_eye_link"/>
        <origin xyz="0.0095 0.057 0.0085" rpy="-1.5708 0 0"/>
    </joint>
 
    <joint name="head_righteye_joint" type="fixed">
        <parent link="head_link"/>
        <child link="right_eye_link"/>
        <origin xyz="-0.0095 0.057 0.0085" rpy="-1.5708 0 0"/>
    </joint>
 
    <link name="camera_link">
  <visual>
            <origin rpy="0.0 0 0" xyz="0 0 0"/>
            <geometry>
                <box size="0.0005 0.0005 0.0005"/>
            </geometry>
            <material name="green"/>
        </visual>
 </link>
 
 
    <joint name="head_camera_joint" type="fixed">
        <parent link="head_link"/>
        <child link="camera_link"/>
        <origin xyz="0 0.057 0.0255" rpy="0 0 0"/>
    </joint>
 
 
</robot>

 

RViz에서 확인하면 다음과 같습니다. TF의 글자가 너무 커서 links가 잘 보이지 않는데, Marker Scale을 0.1로 줄여보세요.

'Study > [ROS] URDF' 카테고리의 다른 글

ROS URDF 3D 모델 불러오기  (3) 2021.09.02