Monday, February 15, 2010

Beep, Beep!

There is a feature of GvR that we haven't yet explored, beepers. In this first look at beepers we will simply have GvR place some beepers on the map. But we'll also build on what we've learned so far as we do it.

Two rooms, No View
To start with we'll need a map for our program. Two things you'll notice about the following map code that is different than what we've had before. First the last number in the robot line is not zero. This indicates the number of beepers in GvR's beeper bag. We'll start with 8, because there will be eight corners on this map. The second change is the addition of a number at the end of the wall statements in the map file. These numbers indicate the length of the wall, up or to the right, from the starting position, up for NS walls, right for EW walls. Enter the following into the world editor and save it as tworooms.wld

robot 2 2 N 8
wall 2 2 W 8
wall 2 9 N 8
wall 9 2 E 8
wall 2 2 S 8
wall 6 2 W 3
wall 6 7 W 3

Once the code is entered and saved, click the reload button. You should have something that looks like this:
 
The plan is to have GvR place a beeper in each corner of the room. One of the sample programs provided on the GvR site shows how to have the robot hug a wall on its right as it moves around. We'll do something similar but hug the wall on the left. When we hit a corner we'll need to turn right so we'll include our turnright definition in this program. So let's break down the steps:
1. Place a beeper in the corner that we are starting in.
2. Move forward along the wall until we hit the corner
3. Place a beeper in the corner
4. Turn right
5. Repeat steps 2-4 for each of the remaining corners on the map.

Seems simple enough. We'll make use of some of the conditions that GvR can test. These are listed on the Language Reference tab of the GvR interface. To start with we'll need the left_is_blocked and front_is_clear conditions.

Let's get started. First thing we do is define the turnright command.

define turnright:
    do 3:
        turnleft

The first step in our list of steps is easy. You place a beeper by using the putbeeper command.

Following the left wall is done by making sure that the left side is always blocked, using the left_is_blocked condition. The next thing we need to know is whether we can move forward. To move forward the front must be clear. So we check front_is_clear and move if it is. If the front is not clear then we are in a corner. So place a beeper and turn right. Here's the code for that.

while left_is_blocked:
    if front_is_clear:
        move
    else:
        putbeeper
        turnright

We've seen the while command in our first exercise. It will loop will that condition is true. The if command is what we call a flow control statement in programming. It will allow us to do a group (or block) of commands based on the results of the conditional test. In this case we check if the front is clear, if it is we move. If it's not then the else clause is executed. In this case we put a beeper and turn right.  Seems simple enough.

Don't for get to include the turnoff command at the end of your program.

Once you've got your code in, save it then click Reload and Execute.
Did the program do what we wanted? Not really, did it. There's one piece missing from our initial analysis and from this code. What do we have the robot do when it reaches the opening in the wall? If we want to follow a wall on the left then when we reach an opening we know we can move to the left. So while there is no wall on our left we turn left and move forward. Use the following code:

while left_is_clear:
    turnleft
    move

Place this code before the turnoff command and save your program. Then Reload and Execute to see what happens. Better? GvR should have made it around the wall and be ready to follow the left hand wall again. How do you start him up again? Since we know we'll hit the opening twice we could try putting everything inside a do 2: loop. Give that a try and see  what happens. We're getting close. GvR stops after making back into the first room. But he still has one beeper to place to finish the task. You could up the loop to 3, but I'll tell you that an error would be generated when we attempt to place a beeper with none in the bag. What follows is my final version of this program that will place beepers in every corner and shutdown the robot when it returns to its starting place. There's a repeat of the check on beepers when we hit the corner. Again if we attempt to place a beeper and there is none the program will error. Also this shows that the end of the program, the turnoff command, isn't always at the end of the code.


define turnright:
    do 3:
        turnleft

putbeeper
while any_beepers_in_beeper_bag:
    while left_is_blocked:
        if front_is_clear:
            move
        elif any_beepers_in_beeper_bag:
            putbeeper
            turnright
        else:
            turnoff
    while left_is_clear:
        turnleft
        move


That's it for now. Here's something to try on your own. Right a program that looks for beepers in the corners of the room and if it finds one moves it to the next unoccupied corner. You can place beepers on the map in a world file using the beeper instruction. It includes the coordinates and the number of beepers. You might want to play with the GvR world builder to learn the syntax.

I'll post a version of this program in about a week so you can check your code against mine. 

No comments:

Post a Comment