简介:激光雷达与惯性测量单元(IMU)融合的SLAM技术,是移动机器人在复杂环境下实现定位与建图的核心方案。非重复扫描雷达因点云覆盖均匀、无需单独外接IMU,在机器人感知领域备受关注。FAST-LIO2作为紧耦合激光惯性里程计算法,依赖高质量点云与精确外参,可通过原始点云迭代配准实现高鲁棒性建图,广泛应用于室内外巡检、无人车导航等工程实践。在实际部署中,从驱动库选择到坐标系对齐,版本兼容性与参数一致性往往决定系统能否稳定运行。本文以MID360与FAST-LIO2组合为例,系统梳理Ubuntu 20.04 + ROS Noetic环境下Livox-SDK2、livox_ros_driver2及FAST-LIO2的完整编译流程,重点解析双雷达融合时的话题合并策略,以及倾斜安装场景下雷达坐标系与IMU坐标系的对齐原则,帮助开发者快速搭建可复用的激光惯性SLAM前端,避开版本混用与外参重复标定的常见陷阱。 最近在给移动机器人换感知方案,正好把手里的 MID360 接到新主机上,配合 FAST-LIO2 做室内外建图。网上关于这套组合的教程不少,但年代和版本错得很厉害,经常把 SDK1 和 SDK2 混着讲,照着抄很容易卡在编译阶段。这篇文章把我这次在 Ubuntu 20.04 + ROS Noetic 上从零跑通 mid360 + Livox-SDK2 + Livox-ros-driver2 + FAST-LIO2 的完整过程整理出来,重点放在那些文档里不会写、但实际操作一定会遇到的地方。如果你手里有一台 MID360,想拿它做实时建图,或者想给机器人接一套能跑的激光惯性 SLAM 前端,这份流程可以省下不少排查时间。
1. 为什么这套组合值得部署:MID360与FAST-LIO2的适配逻辑
1.1 MID360本身能省掉哪些传感器
MID360 是 Livox 面向中近距感知推出的非重复扫描雷达,水平视场角 360°,垂直视场角 -7° 到 52°,测距能力在室内外都能覆盖几十米范围。最方便的一点是它内部集成了 IMU,也就是说不再需要额外买一个独立的惯性测量单元,FAST-LIO2 这类激光惯性里程计算法可以直接使用雷达自带的 IMU 数据。整机体积不大,重量也轻,很适合装在小型移动平台或者四足机器人上。
它的点云不是传统线束雷达那种均匀扫描线,而是非重复扫描路径,时间长了会把视场内覆盖得越来越密。这种特性对 FAST-LIO2 其实很友好,因为算法不是单纯提取角点和平面,而是直接对原始点云做迭代配准,点云在视场里分布得越均匀,提平面特征的鲁棒性就越好。
1.2 SDK2、ros_driver2、FAST-LIO2三者之间的关系
这套系统里三个软件层各有分工。Livox-SDK2 是官方底层通讯库,负责和雷达硬件通信,接收 UDP 数据包,解析出点云、IMU、雷达状态等信息。Livox-ros-driver2 是 ROS 驱动层,它依赖 SDK2 提供的底层数据,再把数据包装成 ROS 话题,例如/livox/lidar和/livox/imu。FAST-LIO2 则是真正干活的 SLAM 算法,它订阅驱动发布的话题,做点云配准和 IMU 融合,输出里程计和全局地图。
所以版本关系是一条链:雷达硬件 -> SDK2 -> ros_driver2 -> FAST-LIO2。其中任何一层版本选错都可能编不过。比如有些老教程让你装 SDK1 然后配合 livox_ros_driver 老版本,那只能驱动 Horizon、MID-40 那一类雷达,MID360 需要到 SDK2 和对应的 ros_driver2 才支持完整功能。
1.3 部署的完整数据流
用文字描述一下实际运行时的数据流,方便后面排查问题。MID360 通过以太网线连接到主机网口,主机在同一个局域网内设置静态 IP。SDK2 在驱动节点内部监听雷达发来的 UDP 数据,SDK2 解析后把每帧点云以回调方式交给 ros_driver2 节点。ros_driver2 节点再根据配置把点云发布到 ROS 总线,同时把 IMU 数据发布出来。FAST-LIO2 节点同时订阅这两个话题,在内部做紧耦合,输出/Odometry、/path和/map。
理解了这条链路,后面遇到雷达不识别、话题没数据、建图飘移这类问题,至少能判断问题出在哪一层。
2. 环境准备阶段最容易翻车的几个点
2.1 Ubuntu和ROS版本怎么选
我这次用的是 Ubuntu 20.04 + ROS Noetic,这是目前最稳的组合。Ubuntu 18.04 + Melodic 也能跑,但系统自带的 CMake、gcc 版本偏老,编 SDK2 或者 FAST-LIO2 时可能要多折腾依赖。Ubuntu 22.04 + ROS2 Humble 也有对应分支,不过 FAST-LIO2 的 ROS2 版本维护节奏和 ROS1 不完全一样,第一次上手不建议直接挑战 ROS2。
如果你的主机还没有装 ROS,先用官方安装步骤把 Noetic 装好,然后执行下面命令确认环境正常:
source /opt/ros/noetic/setup.bash roscore能正常启动 roscore,说明 ROS 基础环境没问题。之后再创建 catkin 工作空间,尽量不要在系统目录下直接放源码。
2.2 依赖安装清单
依赖可以分为两类,一类是通用编译依赖,另一类是点云处理相关库。通用部分用 apt 装:
sudo apt update sudo apt install git cmake build-essential net-tools点云和 ROS 消息相关,Noetic 下建议装:
sudo apt install libpcl-dev libeigen3-dev ros-noetic-pcl-ros ros-noetic-rvizEigen 和 PCL 是 FAST-LIO2 的核心依赖。PCL 如果从源码编译会非常耗时,直接装系统库省心很多。某些版本的 FAST-LIO2 还依赖 Sophus 和 glog,可以在后续编译报错时按提示再补,不用一次性全装。
2.3 网络与工作空间配置
MID360 默认 IP 一般是192.168.1.1,需要把主机网卡配到同一网段,比如192.168.1.50,子网掩码255.255.255.0。配置完用ifconfig查看网卡状态,然后ping 192.168.1.1,能通基本就是物理链路正常。
防火墙是另一个常见问题。UDP 广播和组播被防火墙挡住时,SDK2 会一直搜不到雷达。建议先在调试阶段关掉防火墙:
sudo ufw disable如果不想全局关闭,至少要允许雷达通信所需的 UDP 端口和组播地址。网络不通时,ping 192.168.1.1是最快的判断手段,不用急着去翻驱动日志。
3. 编译Livox-SDK2:别再把SDK1和SDK2混在一起了
3.1 SDK2源码编译
SDK2 的仓库是独立的,不要再从旧项目里拉 SDK1。编译步骤很常规:
git clone https://github.com/Livox-SDK/Livox-SDK2.git cd Livox-SDK2 mkdir build && cd build cmake .. make -j$(nproc) sudo make install编译过程中如果遇到缺头文件或链接错误,先检查 cmake 输出。常见的报错集中在libpcap或者网络相关库缺失,看提示装对应包即可。make -j$(nproc)会调用所有核编译,速度很快,但也可能因为内存不足卡住,小内存机器建议make -j2。
默认安装路径是/usr/local,头文件在/usr/local/include/livox,库文件在/usr/local/lib。后面的 ros_driver2 通过 CMake 的find_package查找 SDK2,如果安装到了非标准路径,需要手动通过CMAKE_PREFIX_PATH告诉它。
3.2 SDK2安装后的验证
安装完先别急着编译驱动,检查一下库是否真的存在:
ls /usr/local/lib | grep livox_sdk ldconfig -p | grep livox能看到类似liblivox_sdk2.so的文件,说明安装成功了。如果之前装过 SDK1,系统里可能会有额外的liblivox_sdk.so,要注意区分,后面驱动编译时务必链接的是 SDK2。
3.3 SDK2与SDK1的差异
很多人照着老教程编驱动,结果卡在 undefined reference 或者版本不匹配。SDK1 和 SDK2 的头文件、命名空间、API 都有差异,ros_driver2 必须配合 SDK2 使用。老版本的 livox_ros_driver 是配合 SDK1 的,不要混用。
区分方法也很简单,看仓库名和分支。Livox-SDK2和livox_ros_driver2是配套的一对,单独去装 SDK1 再拉 ros_driver2,CMake 大概率会直接报Could not find livox_sdk2。装完 SDK2 后,可以先编译一下 SDK2 自带的 sample,确认底层通信已经能解析雷达数据,再进入 ROS 驱动环节。
4. Livox-ros-driver2编译与雷达配置:从单雷达到双雷达
4.1 catkin工作空间里编译驱动
把驱动放进 catkin 工作空间,然后在工作空间根目录编译:
cd ~/catkin_ws/src git clone https://github.com/Livox-SDK/livox_ros_driver2.git cd ~/catkin_ws catkin_make编译前确保已经 source 了 Noetic 环境,并且 SDK2 已经安装好。如果 CMake 提示找不到 livox_sdk2,可以在编译前设置:
export CMAKE_PREFIX_PATH=/usr/local:$CMAKE_PREFIX_PATH编译完成后,先跑一次官方 launch 看雷达能不能正常出数据:
source devel/setup.bash roslaunch livox_ros_driver2 mid360.launch能正常输出时,rostopic list里至少能看到/livox/lidar和/livox/imu。没有这两个话题,就回头查网络和 SDK2 是否装好。
4.2 launch文件与json配置
ros_driver2 的配置主要通过 json 文件完成,launch 文件里再指定 json 路径。第一次跑建议打开驱动包里的示例配置看一下结构。核心是一个lidar_config数组,数组里每个元素对应一台雷达。需要关注的字段包括:
id:雷达唯一标识码,可以在 Livox Viewer 里查到ip:雷达的 IP 地址enable:是否启用extrinsic_parameter:雷达外参,包含 roll、pitch、yaw、x、y、z
xfer_format决定点云输出格式,一般保持默认即可。multi_topic这个参数很重要,单台雷达无所谓,多雷达时必须理解它的作用。
4.3 双雷达融合的话题配置
如果平台上有两台 MID360,最常见做法是在lidar_config里加两个元素,分别填两台雷达的 ID 和 IP。然后把multi_topic设为false,这样驱动会把多台雷达的点云合并到同一个/livox/lidar话题上,FAST-LIO2 只需要订阅一个话题就能拿到全部点云。
multi_topic设为true时,每台雷达会输出独立话题,比如/livox/lidar_1、/livox/lidar_2,这时候需要自己再用点云合并工具。从 SLAM 角度来说,合并到单一话题更省事,但前提是外参必须标定准确。如果两台雷达安装位置和朝向不同,合并后的点云会变得混乱,后续建图质量直接受影响。
4.4 倾斜安装时的坐标系对齐
热词里提到“mid360倾斜雷达坐标系对齐”,这是很容易搞错的地方。MID360 可以不水平安装,比如装在车辆前部,有一个俯仰角或横滚角。这时有两种处理外参的方式:
方式一:在驱动 json 里填写雷达相对 IMU 的外参。这样驱动会先把点云变换到 IMU 坐标系下,再发布出去。方式二:驱动外参全部置零,保持点云在雷达原始坐标系,然后在 FAST-LIO2 的配置里填写雷达到 IMU 的变换。
这两种方式只能选一种,千万不能两边都填。我见过很多人在驱动里填了外参,又在 FAST-LIO2 的extrinsic_R里填了同一份旋转,结果点云被旋转两次,地图直接变成斜的。建议的做法是:驱动里全部置零,所有外参统一交给 FAST-LIO2 处理。这样排查外参问题时只需要看一个地方。
倾斜安装的外参数值按右手定则填写,roll、pitch、yaw 单位是度。比如雷达绕 Y 轴俯仰 30 度,那 pitch 就是 30。注意旋转顺序要和算法内部一致,如果发现地图整体倾斜,第一件事是检查外参符号和旋转顺序,而不是去调建图参数。
5. FAST-LIO2编译与建图参数调整
5.1 编译FAST-LIO2
FAST-LIO2 代码在 hku-mars 的 FAST_LIO 仓库里,里面有 FAST-LIO 和 FAST-LIO2 的实现。克隆到工作空间后,记得更新子模块:
cd ~/catkin_ws/src git clone https://github.com/hku-mars/FAST_LIO.git cd FAST_LIO git submodule update --init cd ~/catkin_ws catkin_make子模块里有 ikd-Tree 等依赖,不更新会在编译时找不到头文件。编译前要确保 livox_ros_driver2 已经 build 进了当前环境,因为 FAST-LIO2 的消息类型依赖驱动包。
5.2 mid360.yaml参数详解
FAST-LIO2 的配置目录在src/FAST_LIO/config下。不同版本里的示例配置文件名不一样,有的叫avia.yaml,有的叫mid360.yaml。没有现成的 mid360 配置时,可以复制一份 avia 的配置再改。
核心参数重点关注这几个:
lid_topic:点云话题,填/livox/lidarimu_topic:IMU 话题,填/livox/imutime_sync_en:时间同步开关,建议填falselidar_type:填1,表示 Livox 非重复扫描雷达point_filter_num:每几个点取一个点,数值越大耗时越低,默认 1filter_size_surf:地图体素滤波粒度,越小越精细,但越吃 CPUextrinsic_rotation和extrinsic_translation:雷达到 IMU 的外参
如果你按我前面的建议,驱动侧外参全部置零,那 FAST-LIO2 里就要填写正确的雷达到 IMU 变换。单位矩阵和零平移表示雷达坐标系和 IMU 坐标系完全重合,如果 MID360 的 IMU 在雷达内部且安装时雷达相对车体没有旋转,可以先用单位矩阵跑通,发现问题再加外参。
5.3 点云话题、IMU话题和时间同步
FAST-LIO2 启动后会检查点云和 IMU 消息的时间戳。如果时间戳偏差太大,会打印 warning 甚至直接不用 IMU,导致建图飘。MID360 自带 IMU,而且 ros_driver2 发布的点云和 IMU 的时间基准是同一个驱动进程,通常不会差太多。如果看到时间戳跳变,先检查电脑系统时间是否准确,再检查驱动的时间同步参数。
time_sync_en这个参数我建议保持 false。开启后驱动会尝试和雷达做时钟同步,需要一系列额外的网络配置,一旦没配好,反而会把本来就正常的点云时间搞乱。对绝大多数机器人场景来说,主机时间配合驱动转发的时间戳已经够用。
5.4 启动与调参
FAST-LIO2 的启动命令通常类似:
roslaunch fast_lio mapping.launch config_file:=mid360.yaml具体 launch 文件名和参数名看仓库里的说明。启动后 Rviz 里应该能看到点云地图和里程计轨迹。如果 Rviz 里一片空白,先确认/livox/lidar有数据,再确认 FAST-LIO2 进程有没有报错。
刚启动时不要立刻推动机器人。让雷达静止 1 到 2 秒,让 IMU 完成 bias 初始化,然后再开始慢慢移动。如果一上来就猛转,IMU 初始化不充分,地图很容易飘。
6. 实际建图时躲不开的坑与排查思路
6.1 雷达识别不到
雷达识别不到是最高频的问题。先按顺序排查:
- 检查网线是否插紧,MID360 网口指示灯是否正常
ifconfig确认主机网卡 IP 和雷达同网段ping 192.168.1.1确认网络通- 关闭防火墙再试
- 看驱动进程有没有报
device not found之类的日志
如果你是在虚拟机里跑的 Ubuntu,网络模式一定要选桥接,不能选 NAT。NAT 模式下虚拟机收不到雷达的 UDP 广播,SDK2 永远发现不了设备。这个坑我踩过,折腾了一个晚上才发现是虚拟机网络模式的问题。
6.2 IMU数据异常导致定位漂移
FAST-LIO2 对 IMU 数据比较敏感。如果启动后地图快速旋转、漂移,最先怀疑 IMU 方向和频率。用以下命令看 IMU 频率:
rostopic hz /livox/imuMID360 内置 IMU 的频率比较高,如果实际频率只有几十赫兹或者不稳定,检查驱动是不是被 CPU 拖累了。然后静态放置雷达,在 Rviz 里显示 IMU 坐标系,观察是否稳定。如果角度数据乱跳,说明 IMU 标定或安装有问题。
外参方向弄反也很常见。比如雷达绕 Y 轴俯仰,你在 FAST-LIO2 里填成了 -30,算法会认为雷达和 IMU 的相对姿态与实际相反,建图时点云会持续扭曲。遇到这种情况,试着把 roll、pitch、yaw 符号取反,多半就能恢复。
6.3 点云丢帧或CPU吃满
MID360 单帧点云数量比不上 64 线机械式雷达,但如果 FAST-LIO2 的配置太激进,CPU 照样会被吃满。最直接的优化是调大point_filter_num,比如从 1 调到 3,点云数量减少到三分之一,建图精度损失不明显,但实时性会好很多。
Rviz 里的可视化也会占用大量资源。别把原始点云全部显示出来,用 Rviz 自带的 Decimation 或通过话题降采样显示。地图保存时也用离线的map_save工具,不要靠在建图过程中一直挂着 Rviz 录屏。
6.4 双雷达融合和倾斜安装的额外坑
双雷达融合时,如果两台雷达用了默认 IP 或同一组广播地址,可能互相冲突。拿到雷达后先用 Livox Viewer 把每台雷达的 IP 改掉,再填到驱动 json 里。两台雷达的 ID 必须是唯一的,不能并排列出两个相同的 ID。
时间戳方面,多雷达如果没做同步,在机器人快速转弯时合并点云可能出现重影。这个问题比外参更难处理,因为跟驱动内部实现有关。简单的规避方法是把两台雷达的xfer_format都设置成一样,并确保它们都由同一个 ros_driver2 节点管理,至少能保证 SDK2 层面使用同一套时间基准。
倾斜安装的多雷达外参标定要更细致。雷达之间的相对位姿如果存在几度误差,融合后的地图会明显分层。建议先用 FAST-LIO2 单雷达分别跑一段数据,看各自建图出来是否平整,再融合。哪台雷达单独跑都有问题,就不要急着上融合,先把单台调好。
最后说几句
整套部署跑通之后,我对这套组合最大的感受是:编译过程本身不难,真正的难点全在版本对应和外参一致性上。双雷达融合也好,倾斜雷达对齐也好,只要遵循“驱动和算法里只保留一套外参,另一套置零”这个原则,问题就少了一大半。另外,遇到地图异常先不要急着调算法参数,停下来看一下 Rviz 里的原始点云是否已经正确变换到了 IMU 坐标系,很多时候问题出在传感器前端而不是后端建图。希望这篇流程能帮你少走弯路,尤其是第一次接 MID360 的朋友,按章节顺序排查,比到处翻零散教程高效得多。
本文还有配套的精品资源,点击获取