简单总结LEGO-LOAM相对于LOAM的一些改进及不同点

一. 地面点的提取

1.动机:在LEGO-LOAM的实验数据中,有地面都是草坪的情况。对于这种地面,如果直接用LOAM,那么就会有一些边缘特征点落在草地上(因为草地的参差),这是拉了位姿估计的后腿的,结果会非常不稳定。
2.缺点:LEGO-LOAM中用到的提取方法需要满足雷达水平安装,或者雷达倾斜安装但已知安装角度的前提。如果是手持设备,这个方法就不太可行,因为手持时不能保证雷达和地面一直都是平行的。
3.方法:相邻行的激光点,求取垂直差距和水平面内差距的atan值,小于15度就可以被认为是地面点。这里有一部分误差是因为雷达安装角度引入的。实际还可以考虑加入一些已知的场景的先验信息,比如雷达距离地面的高度。对于已经标记为地面点的点,还有距离无效(FLT_MAX)的点,labelMat中这里就置为-1,不会参与后续特征点的提取。
<疑惑>:对于自动驾驶的场景,其实是应该追寻一种比较宽泛的场景要求的?算法最好是可以同时满足不同场景的需求吧?

二. 利用广度优先遍历算法对点进行聚类,从而筛除外点

1. 关于广度优先算法:

是一种对于图的的遍历方法,常借助队列queue进行处理。因为图可以分为有向和无向,比如对于无向图来说,如果就用最普通的遍历,那么就无穷无尽陷入死循环了。这种遍历,个人觉得最主要就是对访问过的元素进行了标记(否则就是死循环),至于遍历的方式,根据直觉,可以是把最近的挨个问了(广度优先),或者是一条路走到黑(深度优先)。

2. 代码实现

先把单帧点云建模成一个图模型-> 投影到一个平面上,此处为range image,比如一个16线激光雷达,就是投影到16*1800的图上。对于一个点,上下左右四个相邻点被视为图结构中的邻接节点,左右边界的的点和边界另一侧也构成邻接(16线velodyne水平是360度,物理上是连续的)。从任意一点开始进行BFS搜索,直到遍历完这部分近邻点,聚类点数过少的就是外点,会被去除。

  • 遍历每个点,如果已经被处理过了就不再处理
  • 如果未处理就说明是一个新聚类,然后执行BFS步骤:把队列中的首元素弹出,然后将该元素近邻塞入队列末尾(源码中没有用std::queue,而是用了数组+双指针实现);分别判断近邻和自身距离是否足够近,angle越大,越认为两点可能是同一个聚类物体上的点,给他们相同的Label。angle通过先计算actan的值来求出来。

在这里插入图片描述

  • 有两个阈值来进行判断,如果聚类的点数大于等于30个,那么就会被视为一个有效的类;如果聚类中的点数只超过了5个,但是在竖直方向超过了3个也被认为是有效的(对于16线雷达,水平和垂直角分辨率相差较大所以分了两种情况)。

三. 两步优化的帧间里程计

1.和LOAM的相同点

都是通过前后两帧的点云来估计两帧之间的运动,然后累加得到前端里程计的输出(相对于第一帧),也都是采用的线面约束。

2.不同点

LOAM采用的是线面约束同时优化六自由度帧间位姿不同,LeGO-LOAM的前端分成两个步骤,每个步骤估计三个自由度。
动机:提高运算效率,可以在嵌入式平台运行。
步骤
1)使用地面点构建点面约束,由于地面点之间的约束对x,y,yaw三个自由度是不能观的(地面可以转动,但残差不会明显变化),所以地面点的优化只会对pitch,roll,z进行约束和优化。
2)使用提取的角点进行优化,由于多线激光雷达提取的角点通常是垂直的边缘特征,这些特征对x,y,yaw有较好的能观性,通过角点的优化结合1)中的结果就可以得到六自由度的帧间优化结果。
具体的代码实现在updateTransformation()

3.他人之谈

在实际的工程应用中,这种方式还是用的比较少,就是说可以借鉴一下这个此路。因为工程中加入了其他传感器之后,计算量也可以减少很多,精度也会提高很多。而LeGo-LOAM前端里程计的精度可能不算太好。

四. 后端

LOAM的后端是一个基于栅格的地图,很难进行回环检测以及回环检测后的全局优化。而LEGO-LOAM引入了slam中关键帧的概念,利用单独的关键帧以及对应的位姿拼成的局部地图。更具体内容等之后写了Lio-sam再进行补充。

猜你喜欢

转载自blog.csdn.net/catpico/article/details/120929262
今日推荐