3、传感器原理与特性(下):轮式里程计原理、视觉里程计(VO)简介、激光雷达(LiDAR)原理、点云数据格式
好,咱们接着聊传感器。上一节我们把惯性测量单元(IMU)和磁力计扒了个底朝天,这一节轮到另外三个“狠角色”了:轮式里程计、视觉里程计(VO)和激光雷达(LiDAR)。
说实话,在真正的多传感器融合项目里,这三个传感器经常是“救火队员”。IMU 漂移了?靠它们来修正。GPS 丢了?靠它们来续命。我个人习惯把轮式里程计叫做“穷人的高精度定位”,而激光雷达则是“富人的上帝视角”。
咱们一个一个来,先讲最接地气的。
3.1 轮式里程计原理
轮式里程计,说白了就是靠车轮转了多少圈来推算车走了多远。你想想看,自行车上那个码表,就是最原始的轮式里程计。
它的核心原理其实就一个公式:距离 = 轮子周长 × 转过的圈数。但在机器人或自动驾驶车上,事情要复杂一些。我们通常用左右轮的编码器来推算。
核心模型:差速驱动模型
假设左右轮半径均为 r,左右轮转速分别为 ω_L 和 ω_R,轮距为 b。
那么:
- 线速度 v = (ω_L * r + ω_R * r) / 2
- 角速度 ω = (ω_R * r - ω_L * r) / b
有了 v 和 ω,积分就能得到位置和姿态。
嗯,这里要注意。我在项目中遇到过一个问题:轮子打滑。有一次在瓷砖地面上做测试,轮子空转,编码器疯狂计数,但车纹丝不动。结果定位轨迹直接飞到了墙外面。所以,轮式里程计在越野、湿滑路面下,基本就是“睁眼说瞎话”。
避坑指南:我曾经在工厂AGV项目里吃过亏。AGV在重载急刹车时,轮子会在地面滑行一小段。编码器认为停了,但实际还在滑。后来我加了加速度计做“打滑检测”,一旦检测到加速度异常,就降低里程计的置信度。
轮式里程计的优点很明显:短距离内精度极高(千分之一级别),更新频率快(100Hz以上)。缺点也致命:存在累积误差,且无法消除。说白了,它只能告诉你“相对”走了多远,不知道“绝对”在哪。
3.2 视觉里程计(VO)简介
视觉里程计,就是用摄像头来“看”自己走了多远。它的思路很直观:我盯着墙上那个斑点,我往右走,斑点就在图像里往左移。通过计算这些特征点的移动,反推出相机的运动。
VO 的流程,我习惯总结为四步走:
- 特征提取:从图像里找角点、斑点等“地标”。常用的有 ORB、SIFT、SURF。
- 特征匹配:把上一帧的特征点和这一帧的对应上。
- 运动估计:根据匹配点对,用对极几何或PnP算法算出相机位姿变化。
- 局部优化:用光束法平差(BA)来消除噪声,让轨迹更平滑。
你可能会问:为什么不用深度学习?其实深度学习在特征匹配上确实更强,但实时性是个大问题。在嵌入式平台上,传统的 ORB-SLAM 依然能打。
注意:VO 最怕什么?怕纹理缺失。你拿摄像头对着白墙,VO 直接就“失明”了。还有快速旋转时,图像模糊,特征点全丢了。我做过一个测试,在纯色走廊里,VO 的定位误差在10秒内就超过了2米。
我个人觉得,VO 是“上限很高,下限很低”的传感器。光照好、纹理丰富时,它能达到厘米级精度。但一旦环境恶劣,它还不如一个便宜的轮式编码器靠谱。
3.3 激光雷达(LiDAR)原理
激光雷达,简称 LiDAR。它就像蝙蝠的回声定位,只不过用的是激光。发射一束激光,打到物体上反射回来,通过测量飞行时间(TOF)或相位差,算出距离。
LiDAR 的核心参数有几个:
| 参数 | 说明 | 常见值 |
|---|---|---|
| 线数 | 激光束的数量,16线、32线、64线、128线 | 16线(入门)、64线(主流) |
| 测量距离 | 最远能测多远 | 100m ~ 300m |
| 精度 | 单点测距误差 | ±2cm(典型值) |
| 视场角 | 水平和垂直的扫描范围 | 水平360°,垂直30°~40° |
| 点频 | 每秒发射的激光点数 | 30万点/秒 ~ 200万点/秒 |
为什么 LiDAR 在自动驾驶里这么火?因为它直接给你 3D 点云,不需要像视觉那样去“猜”深度。说白了,它自带深度信息,而且不受光照影响。晚上、雨天(小雨)都能正常工作。
我的经验:LiDAR 虽然精度高,但也不是万能的。它对玻璃、镜面、水面基本无效——激光直接穿透或反射走了。有一次在商场测试,机器人对着玻璃门直接撞了上去,因为 LiDAR 认为那里是空的。
3.4 点云数据格式
聊完原理,咱们得说说数据怎么存。LiDAR 采集到的原始数据就是点云。最常见的格式是 PCD(Point Cloud Data)和 PLY(Polygon File Format)。
一个标准的点云文件,里面存的是啥?
- xyz:每个点的三维坐标
- intensity:反射强度,可以用来区分不同材质
- ring:属于哪条激光线(对于多线 LiDAR)
- timestamp:时间戳,用于同步
下面是一个简单的 PCD 文件示例:
# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z intensity ring
SIZE 4 4 4 4 2
TYPE F F F F U
COUNT 1 1 1 1 1
WIDTH 100
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 100
DATA ascii
1.234 2.345 3.456 120 0
1.235 2.346 3.457 130 0
...
嗯,这里要注意。在实际工程中,我们很少直接读写文本格式的 PCD,太慢了。一般用 二进制格式 或者直接用 ROS 的 sensor_msgs::PointCloud2 消息。我个人习惯在 C++ 里用 PCL 库(Point Cloud Library)来处理点云,它封装好了所有读写、滤波、配准的接口。
小技巧:如果你拿到一个点云文件,第一件事不是做算法,而是先可视化看看有没有“飞点”(离群噪声)。用 PCL 的 pcl::visualization::CloudViewer 扫一眼,能省掉你后面很多调试的麻烦。
最后,我画了一张图,把这三个传感器在融合定位里的角色串起来。你可以看到,它们各有各的“主场”,也各有各的“盲区”。融合的目的,就是让它们互相补位。
好了,这一节的内容就到这。轮式里程计、视觉里程计、激光雷达,这三个传感器各有脾气。你只有摸透了它们的“性格”,才能在融合的时候用好它们。