拿到Livox MID-360之后最容易踩的坑,不是FAST-LIO2算法跑不起来,而是从驱动配置开始,整条链路就没有真正“点通”。网上关于FAST-LIO2建图的教程不少,但大部分停留在“clone下来catkin_make一下就能跑”的理想状态。真到自己手里,网络不通、时间戳错乱、外参不对、地图抽风,哪一个都能把高精度建图变成高精度撞墙。
这篇把我从裸机到跑通MID-360 + FAST-LIO2的完整过程写出来,从网线怎么插、驱动参数怎么填、launch文件怎么改,到第一次手持建图、保存PCD点云,再到那些最容易让人灰心的报错怎么处理,全部按实际走一遍。内容比较长,但每一步都能直接对着做,适合刚拿到MID-360、或者已经在FAST-LIO2里折腾了一段时间但还没跑顺的人参考。
1. 为什么是MID-360 + FAST-LIO2这套组合
先说结论:MID-360是目前把“体积、重量、成本、感知能力”平衡得最好的固态激光雷达之一,FAST-LIO2又是目前对Livox系列雷达支持最友好的开源里程计方案之一。这两者放在一起,几乎就是现成的“机器人感知套件”,从室内小场景到室外中等范围建图,都能很快跑起来。
1.1 非重复扫描:等来的点云密度
MID-360和传统机械雷达最大的区别是扫描方式:它不是360°一圈一圈转,而是通过双棱镜结构生成一种类似李萨如曲线的扫描轨迹。单帧点云看起来稀疏且不规则,但随着时间累积,激光脚点会逐渐填满整个视场。
这个特性对FAST-LIO2这种不提取点特征、直接用原始点云做配准的算法非常友好。传统特征提取算法遇到非重复扫描反而头疼,因为每一帧点的位置都在变,几何特征不稳定;而FAST-LIO2直接把点云当作观测,在ikd-Tree管理的地图里找最近邻配准,天然适配这种“点云分布不规则但覆盖率高”的数据形态。
MID-360的标称探测距离约40米(10%反射率),水平视场角360°、垂直视场角59°(官方标称-7°~52°),最近探测距离能做到0.1米。这个垂直视场比很多机械雷达都大,放在机器人上基本能把近处地面、头顶天花板一次性扫进来,对建图来说非常省事。
1.2 内置IMU:少接一根线,少一个坑
FAST-LIO2是LiDAR-Inertial里程计,IMU是算法里不可或缺的一部分。很多人在其他激光雷达上跑FAST-LIO2,还要外接单独的IMU,然后处理供电、通信、时基同步一大堆问题。MID-360直接把IMU做进了雷达内部,驱动发布两个话题:一个是点云/livox/lidar,一个是IMU数据/livox/imu,FAST-LIO2默认配置接的就是这两个话题。
从年久失修的IMU标定角度看,内置IMU少了很多麻烦。硬件上不用额外接线,软件上不用自己推导外参,哪怕后续要精细标定雷达和IMU之间的位姿关系,也比处理外部IMU简单一个量级。
1.3 这套方案适合解决什么问题
如果你做的是机器人室内导航、园区巡检、增强现实扫描、或者小范围高精度三维重建,MID-360 + FAST-LIO2这套组合基本是开箱即用的标配。
但也要说清楚边界:FAST-LIO2本身没有回环检测,也没有办法和GPS做全局约束,它是一个“里程计”而不是“SLAM全解”。长时间大范围跑下来,依然会累积漂移。如果项目需求是长达几公里的室外地图,这套方案不能单靠FAST-LIO2硬撑,后面一般要接回环检测、RTK融合或者因子图优化。把预期放对位置,后面调参才不会心累。
2. 装驱动之前的硬性准备
很多人在FAST-LIO2编译上折腾半天,结果发现雷达点云根本进不来,回头一看是网线都还没通。MID-360是网口通信雷达,和电脑的要信息交互,网络配置是第一步,也是被忽视最多的一步。
2.1 网络配置:雷达找不到时先查IP
按照官方手册,MID-360出厂默认IP是192.168.1.50,子网掩码255.255.255.0。电脑要访问它,必须把网卡配到同一个网段,比如192.168.1.5。
在Ubuntu里最快的方式是直接用命令临时改,重启后失效,但用来验证硬件够了:
sudo ifconfig eth0 192.168.1.5 netmask 255.255.255.0 up注意把eth0换成你实际的网卡名,可以通过ifconfig或ip addr先查。配完以后用ping验证:
ping 192.168.1.50能ping通再继续,ping不通后面全部白搭。
这里有个实操经验:电脑上如果有多个网卡在活动(Wi-Fi连着、USB网卡也插着),路由表容易乱,到达雷达的报文可能被错误地路由到其他网卡,然后丢包。我的习惯是拔掉其他网线,只保留和雷达直连的那根。等后面一切跑通了,再考虑多网卡场景下的路由配置。
2.2 编译环境:Ubuntu + ROS版本选择
FAST-LIO2官方支持ROS1和ROS2,但绝大多数人用的是ROS1,我这边也以ROS1 Noetic为例。推荐环境组合是Ubuntu 20.04 + ROS Noetic。如果你是Ubuntu 18.04 + ROS Melodic,也能编译,但需要手动改一部分CMakeLists的依赖声明,后面编译报错概率更高,新手不建议一上来就挑战。
系统装完后,先把基础工具链装上:
sudo apt update sudo apt install -y build-essential cmake git pkg-config sudo apt install -y libeigen3-dev libgoogle-glog-dev libgflags-dev libyaml-cpp-dev sudo apt install -y ros-noetic-pcl-ros ros-noetic-rvizROS本身安装这里不展开,但提醒一句:.bashrc里的source /opt/ros/noetic/setup.bash别忘了写,很多人第一次编译失败是因为ROS环境变量没生效。
2.3 雷达自检:先用官方工具确认硬件无问题
在没开始写代码之前,我强烈建议先用Livox官方出的小工具验证雷达硬件是否正常。官方有Windows和Linux版本的Livox Viewer,解压后双击运行,设置好本机IP就能看到雷达的SN号、固件版本、连接状态和实时点云。
这一步能帮你排除很多“算法问题”:如果官方Viewer里都看不到点云,那大概率是网线、供电、IP配置的问题,不用急着去改FAST-LIO2的代码。我第一次用MID-360时就遇到点云时有时无,折腾半天算法,后来发现是供电不足导致雷达间歇性掉线。用官方工具提前发现,能省下好几个晚上。
3. 编译livox_ros_driver2:让点云和IMU进ROS
驱动这一步是整条链路的“水龙头”,水龙头没接好,后面算法只能对着空气干活。livox_ros_driver2是Livox官方维护的ROS驱动,MID-360必须用它,老的livox_ros_driver早期版本不支持MID-360。
3.1 依赖安装与源码编译
创建并初始化catkin工作空间:
mkdir -p ~/catkin_ws/src cd ~/catkin_ws catkin_init_workspace src拉取驱动源码(驱动是ROS1/ROS2双版本,这里是ROS1,如果拉取慢可以稍后重试,git本身支持断点续传):
cd ~/catkin_ws/src git clone https://github.com/Livox-SDK/livox_ros_driver2.git另外需要安装Livox-SDK2,livox_ros_driver2编译时会依赖它:
git clone https://github.com/Livox-SDK/Livox-SDK2.git cd Livox-SDK2 mkdir build && cd build cmake .. make sudo make install然后回到工作空间编译驱动:
cd ~/catkin_ws catkin_make source devel/setup.bash如果编译过程中提示找不到livox_lidar_sdk相关的头文件,基本都是Livox-SDK2没有正确安装导致的,重新检查一下SDK的cmake和install执行情况。
3.2 launch参数里必须确认的几个字段
livox_ros_driver2包里自带了适配各种型号的launch文件,MID-360对应的launch文件名一般是rviz_MID360.launch或msg_MID360.launch(不同版本名字略有差异)。在启动之前,打开launch文件看一眼这几个参数:
lidar_type:MID-360对应的值通常是6,不同版本驱动注释里会写明每个数字对应什么型号,对着注释确认即可。xfer_format:点云输出格式,一般选0,输出xyz等标准字段。msg_frame:点云坐标系框架,FAST-LIO2不强制用什么,但建议保持默认。
这里最容易踩的坑是不看型号直接照抄网上配置,结果用了一个别的型号的lidar_type,驱动大概率能启动,但点云长度和分布明显不对,或者完全不出点。遇到这种情况,先别怀疑驱动代码,去launch里核对参数。
3.3 Rviz确认点云与IMU
启动驱动前,先确认雷达已上电、网线连接正常:
roslaunch livox_ros_driver2 rviz_MID360.launchRviz打开后,如果驱动正常,能看到当前时刻的点云,并且一个跨度接近360°的视野范围都能被扫到。再用命令行验证一下话题:
rostopic hz /livox/lidar rostopic hz /livox/imu正常情况下,点云话题频率在10Hz左右,IMU话题频率在200Hz左右(具体数值以官方标称为准)。如果IMU频率不稳定、突然掉到几Hz,先检查网线和供电,而不是去改算法。
4. FAST-LIO2的编译与参数配置
驱动打通之后,才是FAST-LIO2的正式登场。FAST-LIO2是香港大学MARS Lab开源的紧耦合LiDAR-Inertial里程计算法,核心是用迭代误差状态卡尔曼滤波融合IMU和LiDAR观测,用ikd-Tree维护地图实现增量更新。整个项目在GitHub上开源,搜索FAST_LIO就能找到。
4.1 依赖与编译报错
把FAST-LIO2源码放进工作空间:
cd ~/catkin_ws/src git clone https://github.com/hku-mars/FAST_LIO.git各个雷达型号的launch文件都在FAST_LIO的launch目录里,其中mapping_mid360.launch已经默认适配MID-360。编译前先确认依赖装全:
cd ~/catkin_ws catkin_make常见编译报错我集中列一下:
fatal error: glog/logging.h: No such file or directory:装了libgoogle-glog-dev即可。fatal error: yaml-cpp/yaml.h: No such file or directory:装了libyaml-cpp-dev即可。fatal error: pcl_conversions/...:装上ros-noetic-pcl-ros和ros-noetic-pcl-conversions。- Eigen版本太老导致编译不过:确保
libeigen3-dev版本在3.3以上。
如果你用的是旧版本的FAST_LIO代码,还可能出现ikd-Tree编译不通过、pcl/point_types.h冲突等问题。我的建议:直接拉到master最新版本,别用网上所谓的“稳定老版本”,因为新版持续修复了Livox系列雷达的兼容性问题,尤其是对MID-360的支持。
4.2 外参与topic映射
FAST-LIO2的launch文件里有两组核心参数:外参extrinsic_R和extrinsic_T,表示雷达坐标系到IMU坐标系的旋转矩阵和平移向量。
重点来了:这个外参是雷达相对于IMU的,不是IMU相对于雷达的。写反了之后地图会以非常诡异的方式飘,但又不完全发散,很迷惑人。
MID-360因为IMU内置,官方默认给的外参非常接近单位阵加零平移,所以很多人直接用默认值也能跑通。但注意:如果雷达是固定装到机器人本体上,而不是手持状态,外参可能因为安装结构、结构件公差而和默认值有偏差。这种情况下,最靠谱的做法是先用完整标定流程算一遍,或者打开FAST-LIO2的外参在线估计功能(见6.2)。
topic映射方面,FAST-LIO2的mid360 launch默认订阅的就是/livox/lidar和/livox/imu,和livox_ros_driver2的默认发布话题完全一致。只要你没在驱动launch里改过话题名,这里基本不用动。
4.3 几个影响建图质量的关键参数
打开mapping_mid360.launch对应的配置文件(一般在config/mid360.yaml),有几个参数直接影响建图效果:
point_filter_num:每隔N个点取1个点参与配准。增大该值会降低计算负载,但点云变稀,小场景细节丢失;减小则更精细,但CPU负载上升。桌面级CPU跑MID-360时,设为4左右比较平衡。max_iteration:迭代卡尔曼滤波的最大迭代次数。建图效果差时适当调大,但注意实时性会下降。extrinsic_est_en:是否开启外参在线估计。建议首次跑通后开启,尤其是安装方式不固定时,能显著减少地图重影。time_offset:IMU和雷达之间的时间戳偏移,这个值对建图稳定性影响很大。默认值不一定适配你的系统,如果发现地图在静止时也缓慢漂移,怀疑时间同步问题,可以微调。
5. 第一次建图实操:从启动到保存PCD
配置完成后,第一次实测流程其实只需要三行命令。但顺序很重要,以及启动后你的动作很重要。
5.1 启动流程与检查清单
终端1,启动驱动:
roslaunch livox_ros_driver2 msg_MID360.launch终端2,启动FAST-LIO2:
roslaunch fast_lio mapping_mid360.launchFAST-LIO2启动时会自动打开一个Rviz界面,里面能看到实时点云地图、当前里程计轨迹。如果启动后一切正常,你会看到点云慢慢“变实”,边缘越来越清晰。
在开始走之前,我建议检查三件事:
rostopic hz /livox/imu是否稳定在200Hz左右,不稳定先修网络和供电。- Rviz里的当前点云是否和真实环境几何形态吻合,而不是一团乱麻。
- 雷达是否在你手里固定好,尽量别让雷达本体跟着手臂大幅度晃动(注意:是移动雷达,不是随意甩动)。
FAST-LIO2的初始化阶段很关键。启动后不要立刻大步快走,先缓慢移动几秒,让IMU充分激励,给状态估计器一个收敛过程。很多次地图发飘,都是因为人一启动就跑得飞快,算法还没来得及初始化好就失稳了。
5.2 手持建图的运动控制
建图质量很大程度取决于你怎么拿着雷达走:
- 尽量保持“平移+旋转”组合,不要长时间只绕一个轴转圈。只平移时,退化方向多;只旋转时,角度发散快。让雷达的运动尽量“丰富”,最利于FAST-LIO2的观测收敛。
- 走廊、门洞这种场景,不要直直一条线走过去,适当走“之”字形,让同一个区域被多角度扫描到几次。
- 经过家具、墙角、门框时放慢速度,这些几何特征丰富的区域是算法最好的“锚点”。相反,空旷大厅里没有太多约束,地图容易在水平方向上飘。
- 不要一直盯着一个方向,转身时速度放慢一点,转身太猛IMU容易饱和,观测跳变,之后地图可能会有一小段弯折。
5.3 保存地图与结果验证
FAST-LIO2自带PCD保存服务,当你觉得当前地图质量可以接受时,在另一个终端调用保存服务:
rosservice call /pcd_save "{}"如果你的版本里请求类型是带字段的,也可以写成:
rosservice call /pcd_save "save: true"保存完成后,点云会输出到fast_lio包目录下的PCD文件夹里,文件名是保存时刻的时间戳,同时一般也会保存一份完整地图的Surround文件。用CloudCompare打开保存的PCD,先检查整体点云是否闭合、墙壁是否平直、有没有明显的重影。
6. 高精度建图调优:实测中踩过的坑
跑通只是第一步,真正压榨出高精度地图是第二步。下面这些坑我在实际项目里都遇到过,按优先级从高到低排列。
6.1 时间戳与IMU数据流异常
我遇到过最隐蔽的问题不是算法参数,而是IMU数据流不稳定。现象是:地图刚开始建还可以,走一会儿就慢慢漂开,Rviz里的里程计轨迹在静止时也会缓慢旋转。
排查时我直接在另一个终端看IMU频率,发现/livox/imu不是稳定的200Hz,而是130Hz、190Hz、80Hz来回跳。虽然话题还在发,但频率不稳导致FAST-LIO2的时间同步模块一直处于“将信将疑”的状态,滤波器自然就飘了。
根因是雷达供电不稳定。换了一个独立的、功率余量充足的PoE供电口之后,IMU频率立刻稳定下来,地图漂移问题也随之消失。
6.2 外参不准与IMU初始化
如果你把MID-360装在一个固定的结构件上,但结构件加工精度一般,那么雷达和IMU的实际外参和默认值会有一点差距,表现就是地图边缘有轻微“重影”,或者转弯后地图出现微小的角度闭合差。
对于首次跑通,建议在配置文件里把extrinsic_est_en设为true,让FAST-LIO2在线估计雷达–IMU外参。开启后,算法会在一段时间内持续修正外参,地图会逐渐收敛到更清晰的状态。
需要注意:开放外参在线估计时,如果环境很空旷、观测不够,外参可能跑到一个“看起来合理但其实错误”的值。等地图质量明显稳定后,可以把该参数关掉,用当前估计出来的外参固定,防止后续在退化场景里被带偏。
6.3 退化环境如何处理
FAST-LIO2本质上还是里程计,遇到退化环境会漂。最典型的是长直走廊:沿着走廊方向移动时,激光在走廊轴向几乎没有几何约束,结果地图在长直方向上被拉长,或者出现“弯扭曲”。
我在走廊场景里的应对方式是:主动增加横摆运动,比如走“S”形。虽然没有回环检测,但多次从不同角度观测同一个门洞、柱子,能给优化器更多约束,延缓漂移。如果项目允许,在走廊两端放置几个明显几何特征的标记物,也能显著提升地图质量。
6.4 点云断线、供电与连接不稳定
另一种常见故障是点云话题时不时掉线,rostopic hz能看到断断续续,Rviz里的点云一闪一闪。
处理顺序是:
- 先换网线,优先用质量好的超五类或六类成品网线,别用自己压的、外层已破损的线。
- 检查供电。MID-360可以用PoE交换机供电,也可以单独供电,但无论哪种都要保证功率稳定。
- 尽量用有线网卡直连,而不是USB转千兆网卡。USB转网卡在数据量较大时偶尔会丢包,这种问题很难定位,因为不是每次都丢。
我自己的心得是:先排除硬件问题再去调算法参数,否则就是在故障硬件上找软件的茬,永远找不到根。
最后再分享一个小技巧
如果你有一块已经验证过的场景,平时调参不要每次都用真机重新走一遍,很累。用rosbag把/livox/lidar和/livox/imu两个话题录下来,之后离线回放:
rosbag record /livox/lidar /livox/imu然后回放时同时启动FAST-LIO2:
rosbag play record.bag这样每次改参数只需要重放同样的数据,能明确知道是参数变了导致效果变化,还是这次手持动作和上次不一致导致的差异。把变量控制住,调优效率能高出一大截。