LOAM 原理及代码实现介绍

article/2025/8/30 20:08:03

文章目录

    • LOAM 原理及代码实现介绍
      • LOAM技术点
      • LOAM整体框架
      • 退化问题
      • 代码结构

LOAM 原理及代码实现介绍

paper:《Lidar Odometry and Mapping in Real-time》
LOAM的参考代码链接:
A-LOAM
A-LOAM-Notes
LOAM-notes

使用传感器介绍:
在这里插入图片描述
如果没有电机旋转,则雷达自身的扫描是一个平面的180度。如下:
在这里插入图片描述
加上电机的旋转,则该设备能扫描的范围为雷达前方的半球形。

LOAM技术点

  • 二维雷达固定在一个转轴上,实现3维雷达;一次完整的三维扫描为sweep,雷达平面的一次扫描为scan;
  • 将点云分为两类:边线点(edge point角点)和平面点(planar point),分别对应采取点到线及点到面的约束;在实际的测试中,平面点占总点云的80%。
  • 位姿变化估计采用高频粗估计+低频优化。两套算法来实现定位。(laser odometry & mapping odometry)
    其中,laser odometry高频粗估计是在雷达坐标系下,通过点到线及点到面距离,利用LM得到雷达位姿估计;
    mapping odometry低频位姿精估计,是在世界坐标系下,通过点到线,点到面的距离,得到世界坐标系下的雷达位姿估计优化。
  • 低频位姿精估计是1HZ,与sweep频率相同。也就是一次完整的sweep会进行一次完整的位姿估计。

在这里插入图片描述

LOAM整体框架

在这里插入图片描述
将定位与建图分开运行,高频位姿估计+低频优化建图->实现实时,低计算量,低漂移。

