Shop OBEX P1 Docs P2 Docs Learn Events
Boe-Bot Whisker Roaming Help — Parallax Forums

Boe-Bot Whisker Roaming Help

SabbobotSabbobot Posts: 3
edited 2014-04-16 09:10 in Accessories
So I have a USB Board of Education Boe-Bot with the whisker sensor circuit built, but I have run into trouble programming it to roam on its own. Parallax provides a roaming navigation code in their student guide along with a version with a "corner" failsafe for getting out of a corner (in which the boe bot would turn left then right then left again etc). I modified this program to have a "trap" failsafe (so that the Boe-Bot does not get stuck going back and forth between two parallel walls). Also, I added certain beeps and LED flashes to signal certain things like the start and end of an evasive maneuver or to count how many times the robot has gone back between two parts of the corner or the parallel walls. Corner escaping and both whiskers are individually working just fine, but the Boe-Bot refuses to ever register a double whisker press, whether to do a regular turn around or to do something in the trap counter. Instead it registers one or the other and completes those commands. When running the basic version (no LEDs, beeps, or failsafes) of the code that Parallax provides, it registered one and both whisker presses without a problem. I tried rebuilding the circuit, and retesting, same thing occurred. Help!

 
'-----[Variables]------------------------------------------------------------------------------------
 
pulseCount     [B]VAR[/B]  [B]BYTE[/B]
cornercounter  [B]VAR[/B]  [B]NIB[/B]
trapcounter    [B]VAR[/B]  [B]NIB[/B]
counter        [B]VAR[/B]  [B]NIB[/B]
MEM7           [B]VAR[/B]  [B]BIT[/B]
MEM5           [B]VAR[/B]  [B]BIT[/B]
 
'-----[ Initialization ]-----------------------------------------------------------------------------
 
[B]FREQOUT[/B] 4, 2000, 3000     'Brownout and program start/reset indicator 
cornercounter = 1         'Set to 1 so that the for ... next loop can run
trapcounter = 1           'Set to 1 so that the for ... next loop can run
MEM7 = 1
MEM5 = 0
 
'-----[ Main Routine ]-------------------------------------------------------------------------------
'----------[ Corner Escaping ]-----------------------------------------------------------------------
DO
 
  [B]IF[/B] ([B]IN7[/B] <> [B]IN5[/B]) [B]THEN[/B]                       ' One or other is pressed
    [B]IF[/B] (MEM7 <> [B]IN7[/B]) [B]AND[/B] (MEM5 <> [B]IN5[/B]) [B]THEN[/B]  ' Different from previous
      [B]FOR[/B] counter = 1 [B]TO[/B] cornercounter       ' Run this loop how ever many times the cornercounter is
         [B]FREQOUT[/B] 4, 750, 5000                ' Short high beep to mark the cornercounter
         [B]HIGH[/B] 10                             ' Flash both lights to mark the cornercounter
         [B]HIGH[/B] 1
         [B]PAUSE[/B] 400
         [B]LOW[/B] 10
         [B]LOW[/B] 1
      [B]NEXT[/B]
      cornercounter = cornercounter + 1      ' Alternate whisker count + 1
      MEM7 = [B]IN7[/B]                             ' Record this whisker press
      MEM5 = [B]IN5[/B]                             ' for next comparison
      [B]IF[/B] (cornercounter > 4) [B]THEN[/B]            ' If alternate whisker count = 4
        cornercounter = 1                    ' Reset whisker counter
        [B]FREQOUT[/B] 4, 1250, 3000                ' Beep to signal that an obstacle was detected
        [B]HIGH[/B] 10                              ' Light both LED indicators
        [B]HIGH[/B] 1
        [B]GOSUB[/B] B_U                            ' Execute a U-turn
        [B]GOSUB[/B] T_L
        [B]GOSUB[/B] T_L
      ENDIF                                  ' ENDIF counter > 4
    ELSE                                     ' Not alternate, reset counter
      cornercounter = 1
      MEM7 = [B]IN7[/B]                             ' Record this whisker press
      MEM5 = [B]IN5[/B]                             ' For next comparison anyway
    ENDIF                                    ' ENDIF (MEM7<>IN7) AND (MEM5<>IN5)
  ENDIF                                      ' ENDIF (IN7<>IN5)
 
