Lesson 8.3: Using ZeroPowerBehavior.BRAKE to Hold Position Better
Technical Context
When power is set to 0.0, a heavy mechanism, such as a lift or a high-momentum drivetrain, may continue to move due to gravity or inertia. BRAKE can reduce that motion, but a lift that must maintain a measured height generally needs closed-loop position control, a counterbalance, or both.
Why BRAKE and FLOAT Feel Different on a Real Robot
The setZeroPowerBehavior() method defines how the Expansion Hub motor controller handles a zero-power state. There are two options:
BRAKE: electrically connects the motor terminals so rotation generates a torque opposing that rotation. It can slow coasting or gravity-driven motion, but it does not command a fixed shaft angle.FLOAT(the default): disconnects the motor terminals, allowing the motor shaft to spin freely until mechanical friction brings it to rest. This is also called "coast."
The behavior is configured on the hardware controller, which changes the zero-power behavior of the motor port. Neither mode substitutes for an encoder-based position controller, and a sufficiently large external load can move a motor configured for BRAKE.
Set ZeroPowerBehavior in init() immediately after mapping so the intended response is configured before the match begins.
Annotated Code
package org.firstinspires.ftc.teamcode;
import com.qualcomm.robotcore.eventloop.opmode.OpMode;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import com.qualcomm.robotcore.hardware.DcMotor;
@TeleOp(name="Brake_Demo")
public class BrakeDemo extends OpMode {
private DcMotor armMotor;
@Override
public void init() {
armMotor = hardwareMap.get(DcMotor.class, "arm_motor");
// Configure passive electrical braking at a zero-power command.
armMotor.setZeroPowerBehavior(DcMotor.ZeroPowerBehavior.BRAKE);
armMotor.setPower(0);
telemetry.addData("Status", "Arm motor: BRAKE mode active");
}
@Override
public void loop() {
armMotor.setPower(-gamepad1.left_stick_y);
// When the stick returns to 0, BRAKE resists continued motion.
// It does not guarantee that a loaded arm stays at one angle.
}
}
BRAKE Inside a Closed-Loop Actuator
BunyipsLib's holdable actuator does more than select BRAKE: it captures the current encoder position, enters RUN_TO_POSITION, and supplies power to the controller.
this.motor = (DcMotorEx) motor;
this.motor.setZeroPowerBehavior(DcMotor.ZeroPowerBehavior.BRAKE);
this.motor.setTargetPosition(this.motor.getCurrentPosition());
this.motor.setMode(DcMotor.RunMode.RUN_TO_POSITION);
this.motor.setPower(autoPower);
This distinction matters on a lift. BRAKE resists motion electrically at zero command; it is not by itself a position controller. The remaining lines establish active encoder-based holding. Excerpted from BunyipsLib's HoldableActuator.java at a pinned commit under the MIT License.
Fill-in-the-Blank Practice
- To allow a robot to coast smoothly to a stop, set the behavior to
DcMotor.ZeroPowerBehavior.__________. - The
BRAKEbehavior is implemented by the__________on the robot, not just the software. The port circuit is physically reconfigured. - To resist coasting at zero power, choose the
__________behavior; measured position holding requires additional closed-loop control.
Show answers
FLOAT- Control Hub / Expansion Hub (the hardware motor controller)
BRAKE
Simulator Challenge
Use the simulator below to practice switching a lift between BRAKE and FLOAT while watching the effect live.
BRAKE resists motion electrically. A counterbalance reduces the gravity load mechanically and can reduce the motor effort needed to maintain height.
See Lesson 8.4: Springs, Tubing, and Counterbalancing Static Loads.
Ready to move on?
Only mark complete if you genuinely understand the material. Your progress will be saved in this browser.
Stuck on this lesson?
Ask about anything on this page. It can see which lesson you have open and which part you are reading.