跳转至

近距离传感器

概述

近距离传感器用于检测机器人周围短距离(通常 <5m)的障碍物、悬崖和物理接触。它们是机器人安全系统的最后防线,在扫地机器人、服务机器人和工业机器人中大量使用。

红外接近传感器

工作原理

红外接近传感器发射调制红外光,通过检测反射光的强度或位置来测量距离。

反射式测距

\[ I_{\text{received}} \propto \frac{\rho}{d^2} \]

其中 \(\rho\) 为目标表面反射率,\(d\) 为距离。接收信号强度随距离平方衰减。

Sharp GP2Y0A21YK0F

最经典的红外测距传感器,采用三角测距法。

参数
测距范围 10–80 cm
输出 模拟电压(与距离非线性关系)
响应时间 ~39 ms
供电 4.5–5.5V
电流 ~30 mA
尺寸 29.5 × 13 × 13.5 mm
价格 ~$10

电压-距离关系(近似):

\[ d = \frac{a}{V - b} \]

其中 \(V\) 为输出电压,\(a\)\(b\) 为经验系数(需标定)。

import numpy as np

def sharp_gp2y0a21_distance(voltage):
    """
    Sharp GP2Y0A21 电压转距离
    voltage: ADC 读取电压 (V)
    返回距离 (cm)
    """
    if voltage < 0.4 or voltage > 3.1:
        return None  # 超出有效范围

    # 经验公式(需要根据实际标定调整)
    distance = 29.988 * pow(voltage, -1.173)
    return distance

其他红外传感器

型号 范围 输出 特点 价格
GP2Y0A21 10–80cm 模拟 经典通用 ~$10
GP2Y0A02 20–150cm 模拟 远距离 ~$12
GP2Y0A41SK 4–30cm 模拟 近距离 ~$8
TCRT5000 1–25mm 模拟 反射式,适合循线 ~$0.5

超声波传感器

工作原理

发射超声波脉冲(通常 40kHz),测量回波时间来计算距离:

\[ d = \frac{v_s \cdot t}{2} \]

其中 \(v_s \approx 343 \, \text{m/s}\)(20°C 空气中声速)。

声速与温度

声速随温度变化:\(v_s = 331.3 + 0.606 \cdot T\)(m/s),其中 \(T\) 为摄氏温度。精确测距需要温度补偿。

HC-SR04

最常用的超声波测距模块。

参数
测距范围 2–400 cm
精度 ±3 mm
测量角度 ~15°(锥形波束)
工作频率 40 kHz
触发方式 10μs 高电平脉冲
供电 5V
电流 ~15 mA
价格 ~$2

使用方式

  1. 向 Trigger 引脚发送 >10μs 的高电平脉冲
  2. 模块自动发送 8 个 40kHz 超声波脉冲
  3. Echo 引脚输出高电平,持续时间等于回波时间
import RPi.GPIO as GPIO
import time

TRIG = 23
ECHO = 24

def measure_distance():
    """HC-SR04 测距"""
    GPIO.output(TRIG, True)
    time.sleep(0.00001)  # 10μs 触发脉冲
    GPIO.output(TRIG, False)

    # 等待 Echo 高电平开始
    while GPIO.input(ECHO) == 0:
        pulse_start = time.time()

    # 等待 Echo 高电平结束
    while GPIO.input(ECHO) == 1:
        pulse_end = time.time()

    duration = pulse_end - pulse_start
    distance = duration * 34300 / 2  # cm

    return distance

超声波的局限性

问题 原因 影响
锥形波束 超声波扩散角 ~15° 角分辨率低,小物体可能漏检
镜面反射 光滑斜面将声波反射偏离 测距失败
吸声材料 布料、泡沫吸收声波 无回波
串扰 多个超声波模块相互干扰 需要时分复用
最小距离 发射和接收需要时间间隔 盲区 ~2cm

ToF 接近传感器

工作原理

使用激光 ToF 测量微型化方案,发射 VCSEL 激光,SPAD 探测器接收。

VL53L0X

