项目已开源至Github,欢迎Star:
GitHub - Ikunio/Lidar_nav2_ws: 基于 Livox MID-360 3D LiDAR 的 ROS 2 自主导航工作空间,集成 LIO 里程计、重定位、Nav2 导航,支持仿真与实机部署。 · GitHub基于 Livox MID-360 3D LiDAR 的 ROS 2 自主导航工作空间,集成 LIO 里程计、重定位、Nav2 导航,支持仿真与实机部署。 - Ikunio/Lidar_nav2_ws
https://github.com/Ikunio/Lidar_nav2_ws
做机器人导航,最怕什么?
不是代码编译不过。
编译不过至少还会报错。
真正恐怖的是:
机器人开机以后,一脸自信地觉得自己在 A 点,实际上它在 B 点。
RViz 里它正在优雅导航,现实里它正在优雅撞墙。
这就是重定位问题。
尤其是 3D LiDAR 导航系统里,机器人不是每次都乖乖从固定位置开机。你今天把它放在门口,明天把它搬到走廊,后天它可能被队友随手推到了一个“风水宝地”。
这时候如果系统只能说一句:
请先手动给我一个准确初始位姿。那就有点像导航软件上车第一句话:
请你先告诉我你在哪。我要是知道我在哪,还要你导航干什么?
所以在这个 ROS 2 3D LiDAR 导航项目里,我没有只塞一个重定位算法,然后祈祷它天下无敌。
我给系统准备了三套方案:
ICP small_gicp KISS-Matcher + small_gicp不同场景,用不同算法。
不搞“一招鲜吃遍天”。
因为机器人世界里,一招鲜通常最后会变成:
一招先把自己送走。一、为什么 3D 重定位这么重要?
在 ROS 2 导航里,机器人通常需要知道自己在地图里的位置。
对于 3D LiDAR 系统来说,我们通常会提前保存一张先验点云地图:
prior map.pcd机器人运行时,LiDAR 会实时输出当前点云,例如:
/registered_scan重定位要做的事情就是:
把当前扫描到的局部点云,对齐到之前保存好的全局 PCD 地图里。
说白了就是:
当前我看到的这一小块环境,到底对应地图里的哪一块?如果对齐成功,系统就能知道机器人在map坐标系下的位置,并维护:
map → odom这条 TF 很关键。
因为 LIO 负责的是局部连续运动,也就是:
odom → base_footprint而重定位负责把局部里程计坐标系重新拉回全局地图坐标系:
map → odom这两者配合起来,机器人才能既“走得连续”,又“不忘自己在哪”。
不然 LIO 一路积分,时间久了容易漂。
机器人漂一点,导航歪一点。
最后可能就是:
规划器:我觉得能过。 机器人:我觉得悬。 墙:我觉得疼。二、为什么不只用一个算法?
理论上,一个算法当然最好。
启动简单、配置简单、写博客也简单。
但实际工程里,场景不是这么讲武德的。
有些时候,机器人初始位置很准,只需要快速配准一下。
有些时候,机器人初始位置大概知道,但不够准。
还有些时候,机器人直接被搬走了,系统对当前位置一无所知。
这三种情况,难度完全不一样。
所以你不能指望一个算法在所有情况下都表现完美。
这就像你打游戏:
小怪用平 A 精英怪用技能 Boss 战还只会平 A,那基本就是去送温暖3D 重定位也是一样。
不同难度的局,得上不同配置。
三、方案一:ICP —— 简单直接,适合“我大概知道自己在哪”
ICP,全称 Iterative Closest Point。
它的思想很朴素:
找最近点,算变换;再找最近点,再算变换;一直迭代,直到对齐。
听起来是不是很像:
我先猜一下。 错了? 那我再猜一下。 还错? 那我继续猜。这就是 ICP 的性格。
它不花里胡哨,不搞全局搜索,不搞复杂特征。
它就是很直接地把当前点云往先验地图上贴。
ICP 的优点
ICP 最大的优点是:
简单 直观 依赖少 流程清晰如果机器人初始位置已经比较准,比如就放在建图起点附近,或者你手动给了一个还不错的初值,ICP 很容易完成一次对齐。
它适合这种场景:
机器人开机点基本固定 初始位姿误差不大 只需要开机时修正一次 对持续重定位要求不高简单说:
ICP 适合“你已经站得差不多了,我帮你扶正一下”。
ICP 的缺点
ICP 的问题也很明显:
怕初值差 怕局部最优 怕环境重复 通常只适合一次性初始化如果机器人开机位置离真实位置差太远,ICP 很可能一本正经地对齐到错误地方。
它不是全局搜索算法,它更像一个近视眼。
你把它放在正确答案附近,它能看清。
你把它扔到十万八千里外,它可能会说:
我觉得这里也挺像的。然后机器人就开始在错误地图位置上自信导航。
自信是好事。
但机器人自信错了,就是事故。
四、方案二:small_gicp —— 更稳一点,适合“我大概知道,但不够准”
small_gicp 可以理解为比普通 ICP 更工程化、更高效、更适合点云配准的一类方案。
它不是简单地拿点到点距离硬贴,而是利用点云局部结构和协方差信息,让配准过程更稳定。
你可以把 ICP 理解成:
两个点云互相找最近点,然后硬凑。而 GICP 更像是:
不只看点在哪里,还看这一片点云的局部形状。所以在一些结构明显、点云质量不错的环境里,small_gicp 通常会比普通 ICP 更靠谱。
small_gicp 的适用场景
它适合这种情况:
机器人初始位姿大致已知 初始误差不是特别离谱 希望持续维护 map → odom 希望系统运行中不断修正 LIO 漂移也就是说,如果你能通过配置文件或者 RViz 的2D Pose Estimate给一个大概初值,那么 small_gicp 就可以接着干活。
它不像 ICP 那样只适合“开机那一下”。
在这个系统里,small_gicp 可以持续根据当前/registered_scan和先验 PCD 地图进行配准,并维护:
map → odom这就很重要。
因为机器人运行过程中,LIO 可能会慢慢漂。
small_gicp 就像旁边坐了一个嘴碎但有用的副驾驶:
你偏了。 你又偏了。 你还是偏了。 我给你修一下。虽然有点烦,但能救命。
small_gicp 的缺点
small_gicp 虽然比普通 ICP 稳,但它依然不是魔法。
它仍然需要比较合理的初值。
如果初值太离谱,它也可能收敛失败,或者收敛到一个错误位置。
这就像你打开导航,定位点已经飘到隔壁城市了。
导航软件再聪明,也会沉默两秒,然后开始重新思考人生。
所以 small_gicp 的定位是:
已知大概位置时,快速、稳定、持续地进行 3D 点云重定位。
但它不适合完全无初值的极端场景。
五、方案三:KISS-Matcher + small_gicp —— 不知道在哪?那就先全局找一遍
最有意思的是第三套方案:
KISS-Matcher + small_gicp这套方案主要解决一个问题:
机器人初始位姿未知,怎么办?
也就是说,机器人开机之后,系统不知道它在地图的哪个位置。
这个场景非常真实。
因为实机部署时,经常会出现:
机器人被搬动了 机器人不是从固定点启动 上一次定位结果不能用了 人为拖车换位置 仿真和实机初始点不一致如果还指望 small_gicp 直接收敛,那就有点为难它了。
所以 KISS-Matcher 的作用就是:
先做全局粗配准,找出一个靠谱的初始位姿。
它相当于先帮机器人回答灵魂三问:
我是谁? 我在哪? 我在地图哪一块?当 KISS-Matcher 找到一个初始变换后,再把这个结果交给 small_gicp。
然后 small_gicp 接手后续连续跟踪。
这套流程可以理解为:
KISS-Matcher:负责找大概位置 small_gicp:负责精修和持续跟踪一个负责“找人”。
一个负责“盯人”。
配合起来就比较完整。
六、三套方案怎么选?
这才是这个项目真正想表达的重点。
不是说 ICP 天下第一。
也不是说 small_gicp 天下第一。
更不是说 KISS-Matcher + small_gicp 一出,其他算法就可以下岗。
真正工程化的做法是:
根据场景选择合适的重定位方案。
可以简单这样理解:
| 场景 | 推荐方案 | 原因 |
|---|---|---|
| 开机位置基本固定,初值很准 | ICP | 简单直接,开机修正一下就行 |
| 开机位置大致知道,但需要持续修正 | small_gicp | 收敛更稳,可以持续维护map → odom |
| 开机位置未知,机器人可能被搬过 | KISS-Matcher + small_gicp | 先全局粗配准,再连续精配准 |
| 环境变化小,点云地图稳定 | small_gicp / KISS + small_gicp | 配准成功率更高 |
| 环境重复结构多,比如长走廊 | 需要谨慎使用全局重定位 | 容易匹配到相似区域 |
| 只想快速验证流程 | ICP | 配置简单,适合调试 |
用一句不严谨但好理解的话说:
ICP:适合我知道自己大概在哪 small_gicp:适合我知道自己大概在哪,但想更稳 KISS-Matcher + small_gicp:适合我完全不知道自己在哪这就是多算法自由切换的意义。
不是为了显得算法多。
而是为了让系统在不同场景下有选择权。
七、为什么“可切换”比“只集成一个算法”更重要?
很多机器人项目看起来功能很多,但实际非常脆弱。
换个场景,参数炸了。
换个起点,重定位失败。
换个地图,直接开始表演行为艺术。
原因之一就是:
系统把自己绑定死在了某一个算法假设上。
比如只用 ICP,就默认初值不能差。
只用 small_gicp,就默认机器人不能被搬太远。
只用全局重定位,又可能在简单场景下增加不必要的复杂度。
所以我更倾向于把它们做成可切换方案。
这样系统就可以根据实际场景选择不同模式:
实验室固定起点:ICP 普通实机导航:small_gicp 任意位置开机:KISS-Matcher + small_gicp这才像一个真正能落地的系统。
就像你出门不会一年四季只穿拖鞋。
虽然拖鞋很舒服,但你不能穿着它去爬雪山。
算法也是一样。
舒服不代表万能。
八、这套设计在 ROS 2 系统里怎么串起来?
整个系统围绕一条核心链路工作:
Livox MID-360 + IMU ↓ LIO:FAST-LIO2 / Point-LIO ↓ /registered_scan ↓ ICP / small_gicp / KISS-Matcher + small_gicp ↓ 发布或维护 map → odom ↓ Nav2 根据 map、odom、base_footprint 完成导航这里面有几个关键点。
1./registered_scan是重定位输入
重定位算法不是直接乱拿点云。
它使用的是经过 LIO 处理后的当前局部点云:
/registered_scan这份点云比原始点云更适合用于配准。
因为它已经经过运动估计和一定程度的坐标处理。
2. 先验 PCD 地图是重定位参考
三种算法都需要对齐到一张提前保存好的 PCD 地图:
prior_pcd_file所以在启动前要确认 PCD 路径正确。
路径错了,算法再强也没用。
你让它拿宿舍地图去匹配实验室,它能成功才奇怪。
3. 同一时间只能有一个节点发布map → odom
这个非常重要。
如果 ICP、small_gicp、KISS-Matcher 同时抢着发布:
map → odom那系统就不是重定位了。
那叫三个人抢方向盘。
最后 Nav2 会非常困惑:
我到底该信谁?所以不同重定位方案要二选一或三选一启动。
自由切换不是同时全开。
自由切换是按场景选择一个最合适的。
这点非常关键。
九、实际调试时怎么判断该换算法?
可以按现象来判断。
现象一:初值很准,但只是开机需要对齐
用 ICP 就够。
没必要一上来就全局重定位。
这时候用 KISS-Matcher 有点像:
明明人在你面前,你还要打开全国人口数据库找他。能用,但没必要。
现象二:初值大概对,但走着走着会偏
用 small_gicp。
因为它可以持续维护map → odom,对 LIO 的累计误差进行修正。
这时候 ICP 只在开机对齐一次,后面就不管了。
就像教练只在比赛开始前说一句“加油”,然后全程消失。
精神支持有了,技术支持没了。
现象三:机器人被搬动,初值完全不可信
用 KISS-Matcher + small_gicp。
这时候直接用 small_gicp 容易因为初值太差而收敛失败。
KISS-Matcher 先帮你找全局初始位置,再交给 small_gicp 连续跟踪。
这套流程更适合“任意位置开机”。
当然,它也不是神。
如果当前点云太少、和地图重叠不足、环境重复结构太多,仍然可能失败。
重定位算法不是算命先生。
它需要足够的信息。
你只给它一面白墙,它也很难判断这是走廊第几面白墙。
十、这套系统的亮点到底在哪里?
这个项目真正值得说的点,不是“我用了 ICP”。
也不是“我用了 small_gicp”。
更不是“我把 KISS-Matcher 跑起来了”。
真正值得说的是:
我把多种 3D 重定位算法接入同一套 ROS 2 导航系统,并且根据不同场景设计了可切换的重定位模式。
这句话的含金量比单纯罗列算法高很多。
因为它体现的是工程架构能力。
算法只是零件。
系统设计才是车。
你有一堆好零件,但装不到一起,机器人照样跑不起来。
所以这个项目更像是在做一件事情:
把不同重定位算法统一接入 ROS 2 导航链路 让它们都围绕 /registered_scan、prior_pcd_file、map → odom 工作 再根据场景选择不同方案这就是工程化。
不是哪个算法厉害就永远用哪个。
而是:
场景变了,策略也要变。十一、总结:别让机器人只会一种“找家方式”
3D LiDAR 重定位,本质上是在解决机器人导航里的一个核心问题:
机器人开机以后,如何知道自己在地图中的位置?
不同算法有不同性格。
ICP:老实、直接,但依赖初值 small_gicp:更稳、更适合持续跟踪,但也需要大概初值 KISS-Matcher + small_gicp:适合无初值全局重定位,但对点云重叠和环境结构有要求所以最合理的做法不是押宝某一个算法。
而是把它们都接进系统里。
固定起点,用简单方案。
大概初值,用持续配准。
任意位置开机,用全局初始化。
这才是一个真实机器人系统该有的样子。
最后用一句话总结:
3D 重定位不是选一个最强算法,而是给机器人准备多种“找回自己”的方式。
毕竟,人迷路了还能打开地图。
机器人迷路了,只能靠我们提前把系统设计好。
不然它就会在 RViz 里自信满满,在现实里一头撞墙。
而且撞完以后,它可能还觉得:
路径规划成功。