• 理解ROS tf


    我的理解

    ros的tf反应了一个机器人系统中,不同坐标系之间的关系。以自动驾驶汽车在一个固定园区内行驶为例,自动驾驶汽车有全局utm坐标,园区内地图坐标,然后车辆还装有激光雷达,摄像头等传感器,这些传感器相对于车辆也有对应的相对坐标。在自动驾驶算法里往往涉及这些坐标的输入输出转换调用等操作,如果不统一管理这些坐标系,那么坐标转换等算法将会带来很大麻烦,也不利于代码管理。所以tf就是为了解决这一痛点,让程序员能轻松的知道自己想要的坐标值。比如,我想知道t0时刻,车上相机相对于园区地图的坐标系的值,有了tf就可以轻松实现。

    下图展示的是一个自动驾驶体系里坐标关系图,指令:rosrun rqt_tf_tree rqt_tf_tree
    在这里插入图片描述

    ROS后来又出了tf2,tf2可以看做是tf的扩展,相对于tf来说,tf2引入了相对静态坐标系,如激光雷达在车上安装的位置相对于车辆自身的坐标是恒不变的,那么这就是相对静态坐标系。又如车辆自身坐标系相对于园区地图来说是一直动态变化的,因为车辆在行驶,那么这个就是相对动态坐标系。另外tf2还使用了更多的ROS内置类型,使代码的复用率和可维护性得到了提高。当然代码的接口调用写法也发生了改变。tf2可以实现tf之前所有的功能,然后还加了新功能,但tf2并不是代码层级向下兼容tf的存在。如果之前用tf,现在转tf2,就需要大量重构代码。如果是新项目,那么建议直接使用tf2就可以了。

    代码教学

    tf的代码的写法在官网的教学页里已经讲的很详细了

    tf教学:http://wiki.ros.org/tf/Tutorials

    tf2教学:http://wiki.ros.org/tf2/Tutorials

    这里简单按教学目录里说说

    1. Writing a tf2 static broadcaster
      这一章教你在tf2里如何广播静态坐标系,frame_id字段代表参考坐标系,child_frame_id字段代表在frame_id参考坐标系下的静态子坐标系

    2. Writing a tf2 broadcaster
      这一章教你在tf2里如何广播普通坐标系,frame_id字段代表参考坐标系,child_frame_id字段代表在frame_id参考坐标系下的普通子坐标系,这一章里的broadcaster和上一章里的static broadcaster个人感觉没什么太大写法上的区别,更多的是概念上的区别,以及发布话题的区别,这一章的broadcaster是发布在/tf话题上的,上一章的static broadcaster是发布在/tf_static话题上的。

    3. Writing a tf2 listener
      这一章教你在tf2里如何接收想要的坐标系,比如想知道坐标系A的原点在坐标系B下的坐标是什么。

    4. Adding a frame
      这一章个人感觉和第2章讲的没什么本质区别,adding a frame其实也是broadcaster a new coordinate frame,和第2章的区别感觉就是第2章的发布的是在全局坐标系下(第0级坐标系)子坐标系(第1级坐标系)。那这一章就是发布在第1级坐标系下的第2级坐标系,在第2级坐标系下的第3级坐标系,等等…

    5. Learning about tf2 and time
      这一章教你在tf2里如何等待一个坐标系转换,直到它可用。主要针对ros::Time::now()场景,此场景代表想要现在的坐标,而不是最新的坐标,那现在时刻的坐标可能还没准备好,所以就需要等待,那么如何等待呢,就看这一章是怎么写的就行了。

    6. Time travel with tf2
      这一章主要教你了在tf2里,如何获得在过去一个时间点里想要的坐标和相应的坐标转换。

    常用的CLI

    CLI:Command Line Interface, 命令行接口

    rosrun rqt_tf_tree rqt_tf_tree: 查看实时的tf树结构

    rosrun tf2_tools view_frames.py: 监听5秒,并将tf树存入一个pdf,之后可使用evince frames.pdf来查看该pdf

    rosrun tf tf_echo [reference_frame] [target_frame]查看target_frame在reference_frame坐标下的坐标值

  • 相关阅读:
    【docker】Docker--harbor私有仓库部署与管理——重点
    【并发编程】史上最详细的ReentrantReadWriteLock源码刨析
    这些阻碍程序员升职加薪的行为,你中招了几个?
    Rust : 与C交互动态库和静态库的尝试
    OpenMV与Arduino通信—串口
    js中try...catch和finally的用法
    java多线程中的Fork和Join
    【CSS】伪元素和伪类选择器区别
    文心一言 VS 讯飞星火 VS chatgpt (117)-- 算法导论10.3 2题
    DEC 深度编码聚类函数
  • 原文地址:https://blog.csdn.net/zmhzmhzm/article/details/136455183