STMicroelectronics 出品的微型 ToF 传感器。

参数
测距范围 30–2000 mm
精度 ±3%(长距离模式)
FOV 25°(锥形)
光源 940nm VCSEL
接口 I2C
测量速率 最高 50Hz
供电 2.6–3.5V
尺寸 4.4 × 2.4 × 1.0 mm
价格 ~$3

VL53L1X(升级版)

参数
测距范围 40–4000 mm
FOV 27°(可编程 ROI)
测量速率 最高 50Hz
多区域 支持 4×4 区域检测
价格 ~$4
import board
import adafruit_vl53l0x

# I2C 初始化
i2c = board.I2C()
sensor = adafruit_vl53l0x.VL53L0X(i2c)

# 读取距离
distance_mm = sensor.range
print(f"距离: {distance_mm} mm")

# 设置测量模式
sensor.measurement_timing_budget = 200000  # 200ms,高精度模式

悬崖传感器(Cliff Sensor)

作用

悬崖传感器是扫地机器人、服务机器人等移动平台上的关键安全传感器,用于检测地面的突然下降(楼梯、台阶边缘),防止机器人跌落。

工作原理

使用向下照射的红外反射传感器,检测地面反射信号:

  • 正常地面:红外光被反射回来,接收信号强
  • 悬崖/台阶:红外光射向远处,反射信号极弱或无
\[ \text{Cliff detected} \iff I_{\text{received}} < I_{\text{threshold}} \]

典型配置

扫地机器人通常在底部前方安装 3–6 个悬崖传感器:

graph TD
    subgraph "扫地机器人底部视图(前方朝上)"
    direction TB

    A["前方左 ●"] --- B["前方中 ●"] --- C["前方右 ●"]
    D["侧方左 ●"] --- E["(底盘)"] --- F["侧方右 ●"]
    end

    style A fill:#ff6666
    style B fill:#ff6666
    style C fill:#ff6666
    style D fill:#ff9966
    style F fill:#ff9966

常用传感器

型号 类型 检测距离 说明 价格
TCRT5000 红外反射 1–25mm 最常用 ~$0.5
ITR9608 红外反射 1–15mm 小型封装 ~$0.3
QRD1114 红外反射 1–10mm 分立式 ~$1

悬崖检测的可靠性

悬崖传感器是安全关键传感器。注意以下失效场景:

  • 深色地面:黑色地毯/地面可能被误判为悬崖
  • 透明地面:玻璃地面无法反射红外光
  • 传感器脏污:灰尘覆盖导致信号衰减
  • 强环境光:直射阳光可能干扰红外检测

实际产品中通常采用多传感器冗余 + 保守策略来保证安全。

碰撞传感器(Bumper)

工作原理

碰撞传感器是最简单的近距离检测方式——物理接触触发。通常使用微动开关或触力传感器。

类型

类型 原理 优点 缺点
微动开关 机械触点 简单、可靠、成本低 需要物理接触
力敏电阻 电阻随压力变化 可以感知力度 需要 ADC
电容式 接近改变电容 非接触(~1cm) 环境敏感
压电式 压电效应 灵敏、响应快 信号处理复杂

扫地机器人碰撞传感器

大多数扫地机器人使用前部的弧形 bumper,内部安装微动开关或光电开关:

# 简单的 bumper 中断处理
import RPi.GPIO as GPIO

BUMPER_LEFT = 17
BUMPER_RIGHT = 27

def bumper_callback(channel):
    if channel == BUMPER_LEFT:
        print("左侧碰撞!后退并右转")
        # motor.backward()
        # motor.turn_right()
    elif channel == BUMPER_RIGHT:
        print("右侧碰撞!后退并左转")
        # motor.backward()
        # motor.turn_left()

