交互式模拟器中级

面向移动机器人的障碍物规避模拟器

这是一款面向树莓派项目的避障机器人模拟器,可以用来学习反应式导航、距离感知,以及如何在撞上障碍物之前安全停下来。

类别
Raspberry Pi
时长
2–3 小时
平台
浏览器 · Raspberry Pi
面向移动机器人的障碍物规避模拟器 技术示意图CLEARANCE FIELD

01 / 从这里开始

简介

避障就是把不完整、带噪声的测量转化为安全的运动。这个项目把感知、安全和转向分成独立的层,让你在部署一台移动机器人之前,能逐层想清楚每一层。模拟器会把传感器覆盖范围、停车距离和各种失效情形都摆出来,而不是假装一条反应式规则就能解决所有导航问题。

Live lab / Reactive range-sensing navigation

Obstacle avoidance simulator

Drive a mobile robot toward the goal while a fan of range sensors keeps it clear of obstacles. Reposition the scene by dragging or with the coordinate controls, add noise, and compare two steering rules.

Browser native
A top-down obstacle-avoidance robot simulator. Use the controls below to run it, or read the full theory and algorithm after this lab.

Lines are sensor rays; a brighter ray marks the nearest reading. The dashed line ahead is the predicted stopping distance. The green ring is the goal. Drag a scene item or use the position controls below.

Simulation

Paused. Press Start or Step to begin.

Robot & sensing
Scene position
Status
Seeking
Distance to goal
630 px
Min clearance
170 px
Stopping distance
24 px
Elapsed
0.0 s

Keyboard: focus the workspace, then use Space to run/pause, N to step, R to reset, D to add an obstacle, and F for full screen.

控件

工作区里包含可移动的障碍物、机器人速度、感知距离、视场角、测量噪声和一个安全距离阈值。传感器射线和预测出的停车距离始终保持可见。逐步模式会准确揭示每一次转向决策是由哪一次观测触发的。

原理

机器人必须在它扫过的区域与障碍相交之前停下或转向。安全距离取决于当前速度、控制器延迟、制动能力、测量不确定性以及机器人的物理半径——而不只是最近一次的测距值。

所需安全距离随机器人速度变化的折线图。反应距离分量随速度线性增长,但总所需距离向上弯曲,因为刹车项随速度的平方增长。图中一条水平线标出固定的机器人半径加上安全裕量。
所需净空上升得比速度更快:反应距离是线性的,而刹车距离随 v² 增长,所以速度只要略微提高,就需要大得多的安全间隙。 下载 SVG

势场这类反应式控制器把附近的障碍变成斥力矢量,把目标变成引力矢量。它们响应很快,但可能被困在局部极小值里。实用的做法是把反应式的安全层与一个全局或局部规划器配在一起。

算法

  1. 剔除过期的、物理上不可能的测距样本。
  2. 把有效的观测变换到机器人坐标系。
  3. 把每个障碍按机器人半径加上安全裕量膨胀。
  4. 由速度和估计的减速度算出停车距离。
  5. 前方走廊不安全就停车;否则朝与目标对齐的最空旷扇区转向。
  6. 在发出电机指令之前限制加速度和角速度。

源代码

把紧急决策写得足够小,以便穷举测试:

def safe_velocity(target, ranges, stop_distance):
    front = [r for angle, r in ranges if abs(angle) < 0.35]
    if not front or min(front) <= stop_distance:
        return 0.0, choose_clear_turn(ranges)
    return limit_acceleration(target), steer_toward_clearance(ranges)

在真实系统里,要记录传感器时间戳,并在所需数据变得不可用时进入一个安全停车状态。

假设与硬件差异

这个世界是俯视的、二维的:传感器射线是瞬时的、完美细的,而且永远不会被机器人自己的身体遮挡;机器人是一个可以刹到零而没有惯量的圆盘。在一台树莓派车上,超声波束会扩散 15°,飞行时间读数取决于表面材质和阳光,而停车距离由真实质量、电机扭矩和感知—决策—执行延迟决定——这些都在反应式导航路线里讲过。模拟器还忽略了回路抖动和电源压降,所以请把停车距离曲线当成需要记住的形状,而不是可以直接照抄的数字。

电路图

任何 5 V 回波信号在到达树莓派 GPIO 之前都要先做电平转换。电机单独供电,并把地线在一个刻意选定的公共点连接起来。

避障传感器架构的框图。经 GPIO 或 I²C 接入的测距传感器、经 CSI 接入的相机,以及经 GPIO 接入的轮子编码器,都汇入一台树莓派。树莓派通过 PWM 和方向线驱动电机驱动器,再由电机驱动器给电机供电。
感知、计算和执行彼此分离:多个感知通道汇入树莓派,树莓派再通过一个独立供电的隔离驱动器驱动电机。 下载 SVG

引导实验

1. 推导停车阈值,而不是猜一个

把速度设低,然后降低停车阈值,直到机器人开始蹭到障碍物。记下这个 数值。现在把速度翻倍,再重复一次。

你需要的阈值不会翻倍,因为它是一个随速度线性变化的项加上一个随 速度平方变化的项:

stop_distance = (v x t_latency) + (v^2 / (2 x a_brake)) + robot_radius + margin
速度 延迟项(80 ms) 刹车项(1 m/s²) 合计,含 90 mm 半径 + 50 mm 裕量
0.15 m/s 12 mm 11 mm 16 cm
0.30 m/s 24 mm 45 mm 21 cm
0.60 m/s 48 mm 180 mm 37 cm
0.90 m/s 72 mm 405 mm 62 cm

这就是为什么一台在步行速度下能可靠避障的机器人,一提速就开始撞东西—— 而修法是一个随速度变化的阈值,而不是一个到处都让机器人畏手畏脚的 大号固定值。

