【ROS】官方tf教程turtle_tf2源码原理解读

程序需要沉淀沉淀再沉淀!!!


前言

主要是学习tf坐标变换时候太吃力了,因此先学习官方给的小乌龟跟随这里的tf坐标变换。


直接上源码吧!!!turtle_tf2_broadcaster.cpp 内容如下:

 

 先从主函数开始吧:

35行:ros::init(argc, argv, "my_tf2_broadcaster");这一句就不说了,稍微学过ros的就知道是啥了。

37行:ros::NodeHandle private_node("~");创建一个节点的句柄,用来参数服务器语句的判断。此处和我们定义node的方式不一样。以往我们定义node基本都是直接ros::NodeHandle nh。这里咋就多了一个参数~呢?;表示这个nodehandle是读取局部参数。

38行:if (! private_node.hasParam("turtle"));判断参数服务器中是否存在turtle这个参数,如果没有,则执行else语句。

先看if语句里面的内容:if (argc != 2){ROS_ERROR("need turtle name as argument"); return -1;};判断argc里面的个数是否为2,如果不为2,那么打印ROS_ERROR("need turtle name as argument");并退出节点。如果argc==2,那么将argv[1]赋值给turtle_name,这里有同学可能会问,为什么不讲argv[0]里面的值给到turtle_name;是因为不管有没有参数输入进来,argv[0]永远都是可执行程序的名字。

48行:private_node.getParam("turtle", turtle_name);就是将参数服务器里面turtle的值赋值给到turtle_name这个字符串(第7行定义了turtle_name是一个字符串类型的数据)。

51行:ros::NodeHandle node;创建一个节点句柄,用来订阅回调函数poseCallback。

poseCallback

54行:ros::Subscriber sub = node.subscribe(turtle_name+"/pose", 10, &poseCallback);// 第一个参数指定订阅话题topic;第二个参数设置消息缓冲区的大小;第三个参数指定回调函数。这里需要注意的是turtle_name是一个变量;turtle_tf2_broadcaster_cpp.launch文件里面有说明,最后再讲。

57行:ros::spin();这个就不说了。

接下来看回调函数poseCallback:

13行:static tf2_ros::TransformBroadcaster br;// 定义一个广播TransformBroadcaster,将坐标变换通过话题发布出去,这里为什么是用static,是为了防止重复,因为turtle_tf2_listener.cpp也用到了。

14行:geometry_msgs::TransformStamped transformStamped;实例化transformStamped结构体
  

16-21行:

    transformStamped.header.stamp = ros::Time::now();
    transformStamped.header.frame_id = "world";
    transformStamped.child_frame_id = turtle_name;
    transformStamped.transform.translation.x = msg->x;
    transformStamped.transform.translation.y = msg->y;
    transformStamped.transform.translation.z = 0.0;

ros::Time::now();表示ros里面当前的时间;world是父坐标;turtle_name是子坐标。

具体两个坐标之间的关系是怎么样的呢?自然就涉及到给坐标系之间的rotation和translation赋值。我们说回调函数接收到的是turtle的位置和方向,那么msg中的位置和方向我们就需要赋值transformStamped。先赋值 translation,后赋值 rotation 。19-20行 这里将x轴y轴的坐标赋值给了transformStamped。这里的理解讲得很清楚了。

23行:tf2::Quaternion q;  //头文件部分包含了#include <tf2/LinearMath/Quaternion.h>,代码有一行定义了tf::quaternion的对象tf::Quaternion q需要通过包含这个头文件来实现。

24行:q.setRPY(0, 0, msg->theta);调用了Quaternion中setRPY函数来获取角度值。

25-28行:这里是获取角度,以四元数的形式来获取。

30行:br.sendTransform(transformStamped);将获取的transformStamped发送出去,主函数来订阅。

最后讲一下turtle_tf2_broadcaster_cpp.launch里面的内容吧:

第4和第6行分别是创建一个海龟、开启键盘控制节点。

第8、9行就不说了,太简单了没意思。

第11-18行是node语法,不懂的同学需要自行去学习一下node节点的语法。这里提一下:仔细看这段程序我们会发现:功能turtle_tf2里面的可执行文件turtle_tf2_broadcaster被调用了2次,用一个功能包执行2种不同的参数输入,这样不就提高了代码的复用率了吗?答案是的。

第17到18行是开启监听器的节点,下章节再讲吧,打字太累了哈哈哈。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值