☰
Livox雷达重定位实战:从建图到FAST_LIO_LOCALIZATION全流程解析
2026/10/7 12:59:56 网站建设 项目流程

机器人早上开机,地图还在,里程计却从零开始。轮子一动,点云哗啦一下散开,导航栈里那个“当前位置”和真实位置差出半条走廊——这就是我在仓库里第一次做FAST_LIO_LOCALIZATION之前遇到的典型场景。FAST_LIO_LOCALIZATION这个项目,就是专门解决“建好图之后,机器人重新开机不知道自己在哪里”的问题:它用Livox雷达的实时点云,在预先构建好的全局点云地图里重新找回机器人的位姿,让你不用每次都人工把机器人推到原点,也不用从头重新建图。这篇文我从环境配置、ROS bag录制、离线建图,到重定位的完整流程都盘了一遍,中间夹了大量实测踩坑记录。如果你手里有Livox Mid-360或Avia雷达,正在被“重定位发散”“bag数据没法用”“开机丢位姿”这类事折磨,这篇文章应该能帮你省掉不少弯路。

1. 动手之前:先搞清楚这套重定位系统在做什么

1.1 它和FAST_LIO不是同一个东西

很多人第一次接触FAST_LIO_LOCALIZATION时,习惯性把它当成“FAST_LIO的另一个分支”,用起来才发现完全不是一回事。FAST_LIO本身是紧耦合的LiDAR-Inertial里程计,它靠雷达点云和IMU数据做状态估计,输出的是相对轨迹。问题在于,FAST_LIO构建和维护的是局部地图,时间一长或者场景特征变差,轨迹会慢慢飘,而且一旦程序重启,里程计初始状态就丢了。它自己没有能力告诉你“机器人在地图的哪个位置”。

FAST_LIO_LOCALIZATION做的事情是:用FAST_LIO作前端,把当前实时点云与一个预先构建好的全局点云地图做匹配,通过配准结果不断修正位姿,让机器人始终知道自己在这个全局地图中的绝对位置。你可以这样理解:FAST_LIO是“闭着眼往前走,靠脚下感觉猜自己走了多远”,FAST_LIO_LOCALIZATION则是“手里拿着一张高清地图,每走几步就抬头对一下地标”。前者有累积误差,后者每一帧都在用地图做全局校正。

这个区别也决定了使用方式的差异。跑FAST_LIO建图阶段,你不需要任何先验地图;跑FAST_LIO_LOCALIZATION定位阶段,你必须先有一张全局地图,而且这张地图的质量会直接决定后续重定位的成败。

1.2 完整数据链路长什么样

整套系统的数据流,我用一句话就能说完:Livox雷达原始点云和IMU数据进FAST_LIO前端,前端输出已校正的点云和里程计;随后定位模块把当前帧点云放进全局地图里做配准,得到一个校正后的全局位姿。

拆开来看有四个关键环节。

第一,数据输入。雷达点云话题通常是/livox/lidar,IMU话题通常是/livox/imu。这两个话题是FAST_LIO和FAST_LIO_LOCALIZATION都需要的原始输入。Livox雷达内置IMU,所以不需要额外接独立的IMU传感器。

第二,前端里程计。FAST_LIO完成点云畸变校正、IMU传播、迭代状态更新,输出当前帧相对起始时刻的位姿,以及经过配准后的点云。这个环节输出频率不固定,一般跟随雷达帧率,10Hz左右。

第三,全局地图匹配。定位模块把当前帧点云与预先构建的全局点云地图做最近邻匹配,计算当前帧在地图坐标系下的最优位姿。这部分用的是类似point-to-plane的优化思路,不是传统的NDT,也不是暴力ICP,它对Livox非重复扫描造成的点云密度不均匀有比较好的适应性。

第四,结果输出。定位模块会把匹配后的全局位姿发布出来,供导航栈或者其他业务模块使用。正常工作时,你在RVIZ里能看到点云和地图贴合得非常紧密,轨迹平滑稳定。

理解这条链路很重要,因为后面所有配置和调试,本质上都是在保证这条链路里的每个环节都不掉链子。

1.3 适用场景与硬件要求

这套方案在几种场景里特别吃香。

