资讯动态

ROS2下LIO-SAM与MID360建图实战:从数据集到真机全解析

发布时间:2026/9/28 3:51:40 来源:尧图企业网站定制
LIO-SAM在ROS2下建图这事儿说难不难说简单也真不简单。我最近一个项目就是用MID360做室内外场景下的建图一开始想着先用官方walking_dataset把算法链路跑通再切到真机上结果在数据集转换、topic对齐、时间戳同步这些环节上硬生生耗了两周。今天把这条完整路线整理出来——从walking_dataset入手熟悉LIO-SAM的ROS2移植版再到MID360驱动适配、Gazebo仿真验证、真机建图踩坑一条线讲清楚。适合已经在ROS2里写过几个节点、想开始上手激光惯性SLAM建图的朋友。1. 整体设计思路为什么从walking_dataset起步终点是MID3601.1 LIO-SAM在ROS2生态下的现状LIO-SAM是激光惯性紧耦合里程计算法的代表作之一核心思路是把IMU预积分、激光里程计、回环检测和GPS因子统一放到因子图里做优化输出低漂移的位姿轨迹和全局点云地图。官方实现是基于ROS1的GitHub上star量很高但ROS1已经停止维护现在新项目基本都是Ubuntu 22.04加ROS2 humble起步所以直接用ROS2移植版属于刚需。ROS2移植版和ROS1原版在算法核心上区别不大主要差异集中在消息传递、tf树管理、launch机制和参数系统上。ROS2用的rclcpp API、参数声明机制、launch文件变成Python这些都是接触ROS2移植版时最先遇到的问题。不过好消息是只要把topic对应关系理清楚算法本身的参数和配置思路完全可以沿用ROS1时代的经验。1.2 为什么选walking_dataset做第一站walking_dataset是LIO-SAM作者发布的经典数据集用Velodyne VLP-16采集包含激光点云和IMU数据内容是一段手持设备在室内外行走的轨迹。选它有两个原因一是数据是现成的rosbag不需要自己准备硬件下载解压就能跑二是数据集里包含了比较丰富的场景特征有走廊、墙面、拐角能明显看出建图效果的好坏。更重要的是这个数据集在官方仓库里配套了完善的话题配置和参数文件。你在ROS2下移植时只需要对照着把rosbag从ROS1格式转成ROS2格式再把launch里的topic映射调整正确就能得到一个“标准答案”一样的效果。这对于验证移植代码是否正确、算法链路是否通畅非常有价值。1.3 终点为什么是MID360MID360是Livox推出的一款混合固态激光雷达水平视场角360度、垂直约59度采用非重复扫描方式点云覆盖密度比传统机械式雷达均匀得多。它的量程、精度和成本对室内外建图项目来说很均衡而且自带IMU省去了外挂IMU的标定和固定问题。实际用下来在走廊、拐角这种重复纹理比较少的场景里非重复扫描方式反而能扫到更多角落点建出来的地图边缘更干净。不过MID360也有它自己的麻烦默认发布的点云是自定义格式还是标准PointCloud2、内置IMU的时间戳机制、初始外参的标定这几个点如果没处理好LIO-SAM不但建不出好图还可能出现轨迹漂移甚至发散。后面我会把每一个坑挨个展开。2. 环境准备ROS2 humble、gtsam与lio-sam-ros2编译2.1 ROS2 humble环境与基础依赖建议直接用Ubuntu 22.04加ROS2 humble。安装方式通常两种一种是自己配apt源按官方文档装另一种是用社区的一键安装脚本可以省很多事。不管用哪种装完记得验证一下环境ros2 topic list能正常输出、rviz2能打开基础环境基本就没问题了。LIO-SAM的ROS2移植版依赖几个ROS2核心包包括pcl_ros、pcl_conversions、tf2_ros、robot_state_publisher、nav_msgs、sensor_msgs、geometry_msgs和visualization_msgs。这些直接用apt把ros-humble对应包装齐就行不需要自己从源码编省时间也省心。2.2 编译gtsam最容易卡住的依赖LIO-SAM的核心因子图优化依赖gtsam这是一个专门做平滑和建图的C库。ROS2移植版通常要求gtsam 4.x版本部分系统源里自带的版本可能不满足要求或者干脆没有这个包所以更稳妥的做法是源码编译。编译gtsam有几个注意点cmake版本不要太老安装Boost和TBB开发库编译时建议设置-DGTSAM_BUILD_TESTSOFF -DGTSAM_BUILD_UNSTABLEOFF减少编译时间。我自己的机器上全核编译大概花了十几分钟中间因为缺少libtbb-dev报过一次错装上后重编就通了。这步看着简单但环境不一致时最容易卡住。2.3 编译lio-sam-ros2常见坑点从GitHub上拉取ROS2移植版后放到你的ros2工作空间src目录下用colcon build编译。编译前确保工作空间环境已source并且上面的ROS2依赖都已经安装。我遇到的第一个坑是Eigen和PCL头文件路径冲突。Ubuntu 22.04自带的PCL版本较新跟LIO-SAM源码里某些旧的类型转换写法不一致编译时会报no matching function for call。解决办法一般是升级源码里的转换写法比如把pcl::fromPCLPointCloud2相关调用改成兼容新接口的形式或者干脆用社区已经适配好的较新fork版本。如果不想折腾源码优先选择活跃维护的fork能少踩很多编译层面的坑。编译通过后先别急着跑算法花十分钟看一下工程里的params.yaml和launch文件搞清楚默认的topic名和后处理参数这是接下来调数据的基础。3. walking_dataset实战从rosbag到第一张完整地图3.1 数据集获取与rosbag格式转换walking_dataset在LIO-SAM官方仓库的README里可以找到下载入口下载后是一个ros1格式的bag文件。在ROS2里想直接播放它第一步要做的就是格式转换。ros2本身没有一键转换工具社区常用的是rosbags这个Python库。安装后用命令行即可转换rosbags-convert --src walking_dataset.bag --dst output_dir。转换过程会自动处理消息类型映射把ROS1的topic转成ROS2格式。转换完用ros2 bag info查看convert后的目录确认话题列表和时间戳信息都正常。话题类型上有个细节VLP-16在ROS1下可能发布的是velodyne_msgs/VelodyneScan原始数据包但LIO-SAM需要的是解析后的点云话题sensor_msgs/PointCloud2。walking_dataset这个数据集本身已经发布了PointCloud2类型的点云话题所以转换后直接能用。如果你以后自己录制VLP-16数据需要先用velodyne驱动把原始包解析成点云再喂给LIO-SAM这一步不能省。3.2 修改params.yaml把topic对齐LIO-SAM的ROS2移植版参数文件里最核心的几项是pointCloudTopic: points_raw imuTopic: imu/data odomTopic: odometry/imu gpsTopic: gps/fix不同fork版本命名可能略有差异但核心概念一致。跑walking_dataset时先执行ros2 bag info看看bag里实际的topic名。通常walking_dataset发布的是/points_raw和/imu/data如果实际名称有出入要把params.yaml里的topic配置改成bag里的真实名称。这里有个容易忽略的点topic名别带前导斜杠。LIO-SAM内部拼接topic时如果处理不当带不带斜杠会影响匹配结果。我遇到过参数里写/points_raw导致订阅失败的情况改成points_raw后一切正常。这类问题排查起来很隐蔽建议一开始就养成不带前导斜杠的习惯。3.3 启动、播放、验证建图效果确认参数无误后启动方式分两步。先在一个终端启动LIO-SAMros2 launch lio_sam run.launch.py再开另一个终端播放bagros2 bag play walking_dataset_converted建议先以0.5倍速播放一次因为手持设备运动速度较快第一次跑电脑CPU负载可能较高慢速播放能让算法跟上数据节奏。打开rviz2后手动添加话题PointCloud2选择map或者cloud_registered、Odometry选择odometry/imu路径、Path选择path。你会看到地图点云和轨迹实时累积。判断建图成功有几个标志地图边缘清晰、没有明显的双层重影位姿轨迹连续平滑回环闭合时地图没有大幅跳变。如果地图漂移发散大概率是IMU数据没对齐或参数配置问题这时先暂停回头检查topic频率和消息内容别急着改算法参数。4. 从VLP-16迁移到MID360驱动、时间同步与外参调优4.1 装好livox_ros_driver2理解MID360点云输出MID360要用Livox官方驱动livox_ros_driver2。这个驱动支持ROS2 humble在GitHub上直接拉源码编译即可依赖项主要是Livox SDK。编译完成后用launch文件启动但启动前必须先改配置文件里的雷达IP地址。MID360出厂默认IP一般是192.168.1.5电脑网口需要设置在同一网段比如192.168.1.50。修改好配置文件后启动驱动用ros2 topic echo /livox/lidar --once检查是否有点云数据输出。这里有一个重点livox_ros_driver2默认发布的是Livox自定义点云类型不是标准PointCloud2。LIO-SAM多数移植版本只认标准sensor_msgs/PointCloud2所以要么在驱动配置里把pcl_data_type设置成同时发布标准点云要么自己写一个转换节点把自定义类型转成PointCloud2。转换时注意保留intensity和ring字段LIO-SAM去畸变依赖这些字段。4.2 时间同步MID360建图最隐蔽的坑MID360内置IMU数据默认由驱动发布在/livox/imu但如果您做过时间戳检查就会发现点云中每个点的时间戳和IMU消息时间戳的基准并不完全一致。LIO-SAM在做去畸变时需要把每一帧点云里每个点的时间偏移和IMU数据做关联如果时间轴对不上点云会整体扭曲地图自然就飘了。解决方法是开启驱动里的时间同步功能。在livox_ros_driver2的config文件里把时间同步相关的开关设为true让点云和IMU统一到近似绝对时间戳。开启后建议用ros2 topic hz /livox/imu和ros2 topic echo /livox/lidar | head再核对一次时间戳是否单调递增且接近当前时间。实测下来如果timeSync没开LIO-SAM跑MID360十分钟后轨迹就开始漂移地图呈螺旋状发散。开启后同样的数据地图会立刻稳定下来。这个坑不亲自踩一遍真的很难发现。4.3 外参设置与参数调优LIO-SAM的params.yaml里有外参矩阵包括extrinsicRot、extrinsicTrans和extrinsicRPY。如果你使用的是MID360内置IMUIMU和激光雷达的物理外参通常比较小初值可以设为单位阵和零平移。但如果你把IMU安装在别处这里的值就必须改成实际测量或标定结果。我个人强烈建议在跑LIO-SAM之前先做一次IMU与激光雷达的外参标定。不开回环检测的时候外参误差会直接表现为建图倾斜和轨迹弯曲。标定可以用常见的lidar-imu标定工具也可以先在平坦场景下通过手动测量粗标定后续用建图结果微调。另外scanPeriod这个参数也很关键。激光雷达通常以10Hz发布点云scanPeriod就是0.1秒。如果你把MID360的发布频率调整为20Hz这里就要改成0.05秒否则去畸变计算的点云扫描周期错误点云会变成“波浪形”地图会非常模糊。检查发布频率最直接的方式是ros2 topic hz /livox/lidar。5. Gazebo仿真验证没有激光雷达也能跑通LIO-SAM5.1 仿真环境搭建URDF、传感器插件与模型真机调试之前用Gazebo做仿真验证是个好习惯。仿真能帮你验证launch文件、参数配置和rviz显示链路是否正确也能在没有硬件的情况下熟悉整个工作流。最直接的办法是构造一个包含激光雷达和IMU传感器的机器人URDF模型。在Gazebo里给模型添加gpu_ray传感器插件可以生成点云数据添加imu插件生成IMU消息。Gazebo的点云和IMU话题可以随意配置让它们和LIO-SAM需要的topic名一致即可。Livox官方也提供了MID360的仿真模型和Gazebo插件仿真输出的点云topic可以直接近似模拟真机的/livox/lidar和/livox/imu。你用gazebo加载机器人模型后手动给机器人一个运动指令比如绕圈LIO-SAM就能实时订阅仿真点云和IMU输出一个理想环境下的地图。5.2 仿真和真机的差距到底在哪里仿真环境里点云无噪声、IMU无漂移、时间戳完全同步、外参绝对精准所以LIO-SAM几乎每次都能跑出漂亮的地图。但这恰恰是“假象”如果你在仿真里一切正常换到真机却纷纷出错不用怀疑算法出了问题问题一定出在数据链路上。仿真最大的价值是帮你排除配置层面的低级错误。比如launch文件语法、params.yaml参数是否被正确加载、rviz2里话题显示是否正常这些问题在仿真阶段暴露和修复的成本最低。但仿真无法帮助你验证真机的时间同步、点云噪声、IMU零偏等物理层面的问题所以不要因为仿真跑通了就掉以轻心真机调试该做的检查一步都不能省。6. 常见问题与排查技巧实录6.1 建图漂移、发散的排查顺序建图漂移是玩LIO-SAM遇到最多的问题也是最让人头疼的。我的排查顺序是这样的先看数据再谈算法。具体来说查看点云消息的frame_id是否和tf树一致用ros2 topic echo抽查点云和IMU的头部时间戳确认没有跳变检查IMU频率是否稳定在设定值附近检查点云发布频率和scanPeriod是否匹配最后才考虑外参是否要重新标定6.2 常见问题速查表下面这张表是我实际调试中积累的典型问题和对应解法供参考。问题现象可能原因检查与解决方法地图呈螺旋状发散IMU时间戳与点云时间不同步开启MID360驱动的timeSync功能重新核对两路消息时间戳地图轨迹正常但地图模糊scanPeriod与点云发布频率不匹配用ros2 topic hz查看真实频率修正params.yaml节点启动后立即崩溃params.yaml里参数类型或topic名称错误检查参数类型确认点云topic有数据后再启动算法rviz2里看不到点云和轨迹话题名或frame_id不对用ros2 topic list对比期望话题查看消息frame_idmap建出来有轻微倾斜IMU与雷达外参不准确重新标定外参或根据建图结果手动微调外参矩阵回环闭合时地图跳变回环检测参数过于激进或地图噪声大适当降低回环阈值检查点云去畸变是否正常livox点云为空雷达IP配置错误或网口未连接确认lidar_ip配置正确电脑IP与雷达同网段并能ping通6.3 独家避坑技巧有一个技巧是很多教程不会提的在跑LIO-SAM之前先用ROS2自带的工具把数据录成压缩bag然后从bag回放调试算法。这样做的最大好处是怀疑参数不对时可以反复用同一份数据测试而不用反复搬动设备重新采集。我后面所有MID360的参数调试都是基于录制的bag完成的效率提升非常明显。另一个技巧是留意IMU数据要不要做低通滤波或减零偏处理。MID360内置IMU在静止状态下也会有一定的零偏直接喂给LIO-SAM虽然能跑但在长时间低速运动时会造成累积漂移。如果你发现静止放置雷达时地图还在缓慢移动可以先做一次IMU零偏估计把零偏减掉再进算法。还有一个经验是关于tf树的。LIO-SAM会发布map到odom、odom到base_link的变换但MID360驱动通常只发布livox_frame相关的变换。如果tf树不完整rviz2里所有话题都会飘在原点。建议自己写一个静态tf发布节点把base_link到livox_frame的固定变换发出来问题立刻解决。7. 从数据集到实机的路线复盘与扩展思路整套流程走下来我最深的体会是LIO-SAM这类开源SLAM算法代码层面的门槛其实不高真正的门槛在于数据链路。walking_dataset能顺利建图不代表换一个雷达就一定能顺利因为传感器的时间戳机制、点云类型、外参都不一样。所以我才反复强调先把数据链路检查清楚再谈调参和算法优化。就扩展思路而言这套环境接下来可以做的方向很多。比如在LIO-SAM的基础上接入自定义地图保存逻辑把建好的点云地图保存成PCD或八叉树地图OctoMap为后续导航避障做准备。也可以把GPS因子启用在有GPS信号的室外场景进一步抑制漂移。ROS2的DDS机制天然支持多机通信还可以把建图节点跑在机器人上把地图通过topic实时传回地面站显示这些都是工程上很实用的能力。如果你也正在ROS2下折腾LIO-SAM或者MID360希望这篇文章能帮你少走几天弯路。数据链路排查、topic对齐、时间戳同步、外参初值这四个关键点搞定你离一张干净的地图就不远了。

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

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

免费获取报价 →
↑