Class StateMachine

java.lang.Object
org.wpilib.command3.StateMachine
All Implemented Interfaces:
Command

public final class StateMachine extends Object implements Command
A declarative state machine that can be used to implement complex command routines. State machine setup should be done in stages: first, a state machine is created and its name is set; second, states are added to the state machine using addState(Command); third, transitions between states can be specified using StateMachine.State.switchTo(State):
// Declare the state machine
StateMachine stateMachine = new StateMachine("Example State Machine");

// Declare states
State state1 = stateMachine.addState(...);
State state2 = stateMachine.addState(...);
State state3 = stateMachine.addState(...);

// Set initial state
stateMachine.setInitialState(state1);

// Declare transitions
state1.switchTo(state2).when(...);
state2.switchTo(state3).when(...);

Every state in a state machine runs a single command. While a state's command is running, the state machine will continually check all transitions that can be triggered from that state. If a transition is triggered, the state machine will cancel the state's command and move to the next state as defined by that transition. If no transition is triggered by the time the command completes, the state machine will exit unless a StateMachine.TransitionNeedsConditionStage.whenComplete() transition was specified from that state:

// switch from state1 to state2 when foo is true
state1.switchTo(state2).when(() -> foo == true);

// but if foo never becomes true, switch to state3 when state1 finishes
state1.switchTo(state3).whenComplete();

// no transitions are defined from state2 or state3,
// so the state machine will exit when either state completes
  • Constructor Details

    • StateMachine

      public StateMachine(String name)
      Creates a new state machine.
      Parameters:
      name - The name of the state machine. Cannot be null. This will appear in telemetry as the name of the state machine.
  • Method Details

    • name

      public String name()
      Description copied from interface: Command
      The name of the command.
      Specified by:
      name in interface Command
      Returns:
      the name of the command
    • requirements

      public Set<Mechanism> requirements()
      Description copied from interface: Command
      The mechanisms required by the command. This is used by the scheduler to determine if two commands conflict with each other. No mechanism may be required by more than one running command at a time.
      Specified by:
      requirements in interface Command
      Returns:
      the set of mechanisms required by the command
    • addState

      public StateMachine.State addState(Command command)
      Adds a new state to the state machine. State transitions can be specified on the new state using StateMachine.State.switchTo(State).
      Parameters:
      command - The command for the state to execute. Cannot be null.
      Returns:
      The newly created state.
    • switchFromAny

      Sets up a transition from any of the given states to a specific state. If no states are given, the transition will apply to all states in the state machine at the time this method is called.
      stateMachine.switchFromAny(state1, state2, state3).to(state4).when(() -> foo == true);
      
      // Functionally equivalent to:
      state1.switchTo(state4).when(() -> foo == true);
      state2.switchTo(state4).when(() -> foo == true);
      state3.switchTo(state4).when(() -> foo == true);
      
      // Set up an early exit condition from any state
      stateMachine.switchFromAny().toExitStateMachine().when(() -> bar == true);
      
      // Functionally equivalent to:
      state1.exitStateMachine().when(() -> bar == true);
      state2.exitStateMachine().when(() -> bar == true);
      state3.exitStateMachine().when(() -> bar == true);
      state4.exitStateMachine().when(() -> bar == true);
      
      Parameters:
      states - The states to transition from.
      Returns:
      A builder for the transition.
    • setInitialState

      public void setInitialState(StateMachine.State initialState)
      Sets the initial state for the state machine. This must be called before the state machine is scheduled. Failure to do so will result in an IllegalStateException being thrown when the state machine is started. Usage of this method is enforced by the WPILib compiler plugin; creating a state machine and neglecting to call this method will result in a compilation error.
      Parameters:
      initialState - The new initial state. Cannot be null.
      See Also:
    • run

      public void run(Coroutine coroutine)
      Description copied from interface: Command
      Runs the command. Commands that need to periodically run until a goal state is reached should simply run a while loop like while (!atGoal()) { ... } and call Coroutine.yield() at the end of the loop.

      Warning: any loops in a command must call coroutine.yield(). Failure to do so will prevent anything else in your robot code from running. Commands are opt-in collaborative constructs; don't be greedy!

      Specified by:
      run in interface Command
      Parameters:
      coroutine - the coroutine backing the command's execution