FAST-LIO2低算力高精度建图定位:原理、调参与工程实践
2026/9/8 22:18:22 网站建设 项目流程

“低算力高精度”这几个字放在一起,很容易让人以为是拿精度换性能的折中方案。但FAST-LIO2恰恰相反,它做的是:去掉特征提取环节,换成更聪明的增量式点云管理结构,在计算量更低的情况下把匹配精度做得更好。我最早是在一台老款Jetson上被逼着接触这个框架的——当时手里的定位建图方案一跑起来CPU直接飙到90%,地图还发虚,换到FAST-LIO2之后才真正体会到什么叫“结构决定性能”。

这篇文章主要面向要在嵌入式设备、工控机或普通笔记本上做实时定位建图的工程师和学生,也聊清楚那些网络热词里反复出现的场景:ROS机器人仿真里的建图定位路径规划、RTK融合建图与定位,到底该怎么和FAST-LIO2结合起来用。我会把核心机制、复现步骤、参数调优和踩坑过程都拆开讲,争取让你看完之后能直接在自己的环境里动手跑。

1. 从FAST-LIO到FAST-LIO2:算力焦虑是怎么被解决的

1.1 传统激光里程计的算力瓶颈在哪里

先想一个问题:激光里程计每来一帧新点云,都要把这一帧跟历史地图做配准,配准的核心操作是“查找最近邻”。地图越大,查找越慢。经典的PCL里用的静态KD-Tree,在建图过程中地图一直在增长,最直接的办法是每来一帧就重新建一棵包含全部地图点的KD-Tree。建树的复杂度是O(N log N),N是地图点的数量。地图点到几十万上百万之后,这个重建过程会频繁超出单帧时间预算,于是就开始掉帧、延迟,甚至整个里程计线程卡死。

这就是前几年很多LIO方案在嵌入式设备上跑不动的根本原因——问题不一定出在匹配算法本身,而是出在地图管理上。

1.2 ikd-Tree的出现:把“全量重建”改成“增量更新”

FAST-LIO2的核心创新之一,就是用ikd-Tree(增量KD-Tree)替换了静态KD-Tree。ikd-Tree支持增量式的点插入、点删除和点下采样,只有新增点涉及到的局部区域才会触发树结构更新或局部重建,而不是把整棵树从头建一遍。查询复杂度保持在O(log N)级别,更新也只在受影响区域做操作。

打个比方:静态KD-Tree像是一座图书馆每进一本新书就要把全部书架重新排一遍,ikd-Tree则是只把新书插到对应分类附近,偶尔整理一下那一小片区域。地图规模越大,这种“增量维护”的收益就越明显。这也是FAST-LIO2敢直接拿全量点云计算的原因之一。

1.3 放弃特征提取:全点云直接配准为什么反而更快

FAST-LIO第一个版本的做法是先提取边缘点和平面点这类局部特征,再用这些特征去匹配。特征提取本身是有成本的:每个点要算曲率、要排序、要按阈值筛点,这些操作在嵌入式CPU上并不便宜。更重要的是,特征提取会丢掉信息,在一些弱纹理环境(比如白墙走廊、空旷厂房)里,能提取到的有效特征少而稀,配准精度跟着直线下降。

FAST-LIO2直接把这一步拿掉了。它把降采样后的全量有效点云拿去地图里找最近邻关系,通过邻近点拟合局部平面,计算点到面的残差。全点云携带的信息比稀疏特征更丰富,匹配约束更强,而且省掉了特征提取这一整块的算力开销。所以它做到了“算得更少,但约束更多”。

1.4 两个版本的核心差异对照

对比项FAST-LIOFAST-LIO2
点云管理静态KD-Tree/局部地图ikd-Tree增量管理
配准数据提取的角点/平面点降采样后的全量点云
特征提取成本
地图增长处理需要定期重建/局部更新增量插入+删除
低纹理环境鲁棒性依赖特征密度相对更强
算力瓶颈特征提取+地图重建主要在最近邻搜索和迭代优化

这个表也解释了为什么FAST-LIO2在算力受限的设备上反而可能比老方案跑得更顺:它不是少干了一点活,而是换了一套复杂度更低的数据结构和更聪明的配准策略,属于“结构性省钱”。

