The SickSack controller interfaces all components and creates and controls the slithering movement. In summary, the microcontroller had to be programmed to perform the following tasks:
The servos in themselves work as position servos, actively trying to hold a position (angle) that is commanded by the signal pulse width. This PWM signal consists of pulses with lengths from 500 to 2100 micro seconds, repeating at 50 Hz.
The 20000 micro seconds in a 50 Hz time frame conveniently allows for creating the eight servo pwm pulses one at a time. This meant that an implementation entirely based on timer interrupts was possible, such that the pulse widths were defined by the timer output compare register.
The 50 Hz time frame, as required by the servos, was adapted for the fundamental control cycle time frame. This meant that a new differential sample from each photo transistor should preferable be available 50 times a second.
Thanks to the AD conversion capabilities of the AVR, that was easily achieveable. In fact, the implemented AD conversion scheduling provided four samples for each photo transistor for both illumination on and off for each time frame.
The basic concept of the snake motion is that the angle of the head servo does in turn become the angle of the second servo, the third servo, fourth servo etc. and finally the tail servo, corresponding to the progress of the robot movement.
This basic principle leads to an implementation where the head servo angle solely defines the motion, and a buffer stores the history of head angles for the rest of the servo angles. The implemented circular buffer have 16 slots between each servo, such that 16 steps in the buffer would result in having a given servo angle appearing at the next servo. The speed of stepping forward in the buffer thus defines the speed of intended snake movement.
To define the snake motion thus meant to command the head servo and to decide how fast the buffer should step forward. A sine wave was generated for the head servo motion, with possibilities for defining amplitude and frequency. The sine implementation relies on a lookup table.
SickSack only sees the line on the floor when the head moves over it. Implementing a line following algorithm based on this sensor information was somewhat difficult.
The final algorithm had to work on two levels. Basically the robot constantly keeps track of whether the line is at its left or right. When the line is at the left, the head angle wave is added an offset resulting in the robot turning slowly to the left. When the line is at the right, a similar offset of opposite sign is added to make the robot slowly turning to the right. This seeking motion can be observed when the robot is away from the line.
That principle alone, however, does not lead to a very stable line following performance. Another level of feedback is also performed in the algorithm, the phase of the head wave. Whenever the head crosses the line, the phase of the sine wave is forced to either 0 or Pi radians. This means that the oscillation sort of locks on to the line on the floor. The feedback concept was not easy to get going, and had to be improved with a number of additional rules. But the result was a stable and good performing line following algorithm.
The source is not downloadable, as it is in a rather rough state and possibly contains a lot of bugs. It shows that large part of the code was conjured in a few days of stressful hacking.
Previous: Construction - Next: Afterword