How to set up action when two buttons are pressed

I’m trying to get mechanum wheels to work with the arrow keys, and i cant figure out how to do the diagonals by holding down two buttons.
Here is my code.

/*----------------------------------------------------------------------------*/
/*                                                                            */
/*    Module:       main.cpp                                                  */
/*    Author:       {author}                                                  */
/*    Created:                                                         */
/*    Description:  V5 project                                                */
/*                                                                            */
/*----------------------------------------------------------------------------*/

// Include the V5 Library
#include "vex.h"
  void Forwards (){
      FrontRight.spin(forward);
      FrontLeft.spin(forward);
      RearRight.spin(forward);
      RearLeft.spin(forward);
      while (Controller1.ButtonUp.pressing()){
          wait(1,msec);
      }
      FrontRight.stop();
      FrontLeft.stop();
      RearRight.stop();
      RearLeft.stop();
}
void Back (){
      FrontRight.spin(reverse);
      FrontLeft.spin(reverse);
      RearRight.spin(reverse);
      RearLeft.spin(reverse);
      while (Controller1.ButtonDown.pressing()){
          wait(1,msec);
      }
      FrontRight.stop();
      FrontLeft.stop();
      RearRight.stop();
      RearLeft.stop();
}
void Right (){
      FrontRight.spin(reverse);
      FrontLeft.spin(forward);
      RearRight.spin(forward);
      RearLeft.spin(reverse);
      while (Controller1.ButtonRight.pressing()){
          wait(1,msec);
      }
      FrontRight.stop();
      FrontLeft.stop();
      RearRight.stop();
      RearLeft.stop();
}
void Left (){
      FrontRight.spin(forward);
      FrontLeft.spin(reverse);
      RearRight.spin(reverse);
      RearLeft.spin(forward);
      while (Controller1.ButtonLeft.pressing()){
          wait(1,msec);
      }
      FrontRight.stop();
      FrontLeft.stop();
      RearRight.stop();
      RearLeft.stop();
}
void NW (){
      FrontLeft.spin(forward);
      RearRight.spin(forward);
      while ((Controller1.ButtonLeft.pressing())&(Controller1.ButtonUp.pressing())){
          wait(1,msec);
      }
      FrontRight.stop();
      FrontLeft.stop();
      RearRight.stop();
      RearLeft.stop();
}
// Allows for easier use of the VEX Library
using namespace vex;
int main() {
    FrontRight.setVelocity(100, percent);
    FrontLeft.setVelocity(100, percent);
    RearRight.setVelocity(100, percent);
    RearLeft.setVelocity(100, percent);
    FrontRight.setStopping(hold);
    FrontLeft.setStopping(hold);
    RearRight.setStopping(hold);
    RearLeft.setStopping(hold);

  Controller1.ButtonUp.pressed(Forwards);
  Controller1.ButtonDown.pressed(Back);
  Controller1.ButtonLeft.pressed(Left);
  Controller1.ButtonRight.pressed(Right);
  while ((Controller1.ButtonRight.pressed())&(Controller1.ButtonRight.pressed())) {
    NW();
  }
}

The problem here is that your code will not continue to execute…

When the program gets to this line…

the while statement will be false (assuming you don’t have the buttons pressed right at the beginning), and then the program will end. Instead of this line, you could use an infinite loop with an if statement inside. Pseudocode would look like this.

while(true)
{
if(buttons are pressed)
{
function();
}}.

If you do it this way, however, you may run into some problems with the up and left functions running at the same time as the NW function. I’d recommend making all of your functions with this method, that way you could specify to only run the cardinal direction function if only that one button is pressed.

Hope that helps.

1 Like

I am curious, why don’t you want the drive on the joysticks?

They probably do, but a measured distance can help with strafing between known points for a skills run.

1 Like

I’m used to using WASD to play games, I’m a pc gamer.
Also easier to code like this

Ok thank you, I’ll try it asap

I tried just doing one function like this to test it before i go all- in and it had some weird issues building.

/*----------------------------------------------------------------------------*/
/*                                                                            */
/*    Module:       main.cpp                                                  */
/*    Author:       {author}                                                  */
/*    Created:                                                         */
/*    Description:  V5 project                                                */
/*                                                                            */
/*----------------------------------------------------------------------------*/

