ECE 460

Final Project

 

 

Jonathan Connell's

Muramator Robot

Implemented with

Digital Micro controllers

 

by Sean Korb

December 8, 1995

 

 


Abstract:

Jonathan Connell's Muramator robot, featured in the August 1991 issue of Popular Electronics, is implemented using micro controller neurons instead of analog neurons.  Muramator, a "wall hugging creature", features a neural network to implement sensation, reaction, and basic drive behavior.  Precise adjustment of neuron "weights" is possible using this method.


1.0 Introduction

For living organisms, neurons implement the software of life.  How we feel, move, react, even think is controlled by the neurons in our body.  Even the simplest of creatures can react to light, sound, proximity, and chemicals in a specific and pre-programmed regimen.  Snails will move up out of the water by moving towards light, and then into a crevice when they are in the air.  No prior knowledge was needed, nor was any given.  The snail moves in this manner because it is born with the wiring that made it thus.  In creating Muramator, Jonathan Connell of the MIT robotics lab desired a minimalist creature that would move towards, find, and then run alongside the walls in a room.  He used a small vehicle from Radio Shack that could move forward and turn in reverse. Using capacitors, resistors and a comparator, he implemented 11 neurons to operate as the brain for the creature (see figure 1.1)

 

Figure 1.1

 

In the diagram, dark synapses represent draining neurons and lighter synapses are additive synapses.  Checkered neurons are always on, while the other neurons have a constant leakage current of -1.  The threshold on all neurons is a Shmitt-trigger: that is, the neuron fires when the integrated input is a 1, and does not turn off again until the integrated input is zero again.  The  diagram in appendix B describes this operation.

 

This creature was very effective and inexpensive to build, but once built, it was not very flexible in it's programming,  nor could the weights for the neurons be specifically assigned.  Adjustment of the weights KT and KF were made by adjusting potentiometers.


2.0 System Design and Implementation

This muramator implemented Jonathan Connor's neural network for Muramator using two BASIC Stamp modules available from Parallax Inc.  The sensory and animatory hardware are similar to the specifications for Connor's Muramator.

 

2.1 Muramator's Neural Network

2.1.1 BASIC Stamp Module

The BASIC Stamp 1 and BASIC Stamp 2 are available from Parallax Inc.  They use a PIC microprocessor, voltage regulator, BASIC interpreter, and an EPROM soldered onto a stamp sized PC board.  The Stamp1 has 8 I/O pins and runs at 4Mhz.  The Stamp2 has 16 I/O pins and runs at 20Mhz.  Both modules accept serial inputs and regulate power from a 9V battery to 5.0V on the Stamp.  The Stamp2 provides more instruction and data memory as well as an enhanced instruction set.  Neither stamp directly handles floating point or negative numbers, though numbers may be programmed in hex, binary, octal, or decimal.

 

Programs for the modules are composed using Parallax's editing/downloading software available for the IBM PC by FTP for free from their site.  After loading a program into the editor, the program was translated into tokens that were fed to the EEPROM on the Stamp using serial lines.  The program ran immediately, and could be terminated by removing power to the Stamp.  Once the program was loaded, it would run any time power was applied to the Stamp.  Though 2 Stamp modules were used, it is certainly possible to use only one Stamp, though the code may have been too crowded and execution too slow if implemented on the Stamp1.  The Stamp2 would likely have worked flawlessly if used solo, but it was interesting to find out how two stamps would communicate, especially if discrete behaviors were implemented upon individual Stamps.

 

2.1.2 Neural Network Design

Jonathan Connell's neuron map was followed closely, but some things are easier to implement digitally than in analog, as there are also some things more easily implemented using analog technology rather than digital.  Where obvious, digital technology replaced neurons that performed the same function.  The modified maps are in appendix C.

 

