Skip to main content

Indexer Hoard/Burst State Machine

Disclaimer: WIP and untested on 2026 hardware; tune speeds, thresholds, and sensor logic on your robot. Custom code built on WPILib APIs (not official WPILib sample).

Purpose: Align fuel handling with hub state: hoard when inactive, auto-feed when active, clear jams fast.

What it does

  • Two modes: HOARD (intake fills buffer, holds) and BURST (feeds shooter/hub).
  • Jam detection via beam break (preferred) or motor current spike fallback.
  • Auto-switches to BURST when hub becomes active, back to HOARD when inactive.

Code (Java/WPILib Command)

public class IndexerCommand extends Command {
public enum Mode { HOARD, BURST }
private final IndexerSubsystem indexer;
private final Supplier<HubShiftTimer.HubState> hubState;
private Mode mode = Mode.HOARD;
private final Timer jamTimer = new Timer();

public IndexerCommand(IndexerSubsystem indexer, Supplier<HubShiftTimer.HubState> hubState) {
this.indexer = indexer;
this.hubState = hubState;
addRequirements(indexer);
}

@Override
public void initialize() {
mode = Mode.HOARD;
jamTimer.reset();
}

@Override
public void execute() {
// Mode switch on hub state
if (hubState.get() == HubShiftTimer.HubState.ACTIVE) mode = Mode.BURST;
else mode = Mode.HOARD;

boolean jam = isJammed();

switch (mode) {
case HOARD -> {
if (indexer.isFull()) {
indexer.stop();
} else {
indexer.feedIn();
}
}
case BURST -> {
if (jam) {
indexer.reverse();
} else {
indexer.feedOut();
}
}
}
}

private boolean isJammed() {
// Prefer sensor
if (indexer.hasBeamBreak() && indexer.beamBrokenTooLong(0.5)) return true;
// Fallback current spike
return indexer.getMotorCurrent() > 40.0;
}

@Override
public void end(boolean interrupted) {
indexer.stop();
}
}

IndexerSubsystem sketch

public class IndexerSubsystem extends SubsystemBase {
private final TalonFX motor = new TalonFX(10);
private final DigitalInput beam = new DigitalInput(0);
private final Timer beamTimer = new Timer();

public void feedIn() { motor.set(ControlMode.PercentOutput, 0.4); }
public void feedOut() { motor.set(ControlMode.PercentOutput, -0.6); }
public void reverse() { motor.set(ControlMode.PercentOutput, -0.4); }
public void stop() { motor.set(ControlMode.PercentOutput, 0.0); }

public boolean hasBeamBreak() { return true; }
public boolean isFull() { return beam.get(); } // adjust logic
public boolean beamBrokenTooLong(double sec) { return beamTimer.hasElapsed(sec); }
public double getMotorCurrent() { return motor.getStatorCurrent(); }

@Override
public void periodic() {
if (beam.get()) beamTimer.start();
else { beamTimer.stop(); beamTimer.reset(); }
}
}

Parameters to tune

  • Speeds: feed in/out percentages.
  • Jam thresholds: beam break duration, current spike.
  • Buffer “full” definition: sensor count or time.

How to test

  • Bench: simulate hub active/inactive toggles; confirm mode flips HOARD/BURST.
  • Feed 10 fuel; measure time per shift and success rate; induce jams (block rollers) to see reversals.

Pitfalls

  • Ensure sensor logic matches wiring (beam break true vs false).
  • Add current limit on motor to avoid brownouts during reverse.