/!\ XML verbatim blocks are broken, all special charaters are not displayed.

Note: You should understand the basics of XML and the xacro language before reading this..
(!) Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags.

Understanding the PR2 Robot Description

Description: This tutorial explains the layout of the top level URDF Xacro file for a complex robot such as PR2.

Tutorial Level: INTERMEDIATE

Note: This tutorial still refers to the description in pr2_defs, which has now been replaced by the one in pr2_description. Although similar, there have been changes between this URDF and the current one used by the PR2. In particular, the XML schemas specified in the <robot> element are no longer required by Gazebo, and all references to Gazebo plugins are incorrect as their API has changed considerably.

A full PR2 URDF macro file can be found in the pr2_description package in the file robots/pr2.urdf.xacro. A snapshot of it is presented here for dissection.

   1 <?xml version="1.0"?>
   2 <robot xmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor"
   3        xmlns:controller="http://playerstage.sourceforge.net/gazebo/xmlschema/#controller"
   4        xmlns:interface="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface"
   5        xmlns:xacro="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface"
   6        name="pr2" >
   7   
   8   <!-- The following included files set up definitions of parts of the robot body -->
   9   <!-- misc common stuff? -->
  10   <include filename="$(find pr2_description)/urdf/common.xacro" />
  11   <!-- PR2 Arm -->
  12   <include filename="$(find pr2_description)/urdf/shoulder_v0/shoulder.urdf.xacro" />
  13   <include filename="$(find pr2_description)/urdf/upper_arm_v0/upper_arm.urdf.xacro" />
  14   <include filename="$(find pr2_description)/urdf/forearm_v0/forearm.urdf.xacro" />
  15   <!-- PR2 gripper -->
  16   <include filename="$(find pr2_description)/urdf/gripper_v0/gripper.urdf.xacro" />
  17   <!-- PR2 head -->
  18   <include filename="$(find pr2_description)/urdf/head_v0/head.urdf.xacro" />
  19   <!-- PR2 tilting laser mount -->
  20   <include filename="$(find pr2_description)/urdf/tilting_laser_v0/tilting_laser.urdf.xacro" />
  21   <!-- PR2 torso -->
  22   <include filename="$(find pr2_description)/urdf/torso_v0/torso.urdf.xacro" />
  23   <!-- PR2 base -->
  24   <include filename="$(find pr2_description)/urdf/base_v0/base.urdf.xacro" />
  25   <!-- Head sensors -->
  26   <include filename="$(find pr2_description)/urdf/sensors/head_sensor_package.urdf.xacro" />
  27   <!-- Camera sensors -->
  28   <include filename="$(find pr2_description)/urdf/sensors/wge100_camera.urdf.xacro" />
  29   <!-- generic simulator_gazebo plugins for starting mechanism control, ros time, ros battery -->
  30   <include filename="$(find pr2_description)/gazebo/gazebo.urdf.xacro" />
  31   <!-- materials for visualization -->
  32   <include filename="$(find pr2_description)/urdf/materials.urdf.xacro" />
  33 
  34   <!-- Now we can start using the macros included above to define the actual PR2 -->
  35 
  36   <!-- The first use of a macro.  This one was defined in base.urdf.xacro above.
  37        A macro like this will expand to a set of link and joint definitions, and to additional
  38        Gazebo-related extensions (sensor plugins, etc).  The macro takes an argument, name, 
  39        that equals "base", and uses it to generate names for its component links and joints 
  40        (e.g., base_link).  The included origin block is also an argument to the macro.  By convention, 
  41        the origin block defines where the component is w.r.t its parent (in this case the parent 
  42        is the world frame). For more, see http://www.ros.org/wiki/xacro -->
  43   <xacro:pr2_base_v0 name="base" >
  44     <origin xyz="0 0 0.051" rpy="0 0 0" /> <!-- 5.1cm is the height of the base when wheels contact ground -->
  45   </xacro:pr2_base_v0>
  46 
  47   <xacro:pr2_torso_v0 name="torso_lift" parent="base_link">
  48     <origin xyz="-0.05 0 0.739675" rpy="0 0 0" />
  49   </xacro:pr2_torso_v0>
  50 
  51   <!-- The xacro preprocesser will replace the parameters below, such as ${cal_head_x}, with
  52        numerical values that were specified in common.xacro which was included above -->
  53   <xacro:pr2_head_v0 name="head" parent="torso_lift_link">
  54     <origin xyz="${cal_head_x}    ${cal_head_y}     ${0.3915+cal_head_z}"
  55             rpy="${cal_head_roll} ${cal_head_pitch} ${cal_head_yaw}" />
  56   </xacro:pr2_head_v0>
  57 
  58   <!-- Camera package: double stereo, prosilica -->
  59   <xacro:pr2_head_sensor_package_v0 name="sensor_mount" hd_name="high_def" 
  60                            stereo_name="double_stereo" 
  61                            parent="head_plate_frame">
  62     <origin xyz="0.0 0.0 0.0" rpy="0 0 0" />
  63   </xacro:pr2_head_sensor_package_v0>
  64 
  65   <xacro:pr2_tilting_laser_v0 name="laser_tilt" parent="torso_lift_link" laser_calib_ref="-0.35">
  66     <origin xyz="0.1 0 0.235" rpy="0 0 0" />
  67   </xacro:pr2_tilting_laser_v0>
  68 
  69   <!-- This is a common convention, to use a reflect parameter that equals +-1 to distinguish left from right -->
  70   <xacro:pr2_shoulder_v0 side="r" reflect="-1" parent="torso_lift_link">
  71     <origin xyz="0.0 -0.188 0.0" rpy="0 0 0" />
  72   </xacro:pr2_shoulder_v0>
  73   <xacro:pr2_upper_arm_v0 side="r" reflect="-1" parent="r_upper_arm_roll_link"/>
  74   <xacro:pr2_forearm_v0 side="r" reflect="-1" parent="r_forearm_roll_link"/>
  75 
  76   <xacro:pr2_gripper_v0 side="r" parent="r_wrist_roll_link"
  77                screw_reduction="${4.0/1000.0}"
  78                gear_ratio="${(729.0/25.0)*(22.0/16.0)}"
  79                theta0="${3.6029*M_PI/180.0}"
  80                phi0="${29.7089*M_PI/180.0}"
  81                t0="${-0.1914/1000.0}"
  82                L0="${37.5528/1000.0}"
  83                h="${0.0/1000.0}"
  84                a="${68.3698/1000.0}"
  85                b="${43.3849/1000.0}"
  86                r="${91.5/1000.0}" >
  87     <origin xyz="0 0 0" rpy="0 0 0" />
  88   </xacro:pr2_gripper_v0>
  89 
  90   <xacro:pr2_shoulder_v0 side="l" reflect="1" parent="torso_lift_link">
  91     <origin xyz="0.0 0.188 0.0" rpy="0 0 0" />
  92   </xacro:pr2_shoulder_v0>
  93   <xacro:pr2_upper_arm_v0 side="l" reflect="1" parent="l_upper_arm_roll_link"/>
  94   <xacro:pr2_forearm_v0 side="l" reflect="1" parent="l_forearm_roll_link"/>
  95 
  96   <xacro:pr2_gripper_v0 side="l" parent="l_wrist_roll_link"
  97                screw_reduction="${4.0/1000.0}"
  98                gear_ratio="${(729.0/25.0)*(22.0/16.0)}"
  99                theta0="${3.6029*M_PI/180.0}"
 100                phi0="${29.7089*M_PI/180.0}"
 101                t0="${-0.1914/1000.0}"
 102                L0="${37.5528/1000.0}"
 103                h="${0.0/1000.0}"
 104                a="${68.3698/1000.0}"
 105                b="${43.3849/1000.0}"
 106                r="${91.5/1000.0}" >
 107     <origin xyz="0 0 0" rpy="0 0 0" />
 108   </xacro:pr2_gripper_v0>
 109 
 110   <!-- Forearm Cam (Hand approximated values) -->
 111   <xacro:wge100_camera_v0 name="l_forearm_cam" image_format="L8" image_topic_name="l_forearm_cam/image_raw"
 112                           camera_info_topic_name="l_forearm_cam/camera_info"
 113                           parent="l_forearm_roll_link" hfov="90" focal_length="320"
 114                           frame_id="l_forearm_cam_frame" hack_baseline="0"
 115                           image_width="640" image_height="480">
 116     <origin xyz=".15 0 .07" rpy="${ M_PI/2} ${-45*M_PI/180} 0" />
 117   </xacro:wge100_camera_v0>
 118   <xacro:wge100_camera_v0 name="r_forearm_cam" image_format="L8" image_topic_name="r_forearm_cam/image_raw"
 119                           camera_info_topic_name="r_forearm_cam/camera_info"
 120                           parent="r_forearm_roll_link" hfov="90" focal_length="320"
 121                           frame_id="r_forearm_cam_frame" hack_baseline="0"
 122                           image_width="640" image_height="480">
 123     <origin xyz=".15 0 .07" rpy="${-M_PI/2} ${-45*M_PI/180} 0" />
 124   </xacro:wge100_camera_v0>
 125 
 126 </robot>