最典型的是AGV和AMR:机器人晚上在仓库里跑完任务,回到充电桩,第二天重新上电,不需要人工把车推到“Home点”,开机后在原地稍微转一下,系统就能自己找回位姿。

其次是园区巡检、割草机器人这类室外半室外场景。Livox雷达在白天强光、晚上无光的环境下都能工作,比纯视觉方案稳定得多。也正是因为这点,很多人拿它和“ros相机重定位”做对比:相机重定位对光照变化很敏感,夜班、逆光、阴影里经常掉链子,而Livox雷达方案没有这个问题。

硬件上,最常用的是Livox Mid-360和Avia。Mid-360水平视场角360度,垂直70度左右,特别适合室内外兼顾的场景,机身自带IMU,安装方便;Avia视场角小一些,但点云分辨率更高,适合对细节要求更高的环境。算力方面,普通x86工控机就行,Jetson系列也能跑,只是要在参数里加大点云滤波强度。

2. 从零配置:依赖安装、编译与雷达标定

2.1 环境与依赖准备

我在Ubuntu 18.04和20.04上都验证过这套流程,ROS对应使用Melodic和Noetic。如果你用的是Ubuntu 22.04配合ROS2,那需要另外看FAST_LIO_LOCALIZATION的ROS2分支,这里只讲最常见的ROS1方案。

建议准备一个干净的工作空间,不要和一堆其他功能包混在一起,因为后面编译时经常出现依赖版本冲突。命令很简单:

mkdir -p ~/fastlio_ws/src cd ~/fastlio_ws catkin_make

编译前需要确保这些依赖已安装:PCL、Eigen、Ceres Solver。Ceres是重灾区,Ubuntu自带的版本往往不够新,建议从源码编译1.14.0以上的版本。我自己遇到过因为Ceres版本老,导致编译FAST_LIO时线性代数相关头文件缺失的问题,折腾了半个下午,后来统一升级到源码编译的Ceres才解决。

另外,Livox雷达驱动建议用livox_ros_driver2。Mid-360和Avia都支持这个驱动,不是老的livox_ros_driver。安装方式可以单独建一个工作空间编译,也可以直接放进fastlio_ws的src里一起编译。驱动编译需要依赖Livox SDK2,编译前先把子模块拉全:

cd src git clone https://github.com/Livox-SDK/livox_ros_driver2.git cd livox_ros_driver2 ./build.sh ROS1

2.2 Livox驱动与雷达识别

驱动编译好后,第一步不是急着跑算法,而是确认雷达数据能不能正常发出来。Livox的驱动有一个user_config.json配置文件,里面需要填写雷达的SN码和型号。MID-360的配置项和Avia不太一样,你装驱动的时候一定要看清楚文档里对应你雷达型号的配置方式。

配置完成后启动驱动:

roslaunch livox_ros_driver2 msg_MID360.launch

然后用rostopic检查数据:

rostopic hz /livox/lidar rostopic hz /livox/imu

正常情况是:点云频率在10Hz左右,IMU频率在200Hz左右。如果IMU没有数据,多半是user_config.json里imu相关的使能开关没打开;如果点云频率远低于10Hz,先检查雷达的网口连接和SN配置。

这一步看起来简单,却是很多人第一步就卡住的地方。点云话题名、IMU话题名、时间戳格式,任何一个不对,后面FAST_LIO和FAST_LIO_LOCALIZATION都会跑不起来或者跑起来全是乱数据。

2.3 雷达-IMU外参标定

Livox雷达和它内置IMU之间有一个外参,代表两个传感器坐标系之间的旋转和平移。驱动会提供一个出厂默认外参,但实际安装到机器人上以后,由于安装应力、结构件公差、温度变化等原因,这个外参可能并不精确。对FAST_LIO这种紧耦合系统来说,外参不准带来的问题非常严重,表现是静止时点云看起来没问题,一旦运动起来,点云就开始拖影,建图出现双重影甚至直接发散。

如果你想认真标定,Livox官方提供livox_calibration工具,也有的团队用手眼标定或者“先跑FAST_LIO在线估计外参,再把收敛值回填”的方法。我的习惯是分两步:

