前言
FAST-LIO2 是目前较为经典的激光雷达—惯性里程计算法。它通过紧耦合方式融合 LiDAR 点云和 IMU 数据,可以实时估计设备的位置、姿态和运动轨迹,同时构建三维点云地图。
相较于传统的 LOAM 类算法,FAST-LIO2 不需要强制提取边缘点和平面点,而是可以直接使用经过降采样的原始点云与地图进行匹配。同时,它使用 ikd-Tree 管理不断增长的点云地图,具有较高的实时性。
本文主要介绍:
FAST-LIO2 的基本原理;
FAST-LIO2 的核心处理流程;
FAST_LIO GitHub 仓库中的文件作用;
关键源码之间的调用关系;
Ubuntu 20.04、ROS Noetic 和 Livox MID-360 的落地运行方法;
点云地图保存及常见问题解决方法。
为避免公式在部分博客平台中出现乱码,本文使用纯文本形式表示公式。
一、FAST-LIO2 是什么
FAST-LIO2 全称为:
FAST Direct LiDAR-Inertial Odometry
中文可以理解为:
快速直接式激光雷达—惯性里程计。
它主要融合两种传感器的数据:
-
LiDAR 提供周围环境的三维几何信息;
-
IMU 提供设备的角速度和加速度信息。
系统最终可以输出:
-
设备实时位置;
-
设备实时姿态;
-
设备运动轨迹;
-
去畸变后的点云;
-
世界坐标系下的配准点云;
-
三维点云地图;
-
PCD 格式的地图文件。
FAST-LIO2 比较适合以下应用:
-
手持式三维扫描仪;
-
无人机定位与建图;
-
移动机器人导航;
-
自动驾驶环境感知;
-
室内外三维重建;
-
Livox 固态或混合固态激光雷达建图。
需要注意的是,FAST-LIO2 更准确地说是一套“激光惯性里程计与增量建图系统”。官方核心代码没有集成完整的回环检测和全局位姿图优化,因此长距离运行后仍可能产生累计漂移。
二、相关 GitHub 和论文链接
1. FAST-LIO2 官方 GitHub
FAST-LIO2 没有单独放在名为“FAST-LIO2”的仓库中,而是集成在 FAST_LIO 仓库中。
FAST-LIO2 官方 GitHub 仓库
https://github.com/hku-mars/FAST_LIO
2. FAST-LIO2 论文
FAST-LIO2: Fast Direct LiDAR-inertial Odometry
https://arxiv.org/abs/2107.06829
3. ikd-Tree 官方仓库
ikd-Tree 官方 GitHub
https://github.com/hku-mars/ikd-Tree
4. MID-360 官方 ROS 驱动
Livox ROS Driver 2
https://github.com/Livox-SDK/livox_ros_driver2
5. MID-360 底层 SDK
Livox-SDK2
https://github.com/Livox-SDK/Livox-SDK2
6. LiDAR 和 IMU 标定工具
LiDAR_IMU_Init
https://github.com/hku-mars/LiDAR_IMU_Init
三、FAST-LIO2 的输入与输出
FAST-LIO2 的主要输入如下。
| LiDAR 点云 | 三维坐标、反射强度、扫描线编号、点时间戳 |
| IMU 数据 | 三轴角速度、三轴加速度 |
| 外参 | LiDAR 与 IMU 之间的旋转和平移关系 |
| 配置参数 | 传感器噪声、滤波尺寸、有效距离等 |
FAST-LIO2 的主要输出如下。
| 实时位姿 | 表示设备当前位置和姿态 |
| 运动轨迹 | 记录设备连续运动路径 |
| 配准点云 | 已经转换到世界坐标系的点云 |
| 点云地图 | 由多帧点云累积得到的三维地图 |
| PCD 文件 | 用于后续点云查看、滤波和建模 |
FAST-LIO2 内部需要估计的状态主要包括:
设备位置
设备速度
设备姿态
陀螺仪零偏
加速度计零偏
重力方向
LiDAR 与 IMU 的旋转外参
LiDAR 与 IMU 的平移外参
这些状态主要定义在:
include/use-ikfom.hpp
四、FAST-LIO2 的整体处理流程
FAST-LIO2 的完整处理过程可以概括为:
LiDAR 点云和 IMU 数据
↓
数据接收与缓存
↓
LiDAR 和 IMU 时间对齐
↓
IMU 初始化与状态预测
↓
点云运动畸变校正
↓
当前点云体素降采样
↓
当前点云与已有地图匹配
↓
构建点到平面的距离残差
↓
迭代误差状态卡尔曼滤波
↓
更新设备位置和姿态
↓
将新点加入 ikd-Tree 地图
↓
发布里程计、轨迹和点云
从功能上看,这个过程可以分成两个主要部分:
-
IMU 负责高频预测;
-
LiDAR 负责修正 IMU 的累计误差。
五、IMU 初始化与状态预测
1. 为什么需要进行 IMU 初始化
IMU 测量的是角速度和加速度,它并不会直接输出设备的绝对位置。
FAST-LIO2 在开始运行时,需要根据一段相对静止的 IMU 数据估计:
-
初始重力方向;
-
陀螺仪零偏;
-
加速度计初始状态;
-
设备初始姿态。
因此,在启动 FAST-LIO2 后,应让设备保持静止几秒钟,直到终端中出现:
IMU Initial Done
如果在初始化阶段移动或晃动设备,可能导致:
-
地图倾斜;
-
地面不平;
-
点云出现分层;
-
轨迹快速漂移;
-
地图直接发散。
2. IMU 如何预测设备运动
IMU 的角速度可以用于计算姿态变化,加速度可以用于计算速度和位置变化。
其基本关系可以简单理解为:
角速度积分 → 姿态变化
加速度积分 → 速度变化
速度积分 → 位置变化
但是,IMU 积分会不断累积误差。因此,FAST-LIO2 还需要利用 LiDAR 点云与地图之间的几何关系,对 IMU 预测结果进行修正。
对应的核心代码位于:
src/IMU_Processing.hpp
其中比较重要的函数包括:
| IMU_init() | 初始化 IMU,估计重力和初始零偏 |
| UndistortPcl() | 根据 IMU 运动轨迹校正点云畸变 |
| Process() | 组织 IMU 预测和点云去畸变流程 |
| set_extrinsic() | 设置 LiDAR 与 IMU 外参 |
| set_gyr_cov() | 设置陀螺仪噪声 |
| set_acc_cov() | 设置加速度计噪声 |
六、点云运动畸变校正
LiDAR 的一帧点云不是在同一个时刻采集完成的。
例如,手持设备在扫描一面墙时发生了转动:
-
扫描开始时,设备处于姿态 A;
-
扫描中间时,设备处于姿态 B;
-
扫描结束时,设备处于姿态 C。
如果直接把这些点当作同一时刻采集的数据,原本平整的墙面就可能出现:
-
弯曲;
-
拉伸;
-
错层;
-
重影。
FAST-LIO2 会根据:
-
每个激光点的相对时间;
-
IMU 计算出的连续运动轨迹;
将一帧中的所有点补偿到同一个参考时刻,这个过程就是点云运动畸变校正。
因此,FAST-LIO2 对以下信息非常敏感:
-
LiDAR 和 IMU 的时间同步;
-
每个激光点的相对时间;
-
LiDAR 与 IMU 之间的外参。
如果点云缺少点级时间戳,FAST-LIO2 就无法准确判断一帧中每个点的采集时刻,去畸变效果也会受到严重影响。
七、FAST-LIO2 的直接式点云配准
1. “Direct”是什么意思
LOAM 类算法通常先从点云中提取:
-
边缘特征点;
-
平面特征点。
随后再使用这些人工定义的特征点进行点云配准。
FAST-LIO2 可以关闭传统特征提取,直接使用经过降采样的原始激光点与地图进行匹配。
但是需要注意:
“不进行传统特征提取”并不等于“完全不使用平面约束”。
FAST-LIO2 仍然会在地图中搜索当前激光点附近的若干点,并利用这些邻近点拟合局部平面。
2. 点到平面的距离残差
对于当前帧中的一个激光点,FAST-LIO2 会执行以下操作:
根据当前估计位姿,将激光点转换到世界坐标系;
在 ikd-Tree 地图中搜索若干个最近邻点;
使用邻近点拟合局部平面;
计算当前激光点到该平面的距离;
将该距离作为滤波器的观测残差。
点到平面距离可以表示为:
r = n^T × (p_world – q)
其中:
-
r 表示点到平面的距离残差;
-
n 表示局部平面的法向量;
-
p_world 表示当前激光点在世界坐标系中的位置;
-
q 表示局部平面上的一个点;
-
n^T 表示法向量的转置。
如果当前估计位姿比较准确,当前激光点应该落在地图平面附近,因此残差应当接近零。
相关代码主要位于:
src/laserMapping.cpp
对应的核心函数是:
h_share_model()
该函数负责:
-
将激光点转换到世界坐标系;
-
在 ikd-Tree 中搜索最近邻点;
-
拟合局部平面;
-
筛选有效匹配点;
-
计算点到平面距离;
-
构建观测雅可比矩阵。
八、迭代误差状态卡尔曼滤波
FAST-LIO2 使用的是迭代误差状态扩展卡尔曼滤波器,可以简称为:
Iterated ESKF
其处理过程可以简单理解为:
使用 IMU 预测设备的新位置和姿态;
使用预测位姿将当前点云转换到世界坐标系;
计算当前点云与地图之间的距离残差;
根据残差计算状态修正量;
修正位置、姿态、速度和 IMU 零偏;
使用修正后的位姿重新搜索点云对应关系;
重复迭代,直到状态基本收敛。
这种方式称为紧耦合,是因为 LiDAR 的点到平面残差直接进入滤波器,而不是先单独计算一个 LiDAR 位姿,再与 IMU 位姿进行简单融合。
滤波器相关文件包括:
-
include/use-ikfom.hpp
-
include/IKFoM_toolkit
九、ikd-Tree 增量地图
FAST-LIO2 使用 ikd-Tree 管理点云地图。
普通 KD-Tree 在地图增加大量新点后,可能需要重新建树。随着点云数量增加,重新建树会带来较大的计算开销。
ikd-Tree 支持:
-
增量插入新点;
-
删除局部地图之外的点;
-
动态重新平衡;
-
快速最近邻搜索;
-
地图体素降采样。
每完成一帧状态更新后,FAST-LIO2 会:
将当前点云转换到世界坐标系;
判断哪些点需要加入地图;
删除局部范围之外的旧地图点;
将新点增量加入 ikd-Tree。
对应函数为:
map_incremental()
该函数位于:
src/laserMapping.cpp
ikd-Tree 官方仓库:
https://github.com/hku-mars/ikd-Tree
十、FAST-LIO 与 FAST-LIO2 的区别
| 传感器融合 | 紧耦合迭代卡尔曼滤波 | 紧耦合迭代卡尔曼滤波 |
| 点云处理 | 更依赖特征点 | 可以直接使用原始点 |
| 地图结构 | 普通 KD-Tree 等结构 | 增量式 ikd-Tree |
| 地图更新 | 更新效率相对较低 | 支持快速插入、删除和重平衡 |
| 雷达适应性 | 对扫描结构要求更明显 | 更适合不同扫描模式的雷达 |
| 实时性能 | 较高 | 进一步提高 |
十一、FAST_LIO 仓库文件讲解
官方 FAST_LIO 仓库中的主要文件如下。
| README.md | 项目介绍、依赖安装和运行方法 |
| CMakeLists.txt | CMake 编译配置和 ROS 依赖 |
| package.xml | ROS1 软件包依赖声明 |
| config/ | 不同 LiDAR 对应的 YAML 参数 |
| launch/ | 不同 LiDAR 对应的 ROS 启动文件 |
| src/laserMapping.cpp | FAST-LIO2 主程序和地图匹配 |
| src/IMU_Processing.hpp | IMU 初始化、预测和点云去畸变 |
| src/preprocess.cpp | 不同类型点云的数据预处理 |
| src/preprocess.h | 点云类型和预处理类定义 |
| include/use-ikfom.hpp | 系统状态、过程模型和噪声模型 |
| include/common_lib.h | 公共数据结构和数学工具 |
| include/IKFoM_toolkit/ | 流形上的迭代卡尔曼滤波工具 |
| include/ikd-Tree/ | 增量式 KD-Tree 子模块 |
| msg/Pose6D.msg | 自定义 ROS 消息 |
| rviz_cfg/ | RViz 可视化配置 |
| Log/ | 运行时间和位姿日志 |
| PCD/ | 最终点云地图保存目录 |
| doc/ | 论文、算法结构图和实验结果 |
1. laserMapping.cpp
这是 FAST-LIO2 最核心的文件,相当于整个系统的主控制程序。
它主要负责:
-
接收 LiDAR 点云;
-
接收 IMU 数据;
-
缓存传感器数据;
-
同步一帧点云和对应的 IMU;
-
调用 IMU 去畸变;
-
对当前点云降采样;
-
在地图中搜索最近邻点;
-
构建点到平面距离残差;
-
执行迭代滤波更新;
-
更新 ikd-Tree 地图;
-
发布里程计、轨迹和点云;
-
保存 PCD 地图。
建议重点阅读以下函数:
| livox_pcl_cbk() | 接收 Livox 自定义点云 |
| standard_pcl_cbk() | 接收标准 PointCloud2 |
| imu_cbk() | 接收 IMU 数据 |
| sync_packages() | 将一帧 LiDAR 与对应 IMU 数据对齐 |
| lasermap_fov_segment() | 管理局部地图范围 |
| h_share_model() | 搜索最近邻、拟合平面并构建残差 |
| map_incremental() | 增量更新 ikd-Tree |
| publish_odometry() | 发布实时里程计 |
| publish_frame_world() | 发布世界坐标系点云并保存 PCD |
| main() | FAST-LIO2 主循环 |
2. preprocess.cpp 和 preprocess.h
这两个文件负责将不同 LiDAR 的原始消息转换成 FAST-LIO2 内部统一使用的点云格式。
主要功能包括:
-
读取点坐标;
-
读取反射强度;
-
读取扫描线编号;
-
读取每个点的相对时间;
-
删除近距离无效点;
-
点云抽样;
-
可选的特征提取。
FAST-LIO2 在代码中将点的相对时间临时存放在:
PointXYZINormal.curvature
后续的 IMU 处理模块会使用这个时间进行逐点运动畸变校正。
3. IMU_Processing.hpp
这个文件主要负责:
-
IMU 初始化;
-
IMU 前向积分;
-
保存一帧扫描过程中的设备状态;
-
对当前点云逐点进行运动补偿;
-
更新滤波器预测状态。
4. use-ikfom.hpp
该文件定义了 FAST-LIO2 的系统状态。
主要变量包括:
pos 设备位置
rot 设备姿态
offset_R_L_I LiDAR 到 IMU 的旋转外参
offset_T_L_I LiDAR 到 IMU 的平移外参
vel 设备速度
bg 陀螺仪零偏
ba 加速度计零偏
grav 重力方向
该文件还定义了:
-
IMU 输入;
-
状态传播模型;
-
状态转移雅可比;
-
过程噪声模型。
5. common_lib.h
该文件主要包含:
-
FAST-LIO2 使用的点云类型;
-
LiDAR 与 IMU 数据组合结构;
-
矩阵和向量类型;
-
平面拟合函数;
-
坐标转换工具;
-
常用宏定义。
6. config/mid360.yaml
这是 MID-360 对应的 FAST-LIO2 参数文件。
查看官方 mid360.yaml
它主要配置:
-
LiDAR 话题;
-
IMU 话题;
-
时间同步;
-
LiDAR 类型;
-
扫描线数量;
-
近距离盲区;
-
IMU 噪声;
-
LiDAR 与 IMU 外参;
-
点云发布;
-
PCD 地图保存。
7. mapping_mid360.launch
这是 MID-360 对应的 FAST-LIO2 启动文件。
查看官方 mapping_mid360.launch
它主要负责:
-
加载 mid360.yaml;
-
设置点云降采样参数;
-
设置滤波器最大迭代次数;
-
启动 fastlio_mapping 节点;
-
启动 RViz。
十二、Ubuntu 20.04 和 MID-360 落地运行
下面使用以下环境:
Ubuntu 20.04
ROS Noetic
Livox MID-360
MID-360 内置 IMU
FAST-LIO2 ROS1
以下步骤默认已经完成 ROS Noetic 的安装。
十三、安装基础依赖
sudo apt update
sudo apt install -y \\
git \\
cmake \\
build-essential \\
libeigen3-dev \\
libpcl-dev \\
libapr1-dev \\
ros-noetic-pcl-ros \\
ros-noetic-eigen-conversions \\
ros-noetic-tf \\
ros-noetic-rosbag
加载 ROS Noetic 环境:
source /opt/ros/noetic/setup.bash
十四、安装 Livox-SDK2
MID-360 使用 Livox-SDK2,而不是旧版 Livox-SDK。
cd ~
git clone https://github.com/Livox-SDK/Livox-SDK2.git
cd Livox-SDK2
mkdir build
cd build
cmake ..
make -j4
sudo make install
官方安装说明:
Livox-SDK2 官方仓库
安装完成后,相关库文件通常位于:
/usr/local/lib
相关头文件通常位于:
/usr/local/include
十五、创建 ROS 工作空间
mkdir -p ~/fastlio_ws/src
cd ~/fastlio_ws/src
下载 MID-360 驱动:
git clone https://github.com/Livox-SDK/livox_ros_driver2.git
下载 FAST-LIO2,并同时下载 ikd-Tree 子模块:
git clone –recursive https://github.com/hku-mars/FAST_LIO.git
如果之前下载 FAST_LIO 时没有添加 –recursive,需要执行:
cd ~/fastlio_ws/src/FAST_LIO
git submodule update –init –recursive
否则编译时可能出现:
ikd_Tree.h: No such file or directory
十六、处理 livox_ros_driver2 兼容问题
这是 MID-360 运行 FAST-LIO2 时最容易遇到的问题之一。
官方 FAST_LIO 仓库虽然已经提供:
config/mid360.yaml
launch/mapping_mid360.launch
但是部分源码和编译配置中仍然引用旧版:
livox_ros_driver
MID-360 实际使用的是:
livox_ros_driver2
需要修改以下文件:
CMakeLists.txt
package.xml
src/preprocess.h
src/preprocess.cpp
src/laserMapping.cpp
进入 FAST_LIO 目录:
cd ~/fastlio_ws/src/FAST_LIO
执行兼容替换:
perl -pi -e 's/livox_ros_driver(?!2)/livox_ros_driver2/g' \\
CMakeLists.txt \\
package.xml \\
src/preprocess.h \\
src/preprocess.cpp \\
src/laserMapping.cpp
检查替换结果:
rg -n "livox_ros_driver2" \\
CMakeLists.txt \\
package.xml \\
src/preprocess.h \\
src/preprocess.cpp \\
src/laserMapping.cpp
例如,原来的:
#include <livox_ros_driver/CustomMsg.h>
应当变成:
#include <livox_ros_driver2/CustomMsg.h>
原来的命名空间:
livox_ros_driver::CustomMsg
应当变成:
livox_ros_driver2::CustomMsg
十七、配置电脑和 MID-360 的 IP
MID-360 通过网线连接电脑,因此电脑网卡和雷达必须位于同一个网段。
官方驱动示例一般使用:
电脑 IP:192.168.1.5
雷达 IP:192.168.1.12
子网掩码:255.255.255.0
但不同设备的实际雷达 IP 可能不同,应以 Livox Viewer 2 中显示的信息为准。
在 Ubuntu 中进入:
设置 → 网络 → 有线网络 → IPv4
设置为:
IPv4 方法:手动
地址:192.168.1.5
子网掩码:255.255.255.0
网关:可以留空
然后测试网络:
ping -c 4 192.168.1.12
接下来修改驱动配置:
nano ~/fastlio_ws/src/livox_ros_driver2/config/MID360_config.json
重点检查电脑 IP:
"host_net_info": {
"cmd_data_ip": "192.168.1.5",
"push_msg_ip": "192.168.1.5",
"point_data_ip": "192.168.1.5",
"imu_data_ip": "192.168.1.5"
}
检查雷达 IP:
"lidar_configs": [
{
"ip": "192.168.1.12"
}
]
其中:
-
host_net_info 填写电脑有线网卡 IP;
-
lidar_configs 中的 ip 填写 MID-360 的实际 IP。
官方配置文件:
MID360_config.json
十八、编译工作空间
执行:
source /opt/ros/noetic/setup.bash
cd ~/fastlio_ws/src/livox_ros_driver2
./build.sh ROS1
该脚本会调用:
catkin_make -DROS_EDITION=ROS1
并编译整个 fastlio_ws 工作空间。
以后重新编译时,可以执行:
source /opt/ros/noetic/setup.bash
cd ~/fastlio_ws
catkin_make -DROS_EDITION=ROS1
编译成功后加载工作空间:
source ~/fastlio_ws/devel/setup.bash
十九、单独测试 MID-360 驱动
打开第一个终端:
source /opt/ros/noetic/setup.bash
source ~/fastlio_ws/devel/setup.bash
roslaunch livox_ros_driver2 msg_MID360.launch
这里建议使用:
msg_MID360.launch
不要使用:
rviz_MID360.launch
原因是:
-
msg_MID360.launch 发布 Livox 自定义 CustomMsg;
-
CustomMsg 中包含每个点的 offset_time;
-
FAST-LIO2 需要点级时间信息进行运动畸变校正。
打开第二个终端,查看话题:
source /opt/ros/noetic/setup.bash
source ~/fastlio_ws/devel/setup.bash
rostopic list
正常情况下应当看到:
/livox/lidar
/livox/imu
检查点云消息类型:
rostopic type /livox/lidar
预期结果:
livox_ros_driver2/CustomMsg
检查点云频率:
rostopic hz /livox/lidar
检查 IMU 频率:
rostopic hz /livox/imu
如果这两个话题没有数据,暂时不要启动 FAST-LIO2,应优先检查:
-
电脑网卡 IP;
-
雷达 IP;
-
网线连接;
-
雷达供电;
-
MID360_config.json;
-
Ubuntu 防火墙。
二十、检查 FAST-LIO2 的 MID-360 参数
打开:
nano ~/fastlio_ws/src/FAST_LIO/config/mid360.yaml
首先检查话题:
common:
lid_topic: "/livox/lidar"
imu_topic: "/livox/imu"
time_sync_en: false
time_offset_lidar_to_imu: 0.0
这里的话题名称必须和 rostopic list 中完全一致。
MID-360 预处理参数:
preprocess:
lidar_type: 1
scan_line: 4
blind: 0.5
参数含义如下。
| lidar_type: 1 | 使用 Livox 自定义点云处理方式 |
| scan_line: 4 | MID-360 对应的扫描线配置 |
| blind: 0.5 | 删除距离雷达 0.5 米以内的点 |
外参配置:
mapping:
extrinsic_est_en: false
extrinsic_T: [-0.011, -0.02329, 0.04412]
extrinsic_R: [1, 0, 0,
0, 1, 0,
0, 0, 1]
在 FAST-LIO2 中,这组参数表示:
LiDAR 在 IMU 坐标系中的位置和姿态
如果使用 MID-360 内置 IMU,可以先使用官方示例参数。
如果使用外置 IMU,则必须重新标定 LiDAR 和 IMU 的外参,不能直接照搬 MID-360 内置 IMU 参数。
二十一、启动 FAST-LIO2
保持 MID-360 驱动终端继续运行。
打开新的终端:
source /opt/ros/noetic/setup.bash
source ~/fastlio_ws/devel/setup.bash
roslaunch fast_lio mapping_mid360.launch
正常情况下会自动打开 RViz。
启动后先让 MID-360 静止几秒钟,等待终端出现:
IMU Initial Done
完成初始化后,再缓慢拿起设备开始扫描。
第一次测试时建议:
-
不要快速甩动设备;
-
不要在启动后立刻大角度旋转;
-
尽量避免一直对着纯白墙;
-
选择有墙角、门框、桌椅等结构的环境;
-
保持运动连续和平稳;
-
确保 MID-360 安装牢固。
二十二、FAST-LIO2 的输出话题
运行后可以使用:
rostopic list
查看输出。
| /Odometry | FAST-LIO2 估计的实时位姿 |
| /path | 设备运动轨迹 |
| /cloud_registered | 世界坐标系下的配准点云 |
| /cloud_registered_body | IMU 机体坐标系下的点云 |
| /cloud_effected | 参与滤波更新的有效点 |
| /Laser_map | 地图点云,源码中默认可能未持续发布 |
查看实时里程计:
rostopic echo /Odometry
查看里程计频率:
rostopic hz /Odometry
对于手持扫描系统:
-
实时定位主要使用 /Odometry;
-
实时轨迹显示主要使用 /path;
-
三维点云显示主要使用 /cloud_registered。
二十三、录制和播放 rosbag
运行 MID-360 驱动后,可以记录原始点云和 IMU:
cd ~
rosbag record -O mid360_data.bag \\
/livox/lidar \\
/livox/imu
录制结束后按:
Ctrl + C
查看 rosbag 信息:
rosbag info mid360_data.bag
离线运行时,先启动 FAST-LIO2:
source /opt/ros/noetic/setup.bash
source ~/fastlio_ws/devel/setup.bash
roslaunch fast_lio mapping_mid360.launch
然后在另一个终端播放:
rosbag play mid360_data.bag
如果电脑处理速度不足,可以降低播放速度:
rosbag play -r 0.5 mid360_data.bag
二十四、保存 PCD 点云地图
打开:
nano ~/fastlio_ws/src/FAST_LIO/config/mid360.yaml
检查:
pcd_save:
pcd_save_en: true
interval: -1
参数含义如下。
| pcd_save_en: true | 开启 PCD 地图保存 |
| interval: -1 | 所有点存入内存,结束时保存为一个文件 |
| interval: 500 | 每累计约 500 帧保存一个 PCD 文件 |
如果扫描时间较长,不建议一直使用:
interval: -1
因为所有点会持续保存在内存中,可能导致内存不足。
可以修改为:
pcd_save:
pcd_save_en: true
interval: 500
运行结束后,应当使用:
Ctrl + C
正常关闭 FAST-LIO2。
地图通常保存在:
~/fastlio_ws/src/FAST_LIO/PCD/
可能生成:
scans.pcd
scans_1.pcd
scans_2.pcd
使用 PCL 查看:
pcl_viewer ~/fastlio_ws/src/FAST_LIO/PCD/scans.pcd
二十五、关键运行参数解释
1. point_filter_num
位于:
launch/mapping_mid360.launch
例如:
<param name="point_filter_num" type="int" value="3"/>
它表示按照一定间隔保留激光点。
-
数值越小,保留点越多,地图细节越丰富,计算量越大;
-
数值越大,保留点越少,运行速度越快,细节可能减少。
MID-360 可以先使用默认值:
3
2. filter_size_surf
<param name="filter_size_surf" type="double" value="0.5"/>
它控制当前帧点云的体素降采样尺寸。
-
数值减小:点云更密,计算量增加;
-
数值增大:点云更稀疏,运行速度提高。
室内精细扫描可以尝试:
0.2~0.4
但需要同时观察 CPU 占用和实时性。
3. filter_size_map
<param name="filter_size_map" type="double" value="0.5"/>
它控制地图点云的密度。
-
数值过大:地图细节不足;
-
数值过小:地图点数和内存占用快速增加。
4. max_iteration
<param name="max_iteration" type="int" value="3"/>
表示每帧滤波更新的最大迭代次数。
增加迭代次数可能提高收敛能力,但也会增加计算时间。
5. blind
blind: 0.5
表示删除距离雷达过近的点。
如果设备周围存在大量近距离噪点,可以适当增大;如果需要扫描近距离物体,可以适当减小,但不能忽略 MID-360 本身的近距离测量限制。
6. time_sync_en
time_sync_en: false
只有在无法进行可靠时间同步时,才考虑启用软件时间同步。
软件时间同步不能完全替代可靠的硬件同步。对于 MID-360 内置 IMU,一般先保持该参数为 false。
7. extrinsic_est_en
extrinsic_est_en: false
如果已经知道准确的 LiDAR 与 IMU 外参,建议设为:
false
如果使用外置 IMU 且外参未知,应先进行专门的 LiDAR–IMU 标定。
二十六、常见问题及解决方法
1. 找不到 livox_ros_driver/CustomMsg.h
报错示例:
fatal error: livox_ros_driver/CustomMsg.h:
No such file or directory
原因是 FAST_LIO 仍然依赖旧版 livox_ros_driver。
需要将以下文件中的 livox_ros_driver 替换为 livox_ros_driver2:
CMakeLists.txt
package.xml
src/preprocess.h
src/preprocess.cpp
src/laserMapping.cpp
然后重新编译:
cd ~/fastlio_ws
catkin_make -DROS_EDITION=ROS1
2. 找不到 livox_ros_driver2/CustomMsg.h
常见原因:
-
livox_ros_driver2 没有成功编译;
-
没有加载 ROS 工作空间;
-
FAST_LIO 和驱动不在同一个工作空间;
-
编译缓存存在问题。
重新执行:
source /opt/ros/noetic/setup.bash
cd ~/fastlio_ws
catkin_make -DROS_EDITION=ROS1
source ~/fastlio_ws/devel/setup.bash
3. RViz 中没有点云
依次检查:
rostopic list
rostopic hz /livox/lidar
rostopic hz /livox/imu
rostopic type /livox/lidar
如果 /livox/lidar 没有数据,问题通常出在:
-
电脑网卡 IP;
-
MID-360 IP;
-
驱动配置;
-
网线;
-
雷达供电。
如果原始点云有数据,但 FAST-LIO2 没有输出,应检查消息类型是否为:
livox_ros_driver2/CustomMsg
4. 使用了错误的启动文件
如果使用:
roslaunch livox_ros_driver2 rviz_MID360.launch
驱动主要发布 PointCloud2 数据。
FAST-LIO2 的 Livox 处理分支需要 CustomMsg,因此应该使用:
roslaunch livox_ros_driver2 msg_MID360.launch
5. 出现点时间戳警告
例如:
Failed to find match for field 'time'
这表示点云中缺少 FAST-LIO2 需要的点级时间信息。
MID-360 应优先使用 CustomMsg,其中包含:
offset_time
缺少点时间戳时,点云运动畸变校正将无法正常工作。
6. 地图突然飞走或严重漂移
应重点检查:
启动时是否保持静止;
是否出现 IMU Initial Done;
LiDAR 和 IMU 时间是否同步;
LiDAR–IMU 外参是否正确;
是否快速甩动设备;
是否处于长走廊或空旷场地;
环境中是否有大量动态物体;
MID-360 是否安装牢固。
需要注意的是,只修改 RViz 或 URDF 中的显示旋转,并不会自动修改 FAST-LIO2 内部使用的 LiDAR–IMU 外参。
7. 出现 No Effective Points
可能原因包括:
-
当前点云为空;
-
LiDAR 话题不匹配;
-
blind 设置过大;
-
点云数据格式错误;
-
周围缺少有效几何结构;
-
最近邻平面拟合失败;
-
初始位姿已经严重错误。
应先检查原始点云和 IMU 是否正常,再检查 FAST-LIO2 参数。
8. 找不到 ikd-Tree
执行:
cd ~/fastlio_ws/src/FAST_LIO
git submodule update –init –recursive
然后重新编译。
9. 没有生成 PCD 文件
检查:
pcd_save:
pcd_save_en: true
运行结束时使用:
Ctrl + C
让 FAST-LIO2 正常执行保存流程。不要直接关闭终端窗口,否则最后一部分点云可能没有写入文件。
10. 长距离返回起点后地图没有闭合
这是因为 FAST-LIO2 官方核心代码没有完整的回环检测和全局优化。
FAST-LIO2 更适合作为:
高频、低延迟的 LiDAR–IMU 前端
如果需要大范围全局一致地图,还需要增加:
-
回环检测;
-
位姿图优化;
-
GNSS 约束;
-
重定位模块。
二十七、FAST-LIO2 在手持扫描系统中的应用
对于基于 MID-360 的手持激光雷达,可以采用以下系统结构:
Livox MID-360
├─ 激光点云
└─ 内置 IMU
↓
livox_ros_driver2
↓
FAST-LIO2
├─ 实时位姿 /Odometry
├─ 实时轨迹 /path
├─ 配准点云 /cloud_registered
└─ 三维地图 scans.pcd
↓
点云滤波、裁剪、测量和模型重建
建议按照以下顺序进行开发:
在 Ubuntu 笔记本上单独跑通 MID-360 驱动;
确认 /livox/lidar 和 /livox/imu 正常;
在笔记本上跑通 FAST-LIO2;
完成 PCD 地图保存;
测试走廊、房间、楼梯等不同场景;
优化点云密度和运行参数;
再部署到树莓派或其他嵌入式设备;
最后增加一键启动、自动保存和异常检测功能。
按照这个顺序,可以将硬件问题、网络问题、驱动问题、算法问题和嵌入式性能问题分开排查。
二十八、总结
FAST-LIO2 的核心可以概括为三点:
第一,使用 IMU 进行高频状态预测和点云运动畸变校正。
第二,使用当前激光点与地图中的局部平面构建几何残差,并通过迭代误差状态卡尔曼滤波修正设备位姿。
第三,使用 ikd-Tree 增量管理点云地图,从而提高最近邻搜索和地图更新效率。
对于 MID-360 手持扫描项目,真正决定系统能否稳定运行的关键包括:
-
使用 livox_ros_driver2;
-
使用 msg_MID360.launch 发布 CustomMsg;
-
确保点云包含点级时间信息;
-
正确修改 FAST_LIO 的驱动依赖;
-
保证 LiDAR 与 IMU 的时间同步;
-
设置正确的 LiDAR–IMU 外参;
-
初始化阶段保持设备静止;
-
长时间扫描时分段保存 PCD。
完成以上步骤后,FAST-LIO2 就可以作为手持三维扫描系统中的核心实时定位与建图模块。
网硕互联帮助中心






评论前必须登录!
注册