2. 低算力背后的“省钱”设计:从数据流到参数取舍

2.1 一帧点云从进入到输出位姿,经历了什么

理解FAST-LIO2的算力分配,最好把它的完整数据流走一遍:

  1. IMU数据按时间顺序做前向传播,用迭代误差状态卡尔曼滤波预测当前状态。这一步是纯惯性积分,成本很低。
  2. 雷达帧到达后,根据帧内每个点的时间偏移,用IMU预测出的位姿对点云做去畸变补偿。这一步是矩阵变换运算,开销可控。
  3. 点云经过降采样和点抽稀,进入ikd-Tree的最近邻搜索环节。
  4. 每个查询点在ikd-Tree中找邻近点,用PCA拟合局部法向量,计算点到局部平面的残差。
  5. 残差进入IEKF迭代更新,迭代若干次后输出优化后的位姿和状态。
  6. 新接收并经过配准的关键帧点云插入ikd-Tree,同时使用删除机制移除地图中远处或过时的点,控制地图规模。

这里面最耗时的两块:ikd-Tree上的最近邻搜索和IEKF迭代中的残差计算。很多社区里流传的“FAST-LIO2对CPU友好”,本质上是因为这两块都被压到了很稳定的低延迟区间。

2.2 一次粗略的算力账

我拿单帧5000个有效点来估算一下。如果地图规模在50万点,ikd-Tree上的单次最近邻查询大概要遍历十几层树节点,耗时约几十微秒到几百微秒级别。5000个点全部完成搜索,耗时大约在几毫秒到十几毫秒之间。再加上法向量拟合、残差构建和IEKF迭代三五次,一帧的总耗时一般在10-30毫秒这个区间,也就是能跑30Hz到50Hz的处理频率。这还是在普通x86架构下的保守估计,ARM平台上会低一些,但依然可能实时。

我自己的体验是,在Jetson Nano这种老平台上,单帧6000点、point_filter_num=2、降采样分辨率0.4m的条件,处理频率稳定在12-18Hz之间,用在室内小场景建图足够。在普通i5工控机上跑同样的bag,基本可以跑满30Hz。

2.3 降采样和点抽稀参数就是算力开关

低算力调优这件事,说穿了一句话:不要直接调算法,先调点云规模。FAST-LIO2里有几个参数是天然的“算力开关”:

  • point_filter_num:每N个点取1个参与计算,值越大,参与配准的点越少,算力消耗越低,但太大会损失约束导致漂移。
  • down_sample_size:降采样体素大小,单位是米。0.2m比0.5m保留更多细节,但也意味着更大的数据量和更高的最近邻查询频率。
  • max_iteration:IEKF的最大迭代次数,默认值通常够用,调低可以减少固定开销,但收敛不足会降低精度。

我建议在低算力平台上先固定一个目标处理频率,再反过来调参数。比如目标是20Hz,那就先跑一帧看耗时,如果超了50ms,就把point_filter_num从1调到2,或者把down_sample_size从0.3调到0.4,而不是去动滤波器本身。

2.4 我在低算力平台上调参的实测记录

下面这组参数是我在某低配工控机上调试后比较稳定的一组组合。

参数初始值调优后影响
point_filter_num12单帧点数减少约一半,CPU占用下降明显
down_sample_size0.20.4地图分辨率略降,但点云规模大幅缩小
max_iteration53单帧迭代耗时下降,精度损失可接受
filter_size_map0.40.6减小地图冗余点,树结构更轻

实跑下来,室内小场景里调参后的精度差距在厘米级,而CPU占用下降了将近一半。所以如果你在低算力设备上跑不动,优先从“减少参与计算的点数”入手,而不是去优化代码。

3. 高精度的底气究竟在哪:紧耦合、去畸变和退化环境的验证

3.1 去畸变不是加分项,是精度的前提条件

旋转式雷达在扫描一帧的过程中,雷达自身处于运动中。假如扫描周期是100ms,雷达在这个时间内已经移动了一段距离,每个点采集时刻对应的雷达位姿都不一样。如果不做畸变补偿,一帧“平直墙面”的点云会被拉成一条弯曲的弧线,直接导致地图发虚、墙体变厚。

