本文简介:
本文实际上是知乎cartographer源码详细解读专栏的follow和精简,链接在:
https://zhuanlan.zhihu.com/c_1040559544505704448
算法简介
cartographer是google推出的一套基于图优化的SLAM算法,该算法的主要目标是实现低计算资源消耗,达到实时SLAM的目的。
该算法主要分为两个部分,第一个部分称为Local SLAM, 该部分通过一帧帧的Laser Scan建立并维护一系列的Submap,而所谓的submap就是一系列的Grid Map。当再有新的Laser Scan中会通过Ceres Scan Matching的方法将其插入到子图中的最佳位置。但是submap会产生误差累积的问题,因此,算法的第二个部分,称为Global SLAM的部分,就是通过Loop Closure来进行闭环检测,来消除累积误差:当一个submap构建完成,也就是不会再有新的laser scan插入到该submap时,算法会将该submap加入到闭环检测中。闭环检测的本质也是一个优化问题,该优化问题被表达成了一个pixel-accurate match的形式,解决优化问题的方法是Branch-and-Bound Approach.
整体框架介绍
cartographer的代码主要包括两个部分:cartographer和cartographer_ros。而之前安装的ceres-solver是一个非线性优化的库。我们暂时可以不用管它,只需要知道当我们解决优化问题的时候可以调用这个库来求解即可。
cartographer主要负责处理来自Laser、IMU、Odemetry等传感器的数据并基于这些数据进行地图的构建。所以这一部分应该说是cartographer代码的核心部分。而cartographer_ros是基于ros的通信机制获取传感器的数据并将他们转换成cartographer中定义的格式传递给cartographer处理,与此同时也将cartographer的处理发布用于显示或保存。是基于cartographer的上层应用。所以,cartographer_ros相当于是对cartographer进行了一层ROS接口的封装。根据官网的说明来看,即使不采用ROS,也可以运行cartographer算法。只不过这时候传感器传递数据可能就需要自己去写函数处理了。

cartographer整体可以分为两个部分:
一是Local SLAM部分,也被称为Frontend; 该部分的主要任务是建立维护Submaps,但问题是该部分建图误差会随着时间累积。该部分相关的参数定义在/src/cartographer/configuration_files/trajectory_builder_2d.lua和/src/cartographer/configuration_files/trajectory_builder_3d.lua中。
二是Global SLAM部分,也称为Backend. 该部分的主要任务是进行Loop Closure。如前所述,闭环检测本质上也是一个优化问题,文中将其表达成了pixel-accurate match的形式,采用Branch-and-Bound Approach (BBA)的方法来解决。具体怎么用Branch-and-Bound方法,可以参见论文(Real-Time Loop Closure in 2D LIDAR SLAM)。如果是3D情况下,该部分还负责根据IMU数据找出重力的方向。
可以看出,从传感器出发,Laser的数据经过两个滤波器后进行Scan Matching,用来构建子图submap, 而新的Laser Scan进来后也会插入到已经维护着的子图的适当位置。如何决定插入的最优位姿,就是通过Ceres Scan Matching来实现的。估计出来的最优位姿也会与里程计和IMU数据融合,用来估计下一时刻的位姿。
文件架构

cartographer部分源码主要分为了如图所示的几个文件夹:cloud、common、ground_truth、io、mapping、metrics、sensor、transform。其中一些文件夹的作用我们也能猜到:
1. common: 定义了基本数据结构和一些工具的使用接口。例如,四舍五入取整的函数、时间转化相关的一些函数、数值计算的函数、互斥锁工具等。
2. sensor: 定义了传感器数据的相关数据结构。
3. transform: 定义了位姿的数据结构及其相关的转化。如2d\3d的刚体变换等。详见:
4. mapping: 定义了上层应用的调用借口以及局部submap构建和基于闭环检测的位姿优化等的接口。这个文件也是算法的核心。其中mapping_2d和mapping_3d是对mapping接口的不同实现。
5. io: 定义了一些与IO相关的工具,用于存读取数据、记录日志等。
另外,/src/cartographer/configuration_files文件夹下是一些配置文件。算法一些参数在这里定义,我们也要改这里的参数进行tunning.
\src\cartographer_ros下的文件如图所示:

cartographer_ros_msgs里定义了部分msg文件和srv文件。cartographer_rviz估计是与显示相关的函数。让我们把关注点放到/src/cartographer_ros/cartographer_ros下:

configuration_files是一些配置文件,launch里是一些launch文件。这些暂时不管。继续进入/src/cartographer_ros/cartographer_ros/cartographer_ros。这里我们可以找到程序入口node_main.cc。
网友评论