Introduction
Behaviour-based architectures for autonomous
intelligent agents have successfully demonstrated their ability to provide reliable
solutions to a variety of control problems. Angle (1989, MIT) was able to produce
Genghis, a six-legged autonomous walking robot. Maes and Brooks (1990) then
used Genghis to study learning, and successfully implemented a reinforcement learning
algorithm capable of teaching Genghis to walk forwards and backwards. Our aim was to
reproduce this work, by first constructing a hexapod robot capable of walking using a
behaviour based control system, and then implementing a learning algorithm to achieve the
task. We hoped to gain an understanding of the capabilities of behaviour-based robot
control and to examine the difficulties of learning within such a control system.
It soon became apparent that developing a
suitable robot morphology within the limits of the equipment available was non-trivial.
Hardware restrictions and time-pressures eventually prohibited us from implementing a
learning algorithm. The algorithm we designed will still be discussed in this report but
was never actually realised.
It was
necessary to build a stable and strong Lego framework and install the various Lego and
motor components, in such a way that the six legs fully support the robots weight
and allow it enough freedom of movement to implement an appropriate forward walking gait.
Instead of looking at the robot as a whole and
trying to immediately construct all of it, we decomposed it into three leg segments and
tried to construct the best possible design for an individual leg segment. This divide and
conquer approach allowed us to take advantage of the robots symmetrical morphology.
Designing one segment
Each segment consisted of two legs.
The segment was built using four servomotors two for each leg. This gave the leg
two-degree movement (ie. both horizontal and vertical). The first step was to screw one
long Lego bit to one servomotor and we proceeded by attaching the whole module to the
other servomotor. This would allow the two-degrees of freedom we wanted. The two legs were
then built to complete the segment. This design seemed really strong, and small enough to
achieve what we wanted.
Framework
After successfully constructing the first
segment, the other two segments were duplicated from the first one. The next approach was
to attach the segments together to form the whole robot morphology, using Lego pieces to
build the framework.
Handy Boards
The robot consisted of 12 servomotors
controlling the legs. Since the handy board used had
only six servomotor connections, two
handy boards were needed to control the 12 servomotors.
The handy boards were secured on the robot
properly so that they didnt fall off, and they were positioned so that their weights
were uniformly distributed to allow standing up and walking forward of the robot. The
handy board holder was just a simple frame built with Lego allowing the handy board to
stay in its fixed position.
The two handy boards communicated with each
other using a serial wire. We had to build the serial wire using the configurations found
on the handy board help Internet site.
Attaching the Switches and Whiskers
Switches and Whiskers were necessary for feedback. Four digital switches were needed under the robots body to detect if the robot had fallen down, and two analog whiskers were needed on the front to detect object collision.
Handyboard to Handyboard Communication
It was necessary
to write code to ensure the boards were synchronised at all times. We implemented a very
basic form of handshaking where upon receiving data, the board would reply with an exact
copy, with the sender waiting for this response before any further transmission.
Our aim was to write a program which would allow the robot to walk forwards with a tripod gait without falling over. We also wanted the robot to reverse, and turn left and right if it detected an object in front of it.
The first goal therefore was to lift the first set of legs up, move them forwards, lower them to the floor, and drag them back to their initial position..
We decided to implement this using a state-block for each leg, and a loop which would, for each leg, look at the state-block for that leg, decide on a horizontal and/or vertical movement it, and move the appropriate servo motors. The state-block would contain whether the leg was moving (i.e. whether it was in the set that was currently active) and what stage of the movement it was performing. The program could (if the leg was moving) see if the leg had completed its current movement stage, and move it on to the next stage. If all the legs in the set had completed all the movement stages, the other set could begin.
We had to find the servo values for each leg position. We did this by testing different values on each leg and examining whether they appeared aligned (introducing a small amount of human error), and compiling these into a table with up and down vertical positions, and horizontal normal and forwards positions, for each leg.
It wasnt possible to detect if a robot leg had reached its destination or not using the equipment we had. To solve this, we decided to estimate when a leg had reached its destination, using a cycle counter. At first, we guessed at the number of cycles through the program loop we though a leg would take, to perform a particular movement. We then observed the robot in action, and adjusted as we saw fit.
We realised that if one set of legs began their movement at the same time the other set started dragging back to their initial positions, all legs would be pushing the robot forwards at the same time, whilst retaining stability. We implemented this walking method, and the result was a faster and more elegant walk.
The different modes of operation that the robot could be in were standing still, walking forwards, walking backwards, turning left, and turning right.
The control program had to work out the series of movement stages needed to move or lift to a target position, work out how long each will take, and queue these, performing them in turn. It works these out by using tables which map every position a leg could be in, to every position a leg could want to be in. The tables give the best 'route' to get there. There is a different table for moving directly, and lifting. When the program is performing a movement for a leg, it uses another table to find the horizontal and vertical motor values for that particular movement.
We added support for having sets of legs which can activate each other, as needed for walking.
The small window is not ideal for debugging purposes, and downloading the program onto the handyboards every time we need to test it is very time-consuming. Instead, we wrote a test program for Windows which ran the control program and could output the state of any part of the system (such as the queues). It also allowed keys to be pressed to activate sensors, so the collision detection module could be tested. This allowed us to debug the program before running it on the robot.