The Stamp1 was to control the proximity detection neurons.  Where Connell used a feedback neuron to generate a pulse, I simply toggled the output pin to the Infrared emitter at the beginning of the program loop.  The detector neuron software "integrated" the input from the detector transistor.  The weights on the neuron effected the slope of the output to the threshold such that the neuron would more or less quickly reach it's threshold value.  There was always a leakage current on this neuron, so the sum equation looked like 8(detector) - 1.  Since the equation is integrated over time, the output to the threshold is this sum times the time from t nought divided by the time constant, 100ms in this case.  Since the command "pause 1" halts execution for 1ms, this seemed a good approximation for timing.  The time constant can be increased, or the weight decreased to artificially increase the amount of time that the neuron will fire, and in this case, increase the time the creature spends engaged in a turn.  The integration of the signal allows for rejection of noise pulses and "fly wheeling" through signal dropouts.  This function is obviously more effectively implemented using analog logic, but it was interesting to implement it digitally.

 

It was not necessary to scale the numbers for greater precision since the only results I was interested in were 1 or zero after dividing the result by the time constant.  Since the division function for the BASIC Stamp only returns an integer dividend, I could simply wait for the appropriate integer. 

 

Negative numbers were handled by offsetting calculations by  32768 where appropriate.  Functions that normally decayed to zero due to a negative slope were put in a positive paradigm where they would increase to 1 to simulate the desired calculation.  That said, the coding was rather straightforward, and a complete listing is in appendix A.

 

When  the network on Stamp1 detects an object in Muramator's path, it sends a signal to the Stamp2.  This neuron firing suppresses all other behaviors in favor of the "avoid" behavior.  The creature turns away from an object in it's path.  The "seek" behavior engages about every 3 or 4 seconds if the creature has not found an object, and instructs the machine in a 270_ turn.  If an object is encountered in that turn, the seek behavior is suppressed by the avoid behavior, synchronizing the creature, and directing it toward the wall such that it may run beside it.  The explore behavior is always on, directing the creature forward on it's quest for meaning and tranquillity in it's. . .hmmmnnn. . .

The explore behavior is suppressed as well when the avoid behavior is implemented. 

 

Several intermediate neurons are used to help direct behavior at a lower level so the programmer is free to program at a higher level.  One of the neurons actually implements a simple OR function, so an OR statement was used in the code instead of neuron math.  A NOT-AND gate was also present in the network, but this was implemented using Neurons.  Some of the software was minimized to save variable space.  Code for the Stamp2 implementation is also in Appendix A.

 

2.2 Muramator Vehicle Hardware

This presented some of the most difficult problems for building Muramator.  Since Radio Shack no longer caries simple and inexpensive toys like the ones I needed for Muramator, I scoured the toy stores trying to look for an appropriate vehicle.  I tried one from Radio Shack, but it's turning radius was much too wide, and could not possibly implement Muramator behavior.  I finally settled on a small toy that used independently rotating rear wheels to steer itself.  Unfortunately, I did not know at the time that the way it managed to do that without moving the front wheels is that it made a "wheelie" in every turn.  Since Muramator bristles with batteries for it's payload, and the IR detector needs a stable platform anyway, modifications had to be made.  A Lego front wheel for an airplane set was inserted in the front so that it might move laterally with more ease.  This proved more of a difficulty than originally thought as the creature would nearly always list to the left, probably due to balance conditions.

 

2.2.1 Vehicle Motor Control

Since each wheel in the rear had it's own motor, a system had to be developed to activate either both wheels forward, or one wheel backward to make a turn.  I decided upon using three relays controlled by the Stamp2 to add future flexibility if needed.  The relays are triggered by a transistor whose minimal base current is given by the Stamp2.  The relay provides a resistive load to the collector  tied to the 9V power supply, and the emitter has a resistor tied to ground to divide the voltage across the 5V relay.  Simple 2n3906 transistors were used for economic reasons.  No sense in overkill.  A circuit diagram can be found in Appendix D.

 

