2. 无人机系统基础

做机器人避障,第一步不是写算法,而是搞清楚——你凭什么感知这个世界。

我入行那会儿,有个项目选了纯视觉方案,结果在强光车间里直接瞎了。从那以后,我对传感器选型就特别较真。今天咱们就聊聊三种最常见的传感器:激光雷达、摄像头、超声波,以及怎么把它们的数据揉在一起用。

传感器三兄弟

先看一张总览图,把三者的核心差异说清楚。

传感器三兄弟对比框架 激光雷达 摄像头 超声波 核心特性 • 精度:±2cm • 范围:0.1-100m • 频率:10-50Hz • 输出:点云 核心特性 • 精度:像素级 • 范围:0.1-∞ • 频率:15-60fps • 输出:图像 核心特性 • 精度:±3cm • 范围:0.02-5m • 频率:20-50Hz • 输出:距离值 适用场景 建图、定位、远距避障 适用场景 目标识别、车道线、交通灯 适用场景 近距盲区、透明物体检测 数据融合 → 鲁棒的环境感知

激光雷达:精度之王

激光雷达,说白了就是拿激光束扫一圈,测出每个点的距离。它输出的是点云——一堆三维坐标点。

我个人习惯把激光雷达分成两类:

  • 机械式:旋转扫描,360°覆盖。典型如Velodyne、Hesai。精度高,但有机械磨损。
  • 固态式:用光学相控阵或MEMS镜片,无旋转部件。体积小,寿命长,但视场角有限。

关键参数:选型时我主要看三个数——线数(16线、32线、64线)、测距精度(±2cm以内算合格)、帧率(至少10Hz才能跟上移动机器人)。

我在项目中遇到过最头疼的问题:激光雷达在雨雪天会打出一堆噪点。水滴反射激光,点云里全是飘着的假目标。后来加了滤波算法,才勉强压下去。

摄像头:信息最丰富

摄像头给的是图像,信息量最大。你能从一张图里认出障碍物是人是车还是垃圾桶。但有个致命弱点——没有深度信息。

怎么补深度?常见做法:

  • 单目+深度学习:用神经网络估深度,精度一般,胜在便宜。
  • 双目立体视觉:两个摄像头算视差,精度高但计算量大。
  • RGB-D相机:比如Kinect、Intel RealSense,直接输出深度图,但室外强光下基本废掉。

我的经验:如果你做室内AGV,RGB-D够用。室外无人车,老老实实上双目或激光雷达。别指望单目深度估计能用在安全关键场景——我吃过这个亏。

超声波:近距守护神

超声波传感器,原理就是发射声波、等回波、算时间。它精度不高,但有两个独特优势:

  1. 不怕透明物体——玻璃、亚克力板,激光雷达打上去直接穿透,超声波能检测到。
  2. 近距盲区补全——激光雷达最近探测距离通常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。融合时按置信度加权,比硬切换平滑得多。

好了,环境感知这块就聊到这儿。传感器选型没有银弹,关键看你做什么场景、预算多少、精度要求多高。数据融合也不是越复杂越好,有时候一个简单的加权平均,比花里胡哨的神经网络更稳定。