博客参考:https://www.ncnynl.com/archives/201702/1310.html
ROS与C++入门教程-tf-编写tf broadcaster(广播)
说明:
- 介绍如何广播机器人的坐标系到tf。
准备:
- 在我们开始之前,你需要为这个项目创建一个新的ros包。
- 创建一个名为learning_tf的软件包,该软件包依赖于tf,roscpp,rospy和turtlesim:
$ cd ~/catkin_ws/src $ catkin_create_pkg learning_tf tf roscpp rospy turtlesim $ cd ~/catkin_ws/src $ catkin_make $ source ./devel/setup.bash
广播变换
- 新建文件turtle_tf_broadcaster.cpp. 参考源码
$ roscd learning_tf $ touch src/turtle_tf_broadcaster.cpp
- 代码如下:
#include <ros/ros.h> #include <tf/transform_broadcaster.h> #include <turtlesim/Pose.h> std::string turtle_name; void poseCallback(const turtlesim::PoseConstPtr& msg){ static tf::TransformBroadcaster br; tf::Transform transform; transform.setOrigin( tf::Vector3(msg->x, msg->y, 0.0) ); tf::Quaternion q; q.setRPY(0, 0, msg->theta); transform.setRotation(q); br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "world", turtle_name)); } int main(int argc, char** argv){ ros::init(argc, argv, "my_tf_broadcaster"); if (argc != 2){ROS_ERROR("need turtle name as argument"); return -1;}; turtle_name = argv[1]; ros::NodeHandle node; ros::Subscriber sub = node.subscribe(turtle_name+"/pose", 10, &poseCallback); ros::spin(); return 0; };
代码解释:
-
代码:#include <tf/transform_broadcaster.h>
-
作用:
- tf包提供了TransformBroadcaster的实现,以帮助使发布变换的任务更容易。
- 要使用TransformBroadcaster,我们需要包含tf/transform_broadcaster.h头文件。
-
代码:static tf::TransformBroadcaster br;
-
作用:我们创建一个TransformBroadcaster对象,我们稍后将使用它通过线路发送转换。
-
代码:
tf::Transform transform; transform.setOrigin( tf::Vector3(msg->x, msg->y, 0.0) ); tf::Quaternion q; q.setRPY(0, 0, msg->theta);
-
作用:这里我们创建一个Transform对象,并将信息从2D乌龟姿势复制到3D变换中。
-
代码:transform.setRotation(q);
-
作用:这里我们设置旋转。
-
代码:br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "world", turtle_name));
-
作用:
- 这是真正的工作完成的地方。
- 使用TransformBroadcaster发送转换需要四个参数。
- 首先,我们传递转换本身。
- 现在我们需要给被发布的变换一个时间戳,我们只是用当前时间戳它,ros::Time::now().
- 然后,我们需要传递我们创建的链接的父框架的名称,在这种情况下为“world”
- 最后,我们需要传递我们正在创建的链接的子框架的名称,在这种情况下,这是乌龟本身的名称。
-
注意:sendTransform和StampedTransform具有父对象和子对象的相反顺序。
运行广播
- 编辑CMakeLists.txt文件,增加:
add_executable(turtle_tf_broadcaster src/turtle_tf_broadcaster.cpp) target_link_libraries(turtle_tf_broadcaster ${catkin_LIBRARIES})
- 编译:
$ cd ~/catkin_ws/src $ catkin_make
-
如果编译顺利, 生成二进制的turtle_tf_broadcaster文件,位于devel/lib/learning_tf
-
创建 start_demo.launch,用于启动节点,内容如下:
<launch> <!-- Turtlesim Node--> <node pkg="turtlesim" type="turtlesim_node" name="sim"/> <node pkg="turtlesim" type="turtle_teleop_key" name="teleop" output="screen"/> <!-- Axes --> <param name="scale_linear" value="2" type="double"/> <param name="scale_angular" value="2" type="double"/> <node pkg="learning_tf" type="turtle_tf_broadcaster" args="/turtle1" name="turtle1_tf_broadcaster" /> <node pkg="learning_tf" type="turtle_tf_broadcaster" args="/turtle2" name="turtle2_tf_broadcaster" /> </launch>
- 执行launch
$ roslaunch learning_tf start_demo.launch
- 你应该看到乌龟模拟另一个乌龟。
检查结果:
- 现在,使用tf_echo工具检查龟的姿势是否真正得到广播到tf
$ rosrun tf tf_echo /world /turtle1
- 这应该显示第一只乌龟的姿势。 使用箭头键(确保您的终端窗口是活动的,而不是你的模拟器窗口)绕乌龟。
- 如果你运行tf_echo在/world和/turtle2之间的转换,你不应该看到一个变换,因为第二个乌龟还没有。
- 但是,一旦我们在下一个教程中添加第二只乌龟,turtle2的姿势将被广播到tf。