LOAM主要包括四个节点:点云提取(scan registration)、雷达里程计(lidar odometry)、雷达建图(lidar mapping) 和位姿集成(transform integration)

  1. 点云提取及处理(scan registration):

    根据点的曲率c来将点划分为不同的类别(边/面特征或不是特征),在每一个sweep中,根据曲率对点进行排序,来作为评价局部表面平滑性的标准。
    一个sweep指完成一次完整的扫描,一次sweep分为多个scan,每一次sweep的雷达位姿定义为为这一sweep起始时的状态。

    特征点提取及处理
    LOAM中选用特征点来进行运动估计,特征点选取(edge point角点)和平面点(planar point),如下黄点为edge point,红点为planar point。试验数据表明,大部分点云都是平面点。边线点起到的约束作用较小。
    在这里插入图片描述
    判断公式:
    在这里插入图片描述
    P k P_k Pk第k次整体sweep中得到的点云。 X ( k , i ) L X^L_{(k,i)} X(k,i)L表示第k个sweep中的i点在雷达坐标系下的坐标。

    i ∈ P k i\in P_k iPk,表示点 i i i是第k次整体sweep中的点。选取 i i i点在同一个scan中相邻的前后的5个点 X ( k , j ) L , j ∈ S , j ≠ i X^L_{(k,j)}, j \in S, j\ne i X(k,j)L,jS,j=i,计算 Σ j X ( k , i ) L − X ( k , j ) L \Sigma _jX^L_{(k,i)}-X^L_{(k,j)} ΣjX(k,i)LX(k,j)L。注意,论文中使用的是平面雷达,每个scan扫描区域是半平面,即,空间的平面,雷达一次scan会得到空间平面与雷达扫描平面交线上的点,会得到一条线的点,但是,如果雷达扫过角点,则就是类似平面v字型的点。)
    即:
    如果是平面,前后的5个点与i的距离相加=0,c->0
    如果是边线角点,则 c > 0 c>0 c>0
    c的计算方程的分母,用于归一化c值,防止,因为雷达的距离而带来的c值得过大或小。

    可以参考LOAM论文和程序代码的解读中更详细的解释。

  • 代码文件:scanRegistration.cpp:
    接收雷达驱动发布的点云,解析驱动点云,计算曲率,并按序排布,按照曲率由高到低,将点云分为sharp,less_sharp,flat,less_flat四种点并发布对应的消息。
    雷达驱动发布的点云topic为:/velodyne_points,其中点云的位置是以x,y,z存储的。根据xyz计算点云的仰角(angle),及偏角(ori),并对应的计算出点云对应的线号,存放在point.intensity = scanID + scanPeriod * relTime。其中scanID是整数,为点的线数(0-15),relTime代表水平偏转度(0-1) scanPeriod=0.1。即将偏转度存为归一化的小数。线束为整数。
    从而每个点包含的数据包括x,y,z,intensity,intensity则存放是竖直上的线束及水平上的偏转度。也就是包含位置信息的同时,包含了仰角及偏转角信息。
  1. 位姿粗估计(雷达里程计(lidar odometry)):(高频)
    符号定义:
    P k P_k Pk第k次整体sweep中得到的点云;
    根据插值将 P k P_k Pk映射到k时刻sweep起始坐标系下(点云去掉运动漂移),记为 P k ~ \widetilde{P_k} Pk
    ,则根据插值将 P k + 1 P_{k+1} Pk+1映射到k+1时刻sweep起始坐标系下(点云去掉运动漂移),记为 P k + 1 ~ \widetilde{P_{k+1}} Pk+1 ;
    将第k帧扫描到的特征点 P k P_k Pk映射到第k+1帧的雷达坐标系下,记为 P k + 1 ~ \widetilde{P_{k+1}} Pk+1 .

    点云匹配:
    该作者的点云匹配是基于将 P k + 1 ~ \widetilde{P_{k+1}} Pk+1 P k + 1 ~ \widetilde{P_{k+1}} Pk+1 进行匹配。
    即将第k个sweep的点云映射到第k+1个sweep起始,将第k+1个sweep的点云映射到第k+1个sweep的起始。匹配 P k + 1 ~ \widetilde{P_{k+1}} Pk+1 P k + 1 ~ \widetilde{P_{k+1}} Pk+1 的点云点面关系,计算得到第k+1个sweep中产生的运动。

    点云特征点被分为,边线点和平面点。
    边线约束点两个点确定:设去漂当前帧的点云 i ∈ ξ k + 1 ~ i\in\widetilde{\xi_{k+1}} iξk+1 ,在上一帧点云(映射在k+1时刻坐标系下) ξ k ‾ \overline{\xi_k} ξk中找到距离最近的点 j j j,并在 ξ k ‾ \overline{\xi_k} ξk找到与j相邻scan的点 l l l
    设想两个墙面的竖直墙角线,设雷达偏移较小,相邻的的scan,会出现类似图a的情况,相邻scan会测量到墙角线上的点。因为可以在上一帧中找到两个相邻帧的墙角线上的点,约束当前帧打到墙角上的点到这两个点构成的直线上的距离最小,得到雷达运动T。如下图a所示。

    平面约束点三个点确定:设去漂当前帧的点云 i ∈ H k + 1 ~ i\in\widetilde{\mathcal{H}_{k+1}} iHk+1 ,在上一帧点云(映射在k+1时刻坐标系下) H k ‾ \overline{\mathcal{H}_k} Hk中找到距离最近的点 j j j,并在 H k ‾ \overline{\mathcal{H}_k} Hk找到与j同scan的最近点 l l l和相邻scan的一个点 m m m

    论文中的雷达是二维平面雷达加旋转得到,每一次scan都是一次平面半圆,一个sweep由加在雷达上的电机转动180度,构成半球。一次scan打到对面一个平面上,就是一排直线排列的点。

    橙色线表示点 j j j所在的scan,蓝色线表示与橙色线相邻的两次scan的线。使用velonedy雷达,每个FOV对应的多线构成一个竖直scan,但是点云约束类似。
    在这里插入图片描述

    使用kdtree存储点云信息。

    将第k帧扫描到的特征点 P k P_k Pk映射到第k+1帧的雷达坐标系下,记为 P k ‾ \overline{P_k} Pk:,将 P k ‾ \overline{P_k} Pk与第k+1帧的扫描点云 P k + 1 P_{k+1} Pk+1进行点云匹配。在LOAM代码中,计算 P k ‾ \overline{P_k} Pk是使用TransformToEnd()将 P k {P_k} Pk映射到本k时刻sweep的结束,即k+1时刻sweep的开始来得到的。
    而当前时刻k+1时刻的点云映射到k+1时刻的初始是使用TransformToStart()实现。
    假设k+1时刻的sweep中与前一k时刻的sweep的运动一致 T k + 1 L T^L_{k+1} Tk+1L。使用位置插值方法得到整个sweep点云对应的 T k + 1 , i L T^L_{k+1,i} Tk+1,iL,从而利用TransformToStart(),TransformToEnd()可将点云映射到sweep初始和结束时的坐标系下。

    位姿插值
    论文中,作者采用的是二维雷达加了一个电机旋转,每一次scan得到的点云的xyz是基于雷达的自身的坐标系,就是已经旋转后的雷达坐标系。
    设雷达匀速旋转及匀速偏移,通过插值的方法,得到一个完整的sweep中,每一个scan对应的T(q,t),并将点云坐标变换到每一次的sweep初始坐标系。消除点云在sweep中的因雷达运动而产生的误差,得到undistorted 的点云 P ~ k \widetilde P_k P k
    详细实现在laserOdometry.cpp TransformToStart函数中。
    在这里插入图片描述

    对于边线点 i ∈ P k + 1 i\in P_{k+1} iPk+1,对应找到 P k ‾ \overline{P_k} Pk相邻scan中最近的中两个点(j, l),则两个点则确定了边线,计算变换矩阵T能使,点i到边线(j, l)的距离最小。j为最近点,然后再j所在scan的相邻scan中,找到l点。

    距离约束:
    点到线的距离计算公式如下:原理是目标点到两个原始点组成的两个向量构成的平行四边形面积/底边长度。
    在这里插入图片描述
    对于平面点 i ∈ P k + 1 i\in P_{k+1} iPk+1,对应找到 P k ~ \widetilde{P_k} Pk 相邻scan中最近的中三个点(j, l,m),则三个点则确定了平面,计算变换矩阵T能使,点i到平面的距离(j, l,m)最小。
    在这里插入图片描述
    点到面距离计算公式如下:原理:目标点到三个原始点组成的三个向量构成的斜方体/底面面积。
    分子:第二行两个向量的叉乘结果值等于j,l,m三个点构成的三角形面积,方向垂直于平面向上。
    结果点乘分子第一行,则可以得到i,j,l,m构成的斜三棱柱的体积。
    分母:等同于分子第二行。
    如下图所示:在这里插入图片描述
    即分别对应了点云匹配中的点到线及点到面的算法。

    向量a×向量b=
      | i     j     k |
      |a1   b1  c1|
      |a2   b2  c2|
      =(b1c2-b2c1,c1a2-a1c2,a1b2-a2b1)

