Problem with Field-Oriented Mecanum Drive; Bot Automatically Rotates

So this year our team decided to attempt to use a field-oriented mecanum drivetrain. We are using a gyroscope sensor (NavX), using the driveCartesian() method in the MecanumDrive class with gyro input (now a Rotation2d object instead of a double value) as a fourth argument.

Now my understanding of field-oriented control – and I imagine this should work the same way with mecanum wheels – is that the robot uses not itself as a frame of reference for its motion control but wherever the gyro reading is 0, so as to facilitate driving. If the bot were rotated sideways, for instance, moving the robot forward would move the robot forward relative to the DRIVER, and not simply sideways.

In actuality, what seems to be happening with our robot is that no matter which way the robot is facing, if the joystick is moved in a certain direction, the robot will begin driving in that direction but ALSO automatically rotate itself to face the direction it is driving. It’s honestly pretty cool, but definitely not what we are looking for.

So far, I haven’t come across any other teams who have this problem… could this potentially be some weird quirk in the code, or is this the intended function of the driveCartesian() method and my understanding of field-oriented drive is incorrect? Any way to make the drivetrain work as I want it to?

Thanks so much!

1 Like

Can you share your source code?

1 Like

Thank you! Here’s the code:
5923-RobotCode2023/src/main/java/frc/robot at main · Weaboo45/5923-RobotCode2023 (
This primarily involves the MecanumDrivetrain subsystem, DriveMecanum command, RobotContainer

Here’s a video I took to demonstrate the problem:
Strafe pls - YouTube

1 Like

Thanks. The video is really helpful. A couple of quick observations.

  • It’s hard to make out in the video, but it looks like your wheels may be on wrong. For a mecanum drive, the rollers on the four wheels should form an “X” shape from above, and an O shape from underneath. Squinting at your video, it looks to my old eyes as if they’re an O shape from above.
  • Problems of this sort might be caused by mixing up the CAN ids, which I cannot check in source code. You may want to use the Phoenix Tuner to blink each controller for identification.

Edit: I see you’re using Talon SRX on the front and Victor SPX on the back. (I’m not sure what motors you’re using.) I don’t have a specific reason why this shouldn’t work, but it’s not normal practice to mix different controllers within a drive train.

I don’t know how you have it wired, but it’s common to have to invert the motors (and possibly encoders) on one side. You might want to put the robot on blocks, and just spin all the motors forwards to check both their direction and what their encoders think is going on.

Another potential issue besides the one bovlb identified is that you have two drivetrain classes, both of which appear to be controlling the same motors.

Actually three (instances), but only one is scheduled at once, I think. None of your subsystems call addRequirements(), which is bad.

  private final DriveTank driveTank = new DriveTank(drivetrain, () -> xbox.getLeftY(), () -> xbox.getRightY());
  private final DriveMecanum fieldDriveXbox = new DriveMecanum(mecanumDrivetrain, () -> xbox.getLeftY(), ()-> xbox.getLeftX(),
      ()-> xbox.getRightX(), ()-> ahrs.getRotation2d());
  private final DriveMecanum fieldDriveJoystick = new DriveMecanum(mecanumDrivetrain, () -> stick.getX(), ()-> stick.getY(),
      ()-> stick.getTwist(), ()-> ahrs.getRotation2d());

If you want to be able to use either a joystick or an Xbox controller without having to switch explicitly, you could use something like:

  private final DriveMecanum fieldDrive = new DriveMecanum(
    ()-> xbox.getLeftY() + stick.getX(), 
    ()-> xbox.getLeftX() + stick.getY(),
    ()-> xbox.getRightX() + stick.getTwist(), 
    ()-> ahrs.getRotation2d());

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.