LIO-SAM在lego-loam的基础上新增了对IMU和GPS的紧耦合,采用一个因子图对位姿进行优化,包括IMU因子,激光里程计因子,GPS因子、回环因子。
虽然在创新点上没什么让人觉得有趣的东西,但是在性能上相比Lego-Loam,因为加入了高频的IMU,在一些不好的场景下表现要更鲁棒,回环处的漂移也更小。
不过虽然加入了IMU,但似乎连松耦合都称不上,IMU预积分在LIO-SAM中的作用仅用来对激光点云做运动补偿去畸变,以及在scan-2-map时提供优化的初始位姿
综上,算是一个比较不错的入门算法吧。
参考链接: https://zhuanlan.zhihu.com/p/614039247
算法输入: 激光点云,IMU原始数据,GPS(可选)
主要模块:
imageProjection.cpp
featureExtraction.cpp
imuPreintegration.cpp
mapOptmization.cpp
相比于Lego-Loam,这里没有对点云进行分割和聚类操作,而是直接去畸变后将点云以及对应的位姿发布给特征提取模块。
过程同Lego-Loam,详细见博客《Lego-Laom算法深度解析》
过程同Lego-Loam,详细见博客《Lego-Laom算法深度解析》
和VIO常见算法不同,LIO-SAM是通过激光里程计矫正IMU的累计误差,然后对IMU原始数据进行连续积分得到关于IMU的里程计。
在计算IMU里程计时,使用了因子图,利用激光里程计因子和IMU因子对IMU位姿、速度和偏置进行了因子图优化。
核心函数在laserCloudInfoHandler
,主要流程如下:
updateInitialGuess
extractSurroundingKeyFrames
downsampleCurrentScan
scan2MapOptimization
saveKeyFramesAndFactor
correctPoses
详细内容见链接:https://zhuanlan.zhihu.com/p/622003523
读取特征提取模块的线特征和平面特征,以及由IMU预积分提供的初始位姿。
线特征和平面特征由特征提取模块featureExtraction
发布,
挑选局部地图关键帧的方法很巧妙,每个关键帧的位置(x,y,z)坐标本质上也是一堆3D点,因此可以使用KD树搜索距离当前关键帧最近的点云,同时又对这些3D点位置进行降采样,3D点的稀疏性保证了对应的关键帧位置不会挨得太近。选出关键帧后就提取对应的点云,转到同一个坐标系然后融合为局部地图。
分别进行角点和平面点匹配,找到候选点后整合在一起,然后进行匹配优化。
Ax+By+Cz+1=0
将cornerOptimization
和surfOptimization
两个函数计算出来的边缘点、平面点到局部地图的距离、法向量集合在一起
基于点到直线、点到平面的距离构建残差方程,基于高斯牛顿法迭代求解使得残差最小时对应的位姿
求解过程是将雅格比矩阵的形式写出,然后计算高斯牛顿法的hessian矩阵,然后对Hessian进行QR分解计算特征向量来更新位姿,在达到最大迭代次数之前如果收敛则优化成功。
最后用imu原始RPY数据与scan-to-map优化后的位姿进行加权融合(只加权融合roll、pitch角),更新当前帧位姿的roll、pitch,约束z坐标
在地图优化模块,scan-2-map并没有使用因子图,只是简单的点云配准问题,通过解析解的方式迭代求解局部地图匹配位姿。只有在创建关键帧时才会将新的关键帧加入到因子图,并进行因子图优化位姿。该因子图如下所示:
实则是使用之前因子图优化后的位姿,对位姿序列相应关键帧的位姿进行替换
论文中的对标基线是LOAM,下面的链接对LOAM系列的几个算法做了比较详细的评测,整体上LIO-SAM的稳定性较好因为加入了IMU,回环处的漂移较小
https://github.com/Tompson11/SLAM_comparison