Skip to content

refactor: high-level OOP rewrite of frc.robot subsystems - #42

Draft
YehudaRothstein wants to merge 1 commit into
mainfrom
refactor/high-level-subsystems-oop
Draft

refactor: high-level OOP rewrite of frc.robot subsystems#42
YehudaRothstein wants to merge 1 commit into
mainfrom
refactor/high-level-subsystems-oop

Conversation

@YehudaRothstein

Copy link
Copy Markdown
Member

What

A package-wide OOP overhaul of frc.robot: the subsystems and their coordination layer are rewritten from procedural, internals-leaking code into encapsulated, declarative Java. No tuning values were changed — every gain, conversion factor, interpolation-table entry, current limit, and friction constant is preserved byte-for-byte (they were only moved into the *Constants files).

Why

The original subsystems were "too basic": public motors/mechanisms/currentState fields, ConditionalCommands polling currentState.equals(IDLE), magic numbers inline in constructors, the same state-machine boilerplate copy-pasted three times, a stateful-supplier anti-pattern in Shooter, and weak inter-class wiring (Transport hard-coded to () -> true, Superstructure reaching into shooter.turretMechanism, 12 hand-wired trigger→state blocks).

Key changes

New abstractions

  • frc/robot/lib/StateMachineSubsystem.java — generic base StateMachineSubsystem<S extends Enum<S>> owning currentState + setStateCommand.
  • frc/robot/lib/FieldZones.java — single owner of all field-geometry triggers (alliance/neutral zones, delivery side, trench).
  • frc/robot/superstructure/RobotStateSelector.java — declarative Rule(when, then) table replacing initTriggers.

Subsystems (Shooter, Intake, Transport)

  • Privatized all motors/mechanisms/encoders; expose intent-level API (coastCommand, manualShoot, isShooterReady, atPositionTrigger).
  • *States enums now carry behavior (isHighGoal(), goalAngle(), isShooting(), linearVelocity()) instead of bare public fields.
  • Fixed Shooter's stateful-supplier anti-pattern: setpoints are plain double fields written each loop, read by stable lambdas.
  • Removed dead code (java.sql import, no-op (at)->at=false, redundant turretToHubVector, yoavHatesThisCommandCommandmanualShoot).

Communication

  • Superstructure shrank ~327 → ~115 lines; dropped 18 boolean log-getters (zones self-log via nested FieldZones).
  • Transport now gates on the real shooter-ready signal instead of () -> true (intentional behavior change).

Reviewer notes

  • Untestable without the robot. Only guarantee here is ./gradlew build passing. The two intentional flow changes — real transport gating and the declarative selector — need on-robot re-validation (state transitions, shooting, intake pump, delivery aiming) before competition. The selector was checked rule-by-rule against the old initTriggers and is logically identical.
  • FieldZones lives in frc.robot.lib (not superstructure) because Shooter consumes its inTrench() trigger, and a subsystem importing the superstructure package would be a layering inversion.
  • Alliance/intermediate zone detection remains forced (the team's real geometry was already disabled); behavior preserved, ready to re-enable in FieldZones.

🤖 Generated with Claude Code

Elevate the robot package from procedural, leaky subsystems to encapsulated,
declarative Java while preserving all empirical tuning values byte-for-byte.

New abstractions:
- StateMachineSubsystem<S>: generic base owning currentState + setStateCommand,
  removing the boilerplate copy-pasted across Shooter/Intake/Transport.
- FieldZones: single owner of all field-geometry triggers (alliance/neutral
  zones, delivery side, trench), centralizing logic previously split between
  Superstructure and Shooter.
- RobotStateSelector: declarative Rule(when, then) table replacing the 12
  hand-wired trigger->state blocks in Superstructure.initTriggers.

Subsystems:
- Privatize all motors/mechanisms/encoders; expose intent-level command/Trigger
  API (coastCommand, manualShoot, isShooterReady, atPositionTrigger).
- *States enums carry behavior (isHighGoal/goalAngle/isShooting/linearVelocity)
  instead of bare public fields.
- Fix Shooter's stateful-supplier anti-pattern: setpoints are now plain double
  fields written each loop, read by stable lambdas (single source of truth).
- Extract inline magic numbers into the *Constants files.
- Remove dead code (java.sql import, no-op lambda, redundant fields,
  yoavHatesThisCommandCommand -> manualShoot).

Communication:
- Superstructure shrinks ~327 -> ~115 lines; no longer reaches into
  shooter.turretMechanism, drops 18 boolean log-getters (zones self-log).
- Transport now gates on the real shooter-ready signal instead of () -> true.

Tuning preserved: every gain, conversion factor, interpolation-table entry,
current limit, and friction constant keeps its exact value. ./gradlew build
passes; behavior must still be re-validated on the robot.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3933bfc3-9550-46cd-917d-aaa18d821fad

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/high-level-subsystems-oop

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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