Shop OBEX P1 Docs P2 Docs Learn Events
sonic roaming program im working on.. comments needed.. — Parallax Forums

sonic roaming program im working on.. comments needed..

RontopiaRontopia Posts: 139
edited 2006-12-15 23:42 in BASIC Stamp
so this is for a regular boe bot.. nothing fancy. I have a sonic sensor onboard with with its own servo i got off this website. there are parts of the program that are not being used right now, but they may or may not be in my plans for the future..

the cool things.. this uses about 25% or less of the ram onboard.. so thats cool

the bad.. Im not getting the responses I want with the sub Ping_short_Sweep: sometimes it seems get data that is not there.. in other words.. I get a sweep that should return 0 1 0 and the bot reacts like the data is 1 1 0 . I am using a "if then"··to do the evaluation of the saved varibles, but now im thinking maybe a "select case" would be better? if so why do you think?

also I plan to do some clean up and·optimizing of this code so that there is only one ping_motor sub.. any ideas on this are welcome.

also I would like to add some more math that can evaluate angles of things like walls so adjust to them.. but that I have not raped my mind around yet.

one more thing.. Im having debates in my head as to where the 2nd FOR pulsecount = 0 TO 15 NEXT statement belongs or if it belongs at all in the ping motor sub.. it seems that the ping sensor sends out a ping and you need to make sure it has enough time to get a return signal. but im not sure how long or where to put the time.

comments questions concerns


