ROS2 URDF(3)

2024. 9. 30. 17:06ROS2/URDF

오늘은 레인보우 로보틱스의 로봇팔인 rb10-1300 xacro파일을 분석해보도록 하겠다.

 

먼저 레인보우 로보틱스 깃허브에 들어가서 ros2 버전 프로젝트를 찾아줬다.

https://github.com/RainbowRobotics/rbpodo_ros2

 

GitHub - RainbowRobotics/rbpodo_ros2: ROS 2 package for Rainbow Robotics' cobots

ROS 2 package for Rainbow Robotics' cobots. Contribute to RainbowRobotics/rbpodo_ros2 development by creating an account on GitHub.

github.com

 

여기서 내가 원하는 모델인 rb10-1300 내부 문서를 열어줬다.

 

rb10_1300e.urdf.xacro

<?xml version='1.0' encoding='utf-8'?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="rb10_1300e">

  <xacro:include filename="$(find rbpodo_description)/robots/rb_6dof.xacro" />
  <xacro:include filename="$(find rbpodo_description)/robots/rb_6dof.ros2_control.xacro" />

  <xacro:arg name="prefix" default="" />
  <xacro:arg name="robot_ip" default="10.0.2.7"/>
  <xacro:arg name="cb_simulation" default="true"/>
  <xacro:arg name="use_fake_hardware" default="true"/>
  <xacro:arg name="fake_sensor_commands" default="false"/>

  <!-- torque_constant = actual_torque_constant * gear_ratio -->
  <xacro:property name="base_tc" value="${1}" />
  <xacro:property name="shoulder_tc" value="${1}" />
  <xacro:property name="elbow_tc" value="${1}" />
  <xacro:property name="wrist1_tc" value="${1}" />
  <xacro:property name="wrist2_tc" value="${1}" />
  <xacro:property name="wrist3_tc" value="${1}" />

  <xacro:rb_6dof model_id="rb10_1300e" prefix="$(arg prefix)" tcp_name="tcp" tcp_xyz="0 -0.1153 0" tcp_rpy="0 0 0" />
  <xacro:rb_6dof_ros2_control prefix="$(arg prefix)" robot_ip="$(arg robot_ip)" cb_simulation="$(arg cb_simulation)" use_fake_hardware="$(arg use_fake_hardware)" fake_sensor_commands="$(arg fake_sensor_commands)" torque_constants="${[base_tc, shoulder_tc, elbow_tc, wrist1_tc, wrist2_tc, wrist3_tc]}" />

</robot>

 

당장에 나는 모델이 필요한 것이기 때문에 컨트롤은 치워두고 robots/rb_6dof.xacro 부분을 보면 이 파일은 이름만 전달해주고 6축로봇 파일을 따로 만들어 놓은 것을 알 수 있었다.

 

rb_6dof.xacro