距离公式解释参见LOAM 论文及原理分析

这里列出平面点的距离约束计算对应代码:

// tripod1,tripod2,tripod3对应公式的j,l,m三点
tripod1 = _lastSurfaceCloud->points[_pointSearchSurfInd1[i]];
tripod2 = _lastSurfaceCloud->points[_pointSearchSurfInd2[i]];
tripod3 = _lastSurfaceCloud->points[_pointSearchSurfInd3[i]];//pa,pb,pc为公式中的分母项各分量(利用叉乘的公式得到),pd为分母项的值
float pa = (tripod2.y - tripod1.y) * (tripod3.z - tripod1.z)- (tripod3.y - tripod1.y) * (tripod2.z - tripod1.z);
float pb = (tripod2.z - tripod1.z) * (tripod3.x - tripod1.x)- (tripod3.z - tripod1.z) * (tripod2.x - tripod1.x);
float pc = (tripod2.x - tripod1.x) * (tripod3.y - tripod1.y)- (tripod3.x - tripod1.x) * (tripod2.y - tripod1.y);
float pd = -(pa * tripod1.x + pb * tripod1.y + pc * tripod1.z);float ps = sqrt(pa * pa + pb * pb + pc * pc); 
pa /= ps;
pb /= ps;
pc /= ps;
pd /= ps;// pointSel对应公式的{\widetilde{X}}_{(k+1,i)}^L
float pd2 = pa * pointSel.x + pb * pointSel.y + pc * pointSel.z + pd;

pointSel对应公式的 X ~ ( k + 1 , i ) L {\widetilde{X}}_{(k+1,i)}^L X (k+1,i)L

