1. 为什么MID360配FAST_LIO_ROS2值得单独写一篇配置复盘
MID360这台雷达在固态激光雷达圈子里算是个“甜点级”产品:40万点每秒的采样率、70米左右的量程、非重复扫描的花瓣式光斑,加上相对亲民的价格,让它成了不少个人开发者和实验室做SLAM建图的首选。但真正把它和FAST_LIO_ROS2这套组合跑起来的人都知道,从“能出点云”到“能建出干净可用的地图”,中间隔着一堆默认参数和隐藏配置。我前后用MID360配FAST_LIO_ROS2做过室内办公区、地下车库、矿洞通道三类场景的建图,踩过的坑基本都集中在几个固定位置:外参标定、时间同步、点云预处理、IMU耦合、地图保存策略。这五个点如果没配对,轻则地图飘、重影,重则直接跑飞、轨迹断裂。
这篇内容就是把这五个关键配置拆开讲清楚,每个配置都说明“为什么这么设”“不设会怎样”“具体怎么改”。适合已经装好ROS2和Livox SDK、能跑通基础demo但建图效果不理想的开发者,也适合刚拿到MID360准备做SLAM建图的新手。我不会从头讲怎么装ROS2或者编译FAST_LIO,那些教程网上已经很多,我重点讲的是那些文档里一笔带过、但实际决定成败的配置细节。
2. 整体方案设计与配置思路拆解
2.1 为什么选FAST_LIO_ROS2而不是LIO-SAM或Cartographer
MID360是非重复扫描的固态雷达,它的点云分布和传统机械式雷达完全不同。机械式雷达每一帧的扫描线是固定的,而MID360的光斑在视场内呈花瓣状游走,单帧点云稀疏但多帧累积后覆盖均匀。这个特性决定了它更适合紧耦合的LIO方案,而不是依赖scan-to-map匹配的Cartographer。
FAST_LIO的核心是迭代扩展卡尔曼滤波,把IMU的预测和激光雷达的观测做紧耦合。它对点云的要求是“每帧点云带时间戳且能对应到IMU时间轴”,这恰好是MID360能提供的。相比之下,LIO-SAM依赖GPS和回环检测,在室内或矿洞场景下GPS信号不可用,回环检测又需要额外的特征匹配开销。Cartographer虽然也能用,但它的2D建图模式对3D雷达支持有限,3D模式下配置复杂度高,调参周期长。
我实测下来,MID360配FAST_LIO_ROS2在室内场景下单圈建图的轨迹误差能控制在厘米级,地下车库长走廊场景下也没有明显漂移。前提是下面这五个配置都配对。
2.2 配置的整体逻辑:从数据源头到地图输出
整个数据链路是这样的:MID360通过Livox ROS2驱动发布点云和IMU数据,FAST_LIO订阅这两个话题,在内部做时间对齐和外参变换,然后输出里程计和点云地图。配置的关键节点分布在四个位置:Livox驱动的launch文件、FAST_LIO的config yaml文件、外参标定文件、以及地图保存的调用方式。
很多人只改了FAST_LIO的config,忽略了Livox驱动那边的配置,结果时间戳对不上,建图直接飘。也有人外参用默认值,雷达和IMU的相对位置没标定,导致点云和IMU观测打架。这五个配置之所以关键,是因为它们分别卡在数据链路的四个节点上,任何一个出问题都会传导到最终地图。
2.3 配置前的环境确认清单
在动手改配置之前,先确认几件事。ROS2版本建议用Humble或Foxy,这两个版本的Livox ROS2驱动和FAST_LIO_ROS2兼容性最好。Livox SDK2要装好,MID360的固件版本建议在最新稳定版,老固件有时间戳跳变的问题。IMU方面,MID360内置的IMU是六轴,没有磁力计,所以FAST_LIO的config里要关掉磁力计相关的融合选项。
确认命令很简单,跑一下ros2 topic list,能看到/livox/lidar和/livox/imu两个话题就说明驱动正常。再用ros2 topic hz /livox/lidar看一下频率,正常应该在10Hz左右。如果频率不对,先解决驱动问题,别急着改FAST_LIO。
3. 五个关键配置的逐项拆解与实操
3.1 外参标定:雷达和IMU的相对位置不能靠猜
MID360出厂时雷达和内置IMU的相对位置是固定的,但这个固定值并没有直接写在驱动里。FAST_LIO需要知道IMU到雷达的平移和旋转,才能把IMU的预测和雷达的观测对齐。如果外参错了,最直接的表现是建图时点云出现“双层”或“拖尾”,走直线时地图会弯。
标定方法有两种。一种是手动测量,用卷尺量雷达中心和IMU中心的距离,旋转部分假设IMU和雷达坐标系对齐。这种方法精度有限,适合对建图精度要求不高的场景。另一种是用标定工具,比如lidar_imu_calib或LI-Init,通过采集一段包含充分旋转和平移的数据来优化外参。
我自己的做法是先用手动测量值作为初值,然后跑一段数据用LI-Init优化。LI-Init的输出会给出一个外参矩阵,把这个矩阵填到FAST_LIO的config里。注意,MID360的IMU和雷达在同一个外壳内,平移量很小,通常在厘米级,但旋转量不能忽略,尤其是俯仰角。
# FAST_LIO config中的外参部分 extrinsic_T: [0.011, 0.023, 0.044] # 平移,单位米 extrinsic_R: [1, 0, 0, 0, 1, 0, 0, 0, 1] # 旋转矩阵,行优先注意:外参的旋转矩阵是行优先还是列优先,不同版本的FAST_LIO可能不一样。改之前先看config文件里的注释,或者用单位矩阵测试一下,如果建图正常说明格式对了。
3.2 时间同步:软同步和硬同步的选择
MID360支持硬件时间同步,可以通过PPS信号和GPRS时间戳做硬同步。但在实际项目中,很多人用的是软同步,也就是依赖ROS2的时间戳。软同步的问题是,Livox驱动发布点云和IMU的时间戳可能有微小偏差,这个偏差在低速运动时不明显,高速运动时会导致点云畸变。
硬同步需要额外的硬件支持,比如把MID360的PPS接口接到一个时间源上。如果项目里没有这个条件,软同步也能用,但要在FAST_LIO的config里把time_sync_en设为false,让FAST_LIO自己处理时间对齐。同时,Livox驱动的launch文件里要把publish_freq设成和雷达实际频率一致,避免驱动内部做插值。
# FAST_LIO config中的时间同步部分 time_sync_en: false time_offset_lidar_to_imu: 0.0 # 如果软同步有固定偏差,可以在这里补偿我实测下来,软同步在室内步行速度下建图效果可以接受,但如果是车载或无人机场景,建议上硬同步。另外,ROS2的use_sim_time参数要设成false,除非你在做仿真。
3.3 点云预处理:降采样和盲区过滤
MID360的点云密度很高,40万点每秒的数据量直接喂给FAST_LIO会占用大量计算资源。降采样是必须的,但降采样的方式有讲究。FAST_LIO内部有point_filter_num参数,表示每N个点取一个。这个值设大了点云太稀疏,建图细节丢失;设小了计算量大。
我的经验是,室内场景point_filter_num设成3到5,室外或大场景设成2到3。另外,MID360有最近测距盲区,大概在0.1米左右,太近的点是噪声,要在Livox驱动或FAST_LIO里过滤掉。FAST_LIO的config里有blind_r参数,设成0.1到0.2米比较合适。
# FAST_LIO config中的点云预处理 point_filter_num: 3 blind_r: 0.15 max_iteration: 4 # 迭代次数,室内3-4,室外4-5提示:降采样之后如果发现地图边缘有“毛刺”,可能是盲区过滤没做好,或者雷达表面有遮挡物。检查雷达安装位置,确保视场没有被支架或线缆挡住。
3.4 IMU耦合:内置IMU够用但要调参
MID360内置的IMU是六轴,没有磁力计,所以FAST_LIO的config里imu_gravity_align要设成true,让算法自己估计重力方向。IMU的噪声参数也很关键,acc_n、gyr_n、acc_w、gyr_w这四个值决定了滤波器对IMU数据的信任程度。MID360的IMU噪声参数在数据手册里有,但实际使用中可能需要微调。
如果建图时发现轨迹在静止状态下缓慢漂移,说明gyr_w设小了,滤波器过度信任陀螺仪的零偏。如果运动时轨迹抖动厉害,说明acc_n或gyr_n设大了,滤波器对IMU的观测不够信任。我一般先用数据手册的值,然后根据建图效果微调,每次只改一个参数,改完跑同一段数据对比。
# FAST_LIO config中的IMU参数 imu_gravity_align: true acc_n: 0.01 gyr_n: 0.001 acc_w: 0.0001 gyr_w: 0.00001另外,MID360的IMU频率是200Hz,FAST_LIO的imu_freq要设成200,和实际频率一致。如果设错了,滤波器的时间预测会出问题。
3.5 地图保存:PCD保存和后续使用
FAST_LIO_ROS2默认不保存地图,需要在launch文件里调用pcl_ros的pointcloud_to_pcd节点,或者用FAST_LIO自带的地图保存服务。我一般用后者,在FAST_LIO的config里把pcd_save_en设成true,然后跑完建图后调用/map_save服务。
保存的PCD文件可以用CloudCompare或PCL查看,也可以导入到其他工具做后续处理。注意,保存的PCD是累积点云,不是单帧,文件可能很大。如果要做导航或路径规划,还需要把PCD转成栅格地图或八叉树地图。
# 保存地图的服务调用 ros2 service call /map_save std_srvs/srv/Trigger注意:保存地图前先确认建图已经结束,雷达停止运动。如果在运动过程中保存,点云可能包含未对齐的帧,地图会有重影。
4. 实操过程与核心环节实现
4.1 从零跑通MID360加FAST_LIO_ROS2的完整流程
假设你已经装好了ROS2 Humble和Livox SDK2,下面是完整的操作流程。先创建工作空间,把Livox ROS2驱动和FAST_LIO_ROS2的源码放进去编译。编译时注意,FAST_LIO_ROS2依赖Eigen、PCL和Sophus,这些用apt装就行。
mkdir -p ~/ws_lio/src cd ~/ws_lio/src git clone https://github.com/Livox-SDK/livox_ros_driver2.git git clone https://github.com/hku-mars/FAST_LIO_ROS2.git cd .. colcon build --symlink-install source install/setup.bash编译完成后,先跑Livox驱动,确认点云和IMU话题正常。然后改FAST_LIO的config,把上面五个配置逐项填好。启动FAST_LIO的launch文件,用RViz2看建图效果。如果一切正常,你应该能看到点云地图随着雷达移动逐渐累积。
4.2 外参标定的实操记录
我拿到的第一台MID360,外参用的是默认值,建图时发现走直线地图会弯。后来用LI-Init重新标定,发现默认的旋转矩阵在俯仰角上有大约2度的偏差。标定过程是这样的:先录一段包含充分旋转的数据,用ros2 bag record录/livox/lidar和/livox/imu,然后跑LI-Init的launch文件,它会输出优化后的外参。
标定完成后,把外参填回FAST_LIO的config,重新跑同一段数据,地图的弯曲明显改善。这里的关键是标定数据要包含足够的旋转,尤其是绕三个轴的旋转,否则优化会不收敛。
4.3 时间同步的实测对比
我做过一组对比实验:同一段数据,一次用软同步,一次用硬同步。软同步下,快速转弯时点云有轻微拖尾,地图边缘不够锐利。硬同步下,拖尾消失,地图边缘清晰。硬同步的实现是把MID360的PPS接到一个GPS授时模块上,然后Livox驱动里配置timestamp_type为pps。
如果没有硬同步条件,软同步下可以通过调整time_offset_lidar_to_imu来补偿固定偏差。这个值需要实验确定,方法是跑一段静止数据,看IMU和雷达的时间戳差值,取平均值。
4.4 点云预处理参数的调优过程
点云预处理的参数调优是个反复的过程。我一般先设一个保守值,比如point_filter_num设成5,blind_r设成0.2,跑一段数据看建图效果。如果地图细节丢失,把point_filter_num降到3;如果地图有噪声点,把blind_r调大。
max_iteration的调整也类似,室内场景3次迭代就够,室外大场景可能需要5次。迭代次数越多,计算量越大,但建图精度不一定线性提升。我实测下来,4次迭代是个平衡点。
4.5 地图保存与后续处理
建图完成后,调用/map_save服务保存PCD。保存的PCD可以用CloudCompare打开,做裁剪、滤波、降采样。如果要做导航,可以用octomap_server把PCD转成八叉树地图,或者用nav2_map_server转成栅格地图。
我一般会把PCD先做一次体素降采样,体素大小设成0.05米,这样文件大小能减小一半以上,同时保留足够的几何细节。降采样后的PCD再转成栅格地图,用于后续的路径规划。
5. 常见问题与排查技巧实录
5.1 建图飘、重影、轨迹断裂的排查顺序
建图出问题,排查顺序很重要。先看外参,外参错了什么参数都救不回来。再看时间同步,时间戳对不上会导致点云畸变。然后看点云预处理,降采样太狠或盲区过滤不对会引入噪声。最后看IMU参数,IMU噪声参数不对会导致滤波器发散。
我整理了一个排查表,按优先级排列:
| 问题现象 | 可能原因 | 排查方法 | 解决方式 |
|---|---|---|---|
| 地图弯曲 | 外参旋转错误 | 用LI-Init重新标定 | 更新extrinsic_R |
| 点云拖尾 | 时间同步偏差 | 检查时间戳差值 | 硬同步或补偿time_offset |
| 地图有噪声点 | 盲区过滤不足 | 检查blind_r | 调大blind_r |
| 轨迹抖动 | IMU噪声参数不当 | 对比数据手册 | 微调acc_n/gyr_n |
| 轨迹漂移 | 陀螺仪零偏 | 静止数据测试 | 调小gyr_w |
| 地图重影 | 保存时雷达运动 | 确认静止后保存 | 停止运动再保存 |
5.2 独家避坑技巧:那些文档里不会写的事
第一个坑是Livox驱动的publish_freq。这个参数默认是10Hz,但MID360的实际输出频率可能略有不同。如果驱动做了插值,点云的时间戳会失真。我的做法是把publish_freq设成和雷达实际频率一致,关掉插值。
第二个坑是FAST_LIO的scan_line参数。MID360不是传统意义上的多线雷达,它的scan_line应该设成1,而不是像机械式雷达那样设成线数。设错了会导致点云解析错误。
第三个坑是ROS2的QoS设置。Livox驱动默认的QoS是best_effort,而FAST_LIO订阅时可能用的是reliable,导致话题连不上。检查方法是用ros2 topic info /livox/lidar --verbose看QoS配置,确保两边一致。
第四个坑是地图保存的路径。FAST_LIO保存PCD时默认存在当前工作目录,如果工作目录没有写权限,保存会失败但不报错。建议在config里指定绝对路径。
5.3 不同场景下的参数微调建议
室内办公区:point_filter_num设3,blind_r设0.15,max_iteration设3。室内场景特征丰富,不需要太多迭代。
地下车库:point_filter_num设2,blind_r设0.2,max_iteration设4。车库长走廊特征少,需要更多点云和迭代来维持轨迹。
矿洞通道:point_filter_num设2,blind_r设0.3,max_iteration设5。矿洞环境恶劣,点云噪声大,盲区过滤要更激进。
提示:矿洞场景下,MID360的防尘防水等级可能不够,建议加防护罩。防护罩会影响点云,需要重新标定外参。
5.4 性能优化:让建图跑得更流畅
如果建图时RViz2卡顿,可以把RViz2的点云显示降采样,或者关掉不必要的显示项。FAST_LIO的计算量主要在迭代卡尔曼滤波,如果CPU占用太高,可以降低max_iteration或增大point_filter_num。
另外,ROS2的DDS配置也会影响性能。如果点云话题的数据量很大,可以调整DDS的缓冲区大小,避免丢包。我一般用rmw_cyclonedds_cpp作为DDS实现,它的性能比默认的rmw_fastrtps_cpp好一些。
6. 后续扩展与个人经验分享
这套配置跑通之后,后续可以扩展的方向不少。比如把FAST_LIO的输出接到Nav2做自主导航,或者用octomap_server做三维栅格地图用于避障。如果要做多雷达融合,可以把两台MID360的外参标定好,同时喂给FAST_LIO,但要注意时间同步和点云融合的坐标系变换。
我个人在实际操作中的体会是,MID360配FAST_LIO_ROS2这套组合的稳定性,八成取决于配置,两成取决于环境。配置里最容易被忽略的是外参和时间同步,这两个点如果没做好,后面怎么调参都是白费。另外,建图前先跑一段静止数据,看看IMU的零偏和噪声水平,心里有个底,后面调参就有方向。
最后分享一个小技巧:如果建图时发现地图某个区域特别模糊,可以在那个区域多停留一会儿,让雷达多扫几圈。MID360的非重复扫描特性决定了它在静止时也能累积点云,停留时间越长,那个区域的点云越密,地图越清晰。这个技巧在矿洞和车库场景下特别有用。