<?xml version='1.0' encoding='utf-8'?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro">

  <xacro:macro name="link" params="name model_id:=^ has_inertial:=true">
    <xacro:property name="links_props_file" value="$(find rbpodo_description)/robots/${model_id}/link.yaml" />
    <xacro:property name="links_props" value="${xacro.load_yaml(links_props_file)}" />

    <link name="${name}">
      <visual>
        <geometry>
          <mesh filename="package://rbpodo_description/meshes/${model_id}/visual/${name}.dae" />
        </geometry>
      </visual>

      <collision>
        <geometry>
          <mesh filename="package://rbpodo_description/meshes/${model_id}/collision/${name}.stl" />
        </geometry>
      </collision>

      <xacro:if value="${has_inertial}">
        <!-- Check whether this property is available or not -->
        <xacro:property name="props" value="${links_props[name]}" />
        <xacro:property name="inertial" value="${props.inertial}" />
        <inertial>
          <origin rpy="${inertial.origin.rpy}" xyz="${inertial.origin.xyz}" />
          <mass value="${inertial.mass}" />
          <xacro:property name="I" value="${inertial.inertia}" />
          <inertia ixx="${I.xx}" ixy="${I.xy}" ixz="${I.xz}" iyy="${I.yy}" iyz="${I.yz}" izz="${I.zz}" />
        </inertial>
      </xacro:if>
    </link>
  </xacro:macro>

  <xacro:macro name="joint" params="name model_id:=^">
    <xacro:property name="joints_props_file" value="$(find rbpodo_description)/robots/${model_id}/joint.yaml" />
    <xacro:property name="joints_props" value="${xacro.load_yaml(joints_props_file)}" />
    <!-- Check whether name is in joints_props or not -->
    <xacro:property name="props" value="${joints_props[name]}" />

    <joint name="${name}" type="revolute">
      <origin xyz="${props.origin.xyz}" rpy="${props.origin.rpy}" />
      <parent link="${props.parent}" />
      <child link="${props.child}" />
      <axis xyz="${props.axis.xyz}" />

      <xacro:property name="limit" value="${props.limit}" />
      <limit lower="${limit.lower}" upper="${limit.upper}" effort="${limit.effort}" velocity="${limit.velocity}" />
    </joint>
  </xacro:macro>

  <xacro:macro name="rb_6dof" params="model_id prefix='' tcp_name='tcp' tcp_xyz='0 0 0' tcp_rpy='0 0 0'">
    <xacro:link name="${prefix}link0" has_inertial="false" />
    <xacro:link name="${prefix}link1" />
    <xacro:link name="${prefix}link2" />
    <xacro:link name="${prefix}link3" />
    <xacro:link name="${prefix}link4" />
    <xacro:link name="${prefix}link5" />
    <xacro:link name="${prefix}link6" />
    <link name="${prefix}${tcp_name}" />

    <xacro:joint name="${prefix}base" />
    <xacro:joint name="${prefix}shoulder" />
    <xacro:joint name="${prefix}elbow" />
    <xacro:joint name="${prefix}wrist1" />
    <xacro:joint name="${prefix}wrist2" />
    <xacro:joint name="${prefix}wrist3" />
    <joint name="${prefix}${tcp_name}_joint" type="fixed">
      <origin xyz="${tcp_xyz}" rpy="${tcp_rpy}" />
      <parent link="${prefix}link6" />
      <child link="${prefix}${tcp_name}" />
    </joint>

  </xacro:macro>

</robot>

 

그러나 이 파일도 마찬가지로 여기서 수치를 정하는 것이 아니라 각 모델마다 yaml 파일을 만들어 둬서 거기서 수치를 가져오는 식이었다.

그리고 visual, collision 설정에 필요한 dae, stl파일도 각 폴더에서 가져오는 것을 알 수 있었다. 이때까진 몰랐다 이게 날 힘들게 할줄

 

rb10_1300의 link와 joint 정보가 들어있는 yaml 파일을 열어 수치를 확인하고 xacro 형식의 하나의 파일로 만들었다.

 

rb10_1300.xacro

