Let's Make Robots!

Robot A.I. idea for non neural network approach.

In this Blog I am simply gethering my thoughs in preperation for a long term project. Hopefully some programming Guru's will post some good ideas. Maybe it will inspire someone else. I am just one nueron in the huge brain of humanity.

Personal History
When I was 12, I taught myself to program in GW basic on an IBM clone that ran at 8MHz with monochrome, text only graphics and a 5¼inch floppy disk drive. At that time I wanted to write an artificial inteligence.

My theory was that an A.I. was really just a database with some code that would break down your text input into basic concepts, feed it to a database in a meaningful way and convert the results into a text output that hopefully made sense.

Current Theory
30 years later my programming skills are still pretty basic (pun intended) but I think my general theory is still valid. The most important part is that the A.I needs a database, in this case a memory of events that have happened to it which can then be applied to current events to determine a suitable response.

From what I have read about nueral networks they work on a similar principle. My understanding though is that they would really work best in a machine built using graphic cards where you end up with lots of simple processors performing simple repetative tasks since each neuron is effectively a very simple processor.

In this blog I want to explore the possibility of a simple A.I. using an Arduino or Picaxe processor not using a neural network.In theory, a neural network is very adaptable and should work with any robot configuration. It is also somewhat unpredictable and random to begin with. One advantage of a non-neural network is that you can program specific directives into it from the beginning that will not change.

The most critical part of such a program will be memory and time recognition so an SD card or I2C external memory and real time clock (RTC) would be recommended for any prototype.

Memory Organization
The key to inteligince, artifical or otherwise is memory. Unless you have an Eidetic Memory then you can basically divide your memory into 2 categories, short term and long term. As our robot will have limited memory and processing power I want to divide it's memory in a similar way.

My concept of this memory division is this: When the robot is running about doing robot things, all events will be recorded along with a timestamp from the RTC into short term memory. When the robot is at rest on a charging station then it can do some robot dreaming. In this case, sort through the short term memory and create a compressed version in long term memory. This compressed version will not be as detailed, only storing significant events such as a successful completion of a task or an error such as a collision. Time stamps are used to sort the information into chronological order. As the long term memory is compressed it should also be quicker for the program to sort through when determining a correct response to a situation.

Behaviour Determination
This is perhaps the most important part. The entire reason for storing previous events in memory is so that the robot can derive a proper response to a situation.When the robot encounter a situation, for example, a collision is detected, then the robot can search it's memory for similar events.

If your robot is fairly simple and does not know where it is then it may search the memory to find the maneuver with the highest success rate such as "reverse for 500mS, turn right 30°, continue". A more advanced robot with GPS or some other means of determining location would refine the memory search for previous similar events at that location.

What is Good and Bad to a Robot?
Perhaps the most difficult part is determining what input is bad and what is good. With only limited sensors, what is a bad input or situation to be avoided and what is good? If you look at a baby who is just starting to touch things and try to put them in it's mouth then it is simple - pain or unpleasant taste is bad. No pain is interesting and pleasant taste / sensations is good.

For your robot, good and bad input depends on the task of the robot. If the robot must clean a floor then while a large impact is bad, a gental, continuous pressure against it as it cleans the foor near a wall could be a good thing as it lets the robot know it is not missing any of the floor near the wall.

Experiment 1
For my first experiment I want to keep things simple. Navigation is important for any mobile robot. This first robot will pretend it is cleaning the floor. This means it must cover the entire area of the floor as efficiently as possible without missing any spots.

It will use the RTC to ensure it only cleans from 2am to 5am when everyone should be asleep to reduce the likelyhood of being stepped on. As people may tend to get up during the night for a snack or to use the bathroom The robot will learn through trial and error to avoid those locations during certain times and may even change it's start and finish time on certain days to suit the habbits of the occupants.

I am just going to mount a Micro Magician controller on a Doodle Bot base. The 3-axis accelerometer will provide collision detection and the IR receiver will be used to locate the charging station. Doodle Bot's simple encoders will give 8 counts per wheel revolution and a voltage divider will allow the robot to monitor it's battery voltage. A left and right metal strip along either side will provide terminals for recharging. The front of the Doodle Bot is a wedge shape so it should be easy to follow an IR beacon between two electrodes and wedge itself in for recharging.

I can take advantage of the fact that this robot is designed to draw. By using a large whiteboard for a floor and giving the robot a whiteboard marker I can see where the robot has been and how experience affects the robots path. By setting up a few walls on the board I can easily create a miniature household for the robot to clean.

For my experiment I am using an RTC and SD card reader from Futurelec that I have had sitting in a draw for over 3 years now.