'===============================================================================
'
'·· {$STAMP BS2}
'·· {$PBASIC 2.5}
'
'===============================================================================
'
'
[noparse][[/noparse]Program Description[noparse][[/noparse]
'this program is writen by Ron Morgan for the purpous of sonic obstical avoidance
'it is a work in progress. what I want is for this program to guide my tank bot
'and make choices based on readings from the sonic sensor. Other sensors will be
'added at a later time.
'
'
'
[noparse][[/noparse] revision history ]
'
'version 1.0,
'
'
[noparse][[/noparse] Initialization· ]
FREQOUT Piezo, 500, 1000
'
[noparse][[/noparse] I/O Definitions ]
Piezo········· PIN········ 4
LfIrOut······· PIN········ 8
LfIrIn········ PIN········ 9
RtIrOut······· PIN········ 1
RtIrIn········ PIN········ 0
LMotor········ PIN········ 13
RMotor········ PIN········ 12
PMotor········ PIN········ 14
Ping·········· PIN········ 15
'
[noparse][[/noparse] Variables ]
counter········· VAR··· Nib
counter2········ VAR··· Nib
pulsecount······ VAR··· Byte
rvalue·········· VAR··· Word
distance········ VAR··· Word
distanceL······· VAR··· Bit
distanceC······· VAR··· Bit
distanceR······· VAR··· Bit
distanceLL······ VAR··· Bit
distanceRR······ VAR··· Bit
'
[noparse][[/noparse] initialize Variables ]
counter· = 0
counter2 = 0
'
[noparse][[/noparse] Main Program ]
Main:
counter = 0
DO
IF counter < 10 THEN
GOSUB·· Ping_Motor_Stright
GOSUB·· Forward
counter = counter + 1
ELSEIF· counter = 10 THEN
GOSUB Ping_Short_Sweep
counter = 0
ENDIF
LOOP
GOSUB Main
'
[noparse][[/noparse] Movement ]
Forward:
FOR pulsecount = 0 TO 25
PULSOUT PMotor, 703
PULSOUT LMotor, 850
PULSOUT RMotor, 700
PAUSE 20
NEXT
RETURN

ForwardShort:
FOR pulsecount = 0 TO 10
'PULSOUT PMotor, 703
PULSOUT LMotor, 850
PULSOUT RMotor, 700
PAUSE 20
NEXT
RETURN

Backup:
FOR pulsecount = 0 TO 25
'PULSOUT PMotor, 703
PULSOUT LMotor, 700
PULSOUT RMotor, 850
PAUSE 20
NEXT
RETURN
BackupShort:
FOR pulsecount = 0 TO 10
'PULSOUT PMotor, 703
PULSOUT LMotor, 700
PULSOUT RMotor, 850
PAUSE 20
NEXT
RETURN

All_Stop:
PULSOUT LMotor, 750
PULSOUT RMotor, 750
FREQOUT Piezo, 500, 1000
END
TurnR:
FOR pulsecount = 0 TO 10
PULSOUT LMotor , 800
PULSOUT RMotor , 800
PAUSE 20
NEXT
RETURN

TurnL:
FOR pulsecount = 0 TO 10
PULSOUT LMotor , 700
PULSOUT RMotor , 700
PAUSE 20
NEXT
RETURN

TurnLL:
FOR pulsecount = 0 TO 17
PULSOUT LMotor , 700
PULSOUT RMotor , 700
PAUSE 20
NEXT
RETURN

TurnRR:
FOR pulsecount = 0 TO 17
PULSOUT LMotor , 800
PULSOUT RMotor , 800
PAUSE 20
NEXT
RETURN

TurnAround:
GOSUB TurnRR
GOSUB TurnRR
GOSUB TurnRR
RETURN

'
[noparse][[/noparse] sweep subs ]

Ping_short_Sweep:
GOSUB Ping_Motor_Left
GOSUB Ping_Motor_Center
GOSUB Ping_Motor_Right
GOSUB Ping_Motor_Center
GOSUB Evaluate
RETURN

Ping_Full_Sweep:
GOSUB Ping_Motor_Left_Left
GOSUB Ping_Motor_Left
GOSUB Ping_Motor_Center
GOSUB Ping_Motor_Right
GOSUB Ping_Motor_Right_Right
GOSUB Ping_Motor_Center
RETURN

'
[noparse][[/noparse]Ping Motor servo]

· Ping_Motor_Left_Left:
FOR pulsecount = 0 TO 10
PULSOUT·· PMotor,··· 1157
PAUSE 20
NEXT
FOR pulsecount = 0 TO 10
LOW Ping
PULSOUT Ping, 5
PULSIN· Ping, 1, distance
NEXT
distance = distance ** 887
IF···· (distance < 12) THEN
··· distanceLL = 1
ELSEIF (distance > 12) THEN
··· distanceLL = 0
ENDIF
RETURN

·Ping_Motor_Left:
FOR pulsecount = 0 TO 15
PULSOUT·· PMotor,··· 930
PAUSE 20
NEXT
LOW Ping
PULSOUT Ping, 5
PULSIN· Ping, 1, distance
FOR pulsecount = 0 TO 15
NEXT
distance = distance ** 877
IF (distance < 12) THEN
··· distanceL = 1
ELSEIF (distance > 12) THEN
··· distanceL = 0
ENDIF
RETURN

·Ping_Motor_Center:
FOR pulsecount = 0 TO 15
PULSOUT·· PMotor,··· 703
PAUSE 20
NEXT
LOW Ping
PULSOUT Ping, 5
PULSIN· Ping, 1, distance
FOR pulsecount = 0 TO 15
NEXT
distance = distance ** 887
IF (distance < 20) THEN
··· distanceC = 1
ELSEIF (distance > 20) THEN
··· distanceC = 0
ENDIF
RETURN

·Ping_Motor_Right:
FOR pulsecount = 0 TO 15
PULSOUT·· PMotor,··· 470
PAUSE 20
NEXT
LOW Ping
PULSOUT Ping, 5
PULSIN· Ping, 1, distance
FOR pulsecount = 0 TO 25
NEXT
distance = distance ** 887
IF (distance < 12) THEN
··· distanceR = 1
ELSEIF (distance > 12) THEN
··· distanceR = 0
ENDIF
RETURN

·Ping_Motor_Right_Right:
FOR pulsecount = 0 TO 10
PULSOUT·· PMotor,··· 249
PAUSE 20
NEXT
FOR pulsecount = 0 TO 10
LOW Ping
PULSOUT Ping, 5
PULSIN· Ping, 1, distance
NEXT
distance = distance ** 887
IF···· (distance < 12) THEN
··· distanceRR = 1
ELSEIF (distance > 12) THEN
··· distanceRR = 0
ENDIF
RETURN

Ping_Motor_Stright:
LOW Ping
PULSOUT Ping, 5
PULSIN· Ping, 1, distance
distance = distance ** 887
IF distance < 20 THEN
GOSUB Ping_Short_Sweep
ENDIF
RETURN

'
[noparse][[/noparse] evaluate ]

Evaluate:

IF···· (distanceL = 0) AND (distanceC = 1) AND (distanceR = 0) THEN
GOSUB Randomnum:
GOSUB Main
ELSEIF (distanceL = 1) AND (distanceC = 0) AND (distanceR = 0) THEN
GOSUB TurnR
GOSUB Main
ELSEIF (distanceL = 1) AND (distanceC = 1) AND (distanceR = 0) THEN
GOSUB TurnRR
GOSUB Main
ELSEIF (distanceL = 0) AND (distanceC = 0) AND (distanceR = 1) THEN
GOSUB TurnL
GOSUB Main
ELSEIF (distanceL = 0) AND (distanceC = 1) AND (distanceR = 1) THEN
GOSUB TurnLL
GOSUB Main
ELSEIF (distanceL = 1) AND (distanceC = 1) AND (distanceR = 1) THEN
GOSUB TurnAround
GOSUB Main
ELSEIF (distanceL = 0) AND (distanceC = 0) AND (distanceR = 0) THEN
GOSUB Main
ENDIF

Randomnum:
distance = rvalue
· RANDOM···· rvalue
· IF rvalue > 32767· THEN
· GOSUB TurnR
· ELSE
· GOSUB TurnL
· ENDIF
RETURN

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Muahdib


IC layout designer
Phoenix Arizona

Post Edited (Muahdib) : 12/13/2006 5:51:05 PM GMT

Comments

  • ZootZoot Posts: 2,227
    edited 2006-12-13 16:56
    I didn't have time to go through the whole program before jetting off to work, but this looks it could be the culprit:

    
    Randomnum:
    distance = rvalue
      RANDOM     rvalue
      IF rvalue > 32767  THEN
      GOSUB TurnR
      ELSE
      GOSUB TurnL
      ENDIF
    RETURN
    
    



    You are trying to see your random number with the distance (good) but you are actuall setting the distance to the last random value (bad).

    This should probably be:

    Randomnum:
    rvalue = distance   ' seed random number with last reported distance
      RANDOM     rvalue
      IF rvalue > 32767  THEN
      GOSUB TurnR
      ELSE
      GOSUB TurnL
      ENDIF
    RETURN
    
    



    I also might suggest putting all your obstacle bit flags into a single Nib, then you can use lookup table to determine which turn/back/forward to do.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST
  • RontopiaRontopia Posts: 139
    edited 2006-12-13 17:04
    duh... im so stupid.. thanks zoot for the distance seed number thing


    I dont understand what a lookup table is.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Muahdib


    IC layout designer
    Phoenix Arizona
  • WarrlokWarrlok Posts: 77
    edited 2006-12-13 17:25
    Muahdib said...
    duh... im so stupid.. thanks zoot for the distance seed number thing


    I dont understand what a lookup table is.

    go back to ur boe book on ir distance detection, following boebot.
    hope this helps!!
  • RontopiaRontopia Posts: 139
    edited 2006-12-13 17:33
    thanks for the reply warriok.

    im not aware of being able to set the distance that·a sonic sensor will sense? is that the proper way to say that? in other words with ir emitors you can trun them on and off at a certain freq. I dont know of a way to do this with a sonic sensor. Im certain im missing something here and that its plain as the nose on my face.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Muahdib


    IC layout designer
    Phoenix Arizona

    Post Edited (Muahdib) : 12/13/2006 5:48:06 PM GMT
  • ZootZoot Posts: 2,227
    edited 2006-12-13 17:54
    Here's some pseudo code to get you started.

    Check the Pbasic manual under LOOKUP for lots of good examples and the Sumo programs by Parallax.

    obstacle   VAR   Nib   '4 bits -- bit0 = L, bit1 = R, bit2 = C, bit 3 = whatever
    Obsleft VAR obstacle.BIT0
    Obsright VAR obstacle.BIT1
    Obscenter VAR obstacle.BIT2
    
    DO
       'lots of your code
       'more code
       'do your sonar/IR subroutines and parse something like this:
       'if IR/Sonar on left, then Obsleft = 1 else Obsleft = 0
       'if IR/Sonar on right, then Obsright = 1 else Obsright = 0
       'etc
    
       'now, you've got a variable with 4 bits -- obstacle. Each bit corresponds to an obstacle in that "zone"
       'the value of obstacle must be a number from 0 - 15 (or $0-$F hex or %0000 to %1111 binary )
       'LOOKUP and ON .... let you set a variable or jump to a gosub based on the value of some other variable, for example
        '                         = $0 -- no obstacles; = $1 -- left only; =$2 -- right only; =$3 both left and right; =$4 -- center only, etc
        ON obstacle GOSUB Forward, TurnLeft, TurnRight, BackUp, TurnAround
        'if there's no "match" the program falls through to here
    
        'you can also do lookups to set the value of variable (rather than GOTO or GOSUB):
       LOOKUP obstacle, [noparse][[/noparse] action1, action2, action3, action4 ], actionToDo
        ' if obstacle = $1, then actionToDo (a variable) will be set with whatever the value of action2 is
        'if there's no match then actionToDo keeps whatever value it had originally    
        'do something else
    
       'for what it's worth, in some of the Parallax written programs they use just the lower two bits of a variable like obstacle
       'but it depends on how many sensors you have, what you want to keep track of, etc.
    
       LOOP
    
    'subroutines....... etc.
    
    
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST
  • RontopiaRontopia Posts: 139
    edited 2006-12-13 18:19
    I see. I will toss this around in my head. its a good idea. Im sure you have all been through this before.

    so in your example how much ram does Obsleft take if any? if im understanding this right.. it doesnt use any ram at all. the var obstacle is the only ram being used. am i close?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Muahdib


    IC layout designer
    Phoenix Arizona
  • ZootZoot Posts: 2,227
    edited 2006-12-13 18:34
    Yes. Obsleft, etc. are aliases to bits in the single "real" variable obstacle... they are conveniences... you could just as easily do your code like:

    Check_left:
       IF distance < 10 THEN
    obstacle.BIT0 = 1 ELSE
    obstacle.BIT0 = 0
    ENDIF
       RETURN
    
    Check_right:
       IF distance < 10 THEN
    obstacle.BIT1 = 1
    ELSE
    obstacle.BIT1 = 0
    ENDIF
       RETURN
    
    'even more condensed...but go lookup info on shift bits and negative numbers in the Pbasic manual to figure this one out...
      Check_left:
       Obsleft = distance - 10 >> 15 'or for the purists: Obsleft = distance - 10 >> 15 & 1
       RETURN
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST
  • RontopiaRontopia Posts: 139
    edited 2006-12-13 19:27
    I was reading about shifting a week or 2 ago. the truth is I did not do well in math;( and that is why I do IC layout ..

    I see some of these concepts will help get the program smaller which is a concern for me. I do have another BS2 that I was planing on intergrateing to this, once I understood what I was doing. I believe I will at some point have one that controls the sensors and one that controls motion and choices. then i would like to add all that to the MS robotics studio and see how all that works together. but I ramble..

    the shifting is not easy if you dont understand binary. I have read up on it but then I go to sleep and forget every bit.. no pun intened.

    what about the Ping_Motor Left, Right and Center subs.. am I doing those right? do I need that 2nd "for next" to give the the sensor enough time to get a return signal?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Muahdib


    IC layout designer
    Phoenix Arizona
  • ZootZoot Posts: 2,227
    edited 2006-12-13 20:01
    Somebody said...
    am I doing those right?

    I didn't have a chance to look those over in detail. The better question is -- do they work for you? If they do, then I would suggest moving on to the parts of the program that either don't do what you want. Once you've got every piece working the way want (translate: your 'bot goes where it should) -- then start revisiting routines to refine them, make them more elegant, more efficient, etc.
    P.S. -- I wouldn't really call the bit work and such math -- it's actually a lot more like music than straight math -- you're looking for patterns, rhythms, locations more than doing real math.

    Here's a snippet that might help you visualize bits and such....

    bitCntr VAR Nib
    someBits VAR Byte
    
    someBits = %00000001
    FOR bitCntr = 0 TO 7
       DEBUG "bitCntr: ", DEC bitCntr, "        someBits:", IBIN8 someBits, " -- ", DEC3 someBits, " -- ", IHEX2 someBits, CLREOL, CR
       someBits = someBits << 1 'shift someBits one bit left
    NEXT
    
    FOR someBits = $00 TO $FF  'count from 0 to 255 and show the values and bit states
       DEBUG "someBits:", IBIN8 someBits, " -- ", DEC3 someBits, " -- ", IHEX2 someBits, CLREOL, CR
     NEXT
    
    Finished:
    GOTO Finished
    
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST

    Post Edited (Zoot) : 12/13/2006 8:11:42 PM GMT
  • RontopiaRontopia Posts: 139
    edited 2006-12-14 19:56
    ok.. its now working the way it should with that one change related to the seed value in the random sub.

    thanks for your help, I take back 3% of what I said about you[noparse];)[/noparse]

    so, I acording to your advice. I need to make a list of issues I dont like and improve them one by one. I have already switched the tank treads out as they were giving me nothing but trouble. I may go back to them but for now with all the testing its just easyer to use the regular wheels the boe bot came with.

    so with that being said. this is a list of things I need to fix/address. im listing this here because I'm looking for advice, comments, concerns as I have never really developed any kind of software before. I have monkeyed around with it, but never with any real purpous in mind.

    1) the bot still gets into trouble with long or short or shallow (depending on how you look at it) angles to walls. I am thinking of using the wiskers that the bot came with to fix this, but I was wondering if there was any other way to do this with this one sensor. I thought that maybe having the ping scanning funtion run continuesly while the bot is moving forward would also be a fix but.. I cant seem to figure out how to have the servos all running at the same time.. or at least it would apear that they are all running at the same time. I would really like to get the most out of this one sensor. so.. is there a better way to get the bot to move forward and have the ping sensor pinging as well as the ping servo scaning? any input?

    2) I believe my lovely wife is getting me one of the Memsic 2125 accelerometer from this website for Christmas.. so shhhhhh dont tell her that I already know[noparse];)[/noparse] how well does this work without tank treads in areas around stairs? it seems to me that the treads give the bot better balance or more time to react to input from an accelerometer whereas wheels would be hard to stop in time when going over an edge.. just courious what your folks experance is?

    3) now that this first program is working order, I am still wanting figure out how to cut down the ping_motor subs. Im thinking there has to be a better way to get this work done. any advice on this? im assuming some different counters would be involved?

    thanks for your time

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Muahdib


    IC layout designer
    Phoenix Arizona
  • Bruce BatesBruce Bates Posts: 3,045
    edited 2006-12-15 05:39
    Muahdid -

    If you try to use an accelerometer to detect an edge-fall, you will be OVER THE SIDE,and WAY TOO LATE to do anything about it.·An accelerometer might help to prevent tipping over, but that's abiut it.

    What you need is a downward looking floor detector that looks ahead a foot or so in front of the robot, Then you should have ample time to stop. This detector (unlike others) needs to find presense (the floor is THERE!). With obstacle detectors, you want to AVOD what it detects. This works in just the opposite manner.

    Regards,

    Bruce Bates

    Post Edited (Bruce Bates) : 12/15/2006 6:00:19 AM GMT
  • RontopiaRontopia Posts: 139
    edited 2006-12-15 15:32
    thanks I was afraid you were going to say that

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Muahdib


    IC layout designer
    Phoenix Arizona
  • AImanAIman Posts: 531
    edited 2006-12-15 15:53
    For edge detection you could use simple IR or if the distance is greater a sonar module. If the data changes to a greater number then there is an edge, if it doesn't all is well.
  • RontopiaRontopia Posts: 139
    edited 2006-12-15 20:54
    thanks AIman. I think i am going to need a bigger platform.. or maybe find a way to mount another sonar sensor to the front of the servo that is on the front of the bot now. hmm thats not a bad idea


    thanks agian..

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Muahdib


    IC layout designer
    Phoenix Arizona
  • ZootZoot Posts: 2,227
    edited 2006-12-15 23:42
    I created a cliff/low-object detector using an IR emitter/detector assembly. I mounted the assembly high up on the front of the 'bot, angled down at ~45-60 degrees. This way it scopes out the area *ahead* of the 'bot.

    Then I set up a simple resistor ladder following suggestions here: http://forums.parallax.com/showthread.php?p=561496

    The ideas is that in "long-range" mode, the IR had better be reflected back (obstacle always there) -- that means there is still a floor in front you. At the short range (where the IR beam doesn't reach the floor) there had better NOT be an obstacle there (an object 2" or so in height triggers the IR detector in short-range).

    I would probably have had better results with a Sharp-type IR ranger, but this was cheap, quick and fairly effective.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST

    Post Edited (Zoot) : 12/16/2006 1:30:32 AM GMT
Sign In or Register to comment.