FAST-LIO2用IMU前向传播的位姿对每个点做补偿,把帧内运动导致的畸变先干掉。这是它高精度的第一个保障。如果IMU频率不够或者时间戳不对齐,这个补偿就会出偏差,地图表现会立刻劣化。很多新手第一次跑建图发现墙体漂移,查到最后往往不是算法问题,而是IMU频率太低或外参没标好。

3.2 IEKF紧耦合到底解决了什么问题

FAST-LIO2用的是迭代误差状态卡尔曼滤波框架。它不像松耦合方案那样“先单独做点云配准,再和IMU结果融合”,而是把IMU预测的位姿作为先验,把点云残差作为观测,在同一个迭代优化框架里更新状态。这意味着IMU的信息不只是用来做畸变补偿和运动预测,它本身也在参与点云匹配的约束。

这样做的直接好处是:在点云约束弱的环境里,IMU可以为姿态提供连续约束;在运动剧烈、点云帧间重叠少的场景里,IMU的先验能让匹配收敛得更快、更稳。我在一些快速转向的手持建图数据里对比过,纯激光方案容易出现瞬间跳变,紧耦合方案要平滑很多。

3.3 退化环境里的表现:走廊和隧道实测

我自己试过一条很极端的室内场景——长直走廊,两面墙完全平行,人在中间走向深处推进。这种场景对纯激光里程计来说是典型的退化环境,因为沿走廊方向几乎没有任何几何约束,里程计容易沿着走廊方向漂移。

FAST-LIO2跑下来,虽然也存在轻微漂移,但因为有IMU持续提供加速度和姿态约束,漂移速度相比纯激光方案慢得多。走完大概60米的长廊,转弯回到起点时闭合误差在几十厘米以内,这在很多精度要求不高的巡检场景里是够用的。如果你需要在退化非常严重的场景里把误差压得更低,就要考虑加进来外部绝对观测,这正是后面要说的RTK融合的用武之地。

3.4 外参标定对精度的放大作用

激光雷达和IMU之间的外参,是FAST-LIO2里最容易被忽略的精度瓶颈。外参不准,所有IMU补偿都会带着一个系统误差,而且这个误差会随着运动距离累积放大。我见过一个案例,外参的旋转分量差了不到1度,跑完一圈下来地图整体扭曲了一截,怎么调滤波参数都没用,重新标定后一下恢复正常。

所以拿到新传感器之后,第一件事是标定外参,而不是急着跑建图。就算是用ROS仿真,也要把外参写准确,否则后面所有环节都会基于错误的空间关系做计算。

4. 从零复现FAST-LIO2:环境配置、公开数据集跑通与YAML参数解读

4.1 环境准备:Ubuntu和ROS版本怎么选

FAST-LIO2官方代码主要基于ROS1,我建议直接采用Ubuntu 18.04 + ROS Melodic或Ubuntu 20.04 + ROS Noetic的组合。依赖项主要是PCL、Eigen3和livox_ros_driver。如果你跑的是公开数据集或旋转式雷达,livox_ros_driver不一定非要编译,但官方launch文件里通常会有Livox相关的配置,装好最省事。

我踩过的最大环境坑是Eigen版本太新导致编译报错。Ubuntu 20.04的Eigen 3.3.7一般没问题,但如果你手动升级过Eigen到3.4,可能会出现CMake找不到旧接口的情况。建议编译前先确认Eigen版本,报错时优先检查这里。

4.2 编译和跑通公开数据集

假设你已经建好了catkin工作空间,官方代码克隆到src目录下。编译命令很简单:

cd ~/catkin_ws catkin_make source devel/setup.bash

然后下载港大公开数据集里的室内场景bag文件,按设备类型启动对应的launch:

roslaunch fast_lio mapping_avia.launch

新开一个终端播放bag:

rosbag play your_dataset.bag -r 0.8

在Rviz里添加PointCloud2话题,一般可以看到/cloud_registered,这是一个建图过程中实时生成并注册到地图系的点云话题。如果看到地图在正常增长,就说明已经跑通了。

我建议第一次复现不要开全速播放,用-r 0.8稍微降低播放速度,给算法留出富余的计算时间。速度过快可能导致前端来不及处理点云,表现是地图出现空洞和断层,那不是算法坏了,是数据喂得太快。