The results of this experiment should be some basic code that would be useful to any mobile robot capable of roaming around the home.

 


 

Update: 10-9-2012
I've had a lot of feedback already and think I need to clarify my intentions. I hope to come up with an A.I. library that anyone can use with any Arduino. There are plenty of SD card reader and RTC sheilds about. If all goes well then I might make a suitable shield for my Micro Magician.

At this point, my theoretical library would have a function for storing raw data (short term memory) on the SD card as well as one or more functions for sorting / compressing the data to become long term memory.

Once I have my Doodle Bot modified and ready for experiment 1 I will post my results and code.

 


 

Update: 12-9-2012
I have built my prototype for experiment 1. It is time to start practicing what I preach. I will continue this blog as a robot post.

 


 

UPDATE 16-9-2012

I am still writing my first bit of code which is not much more than a datalogger for the sensors. At this point in the experiment I need to work out the best way to organize the "memories" so that they can be easily interpreted as short term memory and sorted/compressed for long term memory.

Technical difficulties
The first problem I spotted was that the SD card library is huge (about 5K) so I am going to be struggling with the 16K of the current Micro Magician. Fortunately I should have the first prototype of the Micro Magician Pro next week which has an ATmega328P as well as both 5V and 3.3V regulators. This will make the RTC happy as it needs a 5V suppy which is currently being supplied by the USB cable.

The second problem I had was that the Wire library does not work very well with an 8MHz clock. I have now found a new, updated I2C library which solves this problem as well as having cool new features such as fast mode (400Khz), scan() which looks for available I2C addresses and pullup() which enables the processsors internal pullup resistors which is ideal for a 3.3V processor reading a 5V I2C device.

 


 

UPDATE 23-9-2012

Ok, I finally sorted out my problems with the I2C code and the DS1307, as with most difficult problems it was a combination of hardware and software. I have now upgraded to the first prototype of my Micro Magician Pro and a 7.4V, 2 cell LiPo rated at 1000mAh. The onboard 5V regulator allows me to power the DS1307 without limiting myself to 4x 1.2V NiMh batteries.

Now that I have the RTC working properly I wanted to take advantage of it's 56 byte of non volatile ram. Unlike the EEPROM memory in modern MCU's, the non voloatile memory can be written to as many times as you like without damage occuring. This is because it is ordinary RAM and the RTC battery stops it from being lost when you turn the robot off.

For now I am using some of this memory to record the periods of time where the processor is shut down. To do this, my code reads the time from the RTC once every second and writes a copy to the NV RAM. In the setup function which only runs when the processor first starts up, the program reads back the last time stored in memory and compares it with the current time. It then writes this "Shutdown Period" into a second section of the NV RAM.

This data will not be useful for my current experiment but could be handy at a later stage. My main reason for doing this now was to test that I had everything working properly. I suspect the NV RAM will come in handy for other things later.

Now I can start some serious programming!

The first thing I need to do is work out my file structure for the short term memory. The exact structure will depend a lot on your robot and what sensors it has. The short term memory will record all data for later, indepth examination while the batteries are charging (dream time).

When I sat down to plan my memory structure I was surprised at just how many bytes of memory each "event" would need. The robot does not have many sensors (a 3-axis accelerometer, 2 encoders and an IR receiver) but I still ended up with a minimum of 49 bytes. I am going to round this number up to 64bytes per memory event. This way I have a few spare if I've forgotten anything or want to add more sensors later.

Here is the current structure of a single "memory event". The number at the left is an index number used for selecting specific information from the event.

Note index 0, this is a quick reference byte that records the reason for the event being recorded e.g. impact detected or motor stalled.This can be used later when the robot is looking for memories of similar occurances hapening. For our robot to be inteligent it must be able to cross reference and analyze these memories.

	AI short memory data structure

0	memory trigger event	byte
1	year			byte
2	month			byte
3	date			byte
4	day			byte
5	hour			byte
6	minute			byte
7	second			byte
8	magnitude		msb
9	magnitude		lsb
10	deltx			msb
11	deltx			lsb
12	delty			msb
13	delty			lsb
14	deltz			msb
15	deltz			lsb
16	x-axis			msb
17	x-axis			lsb
18	y-axis			msb
19	y-axis			lsb
20	z-axis			msb
21	z-axis			lsb
22	0G time milliseconds	msb
23	0G time milliseconds	lsb
24	left encoder count	msb
25	left encoder count	lsb
26	right encoder count	msb
27	right encoder count	lsb
28	left speed		msb
29	left speed		lsb
30	right speed		msb
31	right speed		lsb
32	left & right brake	byte
33	left & right stall	byte
34	servo position		msb
35	servo position		lsb
36	battery voltage		msb
37	battery voltage 	lsb
38	IR command received	byte
39	current mode		byte
40	position X co-ordinate	msb
41	position X co-ordinate	lsb
42	position Y co-ordinate	msb
43	position Y co-ordinate	lsb
44	position Z co-ordinate	msb
45	position Z co-ordinate	lsb
46	direction		byte
47	action taken		byte
48	reason for action	byte
49-63	spare			byte
	

