让机器回答“我在哪”:激光雷达与 SLAM

车能看见,不等于车知道自己在哪。

画面里,黑线偏到左边,告诉它"现在歪了";编码器数出轮子转了多少圈,告诉它"走了大概多远"。这两件事加起来,仍然回答不了一个更基本的问题:我现在,在地图的哪个位置。

循迹回答的是"线在不在我下面"。这是轨道思维------线铺到哪里,车跟到哪里,位置由线提供。可一旦面前没有线,没有轨道,只有一片没走过的空间,机器要回答的第一个问题就不再是"线在哪",而是"我在哪"。

距离感是怎么来的

想知道"我在哪",先要有"离周围的东西有多远"的感觉。

激光测距有两条常见路子。一条叫飞行时间(TOF):发出一束激光,等它从障碍物弹回来,用一来一回的时间算距离------光速已知,时间就是尺子。另一条叫三角测距:发射点和接收点分开一段距离,目标反射回来的光落在接收器不同位置,用三角形的几何关系反推距离。前者适合较远、较快,后者结构简单、近距离更常见。

单个点只能回答"那个方向有多远"。让激光转起来,一个方向一个方向地扫,就得到一圈点;这些点按角度和距离排开,就是点云------机器眼里的"轮廓"。一圈一圈的轮廓拼起来,房间、走廊、桌腿,都变成点组成的地图。

SLAM:先有鸡还是先有蛋

拿到距离,只是拿到了材料。真正的问题是:这些轮廓,是站在哪儿看到的?

这就是 SLAM 的来历:Simultaneous Localization and Mapping,同时定位与建图。"同时"两个字是重点------它面对的是一个先有鸡还是先有蛋的循环:要知道自己在哪,需要一张地图;要建这张地图,又得先知道自己站在哪儿拍的。

破解这个循环,靠的是把问题拆成几段,各自往前走:

  • 前端:拿这一帧点云和上一帧比一比,算出机器刚才动了多少。像蒙着眼睛走路时,靠脚感估计自己走了几步;
  • 后端:把一小段一小段"刚才动了多少"攒成一条连续的轨迹。每一小段都有一点误差,攒久了会飘,后端负责把整条轨迹收拾得自洽;
  • 回环:走了一圈回到老地方,认出"这地方我来过"------像睁眼看见熟悉的路口,把一路积累的漂移一把拽回正轨;
  • 建图:轨迹定下来了,把一路看到的点云按轨迹叠到一起,地图才立得住。

四段合起来,才形成那个循环的出口:先大概估计自己在哪,建一个大概的地图,再用地图修正位置,用位置修正地图......每一圈都比上一圈准一点。

惯导:闭着眼睛也知道自己在动

激光雷达需要看世界------它是睁着眼睛定位。还有另一条路:完全不看外面,只靠自己的身体。

这就叫惯性导航,简称惯导。它靠两样东西:陀螺仪测"转得多快",加速度计测"被推得多猛"。把这些测量按时间积起来:加速度积成速度,速度积成位移,转动的角速度积成朝向------机器就算闭着眼睛、周围一片漆黑,也能说出"我刚刚往前挪了多少、转了多少度"。

惯导最大的优点是不依赖环境:隧道里、烟雾里、没有特征的空白走廊,它照样数得出来。高频也是它的强项,一秒钟更新几百次,两次激光扫描之间的空隙,它填得满满的。

它有一个绕不开的毛病:积分会漂。测量带一点点误差,积一次、积两次,误差也跟着长大;闭眼走直线,走久了会以为自己越走越偏。惯导自己无法发现这种漂------它没有外部参照来纠正自己。短时间准,长时间漂,这是惯导的宿命。

所以雷达和惯导是天生一对:雷达低频但绝对,看一次就告诉你"相对这堆墙,你在这";惯导高频但相对,一直在说"刚才动了多少"。惯导负责填两帧点云之间的空,雷达负责隔一段时间把惯导攒出来的漂移拽回真实位置。各管各的短处,位置才既平滑又可信。

二维和三维,差的是整个世界

扫地机器人转一圈,得到一圈线,这是二维:它知道自己在地板平面上哪一块。小车在三维世界里走,只有一圈线不够------坡、坎、头顶的树枝都在三维里。三维雷达扫的不是一条线,是一片锥形的点,再和惯导这种"知道头朝哪、动了多少"的传感器揉在一起,才撑得起一个会上下坡、会转弯的"我在哪"。维度每加一,数据的账就翻几倍。

三次转弯:最后都收进一个 UDP 地址

前面把"我在哪"的骨架讲完了:TOF 和三角测距给出距离,点云一圈圈叠成地图,惯导闭着眼也能填上两帧之间的空。原理讲得顺,可真把这件事搬上赛场,第一道坎经常很现实:一个冷冰冰、躲不掉的问题------

要有多准?

这个问题,是 26 年智能车那辆车所有定位弯路的总开关。这一段讲的,就是围着它转的三次转弯。

精度不是形容词,是硬指标

先说清楚这辆车为什么对"准"这么较真。

