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