简介:激光雷达SLAM建图是机器人感知与导航的核心技术之一,而混合固态雷达凭借非重复扫描特性,在特征匹配与地图构建中展现出独特优势。要将这类雷达真正跑起来,离不开底层驱动、ROS适配层与紧耦合里程计算法的协同工作:底层通信库负责解析雷达数据,ROS驱动将点云与IMU消息发布为标准话题,紧耦合算法则融合两者实时估计位姿并增量式构建地图。在Ubuntu 20.04与ROS Noetic环境下,完成Livox-SDK2、Livox-ros-driver2及FAST-LIO2的编译与参数配置,是打通建图链路的关键。本文从环境准备、驱动编译、网络配置到高频问题排查,系统梳理mid360与FAST-LIO2的完整部署过程,帮助开发者快速上手激光惯性SLAM实践。 拿到mid360之后,很多人第一反应是赶紧接上电脑扫一圈,但实际把这颗雷达跑起来、再把FAST-LIO2的建图链路打通,中间隔着一整套环境配置和驱动编译的活。这个部署过程说难不难,说简单也真有不少坑:SDK2和ros-driver2的版本关系、FAST-LIO2对消息类型的依赖、雷达网络配置、IMU时间同步,任何一个环节没对齐,最后看到的点云就是一片乱飘或者直接没数据。
这篇文章把我自己在一台Ubuntu 20.04工控机上从零部署mid360 + Livox-SDK2 + Livox-ros-driver2 + FAST-LIO2的过程完整梳理了一遍。适合刚拿到mid360、准备做SLAM建图的同学,也适合已经被编译报错折腾到头大、想快速排查问题的人。文章里涉及的命令和配置可以直接抄,但更重要的是我会把每一步为什么这么做的原因讲清楚,这样你遇到类似问题也知道往哪个方向查。
1. 动手之前,把这套系统里的四个角色认清楚
1.1 mid360这个雷达到底特殊在哪
mid360是Livox推出的一款混合固态激光雷达,跟传统的机械式雷达不是一个路子。它在内部用棱镜扫描,形成的是非重复扫描图案,点云会随着时间不断填充视场里的盲区。这个特性对SLAM来说非常友好,因为随着雷达转动,同一片区域会被反复扫描,点云密度会越来越高,特征匹配的稳定性比单帧机械雷达好不少。
它的视场角是一个接近70°的圆形FOV,量程官方标称是40米(10%反射率下),实际室内建图十几米范围内效果很好,室外贴着建筑走也够用。更重要的是,mid360内部集成了一个六轴IMU,这颗IMU对FAST-LIO2来说太关键了,因为FAST-LIO2本身就是紧耦合的LiDAR-Inertial里程计,没有IMU的数据,整个算法跑不起来。
还有一个很容易忽略的点:mid360只支持Livox-SDK2,不支持老的Livox-SDK1。如果你之前玩过Horizon或者MID-40,习惯性去装SDK1,那mid360是连不上的。这个兼容性问题后面还会细说。
1.2 SDK2、ros-driver2、FAST-LIO2三者各管什么
很多新手把这三个东西混在一起,其实它们的层级完全不同:
- Livox-SDK2是Livox官方的底层通信库,负责通过以太网协议跟雷达硬件通信,解析雷达数据包,把原始点云和IMU数据从网线里“抠”出来。它不关心ROS,是纯C++库。
- Livox-ros-driver2是ROS适配层,内部调用Livox-SDK2拿到数据,再把数据封装成ROS话题发布出去,比如
/livox/lidar和/livox/imu。它同时支持ROS1和ROS2,但要用对应的分支或编译选项。 - FAST-LIO2是香港大学Mars实验室开源的紧耦合激光惯性里程计算法,它订阅ros-driver2发布的话题,把激光点云和IMU数据融合在一起,实时估计雷达的位姿并构建增量式地图。
打个比方,SDK2是“网卡驱动”,ros-driver2是“操作系统里的网卡接口”,FAST-LIO2则是跑在系统里的地图应用。你只装驱动不装算法,只能在Rviz里看到一堆原始点云;只装算法不装驱动,算法连数据都拿不到。
1.3 为什么不用Livox-SDK1和ros-driver1
这几乎是每个mid360用户都会踩的坑。网上大量老教程还在用Livox-SDK1和livox_ros_driver,甚至连ROS驱动包的仓库名都类似,很容易下错。mid360的底层通信协议和协议解析方式跟老一代雷达不同,SDK1根本识别不到它。
如果你在编译或者启动驱动时看到类似Device not found、lidar count 0的提示,先检查一下自己是不是装成了老版本。正确做法是直接clone仓库名带2的两个项目:Livox-SDK2和Livox-ros-driver2。版本选对了,后面一大半问题都不存在。
2. 环境准备:用Ubuntu 20.04 + Noetic是最舒服的组合
2.1 推荐软硬件版本组合
我部署过好几次这套环境,最省事的组合是:Ubuntu 20.04 + ROS Noetic + Livox-SDK2 + Livox-ros-driver2(ROS1分支) + FAST-LIO2。这个组合里ROS Noetic用的是Python3,很多依赖包都是现成的二进制安装,编译链路比较顺。
如果你想用Ubuntu 18.04 + ROS Melodic,理论上也可以,但要注意两点:一是系统的CMake版本可能太老,Livox-SDK2要求CMake 3.14以上,Ubuntu 18.04默认的CMake是3.10,需要手动升级;二是PCL、Eigen这些库的版本偏旧,FAST-LIO2编译时可能因为C++标准问题报一些莫名其妙的错误。
想用ROS2的话,ros-driver2有ROS2分支,FAST-LIO2官方没有原生ROS2版本,社区有一些移植版,但用起来没有ROS1省心。我自己还是建议先跑通ROS1这套,把整个链路弄熟之后再折腾ROS2。
2.2 ROS和基础依赖安装
装ROS Noetic是第一步,直接按官方流程来最稳:
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' sudo apt install curl curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add - sudo apt update sudo apt install ros-noetic-desktop-full装完之后记得初始化rosdep并设置环境变量:
sudo rosdep init rosdep update echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc source ~/.bashrc接下来安装编译FAST-LIO2需要的核心依赖,主要是Eigen和PCL:
sudo apt install libeigen3-dev libpcl-devEigen在这里尤其重要,FAST-LIO2大量使用Eigen的矩阵运算,如果系统里没有Eigen或者版本太老,编译到一半就会报一堆模板错误。PCL是点云处理的基础库,rviz显示点云、点云滤波、地图保存都会用到。
如果你是连ROS基础都没装过的新手,建议先别急着往下走,打开一个新终端,运行一下roscore,能正常启动就说明ROS环境没问题。
2.3 编译前的检查清单
正式开始编译之前,我建议你先花两分钟检查下面这几项,能省掉后面很多排查时间:
- CMake版本:
cmake --version,至少3.14以上,如果低于这个版本,SDK2编译会直接报错。 - Eigen版本:
pkg-config --modversion eigen3,2.x版本太老,3.3.x以上比较保险。 - gcc/g++版本:
gcc --version,Ubuntu 20.04自带的gcc 9完全没问题。 - 网络设置:确认雷达和电脑的网线已经连好,电脑网卡IP要跟雷达IP在同一网段(后面第3.3节细说)。
这个检查清单看起来琐碎,但真的能救命。我遇到过不止一次,用户反馈SDK2编译失败,最后发现是CMake版本只有3.10。与其在报错信息里猜来猜去,不如一开始就把环境基础打好。
3. Livox-SDK2和Livox-ros-driver2的编译与验证
3.1 编译Livox-SDK2
Livox-SDK2的编译很简单,官方README里给了标准流程,直接执行:
git clone https://github.com/Livox-SDK/Livox-SDK2.git cd Livox-SDK2 mkdir build && cd build cmake .. make -j8 sudo make install这里有个细节:-j8是并行编译参数,如果你的机器内存不大或者CPU核心少,建议改成-j4,避免编译时内存占满导致进程被系统杀掉。SDK2本身的源码量不算大,正常机器几分钟就能编完。
编译完成后会默认把库文件安装到/usr/local/lib,头文件安装到/usr/local/include。如果你在编译ros-driver2时找不到SDK2的库,记得先执行sudo ldconfig刷新一下动态链接库缓存。这个操作很容易被漏掉,漏掉之后编译器会提示找不到liblivox_sdk2.so,其实库就在系统里,只是链接器还没刷新缓存。
3.2 编译Livox-ros-driver2(ROS1分支)
创建catkin工作空间,把ros-driver2源码放进去:
mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone https://github.com/Livox-SDK/Livox-ros-driver2.git cd ~/catkin_ws catkin_make source devel/setup.bash关于ros-driver2,有一个容易踩坑的地方:它同时支持ROS1和ROS2,但ROS1的代码被放在仓库的ROS1目录下,ROS2的代码在ROS2目录下,整个仓库的顶层CMakeLists.txt是ROS2的。如果你在ROS1环境下直接对整个仓库执行catkin_make,可能会发现根本没编译出ROS1的节点。
实际上,ros-driver2仓库会在你指定了ROS1环境时自动处理这个问题。前提是你的终端已经source了ROS1的环境,并且catkin_make是在工作空间根目录执行的。如果你发现编译出来的节点名不对,可以cd到ROS1目录下看一下它的结构和说明。稳妥起见,我把官方推荐的方式列在下面:
source /opt/ros/noetic/setup.bash cd ~/catkin_ws catkin_make source ~/catkin_ws/devel/setup.bash编完之后用rospack find livox_ros_driver2验证一下能不能找到这个包,能正常找到路径就说明ok。
3.3 连接雷达并验证点云
这一步是整个部署里最容易卡住的地方,因为mid360用的是以太网通信,不是USB直接出数据。mid360默认IP是192.168.1.100,你的电脑网卡必须配置成同一网段的IP,比如192.168.1.50,子网掩码255.255.255.0。
我一般是用nmtui或者直接在系统设置里配置有线网络的IPv4为手动模式,填好IP和掩码,然后ping 192.168.1.100验证连通性。能够稳定ping通,再往下走;ping不通的话,后面驱动启动肯定是设备找不到,先检查网线和IP配置。
驱动启动前还需要修改一个配置文件。在ros-driver2的config目录下找到MID360_config.json,检查里面的用户配置路径是否正确。需要注意,如果雷达的IP不是默认的,需要在配置里改成实际IP,另外要确认lidar_type设置为MID360对应的类型。
启动驱动节点:
roslaunch livox_ros_driver2 msg_MID360.launch如果一切正常,你会看到终端里打印出雷达设备信息,然后可以通过rostopic list看到/livox/lidar和/livox/imu这两个话题。用rostopic hz /livox/lidar查看频率,正常应该是10Hz左右;rostopic hz /livox/imu应该是200Hz左右。再用rosrun rviz rviz打开Rviz,Add一个PointCloud2显示,话题选/livox/lidar,就能看到mid360扫描出来的点云了。
这里要提醒一句:mid360的点云是非重复扫描的,所以Rviz里的点云不是机械雷达那种一圈一圈的整齐线条,而是像“磨砂”一样逐渐填充整个圆。很多新手第一次看到这个画面以为雷达坏了,其实完全是正常的。
4. FAST-LIO2编译与mid360参数配置
4.1 编译FAST-LIO2
驱动部分搞定之后,FAST-LIO2的部署就水到渠成了。先把源码放到同一个catkin工作空间的src目录下:
cd ~/catkin_ws/src git clone https://github.com/hku-mars/FAST_LIO.git cd ~/catkin_ws catkin_make source devel/setup.bashFAST-LIO2的编译依赖ros-driver2,因为它的代码里直接用了livox_ros_driver2::CustomMsg这一自定义消息类型。所以在编译FAST-LIO2之前,必须确保livox_ros_driver2已经编译好,并且当前终端已经source过devel环境。如果编译时提示找不到livox_ros_driver2的头文件,多半就是环境没source干净。
另一个容易踩的坑是编译时提示找不到PCL或者Eigen,也就是第2.2节提到的依赖没装。先回过去装依赖,再重新编译。
4.2 mid360的yaml参数逐项说明
FAST-LIO2的配置在src/FAST_LIO/config/mid360.yaml,这个文件决定算法能不能正确驱动mid360。我挑几个关键项说一下:
common: lid_topic: "/livox/lidar" imu_topic: "/livox/imu" time_sync_en: true extrinsic_est_en: true extrinsic_T: [0.0, 0.0, 0.0] extrinsic_R: [1, 0, 0, 0, 1, 0, 0, 0, 1] preprocess: lidar_type: 1 scan_line: 4 blind: 0.1 timestamp_unit: 2lid_topic和imu_topic必须跟ros-driver2发布的话题名一致,否则算法收不到数据。time_sync_en这个参数要打开,它会启用雷达和IMU的时间同步,对FAST-LIO2这种紧耦合算法来说,时间对齐直接影响建图精度。lidar_type: 1表示使用livox自定义消息类型,这个不要改。scan_line: 4对应mid360的4条激光线束。blind: 0.1表示滤除0.1米以内的点,因为近距离点云噪声太大,而且容易把雷达自身反射进去。
extrinsic_T和extrinsic_R是雷达坐标系到IMU坐标系的平移和旋转。用mid360内置IMU时,最稳妥的方式是把它们设为单位阵,并打开extrinsic_est_en让算法在线估计外参。FAST-LIO2的在线外参估计功能已经比较成熟,实际跑起来很快会收敛到真实值。
timestamp_unit这个参数要特别注意,它表示点云时间戳的精度单位。如果你的点云时间戳看起来不对,比如建图时点云抖动、位姿跳变,优先检查这个值的设置是否和驱动的时间戳精度匹配。
4.3 首次跑通建图的完整过程
启动驱动(新终端):
source ~/catkin_ws/devel/setup.bash roslaunch livox_ros_driver2 msg_MID360.launch启动FAST-LIO2(另一个新终端):
source ~/catkin_ws/devel/setup.bash roslaunch fast_lio mapping.launch如果配置没问题,rviz会自动打开,你会看到点云实时堆积成地图,同时终端里会输出每次迭代的位姿信息和耗时。手持雷达或者把雷达装在机器人上缓慢移动,地图会随着运动不断扩展。
第一次跑的时候,我给一个非常具体的建议:先站着不动,让雷达静止扫描几秒钟,等点云稳定了再缓慢平移。这样算法能先初始化好IMU状态,建图的成功率会高很多。如果一上来就大幅度甩动雷达,IMU容易饱和,初始化阶段就可能发散。
跑通之后还可以录一个bag包保存数据,方便反复调试参数。录制bag的指令很简单:
rosbag record /livox/lidar /livox/imu后面调试的时候直接用rosbag play回放数据,就不用一直举着雷达了。这个习惯我强烈建议养成,对排查问题效率提升巨大。
5. 实战中遇到的高频问题和我的排查方法
5.1 编译期报错速查表
编译问题是最让人头大的,但其实很多都是共性问题。下面这几个是我遇到比较多、也经常在网上看到别人问的:
| 现象 | 直接原因 | 解决办法 |
|---|---|---|
| 编译SDK2提示CMake版本过低 | 系统CMake低于3.14 | 升级CMake到3.14+,或用pip装新版cmake |
| ros-driver2编译后找不到节点 | 没有在ROS1环境下编译 | source ROS1环境后重新catkin_make |
| FAST-LIO2编译找不到livox_ros_driver2头文件 | 环境未source或ros-driver2未编译 | source devel/setup.bash后再编译 |
| 编译报一堆Eigen模板错误 | Eigen版本太旧 | 安装libeigen3-dev新版本 |
| 提示找不到liblivox_sdk2.so | SDK2安装后没有刷新库缓存 | 执行sudo ldconfig,或把/usr/local/lib加入LD_LIBRARY_PATH |
关于Eigen报错再补充一句:有时候你明明装了新版本Eigen,但CMake用的是系统里另一个旧版本。建议编译前打印pkg-config --modversion eigen3确认实际生效的版本,别被“我装了啊”骗了。
5.2 运行期问题排查
运行期的问题比编译期更隐蔽,因为编译过了不等于系统在工作。我这里列几个常见表现:
驱动启动后提示device not found:先ping雷达IP,ping不通就是网络问题;ping通了还是找不到,检查是否把SDK1的旧驱动当成SDK2用了,或者设备SN没有正确识别。
有/livox/lidar但没看到/livox/imu:mid360的IMU数据默认是开启的,但确认一下驱动的launch文件里是否设置了IMU使能的参数,有些版本的驱动默认关闭IMU输出。没有IMU数据的话,FAST-LIO2根本起不来。
建图时点云抖动、重影:优先检查time_sync_en是否打开,以及外参配置是否正确。用内置IMU就保持单位阵加在线估计,千万别随便填一个自己量出来的数,填错比不填更可怕。
rz/rviz里点云位置固定不变,不随雷达移动:说明FAST-LIO2没收到IMU数据,或者算法没在运行。看终端的输出是不是卡在初始化阶段。
地图整体漂移:这种情况多半是运动太快或者环境太单调(比如对着白墙反复平移)。mid360的非重复扫描特性已经能提供足够的特征了,如果还是漂,把移动速度放慢,或者检查IMU的坐标系方向是否配置正确。
5.3 扩展讨论:双雷达融合与倾斜安装坐标对齐
很多人在search的时候会关注两个进阶话题:一台机器人装两个mid360,以及把mid360倾斜安装时怎么对齐坐标系。这里我把自己了解的情况说一下,方便你评估这两个方向。
关于双雷达融合,FAST-LIO2官方原生代码是单激光雷达+IMU的结构,不支持直接输入两台雷达的点云。想要做双雷达建图,常见的做法有两种:一是用两个mid360各跑一套驱动,发布两个点云话题,然后在上游做点云拼接,把拼接后的点云作为一个话题喂给FAST-LIO2,但这样时间同步和外参标定的工作量非常大;二是直接选用原生支持多雷达的开源LIO方案,比如STAR-LIO这类多LiDAR+IMU的紧耦合系统,它从设计上就支持多台雷达,省去自己拼接的步骤。
如果你确实要做双雷达,我的建议是先跑通单雷达的FAST-LIO2,把坐标系、外参、时间同步这些概念都理清楚了,再上多雷达方案。不然两个雷达之间的相对外参没标定好,融合出来的地图肯定是散的。
关于倾斜安装坐标对齐,这里要澄清一个概念:FAST-LIO2使用的外参是雷达坐标系到IMU坐标系的变换。如果你用的是mid360内置IMU,那么无论你把雷达横着装、竖着装还是45度斜着装,雷达和那颗内置IMU之间的相对位姿都是不变的,所以严格来说不需要改配置文件里的外参。算法输出的位姿是相对于起始状态的,地图本身不会因为倾斜安装而发散。真正需要改坐标系变换的场景是,你想把建图结果对齐到车辆坐标系,比如轮式机器人上一台mid360斜着装在车前部,这种情况下建图结束后需要做一个固定的坐标变换,把里程计轨迹转换到车体系。
另一个容易混淆的点:如果接的是外置IMU,比如vins或者ins,那雷达和IMU之间的外参就需要精确标定,倾斜安装会放大标定误差,这时候不能再用单位阵或者手工量,必须用标定工具跑一遍数据。
5.4 我踩过的一个坑:盲目升级CMake
最后分享一个我自己踩过的坑。有一阵子在Ubuntu 18.04上部署,为了满足Livox-SDK2的CMake版本要求,我直接removed系统自带的CMake,然后从源码编译装了新版CMake。结果装完之后,系统里一大堆依赖老版本CMake的软件全都不干活了,rosdep、catkin全都异常,最后只能重装系统。
后来我学乖了:要么直接用pip install --user cmake装一个用户态的新版CMake,要么用apt源里提供的backport版本,绝不贸然替换系统自带的CMake。这个教训我一直记着,也希望看到这里的朋友别再踩一遍。
按照我的经验,如果你用的是Ubuntu 20.04 + Noetic这套组合,其实压根不需要折腾CMake,系统默认版本就够用。版本选对,环境干净,这整套流程跑下来比想象中要顺很多。
本文还有配套的精品资源,点击获取