On This Page

Coast mode

This document explains how to set neutral/idle mode so that the robot is safe in use, but moveable when disabled.

Background 🔗

When a motor controller is told to setting a motor’s power to zero, this is known as idle mode (also known as neutral mode). There are two different flavors of idle mode: coast mode and brake mode.

So which do we want to use on an FRC robot? The answer, in most cases, is brake mode. A drive train in brake mode will stop quickly when commanded (say before hitting an obstacle). This reduces wear and tear on your practice space and any unobservant humans present. A motor-actuated elevator or climber will, in brake mode, lock and resist descent, meaning you may be able to get away without adding brakes. A drive train stopped on a ramp will stay there even after being disabled. Remember that end game points are often assessed some number of seconds after the end of the match.

The main circumstance where you want your robot to be in coast mode is when you are positioning your robot by hand (while it is turned on, but disabled). It’s very hard to move an FRC robot in brake mode. When you’re perfecting your autonomous routines, you’re going to be spending a lot of time repositioning your robot.

In this case, it is tempting to say that the robot’s drive train should be in brake mode while enabled, but go into coast mode when disabled. You might get away with this, but one day you’ll disable your robot when it is going at high speed, and then everyone will be unpleasantly surprised that it just keeps on going. This has actually happened in some FRC competition matches, where a robot in motion at the end of the match keeps moving, collides with other robots, and either loses end game points for their alliance or gains fouls as a result.

So what should we do? The best compromise seems to be to enable coast mode only once the robot has been disabled for several seconds, and keep it in brake mode at all other times. That gives it enough time to stop, allows enough time for post-match judging, but still makes it easy to move your robot. Fortunately, with appropriate configuration, idle mode commands can be sent to your motors while the robot is disabled.

Method 🔗

So how do we do this? You need to do three things:

Drive sybsystem 🔗

The exact command required will vary depending on your drivetrain and the motor controllers. Here I give code for Spark Max and Talon FX, assuming two motors on each side.

SparkMAX 🔗

/**
 * Sets idle mode to be either brake mode or coast mode.
 *
 * @param brake If true, sets brake mode, otherwise sets coast mode
 */
public void setBrakeMode(boolean brake) {
    IdleMode mode = brake ? IdleMode.kBrake : IdleMode.kCoast;
    m_leftLeader.setIdleMode(mode);
    m_leftFollower.setIdleMode(mode);
    m_rightLeader.setIdleMode(mode);
    m_rightFollower.setIdleMode(mode);
}

Talon FX/SRX (including Falcon 500) 🔗

public void setBrakeMode(boolean brake) {
    NeutralMode mode = brake ? NeutralMode.Brake : NeutralMode.Coast;
    m_leftLeader.setNeutralMode(mode);
    m_leftFollower.setNeutralMode(mode);
    m_rightLeader.setNeutralMode(mode);
    m_rightFollower.setNeutralMode(mode);
}

Set brake mode on init 🔗

In Robot.java, in both autonomousInit and teleopInit, add the following line:

m_robotContainer.m_driveSubsystem.setBrakeMode(true); // Enable brake mode

You may need to change this code, depending on where your drive subsystem is created and stored. You may also need to change RobotContainer.m_driveSubsystem to be public.

Create trigger 🔗

In Robot.java, at the end of robotInit, add the following code:

// Turn brake mode off shortly after the robot is disabled

new Trigger(this::isEnabled) // Create a trigger that is active when the robot is enabled
    .negate() // Negate the trigger, so it is active when the robot is disabled
    .debounce(3) // Delay action until robot has been disabled for a certain time
    .onTrue( // Finally take action
        new InstantCommand( // Instant command will execute our "initialize" method and finish immediately
            () -> m_robotContainer.m_driveSubsystem.setBrakeMode(false), // Enable coast mode in drive train
            m_robotContainer.m_driveSubsystem) // command requires subsystem
            .ignoringDisable(true)); // This command can run when the robot is disabled

Notes:

References 🔗