我陆续见过不下二十个拿着Livox Avia的初学者,卡在FAST-LIO2这个组合上,问题都差不多:环境装不明白、launch文件不知道改哪个、外参乱填一通、跑起来地图像揉皱了的纸。索性这次我用一篇“麻瓜也能照抄”的教程,把从装系统到拿到一张干净点云地图的全过程,逐步拆开讲,每一步都写清楚为什么这么做、哪里会踩坑,照着操作基本不会跑偏。
这套组合适合谁?刚接触激光惯性SLAM的学生、准备给机器人配建图方案的硬件工程师,或者只是想把手里的Avia“盘活”的折腾党。FAST-LIO2是目前对Livox这种非重复扫描雷达最友好的开源框架之一,它不需要你前期做复杂的特征提取,配置得当以后,基本就是“雷达转一圈,地图自己出来”。但所谓“配置得当”,恰恰是大多数教程没讲透的部分。下面我从头捋一遍。
1. 先搞清楚这三样东西各干什么
1.1 Avia、FAST-LIO2、你的电脑,分别承担什么角色
Livox Avia是一台固态激光雷达,它不像传统机械雷达那样靠电机旋转扫描,而是通过棱镜反射激光束,在视场角内逐点扫描,形成一种“非重复扫描”的花瓣式点云。这种模式的优点是随着时间累积,视场覆盖率会越来越高,非常适合机器人感知和建图。缺点也很明显:点云没有规整的线束结构,传统基于特征提取的LOAM类算法很难直接用,你很难从一帧不规整点云里稳定提取角点和面点。
FAST-LIO2正是为这类问题出现的。它来自香港大学MaRS实验室,核心思路是把IMU数据与激光雷达点云放进一个迭代卡尔曼滤波器(IEKF)里做状态估计,同时因为不再显式提取特征而直接使用原始点云,对于Livox这种扫描方式几乎称得上“天生适配”。它还有一项很实用的能力:在运行中在线估计雷达与IMU的外参,这就大大降低了对精准标定的依赖。
你的电脑则负责把这两者串起来:通过网线接收雷达数据,通过驱动把点云和IMU数据发布成ROS话题,再喂给FAST-LIO2进行状态估计和建图。这里有一个常常被忽略的物理前提:雷达的数据走的是网口,IMU走的是雷达内部串口/总线,二者都由驱动打包发布,你不需要单独接一根IMU线。
1.2 做这件事之前,你应该准备的硬件和软件清单
硬件方面,最简单的配置就是一台Livox Avia、一根六类网线、一台能跑Ubuntu的电脑,以及一个给雷达供电的电源。Avia的供电通常是12V DC,很多套件会附带电源适配器,如果没有,记住功率至少达到10W,插头上也别用劣质降压模块,不然建图到一半雷达重启会非常崩溃。
我个人强烈建议:新手老老实实用Ubuntu 20.04 + ROS Noetic这个组合。倒不是说18.04不行,而是20.04的库版本更宽容,教程也多,遇到问题搜索时看到的基本都能对上号。如果你的电脑是Windows,先用虚拟机装Ubuntu也行,但注意给虚拟机至少分配2个CPU核心和4GB以上内存,网卡要选桥接模式让雷达能直接访问到物理网口。
软件清单大致是:Ubuntu 20.04系统、ROS Noetic、PCL点云库、Eigen矩阵库、livox_ros_driver2驱动、FAST_LIO源码,以及一个RViz可视化工具。这些在后面两步里会一一安装。
2. 环境搭建:网上很多教程省略的“为什么”
2.1 ROS与基础依赖的安装,一次到位
ROS Noetic安装就不展开讲了,官方文档和社区教程非常多。装完ROS后,建议立刻装齐FAST-LIO2需要的依赖:
sudo apt update sudo apt install libeigen3-dev libpcl-dev libyaml-cpp-dev sudo apt install ros-noetic-pcl-ros ros-noetic-cv-bridge ros-noetic-tf2-geometry-msgs为什么要装Eigen和PCL?FAST-LIO2的滤波器里大量使用矩阵运算,Eigen是C++最常用的线性代数库,PCL则负责点云的存储、滤波和可视化。yaml-cpp用来读取参数文件,也就是你在config目录下看到的那些yaml配置文件。cv-bridge是ROS图像消息和OpenCV图像之间的转换桥,虽然在纯雷达建图里用得不多,但很多源码编译时仍会引用相关的头文件,索性一并装上,省得编译时报一堆缺失。
安装完成后,建议验证一下Eigen版本:
pkg-config --modversion eigen3输出3.3.7以上基本就没问题。如果系统里同时存在多个Eigen版本,FAST-LIO2编译时可能因为头文件路径混乱而报错,这种情况需要用find_package(Eigen3 REQUIRED)来显式指定版本,不过新手很少碰到,只要不是自己手动从源码装过Eigen,一般系统默认就够用。
2.2 拉取FAST-LIO2源码并完成首次编译
开始之前,需要创建一个catkin工作空间。catkin是ROS的构建系统,你可以简单把它理解为ROS的“CMake工程管理器”。
mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone https://github.com/hku-mars/FAST_LIO.git注意FAST-LIO2的GitHub仓库名为FAST_LIO,不是FAST_LIO2。仓库里包含几个子模块,需要初始化更新:
cd FAST_LIO git submodule update --init --recursive子模块是源码里引用的一些第三方工具库,比如ikd-Tree,不更新的话编译会报找不到头文件。接下来编译整个工作空间:
cd ~/catkin_ws catkin_make source devel/setup.bash如果第一次编译就顺利通过,恭喜你,运气很好。但多数人在这里会遇到至少一个编译错误,我下面单独列了几种最常见的情况。
2.3 编译过程中常见的“三连坑”及解决思路
第一个坑:找不到livox_ros_driver2或者livox_ros_driver。FAST-LIO2的CMakeLists会在源码树中查找Livox的驱动包,如果你只克隆了FAST_LIO而没有克隆驱动,编译时必然报错。解决办法是把livox_ros_driver2一起克隆到src目录下,放在FAST_LIO旁边:
cd ~/catkin_ws/src git clone https://github.com/Livox-SDK/livox_ros_driver2.git cd ~/catkin_ws catkin_make第二个坑:Eigen3对齐宏报错。这类错误通常出现在使用Eigen新版3.4.x且编译选项开启AVX指令集时,报错信息里会出现EIGEN_MAKE_ALIGNED_OPERATOR_NEW之类的字样。解决办法是在FAST_LIO的CMakeLists.txt中添加编译宏-DDISABLE_AVX,或者直接关闭Eigen的新对齐特性。有的版本还需要在cmake之前先清理一下旧的构建缓存。
第三个坑:yaml-cpp版本不匹配导致运行时报错。有些操作系统的软件源自带yaml-cpp 0.6,而仓库源码是按照0.8编写的,运行时会直接退出并打印YAML解析失败。解决办法是自己编译yaml-cpp 0.8.0并安装到系统目录,或者干脆用vcpkg管理依赖。这类问题报错信息不一定直观,我建议如果遇到YAML::Detail相关报错,优先怀疑yaml-cpp版本。
我根据实际经验整理了一个编译问题速查表,后面会放在第6节里统一讲。
3. 让电脑“看见”雷达,网络配置不能偷懒
3.1 配置雷达的静态IP,保证驱动能找到它
Livox Avia默认使用固定IP与电脑通信,出厂的网口IP一般是192.168.1.12(不同批次可能不同,建议查看说明书或Livox Viewer显示)。电脑端需要配置成同一网段下的IP,比如192.168.1.50。
Ubuntu下可以通过图形界面设置,也可以直接用命令行:
sudo ip addr add 192.168.1.50/24 dev eth0这里eth0要换成你的网卡名称,可以用ip addr查看。如果网卡名称是enp3s0,把eth0改成enp3s0即可。这种即时配置在重启后会失效,新手阶段图省事没问题,长期用建议写到/etc/netplan/配置里做成静态IP。
配置完IP后,给雷达上电,等待约10秒,然后启动livox_ros_driver2的Rviz可视化launch:
source ~/catkin_ws/devel/setup.bash roslaunch livox_ros_driver2 rviz_HDR.launch如果一切正常,Rviz中会出现雷达点云画面,此时说明驱动链路已经跑通。如果画面是空的,先检查网络连通性:
ping 192.168.1.12能ping通说明网络正常,接下来排查供电和驱动参数;ping不通,先查网线、网口和IP本身。
3.2 确认数据话题在发布:rostopic是关键指令
如果想确认FAST-LIO2能否拿到数据,建议额外开两个终端,输入:
rostopic list rostopic hz /livox/lidar rostopic hz /livox/imuAvia的点云话题默认是/livox/lidar,IMU话题默认是/livox/imu,这是FAST-LIO2默认订阅的名字。rostopic hz会周期性打印话题发布频率,正常情况IMU频率在200Hz左右,点云频率在10Hz左右。如果看到频率为0,检查驱动是否真正在运行、话题名是否一致。
这一步很重要。很多人在写yaml参数时把话题名改成了/livox/points,导致FAST-LIO2一直收不到数据,map迟迟不更新,还以为是算法问题。这里我特别说明:不同版本的驱动发布的话题名不同,老版本驱动可能是/livox/lidar,新版驱动也可能是/livox/lidar,但有人改过配置后就变了。最稳妥的方式是先看rostopic list实际输出了什么,再去订正FAST-LIO2的参数文件。
3.3 关于Livox Viewer:调试雷达本身用它,建图过程不必开
Livox Viewer是Livox官方的点云查看工具,可以帮你确定雷达本身是否异常、查看扫描角度和点云质量,也能顺便读取雷达的序列号和固件版本。如果你的IP配置没问题,但ROS驱动始终连不上雷达,打开Livox Viewer看看是不是设备自身报错。多数情况下,驱动能连上就不需要再开Viewer了,它和ROS驱动同时连接雷达可能造成端口冲突。
4. 参数与外参:建图稳不稳的关键
4.1 理解雷达到IMU外参:先填初值,后续再修正
FAST-LIO2融合的是IMU数据和激光点云,所以必须知道IMU坐标系和雷达坐标系之间的变换关系。如果你的Avia没有外接扩展板、使用的是雷达内置IMU,那么物理上IMU与雷达外壳的相对旋转很接近零,外参可以近似填成单位阵:
extrinsic_T: [0.0, 0.0, 0.0] extrinsic_R: [1, 0, 0, 0, 1, 0, 0, 0, 1]如果你手上是别人改装过的雷达,比如把IMU单独用双面胶贴在雷达外壳上,那外参就不能用单位阵了,需要在两个传感器之间量出相对位置和安装角度。但有个好消息:FAST-LIO2支持在线外参估计,把extrinsic_est_en设置成true,它会随着建图过程不断修正外参,你只要给它一个不太离谱的初始值就够了。
这里有一个“麻瓜”建议:第一步先用单位阵跑通,等能看到地图之后,再去关心外参优化。很多入门者一上来就拿着各种标定工具折腾外参,结果还没见过正常地图长什么样就放弃了。先让系统跑起来,再逐步精调,是接触这类算法时最省心的策略。
4.2 avia.yaml参数逐项拆解,别让默认值背锅
FAST_LIO源码里的config目录下有多个yaml文件,Avia对应的通常是avia.yaml。打开这个文件,你会看到类似下面的关键参数:
common: lid_topic: "/livox/lidar" imu_topic: "/livox/imu" preprocess: blind: 0.5 scan_line: 6 dis_compensation: true mapping: max_iteration: 3 point_filter_num: 4 filter_size_surf: 0.5 filter_size_map: 0.5 extrinsic_est_en: true我用“人话”解释一下这几个参数:
blind:雷达盲区半径,即距离雷达太近的点直接忽略。Avia的近距离点云容易受外壳反射干扰,设成0.5米左右比较合理。如果你拿给机器人用,盲区设大一点反而安全,设成1米问题不大。scan_line:扫描线数。Avia是6线,mid360是3线,这个参数影响点云的组织方式,不要随便改。dis_compensation:是否做运动畸变补偿。如果你的平台移动速度快,建议保持true,否则点云会像果冻一样扭曲。point_filter_num:抽稀间隔,每N个点保留一个。这个值越小,点云越密,地图越精细,但计算也更重。Avia默认常用4,如果你觉得CPU占用过高,可以调到5或6。filter_size_surf和filter_size_map:局部地图和全局地图的体素滤波尺寸,单位米。值越小地图细节越丰富,但对噪声越敏感。想快速建图可以先保持默认,后续再根据效果微调。extrinsic_est_en:是否开启外参在线估计,建议先保持true。
4.3 初始化那几秒,直接决定建图成败
FAST-LIO2是基于IMU惯导递推和激光点云匹配的紧耦合系统,启动初期需要“把状态激活”:因为滤波器的初始位姿和速度都不知道,必须靠IMU的加速度和角速度激发出可观测的约束。我测试过很多次,正确的做法是:启动节点后,等待RViz中出现第一幅点云,然后把手持设备拿在手里做缓慢的“8”字形摇晃,持续5到10秒,等终端开始打印里程计信息(类似Odometry ...的调试输出)之后,再开始按你规划的路径移动。
这里有一个很反直觉的注意点:不要等雷达静止超过3秒。很多人习惯启动后,先放在桌面上等地图“加载”,结果IMU零偏还没估出来就停着,系统状态很容易坐到错误的收敛点。更不要一上来就快速旋转雷达,那样IMU角速度瞬间饱和,滤波器容易发散。
另外,如果你的终端里出现类似[WARN] PointCloud has too few points的提示,说明点云数量太少,大概率是盲区设置过大或雷达离墙太近,把盲区调小一点即可。
5. 完整建图实操:从启动到保存一张地图
5.1 一套不会出错的启动顺序
我建议你养成“三个终端,按顺序执行”的习惯,这样每次都能快速定位问题:
第一个终端,启动雷达驱动:
source ~/catkin_ws/devel/setup.bash roslaunch livox_ros_driver2 msg_AVIA.launch第二个终端,启动FAST-LIO2:
source ~/catkin_ws/devel/setup.bash roslaunch fast_lio avia.launch第三个终端,用于查看话题状态和必要时保存地图:
source ~/catkin_ws/devel/setup.bash rostopic hz /livox/lidar注意:有的FAST_LIO版本在avia.launch里已经包含了启动驱动的node,你查看launch文件如果看到livox_ros_driver2_node,说明不需要手动启动驱动。判断方法很简单,看第二个终端启动后,雷达是否有点云数据输出、有没有报错找不到话题。launch文件里默认的RVIZ配置一般会弹出一个RViz窗口,选择FastLIO的固定坐标系就能看到雷达运动轨迹和地图增量。
5.2 建图过程中的操作节奏与距离把控
实际操作时,我一般这样走:先把设备举到膝盖高度,缓慢走一个“8”字初始化;等到终端打印出里程计信息后,开始沿着走廊或房间边缘移动,移动速度保持在0.3到0.8米每秒,转弯的时候尽量平缓。扫室内环境时,尽量让雷达能看到天花板和地面交界处,这样能为地图提供足够的垂直约束。扫室外时,避免对着太阳方向猛拍,Livox的红外点云在强阳光下会有噪点,地图上会出现一撮一撮的“花点”。
整个过程如果看到RN-RANSAC或者ICP的残差突然猛增、地图开始拖影,不要慌,放慢速度、原路退回刚才的位置,系统通常会重新收敛。这是因为FAST-LIO2面对突然的大范围旋转时,匹配退化,回到原有区域后约束恢复,漂移能被慢慢拉回来。
5.3 保存地图与格式转换,自己留着也能给别人用
建图结束后,保存地图有好几种方式。最直接的是启用源码中的自动保存功能。运行FAST-LIO2的那个终端里,如果代码打印了类似“S to save pcd”的提示,按住键盘上的s键,它会自动把当前地图保存成PCD文件。保存位置一般在~/.ros/目录,文件名通常是scans.pcd,保存过程中会刷新进度。
如果你更习惯用参数控制,可以打开README里提到的pcd_save_enable,把它设为true,节点在退出时会自动保存。不管哪种方式,保存后都建议用命令查看一下文件大小:
ls -lh ~/.ros/scans.pcd生成的点云默认是二进制PCD格式,可以用CloudCompare直接打开。如果你想转成PLY用于其他软件,PCL提供现成工具:
pcl_pcd2ply ~/.ros/scans.pcd scans.ply如果只是想快速抽稀,也可以使用PCL的pcl_voxel_grid工具。对地图精度有要求的场合,我建议在保存前先停止移动设备并静止5秒,这样最后一帧点云和地图匹配更充分,输出文件不容易带着尾巴。
6. 常见问题排查:照着表找问题,能省半天时间
6.1 驱动连不上雷达,问题多半在网络和供电
这是所有坑里出现频率最高的。我把常见现象和排查方向整理成表格,方便直接对照。
| 现象 | 可能原因 | 排查与解决 |
|---|---|---|
| ping不通192.168.1.12 | 网口没配置同一网段 | 检查IP地址是否192.168.1.x,网线是否牢靠 |
| ping通但驱动找不到设备 | 雷达被Livox Viewer占用 | 关闭Viewer,重新启动驱动节点 |
| 驱动间歇性断开 | 供电功率不足 | 换12V独立电源或带载更大的电源适配器 |
| 有设备但话题无数据 | lidar_type与型号不匹配 | 确认launch里是msg_AVIA.launch而不是mid360的launch |
这里补充一个细节:livox_ros_driver2里,不同雷达型号的launch文件不一样,Avia用的是msg_AVIA.launch,mid360用的是msg_MID360.launch。如果你拿的是mid360却启动了Avia的配置,驱动一般也能启动,但是点云频次、FOV特征处处不对,提前排查看起来最像参数错误。
6.2 编译期报错的速查对策
| 报错关键信息 | 原因 | 解决办法 |
|---|---|---|
| No such file: livox_ros_driver2/common.h | 缺少驱动源码 | 将livox_ros_driver2克隆到src目录后重新编译 |
| Could not find yaml-cpp | 缺少yaml-cpp库 | sudo apt install libyaml-cpp-dev |
| EIGEN_MAKE_ALIGNED_OPERATOR_NEW | Eigen版本/对齐问题 | 在CMakeLists中加-DDISABLE_AVX或更换Eigen版本 |
undefined reference to... | 多个ROS版本环境冲突 | 确认source的是Noetic的setup.bash,重启终端重试 |
遇到编译错误时,先看第一个错误,不要盯着最后几行崩溃信息。CMake/Make的错误列表通常会很长,但根因往往在最上方。
6.3 建图质量不理想,先别急着换算法
很多人在地图出现漂移后,第一反应是换LOAM、换LIO-SAM,结果问题根本没解决。我个人经验是:地图质量差,优先检查四个方向。
一是初始化是否充分。正确的做法是启动后慢慢“8”字晃5秒以上,让滤波器的IMU零偏、速度和重力方向都收敛。二是外参初始值是否离谱。如果雷达和IMU坐标系差了几十厘米,单位阵初始值会直接导致匹配发散,在线外参估计也无法拉回。三是雷达盲区和抽稀参数是否合适。盲区太大会丢近距离约束,抽稀太高会让地图密度不够。四是移动速度与场景复杂度是否匹配。纯走廊场景下,几何约束不足,漂移在长轴方向几乎是必然的,尽量增加环路,走回起点形成闭环。
7. 如果你手上是mid360,这套方法只需改三处
最近“mid360使用fast-lio建图”被问得特别多,这里单独说一嘴。mid360跟Avia的核心逻辑完全一样,区别在FOV和点云参数。mid360的水平视场是360度,竖直视场大约59度,盲区只有0.1米,比Avia更适合室内的移动机器人底盘。
在FAST-LIO2里用mid360,主要改动三处:第一,launch文件换成mid360对应的版本;第二,yaml里的scan_line从6改成3,blind从0.5改到0.2左右;第三,point_filter_num可以调小到2,因为mid360的单帧点云本来就不多,抽稀太狠会让地图非常稀疏。
驱动那边也一样,用livox_ros_driver2启动mid360对应的launch,话题名同样确认是/livox/lidar和/livox/imu。配置好后,启动、初始化、建图的操作方式与Avia完全一致,你在这一套教程里学会的思路可以直接迁移过去。
最后分享一个实操心得:我第一次用FAST-LIO2时也卡了两天,后来发现大部分时间都花在驱动和编译上,真正的调参只占了半小时。现在你拿到这套“麻瓜教程”,如果还遇到奇怪的问题,建议记一下启动时的完整日志,尤其是WARN、ERROR、FATAL开头的关键词,这些是快速定位问题的钥匙。我自己的习惯是每次调试只改一个参数,改完跑一遍看效果,别同时动三个参数,不然出了问题都不知道是哪一步引入的。祝你们少走弯路,早日建出干净漂亮的地图。