The last example showed two simple commands and how to connect them with the user interface, but the commands were simple: they set a servo position and immediately finished. In practice, robot commands often need to run continuously until something happens; for example, a command to raise an arm might start a motor moving and continue until some time has passed or an encoder indicates that the arm has moved a certain distance or a limit switch is pressed. WPILib commands make this easy. Even better, you can string several such commands together in a !CommandGroup to effect complex behaviors. Commands can be grouped together to run in sequence for example, when the X button is pressed, the following code will run the servo open command, allow time for it to finish, and then run the servo close command. The !OpenCommand adds a Timer to allow the servo motor time to complete moving to the open position before the !CloseCommand is run : Constants.java {{{ package frc.robot; public final class Constants { public static int SERVO_PORT = 0; // PWM port for servo motor public static int OPEN_BUTTON = 1; // A button opens mechanism public static int CLOSE_BUTTON = 2; // B button closes mechanism public static int OPEN_THEN_CLOSE_BUTTON = 3; // X button opens then closes } }}} !ServoSubSystem.java: {{{ package frc.robot.subsystems; import edu.wpi.first.wpilibj2.command.SubsystemBase; import frc.robot.Constants; import edu.wpi.first.wpilibj.Servo; public class ServoSubsystem extends SubsystemBase { private Servo servo; private static ServoSubsystem instance = null; private ServoSubsystem() { servo = new Servo(Constants.SERVO_PORT); } // Singleton design pattern public static ServoSubsystem getInstance() { if (instance == null) { instance = new ServoSubsystem(); } return instance; } public void setAngle(double degrees) { servo.setAngle(degrees); } } }}} !OpenCommand.java {{{ package frc.robot.commands; import edu.wpi.first.wpilibj2.command.CommandBase; import edu.wpi.first.wpilibj2.command.SubsystemBase; import frc.robot.subsystems.ServoSubsystem; import edu.wpi.first.wpilibj.Timer; public class OpenCommand extends CommandBase { private Timer delayTimer; public OpenCommand(SubsystemBase servoSubsystem) { delayTimer = new Timer(); addRequirements(servoSubsystem); } @Override public void initialize() { ServoSubsystem.getInstance().setAngle(30); // set servo to open position delayTimer.start(); } @Override public boolean isFinished() { return delayTimer.hasPeriodPassed(0.5); // allow 500ms for command to finish } } }}} !CloseCommand.java {{{ package frc.robot.commands; import edu.wpi.first.wpilibj2.command.CommandBase; import edu.wpi.first.wpilibj2.command.SubsystemBase; import frc.robot.subsystems.ServoSubsystem; public class CloseCommand extends CommandBase { public CloseCommand(SubsystemBase servoSubsystem) { addRequirements(servoSubsystem); } @Override public boolean isFinished() { ServoSubsystem.getInstance().setAngle(120); // set servo to closed position return true; // and then finish } } }}} !OpenThenCloseCommand.java: {{{ package frc.robot.commands; import edu.wpi.first.wpilibj2.command.SequentialCommandGroup; import edu.wpi.first.wpilibj2.command.SubsystemBase; public class OpenThenCloseCommand extends SequentialCommandGroup { public OpenThenCloseCommand(SubsystemBase servoSubsystem) { this.addCommands(new OpenCommand(servoSubsystem), new CloseCommand(servoSubsystem)); } } }}} !RobotContainer.java: {{{ package frc.robot; import edu.wpi.first.wpilibj.XboxController; import edu.wpi.first.wpilibj2.command.button.Button; import edu.wpi.first.wpilibj2.command.button.JoystickButton; import edu.wpi.first.wpilibj2.command.Command; import frc.robot.subsystems.ServoSubsystem; import frc.robot.commands.OpenCommand; import frc.robot.commands.CloseCommand; import frc.robot.commands.OpenThenCloseCommand; public class RobotContainer { private final ServoSubsystem m_servo = ServoSubsystem.getInstance(); private final XboxController xbox; private final Button openButton, closeButton, openThenCloseButton; public RobotContainer() { xbox = new XboxController(0); openButton = new JoystickButton(xbox, Constants.OPEN_BUTTON); closeButton = new JoystickButton(xbox, Constants.CLOSE_BUTTON); openThenCloseButton = new JoystickButton(xbox, Constants.OPEN_THEN_CLOSE_BUTTON); // Configure the button bindings configureButtonBindings(); } private void configureButtonBindings() { openButton.whenPressed(new OpenCommand(m_servo)); closeButton.whenPressed(new CloseCommand(m_servo)); openThenCloseButton.whenPressed(new OpenThenCloseCommand(m_servo)); } public Command getAutonomousCommand() { return null; } } }}}