Software · Controls

State Machine Lab

Drive the 2026 robot's super state machine (RobotContainer) one 20 ms loop at a time. Hold a button to ask for a state, then watch the transition table pick where the robot goes, updateLogic ask each subsystem for a state, and each subsystem's own state machine decide when it gets there.

The robot

Side view, front is on the right
Flywheel0 rad/s
Drive speed0.00 m/s
Game pieces8

Hold a button (or its key) to ask for that state. Let go to ask for DRIVE.

Robot is in

Alliance zone: scoring_mode_ = SCORE, shoot at the hub (250 rad/s). Neutral zone: PASS, pass to our side (300 rad/s).

Robot states

Solid outline: system_state_. Red outline: wanted.

Inside RobotContainer, this loop

Loop 0

1Wanted state

robot.getWantedState()=DRIVE

Set by the last button call. It stays wanted until something asks for another state ("sticky").

2handleStateTransition(wanted): the transition table

The real Java

            

3system_state_

DRIVE→DRIVE

4updateLogic()

no if in here

          Sent to the subsystems this loop
          

Trimmed: the real arms also set the localization state, the shooter target and a drive speed scale. Every arm asks every subsystem, every loop, so there are no enter or exit actions.

5Then each subsystem runs its own state machine

Things to try

  1. Shoot from a standstill. Turn off Driver is driving, then hold Shoot. The robot waits in SHOOT_WAIT, then jumps to SHOOT_FEED_BRAKED and crosses its wheels.
  2. Watch a shot knock the flywheel out of tolerance. Each game piece slows the flywheel by about 15 rad/s, out of its ±10.5 rad/s tolerance. The shooter drops back to SHOOT_WAIT and so does the robot, until it recovers.
  3. Find the sticky request. In SHOOT_WAIT the robot asks the intake for nothing. Look at the intake card: its wanted state stays whatever was asked last.
  4. Hold Intake, then also hold Shoot, then let go of Intake. The robot keeps shooting: the release only asks for DRIVE if INTAKE is still wanted.
  5. Pass on the move. Pick Neutral zone, keep driving and hold Shoot. SHOOT_PASS_INTAKE keeps intaking. Stop driving and it feeds.
  6. Step through a transition. Pause, hold Shoot (paused, the buttons toggle), and press Step one loop until the robot changes state. Note which table row fired.

Read more: State Machines (the super state machine and writing the transitions) and Subsystems (a subsystem's transition table).

Exercise: build the shooter's transition table

The Shooter from the State Machines lesson

A shooter with three states: IDLE, SPIN_UP (flywheel getting to 250 rad/s) and SHOOTING (feeding balls). The driver's button only ever asks for SHOOTING or IDLE. Pick what each cell of handleStateTransition does, then press Test. It starts as the default, system_state_ = wanted everywhere: every request is honoured at once. Press Test to see what goes wrong.

Your table, as Java

        
updateLogic (locked)no if: conditions go in the table

        

isAtShootingSpeed() is true when the flywheel is within 10 rad/s of 250 rad/s. Each ball the indexer feeds slows the flywheel by 40 rad/s.