// Include the V5 Library
#include "vex.h"
  void Forwards (){
      FrontRight.spin(forward);
      FrontLeft.spin(forward);
      RearRight.spin(forward);
      RearLeft.spin(forward);
      while (Controller1.ButtonUp.pressing()){
          wait(1,msec);
      }
      FrontRight.stop();
      FrontLeft.stop();
      RearRight.stop();
      RearLeft.stop();
}
void Back (){
      FrontRight.spin(reverse);
      FrontLeft.spin(reverse);
      RearRight.spin(reverse);
      RearLeft.spin(reverse);
      while (Controller1.ButtonDown.pressing()){
          wait(1,msec);
      }
      FrontRight.stop();
      FrontLeft.stop();
      RearRight.stop();
      RearLeft.stop();
}
void Right (){
      FrontRight.spin(reverse);
      FrontLeft.spin(forward);
      RearRight.spin(forward);
      RearLeft.spin(reverse);
      while (Controller1.ButtonRight.pressing()){
          wait(1,msec);
      }
      FrontRight.stop();
      FrontLeft.stop();
      RearRight.stop();
      RearLeft.stop();
}
void Left (){
      FrontRight.spin(forward);
      FrontLeft.spin(reverse);
      RearRight.spin(reverse);
      RearLeft.spin(forward);
      while (Controller1.ButtonLeft.pressing()){
          wait(1,msec);
      }
      FrontRight.stop();
      FrontLeft.stop();
      RearRight.stop();
      RearLeft.stop();
}
void NW (){
      FrontLeft.spin(forward);
      RearRight.spin(forward);
      while (Controller1.ButtonLeft.pressing()&Controller1.ButtonUp.pressing()){
          wait(1,msec);
      }
      FrontRight.stop();
      FrontLeft.stop();
      RearRight.stop();
      RearLeft.stop();
}
// Allows for easier use of the VEX Library
using namespace vex;
int main() {
    FrontRight.setVelocity(100, percent);
    FrontLeft.setVelocity(100, percent);
    RearRight.setVelocity(100, percent);
    RearLeft.setVelocity(100, percent);
    FrontRight.setStopping(hold);
    FrontLeft.setStopping(hold);
    RearRight.setStopping(hold);
    RearLeft.setStopping(hold);

  Controller1.ButtonUp.pressed(Forwards);
  Controller1.ButtonDown.pressed(Back);
  Controller1.ButtonLeft.pressed(Left);
  Controller1.ButtonRight.pressed(Right);

while(true){
if((Controller1.ButtonUp.pressed())&(Controller1.ButtonUp.pressed()));
{
NW;
}}
}

Screenshot 2021-03-17 10.50.18

You need parenthases on your method call

NW();

Also, you need to use .pressing, not .pressed on your if statement. .pressed is only used for callbacks, which is not what you’re using in the if statement

3 Likes

Tried and got this result.
One less error thankfully but still has a couple.
Screenshot 2021-03-17 10.53.12

I edited the previous post. See that

1 Like

It built with no issues now, just need to test it
thank you for the help

3 Likes

So I think you are structuring your program completely wrong. Likely because you started with the .pressed function provided by VEXCode that sets up callback functions. (I think its their fault not yours)

https://api.vexcode.cloud/v5/html/classvex_1_1controller_1_1button.html#abf18ef5acb8d3885d206d5f5bfa02cf3
The pressed function sets up a function to call whenever that button is pressed, it has no concept of other criteria. It is an event based paradigm.
The “pressing” function however returns a value 1 when the button is down and 0 when it not being pressed. This 1 and 0 lets us easily evaluate all 4 button states to control the robot.

side_axis = left_button.pressing() - right_button.pressing()
straight_axis = forward_button.pressing() - down_button.pressing()

right_wheels = straight_axis *100 + side_axis * 100
left_wheels = straight_axis *100 - side_axis * 100

In 4 lines I did everything you wanted above. You just need to apply those values as percent to the wheels in a loop. It is the same as controlling with the analog sticks just we only ever have full power and no power.

10 Likes

I’m a little confused as to how that works with the mechanum wheels.

Also, this is my code after following the other members advice. It works kind of, janky controls however, works half the time.

/*----------------------------------------------------------------------------*/
/*                                                                            */
/*    Module:       main.cpp                                                  */
/*    Author:       Serial                                                    */
/*    Created:      3/17/2021                                                 */
/*    Description:  WASD Mecha Wheel                                          */
/*                                                                            */
/*----------------------------------------------------------------------------*/

