Robot Operating System: How to Create a Robot Simulation Model
Tags: ros, robots
Published: 2021-12-06 07:07:43

URDF is a custom data format for describing robots. It’s an XML file that provides concepts such as joints, motors and the general dimension of you robot. From this description, you can create and apply simulations. In this article, I will explain how to describe a robot with URDF.

This article is part of a series about simulating and building a robot with the Robot Operating Systems ROS. Read more in the [blog series](https://admantium.com/category/ros-series/).

_This article originally appeared at my blog [admantium.com](https://admantium.com/blog/ros04_urdf_tutorial_1/)_.

## Create a Catkin Workspace and Package

All extensions and projects you make in ROS should follow a set of conventions. The topmost convention is to start from a private workspace in which all files will be contained. By issuing commands, this workspace will be available to other ROS packages on your system, and thereby enable the seamless interaction of different packages.

The very first step is to define a private workspace in which we will create the separate ROS packages.

```bash
$> mkdir -p ~/ROS/src
$> cd ~/ROS
$> catkin_make
Base path: /home/devcon/ROS
Source space: /home/devcon/ROS/src
...
-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
...
-- Found PythonInterp: /usr/bin/python3 (found suitable version "3.8.5", minimum required is "3")
-- Using PYTHON_EXECUTABLE: /usr/bin/python3
-- Using Debian Python package layout
-- Found PY_em: /usr/lib/python3/dist-packages/em.py  
-- Using empy: /usr/lib/python3/dist-packages/e
```

Then we create the package `car-robot` inside the directory `ROS/src`.

```bash
$> cd ~/ROS/src
$> catkin_create_pkg car-robot
Created file car-robot/package.xml
Created file car-robot/CMakeLists.txt
Successfully created files in /home/devcon/ROS/car-robot. Please adjust the values in package.xml.
```

Now that we have the workspace and the package, we can start modelling the robot.

## Create the URDF File

In ROS, robots are models with URDF file, a self-contained specification of the robot. It defines the physical structure of the robot, consisting of shapes, links and joints.

Lets create a box shaped robot with four wheels that will look like this:

![](https://admantium.com/images/blog/ros04_final_robot.png)

Create a XML file at `urdf/bot.urdf` and continue with the next step.

### Define the Torso

The structure of a robot is defined with `link` and `joint`.

A `link` is a complex object that describes its static `visual` properties, its shape as a box, cylinder or sphere, and its materials with color or textures.

The robots' torso is a box, expressed in URDF like this:

```xml
<?xml version="1.0"?>
<robot name="bot">
  <link>
    <visual>
      <geometry>
        <box />
      </geometry>
    </visual>
  </link>
</robot>
```

The `size` parameters define its x-y-z coordinates in meter. Then we define its color as green, using RGB values.

```xml
<?xml version="1.0"?>
<robot name="bot">
  <link name="torso">
    <visual>
      <geometry>
        <box size="0.6 0.3 0.1"/>
      </geometry>
      <material name="green">
        <color rgba="1.0 1.0 0.0 1"/>
      </material>
    </visual>
  </link>
</robot>
```

So far, so good. Let’s check that the URDF file is correct.

```bash
$> check_urdf urdf/bot.urdf

robot name is: car-bot
---------- Successfully Parsed XML ---------------
root Link: torso has 0 child(ren)
```

Before we continue, we need to learn about another ROS convention. The `base_link` element that represents the central element of the robot, the root of the tree structure defined in the URDF file. Define this element, and connect it to the `torso`.

```xml
<link name="base_link">
  <visual>
    <geometry>
      <box size="0 0 0"/>
    </geometry>
    <material name="red">
      <color rgba="1 0 0 1"/>
    </material>
  </visual>
</link>

<joint name="base_link_torso" type="continuous">
  <parent link="base_link" />
  <child link="torso" />
  <origin xyz="0 0 0" rpy="0 0 0"/>
</joint>
```

Then we can render the torso with the tool `rviz`, and see this:

![](https://admantium.com/images/blog/ros04_robo01.png)

### Add the Wheels

The robot will have four wheels, positioned at the sides of the box. Wheels are drawn as `cylinder`, with attributes `radius` and `link`. To separate them from the torso, they will be painted red.

The URDF declaration is this:

```xml
<link name="left_wheel">
  <visual>
    <geometry>
      <cylinder radius="0.04" length="0.05" />
    </geometry>
    <material name="red">
      <color rgba="1 0 0 1"/>
    </material>
  </visual>
</link>

<link name="right_wheel">
  <visual>
    <geometry>
      <cylinder radius="0.04" length="0.05" />
    </geometry>
    <material name="red">
      <color rgba="1 0 0 1"/>
    </material>
  </visual>
</link>
```

However, we cannot render the robot with just these declarations. We need to express the relationships between all robot parts using `joints`.  

[Joints](https://wiki.ros.org/urdf/XML/joint) define parent-child relationships of other elements in an URDF file. They also enable the positioning of the elements: With `origin`, the relative offset from its parents is defined, and the optional `axis` declaration expresses the rotation of revolute or prismatic joints.

Let start simple with the right wheel. The URDF declaration is as follows:

```xml
<joint name="base_link_right_wheel" type="continuous">
  <parent link="base_link" />
  <child link="right_wheel" />
  <origin xyz="0.2 -0.2 -0.05" rpy="1.570796  0 0"/>
</joint>
```

The <parent> and <child> tags reference the links we created earlier. The origin positions the child relative to its parent. Here, the `xyz` attribute controls the position in the 3D cartesian space. The `rpy` value controls the 'tilt' of the object.

Take a look at the this picture:

![](https://admantium.com/images/blog/ros04_tilt01.png)

In this picture, the right wheel is defined as  `rpy="0 0 0"` - it’s basically lying flat. The left wheel has an `rpy="1.570796 0 0"`, which means that we roll it around the x-axis by value is `pi/2`. It is perfectly aligned with the torso.

With this knowledge, we can produce the following alignment:

```xml
<joint name="base_link_left_wheel" type="continuous">
  <axis xyz="0.0 0.0 1" />
  <parent link="base_link" />
  <child link="left_wheel" />
  <origin xyz="1.5 0 0" rpy="-1.5 0 0" />
</joint>

<joint name="base_link_right_wheel" type="continuous">
  <axis xyz="0.0 0.0 1" />
  <parent link="base_link" />
  <child link="right_wheel" />
  <origin xyz="-1.5 0 0" rpy="-1.5 0 0" />
</joint>
```

Which is rendered as this:

![](https://admantium.com/images/blog/ros04_tilt02.png)

Now both wheels are aligned correctly. Let’s add the definitions of the back wheels.

```xml
<link name="left_wheel_backside">
    <visual>
      <geometry>
        <cylinder radius="0.04" length="0.05" />
      </geometry>
      <material name="red">
        <color rgba="1 0 0 1"/>
      </material>
    </visual>
  </link>

  <joint name="base_link_left_wheel_backside" type="continuous">
    <parent link="base_link" />
    <child link="left_wheel_backside" />
    <origin xyz="-0.2 0.2 -0.05" rpy="1.570796 0 0"/>
  </joint>

  <link name="right_wheel_frontside">
    <visual>
      <geometry>
        <cylinder radius="0.04" length="0.05" />
      </geometry>
      <material name="red">
        <color rgba="1 0 0 1"/>
      </material>
    </visual>
  </link>

  <joint name="base_link_right_wheel_frontside" type="continuous">
    <parent link="base_link" />
    <child link="right_wheel_frontside" />
    <origin xyz="0.2 -0.2 -0.05" rpy="1.570796  0 0"/>
  </joint>

   <link name="right_wheel_backside">
    <visual>
      <geometry>
        <cylinder radius="0.04" length="0.05" />
      </geometry>
      <material name="red">
        <color rgba="1 0 0 1"/>
      </material>
    </visual>
  </link>
```

and see the final result.

![](https://admantium.com/images/blog/ros04_final_robot.png)

## Conclusion

This article showed the essential steps to define a ROS URDF model. We learned about the core XML tags that make up an URDF file: `<link>` that defines structures, with a `<geometry>` property to represent boxes, cylinders or spheres. These shapes can be given colors or even textures. These structures need to be connected by `<joints>`, forming a parent-child relationship. The `<joints>` also position the shapes to each other: defining how to align them along their axis, and where their origin is.

The final file is verbose and contains a lot of repetitive expressions. In the next article, we will see how to utilize the Xarco XML macro format to provide a better readable and manageable representation of our robot.