Escaping Corners

When running roaming_with_whiskers.py, you may have seen your cyber:bot get stuck in a corner.  Its left whisker touches a wall so it turns right, then its right whisker touches a wall so it turns left, over and over again, until you rescue your robot.

Track Input to Recognize Patterns

The next example script counts alternate whisker presses to determine if the cyber:bot is stuck in a corner.  To do this, the script has to remember what state each whisker was in during the previous contact.  If they are opposite, then one is added to a counter.  If that counter goes over a threshold that you set, then it is time to turn around out of the corner (and reset that counter).  In this way, your cyber:bot "remembers its experience" to be "aware of its predicament" so it can respond appropriately; a primitive example of artificial intelligence.

This script relies on nested if...else statements.  The script checks for one condition, then if that condition is true, it checks for another one within the first condition.  The script escaping_corners.py actually uses three if statements nested together.

Example Script: escaping_corners.py

  • Set the cyber:bot board's PWR switch to 0.
  • Use the micro:bit Python Editor to open a previous cyber:bot project, like roaming_with_whiskers or cyberbot-template-with-blink.
  • Set the project's name to escaping_corners, update the script so that it matches the one below, and then click Save.
  • Click Send to micro:bit.  
  • Put the cyber:bot on the floor in a corner and set the cyber:bot board's PWR switch to position 2.
  • Using obstacles or your hands, alternate right and left whisker presses to simulate being stuck in a corner. After four or five bounces off of alternate walls, your cyber:bot should turn around and leave the corner.
# escaping_corners.py

from cyberbot import *

# define functions for maneuvers

def forward():
    bot(18).servo_speed(75)
    bot(19).servo_speed(-75)

def backwards():
    bot(18).servo_speed(-75)
    bot(19).servo_speed(75)
    sleep(750)
    
def right():
    bot(18).servo_speed(75)
    bot(19).servo_speed(75)
    sleep(500)
    
def left():
    bot(18).servo_speed(-75)
    bot(19).servo_speed(-75)
    sleep(500)
    
# initialization

counter = 0
w_l = 0 
w_r = 0
o_w_l = 0
o_w_r = 1

bot(22).tone(4000,50)

# main routine

while True:                                   
    w_l = bot(7).read_digital()               # check left whisker state
    w_r = bot(9).read_digital()               # check right whisker state
   
    if (w_l != w_r):                          # if a whisker was pressed
        if (o_w_l != w_l) and (o_w_r != w_r): # different from last time?
            counter = counter + 1             # in corner - add to counter
            o_w_l = w_l                       # record left whisker press
            o_w_r = w_r                       # record right whisker press
            if (counter > 4):                 # if in corner too long...
                bot(22).tone(3000, 50)        # sound alarm
                counter = 1                   # reset corner counter
                w_l = 1                       # reset left whisker value
                w_r = 1                       # reset right whisker value
                backwards()                   # back out of corner
                left()                        # turn away from corner
                left()
        else:
            counter = 1                       # else, reset counter
    if (w_l == 0 and w_r == 0):               # roam with whiskers
        backwards()                                 
        right()
    elif w_r == 0:   
        backwards()                                  
        left()
    elif w_l == 0:  
        backwards()                                   
        right()
    else:                                           
        forward()

If You Are Done

If you are done for the day, always follow these steps.

  • Set PWR to 0.
  • Unplug the battery holder's barrel plug from the cyber:bot board's barrel jack.

Just taking a break, but will do more today?  Then follow these steps.

  • Just set the cyber:bot board's PWR switch to 0 until it's time to test the next script.