第一步,用出厂外参先跑FAST_LIO,把extrinsic_est_en设为true,让它在线估计外参。找一个特征丰富的环境,走几个“S”弯和“8”字形,跑一两分钟,然后看日志里外参的收敛值。

第二步,把这个收敛值和出厂外参做对比。如果差异很小,直接沿用出厂值,把extrinsic_est_en设为false;如果差异较大,把收敛值填入配置文件,重启FAST_LIO,仍然设extrinsic_est_en为false。这样做的原因是:在线外参估计在弱特征环境下容易被带偏,长期运行时不建议一直开着。

外参在FAST_LIO配置里通常体现为旋转矩阵和平移向量两项,具体字段名不同版本略有差别,但含义一致。你只需要把标定得到的值填进去,并且确保FAST_LIO建图和FAST_LIO_LOCALIZATION定位用的是同一份外参。

2.4 编译两个工程时的常见坑

把FAST_LIO和FAST_LIO_LOCALIZATION放在同一个工作空间里编译,大概率会遇到几个坑。

首先是包名冲突。FAST_LIO和FAST_LIO_LOCALIZATION内部都包含名为fast_lio的功能包目录,如果两个工程同时放到src下,catkin会报“package already exists”的错误。解决办法是不要在同一个工作空间同时放两个完整工程,我的做法是:建图用单独的fastlio_ws,定位用单独的localization_ws,两者各自完整编译,互不干扰。

其次是依赖版本。FAST_LIO_LOCALIZATION对PCL和Ceres的依赖要求比较新,Ubuntu 18.04自带的系统版本可能不够。建议先编译并运行原版FAST_LIO,确认建图流程完全跑通,再编译FAST_LIO_LOCALIZATION。这样万一编译失败,你能快速定位是环境问题还是代码问题。

还有一个坑是launch文件里的node名。如果你以前装过其他版本的FAST_LIO,rosmaster里可能有同名的node,导致launch启动时报“port already in use”。我习惯在运行定位之前先执行:

killall -9 rosmaster roscore

清掉所有残留节点,再干净地启动。

3. 录制一份“教科书级”的自定义bag

3.1 录bag前先确认话题列表和时间戳

FAST_LIO_LOCALIZATION的输入数据,本质上和FAST_LIO建图一样,所以bag里至少要包含雷达点云和IMU两个话题。我一般录制前会先做一次“预检”:

rostopic list rostopic hz /livox/lidar rostopic hz /livox/imu rostopic echo /livox/lidar/header/stamp -n1

为什么要看时间戳?因为FAST_LIO对时间同步非常敏感。如果点云消息里的时间戳是“1970年”的零值,或者IMU消息的时间戳和雷达消息的时间戳来自完全不同源的时钟,FAST_LIO前端在做IMU传播时就会得到完全不合理的角速度和加速度,状态估计直接崩溃。

如果你是通过bag回放跑定位,回放时建议加上--clock,并记得在启动FAST_LIO或FAST_LIO_LOCALIZATION的launch里打开use_sim_time。不加--clock,bag里的时间戳和你系统时钟对不上,IMU积分会乱成一锅粥。

录制命令很简单:

rosbag record /livox/lidar /livox/imu -O scene_01.bag

如果你希望后续能离线分析机器人的运动轨迹,也可以把/tf和/tf_static一起录进去,但这两个话题不是必须的。

3.2 数据采集路线设计的四个原则

bag数据质量直接决定建图质量,而地图质量直接决定重定位效果。很多人在算法上花大把时间,最后发现是当初录数据的时候偷懒了。

我总结出四个原则。

第一,务必回到起点。你录的这段数据应该构成一个闭环,哪怕中间绕了一大圈,最后一定要回到出发的位置附近。闭环是检验里程计漂移最直观的方式:如果回到起点时,建图轨迹跟起点没有重合,说明这段数据建图质量可能有问题。

第二,覆盖特征丰富的区域。走廊拐角、货架边缘、柱子、墙面转角,这些都是特征点密集的地方。不要长时间在空旷的大厅中央晃,也不要总在一面大白墙面前来回走。Livox的匹配需要几何特征,纯平面环境会让位姿退化。

