Self-Programming A.I. basic stamp robot
Jim the Hermit
Posts: 79
Check out my robot
http://www.youtube.com/watch?v=Sq8MBw38AQY
It learns how to avoid hitting the walls. You can actually see it learn!
A link to the code is in the description. I written it so that's it should be easy to use for your robots.
:cool:
http://www.youtube.com/watch?v=Sq8MBw38AQY
It learns how to avoid hitting the walls. You can actually see it learn!
A link to the code is in the description. I written it so that's it should be easy to use for your robots.
:cool:
Comments
http://www.youtube.com/watch?v=kkfpZskVMx4&feature=youtu.be
I'm kind of surprised there wasn't much interest in it. I don't mean to brag, but it is a Basic Stamp powered robot that demonstrates Machine Learning.
Here's the code in case you want to try it out on your bot. I tried to make it easy to modify for other robots.
If there's any interest, I'll post a modified version that contains a Boredom counter and 3 more motor outputs (stop, spin left, and spin right)
' {$STAMP BS2sx}
' {$PBASIC 2.5}
' Self-Programming Robot by James Thies
' *********************
' *** Experiment #1 ***
' *********************
,
' To begin, you'll need a mobile robot with the minimum requirements:
' -- Bumper switches (front and back), or some other kind of collision detection
' -- Some kind of noncontact proximity senses (like Infra-red, sonar, etc.) for the front only.
' It should also have at least 2 LEDs so you can see what's it doing (or some other way of communicating to you)
' When starting out, this robot can detect obstacles, but doesn't know what do
' with that information. It has six choices to move (Forward, Backward,
' Right Forward, Left Forward, Right Backward, Left Backward) but it doesn't know
' which to use. It has the ability to detect a collision and it knows it really
' doesn't like that.
' The robot will eventually learn to avoid collisions. And being that it only has
' proximity sensors in the front, backward directions will result in collisions most of the
' time. So, it should develop a preference for forward directions.
'Initialize Symbols
Icode VAR Nib 'Input Code (0-3)
Mcode VAR Nib 'Motor Code (1-6)
PainMem VAR Bit(24) 'Fear Memory. Learned data
CurStat VAR Byte 'The Current State of the Input Combined with the Output (4 x 6 = 24)
btnWrk VAR Byte 'Pain button workspace
Pain VAR Bit '1 bit for all bumper switches. Mine are installed according the Stamp Manual
FEARLED PIN 6 'Yellow LED
PAINLED PIN 8 'Red LED
seed VAR Word 'for random number
DIRS = 111111111110 ' 0 and 13 are Inputs
' If your robot doesn't have dual differential DC gearmotor drive it's okay.
' You have Pins 1, 2, 3 and 4 available for your drive motors and you'll
' need to modify the DoMotorCode to suit your robot.
RM1 PIN 1
RM2 PIN 2
LM1 PIN 3
LM2 PIN 4
Rside PIN 9
Lside PIN 10
'Pin 0 = Pain input
'Pin 1 = Right Motor - Pin 1 Low, Pin 2 High = Right motor Forward
'Pin 2 = Right Motor +
'Pin 3 = Left Motor - Pin 3 Low, Pin 4 High = Left motor Forward
'Pin 4 = Left Motor +
'Pin 6 = Fear Led
'Pin 8 = Pain Led
'Pin 9 = Right side Indicator Led
'Pin 10 = Left side Indicator Led (for IRPD)
'Pin 13 = Input from IRPD
'Pin 14 = IR Led for Right side
'Pin 15 = IR Led for Left side
PAUSE 1000 'wait for Lynxmotion IRPD to settle.
START:
GetRndMotorCode:
Mcode = (seed//6) + 1 'Random Number from 1-6
GetInputCode:
RANDOM seed 'keep the next Mcode random
Icode = 0 'clear Input Code. 0 = no Obstacles
' ******************************************************
' *** Beginning Code for the Lynxmotion IRPD Ver 3.0 ***
' ******************************************************
' If you are not using this sensor, you'll need to modify this part of the code.
' All you'll need to do is adjust the Icode variable in your sensor code.
' The Icode must = 0, 1, 2 or 3.
HIGH 14 : PAUSE 1
LOW 14 : PAUSE 1
HIGH 14 : PAUSE 1
IF IN13 = 0 THEN Icode = 1: HIGH Lside 'Add one to Icode for Obstacle on Left
LOW 14
HIGH 15 : PAUSE 1
LOW 15 : PAUSE 1
HIGH 15 : PAUSE 1
IF IN13 = 0 THEN Icode = Icode + 2: HIGH Rside 'Add two to Icode for Obstacle on Right
LOW 15
' ******************************************************
' *** End of Code for the Lynxmotioin IRPD ***
' ******************************************************
'DEBUG "Icode = ",DEC icode,CR 'Icode will = three when left And right are blocked
' Determining which side is the right and left is not critical. Being that the robot/program
' will learn what to do with this information, it will behave the exact same way at startup
' if right and left were switched around or if 3 means clear and 0 means both sides are blocked.
Combine: 'Combine Input Code with Motor code to find the Current State
CurStat = 0
ON Icode GOTO Zero, One, Two, Three
Zero: 'Current State is between 1 - 6, same as Mcode, for no obstacles
CurStat = Mcode + 0
GOTO CheckFear
One: 'Current State is between 7 - 12, for obstacles on one side
CurStat = Mcode + 7
GOTO CheckFear
Two: 'Current State = is between 13 - 18, for obstacles on the other side
CurStat = Mcode + 13
GOTO CheckFear
Three: 'Current State is between 19 - 24, for obstacles on both sides
CurStat = Mcode + 19
GOTO CheckFear
CheckFear: ' Check if learned to be Afraid of this Current State
IF PainMem(CurStat) = 1 THEN GOTO Afraid ' 0 = never encountered State before or if not Afraid of it
CheckPain: 'Check for Pain
PAUSE 5
BUTTON Pain, 1, 255, 20, btnWrk, 1, Ouch 'debounce, no auto-repeat
DoMotorCode: 'No Fear, No Pain, do the Mcode
LOW FEARLED 'Shut off all Leds if on
LOW PAINLED
LOW Lside
LOW Rside
ON Mcode GOTO Forward, Backward, ForwLeft, ForwRight, BackLeft, BackRight
' If your robot doesn't have dual differential DC gearmotor drive, you'll
' need to modify these 6 Goto commands.
Forward:
LOW RM1
HIGH RM2
LOW LM1
HIGH LM2
GOTO GetInputCode
Backward:
HIGH RM1
LOW RM2
HIGH LM1
LOW LM2
GOTO GetInputCode
ForwLeft:
LOW RM1
HIGH RM2
LOW LM1
LOW LM2
GOTO GetInputCode
ForwRight:
LOW RM1
LOW RM2
LOW LM1
HIGH LM2
GOTO GetInputCode
BackLeft:
HIGH RM1
LOW RM2
LOW LM1
LOW LM2
GOTO GetInputCode
BackRight:
LOW RM1
LOW RM2
HIGH LM1
LOW LM2
GOTO GetInputCode
GOTO START 'go back to Start, if the program gets lost
Ouch:
PainMem(CurStat) = 1 'This particular Current State lead to a collision, remember it!
HIGH PAINLED
GOTO GetRndMotorCode
Afraid:
HIGH FEARLED ' Show us that you learned this,
GOTO GetRndMotorCode ' and do something else
It IS interesting. What motors and controller are you using?
I don't know if your project carries a lot of weight in the 'self-programming' or 'AI' department. By definition yes, by its actions, not really. It's hard to generate interest with an AI project, ask IBM.
The motors and base is from a toy robot- so, they're just dc gear motors. The controller is an H-bridge circuit from Gordon Mccomb's Robot Builders Bonanza
Nice, more custom built than I'm used to at least. I'm trying out your code to see what it is like on my Boe Bot lol
Good! I want people to try it out and improve upon it. BTW:
"DIRS = 111111111110 ' 0 and 13 are Inputs"
Should be:
"DIRS = %1101111111111110"
I don't know why this forum keeps changing it.
I'll try it some day.
' {$PBASIC 2.5}
' Self-Programming Robot by James Thies
' *********************
' *** Experiment #2 ***
' *********************
' To begin, you'll need a mobile robot with the minimum requirements:
' -- Bumper switches covering the front and back, or some other collision detection
' -- and some kind of proximity senses, like Infra-red in the front only.
' It should also have at least 3 LEDs so you can see what's it doing.
' When starting out, this robot can detect obstacles, but doesn't know what do
' with that information. It has 9 choices for its motors (Forward, Backward,
' Right Forward, Left Forward, Right Backward, Leftbackward, Clockwise spin,
' Counter-clockwise spin and Stop) but it doesn't know
' which to use. It has the ability to detect a collision and it knows it really
' doesn't like that.
' The robot will eventually learn to avoid collisions. And being that it only has
' proximity sensors in the front, backward directions will result in collisions most of the
' time. So, it should develop a preference for forward directions.
'Initialize Symbols
Icode VAR Nib 'Input Code (0-3)
Mcode VAR Nib 'Motor Code (1-9)
Boredom VAR Byte(9) 'Bored of doing the same Mcode
Tedious VAR Byte
Tedious = 5 'Maxium level of Boredomness
i VAR Byte 'For FOR NEXT loops
PainMem VAR Bit(36) 'Fear Memory. Learned data
CurStat VAR Byte 'The Current State of the Input Combined with the Output (4 x 9 = 36)
btnWrk VAR Byte 'Pain button workspace
Pain VAR Bit 'for all bumper switches. Mine are installed according the Stamp Manual
FEARLED PIN 6 'Yellow LED
BOREDLED PIN 7 'Green LED
PAINLED PIN 8 'Red LED
seed VAR Word 'for random number
DIRS = 01111111111110 ' 0 and 13 are Inputs
' If your robot doesn't have dual differential DC gearmotor drive it's okay.
' You have Pins 1, 2, 3 and 4 available for your drive motors and you'll
' need to modify the DoMotorCode to suit your robot.
RM1 PIN 1
RM2 PIN 2
LM1 PIN 3
LM2 PIN 4
Rside PIN 9
Lside PIN 10
'Pin 0 = Pain input
'Pin 1 = Right Motor - Pin 1 Low, Pin 2 High = Right motor Forward
'Pin 2 = Right Motor +
'Pin 3 = Left Motor - Pin 3 Low, Pin 4 High = Left motor Forward
'Pin 4 = Left Motor +
'Pin 6 = Fear Led
'Pin 7 = Bored Led
'Pin 8 = Pain Led
'Pin 9 = Right side Indicator Led
'Pin 10 = Left side Indicator Led (for IRPD)
'Pin 13 = IRPD INPUT
'Pin 14 = IR Led for Right side
'Pin 15 = IR Led for Left side
PAUSE 1000 'wait for Lynxmotion IRPD to settle.
START:
GetRndMotorCode:
Mcode = (seed//9) + 1 'Random Number from 1-9
GetInputCode:
RANDOM seed 'keep the next Mcode random
Icode = 0 'clear Input Code. 0 = no Obstacles
' ******************************************************
' *** Beginning Code for the Lynxmotion IRPD Ver 3.0 ***
' ******************************************************
' If you are not using this sensor, you'll need to modify this part of the code.
' All you'll need to do is adjust the Icode variable in your sensor code.
' The Icode must = 0, 1, 2 or 3.
HIGH 14 : PAUSE 1
LOW 14 : PAUSE 1
HIGH 14 : PAUSE 1
IF IN13 = 0 THEN Icode = 1: HIGH Lside 'Add one to Icode for Obstacle on Left
LOW 14
HIGH 15 : PAUSE 1
LOW 15 : PAUSE 1
HIGH 15 : PAUSE 1
IF IN13 = 0 THEN Icode = Icode + 2: HIGH Rside 'Add two TO Icode FOR Obstacle on Right
LOW 15
' ******************************************************
' *** End of Code for the Lynxmotioin IRPD ***
' ******************************************************
'DEBUG "Icode = ",DEC icode,CR 'Icode will = three when left And right are blocked
' Determining which side is the right and left is not critical. Being that the robot/program
' will learn what to do with this information, it will behave the exact same way at startup
' if right and left were switched around or if 3 means clear and 0 means both sides are blocked.
' Also, the program will adapt to the physical parameters of your robot. If your robot is big enough
' to collide with an Obstacle-on-the-right by Going Forward, it will fear that senario and change
' direction.
' If the robot is small enough so that an Obstacle-on-the-right and Going Forward will not cause
' a collision, then it will not fear it.
Combine: 'Combine Input Code with Motor code to find the Current State
CurStat = 0
ON Icode GOTO Zero, One, Two, Three
Zero: 'Current State is between 1 - 9, same as Mcode, for no obstacles
CurStat = Mcode
GOTO CheckFear
One: 'Current State is between 10 - 18, for obstacles on one side
CurStat = Mcode + 10
GOTO CheckFear
Two: 'Current State is between 19 - 27, for obstacles on the other side
CurStat = Mcode + 19
GOTO CheckFear
Three: 'Current State is between 28 - 36, for obstacles on both sides
CurStat = Mcode + 28
GOTO CheckFear
CheckFear: ' Check if learned to be Afraid of this Current State
IF PainMem(CurStat) = 1 THEN GOTO Afraid ' 0 -if never encountered State before or if not Afraid of it
CheckPain: 'Check for Pain
'PAUSE 5
BUTTON Pain, 1, 255, 20, btnWrk, 1, Ouch 'debounce, no auto-repeat
CheckBored:
Boredom(mcode) = Boredom(mcode) + 2 'see the comment in the For Next Loop
IF Boredom(mcode) > Tedious THEN GOTO BoredNow
DoMotorCode: 'No Fear, No Pain, Not Bored - do the Mcode
FOR I = 1 TO 9 'Reduce Boredom for Mcodes not in use
Boredom(i) = Boredom(i) - 1 IF Boredom(i) < 0 THEN Boredom(i) = 0
'Boredom for Current Mcode will still be incremented by 1
'By incrementing the Current Mcode by 2, this Loop won't have to check for
'it and thus make it go faster, theoretically.
NEXT
LOW FEARLED 'Shut off all Leds if on
LOW BOREDLED
LOW PAINLED
LOW Lside
LOW Rside
ON Mcode GOTO Forward, Backward, ForwLeft, ForwRight, BackLeft, BackRight, ClockTurn, CounterClockTurn, Halt
' If your robot doesn't have dual differential DC gearmotor drive, you'll
' need to modify these 9 Goto commands.
Forward:
LOW RM1
HIGH RM2
LOW LM1
HIGH LM2
GOTO GetInputCode
Backward:
HIGH RM1
LOW RM2
HIGH LM1
LOW LM2
GOTO GetInputCode
ForwLeft:
LOW RM1
HIGH RM2
LOW LM1
LOW LM2
GOTO GetInputCode
ForwRight:
LOW RM1
LOW RM2
LOW LM1
HIGH LM2
GOTO GetInputCode
BackLeft:
HIGH RM1
LOW RM2
LOW LM1
LOW LM2
GOTO GetInputCode
BackRight:
LOW RM1
LOW RM2
HIGH LM1
LOW LM2
GOTO GetInputCode
ClockTurn:
HIGH RM1
LOW RM2
LOW LM1
HIGH LM2
GOTO GetInputCode
CounterClockTurn:
LOW RM1
HIGH RM2
HIGH LM1
LOW LM2
GOTO GetInputCode
Halt:
LOW RM1
LOW RM2
LOW LM1
LOW LM2
GOTO GetInputCode
GOTO START 'go back to Start, if the program gets lost
Ouch:
PainMem(CurStat) = 1 'This particular Current State lead to a collision, remember it!
HIGH PAINLED
GOTO GetRndMotorCode
Afraid:
HIGH FEARLED ' Show us that you learned this,
GOTO GetRndMotorCode ' and do something else
BoredNow: ' Done this Mcode too many times recently, try something else.
HIGH BOREDLED
GOTO GetRndMotorCode
I have a theory that robots can be made smarter by making them more "aware." The only way to do that is through (artifical) emotions. With the addition of boredom, my robot became more independant. It didn't need me to rescue it when it got stuck against the wall. It simply got bored and moved away by itself. And with the addition of spinning, it didn't stay very long in the corner of the hallway, like in the video. It found the way out a lot sooner and travelled a lot more.
Please try these programs on your bot and let me know what happens.