# 避障机器人5--随机方向

不幸的是,你又扑空了,没抓到人。
你在一段时间里,碰到东西了都只往右边转弯。
跟你一起玩捉迷藏的伙伴可是很聪明的,他们会悄悄地一直跟在你身后,你永远都抓不到他们……
聪明的你也想到了这一点,于是你决定……

# 情景分析

  1. 机器人碰到障碍该往左边还是往右边转弯?没有办法确定的情况下,不如掷个骰子选个方向。
  2. 这节我们将学习一个常用的函数random(min,max),对应的积木 。它在minmax之间随机选一个数给我们。注意包括min但是不包括max,还可以省略掉min参数变成random(max),相当于random(0,max)

# 流程解析

  1. 上一节的程序if(距离小于350毫米){转弯;等待}……
  2. 修改转弯过程,使用random(0,2)会得到一个从[0,1]里面随机选择的数,如果是0就左转,如果是1就右转(注意不会返回2),之后再进入等待。
uml diagram

# 参考程序

  • oseppBlock 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) {
        if (random(0, 2)) {   //如果随机数是1
            L.forward(200);   //左边轮子以200速度前进
            R.backward(200);  //右边轮子以200速度后退,机器人右转
        } else {              //如果随机数是0
            L.backward(200);  //左边轮子以200速度后退
            R.forward(200);   //右边轮子以200速度前进,机器人左转
        }
        while (U.ping() < 400) {
        }
    } else if (U.ping() <= 700) {
        L.forward(map(U.ping(), 350, 700, 80, 200));
        R.forward(map(U.ping(), 350, 700, 80, 200));
    } else {
        L.forward(200);
        R.forward(200);
    }
    delay(25);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 运行结果

接通电源,上传程序后,拔掉USB线。打开电池开关,将机器人放到地上,机器人向前移动,接近障碍物时开始减速,遇到障碍物会随机向左边或者向右边转弯。

# 课程解读

  1. random函数可以省略掉min参数,程序里用random(2)也是可以的。注意返回结果是不包括max参数的。
  2. if,while的判断条件不一定是表达式,也可以是数值“0”代表不成立,“不是0”代表成立,这一点也是很常用的。
  3. 上一节添加代码,不单只是提升转弯效率。还同时也在等待整个转弯过程结束。在本节中,如果没有等待代码。在避开障碍物前随机转弯会频繁地被执行。机器人就会频繁地调换转弯方向。这并不是我们所想的,除非你想让你的机器人表达出惊慌失措。

# 拓展知识

random函数产生的随机数实际上并不是完全随机,称为伪随机数,对于arduino而言,如果不先初始化随机数生成器,每次重新启动后得到的随机数序列跟上一次都是相同的(测试方法:开机让机器人使用random选择方向一直转弯,每次都是同一个方向)。调用randomSeed()函数可以搅乱随机数序列,注意它也需要有不确定的数来初始化。例如randomSeed(analogRead(A5))用没有接线也没有使用的模拟端口上得到的不确定的值来打乱随机数序列。

# oseppBlock操作视频

# ArduinoIDE操作视频