第三,控制运动速度。我录数据时习惯把底盘线速度控制在1m/s以内,旋转速度尽量慢。太快的旋转会让点云畸变严重,IMU积分误差也会变大。再好的算法也扛不住你拿着雷达甩来甩去。

第四,录完一段“初始化”。正式采集前,让机器人在原地静止5到10秒,然后缓慢旋转一下,给系统一个良好的初始姿态估计。这个动作能显著降低后面建图发散的概率。

3.3 用rosbag工具控制bag体积和完整性

Livox点云加高频IMU的数据量不小。Mid-360的原始点云加IMU,实测下来一分钟大约100到200MB不等,录个十分钟的bag就是把一两个G的存储吃掉了。我习惯用分卷录制:

rosbag record /livox/lidar /livox/imu --split --size=1024 -O scene_01.bag

这样每个分卷1GB,避免单个bag文件过大导致后续读取和回放卡顿。

录制完成后,一定要做一次完整性检查:

rosbag info scene_01.bag

看duration、topics、每条消息数量是否合理。如果duration和你实际录制时间差太多,说明中途掉过话题或者bag写坏了,建议重录。

还有一个小细节:录制结束的时候,不要直接拔电源线或者kill掉终端。先Ctrl+C,让rosbag把缓冲区的数据写盘,等它自己退出再断电。我吃过一次亏,拔线太急,bag损坏,花了大半天采集的数据直接报废。

4. 离线建图:把bag变成全局点云地图

4.1 基于bag回放跑FAST_LIO建图

有了合格的bag,下一步就是用FAST_LIO把它变成全局点云地图。

我建图的流程是:先启动FAST_LIO的mapping launch文件,然后在新终端里回放bag:

roslaunch fast_lio fastlio_mapping.launch
rosbag play scene_01.bag --clock

在RVIZ里主要看两个东西:/cloud_registered(当前帧配准后的点云)和轨迹。理想状态是点云在运动过程中平滑地拼接,墙体边缘不抖动,轨迹没有明显突变。

如果看到点云突然跳变或者轨迹来回折返,先停下来不要继续录,检查一下是不是外参写错了、IMU话题频率不对、或者bag时间戳有问题。不要指望“多跑一会儿它自己就好了”,建图发散的问题只会越来越严重。

这里要特别注意一个参数:filter_size_map。这个值控制地图点云的分辨率或者说体素滤波大小,一般是0.5。建图和定位两阶段的filter_size_map要尽量保持一致,否则地图密度和定位匹配时采样的尺度不匹配,会影响匹配精度。

4.2 地图保存与质量检查

FAST_LIO建图过程中,全局地图会持续发布。等bag回放结束,我需要把这张地图保存下来。我这里说一个最笨但通用的方法:订阅全局地图话题,用pcl_ros把点云落盘:

rosrun pcl_ros pointcloud_to_pcd topic:=/cloud_registered

不同版本的FAST_LIO,全局地图话题名可能不一样,我见过叫/Map的,也见过叫/cloud_registered_all的,以你的源码发布的话题名为准。跑完bag后,话题里就会生成一个pcd文件。

保存完之后,我强烈建议用CloudCompare打开看一眼。检查三个指标:

一是墙和地面是否平整。如果墙面有“虚胖”的双重影,或者地面像被橡皮泥捏过,说明建图过程有漂移或者外参有偏差。

二是地图边缘是否锐利。货架立柱、门框这些结构件应该轮廓清晰,边缘不模糊。

三是点云密度是否覆盖了整个工作区域。如果某个区域完全没点云或者密度特别低,说明建图时没有走过那里,后续定位在那个区域会很吃力。

这一步有问题的话,不要急着进入定位,回到采集和建图环节把地图修好,否则后面所有重定位调试都是在地图上“屎上雕花”。

4.3 地图精度如何影响后续重定位

有个概念我希望新手朋友能尽早明白:重定位不会改善地图,它只是在现有地图里找一个最符合当前点云的位姿。地图本身漂移了、歪了、畸变了,重定位出来的位姿也会跟着歪,而且点云会被强行“按”到错误的地图位置上,看起来贴合,实际整体飘移。

地图精度的上限,决定了重定位精度的上限。这也是为什么我在前面花了整整一章强调数据采集和建图质量。你后期在定位参数上纠结来纠结去,可能还不如把当初的bag重新录一遍,把地图修得更准一点。

