Cartographer源码理解

一、前言

最近一个半月,利用空余时间对Cartographer源码进行了简单的阅读,在这里做了个简单梳理,和大家分享交流。

cartographer源码量其实是有点大的,逐行逐句去解释实在是有心无力了,而且已经有大佬做了类似的事情,后面链接中给大家分享出来,所以这里只表达我的理解和想法,如有理解偏差,感谢指正!

二、demo视频

老规矩,先看仿真视频。

cartographer-demo

三、源码梳理

面对这么大的项目工程,如何下手阅读也是让我这个小白所头疼的,毕竟我是做导航的,所以前两个星期基本都在梳理框架,先搞清楚数据是怎么流转的,核心对象是如何一步步构造的,在这个基础上再去看细节才会有全局思维。

为了方便,carto团队适配了ros的消息收发机制,这里我们也以ros_cartographer来理解,废话不多说,直接看下图,源码中的demo主函数在 node_main.cc 中,一上来就构造了核心的建图器 MapBuilder,这个建图器包含了前端(子图构建)和后端(闭环检测),然后用这个建图器(指针)构造了Carto的核心node,即 node.cc 文件中,在node构造的过程中,主要做了两件事情,第一件事情是声明了Sub、Pub、Serv等用于数据的传输;第二件事情是创建了MapBuilderBridge对象,顾名思义,它承担了ROS-Message到Carto-Message的消息转换(SensorBridge)及使用转换的数据构建地图(slam过程,即MapBuilder)。
到这,是不是思路清晰了。可以大致分成两条线索去深究,第一是SensorBridge如何实现消息转换,第二是MapBuilder如何工作。
在这里插入图片描述

在有了前面的基础上,我们进一步去探究,梳理下核心功能的调用实现。
在这里插入图片描述
在这里插入图片描述
看到这里,应该会对整个框架有系统性的了解,在此我惊叹carto框架的巧妙!


为了弄明白数据的流转,下面我解释几个地方:
1、demo中从 FLAGS_start_trajectory_with_default_topics接口进入(rosbag play 发布的传感器数据),而不是FLAGS_load_state_filename

2、demo中使用的是 ros::spin()被动的接收topic,或者说纯粹的接收topic,起到阻塞线程的作用,如果topic不接收或者不发布了,它会在自己的函数中死循环,直到主动结束程序或者有topic进来。还有一个是类似的函数是ros::spinOnce(),它可以根据自己的需求设置接收频率,一般配合while使用,会更加主动灵活。可以参考链接https://blog.csdn.net/weixin_40215443/article/details/103793316

3、node构造函数中创建了pub(通过定时器定时调用发布相关话题)、service等,在构造的过程中指定了定时运行的时间。

4、配置文件主要在 backpack_2d.lua 中,顺藤摸瓜include “map_builder.lua”、include “trajectory_builder.lua”

5、前端的核心函数是ScanMatch(local_trajectory_builder_2d.cc),里面主要做了两个核心的事情,
第一个是: scan_matching::RealTimeCorrelativeScanMatcher2D real_time_correlative_scan_matcher_;
主要为 ceres优化 提供更好的先验信息(此时的激光数据已经去畸变)
第二个是:scan_matching::CeresScanMatcher2D ceres_scan_matcher_; 使用Ceres库将扫描数据放置到地图中进行匹配,即图优化的过程。

这里我不做算法的详细推导:原因是还没有足够的时间理解底层核心,后面会继续探究再进行分享。

四、源码注释及好的文章

1、源码注释:https://github.com/lijun-mce/cartographer-detailed-comments
2、推荐文章:https://gaoyichao.com/Xiaotu/?book=Cartographer%E6%BA%90%E7%A0%81%E8%A7%A3%E8%AF%BB&title=index

五、配置仿真环境踩坑

