Skip to content

State Machine Logic

Coordinating multiple mechanisms is where Innovation meets Teamwork. To prevent “spaghetti code” and physical collisions, MARSLib employs the MARSStateMachine within the overarching MARSSuperstructure. This ensures that every movement is intentional and safe, allowing the whole team to trust the robot’s logic during the highest pressure moments of a match.

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
}

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

Putting it all together, here is what a clean, elite subsystem implementing MARSStateMachine entry/exit actions looks like:

public class Superstructure extends SubsystemBase {
private final MARSStateMachine<SuperstructureState> stateMachine;
private final Pivot pivot;
private final Rollers rollers;
public Superstructure(Pivot pivot, Rollers rollers) {
this.pivot = pivot;
this.rollers = rollers;
stateMachine = new MARSStateMachine<>("Superstructure",
SuperstructureState.class, SuperstructureState.STOW);
// 1. Map Valid Paths
stateMachine.addTransition(SuperstructureState.STOW, SuperstructureState.INTAKING_FLOOR);
stateMachine.addBidirectional(SuperstructureState.INTAKING_FLOOR, SuperstructureState.HUB_SCORE);
stateMachine.addWildcardTo(SuperstructureState.STOW);
// 2. Bind Hardware Actions
stateMachine.setEntryAction(SuperstructureState.INTAKING_FLOOR, () -> {
pivot.setGoal(IntakeConstants.DEPLOY_POS);
rollers.setVoltage(12.0);
});
stateMachine.setExitAction(SuperstructureState.INTAKING_FLOOR, () -> {
rollers.setVoltage(0.0);
});
stateMachine.setEntryAction(SuperstructureState.STOW, () -> {
pivot.setGoal(IntakeConstants.STOW_POS);
});
}
public void requestState(SuperstructureState goal) {
stateMachine.requestTransition(goal);
}
}

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.