AdvancedDcMotor

Overview

AdvancedDcMotor is a powerful wrapper around DcMotorEx that provides enhanced control, safety, and performance features.


Key Features

Feature

Caching

Description

Reduces redundant hardware access, improving loop-time performance (thanks to CachingHardware).

Feature

🔒 Current Limiting

Description

Automatically cuts power if the motor is using too much current.

Feature

🎯 Custom PIDF

Description

Allows for usage of a fully custom PIDF controller.

Feature

🔗 Linked Motors

Description

Keeps multiple motors in sync with the primary motor. Useful for motors that are mechanically linked.

Feature

📏 Ticks/Units

Description

Converts between encoder ticks and physical units like inches/degrees.


Usage

Setup

To use AdvancedDcMotor, simply wrap a DcMotorEx motor and provide a name:

AdvancedDcMotor motor = new AdvancedDcMotor("motor", hardwareMap.get(DcMotorEx.class, "motor"));

That's it! You now have access to all the features AdvancedDcMotor provides.

Setting a Current Limit

Motor protection is critical for ensuring your robot's longevity. AdvancedDcMotor supports automatic current limiting: if the motor’s current draw exceeds a defined threshold, power is automatically cut to prevent potential damage.

motor.setCurrentLimit(3.0, CurrentUnit.AMPS); // Cut power if over 3A

Using Custom PID

The built-in RUN_TO_POSITION mode often delivers suboptimal performance due to its fixed 20Hz update rate and default factory-tuned PID coefficients. Using a custom PID controller can significantly improve responsiveness and accuracy.

To use custom PID, simply enable custom PIDF, set the coefficients, and set the mode to RUN_TO_POSITION. This will override the default RUN_TO_POSITION mode and use the custom controller instead.

motor.setUseCustomPIDF(true);
motor.setCustomPIDFCoefficients(1.0, 0.0, 0.1, 0.0);

motor.setTargetPosition(1000);
motor.setMode(DcMotor.RunMode.RUN_TO_POSITION);

Using a Custom PIDF Controller

You can optionally supply the motor with a custom PIDF controller, allowing full control over how motor power is calculated. This is especially useful for mechanisms like pivoting arms, where the feedforward (F) term could vary dynamically based on the arm’s angle to compensate for gravity.

motor = new AdvancedDcMotor("motor", hardwareMap.get(DcMotorEx.class, "motor"));
motor.setMode(DcMotor.RunMode.RUN_TO_POSITION);
motor.setUseCustomPIDF(true);
motor.setCustomPIDFCoefficients(kP, kI, kD, 0);

motor.setCustomPIDFController((motor, target) -> {
    int pos = motor.getCurrentPosition();
    PIDFController controller = motor.getPIDFController();

    double pid = controller.calculate(pos, target);

    int angle = topPos - pos;
    double f = angle * kF;

    return pid + f;
});

Linking Motors

Linking motors is especially useful for mechanisms where multiple motors are mechanically connected—such as multiple motors on an intake or lift.

Simply pass more than one motor to AdvancedDcMotor. This ensures that all linked motors automatically mirror the behavior (power, mode, current limit) of the primary motor.

DcMotorEx motor1 = hardwareMap.get(DcMotorEx.class, "motor1");
DcMotorEx motor2 = hardwareMap.get(DcMotorEx.class, "motor2");

AdvancedDcMotor linkedMotors = new AdvancedDcMotor("linkedMotors", motor1, motor2);

Units Conversion

AdvancedDcMotor supports easy conversion between encoder ticks and real-world units—such as inches, degrees, etc.

Set the scale:

motor.setUnitsPerTick(0.01);  // e.g., 1 tick = 0.01 inch
// --- OR ---
motor.setTicksPerUnit(100.0); // e.g., 1 inch = 100 ticks

Convert values:

double inches = motor.ticksToUnits(500.0); // → 5 inches
int ticks = motor.unitsToTicks(2.0);       // → 200 ticks

Last updated