Mecanum Drive isn't working

Screenshot 2021-10-27 130412
This is my current code (Y1 is Axis 1, X1 is Axis 4, and X2 is Axis 3.) Everything I found on the web says it should be working, but it just isn’t. Can anyone help?

Hi @polarize, welcome to the VEX Forum!

Could you post the complete contents of your main.cpp? That will likely get you help a lot faster.

Be sure to include triple backtics (```) before and after your code for formatting.

A bit more information about what you’re doing would also be helpful – what does your drivetrain look like, and what kind of control scheme are you trying to implement?

4 Likes

understood, thank you! I’ll post it in a sec.


using namespace vex;

#include "robot-config.h"

competition Competition;

int Y1 = 0;
int X1 = 0;
int X2 = 0;
int threshold = 10;
int p = 0;

void userControl() {

while (1) {
    float CH1 = Controller1.Axis3.position() * -1;
    float CH2 = Controller1.Axis2.position() * -1;
    float CH3 = Controller1.Axis1.position() * -1;
    float CH4 = Controller1.Axis4.position() * -1;

    if (fabs(CH3) >= threshold) {
      Y1 = CH3;
    } 
else {
      Y1 = 0;
    }
    if (fabs(CH1) >= threshold) {
      X2 = CH1;
    } 
else {
      X2 = 0;
    }
    if (fabs(CH4) >= threshold) {
      X1 = CH4;
    } 
else {
      X1 = 0;
    }
    
    if (p == 0) {
      FR.spin(fwd, Y1 - X2 - X1, pct);
      BR.spin(fwd, Y1 - X2 + X1, pct);
      FL.spin(fwd, Y1 + X2 + X1, pct);
      BL.spin(fwd, Y1 + X2 - X1, pct);
    } 
  }
}

int main() {
  vexcodeInit();
  Competition.drivercontrol(userControl);
  while (true) {
    userControl();
  }
}

You shouldn’t be calling userControl in the infinite loop in main – the call to Competition.drivercontrol is enough to tell the robot’s firmware to start the userControl function at the appropriate time.

(do leave that infinite loop in main in place though, with just a short delay – it needs to be there to prevent main from exiting)

4 Likes

Thank you, but I tried it and the Mecanums still don’t work. Do you have any other suggestions?

In what way does it not work? Do the motors move at all?

Are the wheels mounted in the correct arrangement? (There are left-handed and right-handed mecanum wheels, your drivetrain should have two of each, with the two wheels of each type mounted diagonally opposite from each other)

4 Likes

So just a reminder that the rollers need to make an X. There are left and right wheels that need to be mounted correctly.

1 Like

The wheels are mounted correctly. The issue is that FR isn’t moving when I spin. (it’s moving when I go forwards and backwards.)

essentially, what’s happening is that the bot moves forwards and backwards, but not side to side, and one of the wheels isn’t working on the spin (it works in fwd/rev.) Does anyone have any working Mecanum code I can take a look at to see what’s different?

is it an issue with the bot or my code?

Take a look at this thread.

3 Likes

Hi, I tried the solution in that thread, and now everything works fine, except I can’t move from side to side. Is there any solution?

  • Did you choose the Tank or Arcade drive option? (Examples below)

  • Can you post your code so we can review it? (Be sure to use ``` [three accent marks in the upper left corner of the keyboard] before and after your code so the VexForum site formats it properly)

Tank

int left = Controller.Axis3.position(vex::percent);
int right = Controller.Axis2.position(vex::percent);
int sideways = Controller.Axis4.position(vex::percent);

//you can also calculate this...
int turn =    (right - left) * 0.5;
int forward = (right + left) * 0.5;

frontRight.spin(vex::forward, right - sideways, vex::percent);
frontLeft.spin(vex::forward,  left  + sideways, vex::percent);
backRight.spin(vex::forward,  right + sideways, vex::percent);
backLeft.spin(vex::forward,   left  - sideways, vex::percent);

Arcade Drive

int forward = Controller.Axis3.position(vex::percent);
int sideways = Controller.Axis4.position(vex::percent);
int turn = Controller.Axis1.position(vex::percent);

frontRight.spin(vex::forward, forward - sideways + turn, vex::percent);
frontLeft.spin(vex::forward,  forward + sideways - turn, vex::percent);
backRight.spin(vex::forward,  forward + sideways + turn, vex::percent);
backLeft.spin(vex::forward,   forward - sideways - turn, vex::percent);
3 Likes

Why do you multiply by -1?
Why there is an infinite do-loop in useControl?
You do not have wait() in the code.

1 Like

