Page 185
task. However, if you do this, the robot "jiggles" badly. The problem is that arbitrate changes the value of motorCommand several times each time it loops. As the value changes,
motorControl responds by changing the motors' directions.
We're really interested only in the value of motorCommand at the end of each loop in arbitrate. Therefore, motorControl is implemented as a subroutine and is called once each time at
the end of the arbitrate loop.
The RoboTag Program
Once you get through the details of implementing subsumption architecture, the rest of the programming is pretty simple. The RoboTag program uses its main task to start up all the behavior
tasks and, of course, arbitrate. It also uses the light sensor initialization code from Minerva (see Chapter 5, Minerva, a Robot with an Arm) to calculate a baseline value for the light sensor.
When the light sensor reads lower than the average, the RoboTag robot can assume it's reached the edge of the arena.
Here is the entire code for RoboTag. You should download this program to both of the robots that will be playing.
// Motor commands.
#define COMMAND_NONE -1
#define COMMAND_FORWARD 1
#define COMMAND_REVERSE 2
#define COMMAND_LEFT 3
#define COMMAND_RIGHT 4
#define COMMAND_STOP 5
#define COMMAND_FLOAT 6
// IR messages.
#define MESSAGE_TAG 33
#define MESSAGE_ACKNOWLEDGE 6
#define BUMP_SENSOR SENSOR_1
#define LIGHT_SENSOR SENSOR_2
int score;
int averageLight;
int cruiseCommand;
task cruise() {
cruiseCommand = COMMAND_FORWARD;
while (true) Wait(100);
}
int tagCommand;
task tag() {