注:向量外积在数值上等于这两个向量构成的平行四边形的面积。
其中:
X ‾ k = R X k − 1 + T \overline X_k=RX_{k-1}+T Xk=RXk1+T X ~ k = R i n t e X k − 1 + T i n t e \widetilde X_k=R_{inte}X_{k-1}+T_{inte} X k=RinteXk1+Tinte
R i n t e 和 T i n t e R_{inte}和T_{inte} RinteTinte为将每个sweep中不同的scan的雷达坐标变换,用于将sweep下每个scan都映射到sweep的起始坐标系。 R i n t e 和 T i n t e R_{inte}和T_{inte} RinteTinte R 和 T R和T RT插值得到。

而后,利用LM方法计算得到 T k + 1 L T^L_{k+1} Tk+1L,得到该时刻的定位值(雷达里程计)
在这里插入图片描述
融合高频粗略的运动估计和优化后的位姿估计,得到准确位姿。根据位姿及得到的点云进行建图,创建点云地图。

  • 代码文件:laserOdometry.cpp
    ALOAM中实现代码比较清晰。根据scanRegistration发布的点云信息,寻找角点与平面点的匹配点,并构建点到线及点到面的约束方程,使用ceres进行求解。

    点云使用pcl下的kdtree存储。先将点云都变换到sweep起始坐标系,然后在存放上一帧点云的kdtree中查找点云的最邻近点,在找到的最邻近点的相邻帧找到邻近点的最邻近的点。并构造距离方程。

    通过迭代得到:q_last_curr,t_last_curr,即上一个sweep其实坐标系相对与这一个sweep的起始坐标系的变换。
    累积便可的odom的输出。

在这里插入图片描述

  1. 雷达建图(lidar mapping): (低频) 一次完整sweep执行一次
    地图创建
    雷达地图创建采用点云地图,通过迭代得到的每一次sweep对应的雷达的世界坐标系下的位姿变换矩阵,得到点云的世界坐标坐标。
    位姿精优化(mapping odometry)
    使用的点云数量是高频odom输出的10倍,使用分块(cude)存储点云,但同时处理频率是odom的1/10。
    将当前雷达所在位置为中心cube,submap为当前中心cube相邻水平左右2两个cube,竖直上下两个cube,深度前后1个cube中的点云(一个方向上5个cube),将submap中的点云进行降采样,并筛除不在当前相机视野下的点云,作为target,以当前帧降采样后的特征点云为source的ICP过程。优化变量为里程计的运动估计误差矩阵 T o d o m 2 m a p T_{odom2map} Todom2map

    精优化的点到线约束代码实现过程(A-LOAM)

    1. 选取点最近邻5个点,进行协方差矩阵特征值、特征向量计算,若其中一个特征值远大于其他特征值,则说明该点是边线点,其中最大的特征值对应的特征向量就是该线的方向向量。这个判断方法同NICP算法的平面法向量计算。解释参考
    2. 利用得到的直线的方向向量在该点附近构造2个邻近点,同odom使用同样点到线的距离约束方程进行约束。

    精优化的点到面约束代码实现过程(A-LOAM):

    1. 选取最近邻5个点 ,设平面方程为ax + by + cz + 1 = 0,求解平面法向量X=(a,b,c),将最近邻5个点带入平面方程,得到 A X = B AX=B AX=B的方程,其中A为有5个点云构成的5*3的矩阵, B = [ − 1 , − 1 , − 1 , − 1 , − 1 ] T B=[-1,-1,-1,-1,-1]^T B=[1,1,1,1,1]T,使用QR分解得到平面法向量X=(a,b,c)。并对向量进行归一化得到(a’, b’, c’)。norm = matA0.colPivHouseholderQr().solve(matB0);
    2. 点( x 0 , y 0 , z 0 x_0,y_0,z_0 x0,y0,z0)到平面的计算公式: a b s ( a x 0 + b y 0 + c z 0 + 1 ) / ( a 2 + b 2 + c 2 ) = a ′ x 0 + b ′ y 0 + c ′ z 0 + 1 / n o r m abs(ax_0 + by_0 + cz_0 + 1) /\sqrt{(a^2 + b^2 + c^2)}=a'x_0 + b'y_0 + c'z_0 + 1/norm abs(ax0+by0+cz0+1)/(a2+b2+c2) =ax0+by0+cz0+1/norm

    这个点(角点/平面点)特征的区分不同于雷达里程计的输入的点云提取,是因为,在雷达里程计的计算中,舍去了参考意义小或重复的点云。

    下图为雷达里程计的输出和laser mapping下优化位姿变换的输出的关系:
    雷达里程计的输出是在雷达坐标系下,高频,有漂移;
    地图最后输出位姿变化是全局的,高精度,低频。
    在这里插入图片描述

  • 代码文件:laserMapping.cpp
    接收odom发来的odom定位估计以及去误差的点云 P k P_k Pk映射到世界坐标系下,记为 Q k Q_k Qk,并将下采用后的点云存储在cubes中,就类似三维栅格,利用cubes将点云分块存放,每个cubes的点云。cubes的预留个数: (Width 21)*(Height 11)*(Depth 21);