2.2.2 Infrared Emitter

A super bright IR emitting LED was selected hooked in series to a current limiting resistor at the emitter of another 2n3906 transistor.  Again, minimal base current is drawn from the Stamp1 module to activate the emitter.

 

2.2.3 Infrared Detector

This was the most problematic of the external devices for the creature.  The output of the IR detecting transistor is most decidedly analog, so a natural desire would be to have the output to the Stamp1 high if there is small Vce and register low if there is large Vce since the IR light provides the base current.  This was accomplished using an LM324 operational amplifier in an inverting comparator configuration.  A test voltage is applied to the positive input to the comparator, and if the voltage at the negative input goes higher than the test voltage, the output goes low (to Vsat, about 1.3 volts) and when the negative input goes lower than the test voltage,  the output goes to the power supply rail, which in this case is 5V.  A 741 was used at first, but it proved too sensitive to input resistance balance, and it seemed to be unhappy having one of it's supply rails sitting at ground state all the time.  The LM324 is designed differently and it's internal negative supply rail is referenced to ground, so it is happy at 0V - 5V.  A voltage divider with a potentiometer was used for field adjustment of sensitivity of the test voltage.

 

2.3 Putting it all together

The hardware previously described was assembled using wire wrap and mounted on the vehicle with wire ties and elastic bands.  Batteries were located in the rear for better traction and maneuverability.  The IR detector/emitter pair was located at the front of the vehicle, pointed approximately 30_ to the right of center.  This makes sense, since the creature avoids obstacles by turning left.  The following diagram shows the hardware configurations.

 

 

Figure 2.1

 

 

 

2.3.1 Testing

The most frustrating bit of testing was the range of the IR detector.  It seemed myopic throughout  all the experiments.  The creature would roll so quickly that it would hit the wall, and then detect it.  It seemed like it needed glasses.  The LM324 seemed to help in this regard, though the vehicle still seemed to move too quickly.  Pulsing the output to the motor to slow it down was tried, but it seemed to give a high inductive load to the rest of the circuits, and unpredictable behavior was the result. 

 

Experiments with the detected neuron weights went as expected, and an arbitrary degree of turn could easily be implemented by adjusting the time constant, the weights, or both.

 

Adjusting KF and KT turned out to be more difficult on this model than could be presumed on the analog model with potentiometers.  Every adjustment led to a hook up to the PC for a new program download.  If dials were installed on Muramator to simulate the action of potentiometers, it might become more ergonomic.  However, using raw numbers for weights made predictions about behavior very accurate.

 

Muramator did indeed implement all of it's behaviors successfully, but it's myopic eyesight and listing celeritous gait made it difficult to show this to the uninformed.  Since I knew exactly what I had programmed the creature to do, it was easier for me to detect when the creature was doing it.


3.0 Design Options

This robot is wide open to design options.  Different vehicles could be used with the same network as used presently, possibly with better results.  The entire network could be redesigned with no hardware alterations to implement entirely different behavior.  A back propagating neural net could be programmed onto the Stamp2 such that the creature might "learn" it's own behavior.

 

Various solutions to the creatures myopic eyesight include using high frequency IR, or using Sonar for proximity detection.

 

These same design principals can lead to much more complex robots implementing interesting behaviors from washing street corners to sorting recycled waste.  The possibilities are endless.

 


4.0 Conclusions and Recommendations

There are many remarks that do not fit in a specific category, not the least of which are the Stamp modules from Parallax.  It seems that these micro controllers could be used by sophomores or even high school students to implement sophisticated projects.  The power supply problems are almost zero, and programming the modules is almost ridiculously easy.  It does give students insight into some of the limitations of micro controllers, as well as some of their greater values.  Since Parallax offers a 15% discount off of bulk rates for educational use, and the documentation and software is available via FTP, it seems criminal for greater institutions  to not teach a course based around the Stamp.

 

