Here, you'll learn how to describe your robot in terms of code. We make a file that gives you complete idea about a robot.
ROS uses URDF (Unified Robot Description Format) as the format for describing robot models. It's an XML based format which is specifically used to write a robot description, so again it all boils down to elements and properties defined using tags. There is a lot to this and a good part of this seeps into simulation but for now, we'll do only the basics that will help you write a simple robot description and visualize it on RViZ.
Let's get started with URDF
URDF (Unified Robot Description Format) is an XML format used to describe robots. It's used for the following purposes:
And much more, but we'll explore only the first two here.
All the URDF files are stored in a folder named "urdf" in your package, we'll create a new package first, to do this run the following commands on a terminal:
cd ~/ROS_workspaces/ros_ws/src/
catkin_create_pkg intro_robot_description robot_state_publisher urdf xacro tf
mkdir urdf
cd ../../
cd ~/ROS_workspaces/ros_ws/src/
).catkin_make
After the package has been created and built. Let's create a file named first_robot.urdf in the "urdf" folder. Let's start with just a single revolute joint robot. Here's how you write the code in this file (info about all XML tags later on):
To get the file on terminal, you can run the following on a terminal:
roscd intro_robot_description/urdf/
cat first_robot.urdf
We can verify a URDF file using the following command:
check_urdf first_robot.urdf
sudo apt install liburdfdom-tools
.Follow the following steps to set up RViZ:
rosrun rviz rviz
, make sure roscore
is running.Here's how the configurations must look like
RViZ configuration
Notice the following:
roslaunch intro_robot_description FirstLaunch.launch
All outputs below
RViZ window with the joint_state_publisher window. You can control all the joint variables using the joint_state_controller window. Play around with different joint values and different views of the robot. We'll make much more sophisticated robots soon.
I've made the following modifications for this one, few of them are:
Tutorial 2 for robot description using URDF
All tags on the official page, there's a summary here as well. The tags for simple robot description are sorted priority wise (high to low).
A link is basically any physical object in the robot. The <link>...</link> tag is used to define a link. It has the following attributes:
It has various elements to describe various properties of the link. Some important ones are:
This is to define the inertia tensor of the robot. It's different for different mass distributions, but here is a list of general mass distributions. The <intertia> ... </inertia> tag is used for this. The elements of this tag are:
The visual properties of a link, the apparent shape. The <visual> ... </visual> tag is used for this. It has the following attributes:
It has the following elements for definition of the visual properties:
These are for the collision boundaries of the link. These are usually primitive boundaries for simpler computation. Since this is also like a region, all of the tags, attributes and elements that are for visual apply for this as well but no <material> tag here. The <collision> ... </collision> tag is used for this.
You can have multiple collision and visual tags under the same link. The ultimate result is just the union of all the regions.
A joint is basically something that connects two links together. The <joint> ... </joint> tag is used for this. It has the following attributes:
These are the important elements for this tag:
XACRO stands for XML Macro. You must have thought that writing code using URDF is very time consuming and that there are many parts that repeat for large structures. XACRO is simply a more advanced way of writing descriptions for robots.
You could check out the official documentation for this and a tutorial showing you how to clean up a URDF using XACRO. However, we'll discuss this briefly here as well.
Here are a few important things to remember while using XACRO for robot modelling:
Let's get started with a simple XACRO file
Name the file "XACROLauncher.launch" and save it in the launch folder. Run the following command on a terminal and play around with the joint_state_publisher GUI window:
roslaunch intro_robot_description XACROLauncher.launch
Output below, all codes after the image
The robot model on RViZ along with transformation frames. You can see that basically a frame is something attached to the link defining it's position and orientation.
XACROLauncher.launch file
first_xacro.xacro file
xmlns:xacro="http://www.ros.org/wiki/xacro"
inside the robot tag as an argument.rosrun xacro xacro --help
xacro --help
There are a few tags declared below.
To declare a constant, use the <xacro:property ... /> tag. It has the following attributes:
Use ${property_name} to substitute for the property value at the site.
For example, the following code
<xacro:property name=”var1” value=”name1” />
<link name=”link_${var1}” />
will generate the following output
<link name=”link_name1” />
The substitution of ${var1} can be observed.
Everything in ${} is evaluated mathematically. All math is done using floating point evaluation. Even variable names (constant names) inside ${} are substituted in value. We can use +, -, *, /, sin and cos. Essentially the math module in python. More info here.
XACRO also allows blocks to be parsed only if certain conditions are met. Virtually, any python evaluateable boolean expression will work. We use the <xacro:unless> ... </xacro:unless> tag and <xacro:if> ... </xacro:if> tag which have the value attribute that must evaluate to "1" (or "true") or "0" (or "false").
MACROs are snippets of codes that are substituted wherever called. The <xacro:macro> ... </xacro:macro> tag is used, it has the following attributes:
Under this, we can write any code that we want to substitute for the macro call. More on this here.
We call the macro using <xacro:macro_name ... > ... </xacro:macro_name> tag.
We use the <xacro:include ... /> tag for this. This is used to include other files (preferably xacro, but it's used for other purposes as well). We'll use this later on in gazebo as well (you will see that in later pages). The attributes of <xacro:include ... /> are:
Here are the following commands that help us in checking a URDF file:
check_urdf first_xacro.urdf
urdf_to_graphiz first_xacro.urdf
Use the "xacro" command (or "rosrun xacro xacro" will also do the same):
xacro first_xacro.xacro > first_xacro.urdf
xacro first_xacro.xacro
command actually parses the XACRO and converts it to URDF and sends the output to the terminal, the > first_xacro.urdf
part is simply to put thing output in a file named first_xacro.urdf (your file names could be anything).xacro --help
command.This is about making the robot move in RViZ. We'll have a simple two link robot with one oscillating joint but you can have this procedure done for any robot.
Execute the following command on a terminal:
roslaunch intro_robot_description RViZ_Robot_Controller.launch
You could also run the following commands on different terminal and see how the joint_states are published:
rostopic echo /joint_states
rostopic info /joint_states
It'll show you the message structure being published.
cd ~/ROS_workspaces/ros_ws/
catkin_make
Now that we've added the sensor_msgs dependency we can use the topic sensor_msgs/JointState to write code.
cd ~/ROS_workspaces/ros_ws/
catkin_make
Run the following launch command on a terminal (we've already created the launch file before)
roslaunch intro_robot_description RViZ_Robot_Controller.launch internal:="true" jc_exec:="JointController_CPP"
The internal tag is set to true, that means we'll assign an executable as a joint controller. In jc_exec, we give the executable name as well. We could run the joint controller using the command rosrun intro_robot_description JointController_CPP
and it's the same thing.
You must see the RViZ window open and the robot model with it's joints receiving the commands.
roscd intro_robot_description/scripts/
chmod +x *.py
roslaunch intro_robot_description RViZ_Robot_Controller.launch internal:="true" jc_exec:="PyJointController.py"
You must see the RViZ window open and the robot model with it's joints receiving the commands.
C++ and Python codes for a Joint State Controller for controlling a robot model on RViZ