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) andBURST(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.