Skip to content

State Machine Logic

Coordinating multiple mechanisms (like an intake, a pivot, and a shooter) is incredibly complex. If you use simple if-statements, you’ll eventually end up with “spaghetti code” where the robot crashes into itself. MARSLib uses MARSStateMachine within the overarching MARSSuperstructure to manage these transitions safely.

1. Defining Your States

Start by creating an enum that represents every possible state of your superstructure for the 2026 game.

public enum SuperstructureState {
STOW,
INTAKING_FLOOR,
LOADED_FUEL_BALL,
HUB_SCORE,
UNJAMMING
}

2. The Transition Table

In your Subsystem’s constructor, you define which transitions are legal. This prevents the robot from trying to shoot into the Hub if it hasn’t successfully acquired a Fuel Ball yet!

stateMachine = new MARSStateMachine<>("Superstructure", SuperstructureState.class, SuperstructureState.STOW);
// Setup the table
stateMachine.addTransition(STOW, INTAKING_FLOOR);
stateMachine.addTransition(INTAKING_FLOOR, LOADED_FUEL_BALL);
stateMachine.addBidirectional(LOADED_FUEL_BALL, HUB_SCORE);
stateMachine.addWildcardTo(STOW); // Can always go back to STOW in an emergency

3. Entry & Exit Actions

Often, you want something to happen exactly once when a state changes. For example, when entering INTAKING_FLOOR, you want to deploy the pivot.

stateMachine.setEntryAction(INTAKING_FLOOR, () -> {
pivot.setGoal(IntakeConstants.DEPLOY_POS);
intakeWheels.run(1.0);
});
stateMachine.setExitAction(INTAKING_FLOOR, () -> {
pivot.setGoal(IntakeConstants.STOW_POS);
});

4. Live Mermaid Visualization

One of the most powerful features of MARSStateMachine is that it automatically generates a Mermaid.js flowchart. This graph is sent over telemetry and can be viewed live in AdvantageScope.




📖 Further Reading & External Resources