LIO-SAM在KITTI上的实战:数据处理、参数调优与定位感知融合

发布时间:2026/9/2 1:21:10
LIO-SAM在KITTI上的实战:数据处理、参数调优与定位感知融合 简介这份资源面向从事同步定位与建图研究的开发者围绕激光雷达惯性里程计与KITTI数据集的结合展开实践。LIO-SAM系统融合激光雷达与惯性测量单元通过滑窗优化完成高精度定位和环境建图适合自动驾驶、机器人导航、三维场景理解等方向的学习与二次开发。压缩包共四十二个文件包体约六十四兆内容包含系统核心源程序、机器人操作系统启动文件、参数配置、可视化图像、文档说明等可支撑从环境部署、算法调试到结果评估的完整流程。资源配套了针对KITTI数据集的适配细节与运行效果演示已有四千二百余人浏览学习。借助该资源可复现LIO-SAM在真实道路数据上的建图效果理解因子图优化、点云特征提取、惯性预积分等关键模块并基于脚本和配置模板开展参数调优与功能扩展是实用性较强的工程参考。 LIO-SAM是目前把激光雷达和惯性测量单元融合得最稳妥的开源方案之一代码仓库就是TixiaoShan/LIO-SAM。很多刚接触的小伙伴会拿KITTI数据集来试跑但往往卡在数据准备、话题映射和参数调优这几步。这篇文章直接记录我在KITTI上跑通LIO-SAM的完整过程以及踩过的坑希望能帮你省掉几个通宵的时间。先说说这个项目到底是干嘛的。LIO-SAM全称Tightly-coupled Lidar Inertial Odometry via Smoothing and Mapping核心思路是把激光雷达里程计和IMU预积分放进同一个因子图做紧耦合优化。它和LOAM系列最大的区别在于LOAM靠滑动窗口优化LIO-SAM直接用全局因子图关键帧之间的约束由IMU预积分、激光里程计、GPS、回环检测四类因子串起来。这种设计的直接收益是IMU能提供高频运动先验激光特征匹配不需要每次从零求解GPS和回环因子又能把长时间漂移拉回来。KITTI数据集本身就是自动驾驶绕不开的标准基准采集车带着64线Velodyne激光雷达、OXTS RT3003组合导航系统和双目相机在市区跑了很多圈。对LIO-SAM来说KITTI的价值在于它同时提供了同步好的点云、IMU和GPS数据正好满足系统对多传感器输入的要求。我们在KITTI上跑LIO-SAM不一定要追求复现论文里的绝对轨迹精度更重要的是把整套数据流和参数逻辑摸透后面换到自己的设备时才能快速上手。这篇文章适合三类人一是刚把ROS环境配好、想用真实数据集跑通LIO-SAM的初学者二是已经用自己的设备跑LIO-SAM但被参数调得头疼的开发者三是想在KITTI上把定位和3D检测打通同时参考mmdetection3d相关配置的同学。1. 项目背景与整体思路1.1 LIO-SAM的核心模块划分LIO-SAM的代码结构其实很清晰主要分为特征提取、IMU预积分、因子图优化和回环检测几个模块。特征提取部分从原始点云中提取角点和平面点这些特征会与局部地图做配准得到激光里程计因子。IMU预积分在两次关键帧之间推算相对运动既给特征匹配提供初始值也作为独立因子进入图优化。回环检测则通过ikd-tree搜索历史关键帧找到闭环约束。理解了模块划分之后再去调参数就有的放矢了。比如地图出现漂移可能是回环没触发轨迹高频抖动大概率是IMU噪声参数设置不合理地图整体倾斜那就是外参标定有问题。我见过不少同学一上来就乱调降采样率结果把特征都滤没了越调越差。1.2 为什么选KITTI做验证KITTI数据有两个容易搞混的版本。Odometry Benchmark的序列00-10虽然带ground truth但只提供点云和图像没有IMU/GPS而LIO-SAM至少要激光雷达和IMU两个输入。Raw Data版本里有完整的OXTS组合导航数据包括IMU、GPS和姿态解算结果所以正确做法是下载Raw Data中与Odometry序列对应的同步数据。对应关系大概是这样的Odometry的sequence 00对应Raw Data里的2011_10_03_drive_0027sequence 01对应2011_10_03_drive_0042以此类推。下载时选择sync版本里面已经按时间戳组织好了velodyne_points、oxts、image_02等子目录省去手动对齐传感器时间戳的麻烦。1.3 从定位到感知的链路思考跑通LIO-SAM之后很多同学会想在同样的KITTI数据上做3D目标检测形成一条“先定位、后感知”的完整链路。这个想法很自然定位模块输出全局一致的参考系检测模块在这个参考系里输出目标框两者配合可以省掉很多坐标变换的麻烦。后面我会专门讲一下mmdetection3d在KITTI上的配置和权重下载正好接上这个需求。2. 环境搭建与数据准备2.1 编译依赖与版本选择LIO-SAM依赖ROS、PCL、Eigen和GTSAM 4.0.2以上版本。我用的Ubuntu 20.04 ROS NoeticGTSAM用源码编译版本4.1.1编译时加了 -DGTSAM_USE_SYSTEM_EIGENON避免和系统Eigen产生冲突。这一步很关键我第一次没加这个宏编译能过但一运行就崩报错指向Eigen对齐相关的问题最后把build目录清掉重新编译才解决。代码本身编译很简单clone下来放进catkin_ws/srccatkin_make或catkin build都行。如果你不想源码编译GTSAM也可以用sudo apt install ros-noetic-gtsam但版本可能偏旧建议还是源码编译。整体编译时间大概五到十分钟取决于机器配置。2.2 KITTI数据下载细节下载KITTI Raw Data时要在官网的Raw Data页面找到对应日期和drive编号。比如sequence 00对应的是2011_10_03_drive_0027点进日期目录后需要下载所有zip包包括sync数据、calib标定文件和oxts数据。很多教程只说“下载raw data”没说清楚具体下载哪些文件结果有人只下了点云没有oxts转换bag时直接报错。我习惯把下载和解压分开做先建一个目录结构清晰的文件夹比如kitti_raw/ 2011_10_03/ calib_imu_to_velo.txt calib_velo_to_cam.txt 2011_10_03_drive_0027_sync/这样做的好处是后面跑多个序列时不会把文件搞混。KITTI的数据文件通常比较大一个sync序列解压后可能好几个GB建议提前确认磁盘空间我遇到过下载到一半磁盘满了的情况。2.3 kitti2bag转换与话题检查拿到原始数据后网上最流行的做法是用kitti2bag这个Python工具转成rosbag。安装简单先clone仓库pip安装依赖然后执行kitti2bag -t 2011_10_03 -r 2011_10_03_drive_0027_sync .这里有个隐藏坑kitti2bag读取的不是当前目录而是以日期为子目录的数据目录结构。如果你把数据平铺在一个目录里它会提示找不到文件。正确做法是先把2011_10_03_drive_0027_sync放到名为2011_10_03的目录下再按上面的命令执行。转换完成后用rosbag info检查bag里的topicrosbag info kitti_2011_10_03_drive_0027_synced.bag典型的输出会包含/kitti/velo/pointcloud/kitti/oxts/imu/kitti/oxts/gps/fix还有相机话题这些就是后续要重映射给LIO-SAM的源话题。3. 核心配置与参数解析3.1 launch文件里的话题重映射LIO-SAM默认订阅三个话题/imu/data、/velodyne_points、/gps/fix。kitti2bag转出来的话题名对不上所以在启动前需要做重映射。我的launch文件里加了这样一段remap from/imu/data to/kitti/oxts/imu/ remap from/velodyne_points to/kitti/velo/pointcloud/ remap from/gps/fix to/kitti/oxts/gps/fix/重映射看起来简单但有个细节LIO-SAM内部很多地方会读IMU消息的orientation字段而kitti2bag从OXTS数据转出的IMU消息linear_acceleration和angular_velocity都有orientation可能是无效四元数。保险的做法是在运行前先rostopic echo看一眼消息内容或者把配置里useImuHeadingInitialization设为false避免启动时用IMU航向做初始化而崩溃。3.2 params.yaml关键参数逐项拆解配置文件config/params.yaml是LIO-SAM最核心的部分每个参数我都建议动手调一遍至少要知道改了之后会发生什么。lidarTypeKITTI用的Velodyne HDL-64是旋转式雷达设成1表示Velodyne。如果你换了其他类型的雷达这里要对应改。cloud_n是每帧点云数量KITTI单帧大约10万个点实际只影响离线关键帧处理对在线建图影响不大。scanPeriod这个参数必须和雷达实际转速一致。KITTI的Velodyne HDL-64是10Hz所以设0.1。如果设错畸变补偿会有问题地图会出现明显的运动模糊。imuAccNoise、imuGyrNoise、imuAccBiasN、imuGyrBiasN这些IMU噪声参数直接进入预积分方程。很多人喜欢照搬论文里的数值但KITTI的OXTS RT3003和高精度MEMS惯性器件差别很大照搬会导致预积分协方差完全不反映真实情况。我实测在KITTI上把这几个噪声系数调大2到3倍轨迹整体更稳原因后面细说。extrinsicRot、extrinsicTrans这是IMU到LIDAR的外参最容易出问题的参数。KITTI的传感器坐标系定义和LIO-SAM默认值不一致如果不改地图角度直接偏。KITTI的标定结果在calib_imu_to_velo.txt里需要读取后自己换算不能依赖默认配置。3.3 外参换算的思路很多同学拿到calib_imu_to_velo.txt之后直接就填进params.yaml结果地图歪得离谱。原因是KITTI文件里给的是从IMU坐标系到Velodyne坐标系的变换而LIO-SAM里的extrinsicRot和extrinsicTrans表示IMU在LIDAR坐标系下的位姿方向正好相反。我处理时把旋转矩阵做了转置平移向量也做了对应变换再填入配置地图才恢复平直。这里有个经验总结如果你发现地图绕某条轴整体旋转多半是外参旋转方向反了如果地图只在某个方向上有偏移可能是平移部分差了几个厘米。小误差在近距离看还行跑到远处累积起来就会导致闭环失败。4. 实操运行与调优记录4.1 启动顺序与rosbag回放我的启动顺序是先roslaunch LIO-SAM的run.launch再单独播放bag。播放bag时建议加上--rate 1.0如果机器性能不足可以用0.8或0.5因为回放速度太快容易丢帧IMU数据一旦丢太多预积分就会发散。命令如下roslaunch lio_sam run.launch rosbag play kitti_2011_10_03_drive_0027_synced.bag --rate 1.0第一次运行可以观察RVIZ里的/lio_sam/mapping/cloud_registered是否稳定增长。如果点云地图逐渐成型但轨迹倾斜这通常是参数没调好的信号不要急着怀疑代码。先把bag暂停回看参数再继续比一路跑到底然后翻车更高效。4.2 地图“扭麻花”的外参排查我第二次跑sequence 00时地图在转弯处出现明显的折叠轨迹像被拧过一样。检查半天最后锁定在外参上。KITTI的calib_imu_to_velo.txt给出的是从IMU到Velodyne的变换而LIO-SAM里要填的是IMU在LIDAR坐标系下的位姿方向需要反过来。我把旋转矩阵做了转置再代入配置地图立刻恢复了平直。这类问题只要遇到过一次以后看到地图变形就能很快定位到外参上。后面我又换了sequence 05发现外参基本不用改因为KITTI的传感器布置在不同采集日期之间保持一致标定结果差异不大。4.3 GPS融合开关与轨迹对比我在sequence 07上做了GPS开关的对比测试。关闭GPS时车辆跑到一半因为长直道缺乏特征轨迹明显漂移回环检测又没触发地图末尾和开头错开了一大截。打开GPS之后因子图里多了全局位置约束长直道的漂移被压住地图闭合效果好很多。但GPS并不是在所有序列上都好用。sequence 02是在公路上跑的OXTS信号经常受遮挡GPS消息协方差很大这种数据加进因子图反而会让轨迹出现锯齿状抖动。我的处理方式是把参数里的gpsCovThreshold调大一些让系统在GPS协方差超过阈值时自动忽略这个约束。默认值2.0我调到5.0实测比手动开关GPS更平滑。注意这个值不是越大越好调太大等于没有GPS约束建议每个序列单独试一下。5. 常见问题与排查技巧实录5.1 时间戳不对齐LIO-SAM对IMU和点云的时间戳非常敏感。ROS bag回放时如果话题时间戳有偏移预积分结果会包含多余运动地图整体发虚。检查方法很简单用rostopic echo分别看IMU和点云的header.stamp确认时间戳增长一致。如果发现IMU比点云晚了几十毫秒可以在bag播放时用--clock选项或者写个小节点做时间补偿。5.2 地图“飘上天”很多同学遇到地图跑着跑着飞起来第一反应是外参错了。其实还有两个常见原因一是IMU加速度计bias初值差太多预积分在毫无约束的情况下快速发散二是点云特征太少比如长直道上路沿和树木距离太远匹配约束不足。前者可以通过调高imuAccBiasN的后验约束来缓解后者只能靠打开GPS或增加回环检测兜底。5.3 CPU占用过高LIO-SAM在点云稠密时非常吃CPUKITTI的64线雷达更容易把算力打满。如果CPU占用接近100%可以考虑在params.yaml里把N_SCAN和Horizon_SCAN调小比如N_SCAN从64降到32。虽然会损失一些特征但实测在KITTI上对轨迹精度影响不大。另一个思路是把bag回放速率降到0.5或者在真实工程中只保留感兴趣区域。症状可能原因处理方式轨迹整体倾斜外参旋转方向反了转置外参旋转矩阵地图闭合错位GPS未开启或回环未触发打开GPS因子检查回环参数高速运动轨迹发散IMU噪声参数过小调大imuAccNoise和imuGyrNoiseCPU占用过高点云密度过大降低N_SCAN或降采样率6. 扩展和mmdetection3d做感知融合6.1 mmdetection3d的KITTI配置与权重跑通LIO-SAM后如果想把3D检测也接上现在最顺手的开源框架是mmdetection3d。官方仓库里已经提供了针对KITTI的配置文件和预训练权重下载链接比如PointPillars的配置在configs/pointpillars/目录下CenterPoint在configs/centerpoint/目录下。下载权重时要注意版本匹配最好用仓库里标注的权重URL下载不要随便去找第三方版本。我第一次图省事用了旧权重结果推理时shape对不上报了一堆错。下载完把.pth文件放到对应目录按照文档里提供的命令跑验证集基本能复现官方报告的mAP。6.2 CenterPoint与PointPillars选型建议CenterPoint和PointPillars虽然都是基于点云的检测方法但思路不太一样。PointPillars把点云划分成柱体再通过2D卷积做检测速度极快KITTI这种稀疏场景下效果稳定CenterPoint用中心点热力图预测目标在稀疏点云上的召回率更好但训练和推理开销更大。如果想快速验证“LIO-SAM地图检测结果”的可视化效果建议先用PointPillars的官方KITTI权重直接推理再把检测框和LIO-SAM轨迹一起画在RVIZ里。6.3 定位与感知协同的实操心得最后分享一点实际感受。LIO-SAM输出的地图坐标系可以作为检测结果的目标坐标系不受车辆自身位姿漂移影响。做离线实验时我通常把LIO-SAM的全局轨迹和mmdetection3d的检测框对齐到同一时间戳再做追踪关联。这条路的好处是只要LIO-SAM的地图质量有保证后续感知模块就不用反复处理传感器外参漂移的问题整体工程效率会高很多。这篇文章记录了我在KITTI上跑通LIO-SAM的全过程重点讲了数据准备、参数调整和几个常见的踩坑点。如果你正在搭车端的定位与感知系统希望这份记录能帮你少走点弯路。之后有空我再把LIO-SAM和mmdetection3d对接的完整工程代码整理出来单独写一篇具体实现。本文还有配套的精品资源点击获取