刚开始用的是 ubuntu22.04 +ros2(humble) 环境,发现了ros2 bag 无法播放的问题(ros中是.bag格式,ros2中是.db3格式,开源包中的德意志博物馆是ros的.bag格式),网上有部分资料说可以进行转换,我折腾了很久很久,不行,放弃了,如果你们不信可以试试。
推荐这篇文章:https://blog.csdn.net/lgh1231/article/details/124939760,可以很快的配置cartographer,建议使用源码的方式进行编译安装。

ros2不行,然后我就安装 ubuntu18.04 +ros(melodic) 环境
推荐这篇文章:https://blog.csdn.net/weixin_44362628/article/details/122540297,可以很快进行配置,在编译的过程中碰到找不到lua库的问题,可能是由于ros版本的问题,可以试试这两个命令。
sudo apt-get install lua5.3-dev
sudo apt-get install lua5.3


争取早点和大家分享 ceres图优化的过程!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/53041.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java笔试面试题AI答之单元测试JUnit(5)

文章目录 25. 简述什么是Junit 忽略测试(Ignore Test)?一、基本概念二、使用方法三、注意事项四、示例 26. 简述什么是Junit 超时测试(Timeout Test)?Junit 超时测试的主要特点包括:实现方式&am…

buildroot移植qt报错Info: creating stash file (补充qt添加字库)

移植qt库,编译文件报错Info: creating stash file /home/rbing/QT/uart/.qmake.stash Project ERROR: Unknown module(s) in QT: serialport rbingouc:~/QT/uart$ /home/rbing/linux/tool/buildroot-2022.02.9/output/host/usr/bin/qmake Info: creating stash fil…

一些写leetcode的笔记

标准库中的string类没有实现像C#和Java中string类的split函数&#xff0c;所以想要分割字符串的时候需要我们自己手动实现。但是有了stringstream类就可以很容易的实现&#xff0c;stringstream默认遇到空格、tab、回车换行会停止字节流输出。 #include <sstream> #incl…

部分动态铜皮的孤岛无法删除。报错

(SPMHCI-1): Cannot break shape into fragments. 网上寻找了很多答案&#xff0c;都不太理想&#xff0c;不是我想要的方法。 终于功夫不负有心人&#xff0c;在Cadence官方论坛找到了蛛丝马迹。 Breaking Static shape into fragments - PCB Design - PCB Design & IC …

枚举算法总结

枚举算法&#xff08;Enumeration Algorithm&#xff09;是一种简单而直接的算法设计策略&#xff0c;它通过列出问题的所有可能情况&#xff0c;逐一进行验证&#xff0c;直到找到问题的解。这种算法适用于问题的解空间不是太大&#xff0c;可以通过遍历所有情况来找到答案的情…

uniapp 做一个查看图片的组件,图片可缩放移动

因为是手机端&#xff0c;所以需要触摸可移动&#xff0c;双指放大缩小。 首先在components里建个组件 查看图片使用 uni-popup 弹窗 要注意 transform的translate和scale属性在同一标签上不会一起生效 移动就根据触摸效果进行偏移图片 缩放就根据双指距离的变大变小进行缩…

【 html+css 绚丽Loading 】 000052 璇玑转轮

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f…

[网络]http的简单认识

文章目录 一. 什么是http二. http协议工作过程三. http协议格式1. 抓包工具fiddler2. http请求报文3. http响应报文 一. 什么是http HTTP (全称为 “超⽂本传输协议”) 是⼀种应⽤⾮常⼴泛的 应⽤层协议 HTTP 诞⽣与1991年. ⽬前已经发展为最主流使⽤的⼀种应⽤层协议 HTTP 往…

【Kubernetes】常见面试题汇总(十一)

目录 33.简述 Kubernetes 外部如何访问集群内的服务&#xff1f; 34.简述 Kubernetes ingress &#xff1f; 35.简述 Kubernetes 镜像的下载策略&#xff1f; 33.简述 Kubernetes 外部如何访问集群内的服务&#xff1f; &#xff08;1&#xff09;对于 Kubernetes&#xff0…

MyBatis中多对一关系的三种处理方法