4.3 YAML参数逐项解读

打开fast_lio的config目录下的yaml文件,核心参数基本集中在common、preprocess和mapping三块。

common段落里主要设置话题名称,lid_topic是激光雷达点云话题,imu_topic是IMU话题。这里最常见的错误是话题名和实际发布名不一致,导致启动后一直等待数据。

preprocess段落里有两个关键参数:lidar_type和scan_line。lidar_type要对应传感器型号,比如Livox Avia、Horizon或旋转式雷达,不同型号的数据组织方式不同,填错会直接导致前端解析异常。scan_line是雷达线数,如果你用的雷达不是按线束组织的点云,这个值要特别小心。

blind参数用来屏蔽近距离盲区内的点,避免雷达自身结构反射点干扰配准。point_filter_num是刚才说过的抽稀倍数,这是调算力的第一入口。

mapping段落里最核心的是down_sample_size、filter_size_surf、filter_size_map和max_iteration。down_sample_size控制输入点云的体素降采样;filter_size_surf控制用于曲面拟合的点范围;filter_size_map控制地图点的稀疏程度。这几个值不是越大越好,也不是越小越好,要在精度和算力之间找平衡点。

4.4 自己录bag再跑:实操上需要注意的细节

如果你想用自己的传感器录bag,有几个地方要注意。IMU频率不能太低,建议至少100Hz,200Hz更稳,因为前向传播和畸变补偿都依赖IMU数据。时间戳必须统一到同一时钟源,否则去畸变会出错。如果用的是第三方IMU而不是雷达内置IMU,要留意IMU坐标系方向和重力对齐,方向错了会让整个滤波发散。

录完bag后播放,先看Rviz里是否有地图生成。如果没有,按这个顺序排查:话题名是否匹配、时间戳是否有数据、IMU频率是否达标、外参是否设置合理。这几个点排查完,大部分问题都能定位到。

5. 室外大场景进阶:与RTK/GNSS融合建图与定位的落地姿势

5.1 纯LIO在室外为什么仍然会漂

FAST-LIO2的里程计是相对定位,误差会随时间累积。室内小场景还好,到了室外跑几百米甚至几公里,累计漂移会明显变大,尤其是在环绕式路径中,回到起点时闭合误差可能达到米级。解决这个问题,最直接的方式是引入RTK/GNSS这类绝对定位信息。RTK在开阔环境下能提供厘米级的绝对位置,正好弥补LIO没有全局参考的短板。

但要注意,RTK并不是室内也能用的方案。它依赖卫星信号,在立交桥下、高楼峡谷、树荫遮挡区域都会出现丢星或定位跳变。所以RTK融合的工程本质,是如何在LIO的局部一致性和RTK的全局绝对性之间做可靠取舍。

5.2 两种主流的融合方式

第一种是松耦合注入。把RTK解算出的位置当作一个“伪观测”塞进FAST-LIO2的滤波更新里。具体做法是在ESIKF的观测模型里增加一个位置残差项,测量值是RTK给出的全局坐标,预测值由当前状态和外参推算出来。代码里通常需要自己构造观测矩阵H和测量噪声矩阵R。

第二种是后处理优化。建图结束之后,把LIO输出的里程计位姿序列作为相对约束,把RTK坐标作为绝对约束,放进GTSAM或Ceres里做一次全局位姿图优化。这种方式的优点是实现简单,不影响前端实时性,缺点是只能在离线阶段得到修正后的地图,不适合实时定位需求。

我个人的倾向是,如果做实时定位地图采集,用松耦合注入;如果只做高精度地图生成,后处理优化更省事也更好控制。

5.3 代码层面:把RTK位置塞进ESIKF大概要改哪里

FAST-LIO2内部没有现成的GNSS融合开关,需要自己在迭代更新部分加一段逻辑。大致思路是:

  1. 写一个GNSS消息类,接收RTK位置和状态标志位。
  2. 在迭代优化的update步骤里,当收到新的RTK位置时,构造一个位置残差项,并把RTK的位置转换到地图坐标系。
  3. 根据RTK状态设定噪声矩阵R:固定解状态给很小的R,浮点解给稍大的R,单点解直接跳过或给很大的R。
  4. 把这一项残差和点云残差一起进入IEKF迭代,完成状态更新。

