# 相扑机器人2--机器人的状态
巡线机器人系列中,如果你的朋友问你,机器人在干嘛呢?你回答他:机器人在巡线。朋友看了一会,称赞:机器人做的很好!
现在你的朋友又问你。你回答:机器人在相扑。一会儿之后,朋友追问道:相扑就是一直转圈圈?
你可以更详细地回道:它现在正在不停地搜索目标,或者在躲避胶带、在进攻敌人。
# 情景分析
- 你的朋友只观察了一小段时间,所以他只看到了机器人其中的一个状态(搜索)。这与之前编程的机器人不一样。巡线机器人只做一件事情,行动都是由传感器来直接决定的,如果传感器发生变化,立刻修改机器人的行动就行。相扑机器人做3件事情:搜索目标,进攻敌人,躲避胶带。搜索目标的时候,检测到目标应该进攻。而碰到胶带的时候,检测到目标就要视而不见了。这种差异是因为机器人当前所做的事情不同造成的。机器人一个时候只能做一件事情,符合一定条件之后,就会放下当前的事情,去做另外一件。机器人正在做什么我们叫做机器人的状态。目前看来有3个状态,搜索状态,进攻状态,躲避状态。
- 上一节,机器人在胶带附近搜索目标时遇到了困难。搜索碰到胶带之后,要躲避胶带,机器人向相反的方向转弯。离开胶带以后,就应该搜索目标。这时方向已经设置好了,那么在没有发现目标或者再次碰到胶带之前,最好的策略就是保持转弯方向不变。而另外一个躲避胶带的方式是后退,那就要特别处理一下。要变成转弯,之后就开始搜索。同样地前进攻击目标,碰到胶带也要特殊处理。特殊处理要等到离开胶带,或者丢失目标以后再处理。我们可以while循环,一直等到条件合适,再设置机器人转弯。
# 流程解析
- 读取传感器,并判断是否碰到胶带,是否发现目标,保存到变量。
- 如果碰到胶带,并且两个传感器都在胶带上
- 机器人开始后退
- 用while等待后退至完全离开胶带(注意,要重新读取传感器)
- 脱离胶带后机器人开始转弯进入搜索状态
- 如果只有一边碰到胶带,机器人向相反的方向转弯,并不需要等待离开胶带。因为离开胶带以后也是要保持现在的方向,没什么可以做的。
- 没有碰到胶带,目标存在,机器人前进进攻目标。并用while来等待丢失目标,或者碰到胶带。(注意,要重新读取传感器)
- 如果是因为碰到胶带而离开了while循环,不做处理,再次进入loop函数时,由碰到胶带的代码来处理。如果是因为目标丢失,则要控制机器人开始转弯,进入搜索状态。
- 重复执行以上步骤
# 参考程序
只需要修改loop函数
void loop() {
readSensor();
if (SL || SR) {
if (SL && SR) { //两个传感器都碰到了胶带
while (SL || SR) { //循环等待离开胶带
L.backward(150); //后退
R.backward(150);
readSensor(); //读传感器,更新状态变量
}
if (random(2)) {//离开胶带后,随机转弯
L.forward(100); //右转
R.backward(100);
} else {
L.backward(100); //左转
R.forward(100);
}
} else if (SL) { //左边传感器碰到胶带
L.forward(100); //右转
R.backward(100);
} else if (SR) { //右边传感器碰到胶带
L.backward(100); //左转
R.forward(100);
}
} else { //没有碰到胶带
if (SU) { //发现目标
L.forward(150); //前进
R.forward(150); //前进
while (SU) { //等待丢失目标
readSensor();
if (SL || SR) break;
}
//如果是因为丢失目标退出while,需要设置机器人转弯
if (!(SL || SR)) {
if (random(2)) {
L.forward(100); //右转
R.backward(100);
} else {
L.backward(100); //左转
R.forward(100);
}
}
// 如果是碰到胶带退出while,留给碰到胶带的代码处理。
}
}
}
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 运行结果
机器人放置在胶带围成的区域中心,打开电源,尝试放个纸盒在中间,机器人对纸盒发起进攻。在胶带附近搜索时,也可以正常搜索全部范围了。程序达到了我们的预期。
# 程序解读
我们用while循环来等待离开胶带、丢失目标,然后转弯进入搜索状态。但是while过程中还需要考虑传感器情况。所以代码显得比较冗长。并且如果传感器增加,或者逻辑增加。代码就会更复杂。例如我们还想要使用遥控器来控制,那么所有的while里面都要加上遥控器的判断代码。例如机器人对着一个目标进攻过程碰到胶带(目标已经出界了),我们要找新的目标,就要先等待丢失现在的目标,再等待发现新目标。代码的逻辑就会越来越复杂。