tf教程(三):Writing a tf listener
2017-06-30 23:00
232 查看
Writing a tf listener (C++)
Description: This tutorial(辅导的) teachesyou how to use tf to get access to frame(设计) transformations(转化).
Tutorial
Level: BEGINNER
Next
Tutorial: Adding a frame (C++)
目录
How to create a tf listener
The Code
The Code Explained
Running the listener
Checking the results
catkin
rosbuild
In the previous tutorials we created a tf broadcaster to publish the pose(姿势) of a turtle(龟) to
tf. In this tutorial we'll create a tf listener to start using tf.
How to create a tf listener
Let's first create the source files. Go to the package we created in the previous tutorial:$ roscd learning_tf
The Code
Fire up your favorite editor and paste(张贴) the following code into a new file called src/turtle_tf_listener.cpp.https://raw.github.com/ros/geometry_tutorials/hydro-devel/turtle_tf/src/turtle_tf_listener.cpp
切换行号显示
#include <ros/ros.h> #include <tf/transform_listener.h> #include <geometry_msgs/Twist.h> #include <turtlesim/Spawn.h> int main(int argc, char** argv){ ros::init(argc, argv, "my_tf_listener"); ros::NodeHandle node; ros::service::waitForService("spawn"); ros::ServiceClient add_turtle = node.serviceClient<turtlesim::Spawn>("spawn"); turtlesim::Spawn srv; add_turtle.call(srv); ros::Publisher turtle_vel = node.advertise<geometry_msgs::Twist>("turtle2/cmd_vel", 10); tf::TransformListener listener; ros::Rate rate(10.0); while (node.ok()){ tf::StampedTransform transform; try{ listener.lookupTransform("/turtle2", "/turtle1", ros::Time(0), transform); } catch (tf::TransformException &ex) { ROS_ERROR("%s",ex.what()); ros::Duration(1.0).sleep(); continue; } geometry_msgs::Twist vel_msg; vel_msg.angular.z = 4.0 * atan2(transform.getOrigin().y(), transform.getOrigin().x()); vel_msg.linear.x = 0.5 * sqrt(pow(transform.getOrigin().x(), 2) + pow(transform.getOrigin().y(), 2)); turtle_vel.publish(vel_msg); rate.sleep(); } return 0; };
If you get an error "Lookup would require extrapolation(外推法) into the past" while running, you can try this alternative(供选择的) code
to call the listener:
try { listener.waitForTransform(destination_frame, original_frame, ros::Time(0), ros::Duration(10.0) ); listener.lookupTransform(destination_frame, original_frame, ros::Time(0), transform); } catch (tf::TransformException ex) { ROS_ERROR("%s",ex.what()); }
The Code Explained
Now, let's take a look at the code that is relevant(有关的) to publishing the turtle(龟) pose(造成) totf.
切换行号显示
2 #include <tf/transform_listener.h> 3
The tf package provides an implementation(实现) of a TransformListener to help make the task of receiving transforms(改变)easier.
To use the TransformListener, we need to include the tf/transform_listener.h header file.
切换行号显示
20 tf::TransformListener listener;
Here, we create a TransformListener object. Once the listener is created, it starts receiving tf transformations(转化) over
the wire, and buffers them for up to 10 seconds. The TransformListener object should be scoped(审视) to persist(存留)otherwise
it's cache will be unable to fill and almost every query will fail. A common method is to make the TransformListener object a member variable(变量) of
a class.
切换行号显示
25 try{ 26 listener.lookupTransform("/turtle2", "/turtle1", 27 ros::Time(0), transform); 28 }
Here, the real work is done, we query the listener for a specific(特殊的) transformation(转化).
Let's take a look at the four arguments:
We want the transform(改变) from this frame(框架) ...
... to this frame.
The time at which we want to transform. Providing ros::Time(0) will just get us the latest available transform.
The object in which we store the resulting transform.
All this is wrapped(包) in a try-catch block to catch possible exceptions(例外).
切换行号显示
35 geometry_msgs::Twist vel_msg; 36 vel_msg.angular.z = 4.0 * atan2(transform.getOrigin().y(), 37 transform.getOrigin().x()); 38 vel_msg.linear.x = 0.5 * sqrt(pow(transform.getOrigin().x(), 2) +
Here, the transform is used to calculate(计算) new linear(线的) and angular(有角的) velocities(速率) for turtle(龟)2,
based on its distance and angle from turtle1. The new velocity is published in the topic "turtle2/cmd_vel" and the sim will use that to update turtle2's movement.
Running the listener
Now that we created the code, lets compile(编译) it first. Open the CMakeLists.txt file, and addthe following line on the bottom:
add_executable(turtle_tf_listener src/turtle_tf_listener.cpp) target_link_libraries(turtle_tf_listener ${catkin_LIBRARIES})
Build your package at the top folder of your catkin workspace:
$ catkin_make
If everything went well, you should have a binary(二进制的) file called turtle_tf_listener in
your devel/lib/learning_tf folder.
If so, we're ready add it the launch(发射) file for this demo. With your text editor, open the launch file called start_demo.launch,
and merge(合并) the node block below inside the <launch> block:
<launch> ... <node pkg="learning_tf" type="turtle_tf_listener" name="listener" /> </launch>
First, make sure you stopped the launch file from the previous tutorial(辅导的) (use ctrl-c). Now you're ready to start your full turtle(龟) demo:
$ roslaunch learning_tf start_demo.launch
You should see the turtlesim with two turtles.
Checking the results
To see if things work, simply drive around the first turtle(龟) using the arrow keys (make sure your terminal window is active, notyour simulator(模拟器) window), and you'll see the second turtle following the first one!
When the turtlesim starts up you may see:
[ERROR] 1253915565.300572000: Frame id /turtle2 does not exist! When trying to transform between /turtle1 and /turtle2. [ERROR] 1253915565.401172000: Frame id /turtle2 does not exist! When trying to transform between /turtle1 and /turtle2.
This happens because our listener is trying to compute the transform(改变) before messages about turtle 2 have been received because
it takes a little time to spawn(产卵) in turtlesim and start broadcasting a tf frame(框架).
Now you're ready to move on to the next tutorial(辅导的), where you'll learn how to add a frame (Python) (C++)
相关文章推荐
- tf教程(二):Writing a tf broadcaster
- ROS:关于tf的探索(2)Writing a tf listener(Python)
- Writing a tf listener (C++)
- GestureDetector和SimpleOnGestureListener的使用教程
- 深入浅出的TensorFlow数据格式化存储工具TFRecord用法教程
- GestureDetector和SimpleOnGestureListener的使用教程[转]
- ExtJS建立大型项目应用教程实例总结Tutorial:Writing a Big Application in Ext
- Android触控屏幕Gesture(GestureDetector和SimpleOnGestureListener的使用教程)
- Android触控屏幕Gesture(GestureDetector和SimpleOnGestureListener的使用教程)
- GestureDetector和SimpleOnGestureListener的使用教程
- 编写一个tf listener
- ROS学习(二十)--tf/写broadcaster和listener
- Mac OS下安装配置Git-TF连接TFS2012教程
- Android实战简易教程-第五十三枪(通过实现OnScrollListener接口实现上拉加载更多功能)
- GestureDetector和SimpleOnGestureListener的使用教程
- ****Android开发教程:OnScrollListener实现ListView滚屏时不加载数据
- 阿里云机器学习平台PAI的视频介绍(其中tensorflow高级教程有tf的代码优化讲解)
- tf教程(五):Learning about tf and time
- tensorflow教程:tf.dynamic_rnn
- GestureDetector和SimpleOnGestureListener的使用教程