variable?

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. :slight_smile: