Loam算法详解(配合开源代码aloam)

简介: Loam算法详解(配合开源代码aloam)

LOAM算法是激光slam中一个经典的开源框架,结合qin tong 博士的开源代码a-loam,对其原理及代码实现简要介绍如下:

LOAM算法的总体框架如下图所示:

除了左侧的硬件采集数据之外,LOAM算法本身主要包括图中标记的-四个部分。该算法的关键想法是把实时定位与测图这一同时寻找优化大量变量的复杂问题进行区分,通过两个算法来进行解决。首先,使用一个高频、低精度的里程计来估计LiDAR的位姿,并以此结果去除实验过程中产生的运动畸变(假设为匀速运动)。另外,使用一个低频、高精度的里程计算法来改善LiDAR位姿的精度,并输出全局坐标系下的地图。

1 LiDAR硬件

LiDAR硬件在采集过程中不断发布点云数据(10 HZ),以符号image.png表示在第K帧接收到的点云数据。

L是局部激光坐标系,坐标原点在Lidar的几何中心,以符号 image.png表示在第K帧中的i点在局部坐标系下的坐标。

W是全局坐标系,坐标原点在Lidar的起始位置,以符号 image.png表示在第 K帧中的 i点在全局坐标系下的坐标。

2 Point Cloud Registration

这一部分中从LiDAR硬件中接收原始点云数据,接着进行预处理(去除噪声点、无效点)并按照扫描线号进行区分,存储在一个vector中。随后,对点云数据进行处理,发布sharp、less_sharp、flat、less_flat四种类型的特征点,如下图中所示:

分别介绍LiDAR点云预处理与特征点提取两部分内

2.1 LiDAR点云预处理

传感器获得的数据可能在一些点的坐标中为NaN(不是数)值, 一个NaNs表明测量传感器距离到该点的距离值是有问题的,可能是因为传感器太近或太远,或者因为表面反射。那么当存在无效点云的NaNs值作为算法的输入的时候,可能会引起很多问题,使用PCL自带的函数进行去除。

随后,去除原始数据中距离很近的点,即相邻点间小于仪器测量的分辨率,这里设置MINIMUM_RANGE为0.1 m。

进行上述处理后,计算每个点的scanID并存储在对应的laserCloudScans变量中。

此外,还计算了当前点在一帧数据中的相对时间(时间比例),存放在intensity中(后续修正运动畸变时使用)。

2.2 提取特征点

在文章中描述了通过公式(1)来描述局部表面的平滑程度,其中S表示选取的一个周围点集,image.png表示当前点,image.png 表示近邻点。

若c值较大,则代表当前点与周围点的差距较大,曲率较高,代表为一个边缘点(也就是代码中的sharp点)。

若c值较小,则代表当前点与周围点的差距较小,曲率较低,代表为一个平面点(也就是代码中的flat点)。

通过如下代码计算公式(1),当前点的前后5个点组成点云集合S。

在选择特征点的过程中,我们还想让其均匀分布,所以文章中计划把每个扫描分为4个部分(代码中分为了6个部分),同时每个子集区域中选取2个sharp点和4个flat点。

此外,为了避免选中不稳定的特征点,作者还讨论了下图中的两种情况要进行避免。1)左图(a)中的B点在一个几乎与激光束平行的表面上。2)右图(b)中的A点在被遮挡区域的边缘。

3 Lidar odometry

3.1 寻找特征点对应关系

假设一个扫描k的开始时间戳为 t k  ,在第 k帧扫描结束接收到的点云为 P k(左侧第一条蓝线),其被投影到image.png 时间戳,用 image.png表示(即中间的绿线),同时在下一个扫描k+1中获取的数据为 (图中的橙线)。

(注意:由于假设为匀速运动,所以上图中可以用直线来表示每一帧扫描的点云数据。)

现在,假设我们有了和 P(k+1)两个点云数据集,基于此来寻找两个点云数据之间的对应关系。

首先,对P(k+1) 采用2.2节中提取特征点的方法找到两个特征点集,边缘点 E ( k + 1 )和平面点 H(k+1)。其次,对进行kd-tree索引,并在 中找到每个边缘点对应的边缘线(两个点,左图(a))与每个平面点对应的面片(三个点,右图(b))。

利用向量叉乘,获取点 i到直线ij的距离,以及点 i到平面ljm的距离。计算公式分别为:

前述假设LiDAR在一个扫描中角速度和线速度均为匀速运动,所以能够对计算出的位姿进行线性插值。假设image.pngimage.png两帧点云数据之间的位姿变换(6-DoF),给定一个点i , image.png,其获取的时间戳为image.png之间的变换为image.png并可以通过下式进行计算。

在每一次迭代过程中均把 P ( k + 1 )中的点i投影到该帧数据的起始点 t ( k + 1 ),然后再与 P k 中的点进行匹配。

假设 image.png为投影之前的i点坐标, image.png 为投影到起始点 t ( k + 1 )之后的i点坐标,则两者之间存在如下关系。

综合考虑前述的公式2与公式3,得到以下公式9与公式10:

综合公式9与公式10,得到:

式11中每一行均为一个特征点及对应的边缘线或平面面片,对公式11中的非线性函数进行优化,不断迭代使得d dd最小。

3.2 Lidar odometry算法总结

Lidar odometry算法如下所示,以上一帧点云image.png,逐渐增长的点云P(k+1),以及上一次迭代计算的位姿参数T(k+1)作为输入(如果是一个扫描的开始则设置为0)。接着,从P

(k+1)中提取边缘点E

