Doubleshot as a Task

I currently have double shot as a function but my driver has complained that it stops his control while it is running. I have been told to use a task to run doubleshot instead but I dont know how to do this. My current code is included below. Can anyone offer insight into this?

int doubleshota;


void doubleshotbackdriver() {
  Adjuster.spin(vex::directionType::fwd, 100, vex::velocityUnits::pct);
  vex::task::sleep(600);
  Adjuster.stop(vex::brakeType::coast);
  Punch.rotateFor(.2, vex::rotationUnits::rev, 100, vex::velocityUnits::pct,true);
  Intake.spin(vex::directionType::fwd, 50, vex::velocityUnits::pct);
  Adjuster.rotateFor(-2, vex::rotationUnits::rev, 100, vex::velocityUnits::pct, false);
  vex::task::sleep(100);
  Punch.rotateFor(1, vex::rotationUnits::rev, 100, vex::velocityUnits::pct,true);
  Intake.stop(vex::brakeType::coast);
}


//Double Shot
    if (Controller1.ButtonY.pressing() && doubleshota == 0) {
      doubleshota = 1;
     } else if (Controller1.ButtonY.pressing() && doubleshota == 1) {
      doubleshotbackdriver();
      } else {
      doubleshota = 0;
    }

Instantiate a thread object with the function for the thread to execute as an argument. So

doubleshotbackdriver();

Becomes

vex::thread t(doubleshotbackdriver);

Then you need some logic to prevent it from being started multiple times, like some global boolean flag:

bool doubleShooting = false;

void doubleshotbackdriver() {
    //etc.
    doubleShooting = false;
}

//somewhere in driver control:
if (conditionsForDoubleShot && !doubleShooting) {
    doubleShooting = true;
    vex::thread t(doubleshotbackdriver);
}
1 Like

Still having some issues, This doesnt seem to be doing anything.

bool doubleShooting = false;

void doubleshotfrontdriver() {
  Adjuster.spin(vex::directionType::fwd, 100, vex::velocityUnits::pct);
  vex::task::sleep(600);  
  Adjuster.stop(vex::brakeType::coast);
  Punch.rotateFor(.2, vex::rotationUnits::rev, 100, vex::velocityUnits::pct,true);
  Intake.spin(vex::directionType::fwd, 50, vex::velocityUnits::pct);
  Adjuster.rotateFor(-2, vex::rotationUnits::rev, 100, vex::velocityUnits::pct, false);
  vex::task::sleep(100);
  Punch.rotateFor(1, vex::rotationUnits::rev, 100, vex::velocityUnits::pct,true);
  Intake.stop(vex::brakeType::coast);
  Punch.rotateFor(fwd,1,rotationUnits::rev);
  doubleShooting = false;
}

//somewhere in driver control:
    if (Controller1.ButtonY.pressing() && doubleShooting==false) {
    doubleShooting = true;
    vex::thread t(doubleshotfrontdriver);
}

Are you controlling those motors (Adjuster, Punch, Intake) anywhere else in the code? You would need to disable those other control schema while doubleshotfrontdriver is running. Previously you accomplished this by not allowing any other code to run while it was running, but now you need a way to distinguish that it is running and not execute those other control statements when it is. Luckily, you already have a flag being used for that purpose, so you can check its state before attempting any of your other control statements for those motors.

I managed to accomplish this by moving the third portion to the top of the while loop. Thanks for the help!

Okay so I now have a slightly related issue, I use vex::task::sleep(); in my doubleshot and its keeping the thread from completing. Is there a different option for threads?

How sure are you? Does it complete if you take out the sleep? Because your function can definitely stall if it isn’t able to complete one of the rotateFor moves.