<?xml version="1.0"?>
<robot xmlns:xacro="http://ros.org/wiki/xacro" name="rb10_1300e">

  <link name="link0">
      <visual>
        <geometry>
          <mesh filename="file://$(find urdf_tutorial)/visual/link0.dae"/>
        </geometry>
      </visual>
      <collision>
        <geometry>
          <mesh filename="file://$(find urdf_tutorial)/collision/link0.stl"/>
        </geometry>
      </collision>
    </link>
    <link name="link1">
      <visual>
        <geometry>
          <mesh filename="file://$(find urdf_tutorial)/visual/link1.dae"/>
        </geometry>
      </visual>
      <collision>
        <geometry>
          <mesh filename="file://$(find urdf_tutorial)/collision/link1.stl"/>
        </geometry>
      </collision>
      <inertial>
        <origin rpy="0 0 0" xyz="0.000021 -0.007855 -0.042537"/>
        <mass value="8.366"/>
        <inertia ixx="0.027403652" ixy="-5.926e-06" ixz="-1.0119e-05" iyy="0.027770573" iyz="0.003030512" izz="0.026140211"/>
      </inertial>
    </link>
    <link name="link2">
      <visual>
        <geometry>
          <mesh filename="file://$(find urdf_tutorial)/visual/link2.dae"/>
        </geometry>
      </visual>
      <collision>
        <geometry>
          <mesh filename="file://$(find urdf_tutorial)/collision/link2.stl"/>
        </geometry>
      </collision>
      <inertial>
        <origin rpy="0 0 0" xyz="-0.000013 -0.155462 0.225241"/>
        <mass value="15.61"/>
        <inertia ixx="1.140650644" ixy="-1.3042e-05" ixz="-6.7084e-05" iyy="1.134398623" iyz="0.024507884" izz="0.050849068"/>
      </inertial>
    </link>
    <link name="link3">
      <visual>
        <geometry>
          <mesh filename="file://$(find urdf_tutorial)/visual/link3.dae"/>
        </geometry>
      </visual>
      <collision>
        <geometry>
          <mesh filename="file://$(find urdf_tutorial)/collision/link3.stl"/>
        </geometry>
      </collision>
      <inertial>
        <origin rpy="0 0 0" xyz="-0.000048 -0.013885 0.325013"/>
        <mass value="5.69"/>
        <inertia ixx="0.312033029" ixy="9.298e-06" ixz="1.169e-05" iyy="0.311287646" iyz="0.005331552" izz="0.011397824"/>
      </inertial>
    </link>
    <link name="link4">
      <visual>
        <geometry>
          <mesh filename="file://$(find urdf_tutorial)/visual/link4.dae"/>
        </geometry>
      </visual>
      <collision>
        <geometry>
          <mesh filename="file://$(find urdf_tutorial)/collision/link4.stl"/>
        </geometry>
      </collision>
      <inertial>
        <origin rpy="0 0 0" xyz="0.000093 -0.113949 0.026461"/>
        <mass value="2.062"/>
        <inertia ixx="0.0027111" ixy="-8.022e-06" ixz="1.1208e-05" iyy="0.002715407" iyz="0.000144243" izz="0.002157043"/>
      </inertial>
    </link>
    <link name="link5">
      <visual>
        <geometry>
          <mesh filename="file://$(find urdf_tutorial)/visual/link5.dae"/>
        </geometry>
      </visual>
      <collision>
        <geometry>
          <mesh filename="file://$(find urdf_tutorial)/collision/link5.stl"/>
        </geometry>
      </collision>
      <inertial>
        <origin rpy="0 0 0" xyz="-0.000093 -0.026434 -0.003233"/>
        <mass value="2.061"/>
        <inertia ixx="0.002706437" ixy="1.1205e-05" ixz="-8.016e-06" iyy="0.002153592" iyz="0.000141528" izz="0.002712272"/>
      </inertial>
    </link>
    <link name="link6">
      <visual>
        <geometry>
          <mesh filename="file://$(find urdf_tutorial)/visual/link6.dae"/>
        </geometry>
      </visual>
      <collision>
        <geometry>
          <mesh filename="file://$(find urdf_tutorial)/collision/link6.stl"/>
        </geometry>
      </collision>
      <inertial>
        <origin rpy="0 0 0" xyz="-0.000210 -0.092540 -0.000292"/>
        <mass value="0.406"/>
        <inertia ixx="0.000345314" ixy="5.73e-07" ixz="6.61e-07" iyy="0.000532873" iyz="-5.4e-08" izz="0.000340021"/>
      </inertial>
    </link>
    <link name="tcp"/>
    <joint name="base" type="revolute">
      <origin rpy="0 0 0" xyz="0 0 0.197"/>
      <parent link="link0"/>
      <child link="link1"/>
      <axis xyz="0 0 1"/>
      <limit effort="10" lower="-3.14" upper="3.14" velocity="3.14"/>
    </joint>
    <joint name="shoulder" type="revolute">
      <origin rpy="0 0 0" xyz="0 -0.1875 0"/>
      <parent link="link1"/>
      <child link="link2"/>
      <axis xyz="0 1 0"/>
      <limit effort="10" lower="-3.14" upper="3.14" velocity="3.14"/>
    </joint>
    <joint name="elbow" type="revolute">
      <origin rpy="0 0 0" xyz="0 0 0.6127"/>
      <parent link="link2"/>
      <child link="link3"/>
      <axis xyz="0 1 0"/>
      <limit effort="10" lower="-3.14" upper="3.14" velocity="3.14"/>
    </joint>
    <joint name="wrist1" type="revolute">
      <origin rpy="0 0 0" xyz="0 0.11715 0.57015"/>
      <parent link="link3"/>
      <child link="link4"/>
      <axis xyz="0 1 0"/>
      <limit effort="10" lower="-3.14" upper="3.14" velocity="3.14"/>
    </joint>
    <joint name="wrist2" type="revolute">
      <origin rpy="0 0 0" xyz="0 -0.11715 0"/>
      <parent link="link4"/>
      <child link="link5"/>
      <axis xyz="0 0 1"/>
      <limit effort="10" lower="-3.14" upper="3.14" velocity="3.14"/>
    </joint>
    <joint name="wrist3" type="revolute">
      <origin rpy="0 0 0" xyz="0 0 0.11715"/>
      <parent link="link5"/>
      <child link="link6"/>
      <axis xyz="0 1 0"/>
      <limit effort="10" lower="-3.14" upper="3.14" velocity="3.14"/>
    </joint>
    <joint name="tcp_joint" type="fixed">
      <origin rpy="0 0 0" xyz="0 -0.1153 0"/>
      <parent link="link6"/>
      <child link="tcp"/>
    </joint>
    