(k+1)和平面点 H(k+1),对于每个边缘点/平面点,在上一帧点云Pk中找到其对应的边缘线/面片,建立公式11中的非线性函数,并进行优,若迭代达到收敛则输出,若达到了扫描的终点则输出 image.pngimage.png

4 Lidar Mapping

第3节中的里程计高频、低精度运行,其输出的位姿参数还需要进一步在后续的mapping中进行优化。

Mapping算法在每个扫描结束才运行一次,如在第k+1次扫描结束后,lidar odometry产生了一个没有畸变的点云 和一个位姿变换参数image.png(代表image.png之间的运动)。Mapping算法把点云image.png 配准到全局坐标系 W下,如下图中所示,假设 Qk为前k次扫描积累的数据所形成的点云地图,为lidar在地图中最后一次扫描k到k+1处的变换位姿。随着lidar odometry的输出,Mapping算法不断扩展 image.pngimage.png(即扫描时间image.png范围的全局变换,并把image.png投影到全局坐标系下,得到image.png。接着,通过不断优化 image.pngimage.png匹配到地图Qk中。

特征点提取方法与上述的2.2节相同(数量增加10倍,即为代码中的less_sharp点与less_flat点)。为了找到特征点之间的对应关系且提高运行效率,使用边长为10m的立方体代替全局地图(代码中是10105)。

取立方体中与image.png相交的部分,建立3D kd-tree索引。在 Q k的特征点中选取点集S’,针对边缘点只保留S’中边缘线上的点,针对平面点,只保留S’中面片上的点。然后,计算点集S’的协方差矩阵M,并分解M得到特征值记为V,特征向量E。如果S’分布在一条线段上,那么V中一个特征值就会明显比其他两个大, E中与较大特征值相对应的特征向量代表边缘线的方向。(一大两小,大方向)

如果S’分布在一个平面上,那么V中一个特征值就会明显比其他两个小, E中与较小特征值相对应的特征向量代表平面的朝向。(一小两大,小方向)

边缘线或平面块的位置通过点集S’的几何中心确定。

边缘线或平面块的位置通过点集S’的几何中心确定。

为了计算边缘点/平面点与其对应边缘线/面片之间的距离,在一个边缘线上选取两个点,在面片上选取三个点,分别通过公式2、3进行计算,并转换为公式9、10,组合为公式11中所示的非线性函数,进行优化。

边缘特征:

平面特征:

求解:

最后,image.png匹配到地图 Qk中时,考虑到点云的均匀分布,还对其进行了一个下采样。

目录
相关文章
|
24天前
|
存储 人工智能 自然语言处理
Delta-CoMe:清华联合OpenBMB等高校开源的新型增量压缩算法
Delta-CoMe是由清华大学NLP实验室联合OpenBMB开源社区、北京大学和上海财经大学提出的新型增量压缩算法。该算法通过结合低秩分解和低比特量化技术,显著减少了大型语言模型的存储和内存需求,同时保持了模型性能几乎无损。Delta-CoMe特别适用于处理数学、代码和多模态等复杂任务,并在推理速度上有所提升。
58 6
Delta-CoMe:清华联合OpenBMB等高校开源的新型增量压缩算法
|
27天前
|
存储 算法 程序员
C 语言递归算法:以简洁代码驾驭复杂逻辑
C语言递归算法简介:通过简洁的代码实现复杂的逻辑处理,递归函数自我调用解决分层问题,高效而优雅。适用于树形结构遍历、数学计算等领域。
|
28天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
61 1
|
1月前
|
存储 缓存 算法
通过优化算法和代码结构来提升易语言程序的执行效率
通过优化算法和代码结构来提升易语言程序的执行效率
|
1月前
|
算法
分享一些提高二叉树遍历算法效率的代码示例
这只是简单的示例代码,实际应用中可能还需要根据具体需求进行更多的优化和处理。你可以根据自己的需求对代码进行修改和扩展。
|
1月前
|
算法 测试技术 开发者
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗;代码审查通过检查源代码发现潜在问题,提高代码质量和团队协作效率。本文介绍了一些实用的技巧和工具,帮助开发者提升开发效率。
49 3
|
1月前
|
分布式计算 Java 开发工具
阿里云MaxCompute-XGBoost on Spark 极限梯度提升算法的分布式训练与模型持久化oss的实现与代码浅析
本文介绍了XGBoost在MaxCompute+OSS架构下模型持久化遇到的问题及其解决方案。首先简要介绍了XGBoost的特点和应用场景,随后详细描述了客户在将XGBoost on Spark任务从HDFS迁移到OSS时遇到的异常情况。通过分析异常堆栈和源代码,发现使用的`nativeBooster.saveModel`方法不支持OSS路径,而使用`write.overwrite().save`方法则能成功保存模型。最后提供了完整的Scala代码示例、Maven配置和提交命令,帮助用户顺利迁移模型存储路径。
|
2月前
|
存储 缓存 算法
如何通过优化算法和代码结构来提升易语言程序的执行效率?
如何通过优化算法和代码结构来提升易语言程序的执行效率?
|
2月前
|
搜索推荐
插入排序算法的讲解和代码
【10月更文挑战第12天】插入排序是一种基础的排序算法,理解和掌握它对于学习其他排序算法以及数据结构都具有重要意义。你可以通过实际操作和分析,进一步深入了解插入排序的特点和应用场景,以便在实际编程中更好地运用它。
|
2月前
|
缓存 分布式计算 监控
优化算法和代码需要注意什么
【10月更文挑战第20天】优化算法和代码需要注意什么
26 0

热门文章

最新文章