Now let's break down the entire XML piece by piece:

   2 <robot xmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor"
   3        xmlns:controller="http://playerstage.sourceforge.net/gazebo/xmlschema/#controller"
   4        xmlns:interface="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface"
   5        xmlns:xacro="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface"
   6        name="pr2" >

The root element for the XML must be robot with a name attribute. XML namespaces are declared here.

   8   <!-- The following included files set up definitions of parts of the robot body -->
   9   <!-- misc common stuff? -->
  10   <include filename="$(find pr2_description)/urdf/common.xacro" />
  11   <!-- PR2 Arm -->
  12   <include filename="$(find pr2_description)/urdf/shoulder_v0/shoulder.urdf.xacro" />
  13   <include filename="$(find pr2_description)/urdf/upper_arm_v0/upper_arm.urdf.xacro" />
  14   <include filename="$(find pr2_description)/urdf/forearm_v0/forearm.urdf.xacro" />
  15   <!-- PR2 gripper -->
  16   <include filename="$(find pr2_description)/urdf/gripper_v0/gripper.urdf.xacro" />
  17   <!-- PR2 head -->
  18   <include filename="$(find pr2_description)/urdf/head_v0/head.urdf.xacro" />
  19   <!-- PR2 tilting laser mount -->
  20   <include filename="$(find pr2_description)/urdf/tilting_laser_v0/tilting_laser.urdf.xacro" />
  21   <!-- PR2 torso -->
  22   <include filename="$(find pr2_description)/urdf/torso_v0/torso.urdf.xacro" />
  23   <!-- PR2 base -->
  24   <include filename="$(find pr2_description)/urdf/base_v0/base.urdf.xacro" />
  25   <!-- Head sensors -->
  26   <include filename="$(find pr2_description)/urdf/sensors/head_sensor_package.urdf.xacro" />
  27   <!-- Camera sensors -->
  28   <include filename="$(find pr2_description)/urdf/sensors/wge100_camera.urdf.xacro" />
  29   <!-- generic simulator_gazebo plugins for starting mechanism control, ros time, ros battery -->
  30   <include filename="$(find pr2_description)/gazebo/gazebo.urdf.xacro" />
  31   <!-- materials for visualization -->
  32   <include filename="$(find pr2_description)/urdf/materials.urdf.xacro" />

