Creating a listener

Create a new file in chapter5_tutorials/src with the name tf_listener.cpp and input the following code:

#include <ros/ros.h> 
#include <geometry_msgs/PointStamped.h> 
#include <tf/transform_listener.h> 
 
void transformPoint(const tf::TransformListener& listener){ 
  //we'll create a point in the base_laser frame that we'd like to 
  transform to the base_link frame 
  geometry_msgs::PointStamped laser_point; 
  laser_point.header.frame_id = "base_laser"; 
   
  //we'll just use the most recent transform available for our 
  simple example 
  laser_point.header.stamp = ros::Time(); 
   
  //just an arbitrary point in space 
  laser_point.point.x = 1.0; 
  laser_point.point.y = 2.0; 
  laser_point.point.z = 0.0; 
   
  geometry_msgs::PointStamped base_point; 
  listener.transformPoint("base_link", laser_point, base_point); 
 
  ROS_INFO("base_laser: (%.2f, %.2f. %.2f) -----> base_link: (%.2f, 
  %.2f, %.2f) at time %.2f", 
  laser_point.point.x, laser_point.point.y, laser_point.point.z, 
  base_point.point.x, base_point.point.y, base_point.point.z, 
  base_point.header.stamp.toSec()); 
  ROS_ERROR("Received an exception trying to transform a point from 
  "base_laser" to "base_link": %s", ex.what()); 
   
} 
 
int main(int argc, char** argv){ 
  ros::init(argc, argv, "robot_tf_listener"); 
  ros::NodeHandle n; 
   
  tf::TransformListener listener(ros::Duration(10)); 
   
  //we'll transform a point once every second 
  ros::Timer timer = n.createTimer(ros::Duration(1.0), 
  boost::bind(&transformPoint, boost::ref(listener))); 
   
  ros::spin(); 
} 

Remember to add the line in the CMakeList.txt file to create the executable. Compile the package and run both the nodes using the following commands in each terminal:

    $ catkin_make
    $ rosrun chapter5_tutorials tf_broadcaster
    $ rosrun chapter5_tutorials tf_listener
  

Remember, always run roscore before starting with the examples. You will see the following message:

    [ INFO] [1368521854.336910465]: base_laser: (1.00, 2.00. 0.00) -----> base_link: (1.10, 2.00, 0.20) at time 1368521854.33
    [ INFO] [1368521855.336347545]: base_laser: (1.00, 2.00. 0.00) -----> base_link: (1.10, 2.00, 0.20) at time 1368521855.33
  

This means that the point that you published on the node, with the position (1.00, 2.00, 0.00) relative to base_laser, has the position (1.10, 2.00, 0.20) relative to base_link.

As you can see, the tf library performs all the mathematics for you to get the coordinates of a point or the position of a joint relative to another point.

A transform tree defines offsets in terms of both translation and rotation between different coordinate frames. Let us see an example to help you understand this.

In our robot model, we are going to add another laser, say, on the back of the robot (base_link):

The system in our robot had to know the position of the new laser to detect collisions, such as the one between the wheels and walls. With the tf tree, this is very simple to do and maintain, apart from being scalable. Thanks to tf, we can add more sensors and parts, and the tf library will handle all the relations for us. All the sensors and joints must be correctly configured on tf to permit the navigation stack to move the robot without problems, and to know exactly where each one of their components is.

Before starting to write the code to configure each component, keep in mind that you have the geometry of the robot specified in the URDF file. So, for this reason, it is not necessary to configure the robot again. Perhaps you do not know it, but you have been using the robot_state_publisher package to publish the transform tree of your robot.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.178.9