LCD Auton Selection-PROS

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 :stuck_out_tongue:

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

When you say “I don’t know where to start,” do you mean that:

  1. You don’t know the high-level/big picture idea of how to do it. That is, you don’t understand the algorithm (not the code, but the algorithm) for autonomous selection with the LCD.
    -or-
  2. You don’t know the syntax to use the LCD.
    -or-
  3. All of the above.
    -or-
  4. None of the above (custom reason).

:wink:

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....     ");
}