
激光SLAM这块FAST_LIO系列算是这两年被讨论得最多的方案之一。我最早接触它是在一个手持建图的项目里当时用LOAM系列跑室内走廊漂移和实时性都不太理想后来换到FAST_LIO同样的数据跑下来轨迹闭合明显好了不少。但说实话从零把环境搭起来、把两个版本都跑通、再做出有意义的对比中间踩的坑远比想象中多——依赖版本冲突、点云话题对不上、外参标定偏差、地图保存格式不兼容每一个都能卡你半天。这篇就把我从头搭FAST_LIO和FAST_LIO2的完整过程、两个版本的核心差异、以及实测下来的性能表现按我自己的操作顺序讲清楚。适合刚上手激光惯性里程计、想快速跑通并理解背后逻辑的朋友也适合已经在用但想搞清楚两个版本到底差在哪的人。1. 先把FAST_LIO和FAST_LIO2的定位搞清楚动手之前得先明白这两个东西是什么关系不然很容易在选型上走弯路。很多人以为FAST_LIO2是FAST_LIO的简单升级版直接装新的就行实际上两者的设计目标和适用场景有明确区别。1.1 两个版本共享的核心思路FAST_LIO全称是Fast LiDAR-Inertial Odometry本质是一个紧耦合的激光惯性里程计。它把激光点云和IMU数据放在一个统一的迭代扩展卡尔曼滤波框架里做状态估计而不是像早期一些方案那样先做激光里程计再和IMU松耦合。紧耦合的好处是IMU的高频输出能在激光帧间隔内持续约束姿态激光帧到来时又反过来修正IMU的漂移两者互相兜底。它最核心的一个设计是直接法配准。传统LOAM系列会先提取角点和面点特征再拿特征去做匹配特征提取这一步本身就丢信息而且在结构化程度低的环境里比如树林、空旷场地特征提取质量很差。FAST_LIO跳过了显式特征提取直接用原始点云构建残差配合它自己维护的ikd-Tree增量式kd树做最近邻搜索。ikd-Tree支持增量插入和删除地图更新时不用重建整棵树这是它能做到实时的一个关键。1.2 FAST_LIO2到底改了什么FAST_LIO2在第一个版本基础上做了几处实质性改动我按影响程度排一下。第一是配准残差模型的调整。FAST_LIO2引入了更细的点面残差处理方式对平面点的判定更严格在退化场景比如长直走廊、隧道里的鲁棒性有提升。我实测在一条约80米的直走廊里FAST_LIO跑下来末端有可见的横向漂移FAST_LIO2明显收敛得更好。第二是对固态激光雷达的适配。FAST_LIO2在代码层面更好地支持了非重复扫描模式的雷达比如一些中短距固态雷达点云组织方式和运动补偿逻辑都做了对应处理。如果你手上是这类雷达直接上FAST_LIO2更省事。第三是地图管理和内存占用。FAST_LIO2对ikd-Tree的维护策略做了优化长时间建图时内存增长更平缓。我跑一个约15分钟的室内数据集FAST_LIO峰值内存到过2.3G左右FAST_LIO2在同样数据下大概1.6G。对比维度FAST_LIOFAST_LIO2残差模型基础点面残差更严格的平面判定退化场景鲁棒性一般较好固态雷达适配需手动改原生支持更好长时间建图内存增长较快增长平缓社区活跃度维护减少相对活跃提示如果你用的是传统机械式多线雷达16线、32线这类两个版本都能跑差异不会特别夸张如果是固态雷达或者对退化场景要求高优先FAST_LIO2。2. 环境搭建依赖版本才是真正的拦路虎环境搭建这一步网上教程一大把但真正照着做能一次跑通的不多。问题几乎都出在依赖版本上。ROS的版本、PCL的版本、Eigen的版本任何一个对不上编译阶段就报一堆看不懂的模板错误。2.1 系统与ROS版本的选择我建议直接用Ubuntu 20.04 ROS Noetic这套组合。原因很实际Noetic是ROS1最后一个长期支持版本PCL默认是1.10Eigen是3.3.7这两个版本和FAST_LIO系列的代码兼容性最好。如果你用Ubuntu 18.04 MelodicPCL是1.8部分API对不上需要改代码用Ubuntu 22.04的话ROS1支持就麻烦了得考虑ROS2版本而FAST_LIO的ROS2分支成熟度参差。安装ROS Noetic按官方流程走就行桌面完整版sudo apt update sudo apt install ros-noetic-desktop-full装完之后记得source环境并且把source命令写进.bashrc不然每开一个新终端都要手动source一次很容易忘。2.2 关键依赖的安装与版本核对FAST_LIO依赖的主要库有PCL、Eigen、Sophus、livox_ros_driver如果用Livox雷达。逐个说。PCL和Eigen在装ROS桌面版时基本都带上了但一定要核对版本# 查看PCL版本 pcl_version$(pkg-config --modversion pcl_common 2/dev/null || echo 未找到) echo PCL: $pcl_version # 查看Eigen版本 grep -E define EIGEN_(WORLD|MAJOR|MINOR)_VERSION /usr/include/eigen3/Eigen/src/Core/util/Macros.hNoetic下正常应该是PCL 1.10、Eigen 3.3.7。如果Eigen版本不对Sophus编译会直接失败。Sophus是李群李代数的库FAST_LIO用它做位姿表示和优化。装的时候注意要用非模板版本模板版本和FAST_LIO的代码接口对不上git clone https://github.com/strasdat/Sophus.git cd Sophus git checkout 1.0.0 mkdir build cd build cmake .. make -j4 sudo make install这里git checkout 1.0.0很关键master分支的接口变过直接编译FAST_LIO会报找不到某些成员函数。livox_ros_driver只有你用Livox系列雷达才需要。装的时候注意它和ROS版本的对应Noetic要用对应的分支。装完记得把driver的launch文件路径记下来后面跑数据要用。2.3 编译FAST_LIO时的常见报错与处理创建工作空间把源码放进去mkdir -p ~/fastlio_ws/src cd ~/fastlio_ws/src git clone https://github.com/hku-mars/FAST_LIO.git cd FAST_LIO git checkout main然后回到工作空间根目录编译cd ~/fastlio_ws catkin_make编译阶段最常见的三个报错我列一下和处理方式。报错一找不到Sophus头文件。说明Sophus没装好或者装到了非标准路径。检查/usr/local/include/sophus是否存在没有的话重新装Sophus装完sudo ldconfig刷新一下库缓存。报错二Eigen相关的模板报错一堆no matching function。九成是Eigen版本不对。Noetic下如果之前手动装过别的Eigen版本可能覆盖了系统自带的需要把多余的卸掉保证/usr/include/eigen3是3.3.7。报错三PCL的pcl::PointCloud相关报错。通常是PCL版本和代码里用的API不匹配。FAST_LIO的main分支适配的是PCL 1.10如果你系统里是1.8需要改代码里用到的新API。注意编译前先source /opt/ros/noetic/setup.bash否则catkin_make找不到ROS的cmake配置会报一堆找不到catkin的错。FAST_LIO2的编译流程基本一样把仓库换成FAST_LIO2的地址即可。两个可以放在同一个工作空间的不同包目录下但包名不能冲突注意看各自的package.xml里的名字。3. 跑通第一个数据集从数据到地图的完整链路环境搭好只是第一步真正跑起来才是见真章的地方。我建议第一个测试用官方提供的示例数据集别急着上自己的雷达先把链路跑通。3.1 数据准备与话题核对FAST_LIO需要的输入话题主要有两个激光点云话题和IMU话题。官方数据集一般会提供bag包跑之前先用rosbag info看一下里面的话题名rosbag info your_dataset.bag重点看两个话题名比如常见的/livox/lidar和/livox/imu或者/velodyne_points和/imu/data。然后去FAST_LIO的配置文件里核对配置文件在config/目录下比如avia.yaml、velodyne.yaml。配置文件里几个关键字段lid_topic激光话题名必须和bag里一致imu_topicIMU话题名必须一致extrinsic_T和extrinsic_R雷达和IMU之间的外参平移和旋转外参这一项是新手最容易忽略的。官方配置文件里的外参是针对特定雷达和IMU组合标定的如果你用自己的设备外参不对跑出来的轨迹会歪得离谱。外参必须自己标定或者至少确认你的雷达和IMU的相对位置和官方配置一致。3.2 启动流程与RViz观察要点跑数据集的完整流程分三步开三个终端。终端一启动roscoreroscore终端二启动FAST_LIOcd ~/fastlio_ws source devel/setup.bash roslaunch fast_lio mapping_avia.launch终端三播放bagrosbag play your_dataset.bag --clock--clock这个参数别漏它让bag里的时间戳和ROS时间同步不加的话RViz里可能看不到点云。RViz里重点观察三样东西。一是点云是否正常显示如果一片空白八成是话题名对不上或者外参有问题。二是轨迹是否连续如果轨迹出现跳变或者断裂通常是IMU数据有问题或者时间戳不同步。三是地图是否逐渐成形正常跑起来地图会随着移动一点点累积出来。3.3 地图保存与格式转换跑完之后地图要保存下来。FAST_LIO提供了保存服务在RViz里或者用命令行调用rosservice call /laser_mapping/save_map resolution: 0.1 destination: /home/user/map.pcd保存出来的是PCD格式的点云地图。如果后续要用在导航或者别的工具里可能需要转成别的格式。PCD转PLY可以用pcl的工具pcl_pcd2ply map.pcd map.ply提示保存地图前先确认建图已经稳定如果轨迹还在漂保存下来的地图会有重影。判断方法是看回环处点云是否重合重合度好说明建图质量可以。4. 两个版本实测对比数据说话跑通之后就该做对比了。我用了三个场景的数据一个室内办公室约200平米有桌椅隔断、一条长直走廊约80米、一个半室外场景有玻璃幕墙和柱子。每个场景分别用FAST_LIO和FAST_LIO2跑记录轨迹精度、实时性和内存占用。4.1 轨迹精度对比精度这块我用的是回到起点的闭合误差作为主要指标因为绝对精度没有真值不好评闭合误差相对客观。场景FAST_LIO闭合误差FAST_LIO2闭合误差室内办公室约0.15m约0.12m长直走廊约0.45m约0.18m半室外场景约0.30m约0.22m室内办公室两个版本差距不大因为场景结构化程度高特征丰富两个版本都能处理好。长直走廊差距最明显FAST_LIO的横向漂移肉眼可见FAST_LIO2靠更严格的平面约束把漂移压下去了。半室外场景因为玻璃幕墙会产生一些无效点两个版本都受一定影响但FAST_LIO2稍好。4.2 实时性与资源占用实时性我用的是单帧处理耗时和CPU占用率。测试机器是i7-10700 32G内存。指标FAST_LIOFAST_LIO2平均单帧耗时约28ms约32msCPU峰值占用约65%约72%峰值内存约2.3G约1.6G建图15分钟后内存约2.3G约1.6G有意思的是FAST_LIO2单帧耗时反而略高因为它残差计算更细但内存控制明显更好。如果你的平台内存紧张FAST_LIO2的优势就体现出来了。单帧耗时那几毫秒的差距在10Hz雷达下基本感知不到。4.3 退化场景的表现差异退化场景是区分两个版本的关键。我专门在长直走廊里做了往返测试走廊两侧是平整墙面几乎没有纵向特征。FAST_LIO在走廊中段开始出现横向漂移走到尽头时轨迹已经偏离实际位置约0.4米返回起点时闭合误差累积到0.45米左右。FAST_LIO2在同样路径下横向漂移被明显抑制闭合误差控制在0.18米。原因在于FAST_LIO2对平面点的判定更严格在只有墙面这种大平面时它能更准确地约束横向自由度。而FAST_LIO的残差模型在这种情况下约束不够横向就飘了。注意退化场景下即使FAST_LIO2表现更好也不代表可以完全依赖。如果走廊特别长超过100米建议配合其他约束手段比如加入已知的平面约束或者用回环检测。5. 踩过的坑与排查思路这部分是我觉得最有价值的内容因为网上教程很少讲这些。每个坑我都按现象—排查—解决的顺序讲方便你复现排查思路。5.1 点云话题对不上导致RViz空白现象启动launch、播放bagRViz里Fixed Frame设对了但点云就是不显示。排查先rostopic list看当前有哪些话题再rostopic hz /your_lidar_topic看有没有数据在发。如果话题存在但没数据说明bag里的话题名和实际发布的不一致或者bag播放有问题。如果话题有数据但RViz不显示检查配置文件里的lid_topic是否和实际话题名完全一致注意大小写和斜杠。解决改配置文件里的lid_topic重新编译改yaml不用编译但改launch要重新source。这个坑我踩过两次都是因为话题名里多了或少了一个斜杠。5.2 IMU时间戳不同步导致轨迹跳变现象轨迹跑着跑着突然跳一下或者整体漂移很大。排查用rostopic echo /your_imu_topic看IMU消息的header.stamp和激光消息的时间戳对比。如果两者时间基准不一致比如一个用系统时间一个用雷达内部时间就会出问题。解决确保IMU和激光的时间戳来自同一时间源。如果是自己的设备检查驱动配置里时间戳的设置。有些雷达驱动默认用雷达内部时钟需要改成用ROS时间。5.3 外参不准导致地图重影现象建出来的地图有明显重影同一个墙面出现两层。排查先确认外参是不是用的官方默认值。如果是大概率不准。外参需要根据你的雷达和IMU实际安装位置标定。解决标定外参有几种方式简单的是用卷尺量雷达和IMU的相对位置得到平移量旋转量如果两者安装方向一致可以设为单位矩阵。要求高的话用专门的标定工具做联合标定。我自己的经验是平移量量准了旋转量在安装规整的情况下用单位矩阵效果已经够用。5.4 长时间建图内存暴涨现象跑十几分钟后程序变卡最后可能崩掉。排查用top或htop看内存占用曲线如果是持续上涨不回落说明地图点云在无限累积。解决FAST_LIO2在这方面做了优化如果还在用FAST_LIO可以手动限制地图范围或者定期清理远处点云。另外检查ikd-Tree的配置参数有些参数控制树的平衡和清理策略调一下能缓解。6. 选型建议与进阶方向跑完这一轮我对两个版本的使用场景有了比较清晰的判断。6.1 什么情况选哪个版本如果你的雷达是传统机械式多线雷达场景结构化程度高对内存不敏感FAST_LIO完全够用代码更简单改起来也方便。如果你用的是固态雷达或者场景里有大量退化区域长走廊、隧道、大平面或者平台内存紧张直接上FAST_LIO2。还有一个实际考虑是社区维护。FAST_LIO2的更新相对活跃遇到问题更容易找到解决方案。FAST_LIO虽然经典但维护节奏慢下来了。6.2 可以继续往下做的几件事跑通基础版本之后有几个方向可以深入。一是加入回环检测FAST_LIO本身不带回环长时间建图累积误差不可避免可以外挂一个回环模块比如用Scan Context做地点识别。二是多传感器融合把轮式里程计或者视觉加进来在退化场景下多一层约束。三是地图后处理建完的PCD地图可以做滤波、降采样、分割方便后续用于导航或者三维重建。我自己下一步打算试试把回环加进去因为纯里程计跑大场景还是吃力。另外外参标定这块也想做得更规范一些现在靠量尺寸终究粗糙准备用联合标定的方式再精调一遍。整体用下来FAST_LIO系列的门槛主要在环境搭建和外参标定这两步跨过去之后跑起来其实挺顺。两个版本没有绝对的好坏关键看你的雷达类型和场景特点。我个人的习惯是先用FAST_LIO2跑一遍看效果如果场景简单再考虑换FAST_LIO省点资源。这套流程走下来从零到跑通大概需要半天到一天主要时间花在依赖排查上编译本身很快。