Skip to content

Tutorial 02: More than one command

James Hagborg edited this page Dec 17, 2018 · 1 revision

As it is, there's only one command, and it's always running. To demonstrate the power of commands, lets see how we can change the code so the driving only works while the user is holding a button. This requires two parts: changing the default command to a "stop command" which turns the motors off, and adding a button in OIMap that triggers the drive command.

You might wonder if we really need a stop command, or if we can get the robot to stop by just not running any command. This can be dangerous, because if we don't update the motors, they will just run at whatever speed we last left them. (In reality, there is a MotorSafety feature which will stop certain motors if you don't update them for a timeout, but that isn't always enabled, so I wouldn't rely on it).

1. Create a stop command

In DriveSubsystem.java, add the following method:

public Command stopCmd() {
    return QuickCommand.continuous(this, () -> {
        robotDrive.tankDrive(0, 0);
    });
}

2. Change the default command to stop

Again in DriveSubsystem.java, change the initDefaultCommand method:

protected void initDefaultCommand() {
    setDefaultCommand(stopCmd());
}

At this point, you can run the code, and nothing should happen, even when you press the joysticks. Progress!

3. Bind the drive command to a button

In OIMap.java, add this entry to LeftJoystick (or whatever joystick you like):

public static class LeftDriver {
    @WhileHeld(1) public final Command drive = Robot.drive.driveCmd();
}

This does what it looks like: it runs the drive command as long as button 1 on the left joystick is held.

Now, if you run the code, pushing the joysticks should only work while button 1 on the left joystick is held. Otherwise, the robot should stop.

Recap

Although I haven't described anything formally, hopefully you have a feel for how commands work now. We have two commands, defined in driveCmd() and stopCmd(). We can bind commands to buttons in OIMap.java, or we can use setDefaultCommand in a subsystem. By default, stopCmd is always running. When you press a button, driveCmd starts running, and it kicks stopCmd off. When you release the button, driveCmd finishes, and so the default command, stopCmd, starts up again. We'll discuss this in more detail later, but first, I should show you how to make multiple subsystems.