LOAM中Mapping线程中的帧与submap的特征匹配,用到的submap就是上图中的黄色区域,submap中的corner特征和surf特征在匹配中作为target(筛除无效点后存放在kdtree[Corner/Surf]FromMap);而当前帧的单帧点云中的两种特征在匹配中作为source(代码中存放在laserCloudxxxStack2中)。
[centerCubeI,centerCubeJ,centerCubeK]为当前帧点云(source)的cube坐标。因为保证索引的非负性,所以计算时要加上laserCloudCenWidth[/Height/Depth]。

此外要保证【3 < centerCubeI < 18, 3 < centerCubeJ < 8, 3 < centerCubeK < 18】,因为要保证【submap为当前中心cube相邻水平左右2两个cube,竖直上下两个cube,深度前后1个cube中的点云(一个方向上5个cube)】,
如果[centerCubeI,centerCubeJ,centerCubeK]不满足以上条件,如centerCubeI<3时,则对应调节预留的cubes的分布位置,保证submap的正确提取。

以下图片来自https://www.cnblogs.com/wellp/p/8877990.html
在这里插入图片描述
MAP的ICP也是将点云分为边线点(edge/corner)和平面点(planner/sur),来一起添加约束方程
边线点判断。边线点和平面点的分类,是通过计算点与周围点簇的协方差矩阵的特征值来判断的。
当最大的特征值远大于其他特征值,说明该点位于边线上;
当最小的特征值远小于其他特征值,说明该点位于平面上。

点云的曲率计算与odom一样,点云数量比odom多;
通过分析点云簇 S ′ S' S的协方差矩阵,分析边线及平面的方向;
A-LOAM 的laserMapping.cpp集成LOAM的transformMaintenance.cpp中的odom输出的高频及map输出的低频集成高频的定位。q_wmap_wodom ,t_wmap_wodom 来消除odom相对于map的偏差。
当odom定位输出后,如果q_wmap_wodom ,t_wmap_wodom有输出则更新,如何没有,则按先前的q_wmap_wodom ,t_wmap_wodom更新odom的输出,从而实现高频的map定位输出。

  • 代码文件:lidarFactor.hpp
    定义ceres的代价结构体及仿函数
    LidarEdgeFactor
    odom和map中点到线约束结构体及仿函数:使用2个临近点(j,l)确定直线,点到直线的距离作为约束

    LidarPlaneFactor
    odom点到面的约束结构体及仿函数:当前点p,使用3个邻近点(j,l,m)确定平面,使用(lp - lpj).dot(ljm),NICP思路

    LidarPlaneNormFactor
    map精优化的点到面的约束及仿函数,就是点到面的计算公式: a b s ( a x 0 + b y 0 + c z 0 + 1 ) / ( a 2 + b 2 + c 2 ) = a ′ x 0 + b ′ y 0 + c ′ z 0 + 1 / n o r m abs(ax_0 + by_0 + cz_0 + 1) /\sqrt{(a^2 + b^2 + c^2)}=a'x_0 + b'y_0 + c'z_0 + 1/norm abs(ax0+by0+cz0+1)/(a2+b2+c2) =ax0+by0+cz0+1/norm

    LidarDistanceFactor未用

退化问题

定位问题分为两步:1、位姿预测;2、位姿优化
1、位姿预测( x p x_p xp):使用imu预测姿态,或前端点云计算得到位姿;
2、位姿优化( x u x_u xu):使用非线性最小二乘优化方法得到的位姿。
退化问题解决思路:
退化问题主要出现在位姿优化,当出现退化现象时,舍弃退化方向的值,使用预测值(由其他传感器估计或者模型估计计算得到)来填充退化方向上的位姿解。