目录 MyBatis中多对一关系的三种处理方法 1.通过级联属性赋值 1&#xff09;mapper 2&#xff09;mapper.xml 3&#xff09;测试代码 4&#xff09;测试结果 2.通过标签 1&#xff09;mapper 2&#xff09;mapper.xml 3&#xff09;测试代码 4&#xff09;测试结果 3.分步查询 …

[NOI2022]冒泡排序

题意&#xff1a; 有 n n n个数&#xff0c; m m m个限制&#xff0c;第 i i i个限制要求在 [ L i , R i ] [L_i,R_i] [Li​,Ri​]的最小值为 V i V_i Vi​&#xff0c;你要得到最小的逆序对数。 数据满足 n , m < 1 0 6 n,m<10^6 n,m<106。 思路&#xff1a; 最近感…

【C++二叉树】102.二叉树的层序遍历

107. 二叉树的层序遍历 II - 力扣&#xff08;LeetCode&#xff09; 思路分析&#xff1a; 层序遍历&#xff0c;但是要注意输出的结果是一个二维数组&#xff0c;不是一层一个值一个值的输出&#xff0c;而是要一层一层的输出。可以通过一个循环控制每一层的数据个数&#xff…

PyCharm 安装教程

传送门 PyCharm 是一款由 JetBrains 开发的强大的 Python 集成开发环境&#xff08;IDE&#xff09;。它支持多种功能&#xff0c;包括调试、代码补全、智能代码分析、版本控制集成等&#xff0c;特别适合开发 Python 项目。接下来&#xff0c;我们将详细介绍如何在不同操作系…

【C++高阶】解锁C++的深层魅力——探索特殊类的奥秘

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;C “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;C 类型转换 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀C特殊类 &#x1f4d2;1. 不能被拷贝…

pyinstaller打包python程序

安装pyinstaller anaconda中直接pip install pyinstaller安装 程序打包 Anaconda Prompt进入python脚本所在目录直接用打包脚本 pyinstaller --onefile yourPyFile.py 打包后会在文件所在根目录生成两个文件夹build、dist dist中xx.exe文件就是打包好的程序

文字loading加载

效果 1. 导入库 import sys from PyQt5.QtCore import QTimer, Qt, QThread, pyqtSignal from PyQt5.QtGui import QPainter, QFont, QColor, QBrush from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QProgressBar, QLabel 代码首先导入了P…

[创业之路-146] :如何理解:复杂的事情简单化,简单的事情标准化,标准的事情流程化,流程的事情数字化,数字化的事情自动化,自动化的事情智能化

目录 一、复杂的事情简单化 二、简单的事情标准化 1、标准化的定义与意义 2、简单事情标准化的实施步骤 3、标准化的案例分析 三、标准的事情流程化 1、流程化的定义与意义 2、标准事情流程化的实施步骤 3、流程化的案例分析 四、流程的事情数字化 1、定义与意义 2…

C++ | Leetcode C++题解之第409题最长回文串

题目&#xff1a; 题解&#xff1a; class Solution { public:int longestPalindrome(string s) {unordered_map<char, int> count;int ans 0;for (char c : s)count[c];for (auto p : count) {int v p.second;ans v / 2 * 2;if (v % 2 1 and ans % 2 0)ans;}retur…

【设计模式-外观】

这里写自定义目录标题 定义UML图角色作用代码使用场景 定义 为子系统中一组相关接口提供一致界面&#xff0c;定义一个高级接口&#xff0c;使得子系统更加容易使用。 UML图 角色作用 外观&#xff08;Facade&#xff09;角色&#xff1a;这是外观模式的核心&#xff0c;它知…

编程环境常用命令合集

cmd: python 进入python运行环境 exit()/quit()/ctrlZ 退出环境 rmdir /s venv 删除环境 pip命令&#xff1a; pip list 查看所有库 pip install <库> 安装库 -i <数据源>可指定安装数据源 pip install <库>x.x.x 安装指定版本的库 pip install --upgrade &…