[ROS Projects] – My Robotic Manipulator – #Part 3 – URDF Inertia

[ROS Projects] – My Robotic Manipulator – #Part 3 – URDF Inertia

In this video we are going to insert inertia property to each link of our robotic manipulator. At the end of the video we’ll be able to simulate this robot using Gazebo, due to having complete physic properties defined to the robot.

Step1. Create Project

Let’s start with creating a new project in ROS development studio.

Notice: If you haven’t had an account yet. You can register one here for free.

Open a shell and clone the package from bitbucket repo(https://goo.gl/1Kbt5v). You’ll have to register a bitbucket account to do that.

Since the repo is a simulation, we’ll clone it into the ~/simulation_ws/src folder.

Then the source tree should look similar like this.

Then we type the following command to compile the package.

cd ~/simulation_ws
catkin_make
source devel/setup.bash

Step2. Add physical properties in the URDF

Open the links_joints.xacro file under the urdf folder of the package and add the following tag in the link tag under the m_link_cylinder tag.

      <inertial>
        <mass value="${mass}" />
        <origin rpy="${origin_rpy}" xyz="${origin_xyz}" />
        <inertia ixx="${ixx}" ixy="${ixy}" ixz="${ixz}" iyy="${iyy}" iyz="${iyz}" izz="${izz}" />
      </inertial>

By adding this part, the link can have a more realistic physical behavior in the simulation, you also have to add the parameters for the inertia(ixx ixy ixz iyy iyz izz) in the pramas part.

  <xacro:macro name="m_link_cylinder" params="name origin_xyz origin_rpy radius length mass ixx ixy ixz iyy iyz izz">

We also need a collision tag to define the collision behavior when the robot collides with something in the simulation. We define the collision shape same as the visual shape here.

      <collision>
        <origin rpy="${origin_rpy}" xyz="${origin_xyz}" />
        <geometry>
          <cylinder radius="${radius}" length="${length}" />
        </geometry>
      </collision>

We also add these properties in the m_link_box.

Step3. Set parameter values

Now we have to define all the values for the parameters in the mrm.xacro file under the urdf folder. You can copy and replace the following code into it.

<?xml version="1.0" ?>

<robot name="mrm" xmlns:xacro="http://www.ros.org/wiki/xacro">
  
  <!-- BGN - Include -->
  <xacro:include filename="$(find mrm_description)/urdf/robot_parameters.xacro" />
  <xacro:include filename="$(find mrm_description)/urdf/links_joints.xacro" />
  <!-- END - Include -->
  
  <!-- BGN - Robot description -->
  <m_link_box name="${link_00_name}"
              origin_rpy="0 0 0" origin_xyz="0 0 0"
              mass="1024"
              ixx="170.667" ixy="0" ixz="0"
              iyy="170.667" iyz="0"
              izz="170.667"
              size="1 1 1" />
              
  <m_joint name="${link_00_name}__${link_01_name}" type="revolute"
           axis_xyz="0 0 1"
           origin_rpy="0 0 0" origin_xyz="0 0 0.5"
           parent="base_link" child="link_01" />
           
  <m_link_cylinder name="${link_01_name}"
              origin_rpy="0 0 0" origin_xyz="0 0 0.2"
              mass="157.633"
              ixx="13.235" ixy="0" ixz="0"
              iyy="13.235" iyz="0"
              izz="9.655"
              length="0.4" radius="0.35" />
              
  <m_joint name="${link_01_name}__${link_02_name}" type="revolute"
           axis_xyz="0 1 0"
           origin_rpy="0 0 0" origin_xyz="0 0 0.4"
           parent="link_01" child="link_02" />
           
  <m_link_cylinder name="${link_02_name}"
              origin_rpy="0 0 0" origin_xyz="0 0 0.4"
              mass="57.906"
              ixx="12.679" ixy="0" ixz="0"
              iyy="12.679" iyz="0"
              izz="0.651"
              radius="0.15" length="0.8" />
              
  <m_joint name="${link_02_name}__${link_03_name}" type="revolute"
           axis_xyz="0 1 0"
           origin_rpy="0 0 0" origin_xyz="0 0 0.8"
           parent="link_02" child="link_03" />
           
  <m_link_cylinder name="${link_03_name}"
              origin_rpy="0 0 0" origin_xyz="0 0 0.4"
              mass="57.906"
              ixx="12.679" ixy="0" ixz="0"
              iyy="12.679" iyz="0"
              izz="0.651"
              radius="0.15" length="0.8" />
              
  <m_joint name="${link_03_name}__${link_04_name}" type="revolute"
           axis_xyz="0 1 0"
           origin_rpy="0 0 0" origin_xyz="0 0 0.8"
           parent="link_03" child="link_04" />
           
  <m_link_cylinder name="${link_04_name}"
              origin_rpy="0 0 0" origin_xyz="0 0 0.4"
              mass="57.906"
              ixx="12.679" ixy="0" ixz="0"
              iyy="12.679" iyz="0"
              izz="0.651"
              radius="0.15" length="0.8" />
              
  <m_joint name="${link_04_name}__${link_05_name}" type="revolute"
           axis_xyz="0 0 1"
           origin_rpy="0 0 0" origin_xyz="0 0 0.8"
           parent="link_04" child="link_05" />
           
  <m_link_cylinder name="${link_05_name}"
              origin_rpy="0 0 0" origin_xyz="0 0 0.125"
              mass="18.056"
              ixx="0.479" ixy="0" ixz="0"
              iyy="0.479" iyz="0"
              izz="0.204"
              radius="0.15" length="0.25" />
  <!-- END - Robot description -->
  
</robot>

Step4. Launch the Simulation

Now, let’s open a graphical tool in the tools tab and launch the rviz with the following command.

$ roslaunch mrm_description rviz.launch

Then we start an empty simulation from the simulation tab. Then we create a spawn.launch file under the launch folder with following code.

<?xml version="1.0" encoding="UTF-8"?>
<launch>
    <param name="robot_description" command="$(find xacro)/xacro --inorder '$(find mrm_description)/urdf/mrm.xacro'" />
    
    <arg name="x" default="0"/>
    <arg name="y" default="0"/>
    <arg name="z" default="0.5"/>
    
    <node name="mybot_spawn" pkg="gazebo_ros" type="spawn_model" output="screen"
          args="-urdf -param robot_description -model mrm -x $(arg x) -y $(arg y) -z $(arg z)" />
          
</launch>

To spawn our robot in the simulation world, type the following command

$ roslaunch mrm_description spawn.launch

Now you’ll see the robot is falling down like this(at least in some physically correct way) since we haven’t applied any control yet.

Takeaway Today:

You can define the inertia properties with URDF to have a more realistic simulation behavior.

 

# Links or resources mentioned in the video: 

  • ROS Development Studio: https://goo.gl/zQQohY
  • Material for the video : https://bitbucket.org/theconstructcore/my-robotic-manipulator/src
  • Robot Ignite Academy : https://goo.gl/Qq4b5E
[ROS Projects] Create a Hopper Robot in Gazebo Step-by-Step

[ROS Projects] Create a Hopper Robot in Gazebo Step-by-Step

 

Locomotion is one of the most challenging topics in robotics. Creating the hard-coded algorithms and the kinematics models is not an easy task. Therefore, its no surprise that AI has been used to try and make robots learn how to move by themselves. In this project you will learn step by step, how to create a Monopod robot simulation working in Gazebo and then set up everything to use OpenAI-Gym infrastructure. OpenAI-Gym allows you to separate learning algorithms from the physical/simulated robot, so that you can test different learning algorithms easily. It also allows you to compare your results with other people in the same conditions.

Part 1

In this first video of a new ROS Development Studio video series, you are going to learn step by step

how to create your own hopper simulation, and may be a real version if there is high support to this videos.

You will learn in this video how to create your ROS packages, modify a URDF given by Alexander W. Winkler, https://github.com/leggedrobotics/xpp to give it control and physics and add all the needed sensors like IMU, odometry and contact sensor.

Here are the steps to create the hopper robot as shown in the video:

Step 1
Head to Robot Development Studio and create a new project.
Provide a suitable project name and some useful description.
Open the project (this will take few seconds)
Once the project is loaded run the IDE from the tools menu. Also verify that the initial directory structure should look like following:

.
├────── ai_ws
├────── catkin_ws
│     ├─── build
│     ├─── devel
│     └─── 
├────── notebook_ws
│     ├─── default.ipynb
│     └─── images
└────── simulation_ws
      ├─── build
      ├─── devel
      └─── src

Note that we use simulation_ws to contain all the files related to simulations. Those files not related to simulations will go to catkin_ws (like python scripts, launch files etc)


Step 2
Now we create two catkin packages with names my_legged_robots_description and my_legged_robots_sims. We will add rospy as dependency for both of them.

Start a SHELL from tools menu and navigate to ~simulation_ws/src directory as follows

$ cd simulation_ws/src

Now we create the first catkin package with following command

$ catkin_create_pkg my_legged_robots_description rospy

Then create second catkin_package with the following command

$ catkin_create_pkg my_legged_robots_sims rospy

At this point we should have the following directory structure

.
├────── ai_ws
├────── catkin_ws
│     ├─── build
│     ├─── devel
│     └─── 
├────── notebook_ws
│     ├─── default.ipynb
│     └─── images
└────── simulation_ws
      ├─── build
      ├─── devel
      └─── src
         ├──── CMakeLists.txt 
         ├──── my_legged_robots_description
         │    ├─── CMakeLists.txt
         │    ├─── package.xml
         │    └─── src
         └──── my_legged_robots_sims
              ├─── CMakeLists.txt
              ├─── package.xml
              └─── src

Step 3
Now we need to copy the mesh for the hopper robot from github. Use the following command to clone the github repository

git clone https://github.com/leggedrobotics/xpp.git

Once the cloning is complete, we should have a new directory with name xpp inside the ~simulation_ws/src directory

This new directory contains the mesh models for various robots such as biped, quadruped etc. We only need the mesh for monoped so we will do following

  • copy the meshes folder from ~simulation_ws/src/xpp/robots/xpp_hyq/ to ~simulation_ws/src/my_legged_robots_description/ directory
  • copy the urdf folder from ~simulation_ws/src/xpp/robots/xpp_hyq/ to ~simulation_ws/src/my_legged_robots_sims/ directory
  • delete the files in ~simulation_ws/src/my_legged_robots_sims/urdf/ directory except the file monoped.urdf

Step 4
Lets analyze the urdf file for the monoped.
Open the monoped.urdf file in the IDE. The file contains 4 links and 3 joints. Moreover the links have only visual properties which means we can’t yet simulate it. However we can load it in rviz for display.

For simulation ability we need to define inertia and collision properties into the monoped.urdf file.
We will add these properties to the monoped.urdf file. Now before we make any changes, its a good idea that we create a copy of monoped.urdf with name monoped_controlled.urdf

Here is the monoped_controlled.urdf file content after editing

<robot name="monoped">
    <link name="base">
        <inertial>
            <origin xyz="0 0 0" rpy="0 0 0"/>
            <mass value="0.18" />
            <inertia ixx="0.0002835" ixy="0.0" ixz="0.0" iyy="0.0002835" iyz="0.0" izz="0.000324"/>
        </inertial>
        <collision>
            <origin xyz="0 0 0" rpy="0 0 0"/>
            <geometry>
                <box size="0.20 0.20 0.30"/>
            </geometry>
        </collision>
	    <visual>
	      <geometry>
	        <box size="0.20 0.20 0.30"/>
	      </geometry>
	      <material name="red">
	        <color rgba="1.0 0 0 1.0"/>
	      </material>
	    </visual>        
    </link>
    
    <gazebo reference="base">
        <kp>1000.0</kp>
        <kd>1000.0</kd>
        <mu1>0.5</mu1>
        <mu2>0.5</mu2>
        <material>Gazebo/Red</material>
    </gazebo>
    
    <link name="hipassembly">
        <inertial>
            <origin xyz="0 0 0" rpy="0 0 0"/>
            <mass value="0.18" />
            <inertia ixx="0.0002835" ixy="0.0" ixz="0.0" iyy="0.0002835" iyz="0.0" izz="0.000324"/>
        </inertial>
        <collision>
            <origin rpy="0.0 0.0 0.0" xyz="0.0 0.0 0.0"/>
	      <geometry>
	        <mesh filename="package://my_legged_robots_description/meshes/leg/hipassembly.dae" scale="1 1 1"/>
	      </geometry>
        </collision>
	    <visual>
	      <origin rpy="0.0 0.0 0.0" xyz="0.0 0.0 0.0"/>
	      <geometry>
	        <mesh filename="package://my_legged_robots_description/meshes/leg/hipassembly.dae" scale="1 1 1"/>
	      </geometry>
	      <material name="white"/>
	    </visual>        
    </link>

    <gazebo reference="hipassembly">
        <kp>1000.0</kp>
        <kd>1000.0</kd>
        <mu1>0.5</mu1>
        <mu2>0.5</mu2>
        <material>Gazebo/Blue</material>
    </gazebo>


    <link name="upperleg">
        <inertial>
            <origin xyz="0 0 0" rpy="0 0 0"/>
            <mass value="0.18" />
            <inertia ixx="0.0002835" ixy="0.0" ixz="0.0" iyy="0.0002835" iyz="0.0" izz="0.000324"/>
        </inertial>
        <collision>
            <origin rpy="0.0 0.0 0.0" xyz="0.0 0.0 0.0"/>
	      <geometry>
	        <mesh filename="package://my_legged_robots_description/meshes/leg/upperleg.dae" scale="1 1 1"/>
	      </geometry>
        </collision>
	    <visual>
	      <origin rpy="0.0 0.0 0.0" xyz="0.0 0.0 0.0"/>
	      <geometry>
	        <mesh filename="package://my_legged_robots_description/meshes/leg/upperleg.dae" scale="1 1 1"/>
	      </geometry>
	      <material name="blue"/>
	    </visual>
    </link>

    <gazebo reference="upperleg">
        <kp>1000.0</kp>
        <kd>1000.0</kd>
        <mu1>0.5</mu1>
        <mu2>0.5</mu2>
        <material>Gazebo/Blue</material>
    </gazebo>


    <link name="lowerleg">
        <inertial>
            <origin xyz="0 0 0" rpy="0 0 0"/>
            <mass value="0.18" />
            <inertia ixx="0.0002835" ixy="0.0" ixz="0.0" iyy="0.0002835" iyz="0.0" izz="0.000324"/>
        </inertial>
        <collision>
            <origin rpy="0.0 0.0 0.0" xyz="0.0 0.0 0.0"/>
	      <geometry>
	        <mesh filename="package://my_legged_robots_description/meshes/leg/lowerleg.dae" scale="1 1 1"/>
	      </geometry>
        </collision>
	    <visual>
	      <geometry>
	        <mesh filename="package://my_legged_robots_description/meshes/leg/lowerleg.dae" scale="1 1 1"/>
	      </geometry>
	      <material name="blue"/>
	    </visual>        
    </link>

    <gazebo reference="lowerleg">
        <kp>1000.0</kp>
        <kd>1000.0</kd>
        <mu1>0.5</mu1>
        <mu2>0.5</mu2>
        <material>Gazebo/Blue</material>
    </gazebo>
    
    <link name="lowerleg_contactsensor_link">
 	    <inertial >
            <origin xyz="0 0 0" rpy="0 0 0"/>
            <mass value="0.01" />
            <inertia ixx="1.28e-06" ixy="0.0" ixz="0.0" iyy="1.28e-06" iyz="0.0" izz="1.28e-06"/>
        </inertial>
        <collision>
            <origin xyz="0 0 0" rpy="0 0 0"/>
            <geometry>
                <sphere radius="0.020"/>
            </geometry>
        </collision>
        <visual>
            <origin rpy="0.0 0 0" xyz="0 0 0"/>
            <geometry>
                <sphere radius="0.020"/>
            </geometry>
            <material name="red">
	            <color rgba="1.0 0 0 1.0"/>
	        </material>
        </visual>
	</link>

    <gazebo reference="lowerleg_contactsensor_link">
        <kp>1000.0</kp>
        <kd>1000.0</kd>
        <mu1>10.0</mu1>
        <mu2>10.0</mu2>
        <material>Gazebo/Red</material>
    </gazebo>

    <joint name="lowerleg_contactsensor_link_joint" type="fixed">
        <parent link="lowerleg"/>
        <child link="lowerleg_contactsensor_link"/>
        <origin xyz="0.35 0 0" rpy="0 0 0"/>
    </joint>
    
   
    <joint name="haa_joint" type="revolute">
        <origin xyz="0.0 0.0 -0.15000" rpy="2.0344439357957036 1.5707962290814481 -1.1071487177940917"/>
        <parent link="base"/>
        <child  link="hipassembly"/>
        <limit effort="200" lower="-1.6" upper="1.6" velocity="10.0"/>
        <axis xyz="0 0 1"/>
    </joint>
    <joint name="hfe_joint" type="revolute">
        <origin xyz="0.08000 0.00000 0.00000" rpy="1.5707963705062866 -0.0 0.0"/>
        <parent link="hipassembly"/>
        <child  link="upperleg"/>
        <limit effort="200" lower="-1.6" upper="1.6" velocity="10.0"/>
        <axis xyz="0 0 1"/>
    </joint>
    <joint name="kfe_joint" type="revolute">
        <origin xyz="0.35000 0.00000 0.00000" rpy="0.0 0.0 0.0"/>
        <parent link="upperleg"/>
        <child  link="lowerleg"/>
        <limit effort="200" lower="-1.6" upper="1.6" velocity="10.0"/>
        <axis xyz="0 0 1"/>
    </joint>
    
</robot>

In addition to the inertia and collision tags we have added a few tags.
First is the gazebo tag, this tag is required to simulate the block in gazebo, it contains information about the material hardness (whether the material is easily deformable or not) and friction values (static and dynamic).
The Second tag that was added is a link tag with name lowerleg_contactsensor_link. This link will help us detect the contact with ground in later part of this project.
Another added tag is a joint tag by name lowerleg_contactsensor_link_joint, this combined with previous link tag completes the contact sensor positioning on the robot.

Note : In the above code the values used for various inertia is calculated using inertial_calculator tool ( it is a part of ROS). Moreover, to simplify calculation of inertia of different blocks with different shapes, a bounding box approximation is applied i.e. we compute the inertia with respect to the dimensions of the bounding box. Though such value might not be perfect, it is reasonably good to work with.


Step 5
Now we will simulate this robot.

To do so first we need to create a world file. Create a directory named worlds inside ~simulation_ws/src/my_legged_robots_sims/ directory.

Using the IDE create a file low_gravity.world inside worlds directory. This is our world file. Write the following content to it:

<sdf version="1.4">
<world name="default">
    <include>
        <uri>model://sun</uri>
    </include>
    <gravity>0 0 0.0</gravity>
    <include>
        <uri>model://ground_plane</uri>
    </include>
</world>
</sdf>

In this file the tag gravity helps us to manipulate the gravity inside the gazebo world.

Next, to launch the world we need to create a launch file main.launch. Before creating this file we create a launch directory inside ~simulation_ws/src/my_legged_robots_sims/ directory.

Using the IDE we add the following code to main.launch file

<?xml version="1.0" encoding="UTF-8"?>
<launch>
    <arg name="robot" default="machines"/>
    <arg name="debug" default="false"/>
    <arg name="gui" default="true"/>
    <arg name="headless" default="false"/>
    <arg name="pause" default="false"/>  <!-- Start Gazebo with a blank world -->
    <include file="$(find gazebo_ros)/launch/empty_world.launch">
        <arg name="world_name" value="$(find my_legged_robots_sims)/worlds/low_gravity.world"/>
        <arg name="debug" value="$(arg debug)" />
        <arg name="gui" value="$(arg gui)" />
        <arg name="paused" value="$(arg pause)"/>
        <arg name="use_sim_time" value="true"/>
        <arg name="headless" value="$(arg headless)"/>
        <env name="GAZEBO_MODEL_PATH" value="$(find my_legged_robots_sims)/models:$(optenv GAZEBO_MODEL_PATH)"/>
    </include>
</launch>

<?xml version="1.0" encoding="UTF-8"?> 
<launch> 
 <include file="$(find spawn_robot_tools_pkg)/launch/spawn_robot_urdf.launch"> 
  <arg name="x" default="0.0" /> 
  <arg name="y" default="0.0" /> 
  <arg name="z" default="1.0" /> 
  <arg name="roll" default="0"/> 
  <arg name="pitch" default="0"/> 
  <arg name="yaw" default="0.0" /> 
  <arg name="urdf_robot_file" default="$(find my_legged_robots_sims)/urdf/monoped_controlled.urdf" />
  <arg name="robot_name" default="monoped" /> 
 </include> 
</launch>

Notice in line 9 we have provided the name of our world file low_gravity.world.
This launch file will only launch an empty world in gazebo with zero gravity. To launch it click on the Simulation menu and select Select launch file option and choose the main.launch item.

To spawn the monoped we need to create another launch file inside the ~simulation_ws/src/my_legged_robots_sims/launch/ directory.
Use IDE to create a new file named spawn_monoped.launch and add following content:

<?xml version="1.0" encoding="UTF-8"?>
<launch>
    <include file="$(find spawn_robot_tools_pkg)/launch/spawn_robot_urdf.launch">
        <arg name="x" default="0.0" />
        <arg name="y" default="0.0" />
        <arg name="z" default="1.0" />
        <arg name="roll" default="0"/>
        <arg name="pitch" default="0"/>
        <arg name="yaw" default="0.0" />
        <arg name="urdf_robot_file" default="$(find my_legged_robots_sims)/urdf/monoped_controlled.urdf" />
        <arg name="robot_name" default="monoped" />
    </include>
</launch>

To run it, start a SHELL from tools menu and execute following command.

$ roslaunch my_legged_robots_sims spawn_monoped.launch

You should see the monoped load in the gazebo world.
We can change the gravity settings in low_gravity.world file and relaunch the robot to see the effect of gravity. Since we have not actuated the robot the robot will fall under the influence of gravity, which is totally fine. This finishes the steps to create the hopper robot using Robot Development Studio as shown in the video.

Checkout the URDF robot creation course in RobotIgniteAcademy: https://goo.gl/NJHwq3

[irp posts=”8194″ name=”All about Gazebo 9 with ROS”]

Part 2

In this second video of a new ROS Development Studio video series, you are going to continue to learn step by step
how to create your own hopper simulation, and may be a real version if there is high support to this videos.

You will learn in this video

  • how to create your ROS packages,
  • modify a URDF given by Alexander W. Winkler, https://github.com/leggedrobotics/xpp to give it control and physics
  • and add all the needed sensors like IMU, odometry and contact sensor.

All the code of the project will be uploaded to this public repo, don’t hesitate to make improvements and add more content:
https://bitbucket.org/theconstructcore/hopper/src/master/

Checkout the URDF robot creation course in RobotIgniteAcademy: www.robotigniteacademy.com

 


Robot-Creation-with-URDF-ROS--banner

My Robotic Manipulator #2: URDF & XACRO

My Robotic Manipulator #2: URDF & XACRO

URDF & XACRO

In this video we’ll improve our URDF code of the robotic manipulator using XACRO. From the URDF model, finish the robot, creating all joints and links and visualize it using RViz. Up to the end of the video, we will have the model finished, a launch file to visualize it and a RViz and some MACROs to help you in the development of the robot.


Related resources:

 

My Robotic Manipulator #1: Basic URDF & RViz

My Robotic Manipulator #1: Basic URDF & RViz

Updated: 07 of August 2023

What we are going to learn

  1. How to build a robot in a matter of minutes
  2. How to see the robot in RViz
  3. How to move the parts of the robot using Joint State Publisher

List of resources used in this post

  1. Use the rosject: https://app.theconstructsim.com/l/5a5b6f9f/
  2. The Construct: https://app.theconstructsim.com/
  3. My Robot Manipulator repository: https://bitbucket.org/theconstructcore/my-robotic-manipulator
  4. ROS Courses:
    1. URDF for Robot modeling: https://app.theconstructsim.com/Course/13
  5. ROS2 Courses:
    1. URDF for Robot Modeling in ROS2 : https://app.theconstructsim.com/courses/83
    2. ROS2 Basics in 5 Days Humble (Python): https://app.theconstructsim.com/Course/132
    3. ROS2 Basics in 5 Days Humble (C++): https://app.theconstructsim.com/Course/133

Overview

From the URDF model, we’re going to define the first two links and visualize them in RViz. Up to the end of the video, we’ll have a basic model, a launch file to visualize it and a RViz configuration file for this specific project.

ROS Inside!

ROS Inside

ROS Inside

Before anything else, if you want to use the logo above on your own robot or computer, feel free to download it and attach it to your robot. It is really free. Find it in the link below:

ROS Inside logo

Opening the rosject

In order to follow this tutorial, we need to have ROS installed in our system, and ideally a ROS Workspace (it can be named simulation_ws). To make your life easier, we have already prepared a rosject with a simulation for that: https://app.theconstructsim.com/l/5a5b6f9f/.

You can download the rosject on your own computer if you want to work locally, but just by copying the rosject (clicking the link), you will have a setup already prepared for you.

After the rosject has been successfully copied to your own area, you should see a Run button. Just click that button to launch the rosject (below you have a rosject example).

Learn ROS2 Parameters - Run rosject

My Robotic Manipulator #1: Basic URDF & RViz – Run rosject (example of the RUN button)

 

After pressing the Run button, you should have the rosject loaded. Now, let’s head to the next section to get some real practice.

Compiling the workspace

As you may already know, instead of using a real robot, we are going to use a simulation. In order to see that simulated robot, we need to have our workspace compiled, and for that, we need a terminal.

Let’s open a terminal by clicking the Open a new terminal button.

 

Open a new Terminal

Open a new Terminal

 

Once inside the first terminal, let’s run the commands below, to compile the workspace

cd ~/simulation_ws/
catkin_make
source devel/setup.bash

How the mrm_description package was created

If you check the contents of the ~/simulation_ws/src folder using the Code Editor or the terminal, you will see that it already contains a package named mrm_description there (mrm stands for My Robotic Manipulator). In case you want to know the commands we used to create that package, the commands were the following (you don’t need to run these commands if you already have the rosject).
To create the package that has the urdf package as a dependency, the commands were the following after opening a terminal:
cd ~/simulation_ws/src
catkin_create_pkg mrm_description urdf
We then created a urdf folder inside the mrm_description package with:
cd mrm_description/
mkdir urdf
After the folder was created, we created a file named mrm.xacro using these commands:
cd urdf/
touch mrm.xacro
and we also created the rviz.launch file, used for launching RViz (Robot Visualization tool) with the following commands:
cd ~/simulation_ws/src/mrm_description/
mkdir launch

touch rviz.xacro
You can see the content of these files using the Code Editor, also known as IDE (Integraded Development Environment). In order to open the IDE, just click the Code Editor button, as we can see in the image below:
Open the IDE - Code Editor

Open the IDE – Code Editor

Once the Code Editor is open, just navigate to simulation_ws/src/mrm_description/launch/rviz.launhc and simulation_ws/src/mrm_description/urdf/mrm.xacro to see the content of those files.

After opening the IDE, you can browse through folders by double-clicking them.  In case you want to create a new folder, right click on the parent folder and choose the option New Folder and type in the name you want to give to the folder.

The mrm.xacro file (My Robot Manipulator xacro file)

If we check the content of the mrm.xacro file, be it using the Code Editor or using the terminal (cat ~/simulation_ws/src/mrm_description/urdf/mrm.xacro), we will find the following:

<?xml version="1.0" ?>

<robot name="mrm" xmlns:xacro="http://www.ros.org/wiki/xacro">
    <link name="base_link">
        <visual>
          <origin rpy="0 0 0" xyz="0 0 0" />
          <geometry>
            <box size="1 1 1" />
          </geometry>
        </visual>
    </link>

    <joint name="base_link__link_01" type="revolute">
        <axis xyz="0 0 1"/>
        <limit effort="1000.0" lower="-3.14" upper="3.14" velocity="0.5"/>
        <origin rpy="0 0 0" xyz="0 0 0.5"/>
        <parent link="base_link"/>
        <child link="link_01"/>
      </joint>

    <link name="link_01">
        <visual>
          <origin rpy="0 0 0" xyz="0 0 0.2" />
          <geometry>
            <cylinder radius="0.35" length="0.4" />
          </geometry>
        </visual>
    </link>

</robot>

 

In the IDE (Code Editor), you can find it under the urdf folder:

Let’s understand the parts of this file.
The xacro file contains the description of our manipulator.
The first line tells us that this is an XML fie:
<?xml version="1.0" ?>
The next line we define a robot using the <robot> tag, that ends in the last line with </robot>:
<robot name="mrm" xmlns:xacro="http://www.ros.org/wiki/xacro">
  ...
</robot>
Then we define a link named base_link , with his visual being a box of width, depth, and height of 1 meter. The origin of the base_link is at the center of the simulated world, at position 0 0 0:
<link name="base_link">
  <visual>
    <origin rpy="0 0 0" xyz="0 0 0" />
    <geometry>
      <box size="1 1 1" />
    </geometry>
  </visual>
</link>
Then we create a joint to connect the base_link we just created, with a link named link_01 that we are about to create. The joint was defined with this code:
<joint name="base_link__link_01" type="revolute">
  <axis xyz="0 0 1"/>
  <limit effort="1000.0" lower="-3.14" upper="3.14" velocity="0.5"/>
  <origin rpy="0 0 0" xyz="0 0 0.5"/>
  <parent link="base_link"/>
  <child link="link_01"/>
</joint>
As we can see in the parent and child tags, we connect base_link to link_01. The link_01 link was defined as follows:
<link name="link_01">
  <visual>
  <origin rpy="0 0 0" xyz="0 0 0.2" />
  <geometry>
    <cylinder radius="0.35" length="0.4" />
  </geometry>
  </visual>
</link>
The link visual is represented by a cylinder.
In summary, this xacro file is a description of our robot in xml language. The robot is composed of various links and joints. In the above xacro we have two links base_link and link1. The base_link is fixed to the ground. It is connected to the link1 with a revolute joint. The joint allows the link1 to rotate about z-axis. We are defining the visual properties in this file.
The geometry property controls the appearance and origin property controls the positioning of the elements.
The joint element has an axis property which defines the degree of freedom of the links connected with joint. In addition to the axis property, the joint element has limit property to control the range of motion, parent and child property to control the relative motion (the child link moves with respect to the parent link).
Now that we have our robot defined, we need a way of launhcing it. For that, we have the rviz.launch file mentioned earlier. Let understand it:

The rviz.launch file

The content of the rviz.launch file that we created in the previous sections can be seen either using the Code Editor or through the terminal using this command:
cat ~/simulation_ws/src/mrm_description/launch/rviz.launch
Its content is as following:
<launch>
  <param name="robot_description" command="$(find xacro)/xacro --inorder '$(find mrm_description)/urdf/mrm.xacro'"/>
  
  <!-- Combine joint values -->
  <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher"/>
  
  <!-- Show in Rviz   -->
  <node name="rviz" pkg="rviz" type="rviz" args="-d $(find mrm_description)/launch/config.rviz" />
  
  <!-- send joint values -->
  <node name="joint_state_publisher_gui" pkg="joint_state_publisher_gui" type="joint_state_publisher_gui">
    <param name="use_gui" value="true"/>
  </node>

</launch>
In the fist line we start the definition of the launch file using the <launch> tag.
In the second line, we load a ROS parameter called robot_description using the content of of the urdf/mrm.xacro file that is found on the mrm_description package. It is basically the xacro file explained in the previous section.
In order to “put the robot pieces together“, we use the robot_state_publisher:
 <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher"/>
We also launch RViz in that launch file, and tell it to load the launch/config.rviz file that is also inside our package. Having that config.rviz file, we don’t have to reconfigure the RViz displays each time we open RViz.
Finally, we load the Joint State Publisher that allows us to move/rotate the links of our robot using a Graphical Tool:
<!-- send joint values -->
<node name="joint_state_publisher_gui" pkg="joint_state_publisher_gui" type="joint_state_publisher_gui">
    <param name="use_gui" value="True"/>
</node>
To summarize, this launch file helps in the task of launching different nodes together. The rviz.launch file above creates three nodes. The first node is for publishing the robot state, the second node starts RViz and the last node starts a GUI tool that helps in manipulating the joint angle of the robot. The first line (param) helps in locating and loading the xacro file that contains the robot description.

Compiling the workspace

Now that we have everything in place, we need to compile our workspace. For that, we use the following commands:

cd ~/simulation_ws/
catkin_make
If everything went well, you should have an output similar to the following:
...
-- catkin 0.8.10
-- BUILD_SHARED_LIBS is on
-- BUILD_SHARED_LIBS is on
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~  traversing 1 packages in topological order:
-- ~~  - mrm_description
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- +++ processing catkin package: 'mrm_description'
-- ==> add_subdirectory(mrm_description)
-- Configuring done
-- Generating done
-- Build files have been written to: /home/user/simulation_ws/build
####
#### Running command: "make -j8 -l8" in "/home/user/simulation_ws/build"
####

Lauching RViz to see our robot model

In the previous sections we already learned how to open a terminal.

Now, in order to launch RViz, let’s run the following commands in the first terminal:

source ~/simulation_ws/devel/setup.bash


roslaunch mrm_description rviz.launch
After running this launch file, you should have seen RViz and the Joint State Publisher. If RViz does not open automatically, just click the Graphical Tools button on the bottom bar of The Construct Desktop. If you don’t know which button is, just hover your mouse over the buttons to know which one opens the Graphical Tools.
After having the Graphical Tools open, feel free to move the joining using the Joint State Publisher. It is going to be difficult to see the joint moving because it has the same red color as the base link, but if you look at RViz closely, you will see it moving.

The GUI tool is like a remote desktop, when it starts you can see there are two tabs at the bottom. One is the RViz tool, and the other is the joint_state_publisher GUI as shown below:

 

In the RViz window, we should have everything in place. We shouldn’t have the red errors like in the image above, because in the rosject we already provided the config.rviz in the launch file, if you remember well.

What we did for creating that config.rviz file was the following, in RViz:

  • Changed Fixed Frame to base_link
  • Added an Axis element
  • Added a RobotModel element

The images below show the operations described above:

 

Congratulations. Now you know how to create a basic robot with two links and a joint using Xacro files.

We hope this post was really helpful to you. If you want a live version of this post with more details, please check the video in the next section. Although the video was recorded in a previous version of The Construct platform, it still adds a lot of value:

Youtube video

So this is the post for today. Remember that we have the live version of this post on YouTube. If you liked the content, please consider subscribing to our youtube channel. We are publishing new content ~every day.

Keep pushing your ROS Learning.

Related Courses & Training

If you want to learn more about ROS and ROS2, we recommend the following courses:

  1. ROS Courses:
    1. URDF for Robot modeling (ROS 1): https://app.theconstructsim.com/Course/13
  2. ROS2 Courses:
    1. URDF for Robot Modeling in ROS2 : https://app.theconstructsim.com/courses/83

Pin It on Pinterest