Trouble understanding BRANCH/irBits in Sumobot program
Can somebody explain to me in IF...THEN terms what this part means:
Taken from the SumoBot code available on the site? Thanks
Post Edited (Catharsis) : 4/29/2006 11:46:19 PM GMT
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
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
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
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.
Ok, pardon my ignorance, but why or how? Why does irLeft make irBits a 2 yet irRight only makes it a 1?
Thanks
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 -->