</robot>

 

그 이후 저번에 만들어뒀던 launch파일을 이용해서 실행을 시켜줬다

# Terminal 1
cd ~/ch2_ws
colcon build
source install/setup.bash
ros2 launch urdf_tutorial robot_2.launch.py

# Terminal 2
rviz2

 

여기서 첫 번째 시련이 다가왔다.

 

base link가 존재하지 않는다며 아무것도 뜨지않는 것이다...

그래서 나는 온갖 행동을 다해보다가 문득 며칠 전에 해봤던 것이 떠올라서 tf정보를 주기로 해봤다.

os2 run joint_state_publisher_gui joint_state_publisher_gui

 

 

이걸 해결하고 다 됐다고 생각했으나 예상치 못한 visual, collision에서 문제가 생겼다.

RROR] [1727673598.817999101] [rviz2]: FileNotFoundException: Cannot locate resource /home/mgt/ch2_ws/src/urdf_tutorial/collision/link5.stl in resource group OgreAutodetect. in ResourceGroupManager::openResource at /tmp/binarydeb/ros-foxy-rviz-ogre-vendor-8.2.8/.obj-x86_64-linux-gnu/ogre-v1.12.1-prefix/src/ogre-v1.12.1/OgreMain/src/OgreResourceGroupManager.cpp (line 703)
[ERROR] [1727673598.818134452] [rviz2]: could not load model '/home/mgt/ch2_ws/src/urdf_tutorial/collision/link5.stl' for link 'link5': FileNotFoundException: Cannot locate resource /home/mgt/ch2_ws/src/urdf_tutorial/collision/link5.stl in resource group OgreAutodetect. in ResourceGroupManager::openResource at /tmp/binarydeb/ros-foxy-rviz-ogre-vendor-8.2.8/.obj-x86_64-linux-gnu/ogre-v1.12.1-prefix/src/ogre-v1.12.1/OgreMain/src/OgreResourceGroupManager.cpp (line 703)
[ERROR] [1727673598.818283235] [rviz2]: Error retrieving file [/home/mgt/ch2_ws/src/urdf_tutorial/collision/link5.stl]: 
[ERROR] [1727673598.818421432] [rviz2]: FileNotFoundException: Cannot locate resource /home/mgt/ch2_ws/src/urdf_tutorial/collision/link5.stl in resource group OgreAutodetect. in ResourceGroupManager::openResource at /tmp/binarydeb/ros-foxy-rviz-ogre-vendor-8.2.8/.obj-x86_64-linux-gnu/ogre-v1.12.1-prefix/src/ogre-v1.12.1/OgreMain/src/OgreResourceGroupManager.cpp (line 703)
[ERROR] [1727673598.818554604] [rviz2]: could not load model '/home/mgt/ch2_ws/src/urdf_tutorial/collision/link5.stl' for link 'link5': FileNotFoundException: Cannot locate resource /home/mgt/ch2_ws/src/urdf_tutorial/collision/link5.stl in resource group OgreAutodetect. in ResourceGroupManager::openResource at /tmp/binarydeb/ros-foxy-rviz-ogre-vendor-8.2.8/.obj-x86_64-linux-gnu/ogre-v1.12.1-prefix/src/ogre-v1.12.1/OgreMain/src/OgreResourceGroupManager.cpp (line 703)
[ERROR] [1727673598.819086228] [rviz2]: Could not load resource [/home/mgt/ch2_ws/src/urdf_tutorial/visual/link6.dae]: Unable to open file "/home/mgt/ch2_ws/src/urdf_tutorial/visual/link6.dae".
[ERROR] [1727673598.819308778] [rviz2]: FileNotFoundException: Cannot locate resource /home/mgt/ch2_ws/src/urdf_tutorial/visual/link6.dae in resource group OgreAutodetect. in ResourceGroupManager::openResource at /tmp/binarydeb/ros-foxy-rviz-ogre-vendor-8.2.8/.obj-x86_64-linux-gnu/ogre-v1.12.1-prefix/src/ogre-v1.12.1/OgreMain/src/OgreResourceGroupManager.cpp (line 703)
[ERROR] [1727673598.819448906] [rviz2]: could not load model '/home/mgt/ch2_ws/src/urdf_tutorial/visual/link6.dae' for link 'link6': FileNotFoundException: Cannot locate resource /home/mgt/ch2_ws/src/urdf_tutorial/visual/link6.dae in resource group OgreAutodetect. in ResourceGroupManager::openResource at /tmp/binarydeb/ros-foxy-rviz-ogre-vendor-8.2.8/.obj-x86_64-linux-gnu/ogre-v1.12.1-prefix/src/ogre-v1.12.1/OgreMain/src/OgreResourceGroupManager.cpp (line 703)
[ERROR] [1727673598.819702639] [rviz2]: Could not load resource [/home/mgt/ch2_ws/src/urdf_tutorial/visual/link6.dae]: Unable to open file "/home/mgt/ch2_ws/src/urdf_tutorial/visual/link6.dae".
[ERROR] [1727673598.819938407] [rviz2]: FileNotFoundException: Cannot locate resource /home/mgt/ch2_ws/src/urdf_tutorial/visual/link6.dae in resource group OgreAutodetect. in ResourceGroupManager::openResource at /tmp/binarydeb/ros-foxy-rviz-ogre-vendor-8.2.8/.obj-x86_64-linux-gnu/ogre-v1.12.1-prefix/src/ogre-v1.12.1/OgreMain/src/OgreResourceGroupManager.cpp (line 703)
[ERROR] [1727673598.820097130] [rviz2]: could not load model '/home/mgt/ch2_ws/src/urdf_tutorial/visual/link6.dae' for link 'link6': FileNotFoundException: Cannot locate resource /home/mgt/ch2_ws/src/urdf_tutorial/visual/link6.dae in resource group OgreAutodetect. in ResourceGroupManager::openResource at /tmp/binarydeb/ros-foxy-rviz-ogre-vendor-8.2.8/.obj-x86_64-linux-gnu/ogre-v1.12.1-prefix/src/ogre-v1.12.1/OgreMain/src/OgreResourceGroupManager.cpp (line 703)
[ERROR] [1727673598.820263343] [rviz2]: Error retrieving file [/home/mgt/ch2_ws/src/urdf_tutorial/collision/link6.stl]: 
[ERROR] [1727673598.820403314] [rviz2]: FileNotFoundException: Cannot locate resource /home/mgt/ch2_ws/src/urdf_tutorial/collision/link6.stl in resource group OgreAutodetect. in ResourceGroupManager::openResource at /tmp/binarydeb/ros-foxy-rviz-ogre-vendor-8.2.8/.obj-x86_64-linux-gnu/ogre-v1.12.1-prefix/src/ogre-v1.12.1/OgreMain/src/OgreResourceGroupManager.cpp (line 703)
[ERROR] [1727673598.820538978] [rviz2]: could not load model '/home/mgt/ch2_ws/src/urdf_tutorial/collision/link6.stl' for link 'link6': FileNotFoundException: Cannot locate resource /home/mgt/ch2_ws/src/urdf_tutorial/collision/link6.stl in resource group OgreAutodetect. in ResourceGroupManager::openResource at /tmp/binarydeb/ros-foxy-rviz-ogre-vendor-8.2.8/.obj-x86_64-linux-gnu/ogre-v1.12.1-prefix/src/ogre-v1.12.1/OgreMain/src/OgreResourceGroupManager.cpp (line 703)
[ERROR] [1727673598.820684876] [rviz2]: Error retrieving file [/home/mgt/ch2_ws/src/urdf_tutorial/collision/link6.stl]: 
[ERROR] [1727673598.820821038] [rviz2]: FileNotFoundException: Cannot locate resource /home/mgt/ch2_ws/src/urdf_tutorial/collision/link6.stl in resource group OgreAutodetect. in ResourceGroupManager::openResource at /tmp/binarydeb/ros-foxy-rviz-ogre-vendor-8.2.8/.obj-x86_64-linux-gnu/ogre-v1.12.1-prefix/src/ogre-v1.12.1/OgreMain/src/OgreResourceGroupManager.cpp (line 703)
[ERROR] [1727673598.820954796] [rviz2]: could not load model '/home/mgt/ch2_ws/src/urdf_tutorial/collision/link6.stl' for link 'link6': FileNotFoundException: Cannot locate resource /home/mgt/ch2_ws/src/urdf_tutorial/collision/link6.stl in resource group OgreAutodetect. in ResourceGroupManager::openResource at /tmp/binarydeb/ros-foxy-rviz-ogre-vendor-8.2.8/.obj-x86_64-linux-gnu/ogre-v1.12.1-prefix/src/ogre-v1.12.1/OgreMain/src/OgreResourceGroupManager.cpp (line 703)

 

이런 에러가 빨갛게 주르르륵 나왔는데 간단하게 말하자면 dae, stl파일이 경로에 없다는 소리다.

그래서 경로도 바꿔보고 절대경로도 써보고 파일 바로 옆에도 붙여 보았지만 답이 없었다.

 

gpt와 몇시간 동안 헤매다 결국 ros 사이트의 한 외국인이 올린 해결방법으로 해결하게 되었다.

<mesh filename="package://urdf_tutorial/visual/${visual_file}"/> 이 부분이 문제였는데 이 방식은 ros2방식이었다.

아직도 왜 안되는지는 모르지만

ros1 방식의 file://$(find urdf_tutorial)/visual/link0.dae 이런식으로 바꾸니까 고쳐졌다.

 

이후 gazebo에도 띄워보았으나 왜인지는 모르겠지만

또 뜨지않는다..

'ROS2 > URDF' 카테고리의 다른 글

ROS2 URDF doosan robot arm  (0) 2024.11.08
ROS2 URDF(4)  (0) 2024.10.04
ROS2 6일차(2) URDF  (0) 2024.09.27
ROS2 6일차(1) URDF  (0) 2024.09.27
ROS2 5일차(2) URDF  (0) 2024.09.26