面向移动机器人的障碍物规避模拟器
这是一款面向树莓派项目的避障机器人模拟器,可以用来学习反应式导航、距离感知,以及如何在撞上障碍物之前安全停下来。
- 类别
- Raspberry Pi
- 时长
- 2–3 小时
- 平台
- 浏览器 · Raspberry Pi
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.
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.
- 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.
控件
工作区里包含可移动的障碍物、机器人速度、感知距离、视场角、测量噪声和一个安全距离阈值。传感器射线和预测出的停车距离始终保持可见。逐步模式会准确揭示每一次转向决策是由哪一次观测触发的。
原理
机器人必须在它扫过的区域与障碍相交之前停下或转向。安全距离取决于当前速度、控制器延迟、制动能力、测量不确定性以及机器人的物理半径——而不只是最近一次的测距值。
势场这类反应式控制器把附近的障碍变成斥力矢量,把目标变成引力矢量。它们响应很快,但可能被困在局部极小值里。实用的做法是把反应式的安全层与一个全局或局部规划器配在一起。
算法
- 剔除过期的、物理上不可能的测距样本。
- 把有效的观测变换到机器人坐标系。
- 把每个障碍按机器人半径加上安全裕量膨胀。
- 由速度和估计的减速度算出停车距离。
- 前方走廊不安全就停车;否则朝与目标对齐的最空旷扇区转向。
- 在发出电机指令之前限制加速度和角速度。
源代码
把紧急决策写得足够小,以便穷举测试:
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 之前都要先做电平转换。电机单独供电,并把地线在一个刻意选定的公共点连接起来。
引导实验
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。
什么是传感器盲区,它为什么重要?
盲区是指一个最小量程,低于这个距离,传感器就无法报告有效的距离——对超声波传感器来说,它由发射脉冲的长度决定。位于盲区内的障碍物会被读成“前方畅通”,所以一台相信原始读数的机器人,可能会直接撞上就在它正前方的东西。安装传感器时要让盲区落在机器人自身的占地范围之内,并把小得可疑的读数当作无效值处理。
如何计算安全的停车距离?
安全距离等于反应距离加上制动距离,再加上机器人的半径和一段裕量。反应距离随速度线性增长(速度乘以感知—决策—执行的延迟),但制动距离随速度的平方增长,所以所需的间隙比速度本身增长得更快。这就是为什么速度稍微提高一点,就可能需要大得多的安全间距。
为什么我的机器人会卡在障碍物前面?
势场这类反应式方法可能会陷入局部极小值:障碍物的斥力恰好抵消了目标的引力,于是机器人停滞不前或来回振荡。采用“跟随缺口”式的转向,坚定地驶向最宽的空旷开口,再在反应层之上加一个全局或局部规划器,就能防止机器人把自己困住。
如何过滤带噪声的距离读数?
剔除物理上不可能的数值和突然的跳变,而不是据此行动;给每个样本打上时间戳;再施加轻度的中值滤波或时间滤波,以抑制虚假回波。如果所需的数据过期或不可用,就进入安全停车状态,而不是凭猜测转向。
延伸阅读
参考资料
权威资料,帮助你越过本模拟器有限的教学模型,进一步深入学习。