一、前言
最近一个半月,利用空余时间对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源码解读\&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) 环境
sudo apt-get install lua5.3-dev
sudo apt-get install lua5.3
争取早点和大家分享 ceres图优化的过程!