资讯动态

雷达SLAM经典:LIO-mapping紧耦合框架与IMU预积分因子图解析

发布时间:2026/10/20 16:04:50 来源:尧图企业网站定制
雷达SLAM方向的论文精读我一直保持着写笔记的习惯这个系列写到第七篇了。今天想拆的是LIO-mapping一篇对我实际工作影响很大的工作。它做的事可以概括成一句话把激光雷达和IMU重新组合成一套完整的定位建图方案输出高频里程计和一致性地图。但真正让我服气的是它的系统设计思路——并没有把IMU当“辅助传感器”来用而是实打实让IMU参与进了后端优化。这篇论文适合谁读如果你在做机器人导航、自动驾驶感知或者手持扫描设备的实时建图只要你手里同时有激光雷达和IMU这篇就是绕不过去的经典。尤其是它启发了后来一系列LIO方案把这篇吃透再看后面那些工作会轻松很多。1. 从“能用”到“好用”LIO-mapping到底做了什么1.1 松耦合与紧耦合IMU在系统里的角色先说背景。在很多早期的激光雷达方案里IMU就是个“工具人”。最典型的是LOAM系的做法IMU负责在两帧激光之间提供一个粗略的旋转初值帮助点云去畸变或者给帧间匹配一个初始猜测。这在大部分场景下够用但有个问题——IMU的测量信息只参与了“前端计算”没有进入后端的优化目标函数。也就是说IMU的误差、IMU的漂移系统根本不关心也不会去修正它。这种方案就是松耦合或者半耦合。IMU精度再高也只是个“初始值提供器”。LIO-mapping的思路完全不同。它把IMU预积分结果做成了因子图里的一个约束项和激光配准得到的约束放在一起由后端优化器统一调整。IMU不再是打杂的而是和激光雷达平起平坐的传感器。这就是“紧耦合”的直观含义两类传感器的原始信息共同决定状态估计的结果。我当时第一次跑通这个系统最大的感受是在快速旋转或者剧烈加减速的时候纯激光方案很容易丢匹配而LIO-mapping靠着IMU因子能撑过去位姿不会突然断掉。这种“兜底”能力松耦合方案给不了。对比维度松耦合方案LIO-mapping紧耦合方案IMU角色提供初始值/去畸变辅助作为因子参与全局优化传感器误差修正IMU误差不会被后端修正零偏在优化中在线估计退化场景表现激光退化时整体失效IMU可短暂支撑缓解漂移计算复杂度较低较高需要预积分和因子图优化代表思路LOAM、部分改进方案LIO-mapping、后续LIO-SAM等1.2 三个关键贡献紧耦合、描述子、增量优化如果只记住这篇论文的三个关键词我建议是这三个紧耦合因子图框架、旋转不变的点云描述子、基于ISAM2的增量优化。第一点容易理解上文已经解释过。第二点是针对回环检测的。很多激光方案在建大场景时容易漂移因为没有闭环能力。LIO-mapping在提取特征的同时还为每帧点云生成一个全局描述子利用描述子之间的相似度判断是否回到曾经去过的地方触发回环约束。第三点它没有用每次全量优化的方式而是用GTSAM里的ISAM2做增量优化。通俗讲就是“哪变了改哪”而不是每次把所有东西重算一遍这样长时间运行的计算压力小很多。这三件事叠在一起构成了一个完整的“里程计建图闭环”闭环系统。在2019年那个时间点这个组合是相当超前的。2. 三个核心模块特征、预积分、因子图2.1 特征提取曲率、分区与全局描述子LIO-mapping的特征提取逻辑继承自LOAM那一套但做了扩展。具体做法是对每一帧点云按扫描线组织数据对每个点计算它和邻域点的曲率。曲率大的点通常是角点、边缘点适合做线特征曲率小的点一般是平面点适合做面特征。计算曲率的方式并不复杂取当前点左右各若干个点算这些邻域点到当前点的距离方差。方差越大说明该点附近几何变化越剧烈越可能是边缘。这个思路很朴素但确实管用到现在很多方案还在沿用。为了保证特征在空间中分布均匀而不是全部挤在某个方向论文里把每一帧点云按方位角分成多个子区域每个区域里再按曲率排序挑出指定数量的角点和平面点。我复现的时候发现这个“分区采样”非常重要——如果只是全局取曲率最大的点遇到树木、栏杆多的场景特征会扎堆匹配效果反而下降。LIO-mapping还多了一步生成全局描述子。它把点云投影到水平方向的网格里每个网格统计该区域内的几何分布信息编码成一个高维向量。两帧点云之间的描述子距离足够小就认为可能回到了同一个地方再用ICP做精配准验证确认后回环因子才真正加入优化。这里的经验是描述子不是越复杂越好关键是“旋转不变”。车或者机器人转了个角度回到原地描述子如果对朝向敏感闭环就会漏检。LIO-mapping在设计描述子时显然考虑了这一点实际测试里横向、纵向偏移几十米都能正确找回。2.2 IMU预积分从原始测量到优化因子IMU预积分是这篇论文里最容易劝退人的部分但也是紧耦合的核心。我尽量用大白话讲清楚。IMU输出的加速度和角速度频率很高一秒钟几百次。如果每一次优化迭代都把两帧之间这几百个测量重新积分一遍计算量完全扛不住。预积分的思路是把两帧之间的所有IMU测量先“离线”积成一个相对量比如两帧之间的相对旋转ΔR、相对速度变化Δv、相对位移Δp以及对应的协方差矩阵。这样优化器看到的不再是几百个RAW数据而是三四个带协方差的相对约束。关键是这个预积分量本身带零偏。IMU的陀螺零偏和加速度计零偏会在运行中缓慢漂移所以预积分量不能一劳永逸。每次优化更新了零偏需要对预积分量做一阶修正。论文里提供了零偏扰动时的雅可比推导这部分数学功底很扎实。我在代码里读到预积分更新时直观感受就是它把“积分”变成“查表微调”。因为预积分量只依赖两帧之间的IMU测量和位姿无关所以不管优化器把位姿怎么改预积分量都不变。唯一需要更新的是零偏影响的修正项。这让优化效率提升非常明显。另外协方差传播也是重点。IMU的噪声模型通过线性传播最终体现在预积分因子的信息矩阵里。信息矩阵越大说明IMU对这个约束越“自信”优化器就会更重视它。实际调参的时候IMU噪声参数如果设置得过于乐观系统会过分相信IMU而忽略激光匹配反而容易出现奇怪的漂移。2.3 因子图构建节点定义与四种因子因子图是LIO-mapping的后端组织方式。先定义节点滑动窗口内每一个关键帧的位姿算一个节点每个关键帧还附带速度、陀螺零偏、加速度零偏这些状态量。窗口大小一般是固定的新帧进来最旧的帧就滑出去。这样既限制了计算规模又保证优化结果能跟上实时性。再看因子。第一类是IMU预积分因子连接相邻两个关键帧约束两者之间的相对位姿、速度和零偏。第二类是激光里程计因子把当前帧的特征点与局部地图做匹配匹配残差成为约束。第三类是回环因子当描述子匹配成功后用ICP精配准得到当前帧和历史关键帧的相对位姿作为约束加入。第四类是先验因子把第一帧或GPS等外部信息固定住给整个优化问题一个锚点。这四种因子在GTSAM里被统一建模交给ISAM2做增量优化。我理解ISAM2类似于“做了缓存的高斯牛顿法”它利用因子图的稀疏结构只重新线性化受影响的部分所以能在嵌入式平台上维持实时性。我当时有一个困惑为什么LIO-mapping要用滑动窗口加回环而不是全局Bundle Adjustment那样把所有帧都优化后来看懂了滑动窗口控制的是“局部一致性”回环约束解决的是“全局一致性”。两者组合既保证了计算量可控又能在大场景下消除累积漂移。这个设计思路后来几乎原样继承到了LIO-SAM里。3. 把论文跑起来环境、参数与数据3.1 环境搭建依赖版本与代码结构复现LIO-mapping环境是第一关。依赖项主要是这几个ROS我用的是Melodic和Noetic都试过、PCL、Eigen、GTSAM、Ceres。其中最容易出问题的是GTSAM版本。我的建议是严格按照开源仓库说明里的版本装。GTSAM版本差异挺大的不同版本对因子定义、ISAM2接口的兼容性不同版本不对经常编译报错。如果你跟我一样用的是Ubuntu系统建议先用apt装ROS和PCLGTSAM用源码编译安装在系统路径下这样后面的catkin编译能顺利找到它。代码结构上主程序包负责节点管理和回调工具包处理坐标系转换点云配准包封装ICP和特征匹配。第一次看代码时建议从launch文件入手把launch里加载的yaml找到再跟踪主程序里对应的回调函数。不要一上来就钻代码细节先把数据流走通。3.2 参数配置弄懂每个yaml字段LIO-mapping的yaml配置项不算多但每个都直接影响精度。下面这份是我在实际项目中用过的配置字段名在不同版本里可能略有差异以你拉的仓库为准common: lid_topic: /points_raw # 点云话题 imu_topic: /imu/data # IMU话题 lidar_type: 0 # 传感器类型标志 n_scans: 16 # 激光雷达线数 scan_rate: 10.0 # 激光帧率 time_offset: 0.0 # 时间补偿 imu: rate: 200.0 # IMU输出频率 acc_n: 0.01 # 加速度计噪声密度 gyr_n: 0.001 # 陀螺仪噪声密度 acc_w: 0.0001 # 加速度计零偏随机游走 gyr_w: 0.0001 # 陀螺仪零偏随机游走 feature: edge_num: 15 # 每帧边缘特征数量档位 planar_num: 30 # 每帧平面特征数量档位几个容易踩坑的点IMU频率必须和传感器实际输出一致。如果IMU实际只有100Hz配置里写成200Hz预积分的协方差会被过度压缩优化器会把IMU约束当“铁律”反而把激光匹配好的位姿拉歪。反过来实际200Hz写成100Hz约束太软退化时IMU兜底能力就弱了。噪声参数不是越大越好。加速度计/陀螺仪噪声密度可以先按IMU数据手册的Allan方差值填如果找不到用上面的量级作为初始值再在公开数据上微调。判断标准很简单回放数据时看地图是否分层、轨迹是否平滑。特征数量参数需要明白它的含义。它不是精确的“取N个点”而是一个控制稀疏度的档位。太少了匹配不稳定太多了匹配速度下降而且容易引入噪点。16线雷达我一般用上面那组参数64线雷达可以把planar_num加大。3.3 数据准备让第一帧顺利跑起来复现用的数据我建议先找公开的自动驾驶数据集训练集很多是“激光雷达IMU”组合采集的转换成ROS bag格式就能直接播。一定要先跑通公开数据再动自己的设备能少走很多弯路。使用公开数据可以这样跑# 启动LIO-mapping主节点 roslaunch lio_mapping lio_mapping.launch # 回放数据 rosbag play your_data.bag # 打开可视化 rosrun rviz rviz -d lio_mapping.rviz第一次跑通看到的应该是随着bag播放地图点云逐渐增长轨迹平滑延伸小车回到起点附近时地图能和之前的点云对得上。如果这一步正常恭喜你系统链路已经通了。我自己第一次跑的时候犯了个低级错误忘了检查点云和IMU话题是否被bag正常发布结果主节点一直在等待数据Rviz里空空如也。排查方法是直接用rostopic echo看话题频率先确认数据流再怀疑算法问题。这条经验后来帮我节省了大量排查时间。4. 复现中踩过的坑和排查思路4.1 时间戳不同步导致的地图分层这是我被坑得最惨的一次。现象是轨迹整体看起来还行但同一面墙在点云地图里变成了两层像“重影”。仔细检查发现IMU时间戳和激光时间戳有将近几十毫秒的偏差。为什么会有重影因为激光点去畸变靠的是IMU提供的帧间运动如果IMU数据比激光晚了几十毫秒去畸变用的运动补偿就错了每帧点云本身的内部一致性被破坏叠到一起自然重影。排查方法很直接用rosbag info对比两个话题的时间戳范围再在代码里打印首帧时间差。如果偏差是固定值在配置里设置time_offset手动补偿。如果是动态变化的问题出在采集环节建议重新采集或者做软件同步。时间同步问题在IMU和激光雷达硬件来自不同厂家时特别常见。别指望两个传感器时间戳天然对齐买设备之前优先问清楚有没有硬件同步引脚。4.2 外参误差的连锁放大IMU到激光雷达的外参也就是两个传感器坐标系之间的旋转和平移是系统误差的主要来源之一。如果外参给得不准最典型的表现是直线运动时地图正常一旦有旋转地图点云就开始“画圈”轨迹越走越歪。外参不准为什么这么致命因为点云去畸变要把IMU的运动信息转换到激光坐标系下。外参错一点去畸变就错一点。这个误差在每一帧里都会重复引入随运行时间累积放大而且不会像零偏那样在优化里被修正。我的处理流程是先在静止状态下采集数据用手动方式尽可能量准外参再用标定工具做优化获得精细结果最后放到LIO-mapping里用小范围场景跑一遍观察地图是否干净。每一步都能排查出上一阶段的问题。4.3 退化场景下的逃生思路既然叫紧耦合IMU的兜底能力在退化场景会体现得很充分。所谓退化场景就是激光特征极少或者几何结构不明确的地方典型的有长走廊、大停车场、隧道。在这些场景里纯激光方案的激光里程计因子会变得非常“软”因为角点和平面点太少匹配残差会在多个方向上都接近零约束不住位姿。LIO-mapping因为还有IMU预积分因子至少能让位姿不瞬间崩掉短时间内还能维持相对合理的状态。但如果退化持续时间太长IMU零偏估计也会慢慢出问题最终还是会漂。我的经验是不要指望单靠算法解决长时退化。配合回环检测让系统在离开退化环境后尽快纠正历史轨迹才是更务实的方案。如果在项目中遇到频繁的退化场景优先考虑引入其他传感器约束比如轮速计或者UWB和LIO-mapping做融合。4.4 依赖冲突与编译运行问题老版本代码在新系统上编译最常见就是GTSAM版本冲突。我自己遇到过编译通过但运行时断言失败查了很久发现是系统里同时存在两个GTSAM版本链接库时选错了版本。建议复现时用容器或者单独的工作空间把依赖版本锁死。另一个容易忽略的问题是PCL版本与代码接口不匹配尤其是点云类型定义在PCL 1.8和1.10之间有些小变化。如果你在编译时报错涉及PointCloud相关函数优先检查是不是PCL版本差异导致。运行时报错“Assertion failed”不一定是你代码逻辑错了先想想是不是第三方库版本不一致。把环境复现到和作者一致比调代码更高效。5. 这篇论文和后续方案的取舍5.1 学习路径建议以我个人的体会LIO-mapping不适合作为第一个SLAM项目来入门。建议的学习路径是先用LOAM把点云配准和特征提取基础打牢再接触IMU预积分的概念最后再读LIO-mapping的因子图和增量优化部分。这样每一步的知识都能对上号。如果你工作里用的是后来的LIO-SAM、FAST-LIO这类方案我仍然建议回头读一遍这篇论文。很多后来方案的“改进点”其实是在LIO-mapping框架上做了工程化取舍。比如LIO-SAM把滑动窗口改成了关键帧局部地图换来更高的计算效率但核心的紧耦合思路一脉相承。理解了源头再看变体会清晰得多。5.2 选型时要想清楚的问题复现和落地是两回事。LIO-mapping在论文里展示了很好的精度和全局一致性但工程落地时要想清楚几个问题。计算资源够不够。ISAM2和描述子匹配都比较吃计算在低算力平台上可能跑不满实时。这种情况下LIO-SAM那种轻量化的局部地图方式可能更合适。是否需要全局回环。如果你只在室内小场景短时间运行可能不需要完整的描述子回环简单的里程计就够。如果场景较大、运行时间长回环约束几乎必不可少。数据质量是否有保障。IMU预积分对IMU频率和时间同步要求较高如果你手上的IMU很老或者频率偏低紧耦合带来的提升可能不明显反而增加了调参难度。从个人实际经验来说我倾向于在项目早期用LIO-mapping跑通整个“里程计回环”逻辑验证传感器组合可行性再根据产品需求决定是否换成更轻量的方案。这样既能利用论文方法的高精度验证硬件又能避免在最终产品上背上过重的计算负担。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