这样改完之后,LIO继续保持高频里程计输出,RTK以低频(1Hz到10Hz)修正全局位置偏移。实际测试中,开阔环境下50米往返的闭合误差能从分米级压到厘米级,前提是RTK状态足够好。

5.4 动态权重的工程细节

RTK融合最怕的不是没有RTK,而是RTK突然从“固定解”变成“浮点解”甚至“单点解”,却仍然被当作高可信度观测输入。这会让滤波器被错误位置拉偏,地图出现锯齿形跳变。

我建议做一个状态到噪声权重的映射。固定解时测量噪声R给到0.1m级别,浮点解放宽到0.5m-1m,单点解直接丢弃或者给10m级别的大噪声。同时可以利用PDOP值作为辅助判断,PDOP越小,位置可信度越高,R就相应减小。这种自适应策略虽然简单,但能避免大量RTK融合中的“数据污染”问题。

6. 机器人项目落地:ROS仿真、地图转换与路径规划的完整链路

6.1 在Gazebo仿真里给FAST-LIO2喂“合格的”传感器数据

很多做机器人仿真的人习惯把注意力放在模型和控制器上,忽略了传感器数据质量。FAST-LIO2对仿真器的传感器质量是有基本要求的:激光雷达点云要带点时间戳、IMU频率要够高、tf树要完整。

在Gazebo里,URDF中的激光雷达插件和IMU插件本身会发布PointCloud2和IMU消息。你只需要保证两个插件使用同一套仿真时间,并且之间的外参关系在URDF和YAML里保持一致。

我见过不少仿真项目,启动FAST-LIO2后地图完全乱成一团,最后发现是仿真的激光雷达扫描周期设置成1秒一帧,IMU却只发了20Hz。这种传感器配置下,运动补偿基本失效,地图自然崩。仿真里合理的配置是激光雷达10Hz到20Hz,IMU至少100Hz,扫描帧率也不要太低。

6.2 把FAST-LIO2输出的点云地图转成导航可用的costmap

FAST-LIO2建图得到的是一张稠密三维点云地图,直接给Navigation2用肯定不行,需要转换。最常用的路径是使用octomap_server把三维点云转成OctoMap,再投影成二维占用栅格地图;也可以用laser_scan_matcher之类的方式在线生成2D costmap。

具体步骤上,先把点云话题重映射到/cloud_registered,配置octomap_server的输入源,设置frame_id为地图坐标系。然后设置投影高度区间,把地面以下和天花板以上的点滤掉,只保留机器人可行走高度范围内的障碍物信息。这样生成的2D costmap可以直接给Navigation2作为静态地图层。

要注意的是,点云地图里的点可能包含建图过程中的噪声点和动态物体留下的残影。在转地图之前最好先做一遍统计滤波或体素降采样,把离群点去掉。否则costmap里可能会出现一些“幽灵障碍物”,导致路径规划绕远甚至无法通行。

6.3 建图、定位、路径规划三个阶段怎么切换

一个完整的机器人任务通常分三个阶段。建图阶段跑FAST-LIO2,输出地图并保存;定位阶段使用FAST-LIO2或替代方案(比如NDT匹配、AMCL)在地图中进行实时定位;规划阶段根据当前位姿和静态地图做路径规划。

实际工程里,FAST-LIO2本身就可以当作定位模块使用,因为它输出的里程计本质上是连续位姿估计。你只需要把FAST-LIO2的odometry话题转发给Navigation2的odom输入,同时设置好base_link到map的tf关系即可。很多机器人项目就是这么做的,省掉了单独跑AMCL的麻烦。

仿真里跑这条链路的模板流程是:Gazebo启动机器人模型 → 启动FAST-LIO2接收仿真传感器数据 → 建图并保存点云/栅格地图 → 用octomap_server发布2D costmap → Navigation2加载costmap并接收FAST-LIO2的odometry → 下发目标点开始路径规划和避障。

6.4 仿真集成中常见的坐标系和时间坑

