十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

LIO-SAM-DetailedNote源码解析(四):MapOptimization之scan-to-map迭代优化全解指南

LIO-SAM-DetailedNote源码解析(四):MapOptimization之scan-to-map迭代优化全解指南 LIO-SAM-DetailedNote源码解析(四)MapOptimization之scan-to-map迭代优化全解指南【免费下载链接】LIO-SAM-DetailedNoteLIO-SAM源码详细注释3D SLAM融合激光、IMU、GPS项目地址: https://gitcode.com/gh_mirrors/li/LIO-SAM-DetailedNoteLIO-SAM-DetailedNote 项目对 LIO-SAM激光IMUGPS 融合的 3D SLAM源码做了逐行中文注释。本篇聚焦最核心的 src/mapOptmization.cpp它如何把一帧激光点云与局部地图对齐scan-to-map 迭代优化又如何通过关键帧因子图把全局轨迹拉直。读完你能看懂 LIO-SAM 位姿估计的完整链路。一、MapOptimization 在 LIO-SAM 系统架构中的位置LIO-SAM 由四个模块串成流水线imageProjection运动补偿→featureExtraction角点/平面点提取→mapOptimizationscan-to-map 因子图→imuPreintegrationIMU 预积分。mapOptimization是大脑它订阅lio_sam/feature/cloud_info来自特征提取与 GPS 里程计对外发布激光里程计lio_sam/mapping/odometry、局部/全局地图、轨迹等十几个话题二、主流程laserCloudInfoHandler 的 7 步流水线每收到一帧点云信息约 0.15s 一帧由mappingProcessInterval控制laserCloudInfoHandlersrc/mapOptmization.cpp第 340 行按顺序执行步骤函数做什么1updateInitialGuessL1001用 IMU 里程计增量初始化当前帧位姿2extractSurroundingKeyFramesL1190从相邻关键帧拼出局部地图3downsampleCurrentScanL1211对当前帧角点/平面点体素降采样4scan2MapOptimizationL1619⭐ scan-to-map 迭代优化位姿本文重点5saveKeyFramesAndFactorL1885关键帧入图 因子图优化6correctPosesL1981闭环后用新位姿刷新全部历史关键帧7publishOdometry/publishFrames发布里程计与地图下面逐一拆解关键步骤。三、步骤 1位姿初始化——IMU 给第一脚scan-to-map 是局部优化必须有足够好的初值。updateInitialGuess的策略很务实第一帧直接取 IMU 原始数据的 RPY 初始化旋转部分后续帧取当前帧与前一帧的 IMU 里程计算出相对位姿增量transIncre左乘到前一帧激光位姿上得到当前帧初值第 1039–1046 行。这样 IMU 高频数据200Hz 级别为低频激光匹配5–10Hz提供了平滑的位姿桥接。四、步骤 2局部地图怎么拼——时空双重邻近extractNearbyL1101extractCloudL1141负责构建局部地图思路是空间邻近 时间邻近双保险以最近关键帧为中心用 KD 树做半径搜索surroundingKeyframeSearchRadius默认 50m找出空间上邻近的关键帧再补上最近 10 秒内的关键帧——防止载体原地转圈时空间搜索漏掉帧对位姿集合按 2m 密度降采样把这些关键帧的角点/平面点变换到世界系合并成laserCloudCornerFromMap/laserCloudSurfFromMap用laserCloudMapContainer缓存已变换过的关键帧点云避免重复计算超过 1000 条清空防内存膨胀。当前帧的特征点则用 0.2m / 0.4m 体素mappingCornerLeafSize/mappingSurfLeafSize降采样保证点数可控。五、步骤 3scan-to-map 迭代优化核心解析这是全文最核心的部分位于scan2MapOptimizationL1619。5.1 总循环最多 30 次迭代初始化 KD 树输入 → for 迭代 ≤ 30 次 { cornerOptimization(); // 角点找直线约束 surfOptimization(); // 平面点找平面约束 combineOptimizationCoeffs(); // 汇总匹配点 if (LMOptimization(iter) 收敛) break; } transformUpdate(); // IMU 加权融合进入优化的前置条件当前帧角点 ≥ 10、平面点 ≥ 100edgeFeatureMinValidNum/surfFeatureMinValidNum。5.2 角点 ↔ 直线covariance 特征值判线cornerOptimizationL1239对每个当前帧角点按当前位姿变换到地图系在局部角点地图中查 5 个最近点5 点距离都 1m才有效计算 5 点关于中心的 3×3 协方差矩阵并做特征分解若最大特征值 3 倍次大特征值认为 5 点构成一条直线角点对应直线特征沿直线方向取中心点 ±0.1m 两点构成三角形算出点到直线的距离和垂线单位向量距离越大惩罚越重权重s 1 - 0.9×|d|要求s 0.1才参与优化。5.3 平面点 ↔ 平面最小二乘拟合surfOptimizationL1358逻辑对称同样查 5 个最近点 1m用最小二乘colPivHouseholderQr拟合平面方程 axbycz10校验5 个点中若有任意一点到拟合平面超过 0.2m判定点太散弃用合格则计算点到平面距离与单位法向量同样带距离惩罚权重s。这就是 LOAM 系算法点-线 / 点-面约束的精髓用几何约束代替一对一最近点天然抑制离群值。5.4 高斯牛顿求解 退化检测LMOptimizationL1474把点到直线/平面的距离作为观测对 6 维位姿增量[dr,dp,dy,dx,dy,dz]求偏导构建 Jacobian 矩阵 A解正规方程AᵀA·Δx AᵀB即 JᵀJ·Δx -Jᵀf匹配点数 50 直接失败返回。值得一提的是退化检测L1550–1572首次迭代对近似 Hessian 矩阵做特征值分解若某方向特征值 100说明该方向约束太弱比如在空旷路面yaw 方向无约束就用投影矩阵matP把增量投影到强约束子空间上避免位姿在弱约束方向上漂移。5.5 收敛判据与 IMU 加权融合收敛旋转增量 0.05° 且平移增量 0.05cmL1599transformUpdateL1667做最后一步IMU 信任投票roll/pitch 用 slerp 在激光解与 IMU RPY 间按imuRPYWeight默认 0.01几乎全信激光加权平均并对 roll、pitch、z 做限幅约束constraintTransformation防止 2D 运动场景下这些维度被点云带偏。六、关键帧策略与因子图优化scan-to-map 只是当前帧的优化LIO-SAM 的全局一致性靠 GTAM 因子图src/mapOptmization.cpp顶部引入gtsam/全家桶用ISAM2增量式求解。saveKeyFramesAndFactorL1885的要点关键帧筛选saveFrameL1718当前帧相对前一关键帧的旋转变化 0.2rad且平移 1.0m → 不入库避免地图冗余激光里程计因子前一关键帧到当前帧的 BetweenFactor旋转/平移噪声方差 1e-6 / 1e-4可信度很高GPS 因子0.2s 窗口内取最近 GPS每隔 5m 才加一个协方差超阈值的 GPS 直接丢弃——只在激光漂移大协方差超 25m²时才真正救场闭环因子见下节ISAM2 更新后取出最新位姿回填transformTobeMapped同时计算位姿协方差供后续 GPS 触发判断。七、闭环检测距离近、时间远的老朋友闭环跑在独立线程loopClosureThreadL6751Hz候选搜索detectLoopClosureDistanceL809半径 15m 内找历史关键帧且时间差 30s——空间上回到老地方时间上确实是很久之前ICP 验证L752–767当前帧与候选帧周围 ±25 个关键帧的降采样点云做 ICPfitness score 0.3才算真闭环误报直接丢弃加入闭环因子把 ICP 解出的相对位姿与 fitness score 作为噪声推入loopIndexQueue由addLoopFactor加进因子图全局刷新闭环当帧 ISAM2 额外多迭代 5 次L1907–1914correctPoses把所有历史关键帧位姿、局部地图缓存、轨迹全部重写。八、关键参数速查config/params.yaml调参时优先看这几个参数默认值作用mappingProcessInterval0.15s映射主循环频率上限surroundingKeyframeSearchRadius50m局部地图空间半径surroundingKeyframeDensity2.0m局部地图关键帧密度surroundingkeyframeAddingDist/AngleThreshold1.0m / 0.2rad关键帧准入阈值mappingCorner/SurfLeafSize0.2 / 0.4m降采样体素大小historyKeyframeSearchRadius/TimeDiff15m / 30s闭环候选条件historyKeyframeFitnessScore0.3闭环 ICP 阈值越小越严gpsCovThreshold/poseCovThreshold2 / 25 m²GPS 可用性阈值imuRPYWeight0.01IMU 姿态融合权重九、小结LIO-SAM 的 scan-to-map 点-线/点-面约束 高斯牛顿 退化保护 30 次迭代收敛比原始 LOAM 的 scan-to-scan 更鲁棒、信息更丰富IMU 全程扮演初值提供者 姿态仲裁者两个角色激光提供精确约束因子图ISAM2把单帧优化升级为全局一致轨迹GPS 与闭环因子是兜底与纠偏想继续深挖IMU 预积分细节在 src/imuPreintegration.cpp特征提取在 src/featureExtraction.cpp运动补偿在 src/imageProjection.cpp全部带详细中文注释建议对照本文通读一遍src/mapOptmization.cpp的函数注释。【免费下载链接】LIO-SAM-DetailedNoteLIO-SAM源码详细注释3D SLAM融合激光、IMU、GPS项目地址: https://gitcode.com/gh_mirrors/li/LIO-SAM-DetailedNote创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表