Irish Micromouse competition - Brandon

Design overview

Hardware

Brandon's hardware is fairly simple. The main bits are:

Processor board
New Micros Inc NMIT0020 board containing a Motorola 68HC11 processor, 48k of static RAM, and a selection of extra circuitry to connect the motors and sensors.
Drive system
Differential drive based on two model aircraft servo motors.
Sensors
Six infra-red emitter/detector pairs - two at each side of the robot, and one each at the front and rear, located approx 25mm from the ground. Two Motion detectors based on bits from a PC mouse - the slotted wheels are kept in contact with the ground, and provide accurate information even if the drive wheels are skidding on the ground.
Batteries
Ten NiCd AA cells.

Software

Brandon's software consists of a multitasking operating system written in assembly language, some libraries written in both assembly language and C, and the maze solving and motion systems which are written in C.

Operating System

Well, an operating system is a bit too grand a term for what Brandon runs, but it does support all the basics required for multitasking. And it was written in just a few weeks so we didn't do too badly. There is obviously no protection available with the 68HC11, so which bits make up the kernel and which are libraries is a bit fuzzy. The basic set of system functions provided by the kernel are:

Process management

void idle(void)
The scheduling of processes is done on a purely round-robin basis, with each process given a fixed timeslice of CPU time before a preemptive context switch occurs. This function allows a process to give up its current time slice, causing an early context switch.
int fork(int stacksize)
A UNIX-style fork function. The only difference is that you must specify the stack size for the new process. This was definitely the most interesting part of the kernel code to write!
void PM_SetTimeSlice(int slicelen)
Set the timeslice of the current process to the given number of microseconds. This is the only way to control the priority of processes.

Memory management

void *malloc(int len)
void free(void *p)
Just like the standard C malloc and free, except they're inefficient and do no argument checks.
int FreeMemory(void)
Returns the amount of free memory in bytes.

Input/Output and Timer Events

void SIO_lock(void)
void SIO_unlock(void)
Lock/unlock the serial IO subsystem. This is used before the putchar and getchar functions to serialise access to the serial interface.
void SIO_putchar(char c)
int SIO_getchar(char *cp)
Write/read a single character to/from the serial port.
int OPT_X_Pos(void)
int OPT_Y_Pos(void)
int OPT_Angle(void)
void OPT_Reset(void)
void OPT_Correct(int dx,int dy,int dtheta)
Functions for accessing the position information updated every time a signal from the optical movement sensors is detected. Coordinates are relative to the maze, and are measured in units of approx 0.5mm for distances, and 0.5 degrees for angles. OPT_Correct allows the position system's idea of where it is to be corrected (usually from wall sensor readings).
void SetMotorSpeed(int Motor1, int Motor2)
Set the speed of the two motors. The motors are controlled with a software PWM system, which uses the HC11's built in timers.
void IR_on(void)
void IR_off(void)
Turn the wall sensor IR LEDs on or off to save power.
int Analog(int input)
Read a value from the given analog input port

Top-level assembly startup code
Process management assembly code
C startup code

Processes

Brandon's code runs in three processes:

The maze solver process is the highest control level. It knows the maze only as a 16 by 16 grid of cells, and the robot's position in cell coordinates. The main control loop of this process consists of asking which of the north, east, south and west directions are blocked by walls, deciding where to go, and telling the navigation system which direction to move next.
Top-level Solver C code

The navigation process is concerned with moving the robot from one maze cell to the next. It receives commands from the maze solver and then uses sensor feedback loops to move in the correct direction. When it has moved to the destination cell, it tells the maze solver process which of the directions contain walls. Note that there is no code for turning corners; if when starting to move, the robot is facing the wrong direction, then this is simply detected and corrected by the feedback loops.
Navigation C code, including feedback loops

The clever bit is how the above two processes interact. With the simple layout described, you would expect the robot to move to the next cell and then stop to wait for the maze solver to tell it what to do next. This would result in very jerky and inefficient movement. What actually happens is that the navigation system can return the list of valid exits long before the robot reaches the centre of its destination cell. As soon as the front 2 side sensors are in the cell, all 4 exits can be checked. When running, this allows the maze solver more than enough time to calculate the next move before the robot even begins to slow down.

The diagnostics system provides regular status indications on the LCD screen, and polls the keypad.

Sample runtime debug output
Ian Dowse <iedowse@maths.tcd.ie>