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.

I am not sure how useful an RTC will really be. You can simulate it with the processors own clock as long as the power is not turned off. At this point, I am treating it like another sensor. As I mentioned it could be useful for determining patterns to events such as what time at night do people turn off the lights and go to sleep. The robot may come to realize that in the early hours of saturday and sunday moring that the bathroom light comes on regularly because the occupants drank a lot at a party. Over time (if it survives) the robot will learn to avoid that area at that time or else it may get stepped on or kicked.

I feel the same way about neural nets as you do. From what I have read about them including an Arduino based robot that was emulating a simple neural net I decided that they are better suited for a FPGA. I think it would be possible to have an FPGA configured to be several neurons and then use several FPGA's to create a simple brain. This is something I would like to try one day.

Memory implementation is something I need to work out in more detail. Once I get my robot assembled and the basic functions sorted out then memory is the next thing. To begin with I was planning to store both short term and long term memory on the SD card so it can be backed up or analysed from the PC.

I will update this blog once I have some basic code worked out.

Maybe you should consider a larger platform so you can fit two micromagicians on board or a second arduino. Not so much for extra IO but for extra processing power. One could, say be left in charge of memory and database management and the other runs the actuators and sensors. Just an idea spurred on by your thoughts above regarding the graphics card and multiple processors.

For now I just want to see what can be done with a single, simple 8 bit processor. I am hoping to create some nice memory management functions and ultimately an A.I. library for an Arduino.

 

Yay!!! An A.I. library! Wooo-hooo!!! (_dancing moves_) Christmas will come early this year!

Thank you OddBot!

I was about to post a huge rant with all the issues I see with your plan, but I think you're the kind of guy who learns by doing and, after a lot of trials, you will eventually find out what works and what doesn't.

In case you would like to learn more about what other people have tried, look up machine learning. You can even take some online classes that will teach you some of the newest and most successful learning algorithms:

http://www.udacity.com/overview/Course/cs373/CourseRev/apr2012

or

https://www.coursera.org/ml

 

Theories and white papers are fine. It is the practical application that counts.

I am always interested in other peoples ideas because sometimes someone has beaten me to it or their idea sparks a new idea in me. At the end of the day I do not like to just copy or implement someone elses idea. To me that is a waste of my time. Let them implement their ideas.

Ultimately I need to come up with my own solution, that is the best way to learn.

 

Have you seen this?

http://www.beam-wiki.org/wiki/Heiserman%2C_David_L.#Relevant_Books

ALPHA CLASS: The robots response to sensory input is randomly selected.

BETA CLASS: Robot can remember what response to particular set of sensor inputs has worked in the past. It then tries to repeat that behavior anytime the same sensory input occurs. So as experience is gained, the behavior becomes more less random and more deliberate.

GAMMA CLASS: Robot begins to generalize its remembered responses.  In doing so, it can begin to anticipate situations not yet experienced. As a result, when a unique situation arises, the robot will probably have at least some idea of how to respond to this new situation.

 

I will read it when I get time. Right now I would like to acheive GAMMA CLASS but I think I will need to acheive BETA CLASS first as gamma seems to be an extention of beta.

The hard part is working within the limitations of a single 8 bit processor and my own programming ability.

These 3 classes I have mentiond are more than definitions. This is already a very brief program sketch. It follows the principles of trial and error. You can simply calculate the ratio of sucess and failure for every sensory input reaction of the robot and rule out the random function after a certain ratio of sucess/failure is reached. Gamma class only means, that for every possible reaction of the robot (for instance forward/backward/turn left/turn right) a certain ratio of sucess/failure is reached. The robot 'knows' then before a certain situation will occur, which reaction it will perform.

I think I have the original white paper on that Α/Β/Γ class intelligence breakdown in a badly scanned PDF somewhere.  If anyone wants it I'll look for it;  It might have been LordHotWing who sent that to me-in any case, the RB5X Basic programming sure makes note of it.

While you're throwing ideas out, I'd like to add two.  First, can you program a robot to have curiosity?  To wonder?  To desire the answer to a question despite possible danger in learning it?  Highfalutin' philosophical mumbo-jumbo, I know, but that's the standard I hold human friends too.  Curious friends are smart, even if their database is limited.  People with a lot of knowlege who are satisfied with it and desire no more (ie, who will hear nothing that disagrees with what they already think they know) are not intelligent.

Second, can you make a robot a "Genius?"  I know that there are IQ definitions for genius that have to do with age but I'm thinking along different lines.  To me a genius is someone who sees unapparent connections between two ideas without having them pointed out too them.  Can a robot be programmed to evaluate concepts-even simple ones-for correlation and causality?  I think there might be analogs-even wtih a 328-to each of these, but I'm not clever enough to suss them out at the moment.  If anyone else is, please move it forward with care-we don't want these things figuring out how to make death-rays!