ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

FAST-LIO2激光SLAM实战:从原理到部署的完整指南

FAST-LIO2激光SLAM实战:从原理到部署的完整指南 激光SLAM圈子里FAST-LIO2最近几年是绕不开的名字。它出自香港大学火星实验室MARS Lab全称是FAST-LIO2: Fast Direct LiDAR-Inertial Odometry一套把激光雷达和IMU紧耦合在一起的里程计与建图框架。相比上一代和同期方案它在计算效率、鲁棒性和地图维护上都有明显优势很多机器人、自动驾驶项目里都能看到它的影子。这篇文章不是抄官方README而是从实操角度带你把FAST-LIO2从零跑起来先拆核心原理再走一遍环境搭建、官方数据集测试、关键参数调优最后整理编译和运行中我踩过的坑顺带聊聊源码阅读顺序和求职面试常见考点。无论你是刚配好ROS环境的学生、准备SLAM岗位面试的候选人还是想把FAST-LIO2用到自己机器人上的工程师这篇都值得收藏。1. 项目全貌与核心原理拆解1.1 FAST-LIO2到底解决了什么问题先打个比方。你闭着眼睛走路手里拿着一个高精度激光测距仪脚下踩着惯性传感器。光靠激光测距只能知道“周围墙在哪”光靠惯性传感器很快会漂得找不到北。FAST-LIO2干的事就是让这两种信息互相纠偏用激光点云去校正IMU的累积漂移用IMU的短时预测去补偿激光雷达运动造成的畸变在每一帧新点云到来时都保持一个全局一致的姿态估计。这套东西最打动我的一点是“直接法”。传统LOAM系方案会先从点云里提取角点、平面点这类特征再做特征配准。问题在于到了走廊、隧道、空旷场地这种低纹理场景特征点很容易不够用退化问题就来了。FAST-LIO2不做特征提取把原始点云直接丢进配准流程配合体素降采样控制计算量在结构退化环境中也能咬住位姿。而且它还顺手做了一件事维护一个增量式地图而不是只保存一小段局部窗口。所以跑完一段数据你不仅能得到轨迹还能直接得到一张可用的点云地图这对后续导航、路径规划非常友好。1.2 三个关键技术点ikd-Tree、直接法配准、迭代ESKF第一个要认识的是ikd-Tree。理解它的最好方式是和普通KD-Tree对比。普通KD-Tree建好之后如果往地图里加了新点通常的做法是重新构建整棵树复杂度高即便在某些实现里用“懒删除”标记失效节点树的平衡性也会慢慢变差。ikd-Tree做的是增量更新只把真正受影响的那部分节点重新平衡删除的点也采取并行懒惰标记、后台回收的策略。结果就是维护一个几十万、上百万点的全局地图单帧更新的开销远小于重建整棵树。第二个是直接法配准。代码里最核心的步骤是把当前帧的每个体素降采样点和地图里最近的面元做距离残差计算。它不关心这个点到底属于墙面还是地面只关心“点到面距离”够不够小。正因为不挑特征才扛得住走廊、空地这类场景。第三个是迭代误差状态卡尔曼滤波器IESKF/ESIKF。它把IMU预积分作为状态预测把点云配准得到的残差作为观测更新在一个迭代框架里反复修正状态。这样一来即使初始化误差较大也能在几个迭代周期内收敛。很多初学者问我“EKF和这个有什么区别”简单说EKF假设观测和状态是线性或弱非线性关系做一次线性化就完事FAST-LIO2的迭代策略相当于把高斯牛顿优化嵌进滤波更新里多轮改进线性化点精度和鲁棒性都更好。1.3 和其他主流方案怎么选方案配准方式地图维护传感器要求适用场景LOAM特征点角点平面点局部地图机械式雷达结构化环境LIO-SAM特征点因子图局部地图回环激光IMUGPS可选有较多特征的环境FAST-LIO1特征点局部地图激光IMU低算力平台FAST-LIO2直接法原始点云ikd-Tree全局地图激光IMU退化场景、低成本传感器直观感受是LIO-SAM工程化程度高、回环和GPS融合方便适合小范围慢速机器人FAST-LIO2更适合追求轻量、快速、场景多变的平台。它还有一个隐藏优势就是对LiDAR型号兼容性广固态雷达、机械雷达都能接。我自己在室内小车上用FAST-LIO2跑低速数据稳定性明显比纯LOAM系好。2. 环境准备与依赖搭建2.1 先确认系统环境别在源上浪费时间FAST-LIO2官方默认是ROS1工程Ubuntu 18.04配ROS Melodic、Ubuntu 20.04配ROS Noetic是两条最成熟路线。我建议优先用Ubuntu 20.04 ROS Noetic库版本比较新踩坑少。如果你手头是Ubuntu 22.04也能跑但需要自己编译更高版本的PCL和Eigen代价是编译时间变长、错误变多新手不建议一上来就挑战。硬件方面i5级别CPU、8GB内存起步比较轻松。官方数据集播放时单帧点云几万到十几万个点体素降采样开起来后CPU占用一般在单核到双核左右。虚拟机里能跑但实时性和Rviz流畅度会打折扣最好还是装双系统或独立Ubuntu机器。另外说一句这是一个C工程不要被“从零搭建”四个字吓到。你不需要自己写滤波器和数据结构只需要把依赖环境配好、会启动和调试就能跑通全流程。2.2 安装依赖库Eigen3、PCL、livox_ros_driver先安装基础编译工具和库sudo apt update sudo apt install git build-essential cmake libeigen3-dev sudo apt install ros-noetic-pcl-ros ros-noetic-pcl-conversionsEigen3建议直接用系统源里的版本FAST-LIO2对Eigen要求不算苛刻没必要手搓源码。PCL在ROS Noetic里已经作为依赖装好ros-noetic-pcl-ros会拉来大部分需要的头文件。比较关键的是livox_ros_driver。很多人编译FAST-LIO2本身一次通过但一跑bag就报“消息类型 livox_ros_driver/CustomMsg 不存在”原因就是这个驱动没有编译进ROS环境。FAST-LIO2官方数据集的点云消息类型往往带有livox雷达的自定义格式你必须先在工作空间里编译livox_ros_driver让消息定义注册到ROS里。cd ~/catkin_ws/src git clone https://github.com/Livox-SDK/livox_ros_driver.git cd ~/catkin_ws catkin_make source ~/catkin_ws/devel/setup.bash注意顺序问题建议第一次就把livox_ros_driver和FAST-LIO2放在同一个工作空间一起编译避免后面补编译导致devel环境混乱。新手最稳妥的做法是先只编译livox_ros_driver确认无报错后再拉FAST-LIO2源码一起编译。2.3 编译FAST-LIO2源码cd ~/catkin_ws/src git clone https://github.com/hku-mars/FAST_LIO.git cd ~/catkin_ws catkin_make源码拉下来后命名是FAST_LIO注意不是FAST-LIO2。编译前建议检查一下源码根目录的CMakeLists.txt里面会自动去找livox_ros_driver和PCL。如果电脑上装了多个Eigen版本CMake报“Eigen3 not found”或版本冲突可以在CMakeLists.txt里显式指定Eigen方向。编译过程中最常见的错误是找不到pcl_conversions/pcl_conversions.h或找不到livox_ros_driver2相关头文件。前者说明PCL相关包没装全后者说明livox_ros_driver没有提前编译成功。还有一类是C标准问题FAST-LIO2要求C14或C17如果你改了系统默认编译器可能出现一些模板报错可以检查源码里set(CMAKE_CXX_STANDARD 14)。编译成功后再提醒一句每次新开终端跑FAST-LIO2之前都要先source你的工作空间source ~/catkin_ws/devel/setup.bash echo $ROS_PACKAGE_PATH如果ROS_PACKAGE_PATH里没有你的工作空间路径直接launch会提示找不到包。3. 官方数据集完整测试流程3.1 下载官方bag数据包FAST-LIO2仓库的README里列了官方测试数据集下载链接一般包含室外校园、室内走廊、隧道等不同场景。每个bag里都同时包含了Livox雷达点云和IMU数据文件名类似HKU_Main Building.bag或HG_*.bag大小从几百MB到几个GB不等。下载后建议统一放在~/slam_dataset下方便后面播放。同时确认一下bag里的话题名用rosbag info ~/slam_dataset/xxx.bag重点看两个topic一个点云话题一个IMU话题。FAST-LIO2官方launch默认点云话题是/livox/lidarIMU话题是/livox/imu如果你下载的bag话题名不同后面需要改launch。官方数据集一般和默认配置严格对齐这也是“先跑官方bag再改自己的数据”这个经验的意义所在。3.2 启动launch文件并打开Rviz可视化启动建图进程roslaunch fast_lio mapping.launch正常启动后终端会滚动输出“... 当前里程计信息”同时自动打开Rviz。Rviz里如果提示坐标系找不到先在左侧Fixed Frame里改成camera_init这是FAST-LIO2使用的世界坐标系。第一次看到地图往外生长是很有成就感的。如果Rviz里没有点云显示检查Global Options的Fixed Frame再检查点云话题选择是否正确。FAST-LIO2会在Rviz中订阅它自己发布的/cloud_registered这个就是配准后的当前帧点云全局地图则通过/map_geneate不同版本话题名可能略有差别发布。看不到点云时不要急着怀疑程序先手动添加PointCloud2显示并把话题切到这些名字上往往立竿见影。3.3 播放bag并保存点云地图另开一个终端播放数据rosbag play ~/slam_dataset/xxx.bag默认播放速度是1倍速。如果你的电脑性能一般可以加-r 0.5用半速播放减少卡顿如果CPU占用过高导致Rviz界面卡顿也可以先-r 0.3慢速跑。跑完之后保存当前构建好的全局点云地图。FAST-LIO2的launch文件里一般配置了一个保存地图的服务在终端里执行rosservice call /save_map resolution: 0.1或者查看launch里是否设置了保存PCD的服务名常见的是/save_pcd。保存下来的文件通常是PCD格式可以用pcl_ros的工具转成其他点云格式rosrun pcl_ros pcd_to_pointcloud map.pcd如果你想要一份可视化方便、后续能直接用于导航的占据栅格地图通常还需要搭配pointcloud_to_laserscan这类工具做降维处理。不过这一步不是FAST-LIO2的核心先把PCD地图存下来后面再做下游处理。预期效果是室内场景墙体轮廓清晰点云厚度较小室外场景路面和建筑墙面都有明显结构。如果跑出来的地图糊成一片或轨迹飞掉八成是时间戳、话题、参数这三类问题下一节详细说。4. 核心参数调节从默认值到你的传感器4.1 launch文件里最值得改的四个参数用roscd fast_lio进入包目录打开launch/mapping.launch和config/下的yaml文件。这里最影响结果的有四组参数。第一降采样分辨率filter_size_surf。这个值决定了点云进入配准前按多大尺寸的体素网格降采样。数值越小保留点越多地图越精细但计算量、内存占用都显著上涨。官方数据集室内场景常用0.5如果你觉得地图稀疏可以下调到0.3但在低配电脑上可能卡顿。我自己的经验是先用默认值跑通再逐步改小观察CPU负载和地图质量。第二IMU噪声参数。yaml里acc_norm、gyr_norm、acc_cov、gyr_cov这些值直接对应IMU的测量噪声和随机游走。用官方数据集时没问题切到自己的IMU时如果数值差一个量级系统会非常敏感或过于迟钝表现就是轻微震动就被误判为运动或者反过来姿态更新极慢。理想方式是查IMU芯片手册填理论值再根据实际静置数据的Allan方差修正。第三外参初始化。extrinsic_T、extrinsic_R描述的是IMU在LiDAR坐标系下的安装位置和姿态。官方数据集里已经标好自己平台千万别跳过这一步。很多“地图发飘、轨迹飞掉”的案例最后查到都是外参差个几厘米、几度。第四最大迭代次数。IESKF迭代上限默认在源码里或参数文件里控制对高动态场景可以适当调大室内慢速场景默认值就够。4.2 雷达型号适配Livox和机械旋转雷达怎么处理FAST-LIO2默认使用livox_ros_driver自定义的livox_ros_driver/CustomMsg消息格式这也是官方数据集的默认格式。如果你用的是Livox系列编译好驱动、确认话题名一致即可。如果手里是Velodyne、Ouster这类机械旋转雷达输出的是sensor_msgs/PointCloud2就不能直接喂给默认流程了。需要在源码里做消息类型适配要么把机械雷达点云转换成Livox的自定义消息再发布要么把源码中的回调函数改成订阅PointCloud2并调整激光扫描编号、时间戳生成等字段。官方仓库和社区里都有一些适配版本但说实话自己从零改还是需要一点时间。新手建议先用官方Livox数据跑通全流程再考虑机械雷达适配否则会把“是不是我代码改错了”和“参数没调好”混在一起排查起来非常痛苦。4.3 我常用的调参顺序先固定外参和IMU噪声官方数据或标定结果只调降采样分辨率。跑通后再静置传感器看IMU噪声表现修正噪声参数。最后才动外参。如果一开始就同时改好几个变量系统发散了你根本不知道是哪一步引入的。5. 常见问题与排查技巧实录5.1 编译期问题livox头文件找不到错误现象编译FAST-LIO2时提示livox_ros_driver/CustomMsg.h: No such file or directory。原因基本是livox_ros_driver没有编译或没有source到当前环境。排查顺序是roscd livox_ros_driver如果能进入包目录说明包在环境里如果提示找不到回工作空间重新catkin_make并确认source ~/catkin_ws/devel/setup.bash。这里有一个小坑如果你在同一个工作空间里先编译FAST-LIO2、后添加livox_ros_driver有时需要删除build和devel目录重新编译一次否则ROS的catkin缓存不会自动把新包加进依赖树。另一个常见的编译问题是Eigen3版本冲突。系统装过多个Eigen版本时CMake可能找到旧版本。在CMakeLists.txt里显式指定set(EIGEN3_INCLUDE_DIR /usr/include/eigen3)通常能解决。5.2 运行期问题消息类型不存在与坐标系报错如果你已经成功编译但rosbag播放过程中终端报错说找不到消息定义十有八九是当前终端没有source带livox_ros_driver的工作空间或者bag是在不同ROS版本下录制的。还有一种情况是bag中的点云消息类型是标准PointCloud2而你launch的FAST-LIO2期望的是CustomMsg类型对不上。Rviz报坐标系问题比如 “No transform from [livox_frame] to [camera_init]”要看两处。一是launch文件中是否有静态坐标变换发布节点FAST-LIO2官方launch通常会发布camera_init到body的静态变换二是bag里本身是否有tf数据。官方数据集完整播放基本不会有tf问题反而是只播放部分bag、没有播完整段tf时会出现。5.3 地图发飘、轨迹飞掉按这个顺序查定位发散是最打击信心的问题。我的排查顺序固定是时间戳、话题频率、外参、IMU噪声。先用rostopic hz /livox/lidar和rostopic hz /livox/imu检查频率Livox雷达一般10Hz左右IMU在200Hz附近看具体型号。如果话题频率忽高忽低先怀疑CPU过载再用-r 0.3慢速播放重试。再检查bag中IMU和雷达的时间戳是不是同一时钟源。不少数据集录制时IMU和雷达时间同步做得很随意导致预处理阶段时间对齐错位表现就是第一帧过后轨迹立刻飞走。官方数据集同步质量较好如果你的数据出现这种问题优先确认时间同步链路。外参问题的特征是低速下地图勉强能用速度一高或者转角一大就开始拖尾、双影。可以用标定工具重新标定或者先用手册里的安装尺寸做粗标定观察是否量级对得上。5.4 问题速查表现象可能原因处理方法编译报livox头文件缺失驱动未编译/未source在同一工作空间编译livox_ros_driver重新source编译报Eigen版本冲突多版本Eigen在CMakeLists中显式指定include路径launch找不到fast_lio包未source工作空间执行source命令检查ROS_PACKAGE_PATHbag播放时消息类型不存在ROS环境缺少livox消息定义确认livox_ros_driver成功进入devel环境Rviz无点云显示Fixed Frame错误/话题错切换Fixed Frame检查/cloud_registered话题地图漂移或飞掉时间戳、外参或IMU噪声问题先检查频率再查外参最后修噪声参数内存占用快速上涨filter_size_surf过小调大降采样分辨率或限制地图范围CPU过载卡顿单帧点云过多降低播放速率、增大体素降采样尺寸6. 从FAST-LIO2延伸源码阅读、工程落地与求职6.1 源码阅读顺序建议跑通官方数据集之后推荐按这个顺序读源码先读laserMapping.cpp的主循环理解一帧点云进来后经历了哪些阶段再读预积分和迭代ESKF部分最后再啃ikd-Tree。读主循环时把注意力放在几个关键函数上点云预处理、状态预测、点云配准迭代、地图更新。配准迭代是核心可以看到它如何把当前帧点云变换到世界系、找最近邻、计算点到面的残差、更新位姿增量。ikd-Tree部分比较硬核我自己的方法是先把它当成黑盒了解对外接口是“支持增量增删点、支持范围搜索、支持盒式搜索”等整体流程理解后再抠内部重新平衡逻辑。对准备SLAM面试的人来说这些阅读经历是最硬核的项目经验。不要只背概念能把FAST-LIO2从“收到一帧点云”到“更新地图”的全链路讲清楚说服力远大于背标准答案。6.2 迁移到自己的机器人平台要做到“换LiDAR、换IMU也能跑”关键三步改点云话题、标定外参、校正IMU噪声参数。其中外参标定最容易忽略。即便你把LiDAR和IMU固定在一个刚性支架上也需要确认三个旋转角和三个平移量。可以借助开源标定工具也可以先手工量一个粗略值再观察地图效果微调。如果你想在嵌入式平台比如RK3588这类ARM板上跑要提前做好心理准备FAST-LIO2的ikd-Tree在ARM上编译没有问题但点云配准的实时性和内存占用需要实测。我的经验是先用本机跑通再交叉编译到ARM板分两步推进别一上来就往板子上搬。另外官方版本目前基于ROS1如果你计划在ROS2环境部署需要自己移植或者找社区维护的ROS2分支。移植的关键点是话题类型、tf和时间同步接口的改动不是所有代码都要重写但工作量和调试成本确实不低。6.3 SLAM面试高频考点延伸招聘市场对SLAM工程师的要求越来越看重“原理工程”两条腿走路。FAST-LIO2最适合用来准备高频考点。比如“EKF和IESKF有什么区别”你可以从滤波更新中引入了迭代优化这个角度答强调状态更新不再是单步线性化而是多轮迭代后的收敛解。再比如“ikd-Tree相对于KD-Tree的改进”要说到增量更新、并行懒惰删除和自动再平衡并说明它如何降低全局地图维护的代价。再比如“为什么直接法配准比特征法抗退化”可以从特征点在低纹理场景中信息量不足这个痛点切入。这些点全部来自FAST-LIO2源码本身读懂了就是实打实的积累。建议准备面试时专门把FAST-LIO2的管线画一遍能对着图从头讲到尾基本就过关了。说句实在话跑通FAST-LIO2只是第一步真正值钱的是跑通之后你愿意花多少时间把源码一层层剥开。我自己第一次编译通过加跑完bag大概用了一个周末但理解ikd-Tree更新逻辑和理解IESKF迭代过程是接下来好几个晚上反复读代码才慢慢啃下来的。这里分享一个小习惯每读一个函数就在旁边用注释写一句“这个函数在解决什么痛点”等整个文件注释完你就会发现自己对SLAM工程的理解上了一个台阶。搞机器人这行慢就是快这套框架值得你投入时间。
返回列表