Note: This tutorial assumes you are familiar with the xml markup language.
(!) It is appreciated that problems/questions regarding this tutorial are asked on answers.ros.org. Don't forget to include in your question the link to this page, versions of your OS & ROS, and also add appropriate tags.

Using urdf with robot_state_publisher

Description: This tutorial gives a full example of a robot model with URDF that uses robot_state_publisher. First, we create the URDF model with all the necessary parts. Then we write a node which publishes the JointState and transforms. Finally, we run all the parts together.

Keywords: robot_state_publisher urdf

Tutorial Level: INTERMEDIATE

Create the URDF File

Here is the URDF file for a 7-link model roughly approximating R2-D2. Save the following link to your computer: model.xml

Some Key Features of the URDF

Error: No code_block found

Publishing the State

Now we need a method for specifying what state the robot is in. To do this, we must specify all three joints and the overall odometry. Create a package to include the source code below (throughout this example, we assume package name "r2d2" and node name "state_publisher"):

   1 #include <string>
   2 #include <ros/ros.h>
   3 #include <sensor_msgs/JointState.h>
   4 #include <tf/transform_broadcaster.h>
   5 
   6 int main(int argc, char** argv) {
   7     ros::init(argc, argv, "state_publisher");
   8     ros::NodeHandle n;
   9     ros::Publisher joint_pub = n.advertise<sensor_msgs::JointState>("joint_states", 1);
  10     tf::TransformBroadcaster broadcaster;
  11     ros::Rate loop_rate(30);
  12 
  13     const double degree = M_PI/180;
  14 
  15     // robot state
  16     double tilt = 0, tinc = degree, swivel=0, angle=0, height=0, hinc=0.005;
  17 
  18     // message declarations
  19     geometry_msgs::TransformStamped odom_trans;
  20     sensor_msgs::JointState joint_state;
  21     odom_trans.header.frame_id = "odom";
  22     odom_trans.child_frame_id = "axis";
  23 
  24     while (ros::ok()) {
  25         //update joint_state
  26         joint_state.header.stamp = ros::Time::now();
  27         joint_state.name.resize(3);
  28         joint_state.position.resize(3);
  29         joint_state.name[0] ="swivel";
  30         joint_state.position[0] = swivel;
  31         joint_state.name[1] ="tilt";
  32         joint_state.position[1] = tilt;
  33         joint_state.name[2] ="periscope";
  34         joint_state.position[2] = height;
  35 
  36 
  37         // update transform
  38         // (moving in a circle with radius=2)
  39         odom_trans.header.stamp = ros::Time::now();
  40         odom_trans.transform.translation.x = cos(angle)*2;
  41         odom_trans.transform.translation.y = sin(angle)*2;
  42         odom_trans.transform.translation.z = .7;
  43         odom_trans.transform.rotation = tf::createQuaternionMsgFromYaw(angle+M_PI/2);
  44 
  45         //send the joint state and transform
  46         joint_pub.publish(joint_state);
  47         broadcaster.sendTransform(odom_trans);
  48 
  49         // Create new robot state
  50         tilt += tinc;
  51         if (tilt<-.5 || tilt>0) tinc *= -1;
  52         height += hinc;
  53         if (height>.2 || height<0) hinc *= -1;
  54         swivel += degree;
  55         angle += degree/4;
  56 
  57         // This will adjust as needed per iteration
  58         loop_rate.sleep();
  59     }
  60 
  61 
  62     return 0;
  63 }

Launch File

This launch file assumes you are using the package name "r2d2" and node name "state_publisher".

   1 <launch>
   2         <param name="robot_description" command="cat $(find r2d2)/model.xml" />
   3         <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
   4         <node name="state_publisher" pkg="r2d2" type="state_publisher" />
   5 </launch>

Viewing the Results

First we have to edit the CMakeLists.txt in the package where we saved the above source code. Make sure to add the tf dependency in addition to the other dependencies:

find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs tf)

Notice that roscpp is used to parse the code that we wrote and generate the state_publisher node. We also have to add the following to the end of the CMakelists.txt in order to generate the state_publisher node:

include_directories(include ${catkin_INCLUDE_DIRS})
add_executable(state_publisher state_publisher.cpp)
target_link_libraries(state_publisher ${catkin_LIBRARIES})

Now we should go to the directory of the workspace and build it using:

$ catkin_make

Now launch the package (assuming that our launch file is named display.launch):

$ roslaunch r2d2 display.launch

Run rviz in a new terminal using:

$ rosrun rviz rviz

Choose odom as your fixed frame (under Global Options). Then choose "Add Display" and add a Robot Model Display and a TF Display (see http://www.ros.org/wiki/rviz/UserGuide).

note= You may need to run roscore in another terminal before starting this stuff.

Wiki: urdf/Tutorials/Using urdf with robot_state_publisher (last edited 2014-08-01 04:29:48 by MohamadKaddoura)