• Home
  • pcDuino
  • WiKi
  • Store
  • Distributors
  • Home
  • pcDuino
  • WiKi
  • Store
  • Distributors
HomeScratchBuilding a Visual Robot Model with URDF from Scrat ...
Previous Next

Building a Visual Robot Model with URDF from Scratch

Posted by: Alvin Jin , January 17, 2014

In this tutorial, we’re going to build a visual model of a robot that vaguely looks like R2D2. In later tutorials, you’ll learn how to articulate the model, add in some physical properties, generate neater code with xacro and make it move in Gazebo. But for now, we’re going to focus on getting the visual geometry correct.

In these tutorials, we’re going to rely on some tools and launch files from the urdf_tools package. Most notably, joint_state_publisher needs to be downloaded from the Washington University repository, linked to on the joint_state_publisher wiki page. All of the robot models mentioned in this tutorial can be found in the urdf_tutorial package.

<span class="anchor" id="line-1-2"></span>$ rosdep install joint_state_publisher
<span class="anchor" id="line-2-2"></span>$ rosdep install urdf_tutorial
<span class="anchor" id="line-3-2"></span>$ roscd urdf_tutorial

 

There is currently a known bug in the urdf_tutorial launch files. See urdf_tutorial/issues/6 for the issue, and no robot visible in rviz for urdf tutorial on ROS Answers for a temporary work-around.

 

Starting with urdf_tutorial version 0.2.3 this workaround is no longer needed. The commands in this (and the following) tutorial(s) have been updated to work with the new version of the package.

 

One Shape

 

First, we’re just going to explore one simple shape. Here’s about as simple as a urdf as you can make. Source

Toggle line numbers
<span class="line"><span class="LineAnchor" id="CA-360a598e8173ffe3fdd7978b189831b146e02d97_1"></span><span class="anchor" id="line-1-6"></span><span class="Preprc">&lt;?xml version="1.0"?&gt;</span></span>
<span class="line"><span class="ID">&lt;robot</span> <span class="ID">name=</span><span class="String">"myfirst"</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;link</span> <span class="ID">name=</span><span class="String">"base_link"</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;visual</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;geometry</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;cylinder</span> <span class="ID">length=</span><span class="String">"0.6"</span> <span class="ID">radius=</span><span class="String">"0.2"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;/geometry&gt;</span></span>
<span class="line"><span class="ID">&lt;/visual&gt;</span></span>
<span class="line"><span class="ID">&lt;/link&gt;</span></span>
<span class="line"><span class="LineAnchor" id="CA-360a598e8173ffe3fdd7978b189831b146e02d97_10"></span><span class="anchor" id="line-10-2"></span><span class="ID">&lt;/robot&gt;</span></span>

 

To translate the XML into English, this is a robot with the name myfirst, that contains only one link (a.k.a. part), whose visual component is just a cylinder .6 meters long with a .2 meter radius. This may seem like a lot of enclosing tags for a simple “hello world” type example, but it will get more complicated, trust me.

To examine the model, type roslaunch urdf_tutorial display.launch model:=urdf/01-myfirst.urdf This does three things. It

  • Loads the specified model into the parameter server
  • Runs nodes to publish the JointState and transforms (more on these later)

  • Starts Rviz with a configuration file

This launch file assumes that 01-myfirst.urdf is in the urdf subdirectory of the directory that you type the command in. Otherwise, you should say model:='$(find pkg-name)/urdf/01-myfirst.urdf' where pkg-name is the name of the package that the file is in (single quotes required). All of the example files are in the urdf_tutorial package, so if you are in that directory you can run the commands without modification.

The model we made should look like this

my first image

Things to note:

  • The fixed frame is transform frame where the center of the grid is located. Here, it’s a frame defined by our one link, base_link.
  • The visual element (the cylinder) has its origin at the center of its geometry as a default. Hence, half the cylinder is below the grid.

Multiple Shapes

 

Now let’s look at how to add multiple shapes/links. If we just add more link elements to the urdf, the parser won’t know where to put them. So, we have to add joints. Joint elements can refer to both flexible and inflexible joints. We’ll start with inflexible, or fixed joints. Source

