Shop OBEX P1 Docs P2 Docs Learn Events
Trouble understanding BRANCH/irBits in Sumobot program — Parallax Forums

Trouble understanding BRANCH/irBits in Sumobot program

CatharsisCatharsis Posts: 27
edited 2006-04-30 15:53 in Robotics
Can somebody explain to me in IF...THEN terms what this part means:

BRANCH irBits, [noparse][[/noparse]Scan, Follow_Right, Follow_Left, Lunge]



Taken from the SumoBot code available on the site? Thanks

' SumoBot-5.1-Basic-Competition-Program.BS2
' {$STAMP BS2}
' {$PBASIC 2.5}

' -----[noparse][[/noparse] I/O Definitions ]-------------------------------------------------

LMotor       PIN        13                      ' left servo motor
RMotor       PIN        12                      ' right servo motor

LLinePwr     PIN        10                      ' left line sensor power
LLineIn      PIN        9                       ' left line sensor input
RLinePwr     PIN        7                       ' right line sensor power
RLineIn      PIN        8                       ' right line sensor input

LfIrOut      PIN        4                       ' left IR LED output
LfIrIn       PIN        11                      ' left IR sensor input
RtIrOut      PIN        15                      ' right IR LED output
RtIrIn       PIN        14                      ' right IR sensor input

Speaker      PIN        1                       ' piezo speaker
StartLED     PIN        0                       ' display start delay

' -----[noparse][[/noparse] Constants ]-------------------------------------------------------

LFwdFast     CON        1000                    ' left motor fwd; fast
LFwdSlow     CON        800                     ' left motor fwd; slow
LStop        CON        750                     ' left motor stop
LRevSlow     CON        700                     ' left motor rev; slow
LRevFast     CON        500                     ' left motor rev; fast

RFwdFast     CON        500                     ' right motor fwd; fast
RFwdSlow     CON        700                     ' right motor fwd; slow
RStop        CON        750                     ' right motor stop
RRevSlow     CON        800                     ' right motor rev; slow
RRevFast     CON        1000                    ' right motor rev; fast

' -----[noparse][[/noparse] Variables ]-------------------------------------------------------

lLine        VAR        Word                    ' left sensor raw reading
rLine        VAR        Word                    ' right sensor raw reading
blackThresh  VAR        Word                    ' QTI black threshold
lineBits     VAR        Nib                     ' decoded sensors value
lbLeft       VAR        lineBits.BIT1
lbRight      VAR        lineBits.BIT0

irBits       VAR        Nib                     ' IR readings (l & r)
irLeft       VAR        irBits.BIT1
irRight      VAR        irBits.BIT0
lastIr       VAR        Nib                     ' info from last reading

pulses       VAR        Byte                    ' counter for motor control
temp         VAR        Byte

' -----[noparse][[/noparse] EEPROM Data ]-----------------------------------------------------

RunStatus    DATA       $00                     ' run status

' -----[noparse][[/noparse] Initialization ]--------------------------------------------------

Reset:
  READ RunStatus, temp                          ' read current status
  temp = ~temp                                  ' invert status
  WRITE RunStatus, temp                         ' save for next reset
  IF (temp > 0) THEN END                        ' okay to run?

' Sets black threshold to 1/4 the average of the two sensor readings.
' SumoBot must be placed over black playing surface before this code runs.

Set_Threshold:                                  ' set QTI black threshold
  GOSUB Read_Line_Sensors
  blackThresh = (lLine / 10) + (rLine / 10)

  LOW LMotor                                    ' make more pins outputs
  LOW RMotor

Start_Delay:                                    ' five second delay
  FOR temp = 1 TO 5
    HIGH StartLED                               ' show active
    PAUSE 900
    INPUT StartLED                              ' blink each second
    FREQOUT Speaker, 100, 2500, 3000            ' beep each second
  NEXT

  GOTO Lunge                                    ' start aggressive!

' -----[noparse][[/noparse] Program Code ]----------------------------------------------------

Main:
  GOSUB Read_Line_Sensors

  ' If not on the Shikiri line (border), continue to look for opponent,
  ' otherwise, spin back toward center and resume search

  BRANCH lineBits, [noparse][[/noparse]Search_For_Opponent, Spin_Left, Spin_Right, About_Face]