这辆车上的定位要拿去喂给 AR(增强现实),不能只停在"我大概在这"的程度。AR 那一头,要把车的位置精准地摆进它自己的坐标系里------车头朝哪、偏了多少、离哪根线几厘米,都要对得严丝合缝。车在真实世界里偏一厘米,AR 那边的车就偏一厘米,对不齐。

所以需求从一开始就钉死了:厘米级,苛刻的地方要到毫米级。不是"尽量准一点",是"不准就不算数"。

记住这条线------后面每一次转弯,都是被它逼的。

第一回合:在线激光 SLAM

最自然的想法,是把前面讲的那套直接搬上来:激光雷达加惯导,边建图、边定位。

硬件是祖传现成的:一只 Livox MID360,360° 的三维激光雷达;内置 IMU,陀螺仪测转得多快、加速度计测推得多猛。算法跑的是 FAST-LIO,把雷达和惯导揉在一起------雷达低频但绝对,惯导高频但相对,正好是前面说的那对互补。

原理上挑不出毛病。车一动,点云一圈圈进来,它一边拼地图、一边猜自己在地图里走到哪了,看起来水到渠成。

可跑起来,问题来了。

在线 SLAM 是"图"和"位置"两个未知数缠在一起解。地图是拿位置猜的,位置又是拿地图对的------一个错了,另一个跟着错,误差就这么一圈圈喂大。短跑一小段还像样,跑久了就漂,漂到厘米毫米级的门槛根本够不着。你要它在一条赛道上从头到尾不漂出几毫米,它做不到。

第一回合,碰壁。

第二回合:视觉标记,毫米级的诱惑

激光这条路不好走,我换了个完全相反的方向------不靠雷达了,靠眼睛。

办法是在场地上贴标记:ArUco、AprilTag 这类二维码式的图案。摄像头看到标记,算出标记在画面里的位置、大小、姿态,反推自己相对标记站哪、朝哪。这套东西理论上能做到毫米级,而且便宜、直观。

诱惑很大,死得也很快------死在哪?死在摄像头上。

毫米级是什么概念?你得让画面里一个像素对应的真实尺寸足够小,小到能分辨出一毫米的位移;同时你还得"实时",一秒钟几十帧,车才跟得上。分辨率 × 帧率 × 算力,三者是乘法。分辨率要高,数据就大;帧率要高,处理就赶;每一个毫米都要像素去兜底,每一帧都要 CPU 去算标记的角点和姿态。

一般的摄像头那点分辨率和帧率,扛不住这个乘法。不是算法错了,是硬件层面就先碰了壁------代码根本没落地,就撤了。

第二回合,也碰壁。

第三回合:回到激光,但一开始没人想建图

两条路都死了,兜兜转转,又回到激光雷达。但这次换了个玩法:先建图、再导航。

这一步不是我"想通了"才走,是被逼到墙角、实在没辙了才走的。因为建图这条路,从一开始就有三个让人想躲的理由:

第一,图是场地的。我们全程离线调试,能建图的只有自己的调试场地,比赛场地赛前根本拿不到。你辛辛苦苦建一张图,到了现场用不上。

第二,图带不走,还总要重来。那阵子要换两三个地方调试,每换一个地方,旧图就废了,得重新扫、重新建。建图不是点一下按钮,是慢速反复跑、一圈圈回环,磨出来的。

第三,也是最重要的------我心里不服。总觉得"定位"这回事应该做得更聪明、更通用一点,而不是靠一张只能在一个房间里用的地图。所以一开始,我是能绕就绕,压根不想碰建图。

可绕到最后,在线 SLAM 精度不够,视觉标记撞了硬件,绕无可绕,才被迫认下"先建图、再导航"这条路。

真走起来,它其实是对的。关键就在于把"建图"和"定位"这两个缠在一起的问题,硬拆成两段:

  • 先建图:车在场地里慢慢跑、反复扫、多圈回环,趁离线、不受比赛节奏逼的时候,把地图磨到足够准------这一步可以慢,可以返工;
  • 再导航:运行时,地图已经固定了,车上只剩"我现在在这张图里哪一点"一个问题要解。

在线 SLAM 是两个未知数互相拖累;拆开之后,运行时只剩一个未知数,求解空间小了一大截,精度和稳定性都上去了。说白了:用离线的时间,换运行时的精度。

那辆车:两条线,一个 UDP 地址

到这儿,定位还没停在"先建图再导航"上,真正值钱的还有下一层。

真正让这辆车跑通的,不是某个算法的胜利,而是一开始就摆在那里的一个设计------视觉和定位,是两条独立、方向相反的线,而把它们接起来的,不是融合,是一个 UDP 地址。

先看那两条线:

一条是 AR 给车:AR 系统把画面送进来,车从共享内存里读帧,跑检测和分割,回答"眼前有什么"------这是视觉那篇讲的那半。

一条是 车给 AR:车把激光加惯导算出来的位置,打包好,通过 UDP 报给 AR,回答"我在哪"------这是这段讲的那半。

一条吃 AR 的画面,一条喂 AR 的位置。它们从一开始就是独立的,各答各的问题。