Toggle line numbers
<span class="line"><span class="LineAnchor" id="CA-5536eaca6fd62b558920aa76c7af49a511c91a0e_1"></span><span class="anchor" id="line-1-8"></span><span class="Preprc">&lt;?xml version="1.0"?&gt;</span></span>
<span class="line"><span class="ID">&lt;robot</span> <span class="ID">name=</span><span class="String">"multipleshapes"</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;link</span> <span class="ID">name=</span><span class="String">"base_link"</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;visual</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;geometry</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;cylinder</span> <span class="ID">length=</span><span class="String">"0.6"</span> <span class="ID">radius=</span><span class="String">"0.2"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;/geometry&gt;</span></span>
<span class="line"><span class="ID">&lt;/visual&gt;</span></span>
<span class="line"><span class="ID">&lt;/link&gt;</span></span>
<span class="line"><span class="ID">&lt;link</span> <span class="ID">name=</span><span class="String">"right_leg"</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;visual</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;geometry</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;box</span> <span class="ID">size=</span><span class="String">"0.6 .2 .1"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;/geometry&gt;</span></span>
<span class="line"> <span class="ID">&lt;/visual&gt;</span></span>
<span class="line"><span class="ID">&lt;/link&gt;</span></span>
<span class="line"><span class="ID">&lt;joint</span> <span class="ID">name=</span><span class="String">"base_to_right_leg"</span> <span class="ID">type=</span><span class="String">"fixed"</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;parent</span> <span class="ID">link=</span><span class="String">"base_link"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;child</span> <span class="ID">link=</span><span class="String">"right_leg"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;/joint&gt;</span></span>
<span class="line"><span class="LineAnchor" id="CA-5536eaca6fd62b558920aa76c7af49a511c91a0e_24"></span><span class="anchor" id="line-24-1"></span><span class="ID">&lt;/robot&gt;</span></span>

 

  • Note how we defined a 0.6m x 0.2m x 0.1m box
  • The joint is defined in terms of a parent and a child. URDF is ultimately a tree structure with one root link. This means that the leg’s position is dependent on the base_link’s position.

roslaunch urdf_tutorial display.launch model:=urdf/02-multipleshapes.urdf Multiple Shapes

Both of the shapes overlap with each other, because they share the same origin. If we want them not to overlap we must define more origins.

Origins

 

So R2D2’s leg attaches to the top half of his torso, on the side. So that’s where we specify the origin of the JOINT to be. Also, it doesn’t attach to the middle of the leg, it attaches to the upper part, so we must offset the origin for the leg as well. We also rotate the leg so it is upright. Source

Toggle line numbers
<span class="line"><span class="LineAnchor" id="CA-d6ff7c253db5895c6a687a53822c54fc90dceee6_1"></span><span class="anchor" id="line-1-10"></span><span class="Preprc">&lt;?xml version="1.0"?&gt;</span></span>
<span class="line"><span class="LineAnchor" id="CA-d6ff7c253db5895c6a687a53822c54fc90dceee6_2"></span><span class="anchor" id="line-2-5"></span><span class="ID">&lt;robot</span> <span class="ID">name=</span><span class="String">"origins"</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;link</span> <span class="ID">name=</span><span class="String">"base_link"</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;visual</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;geometry</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;cylinder</span> <span class="ID">length=</span><span class="String">"0.6"</span> <span class="ID">radius=</span><span class="String">"0.2"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;/geometry&gt;</span></span>
<span class="line"><span class="ID">&lt;/visual&gt;</span></span>
<span class="line"><span class="ID">&lt;/link&gt;</span></span>
<span class="line"><span class="ID">&lt;link</span> <span class="ID">name=</span><span class="String">"right_leg"</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;visual</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;geometry</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;box</span> <span class="ID">size=</span><span class="String">"0.6 .2 .1"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;/geometry&gt;</span></span>
<span class="line"><span class="ID">&lt;origin</span> <span class="ID">rpy=</span><span class="String">"0 1.57075 0"</span> <span class="ID">xyz=</span><span class="String">"0 0 -0.3"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;/visual&gt;</span></span>
<span class="line"><span class="ID">&lt;/link&gt;</span></span>
<span class="line"><span class="ID">&lt;joint</span> <span class="ID">name=</span><span class="String">"base_to_right_leg"</span> <span class="ID">type=</span><span class="String">"fixed"</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;parent</span> <span class="ID">link=</span><span class="String">"base_link"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;child</span> <span class="ID">link=</span><span class="String">"right_leg"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;origin</span> <span class="ID">xyz=</span><span class="String">"0.22 0 .25"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;/joint&gt;</span></span>
<span class="line"><span class="ID">&lt;/robot&gt;</span></span>

 

  • Let’s start by examining the joint’s origin. It is defined in terms of the parent’s reference frame. So we are .22 meters in the x direction (left) and .25 meters in the z direction (up). This means that the origin for the child link will be up and to the left, regardless of the child link’s visual origin tag. Since we didn’t specify a rpy (roll pitch yaw) attribute, the child frame will be default have the same orientation as the parent frame.
  • Now, looking at the leg’s visual origin, it has both a xyz and rpy offset. This defines where the center of the visual element should be, relative to its origin. Since we want the leg to attach at the top, we offset the origin down by setting the z offset to be -.3 meters. And since we want the long part of the leg to be parallel to the z axis, we rotate the visual part PI/2 around the Y axis.

