# 避障机器人2--减速

还好,你已经提前感觉到前面是一堵墙,走的慢一些,不然可能会停不下来撞到墙上……

# 情景分析

  1. 上次机器人在350毫米处停止,其实超声波传感器远远就看到障碍物了。快接近时,我们可以稍微放慢一点脚步。
  2. 我们将见到if语句的另一种形式,if(条件){符合条件指令}else{不符合条件指令}。通过点击 可以把if积木变成if-else积木
  3. 假设我们打算在700毫米处开始减速,到350毫米处停下来。750毫米处的速度是200,350毫米时减速到80,在Arduino里面有一个函数可以帮我们做这个计算题。map(value, fromLow, fromHigh, toLow, toHigh),对应积木 作用是把一个数(在fromLowfromHigh之间)对应到另一个数(在toLowtoHigh之间)

# 流程解析

  1. 在上一节的程序里将if语句改成if(){}else{}格式。
  2. 在if语句的条件成立时(障碍物距离小于350毫米),将执行if(){}花括号内的指令,机器将跟上一节一样,停止移动。
  3. 如果if语句的条件不成立(障碍物距离不小于350毫米),将会执行else{}花括号中的指令。
  4. 在else中使用map(U.ping(), 350, 700, 80, 200)函数计算应当设置的速度。表示将距离350到700换算成速度80到200。
  5. 将两个马达的前进速度都设置成map计算的结果。
  6. 重复步骤2到步骤5。
uml diagram

# 参考程序

  • osepp Block IDE

  • Arduino IDE程序
#include <oseppRobot.h>

OseppRangeFinder U(2);
OseppTBMotor L(12, 11, HIGH);  //左边轮子,如果方向不对,要把HIGH换成LOW
OseppTBMotor R(8, 3, LOW);     //右边轮子,如果方向不对,要把LOW换成HIGH

void setup() {}

void loop() {
    if (U.ping() < 350) {
        L.forward(0);
        R.forward(0);
    } else {
        //距离从350到700,对应速度从80到200
        L.forward(map(U.ping(), 350, 700, 80, 200));
        R.forward(map(U.ping(), 350, 700, 80, 200));
    }
    delay(25);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 运行结果

接通电源,上传程序后,拔掉USB线。打开电池开关,将机器人放到地上,机器人向前移动,接近障碍物时开始减速,最后停下来。帮机器人转弯后机器人重复这个过程。

# 课程解读

  1. 不要让机器人在350毫米处速度降低到0,不然机器人可能会在大于350毫米的地方就停下来了。
  2. 上一节里面,使用if语句,指令可以选择性地执行或者不执行。这次我们使用if-else形式,指令分叉了,要不执行这一段指令,要不就执行另一段指令。
  3. 上一节里面,机器人一旦停止就不会再动了,现在不一样了哦。仔细想想是怎么回事呢?
  4. 我们的程序有一个bug。map函数的使用上有一点疏忽,我们预计map函数从350~700距离变换为0~200速度,在小于350时,只执行if内的指令,不会执行map指令。但是在距离大于700时会执行!会不会有意外的后果?通过试验,map会计算出一个大于200甚至大于255的速度,不过因为马达驱动库里面考虑了这个情况,会将大于255的速度当作255处理,所以程序运行感觉上是正常的。但是不一定每次都有这么好的运气哦,我们一定要认真地对待程序逻辑,并在下一节里面修复它。

# oseppBlock操作视频

# ArduinoIDE操作视频