Shop OBEX P1 Docs P2 Docs Learn Events
Robotics with the Boe-Bot page 246 — Parallax Forums

Robotics with the Boe-Bot page 246

markmbmmarkmbm Posts: 8
edited 2011-06-06 19:33 in Robotics
I believe the logic is incorrect on page 246 (Robotics with the Boe-Bot). The last ELSE is never executed. Shouldn’t the code be something more like this?

DO ' Main Routine.

FREQOUT 8, 1, 38500 ' Check IR detectors.
irDetectLeft = IN9
FREQOUT 2, 1, 38500
irDetectRight = IN0

' Decide navigation.
IF (irDetectLeft = 0) AND (irDetectRight = 0) THEN
pulseCount = 1 ' Both detected,
pulseLeft = 850 ' one pulse forward.
pulseRight = 650
ELSEIF (irDetectLeft = 1) AND (irDetectRight = 1) THEN ' Neither detected,
pulseCount = 15 ' back up and try again.
pulseLeft = 650
pulseRight = 850
ELSEIF (irDetectRight = 1) THEN ' Right not detected,
pulseCount = 10 ' 10 pulses left.
pulseLeft = 650
pulseRight = 650
ELSE ' Left not detected,
pulseCount = 10 ' 10 pulses right.
pulseLeft = 850
pulseRight = 850
ENDIF

FOR loopCount = 1 TO pulseCount ' Send pulseCount pulses
PULSOUT 13,pulseLeft
PULSOUT 12,pulseRight
PAUSE 20
NEXT

LOOP


Original code attached.

