实验四 触须避障导航、光敏电阻导航
GOSUB Back_Up ' Back up & U-turn (left twice) GOSUB Turn_Left GOSUB Turn_Left
ELSEIF (IN5 = 0) THEN ' Left whisker contacts GOSUB Back_Up ' Back up & turn right GOSUB Turn_Right
ELSEIF (IN7 = 0) THEN ' Right whisker contacts GOSUB Back_Up ' Back up & turn left GOSUB Turn_Left
ELSE ' Both whiskers=1, no contacts GOSUB Forward_Pulse ' Apply a forward pulse ENDIF LOOP ‘子程序
Forward_Pulse: ' forward pulse. PULSOUT 13,850 PULSOUT 12,650 PAUSE 20 RETURN
Turn_Left: ' Left turn, about 90-degrees. FOR pulseCount = 0 TO 20 PULSOUT 13, 650 PULSOUT 12, 650 PAUSE 20 NEXT RETURN Turn_Right:
FOR pulseCount = 0 TO 20 ' Right turn, about 90-degrees. PULSOUT 13, 850 PULSOUT 12, 850 PAUSE 20 NEXT
RETURN
Back_Up: ' Back up FOR pulseCount = 0 TO 40 PULSOUT 13, 650 PULSOUT 12, 850 PAUSE 20 NEXT RETURN
6. 被卡后的判断
Boe-Bot 会卡在墙角里而动弹不了。当Boe-Bot 进入墙角里以后,它的触须会碰到左侧的墙壁,所以它会向右转弯,而当Boe-Bot 再次前进的时候,它的
4
实验四 触须避障导航、光敏电阻导航
右触须会碰到右侧的墙壁,所以它会向左转弯,结果再次碰到左侧的墙壁,再次转弯后又会碰到右侧的墙壁,这样不断反复而卡住。
通过修改程序来探测这个问题并作出反应。窍门在于数出触须轮流接触的次数。该窍门的要点是程序必须能够记住上次接触时每个触须的状态。它会拿触须过去的状态和当前的状态相比较。如果它们是相反的,那么次数就加上1。如果累加后的次数超过了编程者定义的极限,那么,是时候执行U-turn 动作并重新为触须接触次数计数了。
‘程序EscapingCorners.bs2 DEBUG\‘定义变量
pulseCount VAR Byte 'FOR...NEXT loop counter. counter VAR Nib 'Counts alternate contacts. old7 VAR Bit 'Stores previous IN7. old5 VAR Bit 'Stores previous IN5.
‘初始化
FREQOUT 4,2000,3000 'Signal program start/reset. counter=1 'Start alternate corner count. old7=0 'Make up old values. old5=1 ‘主程序 DO
IF(IN7<>IN5)THEN 'One or other is pressed.
IF(old7<>IN7)AND(old5<>IN5)THEN 'Different from previous. counter=counter+1 'Alternate whisker count+1. old7=IN7 'Record this whisker press
old5=IN5 'for next comparison.
IF(counter>4)THEN 'If alternate whisker count=4, counter=1 'reset whisker counter
GOSUB Back_Up 'and execute a U-turn. GOSUB Turn_Left GOSUB Turn_Left
ENDIF 'ENDIF counter>4.
ELSE 'ELSE(old7=IN7)or(old5=IN5), counter=1 'not alternate,reset counter. ENDIF 'ENDIF(old7<>IN7)and'(old5<>IN5). ENDIF 'ENDIF(IN7<>IN5).
IF(IN5=0)AND(IN7=0)THEN 'Both whiskers detect obstacle GOSUB Back_Up 'Back up & U-turn(left twice) GOSUB Turn_Left
GOSUB Turn_Left
ELSEIF(IN5=0)THEN 'Left whisker contacts GOSUB Back_Up 'Back up & turn right GOSUB Turn_Right
ELSEIF(IN7=0)THEN 'Right whisker contacts
5
实验四 触须避障导航、光敏电阻导航
GOSUB Back_Up 'Back up & turn left GOSUB Turn_Left
ELSE 'Both whiskers=1,no contacts
GOSUB Forward_Pulse 'Apply a forward pulse ENDIF LOOP ‘子程序
Forward_Pulse: 'forward pulse. PULSOUT 13,850 PULSOUT 12,650 PAUSE 20 RETURN
Turn_Left: 'Left turn,about 90-degrees. FOR pulseCount=0 TO 20 PULSOUT 13,650 PULSOUT 12,650 PAUSE 20 NEXT RETURN
Turn_Right:
FOR pulseCount=0 TO 20 'Right turn,about 90-degrees. PULSOUT 13,850 PULSOUT 12,850 PAUSE 20 NEXT
RETURN
Back_Up: 'Back up. FOR pulseCount=0 TO 40 PULSOUT 13,650 PULSOUT 12,850 PAUSE 20 NEXT RETURN
六、 思考题
1. 触须受压后,I/O 引脚上监测到的电压是多少?输入寄存器将存储的二进制数
值是多少?如果I/O 引脚P8 用来作为输入引脚,当触须受压后,IN8的值会
是多少,如果触须没有受压,它的值又会是多少?
触须受压后,I/O 引脚上监测到的电压是0V,输入寄存器将存储的二进制数值是0。如果I/O 引脚P8 用来作为输入引脚,当触须受压后,IN8的值是0,如果触须没有受压,它的值是1。
6
实验四 触须避障导航、光敏电阻导航
2. 什么命令可以用于根据不同的变量的值跳至不同的子程序?什么命令可以用
于决定跳至某个子程序?这些判断取决于什么?
条件语句可以用于根据不同的变量的值跳至不同的子程序,GOSUB命令用于决定跳至某个子程序。这些判断取决于条件语句中变量的值。
3. 修改程序RoamingWithWhiskers.bs2,使Boe-Bot 在执行避障动作之前发出
100ms 的4KHz 的频响。使它发出两次频响,如果在同一个试验中两个触须同时探测到受压的话。
‘程序RoamingWithWhiskers.bs2 DEBUG \‘定义变量
pulseCount VAR Byte ' FOR...NEXT loop counter. ‘初始化
FREQOUT 4, 2000, 3000 ' Signal program start/reset. ‘主程序 DO
IF (IN5 = 0) AND (IN7 = 0) THEN ' Both whiskers detect obstacle FOR pulseCount = 0 TO 20 HIGH 4
FOR pulseCount = 0 TO 20 LOW 4
FOR pulseCount = 0 TO 20 HIGH 4
FOR pulseCount = 0 TO 20 LOW 4
GOSUB Back_Up ' Back up & U-turn (left twice) GOSUB Turn_Left
GOSUB Turn_Left
ELSEIF (IN5 = 0) THEN ' Left whisker contacts FOR pulseCount = 0 TO 20 HIGH 4
FOR pulseCount = 0 TO 20
LOW 4
GOSUB Back_Up ' Back up & turn right GOSUB Turn_Right
ELSEIF (IN7 = 0) THEN ' Right whisker contacts FOR pulseCount = 0 TO 20 HIGH 4
FOR pulseCount = 0 TO 20 LOW 4
GOSUB Back_Up ' Back up & turn left GOSUB Turn_Left
ELSE ' Both whiskers=1, no contacts
7