GPIO.setup(BUMPER_LEFT, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(BUMPER_RIGHT, GPIO.IN, pull_up_down=GPIO.PUD_UP)

GPIO.add_event_detect(BUMPER_LEFT, GPIO.FALLING, 
                      callback=bumper_callback, bouncetime=200)
GPIO.add_event_detect(BUMPER_RIGHT, GPIO.FALLING, 
                      callback=bumper_callback, bouncetime=200)

扫地机器人传感器布局

graph TD
    subgraph "扫地机器人传感器系统"

    subgraph "顶部"
    L["LiDAR<br/>2D 激光雷达<br/>360° SLAM"]
    end

    subgraph "前部"
    B["Bumper<br/>碰撞传感器<br/>左/右区分"]
    IR["红外/ToF<br/>前方避障<br/>3-5cm~2m"]
    end

    subgraph "底部"
    C1["悬崖传感器 ×4-6<br/>IR反射式<br/>防跌落"]
    W["轮式编码器 ×2<br/>里程计"]
    end

    subgraph "侧面"
    WALL["沿墙传感器<br/>IR/ToF<br/>保持墙距"]
    end

    end

传感器协作逻辑

class VacuumRobotSafety:
    """扫地机器人安全传感器管理"""

    def __init__(self):
        self.cliff_threshold = 100   # ADC 阈值
        self.wall_distance = 50      # mm
        self.obstacle_distance = 200  # mm

    def check_cliff(self, cliff_sensors):
        """检查悬崖传感器,任一触发则紧急停止"""
        for i, value in enumerate(cliff_sensors):
            if value < self.cliff_threshold:
                return True, i  # 检测到悬崖
        return False, -1

    def check_bumper(self, bumper_left, bumper_right):
        """检查碰撞传感器"""
        if bumper_left and bumper_right:
            return 'front'   # 正面碰撞
        elif bumper_left:
            return 'left'    # 左侧碰撞
        elif bumper_right:
            return 'right'   # 右侧碰撞
        return None

    def safety_loop(self, sensors):
        """安全检查主循环 - 优先级最高"""
        # 1. 悬崖检测(最高优先级)
        cliff_detected, cliff_id = self.check_cliff(
            sensors['cliff'])
        if cliff_detected:
            return 'EMERGENCY_STOP', f'Cliff at sensor {cliff_id}'

        # 2. 碰撞检测
        bump = self.check_bumper(
            sensors['bumper_left'], 
            sensors['bumper_right'])
        if bump:
            return 'BACKUP_AND_TURN', bump

        # 3. 接近障碍物
        if sensors['front_tof'] < self.obstacle_distance:
            return 'SLOW_DOWN', sensors['front_tof']

        return 'NORMAL', None

传感器综合对比

传感器 范围 精度 速率 成本 优势 劣势
Sharp IR 10–80cm ±1cm 25Hz $10 简单可靠 受光照影响
HC-SR04 2–400cm ±3mm 20Hz $2 便宜 角分辨率低
VL53L0X 3–200cm ±3% 50Hz $3 小巧、数字输出 范围有限
Cliff IR 1–25mm 检测级 $0.5 极低成本 仅检测有/无
Bumper 0cm 接触 $0.5 最可靠 需物理接触

ROS2 集成

Range 消息

# sensor_msgs/msg/Range
Header header
uint8 radiation_type        # ULTRASOUND=0, INFRARED=1
float32 field_of_view       # 检测锥角 (rad)
float32 min_range           # 最小距离 (m)
float32 max_range           # 最大距离 (m)
float32 range               # 当前距离 (m)

发布传感器数据

from sensor_msgs.msg import Range

def publish_ultrasonic(self, distance_m):
    msg = Range()
    msg.header.stamp = self.get_clock().now().to_msg()
    msg.header.frame_id = 'ultrasonic_front'
    msg.radiation_type = Range.ULTRASOUND
    msg.field_of_view = 0.26  # ~15°
    msg.min_range = 0.02
    msg.max_range = 4.0
    msg.range = distance_m
    self.range_pub.publish(msg)

参考资料

  • Sharp GP2Y0A21 数据手册
  • HC-SR04 技术文档
  • STMicroelectronics VL53L0X/VL53L1X 数据手册
  • iRobot Roomba 开放接口规范
  • ROS2 sensor_msgs 文档

评论 #