求解问题如下:
在这里插入图片描述可使用如下方法求解:
A x = b Ax=b Ax=b两边左乘 A T A^T AT,得到 A T A x = A T b A^TAx=A^Tb ATAx=ATb,保证 A T A A^TA ATA满秩,即可逆,则可根据 x = ( A T A ) − 1 A T b x=(A^TA)^{-1}A^Tb x=(ATA)1ATb解出 x x x

作者定义退化因子 D = λ m i n + 1 \mathcal{D}=\lambda_{min}+1 D=λmin+1
其中 λ m i n \lambda_{min} λmin A T A A^TA ATA的特征值,特征值很小时,则表明该特征值对应的方向存在退化现象。
退化现象的表现:
在这里插入图片描述(a)表示求解约束较好的情况,(b)退化情况,在解在蓝色方向上存在退化,表明,蓝色箭头方向解的不确定性大。

v 1 , . . . , v m v_1,...,v_m v1,...,vm 对应的特征值小于阈值,因此被视为退化方向向量。
v m + 1 , . . . , v n v_{m+1},...,v_n vm+1,...,vn对应的特征值大于阈值,因此被视为非退化方向向量。
在这里插入图片描述则:
在这里插入图片描述其中:
在这里插入图片描述由以下公式得到上式:
在这里插入图片描述 V p x p V_px_p Vpxp将预测值(由传感器或者模型预测得到)映射到退化方向上;
V u x u V_ux_u Vuxu将计算值映射到非退化方向上,其实就是舍弃退化部分;
因此,退化部分使用预测值和计算优化部分的非退化部分。

解释: V f x f = V p x p + V u x u V_fx_f=V_px_p+V_ux_u Vfxf=Vpxp+Vuxu
在这里插入图片描述
设预估值为 x p x_p xp,更新值为 x u x_u xu,更新值 x u x_u xu在特征向量 v 1 v_1 v1方向退化,将预估值 x p x_p xp映射到 v 1 v_1 v1方向,将更新值 x u x_u xu映射到 v 2 v_2 v2方向。最后合成为 x f x_f xf

V p x p V_px_p Vpxp x p x_p xp V p V_p Vp中的各个特征向量的投影*对应向量的模

而在LOAM中,使用imu作为姿态预测,使用雷达点云的点到线、点到面来优化姿态角,并计算得到偏移。或者三前端计算得到位姿,后端批量优化。
Δ x u \Delta x_u Δxu为后端优化相对于前端预测值,得到的位姿偏差。此时:(与论文中的伪代码不同,包括代码中的matP都应为matU), V p V_p Vp应为 V u V_u Vu,即提出 Δ x u \Delta x_u Δxu的非退化部分。
在这里插入图片描述在这里插入图片描述

代码结构

在这里插入图片描述

#loam_velodyne.launch<node pkg="loam_velodyne" type="scanRegistration" name="scanRegistration" output="screen"/><node pkg="loam_velodyne" type="laserOdometry" name="laserOdometry" output="screen" respawn="true"></node><node pkg="loam_velodyne" type="laserMapping" name="laserMapping" output="screen"/><node pkg="loam_velodyne" type="transformMaintenance" name="transformMaintenance" output="screen"/><group if="$(arg rviz)"><node launch-prefix="nice" pkg="rviz" type="rviz" name="rviz" args="-d $(find loam_velodyne)/rviz_cfg/loam_velodyne.rviz" /></group>

scanRegistration:点云提取,特征点分类
laserOdometry:点到线 点到面匹配,得到初始定位信息,高频输出10hz
laserMapping:将点云分块处理,寻找最近邻的匹配点,且用于计算点云簇的法向量,类似point-to-plain方法,实现点到线及点到面的约束,最后得到去漂的优化定位值。低频输出。
transformMaintenance:将odom的高频粗匹配与map的低频高精度定位值进行集成,输出高频高精度的定位信息。

aloam 集成代码中的实现在laserMapping.cpp,当得到odom粗匹配则利用map的定位输出进行校正一下,然后发布校正后的定位信息。map校正是通过计算map与odom之间的坐标系关系匹配的。

loam_velodyne源码解析
A-LOAM代码解析

