一、题目各个坐标系的含义

背景:
本文以 gmapping 为例,其中 map、odom、base_link、laser 均来自 gmapping 中的坐标系。这里的 gmapping 是指使用laser_scan_matcher包,在仅使用激光雷达、无需里程计的情况下跑 gmapping。
下图是执行rosrun rqt_tf_tree rqt_tf_tree的结果:

  • map:可以理解为世界坐标系
  • odom:机器人以为的世界坐标系
  • base_link:机器人本体坐标系
  • laser:激光雷达坐标系

二、对坐标系的理解

  • map:地图坐标系,顾名思义,一般设该坐标系为固定坐标系(fixed frame,rviz中的设置项),一般与机器人所在的世界坐标系一致。
  • base_link:机器人本体坐标系,与机器人中心重合,原点一般为机器人的旋转中心。当然有些机器人(PR 2)是 base_footprint,其实意思差不多,base_footprint 坐标系原点为 base_link 原点在地面的投影,有些许区别(z值不同)。
  • odom:里程计坐标系,这里要区分开odom topic,这是两个概念,一个是坐标系(本文),一个是根据编码器或者视觉等计算的里程计。但是两者也有关系,odom topic 转化的位姿矩阵是odom–>base_link的tf关系。这时可能会有疑问,odom 和 map 坐标系是不是重合的?可以很肯定地说,机器人起始运动位置这两者是重合的。但是,随着时间的推移是不重合的,而出现的偏差就是里程计的累积误差。那 map–>odom 的 tf 怎么得到?就是在一些校正传感器合作校正的 package 比如 amcl 会给出一个位置估计(localization),这可以得到 map–>base_link 的 tf,所以估计位置和里程计位置的偏差也就是 odom 与 map 的坐标系偏差。所以,如果你的 odom 计算没有错误,那么 map–>odom 的 tf 就是 0。
  • laser:激光雷达的坐标系,与激光雷达的安装点有关,其与 base_link 的 tf 为固定的。

三、对于 map --> odom 举个例子

  • 首先,我们制定机器人路径时,使用的必然是绝对坐标系。要完成这件事,机器人需要先知道自己在哪。它没有GPS,所以只能倒推——通过里程计。这也是为什么“没有偏移的话 odam 应该与 map 重合”,因为 odam 本来就是用来倒推 map 的。
  • 假设机器人终点定在了(8,5),初始时刻,map 的(8,5)和 odom 的(8,5)是重合的。
  • odom 坐标系视角看运动过程:假设里程计告诉它,自原点启动起,它在 X 方向移动 2 ,Y 方向移动 5 ,运动描述为(+2,+5)。于是它就认为自己在 odom 坐标系下的(2,5)。反馈给 base_link,则 base_link 坐标系下,机器人需要运动(8,5) - (2,5) = (+6,+0)才能到达目标点(8,5)。而此时如果机器人按(+6,+0)运动完后,确实能到达odom下的终点(8,5),并开始以完成任务为由而沾沾自喜,殊不知,它并没有运动到真正的终点终点:map 坐标系下的(8,5)。
  • map 坐标系看运动过程:然而实际上,因为里程计累计误差,它其实第一次运动到了(3,4)。但在 odom 中它在(2,5)。它理应运动(8,5)-(3,4) = (+5,+1)到达目标点,但它会运动(+6,+0),因为 odam 反馈给 base_link 后,目标在 base_link 坐标系下的(6,0)。其实到达的是 map 坐标系下的(9,4),并不能达到运动到 map 坐标系下目标点(8,5)的目的。机器人只能自以为是地认为自己运动到了odom 坐标系下的(8,5)就算万事大吉了。
  • 而这时,校正传感器又告诉它了,“我觉得你的里程计刚才 X 漏算了 0.999,Y 多算了 1.001”。
    于是它把自己所在位置修正为了(2 + 0.999,5 - 1.001)=(2.999,3.999),接下来该移动(8,5)-(2.999,3.999)=(+5.001,+1.001)。就能将偏差校正回来,到达 map 坐标系下的终点(8,5)了。


过程总结:

#mermaid-svg-atarrKUHFvi7guVu {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-atarrKUHFvi7guVu .error-icon{fill:#552222;}#mermaid-svg-atarrKUHFvi7guVu .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-atarrKUHFvi7guVu .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-atarrKUHFvi7guVu .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-atarrKUHFvi7guVu .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-atarrKUHFvi7guVu .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-atarrKUHFvi7guVu .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-atarrKUHFvi7guVu .marker{fill:#333333;stroke:#333333;}#mermaid-svg-atarrKUHFvi7guVu .marker.cross{stroke:#333333;}#mermaid-svg-atarrKUHFvi7guVu svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-atarrKUHFvi7guVu .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-atarrKUHFvi7guVu .cluster-label text{fill:#333;}#mermaid-svg-atarrKUHFvi7guVu .cluster-label span{color:#333;}#mermaid-svg-atarrKUHFvi7guVu .label text,#mermaid-svg-atarrKUHFvi7guVu span{fill:#333;color:#333;}#mermaid-svg-atarrKUHFvi7guVu .node rect,#mermaid-svg-atarrKUHFvi7guVu .node circle,#mermaid-svg-atarrKUHFvi7guVu .node ellipse,#mermaid-svg-atarrKUHFvi7guVu .node polygon,#mermaid-svg-atarrKUHFvi7guVu .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-atarrKUHFvi7guVu .node .label{text-align:center;}#mermaid-svg-atarrKUHFvi7guVu .node.clickable{cursor:pointer;}#mermaid-svg-atarrKUHFvi7guVu .arrowheadPath{fill:#333333;}#mermaid-svg-atarrKUHFvi7guVu .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-atarrKUHFvi7guVu .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-atarrKUHFvi7guVu .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-atarrKUHFvi7guVu .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-atarrKUHFvi7guVu .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-atarrKUHFvi7guVu .cluster text{fill:#333;}#mermaid-svg-atarrKUHFvi7guVu .cluster span{color:#333;}#mermaid-svg-atarrKUHFvi7guVu div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-atarrKUHFvi7guVu :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