Muramator is much too expensive to produce as a programmable toy.  Even with the entire prototype vehicle weighing in at about  $70 for a pared down version of what was presented here, there are much less expensive toys that can do the same thing with simple switches and whiskers.  It's probably easier to just get yourself a free kitten.  It may not be a Muramator, but it's much softer.


'Program For Stamp 1  IR detector and Emitter control

 

output 5           'Set up output pins

input 6

output 7

 

symbol time = w1

symbol timeConstant = w2

symbol sumdetect = w3

symbol integrand = w4

 

time = 0

timeConstant = 20

 

pin7 = 0

pin5 = 1

 

start:

if pin5 = 0 then pinhigh

pin5 = 0

goto lookattime

pinhigh:

pin5 = 1

lookattime:

if time < timeConstant then addTime

goto notime

addtime

time = time + 1

notime:

sumdetect = 8*pin6 + 32768 - 1

if sumdetect < 32768 then negdetect

posdetect:

sumdetect = sumdetect - 32768

integrand = 0 + sumdetect * time / timeConstant

if integrand >= 1 then activate

goto start

 

negdetect:            ' actualy simulates decay of function

                      ' towards zero

sumdetect = 32768 - sumdetect

integrand = sumdetect * time / timeconstant '1-sum*t/T

if integrand >= 1 then deactivate

goto start

 

activate:

time = 0

pin7 = 1

goto start

 

deactivate:

time = 0

pin7 = 0

goto start

 


'Program for Stamp 2  Neuron net and Motor control

 

input 0

 

time var word

timeConstant con 5000 '5 seconds

sumseek var word

integrand var word

syn1turnsup var bit

syn1turn var bit

detect var bit

KF con 20 'seek interval weight, smaller for larger interval

KT con 80  'turn weight, smaller for larger turn time

syn1forwardsup var bit

syn2forwardsup var bit

synforward var bit

seek var bit

 

time = 0 

seek = 0

detect = 0

 

high 7

low 8 

low 9

 

start:

'pause 1

'debug dec?  seek 

'debug  dec? time

'debug dec? sumseek

'debug dec? integrand

 

avoid:

if in0 = 1 then setavoidsynapse

syn1turnsup = 0

detect = 0

goto skipsetavoid

setavoidsynapse:

syn1turnsup = 1

detect = 1

skipsetavoid:

 

seekbehaviour:

if time < timeConstant then addTime

goto notime

addtime:

time = time + 1

notime:

sumseek = KT * seek  'KF - KT(seek) - 100(detect) - 1 + 32768

sumseek = 1000 * detect + sumseek

sumseek = 32768 + KF - 1 - sumseek

 

 

if sumseek < 32768 then negseek

posseek:

sumseek = sumseek - 32768

integrand = 0 + sumseek * time / timeConstant

if integrand >= 1 then activateseek

goto turnsuppressor negseek:

sumseek = 32768 - sumseek

integrand = sumseek * time / timeConstant '1-sum*t/T

if integrand >= 1 then deactivateseek

goto turnsuppressor  activateseek:

time = 0

seek = 1

goto turnsuppressor

 

deactivateseek:

time = 0

seek = 0

goto turnsuppressor

 

 

turnsuppressor:

 

if syn1turnsup = 1 or seek = 1 then turnset

syn1turn = 0

syn1forwardsup = 0

goto skipturnset

turnset:

syn1turn = 1

syn1forwardsup = 1

skipturnset:

 

'explore

forwardsuppressor:

if 1 - syn1forwardsup = 1 then forwardset '2*syn2 - 2*syn1 =2 or 0

synforward = 0

goto forsupskip

forwardset:

synforward = 1

forsupskip:

 

 

'behave

'debug dec? synforward

'debug dec? syn1turn

'debug"."

'debug"."

'debug"."

out7 = synforward

out8 = syn1turn

out9 = syn1turn

pause 1'000

goto start