Comments

  • markmbmmarkmbm Posts: 8
    edited 2011-05-31 14:59
    Please tell me how the program logic ever enters the last ELSE section of the code. If irDetectLeft and irDetectRight don't both equal zero then the program flow will always go to irDetectRight=1 or irDetectLeft=1 and will never go into the last ELSE section of the code.

    ' Decide navigation.
    IF (irDetectLeft = 0) AND (irDetectRight = 0) THEN
    pulseCount = 1 ' Both detected,
    pulseLeft = 850 ' one pulse forward.
    pulseRight = 650
    DEBUG HOME, "Both detected."
    HIGH 10 'Turn left LED on
    HIGH 1 'Turn right LED on
    ELSEIF (irDetectRight = 1) THEN ' Right not detected,
    pulseCount = 10 ' 10 pulses left.
    pulseLeft = 650
    pulseRight = 650
    DEBUG HOME, "Right not detected."
    HIGH 10 'Turn left LED on
    LOW 1 'Turn right LED off
    ELSEIF (irDetectLeft = 1) THEN ' Left not detected,
    pulseCount = 10 ' 10 pulses right.
    pulseLeft = 850
    pulseRight = 850
    DEBUG HOME, "Left not detected."
    HIGH 1 'Turn right LED on
    LOW 10 'Turn left LED off
    ELSE ' Neither detected,
    pulseCount = 15 ' back up and try again.
    pulseLeft = 650
    pulseRight = 850
    DEBUG HOME, "Neither detected."
    LOW 10 'Turn left LED off
    LOW 1 'Turn right LED off
    ENDIF
  • Jessica UelmenJessica Uelmen Posts: 490
    edited 2011-06-01 11:19
    Hi markmbm,

    I would be inclined to say that your modified program is correct. However, as Andy Lindsay wrote the program, he may have some insight that I do not. He's out of the office this week, but I'll be sure to get you an answer when he returns!

    Thanks for hanging in there!

    Cheers,
    Jessica
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-06-02 00:27
    I'll bet a Basic Stamp 2 you are correct.

    It helps if you put your code between code blocks.

    Use

    [ CODE] your code here [ /CODE]

    But without the spaces inside the square brackets.

    Just so others can see your code easier, I've wrapped it in code tags.

    [SIZE=2]DO                                                                 ' Main Routine.[/SIZE]
     
    [SIZE=2][FONT=Arial][FONT=Arial]FREQOUT 8, 1, 38500                                                  ' Check IR detectors.[/FONT][/FONT][/SIZE]
    [FONT=Arial][SIZE=2][FONT=Arial]irDetectLeft = IN9[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]FREQOUT 2, 1, 38500[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]irDetectRight = IN0[/FONT][/SIZE][/FONT]
     
    [FONT=Arial][SIZE=2][FONT=Arial]                                                                               ' Decide navigation.[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]IF (irDetectLeft = 0) AND (irDetectRight = 0) THEN[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseCount = 1                                                             ' Both detected,[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseLeft = 850                                                             ' one pulse forward.[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseRight = 650[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]ELSEIF (irDetectLeft = 1) AND (irDetectRight = 1) THEN  ' Neither detected,[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseCount = 15                                                          ' back up and try again.[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseLeft = 650[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseRight = 850[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]ELSEIF (irDetectRight = 1) THEN                                  ' Right not detected,[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseCount = 10                                                          ' 10 pulses left.[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseLeft = 650[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseRight = 650[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]ELSE ' Left not detected,[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseCount = 10                                                         ' 10 pulses right.[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseLeft = 850[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseRight = 850[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]ENDIF[/FONT][/SIZE][/FONT]
     
    [FONT=Arial][SIZE=2][FONT=Arial]FOR loopCount = 1 TO pulseCount                               ' Send pulseCount pulses[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  PULSOUT 13,pulseLeft[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  PULSOUT 12,pulseRight[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  PAUSE 20[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]NEXT[/FONT][/SIZE][/FONT]
     
    [SIZE=2]LOOP[/SIZE]
     
     
    

    I think the original code is below.

    [SIZE=2]DO                                                                 ' Main Routine.[/SIZE]
     
    [SIZE=2][FONT=Arial][FONT=Arial]FREQOUT 8, 1, 38500                                                  ' Check IR detectors.[/FONT][/FONT][/SIZE]
    [FONT=Arial][SIZE=2][FONT=Arial]irDetectLeft = IN9[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]FREQOUT 2, 1, 38500[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]irDetectRight = IN0[/FONT][/SIZE][/FONT]
     
    [FONT=Arial][SIZE=2][FONT=Arial]                                                                               ' Decide navigation.[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]IF (irDetectLeft = 0) AND (irDetectRight = 0) THEN[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseCount = 1                                                             ' Both detected,[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseLeft = 850                                                             ' one pulse forward.[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseRight = 650[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]ELSEIF (irDetectRight = 1) THEN                                  ' Right not detected,[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseCount = 10                                                          ' 10 pulses left.[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseLeft = 650[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseRight = 650[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]ELSEIF '(irDetectLeft = 1) THEN                                    ' Left not detected,[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseCount = 10                                                         ' 10 pulses right.[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseLeft = 850[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseRight = 850[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial][FONT=Arial][SIZE=2][FONT=Arial]ELSE                                                                           ' Neither detected,[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseCount = 15                                                          ' back up and try again.[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseLeft = 650[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  pulseRight = 850[/FONT][/SIZE][/FONT]
    ENDIF[/FONT][/SIZE][/FONT]
     
    [FONT=Arial][SIZE=2][FONT=Arial]FOR loopCount = 1 TO pulseCount                               ' Send pulseCount pulses[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  PULSOUT 13,pulseLeft[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  PULSOUT 12,pulseRight[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]  PAUSE 20[/FONT][/SIZE][/FONT]
    [FONT=Arial][SIZE=2][FONT=Arial]NEXT[/FONT][/SIZE][/FONT]
     
    [SIZE=2]LOOP[/SIZE]
     
     
    

    I didn't get the comments spaced correctly. Oh well.

    Yes, you are correct, the last ELSE would never be executed in the original code. Good catch.

    Duane
  • markmbmmarkmbm Posts: 8
    edited 2011-06-06 10:08
    Thanks for the reply Jessica.
  • markmbmmarkmbm Posts: 8
    edited 2011-06-06 10:10
    Thanks for the tip and reply Duane.
  • edited 2011-06-06 16:35
    Hi Mark,

    You are correct. The AvoidTableEdge.bs2 program in the book cannot possibly make it to the ELSE block because the (irDetectRight = 1) condition will be true for two cases: (1) Right not detected and (2) Neither detected. Since IF...ELSEIF...ELSE blocks execute code for the first true condition and then jump to ENDIF, the "Neither detected" condition gets handled by the code for "Right not detected". Your adjusted AvoidTableEdgeCorrected.bs2 code also looks good. We'll use it in the errata and future revisions if that's okay with you.

    I heartily second Duane's "Good catch" comment. The error has been there since the 2.0 revision in 2004. It probably went unreported for so long because the Boe-Bot still successfully avoids the table edge, and the fact that it never seemed to back up and try again is easily (though incorrectly) chalked up to the fact that it's sampling at 40 to 50 times per second. At that rate, detecting the drop-off with both sensors during the same sample is kind of a rare occurrence. It'll typically be one or the other.

    Although it might take multiple tries to get both detectors to see the drop-off during the same sample by sending the Boe-Bot straight at the table edge, you can verify that the ELSE condition gets executed by just lifting the Boe-Bot up well above the table. With your updated code, that'll make both detectors see the drop-off and the Boe-Bot will try to back up repeatedly. With the code in the book, it'll just keep turning left.

    Thanks for posting this bug report and updated code. Nice work.

    Regards, Andy
  • markmbmmarkmbm Posts: 8
    edited 2011-06-06 19:33
    Hi Andy,

    I'm glad I could help. I basically just rearranged the lines of code. Of course you can use it.

    The Boe-Bot and your book are awesome.

    Thanks,
    Mark
Sign In or Register to comment.