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 tablestateMachine.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 emergency3. 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
- WPILib Official Documentation - The definitive baseline resource.