base_link + 里程计
odom
接近 map 坐标系下的定位结果
校正

四、tf 树是怎么回事

布拉布拉

【ROS基础】map、odom、base_link、laser 的理解 及其 tf 树的理解相关推荐

  1. ROS:坐标系之间的关系 (map \ odom \ base_link)

    ROS:坐标系之间的关系 (map \ odom \ base_link) 在使用ROS进行定位与导航操作时,会伴随着各种坐标系,并且每种坐标系都有明确的含义,ros中定义了常见的坐标系,并且所有的坐 ...

  2. 移动机器人平台的坐标系---map,odom,base_link

    文章目录 本问学习记录移动机器人的坐标系 https://blog.csdn.net/w383117613/article/details/46006991

  3. ros中设置Global Options,以及rqt_tf_tree树讲解,TF树的理解,使用GUI插件,用于可视化ROS-TF的框架树

    一.设置Global Options 如图30,启动rviz界面后,首先要对Global Options进行设置,Global Options里面的参数是一些全局显示相关的参数.其中的Fixed Fr ...

  4. ROS中map、odom、base_link坐标系的理解和这三个坐标系在AMCL中的关系

    学了ROS快一年了,依旧对map坐标系.odom坐标系.base_link坐标系之间的关系不是很清晰,这段时间下定决心要捋清楚他们之间的关系. map坐标系:地图坐标系,是一个固定的坐标系: base ...

  5. ROS中map,odom坐标系的理解以及acml和robot_pose_ekf的对比和小车漂移方法解决

    之前一直不知道odom,map到底是什么关系,看了这个博客:https://blog.csdn.net/u012686154/article/details/88174195 才了解了一些.这边记录我 ...

  6. ros 基础知识总结

    45 ros的导航算法(全局路径规划算法与局部路径规划算法) (1) 全局路径规划算法(Dijkstra算法和A*算法)  { 绿色:起点 红色:终点   黑色:障碍物    白色:路径    黄色: ...

  7. 一 ROS基础教程

    ROS教程 这是小弟的学习笔记,有错求请拍,多指教,谢谢 一 ROS基础知识 ROS文件系统介绍 1.功能包集stack ROS软件包集合,像Navigation Stack,属于导航软件包集合,包含 ...

  8. 【一学就会的ROS基础入门教程 】03-1 ROS基础编程:ROS工作空间的创建、话题topic的发布与接收、以及话题消息的自定义使用

    [一学就会的ROS基础入门教程 ]03-1 ROS基础编程:ROS工作空间的创建.话题topic的发布与接收.以及话题消息的自定义使用 文前白话 1.创建工作空间与功能包 关于工作空间的介绍 创建开发 ...

  9. ROS理论与实践——二、ROS基础

    ROS理论与实践--二.ROS基础 前言 一.创建工作空间 1 什么是工作空间 2 创建流程 二.创建功能包 1 创建命令 2 创建流程 三.ROS通信编程 1 话题编程 1.1 话题编程流程 1.2 ...

最新文章

  1. R语言stringr包str_ends函数、str_starts函数起始、结束字符串判断实战
  2. appium ios 真机自动化环境搭建
  3. Python之路(第三十一篇) 网络编程:简单的tcp套接字通信、粘包现象
  4. xtrabackup压缩备份多线程备份(lz4,pigz)全详解
  5. 提高编程能力的7条建议
  6. 2019南昌网络赛  I. Yukino With Subinterval 树状数组套线段树
  7. 扩展中国剩余定理 exCRT 学习笔记
  8. mysql 默认事务隔离级别_详解MySQL事务的四大特性和隔离级别
  9. 【前端 · 面试 】HTTP 总结(八)—— HTTP 强缓存
  10. hibernate运行很慢?查一张只有几条记录的表都要一俩分钟?[问题记录]
  11. SharpGL学习笔记(十二) 光源例子:解决光源场景中的常见问题
  12. Linux和window写python,搭建Python环境(window和linux)
  13. java 实例化数组_java数组实例化
  14. 《自己动手写操作系统 》第九章 一 简易硬盘驱动的实现
  15. Java网络编程:TCP实现群聊功能代码
  16. python爬取qq音乐
  17. OEM 13c 监控RAC部署
  18. 如何利用linux分析转录组数据库,对转录组测序数据进行分析以及注释
  19. 使用Snakemake搭建分析流程
  20. 谷歌身份验证器 java demo实现 及使用中问题分析

热门文章

  1. 为什么使用onehot 独热编码的形式?
  2. UDAF和UDF的介绍
  3. Android打开手机的手电筒
  4. Review impala
  5. WAS上配置数据源连接失败
  6. 数据库--视图的基本概念以及作用
  7. fortran中call的用法_手写源码系列(一)——call、apply、bind
  8. 验证google webrtc服务器demo(apprtc)使用的turn/stun服务器
  9. 移动端横屏/强制横屏
  10. js的exports