真正的手腕,藏在车给 AR 的那条线里:官方只给了一个 UDP 地址,加一套固定的 payload 格式。它把"定位"这件事,定义成了一个接口------一个地址、一种格式,至于这个位姿是"谁算的、怎么算的",AR 那边根本不在乎。

于是,供给侧和消费侧被彻底解耦了:

  • 调试的时候,我拿自己的激光 SLAM 填这个地址------先建图、再导航,把位姿算出来,按官方的格式发过去;
  • 到了比赛现场,官方换上他们自己的定位系统------一个黑盒,我不需要知道它是什么、怎么工作的------只要往那个地址里送进精确的位姿,AR 就马上能定位。

换实现,不动接口。车侧那一大堆折腾------在线 SLAM、视觉标记、先建图再导航------最后都收敛成了同一个能力:把位姿算准,送到那个地址。而官方之所以能这么设计,就是因为它只认接口,不认实现;谁算得准,谁就接上,剩下的都是黑盒。

接口这件事,我其实一直明白------官方要的从来不是"我算得多漂亮",只是"往这个地址报得够准"。可明白归明白,心里还是不甘心只当一个"往地址里送位姿"的模块,总想连地址背后的事也自己扛:在线 SLAM 想一次解两个未知数,视觉标记想绕开激光,撞了两堵墙,才肯回到"先建图再导航"这条更实际的路上。绕远路的根子不在不懂接口,在于总想证明自己能把定位从头做透。

回头看,三次转弯指向的其实是同一句话:系统的上限,往往不在单个环节多先进,在接口划得多干净、变化藏得多深。在线 SLAM 输给了精度,视觉标记输给了硬件,最后能跑通的,是那个"把位姿算准、往一个地址送"的基本功------因为它正对上了官方留的那个口。

这跟视觉那篇、跟整个嵌入式方向,都是同一个道理:拼到最后,拼的不是谁聪明,是谁先撞够了墙,然后绕对了路。

什么时候才值得上这套

SLAM 很漂亮,但它不是所有任务的答案。

只要任务里还有线可循------黑线、轨道、固定路线------循迹那套更便宜、更稳:DO 说线在哪,编码器说轮子转了多少,就够用了。SLAM 回答的是另一类问题:没有线,没有预设地图,没有形状都差不多的赛道,机器要在没走过的空间里自己走,还要始终知道自己在哪。送药的机器人、探索的车、无人驾驶,都属于这一类。

上不上 SLAM,先问三件事:任务里有没有"线"?没有,才轮到考虑它;定位错了后果多严重------扫地机走歪一点没关系,载人的车不行;你的算力和钱包,扛不扛得住又一路点云和惯导数据的账。型号不必现在记,等真需要时,按"要几维、要什么精度、预算多少"去挑就行。

把这张网收一收

把这一路传感器摆在一起看,它们回答的根本不是同一个问题:DO 说线在哪,编码器说轮子转了多少,陀螺和惯导说头朝哪、闭着眼也数得出动了多少,视觉说眼前有什么,雷达和 SLAM 说我在哪。单看任何一个,都只是一个小问题的小答案;把它们织在一起,机器才第一次有了"我在这片世界里,正往那里去"的自觉。前面学的每一块,都是这张网上的一根线。

最后橘猫说

距离感从 TOF 和三角测距来,扫成点云;惯导闭着眼、靠积分说自己动了多少,短时准、长时漂;SLAM 把"我在哪"和"地图长什么样"这对鸡生蛋的问题,拆成前端、后端、回环、建图四段慢慢解,再用雷达把惯导的漂移拽回来。视觉回答"有什么",定位回答"我在哪"。当任务里没有线可循时,才轮到它们上场。

最后蜘蛛说

这不是STM32的范畴了,但是搞嵌入式总得了解得多一些嘛。

相关推荐
wuyk5551 小时前
样章-第10讲-看门狗异常恢复与卡机排查方法论
stm32·单片机·嵌入式硬件·重构
半杯咖啡半行码15 小时前
STM32之ARM通用汇编指令详解:从指令格式到寻址方式
汇编·arm开发·stm32
创界工坊工作室15 小时前
22-基于STM32的汽车防盗系统设计
stm32·单片机·嵌入式硬件·proteus
雨田言炎17 小时前
STM32之RCC系统时钟控制(芯片的心脏控制器)
stm32·单片机·嵌入式硬件
额额额对了18 小时前
IMX6ULL 杂项设备 LED 驱动
stm32·单片机·嵌入式硬件
半杯咖啡半行码19 小时前
STM32开发之IIC通信详解:从协议基础到FM24CL04实战
stm32·单片机·嵌入式硬件
硅基手札20 小时前
【I2C 技术系列 05】I2C 多主仲裁与时钟同步
驱动开发·stm32·单片机·嵌入式硬件·mcu·计算机外设
Zw-awa20 小时前
DO 和 AO 到底怎么选:比较器替你决定了什么
stm32
硅基手札21 小时前
【I2C 技术系列 01】I2C 电气特性与物理层
驱动开发·stm32·单片机·嵌入式硬件·mcu·计算机外设