hi here’s the code (I removed comments) Most of the stuff there is forklifts and should not affect the drivetrain (I think)

#include "vex.h"

using namespace vex;

#include "robot-config.h"

competition Competition;

int threshold = 10;
int p = 0;

int liftSpeed = 50;


void precision() {
  if (p == 0) {
    p = 1;
  } else {
    p = 0;
  }
}

void userControl() {

  while (1) {
    // Controller1.ButtonA.pressed(precision);

    if(Controller1.ButtonUp.pressing() and Controller1.ButtonR1.pressing()){
      ForkF.spin(forward, liftSpeed, pct);
      waitUntil(!Controller1.ButtonR1.pressing());
      ForkF.setVelocity(0, percent);
      ForkF.setStopping(brake);
  }
    if(Controller1.ButtonUp.pressing() and Controller1.ButtonR2.pressing()){
      ForkF.spin(reverse, liftSpeed, pct);
      waitUntil(!Controller1.ButtonR2.pressing());
      ForkF.setVelocity(0, percent);
      ForkF.setStopping(brake);
  }
    if(Controller1.ButtonDown.pressing() and Controller1.ButtonR1.pressing()){
     if(Controller1.ButtonDown.pressing()){
     ForkB.spin(forward, liftSpeed, pct);
     }
     waitUntil(!Controller1.ButtonR1.pressing());
     ForkB.setVelocity(0, percent);
     ForkB.setStopping(brake);
   }
   if(Controller1.ButtonDown.pressing() and Controller1.ButtonR2.pressing()){
     ForkB.spin(reverse, liftSpeed, pct);
     waitUntil(!Controller1.ButtonR2.pressing());
     ForkB.setVelocity(0, percent);
     ForkB.setStopping(brake);
   }
   if(Controller1.ButtonLeft.pressing() and Controller1.ButtonR1.pressing()){
      ForkL.spin(forward, liftSpeed, pct);
      waitUntil(!Controller1.ButtonR1.pressing());
      ForkL.setVelocity(0, percent);
      ForkL.setStopping(brake);
    }
    if(Controller1.ButtonLeft.pressing() and Controller1.ButtonR2.pressing()){
      ForkL.spin(reverse, liftSpeed, pct);
      waitUntil(!Controller1.ButtonR2.pressing());
      ForkL.setVelocity(0, percent);
      ForkL.setStopping(brake);
    }
    if(Controller1.ButtonRight.pressing() and Controller1.ButtonR1.pressing()){
      ForkR.spin(forward, liftSpeed, pct);
      waitUntil(!Controller1.ButtonR1.pressing());
      ForkR.setVelocity(0, percent);
      ForkR.setStopping(brake);
    }
    if(Controller1.ButtonRight.pressing() and Controller1.ButtonR2.pressing()){
      ForkR.spin(reverse, liftSpeed, pct);
      waitUntil(!Controller1.ButtonR2.pressing());
      ForkR.setVelocity(0, percent);
      ForkR.setStopping(brake);   
    }
    
    int front = Controller1.Axis3.position(vex::percent);
    int side = Controller1.Axis4.position(vex::percent);
    int turn = Controller1.Axis1.position(vex::percent); 

    FR.spin(vex::forward, front - side + turn, vex::percent);
    FL.spin(vex::forward, front + side - turn, vex::percent); 
    BR.spin(vex::forward, front + side + turn, vex::percent); 
    BL.spin(vex::forward, front - side - turn, vex::percent); 
  } 
}

int main() {
  vexcodeInit();
  Competition.drivercontrol(userControl);
  while (true) {
    userControl();
  }
}

Hi, the first thing is no longer an issue but could you explain what you meant by the other two? Are those needed? It doesn’t seem to affect the movement of the robot.

Since you are adding userControl to the Competition.drivercontrol, you don’t need it in the main() while loop. Also, adding a short wait allows the processor to switch to other tasks.

Below is the default competition template:

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

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

  // Prevent main from exiting with an infinite loop.
  while (true) {
    //userControl(); <-- Not needed here.
    wait(100, msec);  //<-- Helps to have a wait here to free up the processor.
  }
}
4 Likes

The code looks good from what I can see. The sideways motion is on the left stick (#4). That’s not working?

1 Like

Hudsonville_Robotics beat me by a few seconds.

usually, the FL should be all plus.

FL.spin(vex::forward, front + side + turn, vex::percent);
front_left  = drive	+ strafe + rotate;
rear_left   = drive	- strafe + rotate;
front_right	= drive	- strafe - rotate;
rear_right  = drive	+ strafe - rotate;
3 Likes