Include files containing xacro macros for inidividual robot components. This is like including a header file in C: it sets up a bunch of definitions but doesn't actually call any of them. For example, pr2_common/pr2_description/urdf/shoulder_v0/shoulder.urdf.xacro contains xacro macros for the PR2 shoulder. And the PR2 base macro xacro:pr2_base_v0 is in the included file pr2_description/urdf/base_v0/base.urdf.xacro. This macro has the following nested structure:

  • xacro:pr2_base_v0 - defines the PR2 base, complete with 4 casters and 8 wheels, and a laser range finder.

    • xacro:pr2_caster_v0 - PR2 casters, attached to the base

      • xacro:pr2_wheel_v0 - PR2 wheels, attached to the casters

  34   <!-- Now we can start using the macros included above to define the actual PR2 -->
  35 
  36   <!-- The first use of a macro.  This one was defined in base.urdf.xacro above.
  37        A macro like this will expand to a set of link and joint definitions, and to additional
  38        Gazebo-related extensions (sensor plugins, etc).  The macro takes an argument, name, 
  39        that equals "base", and uses it to generate names for its component links and joints 
  40        (e.g., base_link).  The included origin block is also an argument to the macro.  By convention, 
  41        the origin block defines where the component is w.r.t its parent (in this case the parent 
  42        is the world frame). For more, see http://www.ros.org/wiki/xacro -->

