Computer Science 014
LEGO Robot Engineering

Williams College
Winter 2007


Lab 4: Bumpy and Blind Maze Running
Due: 10:00 AM, Wednesday, January 10, 2007


Today's lab will involve implementing simple reflexive behaviors. In particular, you will implement obstacle sensing and avoidance. Your robot should wander through its world. If it encounters an obstacle, it should back away, adjust its direction, and continue to wander. It should stop only when it is turned off.

There are two parts to this lab. In the first part, you will implement a simple algorithm that detects collisions and adjusts for them. You will find that this simple algorithm generally behaves quite well. Unfortunately, if your robot ever wanders into a corner, it is likely to get into trouble. In the second part of this lab, you will write a program that can infer that the robot is stuck, allowing it to better adjust the position and orientation of the robot.

For this lab you need two touch sensors on the front of your vehicle, one on the left side and the other on the right side, in order to sense the robot's orientation to the obstacle.

Simple Obstacle Avoidance

Write an Interactive C program that demonstrates the first behavior described above. When started, the robot should move forward. As it moves, it should test its touch sensors for signs of collision with obstacles. If there is a collision with the left touch sensor, the robot should back up a little bit, turn to the right a bit, and then continue to move forward from its new position. If there is a collision with the right touch sensor, the robot should back up a little, turn to the left a bit, and then continue to move from its new position. It should do this forever (i.e., until the robot is turned off).

Load your program onto your robot, and try it out. First let the robot wander in a fairly open space with just a few obstacles. Then try it out in a space that has more obstacles. Finally, see what it does when put in the maze. How does it handle corners? Does it get stuck?

Corner Detection and Recovery

If you made only small adjustments when backing up and turning away from an obstacle (a good conservative approach), then you likely found that corners posed a real challenge for your robot. Fortunately, there is a way to take care of this.

Let's consider the problem our robots run into as they wander into a corner, illustrated below. The robot will hit into a wall eventually. Say that the robot hits with its right bumper, as shown. It then backs up a bit and turns to the left. If the turn has been fairly conservative, the robot will hit a wall with its left bumper, soon after it begins to move forward again. It will then back up and adjust to the right. If the adjustment is fairly conservative, the robot will hit again. While the figure illustrates the robot hitting on alternate sides, it is possible that it will hit its right side or left side several times in a row.

Obviously we want to make a fairly major adjustment in the position and orientation of the robot when it gets stuck. The question is how we can determine that the robot is stuck.

We notice that when the robot is in a corner, collisions happen often. Furthermore, they tend to happen in quick succession. That is, the robot doesn't move forward very long before it hits something. So our better obstacle sensing program will need to check for groups of collisions that happen close together.

Suppose we have the capability to measure elapsed time (i.e., something like a stopwatch). If the robot bumps into something with its right touch sensor, it should first check how much time has elapsed since the last bump. If it's been only a short time, we check whether there have been many short bumps recently. If so, we make a big adjustment to the robot (perhaps by moving back more than we normally would and turning more dramatically to the left).

If it's been only a short time since the last collision, but we haven't experienced many other bumps recently, we might want to hold off before making any big adjustments. Instead, we can simply adjust normally and make a note of the fact that this bump was a short one. We can do this by maintaining a counter variable that we increment with each short bump.

If, on the other hand, our timer tells us that the elapsed time between this bump and the last one was large, then we simply adjust normally (i.e., move back and turn a little to the left).

We keep track of the number of collisions with a counter variable that can be incremented whenever the robot hits something soon after the previous bump. But what happens with that counter otherwise? For example, what if we've reached our threshold and have decided to make a big adjustment? In that case, we clear out the memory of the recent bumps. That is, we reset the counter to 0.

What about the case where we simply bumped into something with adequate time between bumps? In that situation we reset the counter to 1. This bump, after all, might be the start of a new sequence of trouble.

While this description is specific to a bump of the right sensor, the left can be handled similarly.

An Interactive C Timer: I have provided two Interactive C

functions that simulate the behavior of a (very!) simple stopwatch. These functions are:

You will find these functions in the file timer.c in the cs014 folder on the lab Macs and here. You will need to include the line

#use "timer.c"

at the top of any program that you wish to have make use of these functions.

Load your program onto your robot, and try it out. First let the robot wander in a fairly open space with just a few obstacles. Then try it out in a space that has more obstacles. Finally, see what it does when put in last week's maze. Does this program handle corners better than the previous one? How does it compare to last week's program?

You will need to demonstrate that your robot successfully navigates away from obstacles. In particular, you will demonstrate that it can work its way through the maze. You should also submit a printout of your program.