Creating Universal Robots .urdf files for Novices (aka Me)

January 16 2024

The Problem

As part of a new project that I'm excited to be working on, I needed to find a .urdf file for Universal Robot's UR10e robot. Unfortunately, it was rather tricky to find one. What I frequently found were files with names like ur.urdf.xacro.

I've seen these files enough around the internet to know that they are some sort of file that can be called to create .urdf files. But I never understood how to until I banged my head against the wall for a few hours figuring out how to use .xacro files. I'd like to share what I've learned to simplify future UR robot fans (or anyone else who needs to use a .xacro file).

The Setting

This tutorial assumes that you are using a setup similar to mine, which is the base Macbook Pro. I have Docker installed and use it to solve some of my problems, but it should be possible to mimic the same steps without having that program.

I found this GitHub repository pretty early on in my search for a URDF file. Inside of its urdf directory, you will find multiple xacro files.

How to Generate the URDF File

I'll organize my instructions into a few sections. First, I'll describe what a xacro file is and how it can be handled using the ros xacro package. Then, I'll describe how to install this package in a ROS2 workspace inside of a Docker container as well as the errors that I experienced while trying to use this package for the first time.

What is a Xacro File and how can I use it?

The .xacro suffix is appended to files written in the Xacro (XML Macros) language. You might already have the intuition that this is a language that can be used to generate XML files. This is correct, and I'd like to add to this intuition that Xacro is meant to make your XML files "shorter and more readable" as mentioned on the ROS package's website.

To use a .xacro file you must install the xacro package and then you can run it using command line tools. For example, once you have finished this tutorial you can generate the ur10e's urdf file with the following command:

        
xacro -o ur10e.urdf ur.urdf.xacro name:=ur10e-test ur_type:=ur10e
        
    

or

        
ros2 run xacro xacro -o ur10e.urdf ur.urdf.xacro name:=ur10e-test ur_type:=ur10e
        
    

One thing that you might notice is that there are command line arguments that are passed into xacro in two different ways. There is -o ur10e.urdf which is a familiar pattern for command line tools. And there is also name:=ur10e-test ur_type:=ur10e which is a pattern that seems to be less common, but is used for providing arguments to the file (more on this later).

Also note: Although this is a correct command to generate the ur10e's urdf file, it will not work until you have completed some other steps in this tutorial (i.e., cleaned up some errors that I encountered).

Install the Necessary Packages in a ROS2 Workspace

In order to keep my personal laptop clean, I like to use Docker containers to run my ROS2 workspaces. If you already have ROS2 installed or are okay with installing it on your local machine, then feel free to ignore the next docker command.

You can create a simple container running ROS2 Foxy with the following command:

        
docker run -td --name ros2_container_v1 \
  osrf/ros:foxy-desktop
        
    

Once this container is created and up and running, then I recommend attaching Visual Studio code to it. (You can do this by installing the Remote - Containers and Docker extensions to Visual Studio code and then right clicking on the running ros2 container.)

Once you have attached Visual Studio code to the container, you can open a terminal in the container and begin working.

I would recommend creating a new ROS2 workspace for the purpose of doing this conversion. You can do this by running the following commands:

        
source /opt/ros/foxy/setup.bash
cd ~
mkdir --parents ros2_ws/src
cd ros2_ws
colcon build
        
    

This will create a new ROS2 workspace in ros2_ws. The packages in this workspace (or any other files) should be saved in the src directory. colcon build builds the workspace (including a new setup.bash script that you should use when running things from this workspace; note that /opt/ros/foxy/setup.bash and the new .bash script will be different).

These instructions were taken from this industrial training tutorial on ROS2. Feel free to return there if something doesn't work, or you have deeper questions.

Now, we will install the necessary packages to this new ROS2 Workspace.

xacro can be installed pretty quickly because there is a apt command for it:

        
sudo apt install ros-foxy-xacro
        
    

This should install xacro in the base ROS2 workspace (and thus to all of the other workspaces on the machine, including the new one). I identified this command from this blog post which was written for ROS2 Foxy.

Now, we will install the Universal_Robots_ROS2_Description package which is a little bit more involved.

        
cd ~/ros2_ws/src
git clone https://github.com/UniversalRobots/Universal_Robots_ROS2_Description.git
cd ..
colcon build
        
    

This will install the associated Universal_Robots_ROS2_Description package into only the new ROS2 workspace.

From here, the command to generate the urdf file would normally work. However, if you try to generate the urdf file now, you will get an error. Open a new terminal and try to run:

        
cd ~/ros2_ws
source install/setup.bash
cd src/Universal_Robots_ROS2_Description/urdf
xacro -o ur10e.urdf ur.urdf.xacro name:=ur10e-test ur_type:=ur10e
        
    

You will likely get the following error:

        
name 'xacro' is not defined
when evaluating expression 'xacro.load_yaml(visual_parameters_file)'
when evaluating expression 'config_visual_parameters['mesh_files']
        
    

Simply put the command xacro.load_yaml which is used often in the ur_common.xacro file in the Universal_Robots_ROS2_Description/urdf/inc directory does not need the xacro. prefix. If you change lines 47-51 to:

        
<!-- Read .yaml files from disk, load content into properties -->
<xacro:property name="config_joint_limit_parameters" value="${load_yaml(joint_limits_parameters_file)}"/>
<xacro:property name="config_kinematics_parameters" value="${load_yaml(kinematics_parameters_file)}"/>
<xacro:property name="config_physical_parameters" value="${load_yaml(physical_parameters_file)}"/>
<xacro:property name="config_visual_parameters" value="${load_yaml(visual_parameters_file)}"/>
        
    

And voila! You should now be able to run the xacro command without any errors!

        
xacro -o ur10e.urdf ur.urdf.xacro name:=ur10e-test ur_type:=ur10e
        
    

As usual, please let me know if you have a question about the approach in an email or direct message!

Appendix: Keywords I Searched For

In this section, I'll write a list of keywords that I searched for during the time that I looked for a solution. Hopefully, this will help others find this page in the future.

  • ur10e urdf
  • ur description
  • ur10e urdf github
  • how to install xacro from source foxy ros2
  • ros2 error name 'xacro' not defined
  • error when evaluating expression 'xacro.load_yaml(visual_parameters_file)'