will a WORD variable hold more than 254? i’m at a last resort of counting loops for our autonomous code so i need a counter…also if anyone has any simple autonomous code that works and would like to share, i just need to see how you worked it into the main code and detecting if auton_mode = 1
and all that jazz…
Thanks,
manodrum
A word variable will hold a value up to 65535. A word variable is 16 bits long which is twice the length of a byte.
Steve
*Originally posted by manodrum *
**will a WORD variable hold more than 254? i’m at a last resort of counting loops for our autonomous code so i need a counter…also if anyone has any simple autonomous code that works and would like to share, i just need to see how you worked it into the main code and detecting if auton_mode = 1
and all that jazz…
Thanks,
manodrum **
Hi,
Here is some of our code.
(Warning: I am not one of the programmers.)
We have multi-bank code. See Innovation FIRST site for an explanation and example.
We have our autonomous code in bank 2.
Below is how we jump to bank 1 where our driver controlled code is, when autonomous is over.
'---------- Aliases for the Pbasic Mode Byte (PB_mode) -------------------------------
'----------------------------------------------------------------------------------------------
’ Bit 7 of the PB_mode byte (aliased as comp_mode below) indicates the status
’ of the Competition Control, either Enabled or Disabled. This indicates the
’ starting and stopping of rounds at the competitions.
’ Comp_mode is indicated by a solid “Disabled” LED on the Operator Interface.
’ Comp_mode = 1 for Enabled, 0 for Disabled.
’
’ Bit 6 of the PB_mode byte (aliased as auton_mode below) indicates the status
’ of the Autonomous Mode, either Autonomous or Normal. This indicates when
’ the robot must run on its own programming. When in Autonomous Mode, all
’ OI analog inputs are set to 127 and all OI switch inputs are set to 0 (zero).
’ Auton_mode is indicated by a blinking “Disabled” LED on the Operator Interface.
’ Auton_mode = 1 for Autonomous, 0 for Normal.
’
’ Autonomous Mode can be turned ON by setting the RC to Team 0 (zero).
’
’ Bit 5 of the PB_mode byte (aliased as user_display_mode below) indicates when
’ the user selects the “User Mode” on the OI. PB_mode.bit5 is set to 1 in “User Mode”.
’ When the user selects channel, team number, or voltage, PB_mode.bit5 is set to 0
’ When in “User Mode”, the eight Robot Feedback LED are turned OFF.
’ Note: “User Mode” is identified by the letter u in the left digit (for 4 digit OI’s)
’ Note: “User Mode” is identified by decimal places on the right two digits (for 3 digit OI’s)
comp_mode VAR PB_mode.bit7
auton_mode VAR PB_mode.bit6
user_display_mode VAR PB_mode.bit5
'After our autonomous routine, we wait for autonomous to end.
WaitQuitAutonomous:
do
Gosub SerialInput
’ Quit autonomous mode when it’s time
Gosub TestQuitAutonomous
Gosub SerialOutput
loop
TestQuitAutonomous:
’ (Test if its time to run the main loop (competition code)
if auton_mode = 0 then Run 1 ’ (If autonomous is turned off, we jump to bank 1 and run the driver controlled program)
if AutonomousSwitch = 0 then Run 1 ’ (We have a switch on our robot which allows us to turn off autonomous mode)
’ Keep going in autonomous mode
Return
Hope that helps.
*Originally posted by manodrum *
**…also if anyone has any simple autonomous code that works and would like to share, i just need to see how you worked it into the main code and detecting if auton_mode = 1
and all that jazz…
Thanks,
manodrum **
This is probably a lot more than you wanted to know, but here are excerpts which provide a a pretty good idea of how our autonomous mode is implemented:
Slot 0 pretty much just contains the normal pre-main-loop initialization stuff.
Slot 1 (BB2003MainLoop):
<snip>
' Since auton_mode, comp_mode, and user_display_mode won't
' be changing that much, it will be safe to print out the new state
' whenever one of them changes.
if (auton_mode <> Autonomous) then
if (auton_mode = 1) then
debug "Autonomous", cr
else
debug "Operator Controlled", cr
endif
endif
if (comp_mode <> Disabled) then
if (comp_mode = 1) then
debug "Disabled", cr
else
debug "Enabled", cr
endif
endif
if (user_display_mode <> UserDisplay) then
if (user_display_mode = 1) then
debug "User Display On", cr
else
debug "User Display Off", cr
endif
endif
' Save the various flags from the PBASIC mode (byte) variable to
' dedicated bit variables so that the byte variable may be reused
' as a temporary variable.
Disabled = comp_mode
Autonomous = auton_mode
UserDisplay = user_display_mode
And later in slot 1:
EEPROM_AUTON_PROG_NUM data 1
' If this is the first time through this code (i.e. immediately after
' power-up) then the scratchpad location which holds our selected
' autonomous program number will be zero (an invalid program
' number) so read the default prog number from EEPROM (or the
' last one saved there.)
get AUTON_PROG_NUM, autonProgNum
if autonProgNum = 0 then
read EEPROM_AUTON_PROG_NUM, autonProgNum
put AUTON_PROG_NUM, autonProgNum
put PROG_SELECT_TIMER, 0
endif
' Select autonomous mode program
get AUTON_PROG_NUM, autonProgNum
' Delay a little before allowing selector change again.
get PROG_SELECT_TIMER, progSelectTimer
progSelectTimer = progSelectTimer min 1 - 1
put PROG_SELECT_TIMER, progSelectTimer
'debug ?progSelectTimer
{$if (Disabled = 1)}
' Make sure that the match timer doesn't start ticking until we're
' enabled. (AND that it gets reset any time we get disabled!)
put MATCH_TIMER_LOW, 0
put MATCH_TIMER_HIGH, 0
if UserDisplay = 1 then
' We are disabled, and in user display mode, so allow selection
' of a different autonomous program.
if progSelectTimer = 0 then
if p4_sw_top = 1 then
' The program select button is down! Reset the autorepeat
' timer, and select the next program number.
put PROG_SELECT_TIMER, 10
select autonProgNum
case < LAST_AUTON_PROG
autonProgNum = autonProgNum + 1
case LAST_AUTON_PROG
autonProgNum = FIRST_LEARN_PROG
case FIRST_LEARN_PROG to LAST_LEARN_PROG - 1
autonProgNum = autonProgNum + 1
case LAST_LEARN_PROG
autonProgNum = FIRST_PLAYBACK_PROG
case FIRST_PLAYBACK_PROG to LAST_PLAYBACK_PROG - 1
autonProgNum = autonProgNum + 1
case else
autonProgNum = 1
endselect
' Again, we won't be changing auton programs so often that
' we dare not print out the currently selected program name.
select autonProgNum
case DEAD_IN_THE_WATER_PROG
debug "Mars rock dance", cr
case LINE_FOLLOW_LEFT_PROG
debug "Follow line from left", cr
case LINE_FOLLOW_RIGHT_PROG
debug "Follow line from right", cr
case DEAD_RECKON_FROM_RIGHT_SIDE
debug "Dead reckon from right", cr
case DEAD_RECKON_FROM_LEFT_SIDE
debug "Dead reckon from left", cr
case WAIT_BY_WALL_FROM_RIGHT_SIDE
debug "Wait by wall from right", cr
case WAIT_BY_WALL_FROM_LEFT_SIDE
debug "Wait by wall from left", cr
case LIMBO_UNDER_BAR_SLOW
debug "Slow limbo", cr
case LIMBO_UNDER_BAR_FAST
debug "Fast limbo", cr
case LEARN6
debug "Learn for Playback 6", cr
case LEARN7
debug "Learn for Playback 7", cr
case LEARN6 + 100
debug "Playback 6", cr
case LEARN7 + 100
debug "Playback 7", cr
endselect
put AUTON_PROG_NUM, autonProgNum
endif
endif ' progSelectTimer = 0
p4_sw_top = 0 ' Prevent the button from being acted upon for
' its normal purpose
else
' We are disabled, but not in user display mode. If the
' autonomous program selector has changed, save it to
' EEPROM.
read EEPROM_AUTON_PROG_NUM, prevAutonProgNum
if autonProgNum <> prevAutonProgNum then
debug "Saving ", ? autonProgNum
write EEPROM_AUTON_PROG_NUM, autonProgNum
endif
endif
{$endif Disabled}
get MATCH_TIMER_LOW, matchTimer.byte0
get MATCH_TIMER_HIGH, matchTimer.byte1
if matchTimer < ****** then
matchTimer = matchTimer + 1 + delta_t
put MATCH_TIMER_LOW, matchTimer.byte0
put MATCH_TIMER_HIGH, matchTimer.byte1
else
***[Excised]***
endif
And a little later in slot 1:
if Autonomous = 1 then
Run BB2003_AUTON_PROG1
endif
Slot 2 contains nothing having to do with auto mode except this… just before it would normally call the “output data” slot:
' If autonProgNum is one of the auto-learn programs, then record the robot actions.
if (Disabled = 0) then
get AUTON_PROG_NUM, autonProgNum
if (autonProgNum >= FIRST_LEARN_PROG) and \
(autonProgNum <= LAST_LEARN_PROG) then
get MATCH_TIMER_LOW, matchTimer.byte0
get MATCH_TIMER_HIGH, matchTimer.byte1
'debug "Learning for playback -- ", dec? matchTimer
select autonProgNum
case LEARN6
run BB2003_PLAYBACK6
case LEARN7
run BB2003_PLAYBACK7
case else
debug "Invalid ", dec? autonProgNum
endselect
endif
endif
Run BB2003_OUTPUT_DATA
Slot 3 (BB2003_OUTPUT_DATA) contains the serout… and this… which controls the digital display on the operator interface when it is in user display mode:
if UserDisplay then
' Display SOMETHING on the OI
get AUTON_PROG_NUM, autonProgNum
{$if (Disabled = 1)}
temp10 = autonProgNum
{$elseif (Autonomous = 1) or \
((autonProgNum >= FIRST_LEARN_PROG) and (autonProgNum <= LAST_LEARN_PROG))}
' Display the number of seconds left in autonomous mode (or
' the number of seconds left to record for later playback in auto
' mode.
get MATCH_TIMER_LOW, matchTimer.lowbyte
get MATCH_TIMER_HIGH, matchTimer.highbyte
temp10 = 573 - (matchTimer max 573) / 38
{$else}
get GRIPPER_POSITION_SENSOR, temp10
{$endif} ' Disabled
outh = temp10
else
' Use PWM 1 and 2 Reverse LEDs on OI to provide visual
' feedback of the state of ***[Excised;)]***
endif ' UserDisplay
Note the strange {$…} syntax. These are directives to my BASIC Stamp Preporcessor which translates these to legal PBASIC 2.0 statements. My preprocessor is still a work in progress. An earlier version is available in the White papers section. I don’t know whether all the code I’m quoting here will work with that version. You shouldn’t have difficulty modding this code to work with either of the currently available BASIC Stamp Editors, but if you’re really a “bleeding edge” type, I’ll let you have a copy of the current program.
continued…**
Slot 4 (BB2003_AUTON_PROG1) contains the first several of our autonomous programs: (BTW, BB2003Include.bsppi is an include file – which defines all our shared variables, and gets included in all our programs.)
' {$STAMP BS2SX}
' {$PBasic 2.5}
{$Include BB2003Include.bsppi}
get MATCH_TIMER_LOW, matchTimer.byte0
get MATCH_TIMER_HIGH, matchTimer.byte1
get AUTON_PROG_NUM, autonProgNum
select autonProgNum
case DEAD_IN_THE_WATER_PROG ' 1
gosub DeadInTheWater
case LINE_FOLLOW_LEFT_PROG ' 2
gosub FollowTheLineFromRightSide
case LINE_FOLLOW_RIGHT_PROG ' 3
gosub FollowTheLineFromLeftSide
case DEAD_RECKON_FROM_RIGHT_SIDE ' 4
gosub DeadReckonFromRightSide
case DEAD_RECKON_FROM_LEFT_SIDE ' 5
gosub DeadReckonFromLeftSide
case else
run BB2003_AUTON_PROG2
endselect
Run BB2003_OUTPUT_DATA
DeadInTheWater:
'debug "DeadInTheWater", cr
leftWheelOutput=127
rightWheelOutput=127
return
******
DeadReckonFromRightSide:
' Handle dead reckoning timing by using the matchTimer.
' matchTimer is incremented every 1/38.2 seconds.
put PORT1_X, 63 ' open the grippers
get MATCH_TIMER_LOW, matchTimer.byte0
get MATCH_TIMER_HIGH, matchTimer.byte1
{$if (matchTimer < 28)} ' Go straight for 0.75 seconds.
leftWheelOutput = 254
rightWheelOutput = 254
{$else if (matchTimer < 28+76)} ' 2 seconds swooping turn to right
leftWheelOutput = 254
rightWheelOutput = 127+25
{$else if (matchTimer < 28+76+19)} ' 0.5 seconds to stop
leftWheelOutput = 127
rightWheelOutput = 127
plantRearWedge = 1
unplantRearWedgeFwd = 0
{$else if (matchTimer < 28+76+19+152)} ' 4 seconds straight up the ramp backwards
leftWheelOutput = 0
rightWheelOutput = 0
{$else if (matchTimer < 28+76+19+152+19)} ' 0.5 seconds to stop
leftWheelOutput = 127
rightWheelOutput = 127
{$else}
put PORT1_X, 127 ' Release grippers
plantRearWedge = 0
unplantRearWedgeFwd = 1
highGear = 0
highGearShiftFwd = highGear
lowGearShiftFwd = highGear ^ 1
leftWheelOutput = 127
rightWheelOutput = 127
{$endif}
return
DeadReckonFromLeftSide:
***[This is just the same as the preceding code... except for the
direction of the turns, some slight timing differences and
some compensation for differences between the left and right
sides of the drive train.]***
Slot 5 (BB2003_AUTON_PROG2) contains some more autonomous programs:
' {$STAMP BS2SX}
' {$PBasic 2.5}
{$Include BB2003Include.bsppi}
get MATCH_TIMER_LOW, matchTimer.byte0
get MATCH_TIMER_HIGH, matchTimer.byte1
get AUTON_PROG_NUM, autonProgNum
select autonProgNum
case WAIT_BY_WALL_FROM_RIGHT_SIDE ' 6
gosub WaitByWallFromRightSide
case WAIT_BY_WALL_FROM_LEFT_SIDE ' 7
gosub WaitByWallFromLeftSide
case LIMBO_UNDER_BAR_SLOW ' 8
gosub LimboUnderBarSlow
case LIMBO_UNDER_BAR_FAST ' 9
gosub LimboUnderBarFast
case LEARN6 + 100
'debug "Playing back -- ", dec? matchTimer
run BB2003_PLAYBACK6
case LEARN7 + 100
'debug "Playing back -- ", dec? matchTimer
run BB2003_PLAYBACK7
case else
' Something's wrong. Go back and do the Mars rock dance.
put AUTON_PROG_NUM, DEAD_IN_THE_WATER_PROG
run BB2003_AUTON_PROG1
endselect
Run BB2003_OUTPUT_DATA
WaitByWallFromRightSide:
' Handle dead reckoning timing by using the matchTimer.
' matchTimer is incremented every 1/38.2 seconds.
put PORT1_X, 63 ' open the grippers
' do an arc for the first 6.29 seconds (240 matchTimer counts)
get MATCH_TIMER_LOW, matchTimer.byte0
get MATCH_TIMER_HIGH, matchTimer.byte1
{$if (matchTimer < 28)} ' 0.75 second straight
leftWheelOutput = 254
rightWheelOutput = 254
{$else if (matchTimer < 28+76)} ' 2 seconds swooping turn to right
leftWheelOutput = 254
rightWheelOutput = 127+25
{$else}
put PORT1_X, 127 ' Release grippers
leftWheelOutput = 127
rightWheelOutput = 127
{$endif}
return
WaitByWallFromLeftSide:
' Handle dead reckoning timing by using the matchTimer.
' matchTimer is incremented every 1/38.2 seconds.
put PORT1_X, 63 ' open the grippers
get MATCH_TIMER_LOW, matchTimer.byte0
get MATCH_TIMER_HIGH, matchTimer.byte1
{$if (matchTimer < 38)} ' Go straight for 1 second
leftWheelOutput = 254
rightWheelOutput = 254
{$else if (matchTimer < 38+76)} ' Swooping turn to right for 2 seconds
leftWheelOutput = 127+10
rightWheelOutput = 254
{$else}
put PORT1_X, 127 ' Release grippers
leftWheelOutput = 127
rightWheelOutput = 127
{$endif}
return
LimboUnderBarSlow:
get MATCH_TIMER_LOW, matchTimer.byte0
get MATCH_TIMER_HIGH, matchTimer.byte1
{$if (LiftLowerLimitSwitch = 0)} ' Lower lift to limit switch
put LIFT_POWER, 127+25 ' Lower the lift
if LiftLowerLimitSwitch = 1 then
debug "Lower Limit Reached", cr
put LIFT_POWER, 127
endif
highGear = 0
highGearShiftFwd = highGear
lowGearShiftFwd = highGear ^ 1
plantFrontWedge = 1
plantRearWedge = 1
unplantRearWedgeFwd = 0
leftWheelOutput = 127
rightWheelOutput = 127
{$else if (matchTimer < 239+114)} ' Stop the lift and Back up under the bar for 3 seconds.
put LIFT_POWER, 127
leftWheelOutput = 0
rightWheelOutput = 0
{$else}
leftWheelOutput = 127
rightWheelOutput = 127
{$endif}
return
LimboUnderBarFast:
get MATCH_TIMER_LOW, matchTimer.byte0
get MATCH_TIMER_HIGH, matchTimer.byte1
{$if (LiftLowerLimitSwitch = 0)} ' Lower lift to limit switch
' Don't move until it's safe.
leftWheelOutput = 127
rightWheelOutput = 127
' Lower the lift at half speed.
put LIFT_POWER, 127+63
if LiftLowerLimitSwitch = 1 then
debug "Lower Limit Reached", cr
put LIFT_POWER, 127
endif
' Make sure we're in high gear ...
highGear = 1
highGearShiftFwd = highGear
lowGearShiftFwd = highGear ^ 1
' ... and wedges are down.
plantFrontWedge = 1
plantRearWedge = 1
unplantRearWedgeFwd = 0
{$else if (matchTimer < 239)} ' Stop the lift and Back up under the bar for 3 seconds.
put LIFT_POWER, 127
leftWheelOutput = 0
rightWheelOutput = 0
{$else}
leftWheelOutput = 127
rightWheelOutput = 127
{$endif}
return
Slots 6 and 7 (BB2003_PLAYBACK6 and BB2003_PLAYBACK7) are identical, and are used to record 15 seconds worth of driver control to EEPROM for later playback in autonomous mode:
' {$STAMP BS2SX}
' {$PBasic 2.5}
{$Include BB2003Playback.bsppi}
BB2003Playback.bsppi which gets inserted into both slots 6 and 7, contains all the logic to both save and replay the operator commands:
{$Include BB2003Include.bsppi}
' We need to save 6 bytes of data to be able to satisfactorily
' control the robot during playback. By only saving every other
' time through the loop, we are able to save 15.5 seconds worth
' of data.
MOVE_COUNT con 296 ' 15.5 seconds worth of "moves"
MOVE_SAVE_SIZE con 6*MOVE_COUNT
theMoves data (MOVE_SAVE_SIZE) ' Reserve space for the learned moves
theMoveIndex = (matchTimer >> 1) * 6 + theMoves
if Autonomous = 0 then
if (theMoveIndex < MOVE_SAVE_SIZE) and (matchTimer & 1 = 0) then
write theMoveIndex+0, leftWheelOutput
write theMoveIndex+1, relayA
write theMoveIndex+2, rightWheelOutput
write theMoveIndex+3, relayB
write theMoveIndex+4, liftPower
write theMoveIndex+5, GripperJoyStick
else
Run BB2003_OUTPUT_DATA
endif
else
if (theMoveIndex < MOVE_SAVE_SIZE) then
read theMoveIndex+0, leftWheelOutput
read theMoveIndex+1, relayA
read theMoveIndex+2, rightWheelOutput
read theMoveIndex+3, relayB
read theMoveIndex+4, liftPower
read theMoveIndex+5, GripperJoyStick
else
' If playback continues longer than we have data for, just
' continue playing back the last data we have (except stop the
' wheels and the lift.)
theMoveIndex = MOVE_SAVE_SIZE - 5
leftWheelOutput = 127
read theMoveIndex+1, relayA
rightWheelOutput = 127
read theMoveIndex+3, relayB
liftPower = 127
read theMoveIndex+5, GripperJoyStick
endif
endif
'debug dec theMoveIndex, ": ", dec leftWheelOutput, " ", \
ibin relayA, " ", dec rightWheelOutput, " ", \
ibin relayB, " ", dec liftPower, " ", dec GripperJoyStick, cr
Run BB2003_OUTPUT_DATA
**
If you are doing autonomous for the first time you might want to just add some simple movements to your regular Main program.
Helping other teams at regionals I’ve found they understand the concepts more easily and get up and running faster if you simply add the autonomous as an override of the regular user controls. You only need to expand into multi-bank code if you need more space. We use an autonomous meta or scripting language, so a sample of our code would be counter productive if you’re new to this.
The example below is for a single joystick than does 3 moves. Add or subtract moves to fit your need. The code is in the old 1.33 style in case you’re modifying last years robot code.
'----------Put these in your declaration section
'These are the # of program loops that completes the movement
FIRST_LEG CON 40 '~ 1 second assuming delta_t=0
SECOND_LEG CON 200 '~5.2 seconds
THIRD_LEG CON 250 '~6.5 seconds
'The last leg you define here should not be > 577 (15 sec.)
auto_counter VAR WORD
'------------Put this before your main loop
auto_counter = 0
'-----------Put this immediately after your Serin command
’ We are just overriding the joystick values as if the driver were moving the joystick
IF auto_mode = 0 then NoAuto
auto_counter = auto_counter + 1
'Can also do: auto_counter = auto_counter + 1 + delta_t
If auto_counter >= FIRST_LEG then LEG2
'These values should be what your driver would normally do with the joystick to accomplish what you want to do
p1_x = 254
p1_y = 0
Goto NoAuto
LEG2:
If auto_counter >= SECOND_LEG then LEG3
p1_x = 254
p1_y = 0
Goto NoAuto
LEG3:
If auto_counter >= THIRD_LEG then NoAuto
'Make sure you come to a stop as the last LEG
p1_x = 127
p1_y = 127
Goto NoAuto
NoAuto:
'------------The rest of your regular code
(BTW: This was indented for readability when I typed it in)
*Originally posted by Mark McLeod *
**(BTW: This was indented for readability when I typed it in) **
Mark,
To preserve indentation, put your code inside {code}…{/code} vBcode tags. (Replace the curly braces with square brackets.)
Here’s your code with them:
'----------Put these in your declaration section
'These are the # of program loops that completes the movement
FIRST_LEG CON 40 '~ 1 second assuming delta_t=0
SECOND_LEG CON 200 '~5.2 seconds
THIRD_LEG CON 250 '~6.5 seconds
'The last leg you define here should not be > 577 (15 sec.)
auto_counter VAR WORD
'------------Put this before your main loop
auto_counter = 0
'-----------Put this immediately after your Serin command
' We are just overriding the joystick values as if the driver were
' moving the joystick
IF auto_mode = 0 then NoAuto
auto_counter = auto_counter + 1
'Can also do: auto_counter = auto_counter + 1 + delta_t
If auto_counter >= FIRST_LEG then LEG2
'These values should be what your driver would normally do
'with the joystick to accomplish what you want to do
p1_x = 254
p1_y = 0
Goto NoAuto
LEG2:
If auto_counter >= SECOND_LEG then LEG3
p1_x = 254
p1_y = 0
Goto NoAuto
LEG3:
If auto_counter >= THIRD_LEG then NoAuto
'Make sure you come to a stop as the last LEG
p1_x = 127
p1_y = 127
Goto NoAuto
NoAuto:
'------------The rest of your regular code
*Originally posted by Mark McLeod *
**We use an autonomous meta or scripting language, so a sample of our code would be counter productive if you’re new to this.
**
Thank you for the code. I think that’s a very clear and workable way to get people started with autonomous. I will pass that on at our regional.
Question: How does one use a “meta or scripting language” with Pbasic?
Thanks for the proper vb tags Greg. I went and read up on the vb Code help after you pointed that out.
Doug,
Here’s an example of what one of our autonomous program scripts looks like. We don’t recode as in my beginners example above, but we change the script instead. It makes it simpler to change the autonomous movements quickly with less risk of introducing coding errors. We have a graphical interface where you drag and click the cursor on an image of the playing field where you want the robot to go and the script gets generated automatically. When each command is executed a subroutine specific to that command does the proper setup and it gets submitted to a master control routine.
The basic command format is: COMMAND, SPEED, DISTANCE
These values are defined constants. Other commands have some variation on the arguments, for instance, some commands have “on/off” arguments and the arm commands are really POT readings.
'Basic ramp attack
LeftProg Data CmdFrwd, SpdFull, 25 'Pull out
Data CmdRght, SpdFull, 40 'Move in front of ramp
Data CmdOpen, SpdFull, 10 'Open arms
Data CmdArmB, SpdFull, 50 'Drop arm
Data CmdBack, SpdFull, 130 'Up ramp
Data CmdStop, SpdStop, 1 'Come to a stop
LeftMax CON 6 'Auto sequence Maximum entries is 255
RghtProg Data CmdFrwd, SpdFull, 25 'Pull out
Data CmdLeft, SpdFull, 40 'Move in front of ramp
Data CmdOpen, SpdFull, 10 'Open arms
Data CmdArmB, SpdFull, 50 'Drop arm
Data CmdBack, SpdFull, 130 'Up ramp
Data CmdStop, SpdStop, 1 'Come to a stop
RghtMax CON 6 'Auto sequence Maximum entries is 255
The commands are stored in EEPROM by the DATA statement and READ in sequence like a script.
*Originally posted by Mark McLeod *
**
We have a graphical interface where you drag and click the cursor on an image of the playing field where you want the robot to go and the script gets generated automatically. **
Wow! Thanks for the info. Very cool.
Did your team create the graphical interface?
If so, what language did you use?
(My son worked on a robot at JPL, called “Urbie”, short for “Urban Robot”. It was a backpackable robot and with a graphical interface that allowed them to outline a door and the robot would head for it. If something got in the way, Urbie would keep going, avoiding obstacles, while it looked for the “door”.)
Hi Doug,
One of our student programmers wrote the graphical interface in a couple of hours using Visual Basic 6. VB is great for knocking off graphical interfaces quickly. He used the image of the playing field published by FIRST as the background and simply made each pixel represent one inch of distance. You have to account for the extra distance over the slope of the ramp though.
One of the nice things about doing it this way is how small the program actually ends up being. Our basic autonomous program takes up 50% of a program slot.
Sounds like your son has valuable robot navigation experience to bring to your team. An obstacle course might be fun for a FIRST game.
*Originally posted by Mark McLeod *
**Hi Doug,One of our student programmers wrote the graphical interface in a couple of hours using Visual Basic 6. VB is great for knocking off graphical interfaces quickly. He used the image of the playing field published by FIRST as the background and simply made each pixel represent one inch of distance. You have to account for the extra distance over the slope of the ramp though.
One of the nice things about doing it this way is how small the program actually ends up being. Our basic autonomous program takes up 50% of a program slot.
Sounds like your son has valuable robot navigation experience to bring to your team. An obstacle course might be fun for a FIRST game. **
That is very impressive, especially the fact that one of your students wrote the interface in such a short time. Sounds like we should have some students learning VB.
Thanks again for the info, and also for the code for beginners in autonomous. Hey, even I can understand it. This week, Team 696 is sponsoring a programming workshop at the S. Calif. Regional. I will have your code there.