' --[noparse][[/noparse] Border Avoidance ]--

Spin_Left:                                      ' right sensor was active
  FOR pulses = 1 TO 20
    PULSOUT LMotor, LRevFast
    PULSOUT RMotor, RFwdFast
    PAUSE 20
  NEXT
  lastIr = %00                                  ' clear scan direction
  GOTO Lunge

Spin_Right:                                     ' left sensor was active
  FOR pulses = 1 TO 20
    PULSOUT LMotor, LFwdFast
    PULSOUT RMotor, RRevFast
    PAUSE 20
  NEXT
  lastIr = %00
  GOTO Lunge

About_Face:                                     ' both sensors on Shikiri
  FOR pulses = 1 TO 10                          ' back up from edge
    PULSOUT LMotor, LRevFast
    PULSOUT RMotor, RRevFast
    PAUSE 20
  NEXT
  FOR pulses = 1 TO 30                          ' turn around
    PULSOUT LMotor, LFwdFast
    PULSOUT RMotor, RRevFast
    PAUSE 20
  NEXT
  lastIr = %00
  GOTO Lunge

' --[noparse][[/noparse] IR Processing ]--

Search_For_Opponent:
  GOSUB Read_IR_Sensors

  ' If opponent is not in view, scan last known direction. Turn toward
  ' opponent if seen by one "eye" -- if both, lunge forward

BRANCH irBits, [noparse][[/noparse]Scan, Follow_Right, Follow_Left, Lunge]

Scan:
  BRANCH lastIR, [noparse][[/noparse]Move_Fwd, Scan_Right, Scan_Left]

Move_Fwd:
  GOSUB Creep_Forward
  GOTO Main

Scan_Right:                                     ' spin right, slow
  FOR pulses = 1 TO 5
    PULSOUT LMotor, LFwdSlow
    PULSOUT RMotor, RRevSlow
    PAUSE 20
  NEXT
  GOSUB Creep_Forward                           ' keep moving
  GOTO Main

Scan_Left:                                      ' spin left, slow
  FOR pulses = 1 TO 5
    PULSOUT LMotor, LRevSlow
    PULSOUT RMotor, RFwdSlow
    PAUSE 20
  NEXT
  GOSUB Creep_Forward
  GOTO Main

Follow_Right:                                   ' spin right, fast
  PULSOUT LMotor, LFwdFast
  PULSOUT RMotor, RRevSlow
  lastIR = irBits                               ' save last direction found
  GOTO Main

Follow_Left:                                    ' spin left, fast
  PULSOUT LMotor, LRevSlow
  PULSOUT RMotor, RFwdFast
  lastIR = irBits
  GOTO Main

Lunge:                                          ' locked on -- go get him!
  FOR pulses = 1 TO 25
    PULSOUT LMotor, LFwdFast
    PULSOUT RMotor, RFwdFast
    GOSUB Read_Line_Sensors
    IF (lineBits = %11) THEN Match_Over         ' in sight, we're on the line
  NEXT
  GOTO Main

' If SumoBot can see the opponent with both "eyes" and both QTIs are
' detecting the border, we must have pushed the opponent out.

Match_Over:
  FOR pulses = 1 TO 10                          ' stop motors
    PULSOUT LMotor, LStop
    PULSOUT RMotor, RStop
    PAUSE 20
  NEXT
  INPUT LMotor
  INPUT RMotor

  FOR temp = 1 TO 10                            ' make some noise
    HIGH StartLED
    FREQOUT Speaker, 100, 2500, 3000            ' beep
    INPUT StartLED                              ' blink LED
    PAUSE 100
  NEXT

  DIRS = $0000                                  ' disable all outputs
  GOTO Reset                                    ' reset for next round

' -----[noparse][[/noparse] Subroutines ]-----------------------------------------------------

Read_Line_Sensors:
  HIGH LLinePwr                                 ' activate sensors
  HIGH RLinePwr
  HIGH LLineIn                                  ' discharge caps
  HIGH RLineIn
  PAUSE 1
  RCTIME LLineIn, 1, lLine                      ' read left sensor
  RCTIME RLineIn, 1, rLine                      ' read right sensor
  LOW LLinePwr                                  ' deactivate sensors
  LOW RLinePwr

  ' convert readings to bits
  LOOKDOWN lLine, >=[noparse][[/noparse]1000, 0], lbLeft           ' 0 = black, 1 = line
  LOOKDOWN rLine, >=[noparse][[/noparse]1000, 0], lbRight
  RETURN