// Include the V5 Library
#include "vex.h"
  void NW (){
      FrontLeft.spin(forward);
      RearRight.spin(forward);
      while (Controller1.ButtonLeft.pressing()&Controller1.ButtonUp.pressing()){
          wait(1,msec);
      }
      FrontRight.stop();
      FrontLeft.stop();
      RearRight.stop();
      RearLeft.stop();
}
void SE (){
      FrontLeft.spin(reverse);
      RearRight.spin(reverse);
      while ((Controller1.ButtonRight.pressing())&(Controller1.ButtonDown.pressing())){
          wait(1,msec);
      }
      FrontRight.stop();
      FrontLeft.stop();
      RearRight.stop();
      RearLeft.stop();
}
void NE (){
      FrontRight.spin(forward);
      RearLeft.spin(forward);
      while ((Controller1.ButtonRight.pressing())&(Controller1.ButtonUp.pressing())){
          wait(1,msec);
      }
      FrontRight.stop();
      FrontLeft.stop();
      RearRight.stop();
      RearLeft.stop();
}
void SW (){
      FrontRight.spin(reverse);
      RearLeft.spin(reverse);
      while ((Controller1.ButtonLeft.pressing())&(Controller1.ButtonDown.pressing())){
          wait(1,msec);
      }
      FrontRight.stop();
      FrontLeft.stop();
      RearRight.stop();
      RearLeft.stop();
}
  void Forwards (){
      FrontRight.spin(forward);
      FrontLeft.spin(forward);
      RearRight.spin(forward);
      RearLeft.spin(forward);
      
      while (Controller1.ButtonUp.pressing()){
          Controller1.ButtonRight.pressed(NW);
      Controller1.ButtonLeft.pressed(NE);
          wait(1,msec);
      }
      FrontRight.stop();
      FrontLeft.stop();
      RearRight.stop();
      RearLeft.stop();
}
void Back (){
      FrontRight.spin(reverse);
      FrontLeft.spin(reverse);
      RearRight.spin(reverse);
      RearLeft.spin(reverse);
      
      while (Controller1.ButtonDown.pressing()){
          Controller1.ButtonLeft.pressed(SW);
      Controller1.ButtonRight.pressed(SE);
          wait(1,msec);
      }
      FrontRight.stop();
      FrontLeft.stop();
      RearRight.stop();
      RearLeft.stop();
}
void Right (){
      FrontRight.spin(reverse);
      FrontLeft.spin(forward);
      RearRight.spin(forward);
      RearLeft.spin(reverse);
      
      while (Controller1.ButtonRight.pressing()){
          Controller1.ButtonUp.pressed(NE);
      Controller1.ButtonDown.pressed(SE);
          wait(1,msec);
      }
      FrontRight.stop();
      FrontLeft.stop();
      RearRight.stop();
      RearLeft.stop();
}
void Left (){
      FrontRight.spin(forward);
      FrontLeft.spin(reverse);
      RearRight.spin(reverse);
      RearLeft.spin(forward);
      
      while (Controller1.ButtonLeft.pressing()){
          Controller1.ButtonUp.pressed(NW);
      Controller1.ButtonDown.pressed(SW);
          wait(1,msec);
      }
      FrontRight.stop();
      FrontLeft.stop();
      RearRight.stop();
      RearLeft.stop();
}

// Allows for easier use of the VEX Library
using namespace vex;
int main() {
    FrontRight.setVelocity(100, percent);
    FrontLeft.setVelocity(100, percent);
    RearRight.setVelocity(100, percent);
    RearLeft.setVelocity(100, percent);
    FrontRight.setStopping(hold);
    FrontLeft.setStopping(hold);
    RearRight.setStopping(hold);
    RearLeft.setStopping(hold);

while(true){
if((Controller1.ButtonUp.pressing())&(Controller1.ButtonLeft.pressing())){
NW();
}
if((Controller1.ButtonUp.pressing())&(Controller1.ButtonRight.pressing())){
NE();
}
if((Controller1.ButtonDown.pressing())&(Controller1.ButtonLeft.pressing())){
SW();
}
if((Controller1.ButtonDown.pressing())&(Controller1.ButtonRight.pressing())){
SE();
}
if(Controller1.ButtonUp.pressing()){
Forwards();
}
if(Controller1.ButtonDown.pressing()){
Back();
}
if(Controller1.ButtonLeft.pressing()){
Left();
}
if(Controller1.ButtonRight.pressing()){
Right();
}}
}```

If you look at the pattern of all of your functions they are essentially doing the same thing. @tabor473 is showing you how to do it mathematically and it also resolves your issue with multiple buttons.

If the Left button equals one (1) and the right button equals one (1) then you have three states.
Left pressed is 1 - 0 = 1, right pressed is 0 - 1 = -1, and no buttons is 0 - 0 = 0.
Left is 1, Right is -1, and nothing is 0

Now do the same math for Up and Down.

Then multiply the values by 100 (to convert to motor percent) and combine the button values together, and you have all 8 directions covered.

//Create variables to hold values
int side_axis;
int straight_axis;
int left_wheels;
int right_wheels;

  while (1) {

//If left button pressed (1) minus right button pressed (1). Left is +1, neither 0, Right is -1;
side_axis = Controller1.ButtonLeft.pressing() - Controller1.ButtonRight.pressing();
//If up button (1) minus down button (1). Up is +1, neither 0, Down is -1;
straight_axis = Controller1.ButtonUp.pressing() - Controller1.ButtonDown.pressing();

//Multiply the directions above by 100 (to percent values) and combine them.
right_wheels = straight_axis * 100 + side_axis * 100;
left_wheels =  straight_axis * 100 - side_axis * 100;

LF.spin(forward, left_wheels, percent);
LR.spin(forward, left_wheels, percent);
RF.spin(forward, right_wheels, percent);
RR.spin(forward, right_wheels, percent);  

This code has not been tested but it should give you an idea as to how you can simplify.

5 Likes