每个cpp文件对应LOAM框架重的一个节点。
推荐两篇讲述论文的博客及文档
LOAM笔记及A-LOAM源码阅读
loam_velodyne
参考:
https://zhuanlan.zhihu.com/p/57351961
LOAM笔记及A-LOAM源码阅读
3D 激光SLAM ->loam_velodyne论文与代码解析Lidar Odometry and Mapping
LOAM论文和程序代码的解读
https://blog.csdn.net/shoufei403/article/details/103664877


http://chatgpt.dhexx.cn/article/nZY4sNcR.shtml

相关文章

学习LOAM笔记——特征点提取与匹配

学习LOAM笔记——特征点提取与匹配 学习LOAM笔记——特征点提取与匹配1. 特征点提取1.1 对激光点按线束分类1.2 计算激光点曲率1.3 根据曲率提取特征点 2. 特征点匹配2.1 scan-to-scan中的特征点匹配2.2 scan-to-map中特征点匹配 3. 补充 学习LOAM笔记——特征点提取与匹配 兜…

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

参考论文&#xff1a;LOAM: Lidar Odometry and Mapping in Real-time 代码&#xff1a;A-LOAM Ubuntu 18.04 ROS Melodic eigen 3.3.4 PCL 1.8.1 ceres 2.0 A-LOAM 配置 LOAM算法是激光slam中一个经典的开源框架&#xff0c;结合qin tong 博士的开源代码a-loam&#xff…

无人驾驶学习笔记 - LOAM 算法论文核心关键点总结

目录 1、框架 2、特征点提取 3、点云去畸变 4、帧间匹配 特征关联与损失函数计算 a 线特征 b 面特征 5、运动估计 6、建图 7、姿态融合 8、LOAM 优劣势 9、参考连接 1、框架 loam框架核心是两部分&#xff0c;高频率的里程计和低频率的建图。两种算法处理。里程计通…

LOAM简介

LOAM 文章目录 LOAMLOAM系统流程1、特征提取&#xff08;1&#xff09;按线数分割&#xff08;2&#xff09;计算曲率&#xff08;3&#xff09;删除异常点&#xff08;4&#xff09;按曲率大小筛选特征点 2、帧间匹配&#xff08;1&#xff09;特征关联与损失函数计算&#xf…

SLAM算法 -LOAM框架分析(一)

LOAM框架分析 算法简介1 激光里程计(高频率)1.1 计算曲率1.2 筛选特征1.3 问题建模1.3.1 损失函数1.3.2 运动补偿 1.4 优化求解1.5 定位输出 2 环境建图(低频率)2.1 问题模型2.2 PCA特征 参考文献 算法简介 LOAM的整体思想就是将复杂的SLAM问题分为&#xff1a;1. 高频的运动估…

顶级高手常用的16个思维模型

“养成一个掌握多元思维模型的习惯是你能做的最有用的事情”&#xff0c;投资家、巴菲特的黄金拍档查理 芒格认为&#xff1a;“思维模型是你大脑中做决策的工具箱。你的工具箱越多&#xff0c;你就越能做出最正确的决策。”与您分享查理芒格的12种思维模型&#xff0c;对做决…

100种思维模型之大脑系统思维模型-52

上世纪60年代&#xff0c;美国神经学家保罗 D 麦克莱恩&#xff08;Paul D. MacLean&#xff09;首次提出“三脑一体”假说&#xff0c;他认为人的大脑是蜥蜴-松鼠-猴子合体的隐喻&#xff0c;代表了进化发展不同阶段的遗传。 复旦大学管理学院的项保华教授对此有一个精彩的总结…

思维模型 SWOT分析

本系列文章 主要是 分享 思维模型&#xff0c;涉及各个领域&#xff0c;重在提升认知 1 模型故事 一个技术岗位想转产品经理&#xff08;个人职业规划SWOT的应用&#xff09;&#xff0c;做的SWOT分析&#xff0c;进而可以量化自己转型的成本&#xff1a; 小王想在自己的居住小…

【转载】100个思维模型(不一定都适用,各取所需)

世界上最有智慧的人是怎样理性思考的&#xff1f;他们在商业活动和个人生活中是如何做决策的&#xff1f; 95岁的智慧老人查理芒格的“多元思维模型”&#xff0c;相信大家都不陌生。 他提倡要学习在所有学科中真正重要的理论&#xff0c;并在此基础上形成所谓的“普世智慧”&…

思维模型 GROW

