Setting up a mecanum drive train with okapi

I’m trying to get my mecanum drive train working in okapi. I’m a bit confused about the ChassisControllerFactory part. I have a few specific questions about the inputs I need to give it.

  • were should you measure your wheel distance? In the middle of booth of the wheels or on the edges of the wheels?

  • how do you use external quad encoders and gyros?

  • what does this do and what do the numbers change? IterativePosPIDController::Gains{0.001, 0, 0.0001},

  • can you set up field oriented drive? and how?

okapi::ChassisControllerPID chassis = okapi::ChassisControllerFactory::create(driveL, driveR,
  IterativePosPIDController::Gains{0.001, 0, 0.0001},
  IterativePosPIDController::Gains{0.001, 0, 0.0001},
  okapi::AbstractMotor::gearset::green, {4.125_in, 16.25_in});

A mechanum is controlled in exactly the same way as a x-base, so use the x-base controller.

You should measure the turning point (center) of the wheels. Okapi uses this information to calculate how much to turn the wheels to turn the robot a certain number of degrees.

As for the rest of your questions, the answers are slightly difficult to answer with the current version of okapi. You would have to do construct the chassis controller yourself without using the factory.

The alternative is to use the new beta version of okapilib.

Okapi v4 allows you to do this:

void opcontrol() {
  auto chassis = ChassisControllerBuilder().withMotors(1, -2, -3, 4).build();
  auto xModel = std::dynamic_pointer_cast<XDriveModel>(chassis->getModel());
  Controller controller(ControllerId::master);
  while (true) {

Note: The model pointer stuff is currently necessary to use the xArcade method of the chassis controller.

Okapi does not implement field-centric drive, it is up to you to measure the heading of the robot and do math yourself.

For your last question, those are PID gains. If you do not know what PID is, you should really find out.
The first one is the PID gains for moving forward, and the second is for turning.

With okapi v3, you are able to omit those gains and instead use the V5 motor’s built-in PID. With the okapi v4 example I showed above, it uses integrated by default.
It is only when you apply custom gains that the chassis controller switches to use custom, okapi PID controllers


I’ve gotten everything working with the mechanum drive using okapi V4.0.2 and Pros V3.1.4 Except for autonomous driving. When I try to use the chassis->moveDistance(1_ft); command the drive train starts up fine and drives the correct distance but when about 1-4 inches away it starts to skid side ways. I’ve been playing around with it and one motor runs a lot longer than the others. I’ve replaced both back motors which were the ones causing the skidding and nothing changed.

Chassis and Motor declaration:

ADIEncoder leftEncoder('E', 'F');
ADIEncoder rightEncoder('C', 'D');
Motor frontLeftMotor(9, false, AbstractMotor::gearset::red, AbstractMotor::encoderUnits::degrees);
Motor backLeftMotor(10, false, AbstractMotor::gearset::red, AbstractMotor::encoderUnits::degrees);
Motor frontRightMotor(2, true, AbstractMotor::gearset::red, AbstractMotor::encoderUnits::degrees);
Motor backRightMotor(3, true, AbstractMotor::gearset::red, AbstractMotor::encoderUnits::degrees);
std::shared_ptr<ChassisController> chassis = ChassisControllerBuilder()
  .withMotors(frontLeftMotor, frontRightMotor, backRightMotor, backLeftMotor)
  .withSensors(leftEncoder, rightEncoder)
  .withDimensions(AbstractMotor::gearset::green, {{4_in, 10_in}, imev5GreenTPR})
          TimeUtilFactory::createDefault().getTimer(), // It needs a Timer
          "/usd/Chassis_Diagnostics", // Output to the SDCard
          Logger::LogLevel::debug // Most verbose log level


void redSmall() {

I noticed you are defining your motors with the red cartridges and then in your chassis builder defining them as green cartridges (the .withDimensions). Make them both the same and try it out.

1 Like

I switched to a custom PID and that fixed it. But I think you solved an other problem were my drive train moved twice the distance that I had told it to. Thanks.