Modeling Robots in ROS
Table of Contents
1 Introduction
Today we will be covering many of the things that are provided by the robot_model metapackage. This metapackage includes many of the tools in ROS for representing robots and sensors
Note if you visit the wiki page for the robot_model
metapackage you'll see
that the metapackage was actually deprecated in ROS Melodic. This doesn't mean
that the functionality went away, it just means they've re-organized how they
are releasing and maintaining the associated packages (they are all independent
packages now instead of one metapackage). That said, the individual packages
contained in the now deprecated metapackage are still conceptually related, and
will still be grouped together for the purpose of these notes.
2 Core concepts
2.1 urdf
- A URDF (Unified Robot Description Format) can mean several things:
- An XML file that describes a robot
- A data structure (in some programming language, usually C++) that several different description formats can be parsed into
- Some work has been done on automatically generating URDFs from several
different formats. However, the functionality of this feature is somewhat
limited.
- SolidWorks, Collada, SDF
- I'd generally recommend generating URDFs by hand
- URDF's can be used in other applications
- KDL (Kinematics and Dynamics Library)
- Gazebo (through SDF)
- Collada (various programs)
- V-REP (a robot simulation tool)
- There are currently eight different XML specifications that are listed on the official XML specifications page of URDFs
- Several of these are rarely used but are still around for legacy purposes
- Much of the functionality of these old tags has been supplanted by the SDF XML specification. This is the format that is native to Gazebo.
2.1.1 Important XML specifications
- model
- This is the primary way you describe the geometry of your robot.
Typically, the
model
tag has many child tags that are primarilylink
andjoint
tags (described below). For almost every URDF that you'll encounter, the outermost tag will be themodel
tag. - link
- Describe the kinematic and dynamic properties of links (distances, coordinates, inertias). You can also include kinematic and dynamic properties of all of the links, visual representations of the links, and collision models that can be used in motion planning and simulation.
- joint
- This tag is used for connecting links together. Has a variety of primitive motions available (prismatic, revolute, etc.).
- gazebo
- If you want to use your URDF in Gazebo for simulating your robot, you'll need to provide some basic attributes in this tag. Read more here on the Gazebo tutorial on using a URDF in Gazebo.
2.1.2 Unimportant XML specifications
- transmission
- This is not used all that often unless you are using the
ros_control package. The
ros_control
package can use this tag to understand how to simulate and implement low-level controllers. - sensor
- Support for this tag has basically completely disappeared. These days if you need to model a sensor, it should be done entirely through Gazebo.
- model_state
- Also an idea that was never really finished, and is not used very often. Supposed to be used for specifying the robot at a particular configuration and time. However, this functionality has been completely supplanted by the SRDF.
- sensor/proposals
- This was supposed to be the future way of specifying sensors. It was never finished because of the creation of the SDF format.
2.2 Model XML format
- As stated above, the
model
tag is the parent tag of almost all URDF files. - There are two primary tags you'll see as children of basically every
model
tag,link
andjoint
. - There are great tutorials on writing URDF's for robots
2.2.1 Link tag
- Describes a rigid body with inertial, visual, and collision features
- One required attribute (
name
) - Three optional elements for every link
- inertial
- Defines the mass and rotational inertia properties of the link
- visual
- Display visual properties of the link. Can use several standard geometric primitives (box, cylinder, sphere), and can also use standard 3D body mesh representations (*.stl and *.dae)
- collision
- Define the collision model for the link using the same
options as the
visual
tag. The collision model is used by many ROS motion planning tools (MoveIt!) and for simulations in Gazebo. Each link can have more than one collision tag
2.2.2 Joint tag
- Joints are used to describe the kinematics, dynamics, and limits of joints connecting links
- Every joint has two required attributes
name
andtype
- name
- This is just the name of the joint
- type
- This described the type of motion between the
link
tags that thejoint
is dealing with. Available types include:- revolute
- Single rotational DOF between the links with upper and lower limits on range of motion.
- continuous
- Single rotational DOF between the links with no limits.
- prismatic
- Single DOF prismatic joint with upper and lower limits.
- fixed
- Zero DOF between the links
- floating
- All 6 DOF free between the links
- planar
- 2 DOF prismatic joint that allows motion in a plane
- Every link has two required elements:
- parent
- which link is the parent
- child
- which link is the child
- There are many optional elements most of which are fairly self-explanatory.
- Note that the
safety_controller
element is not used by anything exceptros_control
and thepr2_controller_manager
- If your joint has motions that are not described by one of the types
above, then you'll need to compose multiple, co-located joints to build up
your motion. For example, let's say you are trying to model a spherical
joint between to links i.e. there are three mutually-orthogonal rotational
degrees-of-freedom between your two links. Then, you would need to specify
three consecutive
continuous
joints to build this behavior. These consecutive joints would require several "dummy" children-parent pairs of links that have no inertia, collisions, or visual properties.
2.3 robot_state_publisher
The robot state publisher reads in a URDF, and then publishes a /tf
for
each link element in the robot model. It does this by subscribing to a topic,
by default called /joint_states
containing a sensor_msgs/JointState
message. This message provides the current configuration, velocity, and
force/torques of a robot. In this case, the robot_state_publisher
uses the
configuration received and the kinematic description from the URDF to process
the forward kinematics of the robot. As it is processing the forward
kinematics, it calculates the pose of each link in the URDF relative to its
parent link and then publishes the /tf
data containing this transform.
In the most common setup, you always have the robot_state_publisher
running, and your robot is continually reading sensors (e.g. optical
encoders) to figure out the current robot configuration and continually
sending that data out on the /joint_states
topic. Only with both of these
pieces will the full geometric description of the robot be available to all
nodes.
2.4 joint_state_publisher
The joint_state_publisher
has several different functions that can
sometimes be useful. Unlike the robot_state_publisher
, this node is not
always run. The node's basic functionality is to publish /joint_states
information. It can be used to publish a complete /joint_states
message if,
for example, your system isn't talking to a robot. Or it can be used to
publish part of a /joint_states
message if your robot is only providing
information about some of the joints.
This node uses one of four possible sources for collecting information about
all of the non-fixed joints in the URDF, and then it publishes a
sensor_msgs/JointState
topic that has combined all four of these sources to
build a complete sensor_msgs/JointState
message. The four possible sources
are:
- GUI Values: If you set the private parameter
use_gui
to be true (e.g._use_gui:=true
when usingrosrun
), then this tool will automatically pop open a GUI that contain sliders that you can drag around to manually specify the angle of non-fixed joints. sensor_msgs/JointState
topics: You can use thesource_list
private parameter to specify a set of topics that this node should subscribe to. This node will then combine the information from all of these topics and then publish a single topic containing all of the combined information.- Value of another joint: You can setup joints to mimic each other. So if you had some source that was publishing information about one joint, you could setup a different joint to mimic the joint you do have information about. You can also multiply the joint values by a scaling factor (e.g. to mimic a transmission), and the scaling factor can be negative (e.g. you could enforce symmetry of a humanoid robot.
- A default value: If no information is available about a given joint,
this node can still publish a default value. This can be useful for
keeping your whole
/tf
tree connected even if part of your robot's software isn't running.
Generally speaking, it is a bit complicated to describe all of the different ways that this tool can be used. So, I'll present a few use cases that I've encountered, and maybe that will help see what can be done with this tool.
2.4.1 URDF Debugging
One of the ways I've most commonly used this node is during the creation of
URDFs. I'll add a few <joint>
and <link>
tags to my URDF, and then add
that URDF to the parameter server as the /robot_description
parameter,
then I'll run the joint_state_publisher
with ~use_gui
set to true. Then
I'll open rviz
and use the joint_state_publisher
GUI to drag the joint
values around and ensure that the robot model in rviz
behaves as I expect
it to.
2.4.2 Two Arm robot
Imagine you have a robot with two arms (e.g. Baxter or Robonaut), and also
imagine that the controllers for each arm are running as separate nodes. So
you might end up with the /left_arm/joint_states
topic providing the state
of the left arm joints and /right_arm/joint_states
topic providing the
right arm joint states. Then you could run a single robot_state_publisher
in the root namespace (/
) along with a single instance of the
joint_state_publisher
in the root namespace. If you set the ~source_list
private parameter of the joint_state_publisher
to be
["/left_arm/joint_states", "/right_arm/joint_states"]
then the
joint_state_publisher
could publish the /joint_states
topic for the
/robot_state_publisher
node, and this topic would contain the combined
information for both arms.
2.4.3 Baxter Grippers
The Baxter robot has the ability to detect when grippers are
attached/detached to/from his arm, and then automatically, the
/joint_states
topic will either include or exclude gripper position
information. One issue, however, is that the original version of the
robot_state_publisher
doesn't allow for dynamic loading of the URDFs. So,
if you take off a gripper, the only way to get the robot_state_publisher
to properly acknowledge that the gripper is gone and not expect information
about the gripper position is to restart the robot. This is not very
convenient! So, we could just start up an instance of the
joint_state_publisher
that publishes default values for the gripper
states. So the ROS world would still reflect that the gripper is there (even
though it isn't), but at least we would still have a nice /tf
tree (which
is very important). Note that since V1.2 of the Baxter Research SDK, Baxter
now runs a custom, patched version of the robot_state_publisher
called the
mutable_robot_state_publisher that subscribes to a special topic that allows
you to add/remove parts of the URDF without restarting Baxter.
2.5 xacro
xacro
is an xml macro language. It can greatly simplify the creation of URDF files.- Supports basic math, defining constants, conditional blocks, for loops, etc.
- xacro files get parsed and converted into URDF files using the
xacro
node that is part of thexacro
package. Usually this is done at runtime, and the generated URDF is directly added to the parameter server instead of storing it as a file. As an example of how this is done, check out the planning_context.launch file used when using Baxter with MoveIt!. - For most complex robots,
xacro
is used heavily in the creation of the complete URDF. - Check out this xacro tutorial for an idea of how to use xacro to clean up a URDF. The main xacro page also contains a good reference on which macros and features are available.
2.6 Gazebo
- Gazebo is the primary simulation tool of ROS.
- Can simulate kinematics and dynamics including contact, joint controllers, inertia, torque limits, etc.
- Can simulate a variety of sensors
- Cameras
- Laser scanners
- Depth cameras
- IMUs
- Gazebo doesn't use URDF's directly, but rather uses SDF format
- Gazebo will automatically convert URDFs into SDFs
- URDF actually supports several special tags for passing information to the
SDFs that get auto-created by Gazebo
- These tags are ignored by standard ROS tools
- Gazebo uses them when building an SDF