本系列文章 主要是 分享 思维模型&#xff0c;涉及各个领域&#xff0c;重在提升认知 1 模型故事 推广故事&#xff1a;近期A公司开发一个产品活动的 促销方案&#xff0c;进行了简单的业务流程梳理后便开始了小范围的推广。首先让公司里的同事每人每天拉取20个新人。经过10天…

100种思维模型之细节效率思维模型-74

提及细节效率&#xff1f;也许很多人会有疑问&#xff0c;“效率”怎么跟“细节”挂上钩&#xff0c;注重“细节”了&#xff0c;还能有“高率”&#xff1f; 是的&#xff0c;细节能提高效率&#xff0c;注意某些细节&#xff0c;效率事半功倍。 01、何谓细节效率思维模型 一…

100种思维模型之长远思考思维模型-63

古语有云&#xff1a;“人无远虑&#xff0c;必有近忧&#xff01;” 任正非说&#xff1a;不谋长远者&#xff0c;不足以谋一时&#xff01; 长远思考思维&#xff0c;一个提醒我们要运用长远眼光&#xff0c;树立宏大目标&#xff0c;关注长期利益的思维模型 01何谓长远思考…

提升自己的认知-思维模型

之前写过有关思维的博客思维方式与认知,关于思维方式与做事方式有所思考。最近看到如何判断一个人是杰出的聪明人还是平庸的普通人?的文章,感触颇深。现摘录有所感触的思维方式。 一、思维模型 1、每周“5小时”学习法则 参考:https://36kr.com/p/5130501.html?from=aut…

100种思维模型之坏模因思维模型-44

啥是模因&#xff1f; 简单说&#xff0c;就是 文化基因&#xff0c; 也就是别人传输给我们的 观念。 我们生活中到处都是 模因&#xff0c; 比如&#xff0c;“跟我不一致的观点都是错的”&#xff0c;属于敌对型模因&#xff0c;让别的观念没办法进入你的大脑&#xf…

40个经典思维模型(附下载)

导读&#xff1a; 思维模型可以称之为知识背后的知识&#xff0c;道理背后的道理&#xff0c;现象背后的真相。可以指导我们以一当百&#xff0c;更加本质的看透事物和现象&#xff0c;并更加本质的解决问题。 如果我们要学习的东西有限&#xff0c;那么我会推荐每个人优先去学…

100种分析思维模型(1)

公众号后台回复“图书“&#xff0c;了解更多号主新书内容 作者&#xff1a;林骥 来源&#xff1a;林骥 最近&#xff0c;我在读《穷查理宝典》这本书&#xff0c;其中提到查理芒格应用大约 100 种多元思维模型&#xff0c;他孜孜不倦地对投资问题进行充分的准备、广泛的研究和…

常见思维模型汇总(一)

文章目录 一、SWOT模型1、简介 2、SWOT模型的拆解二、波士顿5力模型1、简介2、缺陷3、分解3.1&#xff0e;供应商的议价能力&#xff08;Bargaining Power of Suppliers)3.2&#xff0e;购买者的议价能力 (Bargaining Power of Buyers)3.3&#xff0e;新进入者的威胁&#xff0…

12个顶级思维模型,非常值得一看!

“思维模型是你大脑中做决策的工具箱。你的工具箱越多,你就越能做出最正确的决策。”不管你是领导团队,还是制定市场战略,思维模型都能够在其中发挥至关重要的作用。 打造多元思维模型的想法来自查理芒格:“思维模型是你大脑中做决策的工具箱。你的工具箱越多,你就越能做…

16个顶级思维模型

思维模型会给你提供一种视角或思维框架&#xff0c;从而决定你观察事物和看待世界的视角。顶级的思维模型能提高你成功的可能性&#xff0c;并帮你避免失败。 打造多元思维模型想法来自查理芒格&#xff0c;而查理芒格是沃伦巴菲特的得力助手。Farnam Street曾这样描述思维模型…

100种分析思维模型(5)

公众号后台回复“图书“&#xff0c;了解更多号主新书内容 作者&#xff1a;林骥 来源&#xff1a;林骥 很多分析思维模型&#xff0c;本质上都是在研究人的行为。 下面介绍的 RFM 分析思维模型&#xff0c;本质上也是在研究人的行为。 1. 模型介绍 美国有一个叫 Arthur Hughes…