Movement while shooting

I have a question how can I make it where I can still move while running my shooter code This is how it looks now
if(Controller1.ButtonL1.pressing()) {
Shooter.setVelocity(95, percent);
Pusher.setVelocity(100,percent);
Shooter.spin(reverse);
wait(4,seconds);
Pusher.spin(reverse);
wait(1,seconds);
Pusher.spin(forward);
wait(1,seconds);
Pusher.spin(reverse);
wait(1,seconds);
Pusher.spin(forward);
wait(1,seconds);
Pusher.stop();
Shooter.stop();
} else if (Controller1.ButtonL2.pressing()){
Shooter.spin(forward);
} else {
Shooter.stop();
}

That’s not really true, else if is more about allowing the first conditional test to have priority over the second. so in this case.

if (Controller1.ButtonL1.pressing()) {
  // code
}
else
if (Controller1.ButtonL2.pressing()) {
  // more code
} else {
 // even more code
}

ButtonL1.pressing() will have priority over ButtonL2.pressing() if both are true. Without the else the poor motor may get conflicting commands if both buttons are pressed (which won’t happen with OP code due to all the waits in the first test)

4 Likes

The only thing I can think of would be to use a separate thread for the shooter code but I’m not quite sure how threads work so I am using the example and hoping I guessed how it works. Here is what I got.

/*----------------------------------------------------------------------------*/
/*                                                                            */
/*    Module:       main.cpp                                                  */
/*    Author:       VEX                                                       */
/*    Created:      Sun Oct 06 2019                                           */
/*    Description:  This program will run a thread parallel (at the same time */
/*                  to main.                                                  */
/*                                                                            */
/*----------------------------------------------------------------------------*/

// ---- START VEXCODE CONFIGURED DEVICES ----
// Robot Configuration:
// [Name]               [Type]        [Port(s)]
// Controller1          controller                    
// Shooter              motor         1               
// Pusher               motor         2               
// ---- END VEXCODE CONFIGURED DEVICES ----

#include "vex.h"

using namespace vex;

bool Stop = 0;

int myThreadCallback() {
    //turns off ability to control shooter
    Stop = 1;
    Shooter.setVelocity(95, percent);
    Pusher.setVelocity(100,percent);
    Shooter.spin(reverse);
    wait(4,seconds);
    Pusher.spin(reverse);
    wait(1,seconds);
    Pusher.spin(forward);
    wait(1,seconds);
    Pusher.spin(reverse);
    wait(1,seconds);
    Pusher.spin(forward);
    wait(1,seconds);
    Pusher.stop();
    Shooter.stop();
    //turns on ability to control shooter
    Stop = 0;
    //Might be left over from loop example but keep just in case
    this_thread::sleep_for(25);
  //ends the thread
  return 0;
}

int main() {
  // Initializing Robot Configuration. DO NOT REMOVE!
  vexcodeInit();
  while(true){
    
    if(Controller1.ButtonL1.pressing()){
      //Not sure if this can be ran more than once since I can't test it
      thread myThread = thread(myThreadCallback);
    }
    //won't run if the thread code is still running to avoid messing it up
    else if(Controller1.ButtonL2.pressing() && !Stop){
      Shooter.spin(forward);
    }
    else {
    Shooter.stop();
    }

    wait(25, msec);
  }
}

I am unsure if the wait command would work correctly in this way but no reason to not try it.
If someone knows how to make this better / work please share.

1 Like

I would recommend using a function callback so the wait statements don’t interrupt your driving.
The code would look like this.
Inside main:

controller1.buttonL1.pressed(fireShooter)

Outside main as a function

void fireShooter(){ 
The code to shoot goes here
}

Does a callback make a separate task for the function it calls? Cause if it doesn’t then the wait timers would still affect the driving

1 Like

Alright so I have had the chance to test it myself and I found that you would probably want a latch in there as well to keep it from starting the thread 100 times from one push, here is the new code.

/*----------------------------------------------------------------------------*/
/*                                                                            */
/*    Module:       main.cpp                                                  */
/*    Author:       NinjaPenguin16                                            */
/*    Created:      1/12/2023                                                 */
/*    Description:  This program will run a thread parallel (at the same time */
/*                  to main.                                                  */
/*                                                                            */
/*----------------------------------------------------------------------------*/

// ---- START VEXCODE CONFIGURED DEVICES ----
// Robot Configuration:
// [Name]               [Type]        [Port(s)]
// Controller1          controller                    
// Shooter              motor         1               
// Pusher               motor         2               
// ---- END VEXCODE CONFIGURED DEVICES ----

#include "vex.h"

using namespace vex;

bool Stop = 0;

int myThreadCallback() {
    //turns off ability to control shooter
    Stop = 1;
    Shooter.setVelocity(95, percent);
    Pusher.setVelocity(100,percent);
    Shooter.spin(reverse);
    wait(4,seconds);
    Pusher.spin(reverse);
    wait(1,seconds);
    Pusher.spin(forward);
    wait(1,seconds);
    Pusher.spin(reverse);
    wait(1,seconds);
    Pusher.spin(forward);
    wait(1,seconds);
    Pusher.stop();
    Shooter.stop();
    //turns on ability to control shooter
    Stop = 0;
    //Might be left over from loop example but keep just in case
    this_thread::sleep_for(20);
  //ends the thread
  return 0;
}

bool latchL1 = 0;
bool toggleL1 = 0;

int main() {
  // Initializing Robot Configuration. DO NOT REMOVE!
  vexcodeInit();
  while(true){

    //Starts thread and puts down latch when L1 pushed
    if(Controller1.ButtonL1.pressing() && !latchL1){
      thread myThread = thread(myThreadCallback);
      latchL1 = true;
    }
    //
    else if(!Controller1.ButtonL1.pressing() && latchL1){
      latchL1 = false;
    }

    //won't run if the thread code is still running to avoid messing it up
    if(Controller1.ButtonL2.pressing() && !Stop){
      Shooter.spin(forward);
    }
    else {
    Shooter.stop();
    }

    wait(20, msec);
  }
}

Only trouble you should have now is integrating it into your code.

1 Like

It does make a seperate task and is much simpler than creating a thread.

nice, thanks for the clarification :+1:

1 Like

You would need to add a way for it to disable user control of the launcher while the callback is running though right? So you can’t accidentally mess it up?

1 Like