2. 先造出阈值抖动,再修掉它

把机器人停在恰好处于停车距离的位置上。用单一阈值时,它每秒会在 行驶和转向之间来回翻转好多次。

现在把两者分开:20 cm 停车,30 cm 才恢复行驶。抖动消失了, 因为这个行为必须做出承诺。那道间隙就是迟滞,而同一个模式能修掉 机器人代码里几乎所有由阈值驱动的振荡。

3. 故意把它困住

搭一个凹角——一个马蹄形——让机器人开进去。用确定性的“朝最开阔方向转” 规则,它会转、开,然后永远回到它出发的地方。

这不是一个需要修的 bug。这就是没有地图的含义,也是反应式导航的上限 最清晰的演示。缓解手段是在转向中加入一个随机分量,以及一个在几次尝试 都失败之后升级处理的卡住检测器;真正的解法是记忆,那属于 完全不同的另一条路线。

4. 扫描分辨率与扫描时间的对比

增加扫描角度的数量,然后观察两件事朝相反方向变化:转向决策变好了, 而机器人站着不动的时间变长了。

一次扫描是一段致盲时刻——机器人停着,没有任何进展。三到五个角度 是通常的甜蜜点,再往上,多出来的信息很少值得多花的时间。

你应该观察到什么

行为 原因
高速时蹭到障碍 阈值没有按二次的刹车项缩放
在固定距离上抖动 只有一个阈值,没有迟滞
原地左右摇摆 在转向还没带来任何变化时就重新决策
在角落里永远绕圈 确定性的逃逸策略撞上了对称陷阱
到处都过早停车 阈值是按最坏情况设的,而不是按当前速度
朝缺口的边缘转 挑了最大角度,而不是加权质心

硬件落地

模拟器里的射线是瞬时的、无噪的、无限细的。真实的超声波传感器这三样 一样都不具备,而这些差别就是硬件上的全部工作:

这个实验台 真实机器人上的 HC-SR04
一条细射线 一个约 15° 的锥面,在 1 m 处宽约 53 cm
每个表面都反射 柔软和大幅倾斜的表面干脆什么都回不来
瞬时读数 每次 ping 最长 25 ms,彼此间隔约 60 ms
没有舵机 每个扫描角度需要 100–200 ms 的稳定时间
没有噪声 偶尔出现的反常数值,需要中值滤波
什么都看得见 一道窗帘是看不见的——这就是你要装碰撞开关的原因

先在这里找到安全的停车距离和一条空旷方向规则,在这里犯错不花任何代价。 然后到了硬件上,再加上中值滤波、舵机稳定延迟和接触感知—— 避障算法教程里有每一项的代码。

硬件清单

元器件

  • Raspberry Pi 及其支持的电源
  • 两个或更多飞行时间或超声波传感器
  • 可选的摄像头模块,用于视觉检测
  • 带独立电机电源的电机驱动器
  • 差速驱动底盘和编码器

探索关联图谱

哪里用到这个模拟器

以这个实验台为基础的项目、学习路线和教程。

继续搭建

下载资源

完成项目时可以参考本页上的这些资料。可下载的项目包只会在其源文件和版本发布之后才会添加。

常见问题

常见问题解答

为什么只用一个朝前的传感器不够?

单一波束会在机器人附近留下盲区,而且无法区分一个窄小的物体和一堵墙。多个视角或一个扫描式传感器能提供足够的几何信息,让机器人选择更安全的转向。

避障能取代路径规划吗?

不能。反应式避障处理的是眼前的危险,而规划器负责选择朝目标推进的路线。稳健的机器人会把两者结合起来,并让安全层能够否决不安全的规划运动。

超声波传感器和飞行时间传感器,哪个更适合避障?

超声波传感器便宜,对大多数表面都有效,但角分辨率差,而且在靠近传感器的地方有盲区。飞行时间(ToF)传感器能给出更快、更精确的近距离测距,波束也窄,但可能受到强烈阳光、深色或镜面般的表面以及墙角反射的干扰。许多机器人用超声波做粗略的覆盖,在需要精确近距离感知的地方用 ToF。

什么是传感器盲区,它为什么重要?

盲区是指一个最小量程,低于这个距离,传感器就无法报告有效的距离——对超声波传感器来说,它由发射脉冲的长度决定。位于盲区内的障碍物会被读成“前方畅通”,所以一台相信原始读数的机器人,可能会直接撞上就在它正前方的东西。安装传感器时要让盲区落在机器人自身的占地范围之内,并把小得可疑的读数当作无效值处理。

如何计算安全的停车距离?

安全距离等于反应距离加上制动距离,再加上机器人的半径和一段裕量。反应距离随速度线性增长(速度乘以感知—决策—执行的延迟),但制动距离随速度的平方增长,所以所需的间隙比速度本身增长得更快。这就是为什么速度稍微提高一点,就可能需要大得多的安全间距。

为什么我的机器人会卡在障碍物前面?

势场这类反应式方法可能会陷入局部极小值:障碍物的斥力恰好抵消了目标的引力,于是机器人停滞不前或来回振荡。采用“跟随缺口”式的转向,坚定地驶向最宽的空旷开口,再在反应层之上加一个全局或局部规划器,就能防止机器人把自己困住。

如何过滤带噪声的距离读数?

剔除物理上不可能的数值和突然的跳变,而不是据此行动;给每个样本打上时间戳;再施加轻度的中值滤波或时间滤波,以抑制虚假回波。如果所需的数据过期或不可用,就进入安全停车状态,而不是凭猜测转向。

延伸阅读

参考资料

权威资料,帮助你越过本模拟器有限的教学模型,进一步深入学习。