Some useful comments.

  43   <xacro:pr2_base_v0 name="base" >
  44     <origin xyz="0 0 0.051" rpy="0 0 0" /> <!-- 5.1cm is the height of the base when wheels contact ground -->
  45   </xacro:pr2_base_v0>

Now we actually use the macros defined above. Here, we define PR2's base, using the xacro:pr2_base_v0 macro, with name parameter equal to "base" and an origin parameter block. After running the original file through the xacro preprocessor, this element will be replaced with a rather long URDF definition of the base and its components.

  47   <xacro:pr2_torso_v0 name="torso_lift" parent="base_link">
  48     <origin xyz="-0.05 0 0.739675" rpy="0 0 0" />
  49   </xacro:pr2_torso_v0>

Similarly, we define the PR2 torso, using the xacro:pr2_torso_v0 macro, which can be found in the included file pr2_description/urdf/torso_v0/torso.urdf.xacro.

The origin block seen here occurs in most of the macros. We use it to denote where the link being defined is in relation to its parent link. Here, it says where the torso_lift_link starts off in relation to its parent (base_link).

  51   <!-- The xacro preprocesser will replace the parameters below, such as ${cal_head_x}, with
  52        numerical values that were specified in common.xacro which was included above -->
  53   <xacro:pr2_head_v0 name="head" parent="torso_lift_link">
  54     <origin xyz="${cal_head_x}    ${cal_head_y}     ${0.3915+cal_head_z}"
  55             rpy="${cal_head_roll} ${cal_head_pitch} ${cal_head_yaw}" />
  56   </xacro:pr2_head_v0>

Next we use xacro:pr2_head_v0 macro. It can be found in the included file pr2_description/urdf/head_v0/head.urdf.xacro. Note that rather than hardcoded numbers for the origin, we're using constants (that were defined in the calibration file included above:pr2_description/urdf/common.xacro).

PR2 head macros are nested as follows:

  • xacro:pr2_head_v0

    • xacro:pr2_head_pan_v0

    • xacro:pr2_head_tilt_v0

  58   <!-- Camera package: double stereo, prosilica -->
  59   <xacro:pr2_head_sensor_package_v0 name="sensor_mount" hd_name="high_def" 
  60                            stereo_name="double_stereo" 
  61                            parent="head_plate_frame">
  62     <origin xyz="0.0 0.0 0.0" rpy="0 0 0" />
  63   </xacro:pr2_head_sensor_package_v0>

PR2 head sensor packages, including two interlacing stereo cameras and a high resolution Prosilica GC2450 camera.

  65   <xacro:pr2_tilting_laser_v0 name="laser_tilt" parent="torso_lift_link" laser_calib_ref="-0.35">
  66     <origin xyz="0.1 0 0.235" rpy="0 0 0" />
  67   </xacro:pr2_tilting_laser_v0>

PR2 tilting Hokuyo laser range scanner.

  69   <!-- This is a common convention, to use a reflect parameter that equals +-1 to distinguish left from right -->
  70   <xacro:pr2_shoulder_v0 side="r" reflect="-1" parent="torso_lift_link">
  71     <origin xyz="0.0 -0.188 0.0" rpy="0 0 0" />
  72   </xacro:pr2_shoulder_v0>
  73   <xacro:pr2_upper_arm_v0 side="r" reflect="-1" parent="r_upper_arm_roll_link"/>
  74   <xacro:pr2_forearm_v0 side="r" reflect="-1" parent="r_forearm_roll_link"/>
  75 
  76   <xacro:pr2_gripper_v0 side="r" parent="r_wrist_roll_link"
  77                screw_reduction="${4.0/1000.0}"
  78                gear_ratio="${(729.0/25.0)*(22.0/16.0)}"
  79                theta0="${3.6029*M_PI/180.0}"
  80                phi0="${29.7089*M_PI/180.0}"
  81                t0="${-0.1914/1000.0}"
  82                L0="${37.5528/1000.0}"
  83                h="${0.0/1000.0}"
  84                a="${68.3698/1000.0}"
  85                b="${43.3849/1000.0}"
  86                r="${91.5/1000.0}" >
  87     <origin xyz="0 0 0" rpy="0 0 0" />
  88   </xacro:pr2_gripper_v0>
  89 
  90   <xacro:pr2_shoulder_v0 side="l" reflect="1" parent="torso_lift_link">
  91     <origin xyz="0.0 0.188 0.0" rpy="0 0 0" />
  92   </xacro:pr2_shoulder_v0>
  93   <xacro:pr2_upper_arm_v0 side="l" reflect="1" parent="l_upper_arm_roll_link"/>
  94   <xacro:pr2_forearm_v0 side="l" reflect="1" parent="l_forearm_roll_link"/>
  95 
  96   <xacro:pr2_gripper_v0 side="l" parent="l_wrist_roll_link"
  97                screw_reduction="${4.0/1000.0}"
  98                gear_ratio="${(729.0/25.0)*(22.0/16.0)}"
  99                theta0="${3.6029*M_PI/180.0}"
 100                phi0="${29.7089*M_PI/180.0}"
 101                t0="${-0.1914/1000.0}"
 102                L0="${37.5528/1000.0}"
 103                h="${0.0/1000.0}"
 104                a="${68.3698/1000.0}"
 105                b="${43.3849/1000.0}"
 106                r="${91.5/1000.0}" >
 107     <origin xyz="0 0 0" rpy="0 0 0" />
 108   </xacro:pr2_gripper_v0>

Defines PR2 left and right arms, from shoulder pan link to the gripper.

 110   <!-- Forearm Cam (Hand approximated values) -->
 111   <xacro:wge100_camera_v0 name="l_forearm_cam" image_format="L8" image_topic_name="l_forearm_cam/image_raw"
 112                           camera_info_topic_name="l_forearm_cam/camera_info"
 113                           parent="l_forearm_roll_link" hfov="90" focal_length="320"
 114                           frame_id="l_forearm_cam_frame" hack_baseline="0"
 115                           image_width="640" image_height="480">
 116     <origin xyz=".15 0 .07" rpy="${ M_PI/2} ${-45*M_PI/180} 0" />
 117   </xacro:wge100_camera_v0>
 118   <xacro:wge100_camera_v0 name="r_forearm_cam" image_format="L8" image_topic_name="r_forearm_cam/image_raw"
 119                           camera_info_topic_name="r_forearm_cam/camera_info"
 120                           parent="r_forearm_roll_link" hfov="90" focal_length="320"
 121                           frame_id="r_forearm_cam_frame" hack_baseline="0"
 122                           image_width="640" image_height="480">
 123     <origin xyz=".15 0 .07" rpy="${-M_PI/2} ${-45*M_PI/180} 0" />
 124   </xacro:wge100_camera_v0>

Defines the forearm cameras.

Next Tutorial: Understanding the PR2 Robot Description, Part 2

Wiki: urdf/Tutorials/UnderstandingPR2URDF (last edited 2013-05-21 03:07:47 by davetcoleman)