Hey,
Anybody have an autonomous selection program for the LCD in PROS they would be willing to share? I don’t know where to start
Thanks,
Daniel
Hey,
Anybody have an autonomous selection program for the LCD in PROS they would be willing to share? I don’t know where to start
Thanks,
Daniel
You can adapt ROBOTC (or ConVEX) code with very little change to the structure. Replace the various calls to get buttons or setting the LCD with the PROS version of that function, for example;
nLCDButtons in ROBOTC becomes lcdReadButtons(uart2) in PROS.
I will do a quick translate of one of my ROBOTC examples later if you like.
Disclaimer: I don’t know anything about the PROS framework, but I do know how to program LCD menus in ROBOTC.
When you say “I don’t know where to start,” do you mean that:
Knowing which of those would help us give better feedback/advice.
I recommend you read some of the great threads on this forum on how to write LCD selection code for ROBOTC to get an idea of the “big picture” of autonomous selection. Then, porting code should just be a matter of finding the syntax to command the LCD with PROS.
This isn’t anything fancy, and robust to all of my testing so far…
if (!hasAutonomousRun && !isEnabled() && digitalRead(dAUTON_DISABLE) == LOW)
{ // A boolean called hasAutonomousRun is created to ensure autonomous doesn't ever run twice
// Obviously, check to make sure a match isn't in session
// Check to make sure that the Autonomous Override jumper clip is plugged in (unplugging it will disable autonomous)
/* ALLIANCE SELECTION */
lcdSetText(uart1, 1, " Alliance? ");
lcdSetText(uart1, 2, "Red Blue");
delay(10);
startTime = millis();
for (startTime = millis(); millis() < startTime + LCD_TIMEOUT;)
{
if (buttonIsNewPress(LCD_LEFT)) {
startingLocation = 0;
startTime -= LCD_TIMEOUT;
}
else if (buttonIsNewPress(LCD_RIGHT)) {
startingLocation = 1;
startTime -= LCD_TIMEOUT;
}
delay(40);
}
lcdSetText(uart1, 1, " Alliance: ");
switch (startingLocation)
{
case 0:
lcdSetText(uart1, 2, " Red ");
break;
case 1:
lcdSetText(uart1, 2, " Blue ");
break;
default:
lcdSetText(uart1, 2, "None Selected");
break;
}
delay(1000);
/* TILE SELECTION */
if (startingLocation != 4) // only select tile if alliance color has been selected
{
lcdSetText(uart1, 1, " Tile? ");
lcdSetText(uart1, 2, "Middle Hanging");
delay(10);
for (startTime = millis(); millis() < startTime + LCD_TIMEOUT;)
{
if (buttonIsNewPress(LCD_LEFT)) {
startingLocation += 2;
startTime -= LCD_TIMEOUT;
}
else if (buttonIsNewPress(LCD_RIGHT)) {
startingLocation += 0;
startTime -= LCD_TIMEOUT;
}
delay(40);
}
}
lcdSetText(uart1, 1, "StartingLocation");
switch (startingLocation)
{
case 0:
lcdSetText(uart1, 2, " Red Hanging ");
break;
case 1:
lcdSetText(uart1, 2, " Blue Hanging ");
break;
case 2:
lcdSetText(uart1, 2, " Red Middle ");
break;
case 3:
lcdSetText(uart1, 2, " Blue Middle ");
break;
default:
lcdSetText(uart1, 2, "Unknown");
break;
}
delay(1000);
}
/* Final Display */
if (!isEnabled()) {
lcdClear(uart1);
lcdSetText(uart1, 1, "Disabled");
switch (startingLocation)
{
case 0:
lcdSetText(uart1, 2, "RedHang");
break;
case 1:
lcdSetText(uart1, 2, "BluHang");
break;
case 2:
lcdSetText(uart1, 2, "RedMid");
break;
case 3:
lcdSetText(uart1, 2, "BluMid");
break;
default:
lcdSetText(uart1, 2, "default");
break;
}
}
Oh yeah, the ButtonNewPress() is one of my “in-house” functions and I’m not quite ready to part with it yet… It’s not all that difficult to imagine-and program-what it does, but I’m not quite ready to give it away.
In a separate file, not within a function:
/* Starting Location Codes */
// 0: red haning
// 1: blue hanging
// 2: red middle
// 3: blue middle
// 4: default
// red = 0
// blue = 1
// hanging = 0,
// middle = 2
char startingLocation = 4;
bool hasAutonomousRun = false;
I think that covers it for my autonomous selection. I have a bit more to it, but that’s it for selecting autonomous. I know there are probably more elegant ways of putting together an autonomous routine selection function, and I have a bit of a fascination with switches. I should also have made the startingLocation an enum, but ain’t nobody got time fo’ dat.
I’m considering releasing my original code from my 1.0 bot. It worked really well, except the robot itself. It was partially banged together and partially planned. I’m not sure if it’s necessary to release the code, especially when, as James and RoboDesigners said, it’s easy to port code over to PROS.
Well, I imagined, but it was quite awkward to get it working with your code. What do you normally set LCD_TIMEOUT to be.
bool
buttonIsNewPress( int button )
{
int b;
static int pressed = false;
if( pressed ) {
// wait for release
if( lcdReadButtons(uart1) != 0 )
return(false);
pressed = false;
}
// get new button
b = lcdReadButtons(uart1);
// check for match
if( b == button ) {
pressed = true;
return(true);
}
else
return(false);
}
So for fun (not) I ported Demo 1 from this thread (see post #1).
https://vexforum.com/t/robotc-lcd-autonomous-selection/24818/1
You will see most of the code follows the ROBOTC version almost exactly, PROS does have some weird behavior on power up, it needs the magic delays before using flags like IsEnabled() and such. The other demo code from the ROBOTC thread could be ported as well, but there’s not much point in my doing that as it’s mostly just a cut and paste exercise and sorting out the PROS task handling which to me is still a little clunky (but I’m obviously biased in how such things should work). See the other thread for a little explanation on the reason for the getLcdButtons function.
#include "main.h"
// Little macro to keep code cleaner, masks both disable/enable and auton/driver
#define vexCompetitionState ( (isEnabled()?0:2) + (isAutonomous()?1:0) )
#define kButtonNone 0
#define kButtonLeft LCD_BTN_LEFT
#define kButtonCenter LCD_BTN_CENTER
#define kButtonRight LCD_BTN_RIGHT
int
getLcdButtons()
{
int competitionState = vexCompetitionState;
int buttons;
// This function will block until either
// 1. A button is pressed on the LCD
// If a button is pressed when the function starts then that button
// must be released before a new button is detected.
// 2. Robot competition state changes
// Wait for all buttons to be released
while( lcdReadButtons(uart1) != kButtonNone ) {
// check competition state, bail if it changes
if( vexCompetitionState != competitionState )
return( kButtonNone );
taskDelay(10);
}
// block until an LCD button is pressed
do {
// we use a copy of the lcd buttons to avoid their state changing
// between the test and returning the status
buttons = lcdReadButtons(uart1);
// check competition state, bail if it changes
if( vexCompetitionState != competitionState )
return( kButtonNone );
taskDelay(10);
} while( buttons == kButtonNone );
return( buttons );
}
// global hold the auton selection
static int MyAutonomous = 0;
/*-----------------------------------------------------------------------------*/
/* Display autonomous selection */
/*-----------------------------------------------------------------------------*/
void
LcdSetAutonomous( int value )
{
// Simple selection display
if( value == 0 ) {
lcdSetText(uart1 ,1, "auton 0");
lcdSetText(uart1, 2, "[00] 01 02 ");
}
if( value == 1 ) {
lcdSetText(uart1, 1, "auton 1");
lcdSetText(uart1, 2, " 00 [01] 02 ");
}
if( value == 2 ) {
lcdSetText(uart1, 1, "auton 2");
lcdSetText(uart1, 2, " 00 01 [02]");
}
// Save autonomous mode for later
MyAutonomous = value;
}
/*-----------------------------------------------------------------------------*/
/* Select one of three autonomous choices */
/*-----------------------------------------------------------------------------*/
void
LcdAutonomousSelection()
{
int button;
// Clear LCD and turn on backlight
lcdClear(uart1);
lcdSetBacklight(uart1,true);
// diaplay default choice
LcdSetAutonomous(0);
// PROS seems to need a delay
taskDelay(2000);
while( !isEnabled() )
{
// this function blocks until button is pressed
button = getLcdButtons();
// Display and select the autonomous routine
if( button == kButtonLeft )
LcdSetAutonomous(0);
if( button == kButtonCenter )
LcdSetAutonomous(1);
if( button == kButtonRight )
LcdSetAutonomous(2);
// Don't hog the cpu !
taskDelay(10);
}
lcdSetText(uart1, 2, "Running.... ");
}