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.

Curiosity is simply the ability to recognize a new situation and then explore it to see if any new data can be gained from it. When you put a new toy in front of a cat and it gently paws at it.

The cat is firstly trying to determine if the object poses any danger. If the object gave the cat an electric shock or tried to bite the cat then most cats would soon walk (or run) away and be cautious of it from then on.

If no danger is present then the cat may continue to investigate if the object has a nice smell (perhaps it's food) or an interesting texture. The cat may even take a tentative bite to confirm if it is food or not.

All up the cat is only useing it's sensors to determine the nature of the object and what risk / reward it may represent. A robot can easily be programmed to do the same thing although it's sensors may limit it's ability to test the object.

Wonder is much harder to define. As far as my plans are concerned, the closest the robot will acheive will be when it converts short term to long term memory. At that point it will check the data to see what, if any significance it may hold so that the memory can be categorized correctly.

Genius is a bit like the movie "Limitless" if you have access to enough information and can correlate the information in enough different ways then you are considered a Genius. Having an eidetic memory such as a computer has is an important step. I think this is possible for a computer to acheive although certainly not an 8-bit processor like I am working with.

Imagination (you did not mention this) is also something that a powerful computer should be able to acheive. When we try to solve a problem we use our imagination to take all available data and rearange it until a solution is discovered. When I say "all available" this includes information that may not seem relavent at first. That is what lateral thinking boils down to.

Those classes seem to require just a recursive application of intelligence, so it's mostly a matter of processing power, and unlike natural brains which need to fit within an animal's skull, we can build artifficial minds as large as we want to (well, there are actually many issues with scaling but it's still much easier than making humans with very big heads).

Now, regarding your questions:

Can you program a robot to have curiosity?

I think the answer is definitely yes. I don't think there's anything mystical about curiosity and you can definately build a machine that seeks out new information. Not just more information, but new information, information that changes the robot's model of the world. Given a set of possible actions the robot could estimate the impact of each action on its theories about how the world works and always pick the one that will prove or disprove the most of it's "beliefs". This could be done with existing algorithms such as particle filters.

Can you make a robot a "Genius?" 

I think it might be possible. Computers are already very good at making statistical correlations. For example a data mining program realised that a teenage girls was pregnant before her family suspected anything. http://digitalminimalism.com/2012/target-figured-teen-girl-pregnant-father/ . The issue is putting togather a system that applies these techniques to interesting problems without being told what problems to look at or what "interesting" means. But I think that defining "interesting" might also be a data mining problem. 

The bad news is that all of these will require significant computing power,much much more than what any microcontroller can do, even for a robot with a very simple universe.

awesome!! wait..no neural network?! dang it! jk :P

i had a theory on neural network-less brain before, using only programming, since the digital world can simulate a whole world in a small chip, then you can make billions of memory, or even a billion of neurons(yes, neural network-less, but that could work)....if you can simulate and mold a digital clay in the digital world, then you can simulate a brain with billions of info in a single device.

well, neural nets are basically for analogue, since you don't have to programme a neuron, just connect them randomly(yes, randomly, if those neurons simulate right) and chaos theory will just work :)

btw, yer theory might work, since collecting info and releasing them when in need simulates like neurons....and if it simulates correctly, it can actually work like watson(the a.i computer that won jeopardy), since watson gets info, gather them if needed, and gives info :)

there are two types of a.i , the strong AI and the weak AI, and this AI that you are making is the weak AI, w/c is great! because i love weak AI,  that's what ALAN(aka project phoenix) should be, since strong AI like watson is not really like a living being since they learn from info that their creator gives, and not like weak AI that a robot just learn for itself from it's surrounding....w/c is great :)

Assuming 1 billion to be 1000 million (a fact sometimes disputed) then you would need 46 unsigned bits of binary data to represent that number. The atmega is an 8 bit controller, the largest value its capable of is 255. So no, an arduino cannot simulate a billion nuerons. You would need a much more powerful processor. The new arm processors coming out have 64 bits available, as do the usual Intel and AMD desktop cpu's.
  • 1 billion can be represented using 30 bits
  • 8 bit microcontrollers can represent numbers much much larger than 255 and can even do math with much larger numbers. See: http://arduino.cc/en/Reference/UnsignedLong or better yet: http://www.gammon.com.au/forum/?id=11519
  • The processor architecture or speed doesn't really limit the number of neurons you can simulate, the major limiting factor is memory. A billion neurons could probably be simulated with a few GB of memory. It doesn't have to be RAM, it could also be a hard disk.

On the other hand, although an atmega could theoretically simulate 1 billion neurons, it probably won't be fast enough to be of any use.

Somehow I managed to make a truely epic failure in counting the digits on my phone screen, I used a programmers calculator app to convert 1 billion into binary, sure enough double checked it and it is indeed 30 bits.

Yes a CPU can represent a number larger than its maximum number of bits but just lets say you do 16 bit addition on an 8 bit controller, from what I've read this is exponentially slower than addition on a 8 bit controller, in the case of then simulating 32 bit addition its going to crawl to a halt.


Maybe it could be done on an avr, but I would expect it to sit around waiting for a good few minutes just to make a simple choice.

Perhaps you misunderstand. No one is going to try to simulate 1000,000,000 neurons unless their computer is one of the top 10 super computers of the world and they have no idea what to do with a world class super computer except to make up lymerics. My idea is not to turn an 8 bit Arduino into a super computer but to try and make the most of what it does have.

I am talking seriously about creating a simple A.I. using an Arduino or Picaxe processor.

You could not "simulate a brain with billions of info in a single device". Do you know how much a billion is?

I disagree with the strong/weak AI definitions. At best the names are terrible. Although a neural net design should prove more adaptable like the human brain I think it is also more susceptable to errors which is why we have terms like "human error".
If Neural nets are created at the same level of complexity as the human brain then terms like "artifical error" could come into common use.

This approach seems more likely for us dudes with no understanding of neural nets and stuff :-) 

It remainds me of a language called prolog which is just that: a collection of facts which are described and then queried to get a true or false.

Wow! I am SO glad that someone has started such an experiment! And I am also glad that is someone with a special talent to express his ideas in a clear and understandable way (I could never do it this good...). We all want our robots to be able to do something more than just roam around avoiding objects or following lines. What good is it to build a butler robot if the robot stays in a corner not knowing what to do? I believe the software is what gives our robots life and my robots definitely lack it. OddBot, some time ago, you became my role model in robotics, I have tried to follow your steps and partly succeded. It takes me more time because my daily job is not robotics related and now I have a different weekend job over the Summer. I will certainly follow your experiments and perhaps one day I'll thankfully use your code to bring life to my butler robots.

Thank you from all my heart for all your efforts to advance the robotics hobby!