AdvancedDcMotor
Overview
AdvancedDcMotor
is a powerful wrapper around DcMotorEx
that provides enhanced control, safety, and performance features.
Key Features
✅ Caching
Reduces redundant hardware access, improving loop-time performance (thanks to CachingHardware).
🔒 Current Limiting
Automatically cuts power if the motor is using too much current.
🎯 Custom PIDF
Allows for usage of a fully custom PIDF controller.
🔗 Linked Motors
Keeps multiple motors in sync with the primary motor. Useful for motors that are mechanically linked.
📏 Ticks/Units
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
You must call AdvancedDcMotor.updateAll()
in your loop()
method for this to work. This method will update all instantiated motors.
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);
You must call AdvancedDcMotor.updateAll()
in your loop()
method for this to work. This method will update all instantiated motors.
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