Skip to content

Power conservation: current limits, compressor inhibit, flywheel gating#180

Open
nlaverdure wants to merge 5 commits intomainfrom
power-conservation
Open

Power conservation: current limits, compressor inhibit, flywheel gating#180
nlaverdure wants to merge 5 commits intomainfrom
power-conservation

Conversation

@nlaverdure
Copy link
Copy Markdown
Member

@nlaverdure nlaverdure commented Mar 27, 2026

Summary

  • Reduce subsystem current limits to improve brownout margin (VACHE analysis): spindexer/kicker get a hard 80A secondary limit to cap stall events; intake stator reduced 100→60A; flywheel stator reduced 100→60A per motor
  • Inhibit compressor during shot cycles — wraps all three shoot trigger sites; 70in³ tank provides 30+ sec reserve so brief inhibits have no operational impact
  • Flywheel power gating in teleop — flywheel only runs when hub is active for our alliance, robot is in our alliance zone, and (on Zorro) the left dial is up; FMS bypass keeps full behavior during competition
  • At-speed shot gate — feeder only advances once flywheel is within 5% of setpoint (kAtSpeedToleranceFraction, validated 1–3% steady-state error at VACHE); hoodInitialized flag prevents spurious at-speed reads during the 1-second hood initialization stroke
  • Auto vs teleop launcher defaults — separate createAutoLauncherDefault() (always aims hub, flywheel always on) and createTeleopLauncherDefault() (position-dependent target, full policy gating); installed at mode transitions

Test plan

  • Confirm flywheel stays off in teleop when robot is outside alliance zone (log GameState/IsMyHubActive, RealOutputs/Launcher/FlywheelAtSpeed)
  • Confirm flywheel force-enables and feeder fires after at-speed wait when shoot button held
  • Confirm shot does not fire during the first ~1 second of teleop (hood initialization window)
  • Confirm Zorro dial disables flywheel in practice; dial-up and FMS-attached both enable it
  • Confirm auto always spins flywheel and aims hub center regardless of robot position
  • Check battery voltage trace — expect reduced sag vs VACHE baseline during high-current events

🤖 Generated with Claude Code

nlaverdure and others added 5 commits March 26, 2026 19:51
Addresses VACHE analysis findings (doc/VACHE_POWER_ANALYSIS.md):

- Spindexer + Kicker: add secondaryCurrentLimit(80A) as a hard cap.
  The existing smartCurrentLimit(60A) is velocity-dependent and does not
  prevent transient stalls; four 149A stall events across Q54/Q13 were
  the direct cause of the worst voltage dips at VACHE.

- Intake rollers: stator limit reduced 100A → 60A. Observed VACHE peaks
  were 56A; this matches the operating envelope with no performance impact.

- Flywheel: stator limit reduced 100A → 60A per motor. Observed spin-up
  peaks touched 60A; capping at the observed ceiling avoids excess headroom
  contributing to battery sag.

Drive motor limits unchanged per analysis recommendation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wraps the spin-forward command (all three trigger sites — operator A,
driver A, and right bumper desaturate-and-shoot) with compressor::disable
before start and compressor::enableDigital on end.

The compressor was present and adding 6-20A at every major voltage dip
in the VACHE analysis; in Q54 it ramped to 19.6A at the exact worst
moment (6.67V). The 70in³ storage tank provides 30+ seconds of reserve,
so brief inhibits during shot cycles have no operational impact.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…speed shot gate

- Launcher.aim() takes policyEnabled; flywheel off when policy false and force-enable not active
- Turret falls back to nominal aim direction when flywheel is off/spinning up (<0.5 m/s ballistic)
- flywheelForceEnabled / isFlywheelAtSpeed() gate the feeder: spin up before advancing
- hoodInitialized flag prevents isFlywheelAtSpeed() returning true during hood initialization
- kAtSpeedToleranceFraction = 0.05 (validated against VACHE logs: steady-state error 1-3%)
- Separate createAutoLauncherDefault() (always policyEnabled=true) and createTeleopLauncherDefault()
  (flywheelPolicy && isMyHubActive && isInMyAllianceZone); set at mode transitions, not constructor
- flywheelPolicy BooleanSupplier: defaults to always-true; Zorro driver overrides with dial gate
  (FMS bypass: dial ignored when FMS attached)
- GameState: add getMyHub(), isInMyAllianceZone()
- Remove dead Zorro launcher trigger (was scheduling the default command as whileTrue)
- shootWithCompressorInhibit: sequence force-enable → waitUntil(atSpeed) → feeder

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Makes LoggedCompressor a SubsystemBase so the command scheduler owns
compressor state. Default command applies 150A/100A hysteresis against
PDH total current; shot commands interrupt it via deadlineWith. Adds
PowerConstants (inhibit/resume thresholds, electronics overhead) to
Constants.java.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant