Field Oriented Control

Out of the numerous reasons why holonomic drivetrains are superior to traditional tank drives, one key reason is that field oriented control is possible. For those that do not know what field oriented control is, you can take a look at this video

Note

Okapi must be version 4.5.0 or higher for this to work.

To use Okapi’s fieldOrientedXArcade, you must cast chassis to an XDriveModel.

std::shared_ptr<XDriveModel> model = std::static_pointer_cast<XDriveModel> (chassis->getModel());

Next, use a controller and the fieldOrientedXArcade method to move the chassis.

 1void opcontrol() {
 2    Controller controller = Controller();
 3    while(true) {
 4        model->fieldOrientedXArcade(master.getAnalog(ControllerAnalog::leftY),
 5                                    master.getAnalog(ControllerAnalog::leftX),
 6                                    master.getAnalog(ControllerAnalog::rightX),
 7                                    // you can use an IMU as an alternative
 8                                    controller->getPose().theta.convert(degree),
 9                                    0.05);
10
11        pros::delay(10);
12    }
13}

Here is a complete example:

 1/** Create Okapi OdomChassisController */
 2std::shared_ptr<OdomChassisController> chassis = ChassisControllerBuilder()
 3    .withMotors(
 4        1,  // Top left
 5        -2, // Top right (reversed)
 6        -3, // Bottom right (reversed)
 7        4   // Bottom left
 8    )
 9    .withSensors(
10        ADIEncoder{'A', 'B'}, // left encoder in ADI ports A & B
11        ADIEncoder{'C', 'D', true},  // right encoder in ADI ports C & D (reversed)
12        ADIEncoder{'E', 'F'}  // middle encoder in ADI ports E & F
13    )
14    // specify the tracking wheels diameter (2.75 in), track (7 in), and TPR (360)
15    // specify the middle encoder distance (1 in) and diameter (2.75 in)
16    .withOdometry({{2.75_in, 7_in, 1_in, 2.75_in}, quadEncoderTPR})
17    .buildOdometry();
18
19/** Cast OdomChassisController model to XDriveModel */
20std::shared_ptr<XDriveModel> model = std::static_pointer_cast<XDriveModel> (chassis->getModel());
21
22/** Opcontrol: uses field oriented control to control the chassis */
23void opcontrol() {
24
25    Controller controller = Controller();
26    while(true) {
27        model->fieldOrientedXArcade(master.getAnalog(ControllerAnalog::leftY),
28                                    master.getAnalog(ControllerAnalog::leftX),
29                                    master.getAnalog(ControllerAnalog::rightX),
30                                    // you can use an IMU as an alternative
31                                    controller->getPose().theta.convert(degree),
32                                    0.05);
33
34        pros::delay(10);
35    }
36}

More information regarding the HolonomicLib API can be found here