环境感知基础:传感器类型与数据融合
做机器人避障,第一步不是写算法,而是搞清楚——你凭什么感知这个世界。
我入行那会儿,有个项目选了纯视觉方案,结果在强光车间里直接瞎了。从那以后,我对传感器选型就特别较真。今天咱们就聊聊三种最常见的传感器:激光雷达、摄像头、超声波,以及怎么把它们的数据揉在一起用。
传感器三兄弟
先看一张总览图,把三者的核心差异说清楚。
激光雷达:精度之王
激光雷达,说白了就是拿激光束扫一圈,测出每个点的距离。它输出的是点云——一堆三维坐标点。
我个人习惯把激光雷达分成两类:
- 机械式:旋转扫描,360°覆盖。典型如Velodyne、Hesai。精度高,但有机械磨损。
- 固态式:用光学相控阵或MEMS镜片,无旋转部件。体积小,寿命长,但视场角有限。
关键参数:选型时我主要看三个数——线数(16线、32线、64线)、测距精度(±2cm以内算合格)、帧率(至少10Hz才能跟上移动机器人)。
我在项目中遇到过最头疼的问题:激光雷达在雨雪天会打出一堆噪点。水滴反射激光,点云里全是飘着的假目标。后来加了滤波算法,才勉强压下去。
摄像头:信息最丰富
摄像头给的是图像,信息量最大。你能从一张图里认出障碍物是人是车还是垃圾桶。但有个致命弱点——没有深度信息。
怎么补深度?常见做法:
- 单目+深度学习:用神经网络估深度,精度一般,胜在便宜。
- 双目立体视觉:两个摄像头算视差,精度高但计算量大。
- RGB-D相机:比如Kinect、Intel RealSense,直接输出深度图,但室外强光下基本废掉。
我的经验:如果你做室内AGV,RGB-D够用。室外无人车,老老实实上双目或激光雷达。别指望单目深度估计能用在安全关键场景——我吃过这个亏。
超声波:近距守护神
超声波传感器,原理就是发射声波、等回波、算时间。它精度不高,但有两个独特优势:
- 不怕透明物体——玻璃、亚克力板,激光雷达打上去直接穿透,超声波能检测到。
- 近距盲区补全——激光雷达最近探测距离通常0.1m,超声波可以到2cm。
嗯,这里要注意:超声波有锥角,一般是15°-30°。两个物体靠太近,回波会混在一起,你分不清是一个还是两个。
避坑指南:我曾经在自动泊车项目里,超声波被地面反射干扰,明明前面没东西,系统硬是刹停了。后来加了多回波解析和置信度判断才解决。别信单次回波,一定要做多帧验证。
数据融合:1+1>2
单个传感器都有短板。激光雷达怕雨雪、摄像头怕光照、超声波怕干扰。所以得融合。
数据融合分三个层级:
| 层级 | 做法 | 典型方法 | 我推荐指数 |
|---|---|---|---|
| 数据级 | 原始数据直接拼接 | 点云+图像像素对齐 | ⭐⭐ |
| 特征级 | 提取特征后再融合 | 边缘+深度聚类 | ⭐⭐⭐⭐ |
| 决策级 | 各自出结果再投票 | 卡尔曼滤波、贝叶斯 | ⭐⭐⭐ |
我个人最常用特征级融合。举个例子:摄像头检测到前方有个行人轮廓,激光雷达在那个方向测到距离2.3m。把这两个信息对齐,你就知道——前方2.3m处有行人。比单用任何一个都靠谱。
核心原则:融合不是简单叠加,而是互补短板。激光雷达给距离,摄像头给语义,超声波补盲区。各司其职,才能构建鲁棒的环境模型。
一个简单的融合示例
假设你有一个激光雷达和一个超声波。激光雷达每50ms出一帧点云,超声波每20ms出一个距离值。怎么融合?
// 伪代码:激光雷达+超声波融合
void sensorFusion() {
// 1. 时间对齐
auto lidarData = getLatestLidarFrame(); // 最近一帧点云
auto sonarData = getLatestSonarReading(); // 最近一次超声波读数
// 2. 空间对齐(假设传感器已标定)
float sonarAngle = sonarData.angle; // 超声波安装角度
float sonarRange = sonarData.range; // 超声波测距值
// 3. 检查激光雷达在该方向是否有有效点
bool lidarHasPoint = lidarData.hasPointAtAngle(sonarAngle);
float lidarRange = lidarData.getRangeAtAngle(sonarAngle);
// 4. 融合决策
if (lidarHasPoint && abs(lidarRange - sonarRange) < 0.1) {
// 两者一致,取高精度值(激光雷达)
finalRange = lidarRange;
} else if (lidarHasPoint && lidarRange > 0.5) {
// 激光雷达有值但超声波没检测到?可能是透明物体
finalRange = sonarRange; // 信任超声波
} else {
// 只有一方有数据,直接使用
finalRange = lidarHasPoint ? lidarRange : sonarRange;
}
// 5. 输出融合后的障碍物距离
publishObstacle(sonarAngle, finalRange);
}
这段代码看着简单,但实际工程里要考虑更多:传感器标定、时间戳同步、异常值剔除……不过核心逻辑就是这个——谁可靠信谁。
小技巧:我习惯给每个传感器加一个置信度字段。激光雷达在雨天的置信度自动降到0.6,超声波在强风环境降到0.4。融合时按置信度加权,比硬切换平滑得多。
好了,环境感知这块就聊到这儿。传感器选型没有银弹,关键看你做什么场景、预算多少、精度要求多高。数据融合也不是越复杂越好,有时候一个简单的加权平均,比花里胡哨的神经网络更稳定。