另外,地图不是越密越好。地图点云太密,匹配时的计算量上去了,实时性会变差;太稀疏,特征不够,匹配容易走偏。我习惯把最终保存的地图做一次降采样,让墙面的平均点间距在3到5厘米左右,兼顾精度和计算效率。

5. 重定位实战:配置、启动与调参

5.1 localization配置文件的几个关键项

FAST_LIO_LOCALIZATION的工程目录里,有一个config文件夹,里面是针对不同雷达型号的yaml文件,比如livox_avia.yaml、livox_mid360.yaml一类的名字。修改之前,建议先复制一份原文件,改成自己的版本,避免把默认配置搞坏。

我每次必改四项。

第一,雷达型号相关参数。lidar_type要选Livox对应的值,scan_line和point_filter_num要和建图时保持一致。注意:Mid-360和Avia的scan_line并不一样,网上很多默认配置是从特定型号拷出来的,直接套用不出问题则已,出了问题第一个查这里。

第二,外参。把你在2.3里确定好的雷达-IMU外参填进去,确保和建图阶段完全一致。定位阶段extrinsic_est_en建议设为false,让它用固定外参,减少在线估计的不确定性。

第三,地图路径。指定之前保存的pcd文件路径。注意路径不要写错,很多版本如果地图文件找不到,会直接在一个空地图上做匹配,然后给你发一堆发散警告。

第四,初始位姿。有些版本支持在yaml里写一个初始位姿,有些版本只能靠RVIZ里的“2D Pose Estimate”设置。前一版适合你知道机器人大致位置的场景,后一版更灵活。我习惯用RVIZ手动给。

另外,filter_size_map、点云滤波相关参数、IMU加速度和角速度噪声参数,都和建图时保持一致。不要定位时随手改大改小,否则你很难判断效果变化到底来自哪里。

5.2 初始位姿给法和失败后的补救

FAST_LIO_LOCALIZATION的全局匹配不是全球搜索,它需要一个足够好的初始值。如果初始位姿偏差太大,点云和地图匹配时会陷入局部最优,表现是点云散开、轨迹跳变、位姿乱飘。

我给初始位姿的方法是:启动定位后,先在RVIZ里找到地图,然后观察实时点云,用“2D Pose Estimate”在地图上标出机器人当前的大致位置和朝向。关键是朝向不要搞反。位置差个两三米问题不大,但朝向差了四五十度,系统很可能收敛不回来。

如果给了初始位姿之后点云依然发散,我的处理流程是先撤销错误位姿,重新观察机器人周围的特征,再给一次更准的初始值。如果反复试了几次都失败,检查这几项:

一是地图文件是否加载成功。在RVIZ里能看到地图点云,才能确认地图加载成功。

二是当前环境是否发生剧烈变化。如果几年前建的地图,今天货架全搬走了,那重定位当然不容易成功。

三是点云话题是否和建图时一致。可能驱动换过,点云帧率或话题名变了。

5.3 启动顺序与可视化判断

启动定位有一个稳定顺序:先启动FAST_LIO_LOCALIZATION的launch,再打开RVIZ加载对应配置,最后回放bag或启动实时雷达。

启动后我在RVIZ里重点盯三个迹象。

第一,点云是否贴合地图。这是最直观的。如果实时点云和地图点云高度重合,说明位姿估计很准;如果出现双影、偏移,说明还没收敛。

第二,轨迹是否平滑。观察系统发布的位姿轨迹,如果轨迹出现来回抖动或者突然大跳,说明匹配不稳定,可能被某些错误点带偏了。

第三,点云是否均匀地“贴”在地图上。有时你能看到点云基本贴合,但某个局部区域有明显的“凸起”或“凹陷”,这往往是初始位姿的微小偏差没消除干净。可以尝试重新给一次更精确的初始位姿,或者让机器人缓慢移动一小段距离,让系统自己修正。

当这三个迹象都稳定,基本可以认定重定位成功了。这时候把定位模块发布出来的全局位姿接到导航栈里,机器人就能在已有地图上自然运行。

6. 常见问题排查与实战心得

6.1 高频问题速查表

