读这篇论文的初衷在于希望能够读懂 Google’s Cartographer(开源激光SLAM算法),这篇文章是 Cartographer 的论文 《Real-Time Loop Closure in 2D LIDAR SLAM》的引用文献之一,也是代码实现里 real time correlative scan matcher 和 fast correlative scan matcher 的算法来源(两者分别用在了前段和后端的算法中),总之是读懂 Cartographer 的关键论文之一,故这里写下我读这篇论文的一些理解。
有一些基础的概念这里是默认读者是能理解的
1. Scan Matching —— 求解两帧雷达数据(scan to scan)或者雷达数据与地图(scan to map)之间的旋转矩阵(位移和旋转)的过程;
2. Maximum likelihood estiamtion (极大似然估计) —— 利用已知样本结果,在使用某个模型的基础上,反推最有可能导致这样的结果的参数。这是一个相对生涩的解释,有兴趣的读者可以自行搜索相关的博客或文章来看,完整的看下来会比较容易理解。
我们这里用极大似然估计的思路来给 Scan Matching 建模,这里我们采用的是 Cartographer 中的 Scan-to-Map 的模式:
其中, xt x t , xt−1 x t − 1 就是当前时刻和上一时刻的位姿,前者为未知的带求解的量, zt z t 为当前scan里的所有数据的集合,相当于是当前一帧雷达数据中的所有点,包括角度和距离; mt−1 m t − 1 现有的地图信息; ut−1 u t − 1 是上一时刻到这一时刻的运动量(或者运动相关的观测量,如里程计数据、IMU数据等)。
那么,这个式子的比较通俗的解释(可能跟式子中的含义并非完全相同)即:
在上一时刻 t−1 t − 1 ,我们已经获得了地图 m m , 还有位姿信息和一些运动相关的信息,我们想要通过这个运动信息和上一时刻的位姿信息来估计当前时刻的位姿,当然由于观测量或者模型的一些不准确性,我们得到的是一个分布的信息,也就是当前的位姿会落在一定的范围内;接着我们就需要求解在这个范围内的所有位姿哪个最符合观测模型,也就是(CS) 式中的第一个概率 —— 在已知地图下,若获得某一雷达观测量 zt z t , 机器人最有可能的位姿(这个就是极大似然估计的思路),不过我们这里换一个思路:我们已经从运动模型获得了一个位姿估计的范围,我们只需要在这个范围里面遍历所有的位姿,每个位姿在已有地图里面获得会获得的观测信息(scan)与实际scan最接近的那个,那这个位姿就是我们要找到的 xt x t
首先,并不是所有的机器人都可以获取运动信息(odom、 imu),也就是模型里面的 ut−1 u t − 1 并不是在所有应用场景都存在,或者说这个数据的可信度有时候很低,我们并不一定使用这个观测量,在这样的情况下我们省略掉 (CS)式中第二个概率计算式(通常称作运动模型),而专注于第一个概率计算式(通常称作观测模型)。
接着,针对这个观测模型:
好了,经过上面的简化,我们的算法已经相对要简单多了,下面就是这个算法的核心:
首先,在我们的直观感受里, zt z t (雷达观测数据)里包含了很多点数据(二维平面上的极坐标),而这些数据相互之间并没有关联,所以我们这里假设他们是完全独立的:
到了最后一步,scan to map 的 scan matching 问题。如下图(我不知道用什么工具可以快速画出上面图中的效果,所以只好手绘拍下来,有更好办法的读者希望可以留言告知),我们假设已经有的地图为 Figure.1 F i g u r e .1 ,图中小三角形是上一时刻的机器人的位姿。当前时刻我们获取到的雷达数据(scan)见 Figure.2 F i g u r e .2 ,我们很容易就能判断出当前的机器人位置(较上一时刻前进了3个像素),不过我们需要用算法实现这个判断。
Cartographer 中的实现思路大概如上,详细可以看Cartographer代码中的 real_time_correlative_scan_matcher 的实现。不过论文中提供了几个思路的比较,如BF, 2D Slices 等,不过重点在于一个分辨率切换的思路—— multi-resolution:
这个思路在保证不错过最佳匹配的同时明显减少了计算量,使得scan matching可以达到real time的效果。
Cartographer中有两个scan matcher都涉及到了这个论文里的类似算法,包括前面提高的real time correlative scan matcher, 而真正实现了上面的multi-resolution的思路的是fast correlative scan matcher,有兴趣的读者可以去阅读一下源码,代码量不大,也不难懂。