roslaunch urdf_tutorial display.launch model:=urdf/03-origins.urdf Origins Screenshot

  • The launch file runs packages that will create TF frames for each link in your model based on your URDF. Rviz uses this information to figure out where to display each shape.
  • If a TF frame does not exist for a given URDF link, then it will be placed at the origin in white.

Material Girl

 

“Alright,” I hear you say. “That’s very cute, but not everyone owns a B21. My robot and R2D2 are not red!” That’s a good point. Let’s take a look at the material tag. Source

Toggle line numbers
<span class="line"><span class="LineAnchor" id="CA-e73c9a84933fd2c39c8dd8508bb8a46d3d5390ec_1"></span><span class="anchor" id="line-1-12"></span><span class="Preprc">&lt;?xml version="1.0"?&gt;</span></span>
<span class="line"><span class="ID">&lt;robot</span> <span class="ID">name=</span><span class="String">"materials"</span><span class="ID">&gt;</span></span>
<span class="line"> <span class="ID">&lt;link</span> <span class="ID">name=</span><span class="String">"base_link"</span><span class="ID">&gt;</span></span>
<span class="line"> <span class="ID">&lt;visual</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;geometry</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;cylinder</span> <span class="ID">length=</span><span class="String">"0.6"</span> <span class="ID">radius=</span><span class="String">"0.2"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;/geometry&gt;</span></span>
<span class="line"><span class="ID">&lt;material</span> <span class="ID">name=</span><span class="String">"blue"</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;color</span> <span class="ID">rgba=</span><span class="String">"0 0 .8 1"</span><span class="ID">/&gt;</span></span>
<span class="line"> <span class="ID">&lt;/material&gt;</span></span>
<span class="line"><span class="ID">&lt;/visual&gt;</span></span>
<span class="line"><span class="ID">&lt;/link&gt;</span></span>
<span class="line"><span class="ID">&lt;link</span> <span class="ID">name=</span><span class="String">"right_leg"</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;visual</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;geometry</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;box</span> <span class="ID">size=</span><span class="String">"0.6 .2 .1"</span><span class="ID">/&gt;</span></span>
<span class="line"> <span class="ID">&lt;/geometry&gt;</span></span>
<span class="line"> <span class="ID">&lt;origin</span> <span class="ID">rpy=</span><span class="String">"0 1.57075 0"</span> <span class="ID">xyz=</span><span class="String">"0 0 -0.3"</span><span class="ID">/&gt;</span></span>
<span class="line"> <span class="ID">&lt;material</span> <span class="ID">name=</span><span class="String">"white"</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;color</span> <span class="ID">rgba=</span><span class="String">"1 1 1 1"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;/material&gt;</span></span>
<span class="line"><span class="ID">&lt;/visual&gt;</span></span>
<span class="line"><span class="ID">&lt;/link&gt;</span></span>
<span class="line"><span class="ID">&lt;joint</span> <span class="ID">name=</span><span class="String">"base_to_right_leg"</span> <span class="ID">type=</span><span class="String">"fixed"</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;parent</span> <span class="ID">link=</span><span class="String">"base_link"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;child</span> <span class="ID">link=</span><span class="String">"right_leg"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;origin</span> <span class="ID">xyz=</span><span class="String">"0.22 0 .25"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;/joint&gt;</span></span>
<span class="line"> <span class="ID">&lt;link</span> <span class="ID">name=</span><span class="String">"left_leg"</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;visual</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;geometry</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;box</span> <span class="ID">size=</span><span class="String">"0.6 .2 .1"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;/geometry&gt;</span></span>
<span class="line"><span class="ID">&lt;origin</span> <span class="ID">rpy=</span><span class="String">"0 1.57075 0"</span> <span class="ID">xyz=</span><span class="String">"0 0 -0.3"</span><span class="ID">/&gt;</span></span>
<span class="line"> <span class="ID">&lt;material</span> <span class="ID">name=</span><span class="String">"white"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;/visual&gt;</span></span>
<span class="line"><span class="ID">&lt;/link&gt;</span></span>
<span class="line"><span class="ID">&lt;joint</span> <span class="ID">name=</span><span class="String">"base_to_left_leg"</span> <span class="ID">type=</span><span class="String">"fixed"</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;parent</span> <span class="ID">link=</span><span class="String">"base_link"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;child</span> <span class="ID">link=</span><span class="String">"left_leg"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;origin</span> <span class="ID">xyz=</span><span class="String">"-0.22 0 .25"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;/joint&gt;</span></span>
<span class="line"><span class="LineAnchor" id="CA-e73c9a84933fd2c39c8dd8508bb8a46d3d5390ec_48"></span><span class="ID">&lt;/robot&gt;</span></span>

 

  • The body is now blue. By adding the first material tag, we’ve defined a new material called “blue”, with the red, green, blue and alpha channels defined as 0,0,.8 and 1 respectively. All of the values can be in the range [0,1].
  • The white material is defined similarly
  • For the second leg, we can refer to the material just by name, since it’s been previously defined. No one will complain if you redefine it though.
  • You can also use a texture to specify an image file to be used for coloring the object