我在实际调试中遇到过的坑,挑一部分整理成表格,方便你对照排查。

现象可能原因解决方向
雷达点云话题无数据驱动未启动或SN配置错误检查livox_ros_driver2的launch和user_config.json
IMU话题无数据或频率低驱动配置中IMU使能没打开检查驱动配置里的imu相关开关
建图时点云拖影、重影外参不准或scan_line错误重新标定外参回填配置,核对scan_line
bag回放后时间对不上没有启用use_sim_time或没加--clock在launch中设use_sim_time为true,回放加--clock
FAST_LIO建图轨迹发散数据采集时运动过激或特征太少控制速度,增加特征丰富路线,重新录bag
重定位点云散开初始位姿偏差过大重新用2D Pose Estimate给更准的初始位姿
重定位后轨迹缓慢漂移地图本身有畸变或外参有偏差回查建图阶段的地图质量
定位结果与实际位置差一个固定距离地图坐标系与机器人的初始定位基准不一致确认地图坐标系原点和机器人工作原点的定义

表格里的每一项,本质都能往前追溯到我们前面讲的某一环。遇到问题时不要一头扎进参数里反复试,先定位是硬件、数据、地图,还是算法的问题。

6.2 关于FAST_LIO_LOCALIZATION定位精度的一些体会

这套方案我实际用下来,正常环境下重定位精度能达到厘米级到十厘米级,具体取决于地图密度、环境特征丰富度和传感器标定精度。但要注意,它不是“每次开机都一样完美”的魔法。环境变化是重定位最大的敌人:茶几被挪了位置、货架被移走、墙面新增了一块巨大广告牌,都会让匹配质量下降。

我的经验是,给自己留一个“定位参考区域”。在机器人经常工作的环境中,挑出几个特征稳定、不易被改动的区域,比如承重柱边、固定货架端头、门框附近,这些地方作为开机后的首选位置。每次开机,让机器人先走到这些区域附近,再启动重定位,成功率会大大提升。

另外,如果你是从“ros相机重定位”的方案转过来的,最直观的感受可能是:雷达方案不挑光线,夜里也能稳定跑,但代价是建图阶段的功夫不能省。相机重定位对纹理变化敏感,而雷达重定位对几何结构变化敏感,两者各有边界,不能互相覆盖。

6.3 后续扩展:多地图切换、GPS融合等方向

FAST_LIO_LOCALIZATION单地图定位跑通之后,很多人会想把地图扩展到多楼层、多车间。做法不复杂:准备多个pcd文件,在上层业务逻辑里根据机器人大致位置或任务区域动态切换地图。切换时要注意把定位模块复位,重新给一次新地图下的初始位姿。

另一个常见的扩展方向是和GPS融合。室外大场景下,完全依赖LiDAR地图定位可能不够灵活,如果先把GPS给一个粗糙的初始位姿,再用FAST_LIO_LOCALIZATION做精细化匹配,就能兼顾全局和局部。这个思路在园区无人车项目里很常见,等于用“粗定位+精定位”两级策略。

如果手里有相机又想融合视觉信息,也可以做雷达-视觉融合定位,但前提是把雷达重定位这条路先走通。它足够稳定以后,视觉只是作为一个辅助置信源,用来解决特定场景下的退化问题,而不是替代雷达。

6.4 最后分享一点个人体会

我踩过很多次坑之后最大的体会是:FAST_LIO_LOCALIZATION调起来其实没什么玄学,它的调试时间大头往往不是算法本身,而是前面的数据质量和外参精度。外参没标好,地图建出来就是歪的,后面怎么做重定位都别扭;bag录制得潦草,全局地图里缺少关键区域的特征,等到实际定位时就会在那些区域疯狂掉点。

所以如果你现在正在被重定位问题折磨,不要急着去改一堆定位参数,先回到源头,拿着雷达好好录一段干净、完整、有闭环、运动温和的数据,把地图建到让你自己满意的程度。地图好了,外参准了,重定位就是水到渠成的事。反过来,地图一塌糊涂,你花再多时间调匹配阈值都是白费。这套流程我用了很长时间,希望这篇文能帮你把最耗时的坑提前绕开。

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

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

立即咨询