Shop OBEX P1 Docs P2 Docs Learn Events
Self-Programming A.I. basic stamp robot — Parallax Forums

Self-Programming A.I. basic stamp robot

Jim the HermitJim the Hermit Posts: 79
edited 2012-06-18 19:02 in BASIC Stamp
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:

Comments

  • stevebzzzzzstevebzzzzz Posts: 38
    edited 2011-07-18 18:51
    I like it. Why not build a maze for it?
  • Jim the HermitJim the Hermit Posts: 79
    edited 2012-06-11 08:57
    I posted this video last year. It and my account is gone, so I'm posting it again.

    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
  • xanaduxanadu Posts: 3,347
    edited 2012-06-11 13:53
    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.

    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.
  • Jim the HermitJim the Hermit Posts: 79
    edited 2012-06-12 06:13
    xanadu wrote: »
    It IS interesting. What motors and controller are you using?

    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
  • xanaduxanadu Posts: 3,347
    edited 2012-06-12 11:59
    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 :)
  • Martin_HMartin_H Posts: 4,051
    edited 2012-06-13 07:20
    That's pretty neat. It should be possible to port that to a Scribbler I without much effort. Instead of bump switches you could use the stall sensor to detect a physical collision. It's got the IR built right in too.
  • Jim the HermitJim the Hermit Posts: 79
    edited 2012-06-13 12:04
    xanadu wrote: »
    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.
  • TheDoctorTheDoctor Posts: 11
    edited 2012-06-17 04:46
    Thanks for sharing your code.
    I'll try it some day.
  • Jim the HermitJim the Hermit Posts: 79
    edited 2012-06-18 18:53
    ' {$STAMP BS2sx}
    ' {$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
  • Jim the HermitJim the Hermit Posts: 79
    edited 2012-06-18 19:02
    Side Note:
    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.
    :smile:
Sign In or Register to comment.