Read_IR_Sensors:
  FREQOUT LfIrOut, 1, 38500                     ' modulate left IR LED
  irLeft = ~LfIrIn                              ' read input (1 = target)
  FREQOUT RtIrOut, 1, 38500                     ' modulate right IR LED
  irRight = ~RtIrIn                             ' read input (1 = target)
  RETURN

Creep_Forward:
  FOR pulses = 1 TO 20
    PULSOUT LMotor, LFwdSlow
    PULSOUT RMotor, RFwdSlow
    PAUSE 20
  NEXT
  RETURN

Post Edited (Catharsis) : 4/29/2006 11:46:19 PM GMT

Comments

  • allanlane5allanlane5 Posts: 3,815
    edited 2006-04-29 23:22
    "BRANCH·irBits,·[noparse][[/noparse]Scan,·Follow_Right,·Follow_Left,·Lunge]"

    Roughly:

    IF irBits = 0 THEN GOTO Scan

    IF irBits = 1 THEN GOTO Follow_Right

    IF irBits = 2 THEN GOTO FOllow_Left

    IF irBits = 3 THEN GOTO Lunge

    I believe PBasic 2.5 has an "On value GOSUB" construct.· I'll look for it.

    P.S. -- Yup, "ON irBits GOSUB Scan, Follow_Right, Follow_Left, Lunge"




    Post Edited (allanlane5) : 4/29/2006 11:28:01 PM GMT
  • CatharsisCatharsis Posts: 27
    edited 2006-04-29 23:39
    Alright. That is kind of what I figured so perhaps this isn't a branch problem. I guess the question then would be when would irBits = 2 or 3?

    Edit: If counted in Binary 0000 = 0, 0011 = 3, etc Where the 1s signify which sensor is seen, is that it?

    Post Edited (Catharsis) : 4/29/2006 11:55:38 PM GMT
  • allanlane5allanlane5 Posts: 3,815
    edited 2006-04-29 23:53
    Ah.

    Well, irLeft is an alias for irBits, bit 1. irRight is an alias for irBits, bit 0. What that 'alias' means is, when you set irRight to a '1', then irBits, bit zero, is also set to a '1' (because both variables are 'pointing' at the same register bits).

    So, if irRight and irLeft are both zero, irBits will be zero. If irRight is a 1 (because something is 'seen' on the right) then irBits will be 1. if only irLeft is a 1, then irBits will be a '2'. And if irRight and irLeft are BOTH set, then irBits will be 3.
  • CatharsisCatharsis Posts: 27
    edited 2006-04-30 00:14
    allanlane5 said...
    So, if irRight and irLeft are both zero, irBits will be zero. If irRight is a 1 (because something is 'seen' on the right) then irBits will be 1. if only irLeft is a 1, then irBits will be a '2'. And if irRight and irLeft are BOTH set, then irBits will be 3.

    Ok, pardon my ignorance, but why or how? Why does irLeft make irBits a 2 yet irRight only makes it a 1?

    Thanks
  • Bruce BatesBruce Bates Posts: 3,045
    edited 2006-04-30 04:34
    Catharsis -

    You have to think in BINARY to gain understanding of what's going on:

    /code

    · ··· Binary········· Decimal···············Sensor
    ·irLeft·· irRight·· Equivalent·············Status
    ·
    ·
    ·
    ····
    · · 0········ 0·········· · 0·············None sensed
    · · 0········ 1··········· ·1·············Right only sensed
    · · 1········ 0··········· ·2·············Left only sesed
    · · 1········ 1··········· ·3·············Left and right sensed

    code/

    I hope it makes better sense now? Perhaps sadly, we oldtimers often automatically think in binary, and don't realize that it takes a while for that sort of brain warp to set in :-)

    Regards,

    Bruce Bates


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    <!--StartFragment -->
  • CatharsisCatharsis Posts: 27
    edited 2006-04-30 15:53
    Ok thanks, I was thinking it had something to do with binary. blush.gif
Sign In or Register to comment.