
Real-time Systems – D0003E
Lab 6 (extra lab)
Commanding a robot
The task of this lab assignment is to write the software controlling a
miniature industrial robot. Our robots consist of three linked arms
with a claw at one end, mounted at the other end onto a rotatable base.
Each arm joint as well as the claw and the base can be individually
controlled via five servo motors, as illustrated by the following
picture:
A robot unit needs three electrical connections to the external world:
- A serial programming interface, joining host PC port COM1 to the
on-board ICSP socket via a serial cable and a special purpose adapter.
- A 5V/2A power source for the servos. Use an external power supply
for this purpose, connected to the bipolar socket on the robot unit.
Note:
make absolutely sure that the
voltage setting is below 6V before connecting!
- A USB connection between the robot and the host PC, in this
assignment only used for supplying power to the embedded
microcontroller.
The servo motors each have a span of about 180°, although
mechanical constraints render some angles – or rather, combinations of
angles for the five different servos – unobtainable. Directing a servo
towards a specific angular position amounts to sending a flow of pulses
to its control signal input, where the length of each pulse determines the
desired angle. The full span is obtained by letting the pulse length
take on values in the range 1 ms (one extreme position) to 2 ms (the
other extreme position). The actual pulse rate is not particularly
critical, though; a good recommendation is to send around 50 pulses
a second to each servo. However, in order to limit the load on the
external power supply, it is advisable to avoid overlapping of pulses
to multiple servos.
The overall task of this assignment is to write software for the
embedded microcontroller that lets the robot perform a sequence of
pre-programmed movements. The
shape and purpose of these movements is unimportant, as long as the set
contains at least two movements with clearly distinct start positions.
One option
might be to design a movement that makes the robot arm grip a small
object and move it from one place to another, together with a movement
that is the reversal of the first one. For illustrative purposes it is
useful to smoothen out each movement so
that it extends over several seconds. This can be achieved by changing
the servo settings in small increments, suitably distributed over time.
The final position of one movement must be the starting position of the
subsequent one, extended in a circular fashion such that the last
movement ends up in a position that is also the starting position of
movement no. 1. Each movement in a cycle is supposed to be triggered by
pressing the push button
mounted on the microcontroller board adjacent to the USB socket.
Without such a "go ahead" event, the microcontroller shall just hold
the robot arm in the starting position of the upcoming movement.
However, the real challenge in this assignment is to make it possible
to request the next movement ahead
of time;
i.e., even when the robot arm is in the middle of another movement.
The correct behavior in this situation is to abort the current movement
and quickly adjust the robot arm into its new starting position, before
commencing the requested movement proper. This "fast forward" behavior
shall furthermore be transitive; i.e., pressing the button again while
the arm is adjusting shall immediately trigger an adjustment towards
the starting position yet another step ahead in the movement cycle.
The microcontroller embedded in our miniature robots is an AVRmega32, which is a slight
variant of the controller that powers the Butterfly boards.
Documentation on the microcontroller can be found in the AVRmega32 datasheet, and
further information
regarding the microcontroller board and its peripherals (including a
wiring diagram) can be had here.
The
signal inputs to the five servo motors are all connected to port C,
according to the following schema:
Servo no. 1
|
(grip)
|
Port C, bit 0
|
Servo no. 2
|
|
Port C, bit 1
|
Servo no. 3
|
|
Port C, bit 2
|
Servo no. 4
|
|
Port C, bit 3
|
Servo no. 5
|
(base)
|
Port C, bit 4
|
The assignment shall be implemented as a system of reactive objects
running under the TinyTimber
kernel. Note: unlike the controller on the Butterfly boards, the
AVRmega32 is incapable of generating interrupts from state changes on
arbitrary port input pins. This means – among other things – that the
on-board push button must be sampled
at regular intervals (see the wiring diagram for the appropriate port
and bit number). On the other hand, the AVRmega32 is equipped with more
memory, which gives TinyTimber space enough to maintain many more
outstanding asynchronous messages than in the previous assignments. To
obtain an updated version of TinyTimber that runs on the AVRmega32 as
well, download files TinyTimber.h
and TinyTimber.c.
Note on the development tools: the compiler avr-gcc
needs the flag -mmcu=atmega32
in order to generate correct code for the AVRmega32. Furthermore, the
software download utility avrdude
must be told about the new hardware interface (flag -c ponyser)
and the new target architecture (flag -p atmega32)
in
order
to
work with the robot units. Both these changes can
preferably be edited into the makefile used in previous assignments.