roslaunch urdf_tutorial display.launch model:=urdf/04-materials.urdf Materials Screenshot

Finishing the Model

 

Now we finish the model off with a few more shapes. Most notably, we add a sphere and a some meshes. We’ll also add few other pieces that we’ll use later. Source

roslaunch urdf_tutorial display.launch model:=urdf/05-visual.urdf Visual Screenshot

How to add the sphere should be fairly self explanatory

Toggle line numbers
<span class="line"><span class="ID">&lt;link</span> <span class="ID">name=</span><span class="String">"head"</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;visual</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;geometry</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;sphere</span> <span class="ID">radius=</span><span class="String">"0.2"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;/geometry&gt;</span></span>
<span class="line"><span class="ID">&lt;material</span> <span class="ID">name=</span><span class="String">"white"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;/visual&gt;</span></span>
<span class="line"><span class="ID">&lt;/link&gt;</span></span>

 

The meshes here were borrowed from the PR2, meaning you’ll need the package pr2_description to be able to see them.

Toggle line numbers
<span class="line"><span class="ID">&lt;link</span> <span class="ID">name=</span><span class="String">"left_gripper"</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;visual</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;geometry</span><span class="ID">&gt;</span></span>
<span class="line"><span class="ID">&lt;mesh</span> <span class="ID">filename=</span><span class="String">"package://pr2_description/meshes/gripper_v0/l_finger.dae"</span><span class="ID">/&gt;</span></span>
<span class="line"><span class="ID">&lt;/geometry&gt;</span></span>
<span class="line"><span class="ID">&lt;/visual&gt;</span></span>
<span class="line"><span class="ID">&lt;/link&gt;</span></span>

 

  • The meshes can be imported in a number of different formats. STL is fairly common, but the engine also supports DAE, which can have its own color data, meaning you don’t have to specify the color data.
  • Meshes can also be sized using relative scaling parameters or a bounding box size.

There you have it. A R2D2-like URDF model. Now you can continue on to the next step, making it move.

Tags: Scratch

Share!
Tweet

Alvin Jin

About the author

Leave a Reply Cancel reply

You must be logged in to post a comment.

Category

  • Home
  • pcDuino
  • WiKi
  • Store
  • Distributors