'----------[ Trap Escaping ]-------------------------------------------------------------------------
 
  [B]IF[/B] ([B]IN5[/B]  = 0) [B]AND[/B] ([B]IN7[/B] = 0) [B]THEN[/B]           ' Both whiskers detect an obstacle                 
    [B]IF[/B] (MEM5 = [B]IN5[/B]) [B]AND[/B] (MEM7 = [B]IN7[/B]) [B]THEN[/B]    ' Both whiskers were pressed last time as well
      [B]FOR[/B] counter = 1 [B]TO[/B] trapcounter         ' Run this loop how ever many times the trapcounter is
         [B]FREQOUT[/B] 4, 750, 5000                ' Short high beep to mark trapcounter
         [B]HIGH[/B] 10                             ' Flash both lights to mark the trapcounter
         [B]HIGH[/B] 1
         [B]PAUSE[/B] 400
         [B]LOW[/B] 10
         [B]LOW[/B] 1
      [B]NEXT[/B]
      trapcounter = trapcounter + 1     ' Double whisker count + 1
      MEM7 = [B]IN7[/B]                        ' Record this whisker press
      MEM5 = [B]IN5[/B]
        [B]IF[/B] (trapcounter > 3) [B]THEN[/B]       ' If double whisker count = 3
          trapcounter = 1               ' Reset whisker counter
          [B]FREQOUT[/B] 4, 1250, 3000         ' Beep to signal that an obstacle was detected
          [B]HIGH[/B] 1                        ' Light the left LED indicator
          [B]GOSUB[/B] B_U                     ' Execute left turn
          [B]GOSUB[/B] T_L
          [B]FREQOUT[/B] 4, 1250, 3000         ' Beep to signal resume of normal forward movement
        ENDIF                           ' ENDIF counter > 3
      ELSE                              ' Not 3 consecutive times
        trapcounter = 1                 ' Reset counter
        MEM7 = [B]IN7[/B]                      ' Record this whisker press
        MEM5 = [B]IN5[/B]                      ' For next comparison anyway
        [B]FREQOUT[/B] 4, 1250, 3000           ' Beep to signal that an obstacle was detected
        [B]HIGH[/B] 10                         ' Light both LED indicators
        [B]HIGH[/B] 1
        [B]GOSUB[/B] B_U                       ' Back up & U-turn (left twice)
        [B]GOSUB[/B] T_L
        [B]GOSUB[/B] T_L
        [B]FREQOUT[/B] 4, 1250, 3000           ' Beep to signal resume of normal forward movement
      ENDIF                             ' ENDIF (MEM5 = IN5) and (MEM7 = IN7)
    ENDIF                               ' ENDIF (IN5 = 0) and (IN7 = 0)
 
'----------[ Regular Roaming ] ----------------------------------------------------------------------
 
[B]IF[/B] ([B]IN5[/B] = 0) [B]THEN[/B]             ' Left whisker contacts
    [B]FREQOUT[/B] 4, 1250, 3000     ' Beep to signal that an obstacle was detected
    [B]HIGH[/B] 1                    ' Right reverse light
    [B]GOSUB[/B] B_U                 ' Back up & turn right
    [B]GOSUB[/B] T_R
    [B]FREQOUT[/B] 4, 1250, 3000     ' Beep to signal resume of normal forward movement
ELSEIF ([B]IN7[/B] = 0) [B]THEN[/B]         ' Right whisker contacts
    [B]FREQOUT[/B] 4, 1250, 3000     ' Beep to signal that an obstacle was detected
    [B]HIGH[/B] 10                   ' Left reverse light
    [B]GOSUB[/B] B_U                 ' Back up & turn left
    [B]GOSUB[/B] T_L
    [B]FREQOUT[/B] 4, 1250, 3000     ' Beep to signal resume of normal forward movement
ELSE                          ' Both whiskers 1, no contacts
    [B]GOSUB[/B] P_F                 ' Apply a forward pulse
    [B]LOW[/B] 10                    ' Both lights turned off
    [B]LOW[/B] 1
ENDIF
 
LOOP                          ' and check again
 
'-----[ Subroutines ] -------------------------------------------------------------------------------
 
[B]P_F:[/B]
    [B]PULSOUT[/B] 13,850
    [B]PULSOUT[/B] 12,655
    [B]PAUSE[/B] 20
  [B]RETURN[/B]
 
[B]T_L:[/B]
  [B]FOR[/B] pulseCount = 0 [B]TO[/B] 19
    [B]PULSOUT[/B] 13, 666
    [B]PULSOUT[/B] 12, 655
    [B]PAUSE[/B] 20
[B]NEXT[/B]
[B]RETURN[/B]
 
[B]T_R:[/B]
  [B]FOR[/B] pulseCount = 0 [B]TO[/B] 19
    [B]PULSOUT[/B] 13, 850
    [B]PULSOUT[/B] 12, 850
    [B]PAUSE[/B] 20
  [B]NEXT[/B]
[B]RETURN[/B]
 
[B]B_U:[/B]
  [B]FOR[/B] pulseCount = 0 [B]TO[/B] 40
    [B]PULSOUT[/B] 13, 666
    [B]PULSOUT[/B] 12, 850
    [B]PAUSE[/B] 20
  [B]NEXT[/B]
[B]RETURN[/B]
 