坐标系错误是仿真集成的第一大坑。FAST-LIO2要求帧里的点云坐标是在雷达坐标系下,IMU数据在IMU坐标系下,外参决定了雷达坐标系和IMU坐标系、body坐标系的关系。URDF里的link关系必须和YAML里的外参保持一致,否则系统会有“一个点在不同坐标描述里位置不同”的矛盾,地图必然发散。

时间戳问题是第二大坑。仿真环境默认使用仿真时间,如果FAST-LIO2节点和传感器驱动节点的时间基准不一致,message_filters同步就会失效,表现为启动后一直没有点云回调或者地图卡住不动。解决方法是在launch文件里显式设置use_sim_time为true,保证所有节点共用同一套仿真时钟。

7. 排错实录:建图重影、定位抖动、CPU过高这几个坑怎么填

7.1 案例一:墙体发虚、地图重影的完整排查链路

现象是建图跑到几十米后,墙体出现明显的双影,越往后越虚。我没有直接去调参数,而是按链路一层层查。

第一检查IMU话题频率,发现IMU只有50Hz,偏低于推荐值,但还在可用范围。第二检查外参,雷达和IMU之间的旋转矩阵写得很随意,是厂家给了一个粗略值后一直没有标定。最后把外参重新标定后,重影明显改善,但还没有完全消除。

再到参数层排查,发现filter_size_surf设得偏小,导致参与曲面拟合的点集噪声较大,局部法向量估计不稳定。把filter_size_surf调到0.4后,墙体重影彻底消失。这个例子说明:一个现象往往由多个因素叠加导致,只解决一个是不够的,得按传感器数据、标定、参数三层挨个排。

7.2 案例二:设备静止时定位输出轻微抖动

有一次测试时设备完全静止,但Rviz里的位姿出现低频抖动。一开始以为是滤波噪声,后来发现是IKD-Tree的更新逻辑问题。设备静止时连续插入的降采样点没有匹配好,“新点插入”和“地图点删除”之间出现了短暂的不一致,导致残差在零点附近震荡。

解决办法是适当增大filter_size_map,减少地图里冗余点带来的不稳定性;同时检查点云降采样是否过度,如果降采样导致单帧点云太少,匹配约束不够,也会出现抖动。这类问题没有统一答案,但排查方向基本就是“地图点太密或者太疏两个极端都容易出问题”。

7.3 案例三:树莓派4B上CPU占用过高

树莓派4B不是FAST-LIO2的最佳平台,但确实有人这么做,我也试过。一开始跑起来CPU直接顶满,地图更新很卡。后来做了三件事:point_filter_num从1调到3,把单帧参与计算的点数砍到三分之一;down_sample_size从0.3调到0.5,缩小整体点云规模;关闭了Rviz里的连续渲染,只保留必要的可视化。

调完后CPU占用从接近100%降到60%左右,处理频率稳定在10-15Hz,对一个室内小巡检车来说够用了。结论依然是那句话:低算力环境下先通过减少数据量换取实时性,再考虑精度优化。

7.4 常见问题定位速查表

现象可能原因排查方向
地图重影、墙体发虚外参不准、IMU频率低、时间戳不同步检查标定、时间同步、filter_size_surf
地图断层bag播放速度过快、点云迟到降低播放速率、检查话题同步
静止抖动IKD-Tree更新不一致、点云过疏增大filter_size_map、降低降采样强度
CPU占用过高参与计算点数过多调大point_filter_num、down_sample_size
启动后无地图输出话题名不匹配、时间戳基准不一致检查YAML话题配置、use_sim_time
地图整体扭曲外参旋转分量错误重新标定外参

说说我个人的体会:FAST-LIO2最大的价值不在于某一项技术指标有多惊艳,而在于它把“高精度定位建图”这件事的算力门槛拉低到了普通工控机甚至嵌入式设备能承受的范围。但它的强项也有边界——高速运动、极端退化环境、低质量IMU这些场景下,还是要靠外部传感器和合理的工程策略来补齐。如果你刚接触这套框架,我建议别急着拿真车真雷达开跑,先把公开数据集跑明白,再逐步换成自己的传感器,这样遇到问题的时候至少能判断是数据问题还是算法问题,排查起来会轻松非常多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询