Brain Screen Pre_Auton Problem

I programmed an autonomous selection program on the pre_auton section of the competition template because I wanted it to run before the autonomous started so my team could select an autonomous before the match started. Something messed up because the robot stopped moving as soon as I implemented the code into the robot brain. The only code so far I had was a code to change the color and text of buttons. It was merely a graphical program. Our team had not programmed autonomous yet so we could not implement the code to change autonomous. I could not figure out the problem because nothing in the code could effect the motors in any way. The only thing I theorized that might be effecting the motors is the wait function I put in. I told the program to:

vex::task::sleep(300);

before being able to change text and color again because I had the problem of the colors and text switching a thousand times after I tapped it once. That is the only way that I could think to stop that problem was to use a wait function. I discovered that my motors would run if I held the joysticks at a position (it can be any position) and then tap a button. The robot was locked in that motion until I held the joysticks at a different position and pressed another button. Then the robot would be locked in the new motion. I put the joysticks at rest and then pressed a button. The result was that the robot stopped.

Does anybody know how to fix the problem?

Yes. I tried this, and here’s your issue. To implement this you need a while(true) in pre-auton a while(true) loop will keep it stuck not being able to read the comp. Control code. Put it in driver control.

I had the whole thing inside a while(true) loop when I had the issue.

1 Like

So just move it inside your main drive control loop.

Last season I had it set such that the controller was used to choose the autonomous. I had that set in a bunch of external functions that I called pre autonomous. They looped while the auton had not yet been chosen. Looking back, I would have just put it in drive control.

Post the code, that’s really the only way to know what’s happening.

Putting the code into the driver controlled loop would just mean that the code would implement during the driver controlled period, right? I’m trying to choose an autonomous before the match starts.

When running a competition program not hooked up to field controls, just running the program automatically runs the driver loop. You need to be hooked up to the competition switch to run auton not at a field. Look at it like this:

When running a COMPETITION program:

No field controls:

  1. Pre auton (should just calibrate sensors and not run any important code)
  2. Driver control loop forever until the program ends

Comp switch/field controls:

  1. Pre auton (should just calibrate sensors and not run any important code)

  2. Auton for 15 seconds

  3. Driver control for 1:45


The pre auton will (should) run in a few milliseconds right when you start the program. If you start the program, pick an auton while in driver mode while not at the field, then go to the field, and connect to the field controls, it will be put in the disabled state, then once auton starts it will do the correct auton.

The problem is that the rest of your code does not run before initialize completes running.
Initialize is meant for just that - initializing things. It could be used to set up a display, calibrate sensors, or do other non-blocking tasks.
As soon as you have a loop in initialize, it will prevent the rest of the code from executing, as it will never stop running.
There are two approaches to making a auton selector -

  1. Blocking on-boot selector: this does not run the rest of the code until an option is selected and the selector exits
  2. Drivercontrol selector: all the selection is done in driver mode
  3. Continuous asynchronous selector: is not specific to any competition mode, and runs in the background

Option 3 is by far the best option. It does not block drivercontrol from running when the program starts, and it is always available (works in disable and is not limited to driver).
To do this, you need to learn how to make tasks. It is not complicated in VCS, just read the API.
Then, you can start the task in initialize, and it will forever run in the background. When autonomous is executed, just run the currently selected auton.

However, this might not be your problem. If it isn’t, you have a logic problem, and you are making code separation mistakes. The display should never interfere with motors.
The problem is that you are probably checking for joystick updates while waiting for button presses, and the waiting for buttons is preventing the driver loop from running.
Again, tasks are your friends in things like this.
Probably show us your code, but it is likely you need to separate things instead of having everything in one giant loop.

Ok, but every time I start the program up again, it resets all status. They have you start your program before the competition starts and it runs until the field directors start the match and the robots run autonomous. I am trying to make the autonomous selection screen run while connected to the field but after I start my program and before the field director starts the match.

Thank you. I will look up tasks.

I’m assuming the OP is using VCS or VEXcode
(they didn’t specify but mentioned vex::task::sleep(300) )
(also, assuming the driver and autonomous functions are named as per the template provided)

You can block in pre_auton without issue for both solutions.

This code would run ok, driver etc. will still be started.

Code
// A global instance of vex::brain used for printing to the V5 brain screen
vex::brain       Brain;
// A global instance of vex::competition
vex::competition Competition;

// define your global instances of motors and other devices here

void pre_auton( void ) {
  int count = 0;

  while(1) {
    Brain.Screen.printAt(10, 20, "%d", count++ );
    vex::task::sleep(100);
  }
}

void autonomous( void ) {
}

void usercontrol( void ) {
  Brain.Screen.printAt(10, 40, "Driver");
  while (1) {
    vex::task::sleep(20);
  }
}

int main() {
    //Run the pre-autonomous function. 
    pre_auton();

    //Set up callbacks for autonomous and driver control periods.
    Competition.autonomous( autonomous );
    Competition.drivercontrol( usercontrol );
           
    while(1) {
      vex::task::sleep(100);
    }           
}

Are you sure?

int main() {
    //Run the pre-autonomous function. 
    pre_auton();

    //Set up callbacks for autonomous and driver control periods.
    Competition.autonomous( autonomous );
    Competition.drivercontrol( usercontrol );

If pre_auton is blocking, won’t the callbacks for autonomous and usercontrol never be registered?

as long as they have the default names, registering the callbacks is actually superfluous, we check during the Competition constructor to see if they have been defined, like this.

    if( ::autonomous )
      competition::_autonomous_callback    = ::autonomous;
    if( ::usercontrol )
      competition::_drivercontrol_callback = ::usercontrol;

we define them extern as follows

    extern void __attribute__((weak)) autonomous( void );
    extern void __attribute__((weak)) usercontrol( void );

Oh ok that’s interesting.
Well, seems the OP’s issue was something else.

we can only guess until we can see the code.

I had the same issue that OP did last year. I had a while(true) loop in pre-auton that would make the robot get stuck in the loop forever and not run driver code. That was when it wasn’t connected to a comp switch, so it didn’t have anything telling it to run driver or auton.

When I connected it to a comp switch it worked fine.

Could it be that on default, when pre_auton completes, it automatically runs usercontrol, but if pre_auton is blocking, it will only run usercontrol with a competition switch plugged in?
That seems to be what I am hearing from @TaranMayer
I would have to test myself, but I feel like there might actually be a problem with blocking in pre_auton.

1 Like

As far as I remember, as long as the controller is connected then driver control should run if there is no comp switch. This is with recent versions of vexos, the initial couple of releases from last August did have some bugs in the competition control code, but that was all sorted out by October IIRC.

Alright.
Just curious, does this mean there is no guarantee that pre_auton will run before usercontrol (such as for initializing dynamic memory)?
It seems like there could be conflicts if pre_auton and usercontrol are not sequentially executed.
Personally, in PROS, I do a lot of dynamic initialization on boot, and take a second or two to go through calibration etc. If usercontrol were to run before I was done initializing, I would have many segfaults.