Comments

  • GenetixGenetix Posts: 1,754
    edited 2014-04-10 18:42
    Part of your problem is that you didn't comment the changes to your code. If took me quite a while to figure out what you did.
    Why did you change the variable old5, old7, and counter to MEM5, MEM7, and cornercounter? There was nothing wrong with the old names and the text clearly explains what the code.
    I saw that added signaling for when the Boe-Bot encounters a corner and when it executes the escape maneuver, but I don't understand why in the ELSE portion you added the recording of the whisker presses. Nothing had changed if the ELSE is executed so resaving the whisker presses does nothing.

    The next section has me really confused. I can understand the escaping from the 2 parallel walls but why are you doing a U-Turn if you are not stuck?
    And I also don't understand why you broke up the long IF...THEN...ELSEIF...ELSE...ENDIF in 2 piecies. You added an ENDIF and then changed an ELSEIF to an IF.
    ' ----- [Title] -------------------------------------------------------------------------------------
    ' Robotics with the Boe-Bot - EscapingCorners.bs2
    ' Boe-Bot navigates out of corners by detecting alternating whisker presses.
    
    ' Chapter 5, Activity #1 (TestWhiskers.bs2)
    ' Whiskers Schematic  (Active-Low or pressed when 0)
    ' P7 - 220 ohm Resistor --- 10K Resistor - Vdd
    '               |_ Right Whisker - Vss
    ' P5 - 220 ohm Resistor --- 10K Resistor - Vdd
    '               |_ Left Whisker - Vss
    ' Chapter 5, Activity #2 (TestWhiskersWithLeds.bs2)
    ' LED Whisker Testing Schematic
    ' P10 - 220 ohm Resistor - (Anode)Red_LED(Cathode) - Vss     [Left Whisker]
    ' P1 - 220 ohm Resistor - (Anode)Red_LED(Cathode) - Vss     [Right Whisker]
    ' Chapter 5, Activity #3 (RoamingWithWhiskers.bs2)
    ' Your Turn
    ' You can also modify your IF...THEN statements to make the LED indicators from the previous activity broadcast what
    '   maneuver the Boe-Bot is in by adding HIGH and LOW commands to control the LED circuits.
    ' Chapter 5, Activity #4 (EscapingCorners.bs2)
    ' Depending on which which Whisker you started with, the Boe-Bot should execute its U-Turn maneuver after either the
    '   fourth of fifth consecutive whisker press.
    ' The routine for detecting alternate corners always compares an alternating pattern,
    '   either (IN5 = 1 and IN7 = 0) or (IN5 = 0 and IN7 =1).
    ' Likewise, old5 and old7 have to be different from each other.
    '
    ' Project 1 - Modify RoamingWithWhiskers.bs2 so that it makes a 4 kHz beep that lasts 100 ms before executing the
    ' evasive maneuver. Make it beep twice if both whisker contacts are detected during the same sample.
    
    ' {$STAMP BS2}                                ' Stamp directive.
    ' {$PBASIC 2.5}                               ' PBASIC directive
    
    DEBUG "Program Running!"
    
    '-----[Variables]------------------------------------------------------------------------------------
     
    pulseCount     VAR  BYTE                      ' FOR...NEXT loop counter.
    cornercounter  VAR  NIB                       ' (Added)
    trapcounter    VAR  NIB                       ' (Added)
    counter        VAR  NIB                       ' Counts alternate contacts. [***** Not used - changed to cornercounter]
    MEM7           VAR  BIT                       ' Stores previous IN7 (Changed from old7 to MEM7)
    MEM5           VAR  BIT                       ' Stores previous IN5 (Changed from old5 to MEM5)
     
    '-----[ Initialization ]-----------------------------------------------------------------------------
     
    FREQOUT 4, 2000, 3000                         ' Brownout and program start/reset indicator 
    ' REMOVED:     counter = 1                                   ' Start alternate corner count.
    cornercounter = 1                             ' Set to 1 so that the for ... next loop can run (Added - Alernate contact)
    trapcounter = 1                               ' Set to 1 so that the for ... next loop can run (Added - Same contact )
    MEM7 = 1                                      ' (Changed from old7 = 0, to MEM7 = 1)
    MEM5 = 0                                      ' (Changed from old5 = 1, to MEM5 = 0)
     
    '-----[ Main Routine ]-------------------------------------------------------------------------------
    DO
    
    '----------[ Corner Escaping ]----------------------------------------------------------------------- (Added)
    ' --- Detect Consecutive Alternate Corners ----------------------------------------------------------
    ' See the "How EscapingCorners.bs2 works" section that follows this program. 
      IF (IN7 <> IN5) THEN                       ' (Check if) one or (the) other (whisker) is pressed.
        IF (MEM7 <> IN7) AND (MEM5 <> IN5) THEN  ' (Check if exact exact opposite), different, (pattern) from previous (time).
                                                 '   [Changed from old7 to MEM7, and old5 to MEM5]
          ' *** Signal the number of consecutive alternate whisker contacts. (Could be a subroutine)
          FOR counter = 1 TO cornercounter       ' Run this loop how ever many times the cornercounter is (Added)
            FREQOUT 4, 750, 5000                 ' Short high beep to mark the cornercounter (Added)
            HIGH 10                              ' Flash both lights to mark the cornercounter (Added)
            HIGH 1                               ' (Added)
            PAUSE 400                            ' (Added)
            LOW 10                               ' (Added)
            LOW 1                                ' (Added)
          NEXT                                   ' (Added)
          cornercounter = cornercounter + 1      ' Add 1 (to the) alternate whisker (contact) count (variable).
                                                 '   [Changed from counter to cornercounter]
          MEM7 = IN7                             ' Record this whisker press (Changed from old7 to MEM7)
          MEM5 = IN5                             ' for next comparison. (Changed from old5 to MEM5)
          IF (cornercounter > 4) THEN            ' (Check) if (the consecutive) alternate whisker (contact) count = 4.
                                                 '   [Changed from counter to cornercounter]
            cornercounter = 1                    ' Reset (the alternate) whisker (contact) counter.
                                                 '   [Changed from counter to cornercounter]
            ' *** Signal evasive maneuver is being executed.
            FREQOUT 4, 1250, 3000                ' Beep to signal that an obstacle was detected (Added)
            HIGH 10                              ' Light both LED indicators (Added)
            HIGH 1                               ' (Added)
            GOSUB B_U                            ' Execute a U-turn. (Changed from Back_Up to B_U)
            GOSUB T_L                            ' (Changed from Turn_Left to T_L)
            GOSUB T_L                            ' (Changed from Turn_Left to T_L)
          ENDIF                                  ' ENDIF (for when alternate whisker contact counter), cornercounter, > 4.
                                                 '   [Changed from counter to cornercounter]
        ELSE                                     ' ELSE (MEM7=IN7) or (MEM5=IN5), [Changed from old7 to MEM7, old5 to MEM5]
          cornercounter = 1                      ' not alernate (whisker pressed), (so) reset (alternate contact) counter.
                                                 '   [Changed from counter to cornercounter]
          ' ***** Same whisker presses as before, so why save the whisker presses again???
          MEM7 = IN7                             ' Record this whisker press (Added)
          MEM5 = IN5                             ' For next comparison anyway (Added)
        ENDIF                                    ' ENDIF (MEM7<>IN7) AND (MEM5<>IN5) [Changed from old7 to MEM7, old5 to MEM5]
      ENDIF                                      ' ENDIF (IN7<>IN5)
     
    '----------[ Trap Escaping ]-------------------------------------------------------------------------
    ' --- Same Navigation routine from RoamingWithWhiskers.bs2 ---------------------- 
      IF (IN5 = 0) AND (IN7 = 0) THEN            ' Both whiskers detect an obstacle                 
        IF (MEM5 = IN5) AND (MEM7 = IN7) THEN    ' Both whiskers were pressed last time as well (Added)
        ' *** Stuck between 2 parallel walls.
          ' *** Signal the number of consecutive both whiskers contact. (Could be a subroutine)
          FOR counter = 1 TO trapcounter         ' Run this loop how ever many times the trapcounter is (Added)
            ' ***** Sound should be different because this is a different situation.
            FREQOUT 4, 750, 5000                 ' Short high beep to mark trapcounter (Added)
            HIGH 10                              ' Flash both lights to mark the trapcounter (Added)
            HIGH 1                               ' (Added)
            PAUSE 400                            ' (Added)
            LOW 10                               ' (Added)
            LOW 1                                ' (Added)
          NEXT                                   ' (Added)
          trapcounter = trapcounter + 1          ' Double whisker count + 1 (Added)
          MEM7 = IN7                             ' Record this whisker press (Added)
          MEM5 = IN5                             ' (Added)
            IF (trapcounter > 3) THEN            ' If double whisker count = 3 (Added)
            ' Stuck between 2 parallel walls so move 90-degrees to escape.
              trapcounter = 1                    ' Reset whisker counter (Added)
            ' ***** Sound should be different because this is a different situation.
              FREQOUT 4, 1250, 3000              ' Beep to signal that an obstacle was detected (Added)
              HIGH 1                             ' Light the left LED indicator (Added)
              GOSUB B_U                          ' Execute left turn (Added)
              GOSUB T_L                          ' (Added)
            ' ***** Sound should be different because this is a different situation.
              FREQOUT 4, 1250, 3000              ' Beep to signal resume of normal forward movement (Added)
            ENDIF                                ' ENDIF counter > 3 (Added)
        ELSE                                     ' Not 3 consecutive times (Added - Inner IF)
        ' Not stuck between 2 parallel walls. (What situation is this then???)
            trapcounter = 1                      ' Reset counter (Added)
           ' Same whisker presses as before, so why save the whisker presses again???
            MEM7 = IN7                           ' Record this whisker press (Added)
            MEM5 = IN5                           ' For next comparison anyway (Added)
            ' ***** Sound should be different because this is a different situation.
            FREQOUT 4, 1250, 3000                ' Beep to signal that an obstacle was detected (Added)
            HIGH 10                              ' Light both LED indicators (Added - Your Turn)
            HIGH 1                               ' (Added - Your Turn)
            ' What is the Boe-Bot escaping from here???
            GOSUB B_U                            ' Back up & U-turn (left twice) [Changed from Back_Up to B_U]
            GOSUB T_L                            ' (Changed from Turn_Left to T_L)
            GOSUB T_L                            ' (Changed from Turn_Left to T_L)
            ' ***** Sound should be different because this is a different situation.
            FREQOUT 4, 1250, 3000                ' Beep to signal resume of normal forward movement (Added)
          ENDIF                                  ' ENDIF (MEM5 = IN5) AND (MEM7 = IN7) [Added - Inner IF]
      ENDIF                                    ' ENDIF (IN5 = 0) and (IN7 = 0) [Added - Outer IF]
     
    '----------[ Regular Roaming ] ---------------------------------------------------------------------- (Added)
     
      ' ***** Why was this code seperated from the previous section???
      IF (IN5 = 0) THEN                          ' Left whisker contacts (Changed from ELSEIF to IF)
        FREQOUT 4, 1250, 3000                    ' Beep to signal that an obstacle was detected (Added)
        HIGH 1                                   ' Right reverse light (Added - Your Turn) [HIGH 10]
        GOSUB B_U                                ' Back up & turn right (Changed from Back_Up to B_U)
        GOSUB T_R                                ' (Changed from Turn_Right to T_R)
        FREQOUT 4, 1250, 3000                    ' Beep to signal resume of normal forward movement (Added)
      ELSEIF (IN7 = 0) THEN                      ' Right whisker contacts
        FREQOUT 4, 1250, 3000                    ' Beep to signal that an obstacle was detected (Added)
        HIGH 10                                  ' Left reverse light (Added - Your Turn) [HIGH 1]
        GOSUB B_U                                ' Back up & turn left (Changed from Back_Up to B_U)
        GOSUB T_L                                ' (Changed from Turn_Left to T_L)
        FREQOUT 4, 1250, 3000                    ' Beep to signal resume of normal forward movement (Added)
      ELSE                                       ' Both whiskers 1, no contacts [Neither whisker is pressed]
        GOSUB P_F                                ' Apply a forward pulse (Changed from Forward_Pulse to P_F)
        LOW 10                                   ' Both lights turned off (Added - Your Turn)
        LOW 1                                    ' (Added - Your Turn)
      ENDIF                                      ' and check again
     
    LOOP
     
    '-----[ Subroutines ] -------------------------------------------------------------------------------
     
    P_F:                                         ' Send a single forward pulse. (Changed from Forward_Pulse to P_F)
      PULSOUT 13,850
      PULSOUT 12,655                             ' (Changed from 650 to 655)
      PAUSE 20
      RETURN
     
    T_L:                                         ' Left turn, about 90-degrees. (Changed from Turn_Left to T_L)
      FOR pulseCount = 0 TO 19                   ' (Changed from 20 to 19)
        PULSOUT 13, 666                          ' (Changed from 650 to 666)
        PULSOUT 12, 655                          ' (Changed from 650 to 655)
        PAUSE 20
      NEXT
      RETURN
     
    T_R:                                         ' Right turn, about 90-degrees. (Changed from Turn_Right to T_R)
      FOR pulseCount = 0 TO 19                   ' (Changed from 20 to 19)
        PULSOUT 13, 850
        PULSOUT 12, 850
        PAUSE 20
      NEXT
      RETURN
     
    B_U:                                         ' Back up. (Changed from Back_Up to B_U)
      FOR pulseCount = 0 TO 40
        PULSOUT 13, 666                          ' (Changed from 650 to 666)
        PULSOUT 12, 850
        PAUSE 20
      NEXT
      RETURN
    
  • SabbobotSabbobot Posts: 3
    edited 2014-04-16 05:44
    Dear Genetix,
    Thank you for the reply.
    The variables old5 and old7 were not changed to MEM5 and MEM7 for any particular reason. I have changed them and some other things back to their original states.
    I changed the counter to cornercounter because I needed two separate counters (one for the corner escaping and one for the trap escaping). If the counters were the same, four presses of any kind would trigger the escaping maneuver.
    As for the secondary saving of the memory in the ELSE portion, I do that to make use of the single memory slot for each whisker. With the memory saving in the first loop, the Boe-Bot only remembers the press providing that the first conditions are met. In this case, the Boe-Bot will never remember a single press if the first is a double, or a double press if the first is a single. Since I initialize old7 and old5 and 0 and 1, if I don't have the memory saved there, trap escaping will never work.
    I tried to answer most of what I could answer in comments placed next to your commented questions in the code posted (I will re-post the changed code below), and changed anything you thought I should change or noted was different.
    One last note you have probably noticed from my code that I am relatively new at this, so most things - with the exception of a few that I can explain - that seemed/seem counter-productive, redundant, or like they make no sense probably are so because I don’t know any better. If you have any other discrepancies with the code please point them out.
     
    ' ----- [Title] -------------------------------------------------------------------------------------
    ' Robotics with the Boe-Bot - EscapingCorners.bs2
    ' Boe-Bot navigates out of corners by detecting alternating whisker presses.
     
    ' Chapter 5, Activity #1 (TestWhiskers.bs2)
    ' Whiskers Schematic  (Active-Low or pressed when 0)
    ' P7 - 220 ohm Resistor --- 10K Resistor - Vdd
    '               |_ Right Whisker - Vss
    ' P5 - 220 ohm Resistor --- 10K Resistor - Vdd
    '               |_ Left Whisker - Vss
    ' Chapter 5, Activity #2 (TestWhiskersWithLeds.bs2)
    ' LED Whisker Testing Schematic
    ' P10 - 220 ohm Resistor - (Anode)Red_LED(Cathode) - Vss     [Left Whisker]
    ' P1 - 220 ohm Resistor - (Anode)Red_LED(Cathode) - Vss     [Right Whisker]
    ' Chapter 5, Activity #3 (RoamingWithWhiskers.bs2)
    ' Your Turn
    ' You can also modify your IF...THEN statements to make the LED indicators from the previous activity broadcast what
    '   maneuver the Boe-Bot is in by adding HIGH and LOW commands to control the LED circuits.
    ' Chapter 5, Activity #4 (EscapingCorners.bs2)
    ' Depending on which which Whisker you started with, the Boe-Bot should execute its U-Turn maneuver after either the
    '   fourth of fifth consecutive whisker press.
    ' The routine for detecting alternate corners always compares an alternating pattern,
    '   either (IN5 = 1 and IN7 = 0) or (IN5 = 0 and IN7 =1).
    ' Likewise, old5 and old7 have to be different from each other.
    '
    ' Project 1 - Modify RoamingWithWhiskers.bs2 so that it makes a 4 kHz beep that lasts 100 ms before executing the
    ' evasive maneuver. Make it beep twice if both whisker contacts are detected during the same sample.
     
    ' {$STAMP BS2}                                ' Stamp directive.
    ' {$PBASIC 2.5}                               ' PBASIC directive
     
    [B]DEBUG[/B] "Program Running!"
     
    '-----[Variables]------------------------------------------------------------------------------------
     
    pulseCount     [B]VAR[/B]  [B]BYTE[/B]                      ' FOR...NEXT loop counter.
    cornercounter  [B]VAR[/B]  [B]NIB[/B]                       ' (Added) Counts alternate single whisker presses
    trapcounter    [B]VAR[/B]  [B]NIB[/B]                       ' (Added) Counts conseutive double whisker presses
    counter        [B]VAR[/B]  [B]NIB[/B]                       ' (Added) Counts the number of times to run the loop in the Corner_Beep_Flash and Trap_Beep_Flash subrountines
    old7           [B]VAR[/B]  [B]BIT[/B]                       ' Stores previous IN7
    old5           [B]VAR[/B]  [B]BIT[/B]                       ' Stores previous IN5
     
    '-----[ Initialization ]-----------------------------------------------------------------------------
     
    [B]FREQOUT[/B] 4, 3000, 1000                         ' Brownout and program start/reset indicator 
    counter = 1
    cornercounter = 1                             ' Set to 1 so that the for ... next loop can run (Added - Alernate contact)
    trapcounter = 1                               ' Set to 1 so that the for ... next loop can run (Added - Same contact )
    old7 = 0
    old5 = 1
     
    '-----[ Main Routine ]-------------------------------------------------------------------------------
    DO
     
    '----------[ Corner Escaping ]----------------------------------------------------------------------- (Added)
    ' --- Detect Consecutive Alternate Corners ----------------------------------------------------------
    ' See the "How EscapingCorners.bs2 works" section that follows this program. 
      [B]IF[/B] ([B]IN7[/B] <> [B]IN5[/B]) [B]THEN[/B]                       ' (Check if) one or (the) other (whisker) is pressed.
        [B]IF[/B] (old7 <> [B]IN7[/B]) [B]AND[/B] (old5 <> [B]IN5[/B]) [B]THEN[/B]  ' (Check if exact exact opposite), different, (pattern) from previous (time).
          [B]GOSUB[/B] Corner_Beep_Flash                ' (Added)
          cornercounter = cornercounter + 1      ' Add 1 (to the) alternate whisker (contact) count (variable).
                                                 '   [Changed from counter to cornercounter]
          old7 = [B]IN7[/B]                             ' Record this whisker press (Changed from old7 to old7)
          old5 = [B]IN5[/B]                             ' for next comparison. (Changed from old5 to old5)
          [B]IF[/B] (cornercounter > 4) [B]THEN[/B]            ' (Check) if (the consecutive) alternate whisker (contact) count = 4.
                                                 '   [Changed from counter to cornercounter]
            cornercounter = 1                    ' Reset (the alternate) whisker (contact) counter.
                                                 '   [Changed from counter to cornercounter]
            ' *** Signal evasive maneuver is being executed.
            [B]FREQOUT[/B] 4, 1250, 2500                ' Beep to signal that an obstacle was detected (Added)
            [B]HIGH[/B] 10                              ' Light both LED indicators (Added)
            [B]HIGH[/B] 1                               ' (Added)
            [B]GOSUB[/B] Back_Up                        
            [B]GOSUB[/B] Turn_Left                      
            [B]GOSUB[/B] Turn_Left
            [B]FREQOUT[/B] 4, 1250, 2500                      
          ENDIF                                  ' ENDIF (for when alternate whisker contact counter), cornercounter, > 4.
                                                 '   [Changed from counter to cornercounter]
        ELSE                                     ' ELSE (old7=IN7) or (old5=IN5), [Changed from old7 to old7, old5 to old5]
          cornercounter = 1                      ' not alernate (whisker pressed), (so) reset (alternate contact) counter.
                                                 '   [Changed from counter to cornercounter]
          old7 = [B]IN7[/B]                             ' Record this whisker press (Added)
          old5 = [B]IN5[/B]                             ' For next comparison anyway (Added)
        ENDIF 
    '----------[ Trap Escaping ]-------------------------------------------------------------------------
    ' --- Same Navigation routine from RoamingWithWhiskers.bs2 ---------------------- 
      [B]IF[/B] ([B]IN5[/B] = 0) [B]AND[/B] ([B]IN7[/B] = 0) [B]THEN[/B]            ' Both whiskers detect an obstacle                 
        [B]IF[/B] (old5 = [B]IN5[/B]) [B]AND[/B] (old7 = [B]IN7[/B]) [B]THEN[/B]    ' Both whiskers were pressed last time as well (Added)
        ' *** Stuck between 2 parallel walls
          [B]GOSUB[/B] Trap_Beep_Flash
          trapcounter = trapcounter + 1          ' Double whisker count + 1 (Added)
          old7 = [B]IN7[/B]                             ' Record this whisker press (Added)
          old5 = [B]IN5[/B]                             ' (Added)
            [B]IF[/B] (trapcounter > 3) [B]THEN[/B]            ' If double whisker count = 3 (Added)
            ' Stuck between 2 parallel walls so move 90-degrees to escape.
              trapcounter = 1                    ' Reset whisker counter (Added)
              [B]FREQOUT[/B] 4, 1250, 3500              ' Beep to signal that an obstacle was detected (Added)
              [B]HIGH[/B] 1                             ' Light the left LED indicator (Added)
              [B]GOSUB[/B] Back_Up                      ' Execute left turn (Added)
              [B]GOSUB[/B] Turn_Left                    ' (Added)
              [B]FREQOUT[/B] 4, 1250, 3500              ' Beep to signal resume of normal forward movement (Added)
            ENDIF                                ' ENDIF counter > 3 (Added)
        ELSE                                     ' Not 3 consecutive times (Added - Inner IF)
        ' Not stuck between 2 parallel walls. (What situation is this then???) A regular manuver to turn around when the Boe-Bot hits a wall as it would have in the regular roaming program
            trapcounter = 1                      ' Reset counter (Added)
           ' Same whisker presses as before, so why save the whisker presses again??? To make it so that one-variable can serve trap and corner escaping purposes (see attatched response)
            old7 = [B]IN7[/B]                           ' Record this whisker press (Added)
            old5 = [B]IN5[/B]                           ' For next comparison anyway (Added)
            [B]FREQOUT[/B] 4, 1250, 3000                ' Beep to signal that an obstacle was detected (Added)
            [B]HIGH[/B] 10                              ' Light both LED indicators (Added - Your Turn)
            [B]HIGH[/B] 1                               ' (Added - Your Turn)
            ' What is the Boe-Bot escaping from here??? A wall; it is turning around because it hit one of the walls just as it would in the regular roaming program
            [B]GOSUB[/B] Back_Up                        ' Back up & U-turn (left twice)
            [B]GOSUB[/B] Turn_Left
            [B]GOSUB[/B] Turn_Left
            [B]FREQOUT[/B] 4, 1250, 3000                ' Beep to signal resume of normal forward movement (Added)
          ENDIF                                  ' ENDIF (old5 = IN5) AND (old7 = IN7) [Added - Inner IF]
      ENDIF                                    ' ENDIF (IN5 = 0) and (IN7 = 0) [Added - Outer IF]
     
    '----------[ Regular Roaming ] ---------------------------------------------------------------------- (Added)
     
      ' ***** Why was this code seperated from the previous section??? I am not actually sure. I left it sperate only because that is how it was in EscapingCorners.bs2. Would it be better if they were together?
      ELSEIF ([B]IN5[/B] = 0) [B]THEN[/B]                       ' Left whisker contacts
        [B]FREQOUT[/B] 4, 1250, 3000                    ' Beep to signal that an obstacle was detected (Added)
        [B]HIGH[/B] 1                                   ' Right reverse light (Added - Your Turn) [HIGH 10]
        [B]GOSUB[/B] Back_Up                            ' Back up & turn right
        [B]GOSUB[/B] Turn_Right                         
        [B]FREQOUT[/B] 4, 1250, 3000                    ' Beep to signal resume of normal forward movement (Added)
      ELSEIF ([B]IN7[/B] = 0) [B]THEN[/B]                      ' Right whisker contacts
        [B]FREQOUT[/B] 4, 1250, 3000                    ' Beep to signal that an obstacle was detected (Added)
        [B]HIGH[/B] 10                                  ' Left reverse light (Added - Your Turn) [HIGH 1]
        [B]GOSUB[/B] Back_Up                            ' Back up & turn left
        [B]GOSUB[/B] Turn_Left                          
        [B]FREQOUT[/B] 4, 1250, 3000                    ' Beep to signal resume of normal forward movement (Added)
      ELSE                                       ' Both whiskers 1, no contacts [Neither whisker is pressed]
        [B]GOSUB[/B] Forward_Pulse                      ' Apply a forward pulse
        [B]LOW[/B] 10                                   ' Both lights turned off (Added - Your Turn)
        [B]LOW[/B] 1                                    ' (Added - Your Turn)
      ENDIF                                      ' and check again
     
    LOOP
     
    '-----[ Subroutines ] -------------------------------------------------------------------------------
     
    [B]Forward_Pulse:[/B]                               ' Send a single forward pulse.
      [B]PULSOUT[/B] 13, 850
      [B]PULSOUT[/B] 12, 655                            ' (Changed from 650 to 655 [to match my Boe-Bot's servo frequency to go straight as discovered in Chapter 4, Activity 2: staightening the Boe-Bot's path)
      [B]PAUSE[/B] 20
      [B]RETURN[/B]
     
    [B]Turn_Left:[/B]                                   ' Left turn, about 90-degrees. (Changed from Turn_Left to Turn_Left)
      [B]FOR[/B] pulseCount = 0 [B]TO[/B] 19                   ' (Changed from 20 to 19)
        [B]PULSOUT[/B] 13, 666                          ' (Changed from 650 to 666 to match my Boe-Bot's servo frequency to go straight)
        [B]PULSOUT[/B] 12, 655                          ' (Changed from 650 to 655 to match my Boe-Bot's servo frequency to go straight)
        [B]PAUSE[/B] 20
      [B]NEXT[/B]
      [B]RETURN[/B]
     
    [B]Turn_Right:[/B]                                  ' Right turn, about 90-degrees
      [B]FOR[/B] pulseCount = 0 [B]TO[/B] 19                   ' (Changed from 20 to 19. This part is not exact, program's functionality before fine-tuning))
        [B]PULSOUT[/B] 13, 850
        [B]PULSOUT[/B] 12, 850
        [B]PAUSE[/B] 20
      [B]NEXT[/B]
      [B]RETURN[/B]
     
    [B]Back_Up:[/B]                                     ' Back up
      [B]FOR[/B] pulseCount = 0 [B]TO[/B] 40
        [B]PULSOUT[/B] 13, 666                          ' (Changed from 650 to 666 to match my Boe-Bot's servo frequency to go straight)
        [B]PULSOUT[/B] 12, 850
        [B]PAUSE[/B] 20
      [B]NEXT[/B]
      [B]RETURN[/B]
     
    [B]Corner_Beep_Flash:[/B]
      [B]FOR[/B] counter = 1 [B]TO[/B] trapcounter             ' Run this loop how ever many times the cornercounter is
            [B]FREQOUT[/B] 4, 750, 4500                 ' Short high beep to mark cornercounter (Added)
            [B]HIGH[/B] 10                              ' Flash both lights to mark the cornercounter (Added)
            [B]HIGH[/B] 1                               ' (Added)
            [B]PAUSE[/B] 400                            ' (Added)
            [B]LOW[/B] 10                               ' (Added)
            [B]LOW[/B] 1                                ' (Added)
          [B]NEXT[/B]                                   ' (Added)
     
    [B]Trap_Beep_Flash:[/B]
      [B]FOR[/B] counter = 1 [B]TO[/B] trapcounter             ' Run this loop how ever many times the trapcounter is (Added)
            [B]FREQOUT[/B] 4, 750, 5500                 ' Short high beep to mark trapcounter (Added)
            [B]HIGH[/B] 10                              ' Flash both lights to mark the trapcounter (Added)
            [B]HIGH[/B] 1                               ' (Added)
            [B]PAUSE[/B] 400                            ' (Added)
            [B]LOW[/B] 10                               ' (Added)
            [B]LOW[/B] 1                                ' (Added)
          [B]NEXT[/B]                                   ' (Added)
     
     
    
  • GenetixGenetix Posts: 1,754
    edited 2014-04-16 09:10
    This video explains and animates how the EscapingCorners.bs2 program works.

    http://boebotteacher.com/Animation-EscapeCorners.aspx
Sign In or Register to comment.