Pre-Auton Not Running

I’m not too sure why but my pre-auton code doesn’t run and it skips straight to user control even though there is a while loop in my pre-auton code to prevent it from doing so. Confused as according to my understanding, pre-auton starts once the code file is run (I’ve never used pre-auton before so I may be wrong on this).

bool autonSelect = true;

void init_vector(){

  init_obj(red1);
  init_obj(red2);
  init_obj(red3);
  init_obj(red4);
  init_obj(blue1);

}

void pre_auton( void ) {
  
  Brain.Screen.clearScreen();

  Controller.ButtonA.pressed(upAuto);
  Controller.ButtonB.pressed(downAuto);

  init_vector();
  
  autonList[Auto].toString();

  while(autonSelect){

    if(Controller.ButtonL1.pressing() || Controller.ButtonR1.pressing()){
      autonSelect = false;
    }

    vex::task::sleep(20);
  }

}



void autonomous( void ) {


}



void usercontrol( void ) {

    // Turn on animation
  enable_bounce = true;
  vex::task bouncy(bounce);

  while (true) {
    
    LMotor.spin(vex::directionType::fwd, Controller.Axis1.value(), vex::velocityUnits::pct);
 
    vex::task::sleep(20); //Sleep the task for a short amount of time to prevent wasted resources. 
  }
}



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

    
    //Run the pre-autonomous function. 
    pre_auton();
       
    //Prevent main from exiting with an infinite loop.                        
    while(1) {
      vex::task::sleep(100);//Sleep the task for a short amount of time to prevent wasted resources.
    }    
       
}

User control is in a separate thread (or task if you prefer that terminology). They will both be running at the same time.

5 Likes

How would I split the threads? I’m not too sure as I don’t want to mess with the competition threads incorrectly and then my robot does “illegal” things or just doesn’t work at the right times.

1 Like

Sorry to revive but I’ve been going at this for a few hours now and I can’t seem to figure it out. Would someone mind helping?

2 Likes

The thread “main” always runs and it is starting two threads “autonomous” and “usercontrol” then it executes the pre_auton function. So main will be running when other threads are running.

The thread “main” starts up and runs whatever code is in it. The thread “autonomous” is only activated when either field control or the competition switch is selecting autonomous and isEnabled==true. The thread “usercontrol” runs if autonomous is not activated and isEnabled==true. See here for how to see this in code. So the only time you will see the function “pre_auton” running from main w/o usercontrol is when the robot is disabled.

If you want to see pre_auton run w/o the other two threads then set the competition switch to “disabled”.

If you don’t want to see pre_auton in driver (usercontrol) then use the link above to see if what mode the robot is in (look at isDriverControl() member function.

hopefully @jpearman can correct me if i’ve made a mistake or embellished too much. Also, these are listed on https://api.vexcode.cloud/ but not described are they useful in any way?

void test_auton (void)
void test_driver (void)
void test_disable (void)
5 Likes

So using that information, I tried preventing the “autonomous” and “usercontrol” threads from being created but it still didn’t work and I’m not too sure why. I basically added a variable that is checked in the main thread. This boolean is then updated in “pre-auton”, which is now called first, and only then is it supposed to allow the creation of the other threads.

bool autonSelect = true;
bool createComp = false;

void init_vector(){

  init_obj(red1);
  init_obj(red2);
  init_obj(red3);
  init_obj(red4);
  init_obj(blue1);

}

void pre_auton( void ) {
  
  Brain.Screen.clearScreen();

  Controller.ButtonA.pressed(upAuto);
  Controller.ButtonB.pressed(downAuto);

  init_vector();
  
  autonList[Auto].toString();

  while(autonSelect){
    
      // Debug
    Controller.Screen.clearScreen();
    Controller.Screen.print(createComp);

      // Exit loop after auton set
    if(Controller.ButtonL1.pressing() || Controller.ButtonR1.pressing()){

        // Print selected info
      autonList[Auto].select();

        // Exit Pre-Auton loop
      autonSelect = false;

        // Enable comp threads
      createComp = true;

        // Debug
      Controller.Screen.clearScreen();
      Controller.Screen.print(createComp);
    }

  }

}



void autonomous( void ) {


}



void usercontrol( void ) {

    // Turn on animation
  enable_bounce = true;
  //vex::task bouncy(bounce);

  while (1) {

    LMotor.spin(vex::directionType::fwd, Controller.Axis1.value(), vex::velocityUnits::pct);
 
    vex::task::sleep(20); //Sleep the task for a short amount of time to prevent wasted resources. 
  }
}



int main() {

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

    //Prevent main from exiting with an infinite loop.                        
    while(1) {

        // threads when enabled
      if(createComp == true){
        
          //Set up callbacks for autonomous and driver control periods.
        Competition.autonomous( autonomous );
        Competition.drivercontrol( usercontrol );

        createComp = false;

      }

      vex::task::sleep(100);//Sleep the task for a short amount of time to prevent wasted resources.
    }    
       
}

do you want pre_auton to run before driver control?

Yeah, I wanted pre_auton to be the first thing run when the program runs. Only after pre_auton is done do I want the program to behave “normally” again. I was just about to say, unless you know of a different way, I figured out if I just base the while loop in the “usercontrol” thread off the variable updated by the pre_auton function I could then activate the program “normally”. Of course if you know a better method that would be nice.

If you plan to use this for competition then leave main and autonomous as is and just wait for pre_auton to be done in usercontrol before doing anything. Hopefully this is what you are doing.

bool pre_auton_done = false;

void pre_auton(vod) {
  //my code
  pre_auton_done = true;
}

void usercontrol( void ) {
  // wait for pre_auton to complete before running driver code
  while (!pre_auton_done) {
    vex::task::sleep(100);
  }
  
  while (1) {
   // drive code
  }
} 
4 Likes

Yes that’s exactly what I did. Thanks for the help on understanding the processes though!

1 Like