A lot of this data is not really relavent and can ultimately be eliminated from a memory event. For example, 0G fall time is only relavent if the robot actually falls. The problem is that our processor is no super computer and trying to sort through this information while the robot is functioning would significantly slow down it's reaction time.

Another problem is that until the information is fully analysed we do not know what information is significant and what is not. This is where the robots "dream time" comes in. The idea is that the robot uses the time in the docking station to analyse the events with 20-20 hind sight and try to find ways to improve it's response in a situation.

My goal is to have all this done by my lowly MCU although I admit it may be neccessary to use a PC to analyse the data on the SD card while the robot sleeps. At this stage it might sound like I am attempting the impossible but stop and look at Patrick's maze solving robot. The robot runs through the maze using a standard "follow the wall" routine and then analyzes the path it took to optimize it. Next time the robot goes through the maze it makes no wrong turns.

My current approach for STEP 1 is to just save it all in a standard format as quick as possible and sort it later when the batteries are on charge. This may change as I write the code. I'm having a few problems with the impact code right now which may be due to either mechanical vibration or electrical noise from the I2C interface.

 

 

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

About the memory device, I happen to have an OpenLog. Will your code work with it?

Right now it will not because your OpenLog has it's own Arduino running the SD library. You would need to modify my code to bypass the SD library and send the data directly to the Open Log. It should not be a major change. As I do not have an Open Log I cannot test the code on it.

Ultimately, If I succeed then the Open Log will not be compatible without a rewrite of it's firmware. This will be something like step 10 (if I ever get that far). Now I am on step 1 and just trying to determine the best data structure to store the information.

Great works oddbot!!Every time you came up with new thought.Can you provide any details about the memory device you are using  

( Futurelec SD card).

I mean how do you connect it to the arduino platform or the language/logic to program the chip etc.

while taking the Udacity courses I always thought about making one.

I just bought a couple of cheap sdcard breakouts here for a few dollars.

They look perfect. Just beware, although they have a nice 3.3V regulator they do not have the level shifting IC needed to prevent you frying your SD card with a 5V signal from your processor.

Because I am using a Micro magician that runs at 3.3V this is not a problem for me but you may want to add a 4050 hex-non inverting buffer like Sparkfun did here: http://www.sparkfun.com/datasheets/DevTools/Arduino/microSD_Shield-v13%20Schematic.pdf

Thanks for the advice. I mightn't have caught that.

The mini SD card I am using was bought from Futurlec almost 4 years ago. it is just a simple breakout board for for an SD card, nothing special. The only reason I am using it is because it has been sitting in my desk draw for over 3 years now and has never been used. Any SD card breakout board could be used.

My connections are:
D10(SS)     from Arduino to SD card pin 1(CD/DAT3)
D11(MOSI)  from Arduino to SD card pin 2(CMD)
D12(MISO)  from Arduino to SD card pin 7(DAT0)
D13(SCK)   from Arduino to SD card pin 5(CLK)

http://www.futurlec.com/Mini_SC.shtml

although I would go with this one:

http://www.futurlec.com/Mini_microSD_Board.shtml

but I already have an OpenLog from SparkFun so I'm going to use it and profit from the fact that I do not need to load a huge library to read/write to the SD card.

I know when I was growing up one of best ways I learn't not to do something was the word "NO", and the times when I couldn't figure out what the word "NO" meant... well lets just say I now know a wooden spoon is for cooking ;-)

Thinking of this, I can see an IR "Wooden spoon" coming in handy. eg. Robot bumps into an object, reverse's, then goes straight back into the object "SMACK", Robot learns that a HIGH signal on pin X is bad if it stays on the same course.

I'd love to see this project come to fruition and Oddbot you always seem to be able to brake a huge idea down to simplistic goals!

Wish I had the brains to help!

Your analogy is better suited to a neural net AI. In the case of X1, it's purpose and goals are programmed in. A failed attempt to acheive a goal is a "NO". An unexpected impact could also be considered a "NO" under certain circumstances.