Skip to content

Sim docs#113

Draft
Project516 wants to merge 72 commits into
mainfrom
sim-docs
Draft

Sim docs#113
Project516 wants to merge 72 commits into
mainfrom
sim-docs

Conversation

@Project516

@Project516 Project516 commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Added full-field fuel physics simulation with ball launching, intake, scoring, collisions, and telemetry.
    • Added robot bump and ramp simulation.
    • Added turret-based aiming, updated superstructure controls, and improved vision pose integration.
    • Added AdvantageScope robot assets and simulation guidance.
    • Added updated LED patterns and support for new robot configurations.
  • Bug Fixes

    • Corrected shift-timer calculations and improved vision data handling.
    • Updated autonomous routines with an additional path segment.
  • Documentation

    • Expanded SpectrumLib and simulation documentation.

A2A1x and others added 30 commits March 23, 2026 00:00
Reorganize spectrumLib into clearer subpackages and apply multiple safety/bug fixes across the codebase.

Key changes:
- Move core spectrumLib classes into new packages (framework, hardware, telemetry, mechanism, etc.) and update all imports accordingly.
- Refactor Mechanism: cleanup docs, reorganize fields, improve cached sensor accessors and initialization, and update imports to TalonFXFactory/util locations.
- Replace usages of frc.spectrumLib.Telemetry with frc.spectrumLib.telemetry.Telemetry across the project.
- Fix sign/logic bugs: normalize reverseTorqueCurrentLimit usages (removed negative literals) in Hood, IntakeExtension, Launcher, and other mechanisms.
- Add guards around ShotCalculator parameter use (params.isValid()) in Hood and Launcher to avoid invalid targeting.
- Remove debug prints from Tag align controllers and adjust controller.reset() usage.
- Improve Robot auton startup: handle empty path list (log a warning) and remove an unnecessary clearCommandsAndButtons call in disabledInit.
- Delete unused HomeOffsets class.
- Add VSCode Java VM args to .vscode/settings.json to improve editor JVM behavior.

These changes are primarily structural (package reorganization) and safety-oriented to prevent invalid operations and improve code clarity/telemetry integration.
Replace the minimal README with a comprehensive usage and API overview for the spectrumLib package. The new README documents package structure and modules (framework, hardware, telemetry, util, mechanism, gamepads, leds, sim, swerve, vision), enumerates key classes and responsibilities, lists dependencies, and provides usage/installation guidance to help developers onboard and reuse library components across robot projects.
Large refactor of the Vision subsystem: introduce VisionConfig and VisionFieldPoseEstimate classes; add per-camera VisionLogger instances and bulk telemetry logging; implement robust MT1/MT2 pose pipelines with detailed rejection checks, std-dev selection, and imu-mode caching; expose utility methods (getBestLimelight, hasAccuratePose, tagsInView, triggerRewindCaptureForAllCameras, setLimelightPipelines, pose reset with stricter sanity checks) and improved commands for LED control. Also reorganized periodic logic and cleaned up many null/units/angle checks and timestamp handling. Additionally moved/normalized Telemetry import positions across multiple mechanism and robot subsystem classes and applied small Javadoc/formatting tweaks in Mechanism.
Delete the locally modified Trigger implementation and its README, and update all call sites to use the standard Trigger API. Replaced deprecated .not() calls with .negate(), converted multi-argument .and()/.or() usages into chained .and()/.or() calls to match the available API, and updated related call sites (Pilot, Operator, Gamepad, SwerveStates, SpectrumState, PilotStates, OperatorStates, RobotStates). Also adjusted some command names and a pilotAimDrive parameter name (degrees -> radians) and updated a WaitCommand.onlyWhile(...) call to use negate(). These changes restore compatibility with the external WPILib Trigger implementation and align the codebase with its API.
Adjust pilot input bindings and formatting, resize simulator GUI, and tidy imports:

- Swap and rewire LT/RT trigger handlers (onTrue/onFalse) and update the combined trigger order for launch/intake state transitions in RobotStates.
- Resize simgui window from 2256x1415 to 1920x1009 and reduce widget sizes/positions for Addressable LEDs and Joysticks in simgui-window.json.
- Reorder the Telemetry import in LauncherStates (style-only) and collapse the multi-line Trigger composition into a single expression in PilotStates.
Replace the previous interpolation/map-based shot lookup with a degree-3 polynomial surface and an iterative "virtual-target" solver in ShotCalculator. Introduces a ShootingParameters record, clamped fitted ranges, MPS/RPM scaling constants, and a 1690-style iterative lookahead that accounts for radial and tangential launcher velocities to compute exit speed, launch angle, yaw offset, converged lookahead distance and time-of-flight. Adds constants for phase delay, loop period, and filters; moves hood offset/drive offset handling into runtime-adjustable fields; and expands Telemetry outputs for debugging.

Also updates RobotSim to use the computed exit speed (m/s) directly instead of deriving a simulated launcher speed from the old flywheel RPM mapping. Misc: removes dependence on interpolating maps (and related imports), and consolidates hood/flywheel/drive computations around the new polynomial-based solver.
@Project516

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Review Change Stack

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: edc62da8-fd7b-48a7-959f-2de408720af9

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
📝 Walkthrough

Walkthrough

This PR restructures robot control around SuperStructure, adds new ball and bump physics simulation, refactors SpectrumLib hardware and subsystem APIs, introduces turret-based aiming and Limelight vision, and updates simulation tooling, documentation, assets, and dependency metadata.

Changes

Robot platform and control architecture

Layer / File(s) Summary
Robot wiring and superstructure
src/main/java/frc/robot/Robot.java, src/main/java/frc/robot/subsystems/SuperStructure.java, src/main/java/frc/robot/auton/Auton.java, src/main/java/frc/robot/configs/*, src/main/java/frc/robot/operator/Operator.java, src/main/java/frc/robot/pilot/Pilot.java
Robot initialization, bindings, autonomous launch behavior, and subsystem coordination now use SuperStructure wanted/current states.
State-based mechanism subsystems
src/main/java/frc/robot/subsystems/{fuelIntake,indexerTower,intakeExtension,launcher,spindexer,turret}/*, src/main/java/frc/robot/subsystems/leds/Leds.java
Mechanisms expose state-based control and simulation lifecycle methods, with updated configuration and telemetry.
Swerve, vision, and operator inputs
src/main/java/frc/robot/subsystems/swerve/*, src/main/java/frc/robot/subsystems/vision/*, src/main/java/frc/robot/pilot/Pilot.java, src/main/java/frc/robot/operator/Operator.java
Swerve driving, zone checks, vision fusion, and controller mappings are refactored for the new subsystem architecture.

Simulation and reusable library

Layer / File(s) Summary
Field and robot physics simulation
src/main/java/frc/rebuilt/FuelPhysicsSim.java, src/main/java/frc/rebuilt/RobotBumpSim.java, src/main/java/frc/robot/RobotSim.java
Ball dynamics, field collisions, scoring, intake behavior, bump traversal, articulated visualization, and simulation launch commands are added or integrated.
SpectrumLib core and hardware migration
src/main/java/frc/spectrumLib/framework/*, src/main/java/frc/spectrumLib/hardware/*, src/main/java/frc/spectrumLib/mechanism/Mechanism.java, src/main/java/frc/spectrumLib/telemetry/*
SpectrumLib types move into structured packages, subsystem contracts change to WPILib Subsystem, and mechanism target tracking is expanded.
LED and simulation library
src/main/java/frc/spectrumLib/leds/SpectrumLEDs.java, src/main/java/frc/spectrumLib/sim/*, src/main/java/frc/spectrumLib/swerve/*
LED control moves to CANdle patterns, while simulation helpers receive new behavior and extensive API documentation.

Supporting configuration and documentation

Layer / File(s) Summary
Field geometry and turret aiming
src/main/java/frc/rebuilt/Field.java, src/main/java/frc/rebuilt/FieldHelpers.java, src/main/java/frc/rebuilt/ShotCalculator.java
Field constants and flipping helpers are adjusted, and shot outputs now provide turret angle, turret angular velocity, and flywheel speed.
Simulation tools and operator assets
docs/tools/simulation.md, advantagescope-custom-assets/*, simgui-*.json, src/main/deploy/pathplanner/autos/TBTB Full.auto
Simulation documentation, AdvantageScope robot assets, simulator layouts and joystick configuration, and one autonomous path sequence are updated.
Dependency metadata and vision telemetry
vendordeps/Phoenix6-26.3.0.json, src/main/java/frc/spectrumLib/vision/*, src/main/java/frc/spectrumLib/README.md
Phoenix metadata, Limelight null handling and telemetry keys, and SpectrumLib documentation are updated.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Robot as Robot
  participant SuperStructure as SuperStructure
  participant RobotSim as RobotSim
  participant FuelPhysicsSim as FuelPhysicsSim
  participant AdvantageScope as AdvantageScope
  Robot->>SuperStructure: setWantedSuperState()
  SuperStructure->>RobotSim: expose current state
  RobotSim->>FuelPhysicsSim: launchBall() or tick()
  FuelPhysicsSim->>AdvantageScope: publish positions, arcs, scores, and stats
Loading

Poem

I’m a rabbit with a brand-new track,
Turrets aim and balls bounce back.
States now guide each careful hop,
CANdle lights glow at every stop.
Through fields and ramps the sim leaps bright—
A fluffy review says, “Ship it right!”

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 68.36% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is very vague and only loosely hints at simulation documentation changes. Rename it to a specific summary of the main change, such as updating simulation docs and AdvantageScope assets.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sim-docs

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

@Project516

Copy link
Copy Markdown
Contributor Author

@coderabbitai resolve merge conflict

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Merge conflicts resolved successfully!

Resolved 1 conflict file(s). Commit: 5a280d14762105ee78779ee0ea4137c7bae59473 pushed to sim-docs.

126 file operation(s)
  • .vscode/settings.json (update)
  • advantagescope-custom-assets/README.txt (update)
  • advantagescope-custom-assets/Robot_FM/config.json (update)
  • advantagescope-custom-assets/Robot_FM/model_0.glb (update)
  • advantagescope-custom-assets/Robot_FM/model_1.glb (update)
  • advantagescope-custom-assets/Robot_PM/config.json (update)
  • advantagescope-custom-assets/Robot_PM/model_0.glb (update)
  • advantagescope-custom-assets/Robot_PM/model_1.glb (update)
  • simgui-ds.json (update)
  • simgui-window.json (update)
  • src/main/deploy/pathplanner/autos/TBTB Full.auto (update)
  • src/main/java/frc/rebuilt/Field.java (update)
  • src/main/java/frc/rebuilt/FieldHelpers.java (update)
  • src/main/java/frc/rebuilt/FuelPhysicsSim.java (update)
  • src/main/java/frc/rebuilt/RobotBumpSim.java (update)
  • src/main/java/frc/rebuilt/ShiftHelpers.java (update)
  • src/main/java/frc/rebuilt/ShotCalculator.java (update)
  • src/main/java/frc/rebuilt/targetFactories/FeedTargetFactory.java (update)
  • src/main/java/frc/robot/Robot.java (update)
  • src/main/java/frc/robot/RobotSim.java (update)
  • src/main/java/frc/robot/auton/Auton.java (update)
  • src/main/java/frc/robot/configs/FM2026.java (update)
  • src/main/java/frc/robot/configs/OM2026.java (update)
  • src/main/java/frc/robot/configs/PHOTON2026.java (update)
  • src/main/java/frc/robot/configs/PM2026.java (update)
  • src/main/java/frc/robot/configs/XM2026.java (update)
  • src/main/java/frc/robot/operator/Operator.java (update)
  • src/main/java/frc/robot/pilot/Pilot.java (update)
  • src/main/java/frc/robot/subsystems/SuperStructure.java (update)
  • src/main/java/frc/robot/subsystems/fuelIntake/FuelIntake.java (update)
  • src/main/java/frc/robot/subsystems/indexerTower/IndexerTower.java (update)
  • src/main/java/frc/robot/subsystems/intakeExtension/IntakeExtension.java (update)
  • src/main/java/frc/robot/subsystems/launcher/Launcher.java (update)
  • src/main/java/frc/robot/subsystems/leds/Leds.java (update)
  • src/main/java/frc/robot/subsystems/spindexer/Spindexer.java (update)
  • src/main/java/frc/robot/subsystems/swerve/Swerve.java (update)
  • src/main/java/frc/robot/subsystems/swerve/SwerveConfig.java (update)
  • src/main/java/frc/robot/subsystems/turret/Turret.java (update)
  • src/main/java/frc/robot/subsystems/vision/Vision.java (update)
  • src/main/java/frc/spectrumLib/README.md (update)
  • src/main/java/frc/spectrumLib/framework/SpectrumRobot.java (update)
  • src/main/java/frc/spectrumLib/framework/SpectrumState.java (update)
  • src/main/java/frc/spectrumLib/gamepads/Gamepad.java (update)
  • src/main/java/frc/spectrumLib/hardware/Rio.java (update)
  • src/main/java/frc/spectrumLib/hardware/SpectrumCANcoder.java (update)
  • src/main/java/frc/spectrumLib/hardware/SpectrumCANcoderConfig.java (update)
  • src/main/java/frc/spectrumLib/hardware/SpectrumServo.java (update)
  • src/main/java/frc/spectrumLib/hardware/TalonFXFactory.java (update)
  • src/main/java/frc/spectrumLib/leds/SpectrumLEDs.java (update)
  • src/main/java/frc/spectrumLib/mechanism/Mechanism.java (update)
  • src/main/java/frc/spectrumLib/sim/ArmConfig.java (update)
  • src/main/java/frc/spectrumLib/sim/ArmSim.java (update)
  • src/main/java/frc/spectrumLib/sim/Circle.java (update)
  • src/main/java/frc/spectrumLib/sim/LinearConfig.java (update)
  • src/main/java/frc/spectrumLib/sim/LinearSim.java (update)
  • src/main/java/frc/spectrumLib/sim/Mount.java (update)
  • src/main/java/frc/spectrumLib/sim/Mountable.java (update)
  • src/main/java/frc/spectrumLib/sim/RollerConfig.java (update)
  • src/main/java/frc/spectrumLib/sim/RollerSim.java (update)
  • src/main/java/frc/spectrumLib/swerve/MapleSimSwerveDrivetrain.java (update)
  • src/main/java/frc/spectrumLib/swerve/SysID.java (update)
  • src/main/java/frc/spectrumLib/telemetry/BatteryLogger.java (update)
  • src/main/java/frc/spectrumLib/telemetry/Telemetry.java (update)
  • src/main/java/frc/spectrumLib/telemetry/TuneValue.java (update)
  • src/main/java/frc/spectrumLib/util/CachedDouble.java (update)
  • src/main/java/frc/spectrumLib/util/CanDeviceId.java (update)
  • src/main/java/frc/spectrumLib/util/CrashTracker.java (update)
  • src/main/java/frc/spectrumLib/util/ExpCurve.java (update)
  • src/main/java/frc/spectrumLib/util/Network.java (update)
  • src/main/java/frc/spectrumLib/util/Trio.java (update)
  • src/main/java/frc/spectrumLib/util/Util.java (update)
  • src/main/java/frc/spectrumLib/util/exceptions/KillRobotException.java (update)
  • src/main/java/frc/spectrumLib/vision/Limelight.java (update)
  • src/main/java/frc/spectrumLib/vision/VisionLogger.java (update)
  • vendordeps/Phoenix6-26.3.0.json (update)
  • src/main/java/edu/wpi/first/wpilibj2/command/button/README.md (delete)
  • src/main/java/edu/wpi/first/wpilibj2/command/button/Trigger.java (delete)
  • src/main/java/frc/rebuilt/TagProperties.java (delete)
  • src/main/java/frc/rebuilt/Zones.java (delete)
  • src/main/java/frc/rebuilt/launchingMaps/AndyMarkMap.java (delete)
  • src/main/java/frc/rebuilt/launchingMaps/HomeMap.java (delete)
  • src/main/java/frc/rebuilt/offsets/HomeOffsets.java (delete)
  • src/main/java/frc/robot/Coordinator.java (delete)
  • src/main/java/frc/robot/RobotStates.java (delete)
  • src/main/java/frc/robot/State.java (delete)
  • src/main/java/frc/robot/fuelIntake/FuelIntakeStates.java (delete)
  • src/main/java/frc/robot/hood/Hood.java (delete)
  • src/main/java/frc/robot/hood/HoodStates.java (delete)
  • src/main/java/frc/robot/indexerBed/IndexerBed.java (delete)
  • src/main/java/frc/robot/indexerBed/IndexerBedStates.java (delete)
  • src/main/java/frc/robot/indexerTower/IndexerTower.java (delete)
  • src/main/java/frc/robot/indexerTower/IndexerTowerStates.java (delete)
  • src/main/java/frc/robot/intakeExtension/IntakeExtensionStates.java (delete)
  • src/main/java/frc/robot/launcher/LauncherStates.java (delete)
  • src/main/java/frc/robot/leds/CANdleLeds.java (delete)
  • src/main/java/frc/robot/leds/LedStates.java (delete)
  • src/main/java/frc/robot/operator/OperatorStates.java (delete)
  • src/main/java/frc/robot/pilot/PilotStates.java (delete)
  • src/main/java/frc/robot/fuelIntake/FuelIntake.java (delete)
  • src/main/java/frc/robot/intakeExtension/IntakeExtension.java (delete)
  • src/main/java/frc/robot/launcher/Launcher.java (delete)
  • src/main/java/frc/robot/swerve/Swerve.java (delete)
  • src/main/java/frc/robot/swerve/SwerveConfig.java (delete)
  • src/main/java/frc/robot/swerve/SwerveStates.java (delete)
  • src/main/java/frc/robot/swerve/controllers/RotationController.java (delete)
  • src/main/java/frc/robot/swerve/controllers/TagCenterAlignController.java (delete)
  • src/main/java/frc/robot/swerve/controllers/TagDistanceAlignController.java (delete)
  • src/main/java/frc/robot/swerve/controllers/TranslationXController.java (delete)
  • src/main/java/frc/robot/swerve/controllers/TranslationYController.java (delete)
  • src/main/java/frc/robot/vision/Vision.java (delete)
  • src/main/java/frc/robot/vision/VisionStates.java (delete)
  • src/main/java/frc/robot/vision/VisionSystem.java (delete)
  • src/main/java/frc/spectrumLib/SpectrumCANcoderConfig.java (delete)
  • src/main/java/frc/spectrumLib/SpectrumServo.java (delete)
  • src/main/java/frc/spectrumLib/SpectrumSubsystem.java (delete)
  • src/main/java/frc/spectrumLib/TuneValue.java (delete)
  • src/main/java/frc/spectrumLib/SpectrumRobot.java (delete)
  • src/main/java/frc/spectrumLib/SpectrumState.java (delete)
  • src/main/java/frc/spectrumLib/Rio.java (delete)
  • src/main/java/frc/spectrumLib/SpectrumCANcoder.java (delete)
  • src/main/java/frc/spectrumLib/talonFX/TalonFXFactory.java (delete)
  • src/main/java/frc/spectrumLib/BatteryLogger.java (delete)
  • src/main/java/frc/spectrumLib/Telemetry.java (delete)
  • src/main/java/frc/spectrumLib/CachedDouble.java (delete)
  • vendordeps/Phoenix6-26.1.3.json (delete)
  • vendordeps/photonlib.json (delete)
View agent analysis

Resolved conflicts in:
- docs/tools/simulation.md (content)

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
@Project516

Copy link
Copy Markdown
Contributor Author

@coderabbitai help

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

CodeRabbit commands

These commands are invoked using PR/Issue comments.

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai rate limit to show your current review rate limit status.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai evaluate custom pre-merge check --instructions <custom-checks-instructions> --name <custom-checks-title> [--mode <error|warning>] to validate the custom pre-merge checks instructions. Defaults to error when --mode is omitted.
  • @coderabbitai ignore pre-merge checks to override pre-merge checks and get an approval on PR.
  • @coderabbitai run pre-merge checks to run pre-merge checks on the pull request.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai emit path instructions to emit generated path-specific review instructions for this repository.
  • @coderabbitai resolve merge conflict to automatically resolve merge conflicts.
  • @coderabbitai autofix to automatically fix issues identified in unresolved review comments.
  • @coderabbitai fix-ci to automatically fix failing CI checks by creating a stacked PR with fixes.
  • @coderabbitai resolve to resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai generate configuration to create a PR that adds the current resolved configuration as .coderabbit.yaml (or show it if already present).
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit configuration file (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, support, documentation and community

  • Visit our status page to check the current availability of CodeRabbit.
  • Create a ticket on our support page for assistance with any issues or questions.
  • Visit our documentation site for detailed information on how to use CodeRabbit.
  • Join our Discord community to connect with other users and get help from the community.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 65

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (6)
docs/tools/simulation.md (1)

76-77: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Retain a MapleSim reference.

The new section relies on MapleSim behavior in Lines 35, 46, and 72, but this change removes the MapleSim dependency link. Keep a current link or add one inline at the first MapleSim reference.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/tools/simulation.md` around lines 76 - 77, Update the simulation
documentation around the PathPlanner dependency reference to retain a current
MapleSim link, placing it inline at the first MapleSim mention if no dedicated
dependency link is appropriate. Ensure the existing MapleSim references remain
navigable without changing unrelated documentation.
src/main/java/frc/robot/subsystems/launcher/Launcher.java (2)

143-154: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing WantedState/SystemState telemetry.

Every sibling subsystem in this PR (IndexerTower, IntakeExtension, Swerve) logs both keys; the launcher — the one mechanism whose state is hardest to infer from voltage alone — logs neither.

📊 Proposed addition
         systemState = handleStateTransition();
         logBatteryUsage();
         applyStates();
+        Telemetry.log("Launcher/WantedState", wantedState.toString());
+        Telemetry.log("Launcher/SystemState", systemState.toString());
         Telemetry.log("Launcher/CurrentCommand", getCurrentCommandName());
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/frc/robot/subsystems/launcher/Launcher.java` around lines 143 -
154, Update Launcher.periodic() to log both the current WantedState and
SystemState telemetry, matching the corresponding keys and value style used by
sibling subsystems such as IndexerTower, IntakeExtension, and Swerve. Add these
logs alongside the existing launcher telemetry without changing the
state-transition or actuator flow.

23-40: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Two competing sets of current-limit fields.

LauncherSupplyCurrent (30) and LauncherStatorCurrent (85) are settable but never applied — the constructor configures the motor from supplyCurrentLimit (80) / statorCurrentLimit (100). Calling the generated setters at runtime silently does nothing. Remove the unused pair or make the constructor use them.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/frc/robot/subsystems/launcher/Launcher.java` around lines 23 -
40, Remove the unused settable LauncherSupplyCurrent and LauncherStatorCurrent
fields from Launcher, or consolidate the configuration so the constructor and
runtime setters use the same current-limit values; ensure no competing field
pair remains and generated setters cannot silently have no effect.
src/main/java/frc/spectrumLib/framework/SpectrumState.java (1)

180-189: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

toggle() duplicates setState instead of delegating.

The lambda re-implements the three lines of setState(boolean); any future change to setState (logging, guards) silently skips the toggle path.

♻️ Proposed fix
     public Command toggle() {
-        return Commands.runOnce(
-                        () -> {
-                            value = !value;
-                            alert.set(value);
-                            setCondition(name, value);
-                        })
+        return Commands.runOnce(() -> setState(!value))
                 .ignoringDisable(true)
                 .withName(name + " state: Toggle");
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/frc/spectrumLib/framework/SpectrumState.java` around lines 180
- 189, Update toggle() to delegate its state change to the existing
setState(boolean) method instead of directly mutating value, updating alert, and
calling setCondition. Preserve the current command behavior and toggle the state
by passing the inverse of the current value to setState.
src/main/java/frc/spectrumLib/sim/Circle.java (1)

59-78: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Apply the requested initial color after delegation.

The delegated constructor draws all ligaments with the default black color before Line 77 assigns this.color; this overload therefore ignores its color argument visually.

Proposed fix
         this(backgroundLines, diameterInches, name, root, mech);
         this.color = color;
+        setBackgroundColor(color);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/frc/spectrumLib/sim/Circle.java` around lines 59 - 78, Update
the Circle constructor overload that accepts Color8Bit so the requested color is
applied to every already-created background ligament after delegating
construction; assigning this.color alone is insufficient. Reuse the existing
ligament collection and color-application mechanism in Circle, ensuring all
radial lines visibly use the provided color immediately.
src/main/java/frc/spectrumLib/framework/SpectrumRobot.java (1)

20-34: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Gate the watchdog widening to simulation. SpectrumRobot widens both loop-overrun watchdogs to 200 ms on every Robot startup, so real hardware can miss genuine 20 ms loop overruns. If this is only for sim physics, wrap the reflection block and CommandScheduler.setPeriod(0.20) in if (isSimulation()) so the robot keeps the normal timing diagnostics.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/frc/spectrumLib/framework/SpectrumRobot.java` around lines 20 -
34, Update the SpectrumRobot constructor so the watchdog reflection block and
CommandScheduler.getInstance().setPeriod(0.20) execute only when isSimulation()
is true; preserve the existing warning behavior and leave real-hardware loop
timing unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.vscode/settings.json:
- Line 62: Update the java.jdt.ls.vmargs setting in the workspace configuration
to replace the tracked -Xmx8G maximum heap with a substantially smaller default,
while preserving the other JVM arguments. Users should still be able to override
the heap size in their personal settings.
- Line 61: Update the java.debug.settings.onBuildFailureProceed setting in the
VS Code configuration to false so debugging does not continue after a failed
build.

In `@docs/tools/simulation.md`:
- Line 44: Update the simulation documentation sentence to name the actual
AdvantageScope 3D Field topics: replace FuelInFlight with Sim/Fuel/InFlight,
identify its type as Translation3d[], and mention Sim/Fuel/LastShotArc as the
other relevant topic.

In `@simgui-window.json`:
- Around line 4-8: Normalize the saved Glass dock layout in simgui-window.json
so all window and dock positions remain within the 1920×974 main-window bounds,
especially the panes positioned beyond the right edge. Adjust the affected Pos
and Size values while preserving the existing dock hierarchy and split
relationships.

In `@src/main/java/frc/rebuilt/FuelPhysicsSim.java`:
- Around line 984-986: Prevent launchBall in FuelPhysicsSim from decrementing
totalIntaked below zero, or introduce a separate held-ball count while
preserving totalIntaked as a monotonic telemetry counter. In RobotSim, clamp the
totalIntaked snapshot with Math.max(0, ...) before dividing by numOfLanes, and
return group1 directly instead of wrapping the single command in
Commands.parallel; apply these changes at FuelPhysicsSim.java:984-986 and
RobotSim.java:240-251.
- Around line 722-737: Update shouldIntake so it only computes and returns
whether the ball is eligible, removing the callback.run side effect. Move
intake.callback invocation into handleIntakePickup, executing it only after
shouldIntake returns true during actual pickup handling.
- Around line 289-292: Extract the shared tower geometry values used by both
static blocks in FuelPhysicsSim into named constants, including blue/red tower X
and Y positions and halfSpacing. Replace the inline literals and duplicate local
declarations in the AABB upright and rung-cylinder setup with those constants so
all tower geometry remains synchronized.
- Around line 1192-1227: Move the per-frame bookkeeping from stepSubtick into
advancePhysics after the subtick loop: updateSleepState, the finite/position
bounds scan, and elevatedSlowCounter handling must each run once per 20 ms frame
rather than once per subtick. Preserve the existing checks, thresholds, and
outOfBounds behavior while removing their execution from the subtick path.

In `@src/main/java/frc/rebuilt/RobotBumpSim.java`:
- Line 294: Update the contactFactor calculation in RobotBumpSim to use the
documented diagonal behavior, yielding approximately 0.71 at 45° instead of
zero; preserve the absolute-value handling and ensure diagonal collisions still
apply ramp deceleration.
- Around line 418-427: Update the ramp-collision correction around the
projected-distance calculation to use signed separation from the ramp rather
than unsigned dist. Preserve the existing normal computation, derive the signed
distance using the normal, and apply only the Z correction through normalZ so
modules below the ramp are pushed out even at contact; keep the non-intersection
check based on the appropriate radius condition.

In `@src/main/java/frc/rebuilt/ShotCalculator.java`:
- Around line 193-206: Remove the offset applications from ShotCalculator’s
calculation flow: stop adding TURRET_ANGLE_OFFSET_DEGREES to turretAngle and
stop applying FLYWHEEL_SPEED_OFFSET to flywheelSpeed. Preserve the raw
map-derived angle and speed so Turret and Launcher remain the sole consumers
applying their respective offsets.
- Around line 120-128: Fix the feed condition in the ShotCalculator feed-target
logic by replacing the tautological OR of negated launch-state checks with a
guard that excludes all three launch states using the appropriate AND semantics.
Preserve the isRobotInFeedZone() requirement while ensuring feed is false for
LAUNCH_WITH_SQUEEZE, LAUNCH_WITHOUT_SQUEEZE, and
LAUNCH_WITH_SQUEEZE_WITH_NO_DELAY.
- Line 217: Update the telemetry key in the ShotCalculator logging statement for
turretAngularVelocityRotPerSec to identify rotations per second rather than
radians per second, while leaving the computed value and formatting unchanged.
- Around line 152-162: Correct the tangential-velocity calculation in the turret
velocity logic by updating turretVelocityX to use the negative omega
contribution of the rotated offset, specifically -omega * (dx*sinθ + dy*cosθ).
Leave turretVelocityY unchanged.
- Line 192: Update the turret-angle calculation in ShotCalculator so the
field-relative target direction is converted to a mechanism-relative angle by
subtracting the robot heading before returning or commanding it. Preserve the
existing compensatedTurretTranslation calculation and ensure the resulting angle
matches Turret.setMMPositionFoc’s expected reference frame.

In `@src/main/java/frc/robot/auton/Auton.java`:
- Around line 108-114: Update the command returned by launch() so interruption
or cancellation also restores WantedSuperState.IDLE and clears autonLaunching,
rather than relying only on the sequence’s trailing commands. Preserve the
normal 2.5-second launch sequence while adding cleanup that runs when the
command is interrupted.

In `@src/main/java/frc/robot/configs/FM2026.java`:
- Around line 19-20: Update mechanism attachment flags consistently: in
src/main/java/frc/robot/configs/FM2026.java lines 19-20, attach turret alongside
spindexer (or explicitly document why FM has no turret); in
src/main/java/frc/robot/configs/PHOTON2026.java line 19, replace the commented
indexerBed attachment with spindexer.setAttached(true) and
turret.setAttached(true).

In `@src/main/java/frc/robot/configs/OM2026.java`:
- Around line 9-10: Update the robot configuration selection in Robot.java so
UNKNOWN roboRIO serials do not use OM2026’s zero encoder offsets: either
introduce and select a distinct simulation-only configuration for SIM while
rejecting UNKNOWN explicitly, or otherwise fail loudly before starting with
UNKNOWN. Keep OM2026 available only for the intended robot hardware.

In `@src/main/java/frc/robot/configs/PM2026.java`:
- Line 20: Remove the commented-out indexerBed attach call from PM2026.java and
apply the same change to XM2026.java; if indexerBed remains an active mechanism,
replace the commented calls in both configs with indexerBed.setAttached(false)
instead.

In `@src/main/java/frc/robot/Robot.java`:
- Around line 484-487: Remove the commented-out simulation reset block near the
autonomous-start logic. If resetting field balls on autonomous start remains
required, restore that behavior using RobotBase.isSimulation() instead of the
removed Utils reference.
- Around line 179-184: Invoke configureSimBindings() within the
RobotBase.isSimulation() branch after creating robotSim, while retaining
configureBindings() for common bindings. Ensure the RobotSim.simLaunching() to
ballSimLaunchFuel() binding becomes active only during simulation.

In `@src/main/java/frc/robot/RobotSim.java`:
- Around line 104-108: Define a named constant for the 9-degree turret
visualization offset alongside SHOOTER_TURRET_PIVOT_POINT, then update the
turretPose3d rotation calculation to use that constant instead of the hard-coded
subtraction. Preserve the existing offset value and behavior.
- Around line 71-76: Update the lane1 initialization in RobotSim to remove the
misleading -2 * laneWidth / 2 expression: use the general lane-position formula
based on the lane index and numOfLanes, or express the single-lane offset
plainly as -laneWidth. Preserve the intended lane positioning behavior.
- Around line 212-219: Update the launch kinematics in the RobotSim
shot-creation block so params.flywheelSpeed() is converted from RPM to exit
velocity using the flywheel surface-speed conversion and efficiency before
constructing Translation3d. Use params.turretAngle() directly as the
field-relative launch yaw, and replace its use as pitch with the configured
hood/launch elevation constant; keep launchRotation and launchVelocity
consistent with these corrected components.
- Around line 122-129: Update drawTurretCircle to pass the top-view dimensions
to topView.getRoot in the same x/y order as drawTopRobot, using topViewWidth for
x and topViewHeight for y. Store the created Circle in a field instead of a
local variable so it is retained for future updates, and remove the
now-unnecessary unused suppression.
- Around line 240-251: Update the deferred command construction in the RobotSim
fuel-launch flow to clamp the value from ballSim.getTotalIntaked() to a
non-negative launch count before the loop builds waits and launches. Return
group1 directly and apply withName("RobotSim.ballSimLaunchFuel") to it instead
of wrapping it with Commands.parallel.
- Around line 186-191: Correct the intake-zone axis mapping in the visible
extent calculations: use the robot length/X extent when computing intakeXMax,
and use the intake width/Y extent for the Y bounds. Update the variable names
and conversions around intakeWidth and intakeLength as needed so the
calculations align with FuelPhysicsSim.configureRobot and handleRobotCollision.

In `@src/main/java/frc/robot/subsystems/fuelIntake/FuelIntake.java`:
- Around line 52-80: Collapse the duplicate WantedState/SystemState enums in
FuelIntake.java (lines 52-80) into one enum, update state handling to use it
directly, and remove handleStateTransition() while transitions remain identity
mappings. Apply the same change to Spindexer.java (lines 46-74) so both
subsystems use a single state enum without transition indirection.

In `@src/main/java/frc/robot/subsystems/intakeExtension/IntakeExtension.java`:
- Around line 199-203: Update setInitialPosition to convert
config.getInitPosition() with percentToRotations instead of degreesToRotations,
matching the subsystem’s other setpoints and maxRotations-based representation
while preserving the existing attachment check.
- Around line 184-232: Remove the unused inSpringyMode field and its
getter/setter from IntakeExtension, remove the corresponding
springyMode*CurrentLimit configuration values, and delete the
IntakeExtension/InSpringyMode telemetry entry in periodic(). Do not add new
state-machine behavior unless wiring SLOW_CLOSE to this flag is required by
existing design.
- Around line 205-215: Update resetCurrentPositionToMax() to call
motor.setPosition(config.getMaxRotations()) only when isAttached() is true,
matching setInitialPosition(). Change resetCurrentPositionToMaxCommand() and
resetToInitialPos() from run(...) to runOnce(...) so both reset commands execute
once and finish.
- Around line 157-182: Update applyStates() to use the existing config.fullOut,
config.home, and config.squeeze values instead of hardcoded 100, 0, and 25
setpoints. Replace the slow-close profile literals 4.0, 20.0, and 1000.0 with
appropriately named configuration constants, adding them to config if they do
not already exist.

In `@src/main/java/frc/robot/subsystems/launcher/Launcher.java`:
- Around line 103-121: Remove the obsolete `@SuppressWarnings`("unused")
annotations from handleStateTransition() and applyStates(), since periodic()
invokes both methods. In applyStates(), replace the hardcoded idle RPM value of
700 with config.getIdlingRPM() so the configured setter value controls IDLE_PREP
behavior.
- Around line 123-126: The ShotCalculator preference offsets are applied twice
by the launcher and turret consumers. In
src/main/java/frc/robot/subsystems/launcher/Launcher.java lines 123-126, update
the LAUNCH handling to assign params.flywheelSpeed() directly; in
src/main/java/frc/robot/subsystems/turret/Turret.java lines 143-152, use
params.turretAngle().getDegrees() directly. Remove both raw offset additions
while preserving the existing parameter retrieval and control flow.

In `@src/main/java/frc/robot/subsystems/leds/Leds.java`:
- Around line 27-42: Update the static initialization of ledsConfig to set the
documented startIdx offset of 8, so NUM_LEDS addresses the external LED strip at
device indices 8–27; keep the existing LED configuration settings unchanged and
ensure the Javadoc matches the resulting behavior.

In `@src/main/java/frc/robot/subsystems/spindexer/Spindexer.java`:
- Around line 76-95: Replace the guessed RPM setpoints in Spindexer.applyStates
with calibrated, hardware-validated values for INDEX_MAX, SLOW_INDEX, and UNJAM
before enabling them on the built robot; remove the placeholder TODO once the
values are sourced from characterization or an approved configuration.
- Around line 19-23: Make the Spindexer configuration fields supplyCurrentLimit,
statorCurrentLimit, velocityKp, velocityKv, and velocityKs final and remove
their setters, matching the immutable configuration pattern used by
FuelIntakeConfig. Preserve the existing constructor-based application of these
values to the Talon configuration.

In `@src/main/java/frc/robot/subsystems/SuperStructure.java`:
- Around line 275-285: Remove the duplicated
spindexer.setWantedState(Spindexer.WantedState.OFF) call in forceHome(), leaving
a single OFF state transition unless the surrounding subsystem initialization
identifies a missing intended call.
- Around line 106-122: Update handleStateTransitions() so Util.disabled forces
CurrentSuperState.AUTON_IDLE before evaluating wantedSuperState, while
preserving the existing autonomous-IDLE behavior and normal wantedSuperState
mappings when enabled. Ensure disabled mode cannot pass through launcher,
turret, or drive commands from any non-IDLE wanted state.

In `@src/main/java/frc/robot/subsystems/swerve/Swerve.java`:
- Around line 577-584: Update the overloaded isAtDesiredRotation(double
toleranceRadians) method to require systemState ==
SystemState.PILOT_AIM_AT_TARGET before evaluating
HeadingController.getPositionError(). Return false in all other states, while
preserving the existing tolerance comparison during pilot aim.
- Around line 258-277: Update applyStates() so the IDLE case issues a neutral
drivetrain control request via setControl, clearing any previously commanded
translational and rotational speeds. Preserve the existing behavior for
PILOT_AIM_AT_TARGET and TELEOP_DRIVE.
- Around line 211-230: Synchronize the bump-simulation state access in the
periodic() simulation block with the simNotifier thread that runs
mapleSimSwerveDrivetrain::update and SimulatedArena.simulationPeriodic().
Introduce or reuse a common simLock, wrapping the reads of simulated pose and
chassis speeds, robotBumpSim.update, and setSimulationWorldPose in synchronized
(simLock); ensure the notifier callback uses the same lock around its simulation
step.
- Around line 413-446: Update the zone-bound constants near NEUTRAL_ZONE and
ENEMY_ALLIANCE_ZONE to use Field.fieldLength instead of the hard-coded
FIELD_LENGTH_METERS value, while preserving the existing field-width handling
and zone geometry. Ensure isInEnemyAllianceZone remains aligned with
FieldHelpers.flipXifRed’s field-length mirror.
- Around line 263-270: Update the PILOT_AIM_AT_TARGET branch in Swerve.java so
DRIVE_AT_ANGLE_REQUEST.withTargetDirection uses a chassis heading computed from
the robot pose toward the target, rather than params.turretAngle(). Keep the
turret shot-angle calculation separate and preserve the existing joystick
velocity inputs.

In `@src/main/java/frc/robot/subsystems/swerve/SwerveConfig.java`:
- Around line 47-51: Update the comments above linearSpeedAt12Volts and
angularSpeedAt12Volts to describe their actual units: meters per second for
translational speed and degrees per second for rotational speed, without
changing the field types or values.
- Around line 102-106: Remove the redundant withSupplyCurrentLowerLimit call
from the current-limit configuration in SwerveConfig, since it duplicates
withSupplyCurrentLimit. Leave the 40A supply limit and its enable setting
unchanged.

In `@src/main/java/frc/robot/subsystems/turret/Turret.java`:
- Around line 155-162: Remove the unused TrapezoidProfile scaffolding from
Turret, including profile, turretSetpoint, and turretRequest, along with the
TurretConfig.turretConstraints construction and their assignments in the turret
initialization/update flow. Preserve the existing Talon Motion Magic control
through setMMPositionFoc.
- Around line 21-23: Reorder the imports in Turret.java so
frc.rebuilt.ShotCalculator appears before the Lombok import, matching the
project's formatter and allowing spotlessCheck to pass.

In `@src/main/java/frc/robot/subsystems/vision/Vision.java`:
- Around line 544-548: Enforce VisionConfig.kMaxTimeDeltaSeconds for both MT1
and MT2 pose-estimate paths before returning or submitting measurements to the
pose estimator, comparing each getMegaTagXPoseTimestamp() against the current
FPGA time and rejecting stale measurements. Apply the same age-gating behavior
at both estimate sites, or remove the unused configuration field if no gating is
intended.
- Around line 705-714: Update the Javadoc for Vision.tagsInView() to state that
an unknown alliance falls back to Blue, matching the existing
DriverStation.getAlliance().orElse(DriverStation.Alliance.Blue) behavior; leave
the implementation unchanged.
- Around line 876-877: Update the VisionFieldPoseEstimate nested class
declaration to be static, preserving its immutable data-holder behavior and
existing Lombok-generated accessors; do not change how callers construct or
consume estimates.
- Around line 448-451: Update the heading-discard condition in Vision’s rotation
handling to use the absolute value of robotSpeed.omegaRadiansPerSecond, matching
the Math.abs-based check in rejectionCheck(), so fast rotation in either
direction sets degStds to 50.
- Around line 794-796: Update resetPoseToVision() so the poseTimestamp passed to
addVisionMeasurement is converted with Utils.fpgaToCurrentTime(...), matching
the timestamp handling in the other estimate pipelines. Keep the existing
integratedPose and measurement uncertainty behavior unchanged.

In `@src/main/java/frc/spectrumLib/hardware/Rio.java`:
- Around line 27-28: Update the Rio enum serial registration and checkID() flow
to prevent blank or null serials from colliding in the IDs map: populate IDs
only for valid serial values, and make checkID() explicitly return SIM whenever
RobotBase.isReal() is false. Preserve real-hardware lookup so FM_2026 and
OM_2026 resolve to their own enum values and remain reachable by Robot().

In `@src/main/java/frc/spectrumLib/hardware/SpectrumServo.java`:
- Around line 10-19: Update the SpectrumServo constructor to register the
subsystem with the scheduler after initializing the Servo superclass. Ensure
every SpectrumServo instance invokes the inherited Subsystem registration
behavior so periodic methods and default commands are scheduler-managed.

In `@src/main/java/frc/spectrumLib/leds/SpectrumLEDs.java`:
- Around line 692-716: Update the edges method to handle clampedLen <= 0 before
constructing edge SolidColor ranges. In that case, configure a single SolidColor
covering the entire segment from startIdx through startIdx + numLeds - 1 with
black, then preserve the existing edge and optional-center behavior for positive
lengths.
- Around line 404-419: Document in the CANdlePattern javadoc that pattern
instances are stateful, capture the first applyTo segment and enclosing
animation slot, and must not be reused across SpectrumLEDs instances or
different segments; alternatively, update the lazy holder in blink and other
pattern factories to cache animations per incoming startIdx/numLeds and slot.
- Around line 661-680: Update the software patterns gradient, ombre, wave,
countdown, and switchCountdown to reduce CAN traffic by grouping contiguous LEDs
with identical colors into range-based SolidColor controls instead of calling
setControl once per LED on each loop. Preserve each pattern’s visual output, and
consider a hardware animation where equivalent.
- Around line 261-292: Honor config.isAttached() in SpectrumLEDs: only
create/configure the CANdle when the strip is attached, and prevent the default
command or pattern execution from calling candle.setControl(...) when it is
absent. Update the relevant default-command/write path while preserving
isAttached() as the exposed status check.

In `@src/main/java/frc/spectrumLib/README.md`:
- Line 17: Update src/main/java/frc/spectrumLib/README.md lines 17-17 to
describe leds as the CANdle pattern library, and update lines 99-106 to document
the current CANdle API and CTRE animation behavior instead of the removed
AddressableLED and buffer-view details.

In `@src/main/java/frc/spectrumLib/sim/ArmSim.java`:
- Line 50: Update the TurretSim construction/configuration to disable gravity
explicitly rather than using the default true value. Keep ArmSim’s
config.isSimulateGravity() forwarding unchanged, and ensure the TurretSim path
passes false to its SingleJointedArmSim setup.

In `@src/main/java/frc/spectrumLib/swerve/SysID.java`:
- Around line 20-21: Remove the commented-out swerve field from SysID and delete
the corresponding dead assignment in its constructor; keep using the constructor
parameter directly.
- Line 9: Remove the robot-specific Swerve dependency from SysID and change its
API to accept a reusable CTRE SwerveDrivetrain/Subsystem handle, or a minimal
interface exposing setControl(SwerveRequest). Update SysID’s construction and
control calls to use that abstraction while preserving its existing behavior.

In `@src/main/java/frc/spectrumLib/vision/Limelight.java`:
- Around line 175-179: Update the Limelight constructor to enforce one camera
identity: validate that the supplied name matches config.getName(), or derive
cameraName directly from config.getName() instead of storing an independent
value. Ensure pose methods and target-space methods consistently query the same
configured Limelight.
- Around line 402-407: Update getRawFiducial() to check isAttached() before
querying LimelightHelpers.getBotPoseEstimate_wpiBlue. Return an empty
RawFiducial array immediately when the camera is detached, while preserving the
existing null-estimate handling for attached cameras.

---

Outside diff comments:
In `@docs/tools/simulation.md`:
- Around line 76-77: Update the simulation documentation around the PathPlanner
dependency reference to retain a current MapleSim link, placing it inline at the
first MapleSim mention if no dedicated dependency link is appropriate. Ensure
the existing MapleSim references remain navigable without changing unrelated
documentation.

In `@src/main/java/frc/robot/subsystems/launcher/Launcher.java`:
- Around line 143-154: Update Launcher.periodic() to log both the current
WantedState and SystemState telemetry, matching the corresponding keys and value
style used by sibling subsystems such as IndexerTower, IntakeExtension, and
Swerve. Add these logs alongside the existing launcher telemetry without
changing the state-transition or actuator flow.
- Around line 23-40: Remove the unused settable LauncherSupplyCurrent and
LauncherStatorCurrent fields from Launcher, or consolidate the configuration so
the constructor and runtime setters use the same current-limit values; ensure no
competing field pair remains and generated setters cannot silently have no
effect.

In `@src/main/java/frc/spectrumLib/framework/SpectrumRobot.java`:
- Around line 20-34: Update the SpectrumRobot constructor so the watchdog
reflection block and CommandScheduler.getInstance().setPeriod(0.20) execute only
when isSimulation() is true; preserve the existing warning behavior and leave
real-hardware loop timing unchanged.

In `@src/main/java/frc/spectrumLib/framework/SpectrumState.java`:
- Around line 180-189: Update toggle() to delegate its state change to the
existing setState(boolean) method instead of directly mutating value, updating
alert, and calling setCondition. Preserve the current command behavior and
toggle the state by passing the inverse of the current value to setState.

In `@src/main/java/frc/spectrumLib/sim/Circle.java`:
- Around line 59-78: Update the Circle constructor overload that accepts
Color8Bit so the requested color is applied to every already-created background
ligament after delegating construction; assigning this.color alone is
insufficient. Reuse the existing ligament collection and color-application
mechanism in Circle, ensuring all radial lines visibly use the provided color
immediately.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 63327ba1-62cd-40f6-b61d-939f6d56c5ac

📥 Commits

Reviewing files that changed from the base of the PR and between 072e273 and e603014.

📒 Files selected for processing (115)
  • .vscode/settings.json
  • advantagescope-custom-assets/README.txt
  • advantagescope-custom-assets/Robot_FM/config.json
  • advantagescope-custom-assets/Robot_FM/model.glb
  • advantagescope-custom-assets/Robot_FM/model_0.glb
  • advantagescope-custom-assets/Robot_FM/model_1.glb
  • advantagescope-custom-assets/Robot_PM/config.json
  • advantagescope-custom-assets/Robot_PM/model.glb
  • advantagescope-custom-assets/Robot_PM/model_0.glb
  • advantagescope-custom-assets/Robot_PM/model_1.glb
  • docs/tools/simulation.md
  • simgui-ds.json
  • simgui-window.json
  • src/main/deploy/pathplanner/autos/TBTB Full.auto
  • src/main/java/edu/wpi/first/wpilibj2/command/button/README.md
  • src/main/java/edu/wpi/first/wpilibj2/command/button/Trigger.java
  • src/main/java/frc/rebuilt/Field.java
  • src/main/java/frc/rebuilt/FieldHelpers.java
  • src/main/java/frc/rebuilt/FuelPhysicsSim.java
  • src/main/java/frc/rebuilt/RobotBumpSim.java
  • src/main/java/frc/rebuilt/ShiftHelpers.java
  • src/main/java/frc/rebuilt/ShotCalculator.java
  • src/main/java/frc/rebuilt/TagProperties.java
  • src/main/java/frc/rebuilt/Zones.java
  • src/main/java/frc/rebuilt/launchingMaps/AndyMarkMap.java
  • src/main/java/frc/rebuilt/launchingMaps/HomeMap.java
  • src/main/java/frc/rebuilt/offsets/HomeOffsets.java
  • src/main/java/frc/rebuilt/targetFactories/FeedTargetFactory.java
  • src/main/java/frc/robot/Coordinator.java
  • src/main/java/frc/robot/Robot.java
  • src/main/java/frc/robot/RobotSim.java
  • src/main/java/frc/robot/RobotStates.java
  • src/main/java/frc/robot/State.java
  • src/main/java/frc/robot/auton/Auton.java
  • src/main/java/frc/robot/configs/FM2026.java
  • src/main/java/frc/robot/configs/OM2026.java
  • src/main/java/frc/robot/configs/PHOTON2026.java
  • src/main/java/frc/robot/configs/PM2026.java
  • src/main/java/frc/robot/configs/XM2026.java
  • src/main/java/frc/robot/fuelIntake/FuelIntakeStates.java
  • src/main/java/frc/robot/hood/Hood.java
  • src/main/java/frc/robot/hood/HoodStates.java
  • src/main/java/frc/robot/indexerBed/IndexerBed.java
  • src/main/java/frc/robot/indexerBed/IndexerBedStates.java
  • src/main/java/frc/robot/indexerTower/IndexerTower.java
  • src/main/java/frc/robot/indexerTower/IndexerTowerStates.java
  • src/main/java/frc/robot/intakeExtension/IntakeExtensionStates.java
  • src/main/java/frc/robot/launcher/LauncherStates.java
  • src/main/java/frc/robot/leds/CANdleLeds.java
  • src/main/java/frc/robot/leds/LedStates.java
  • src/main/java/frc/robot/operator/Operator.java
  • src/main/java/frc/robot/operator/OperatorStates.java
  • src/main/java/frc/robot/pilot/Pilot.java
  • src/main/java/frc/robot/pilot/PilotStates.java
  • src/main/java/frc/robot/subsystems/SuperStructure.java
  • src/main/java/frc/robot/subsystems/fuelIntake/FuelIntake.java
  • src/main/java/frc/robot/subsystems/indexerTower/IndexerTower.java
  • src/main/java/frc/robot/subsystems/intakeExtension/IntakeExtension.java
  • src/main/java/frc/robot/subsystems/launcher/Launcher.java
  • src/main/java/frc/robot/subsystems/leds/Leds.java
  • src/main/java/frc/robot/subsystems/spindexer/Spindexer.java
  • src/main/java/frc/robot/subsystems/swerve/Swerve.java
  • src/main/java/frc/robot/subsystems/swerve/SwerveConfig.java
  • src/main/java/frc/robot/subsystems/turret/Turret.java
  • src/main/java/frc/robot/subsystems/vision/Vision.java
  • src/main/java/frc/robot/swerve/SwerveStates.java
  • src/main/java/frc/robot/swerve/controllers/RotationController.java
  • src/main/java/frc/robot/swerve/controllers/TagCenterAlignController.java
  • src/main/java/frc/robot/swerve/controllers/TagDistanceAlignController.java
  • src/main/java/frc/robot/swerve/controllers/TranslationXController.java
  • src/main/java/frc/robot/swerve/controllers/TranslationYController.java
  • src/main/java/frc/robot/vision/Vision.java
  • src/main/java/frc/robot/vision/VisionStates.java
  • src/main/java/frc/robot/vision/VisionSystem.java
  • src/main/java/frc/spectrumLib/README.md
  • src/main/java/frc/spectrumLib/SpectrumCANcoderConfig.java
  • src/main/java/frc/spectrumLib/SpectrumServo.java
  • src/main/java/frc/spectrumLib/SpectrumSubsystem.java
  • src/main/java/frc/spectrumLib/TuneValue.java
  • src/main/java/frc/spectrumLib/framework/SpectrumRobot.java
  • src/main/java/frc/spectrumLib/framework/SpectrumState.java
  • src/main/java/frc/spectrumLib/gamepads/Gamepad.java
  • src/main/java/frc/spectrumLib/hardware/Rio.java
  • src/main/java/frc/spectrumLib/hardware/SpectrumCANcoder.java
  • src/main/java/frc/spectrumLib/hardware/SpectrumCANcoderConfig.java
  • src/main/java/frc/spectrumLib/hardware/SpectrumServo.java
  • src/main/java/frc/spectrumLib/hardware/TalonFXFactory.java
  • src/main/java/frc/spectrumLib/leds/SpectrumLEDs.java
  • src/main/java/frc/spectrumLib/mechanism/Mechanism.java
  • src/main/java/frc/spectrumLib/sim/ArmConfig.java
  • src/main/java/frc/spectrumLib/sim/ArmSim.java
  • src/main/java/frc/spectrumLib/sim/Circle.java
  • src/main/java/frc/spectrumLib/sim/LinearConfig.java
  • src/main/java/frc/spectrumLib/sim/LinearSim.java
  • src/main/java/frc/spectrumLib/sim/Mount.java
  • src/main/java/frc/spectrumLib/sim/Mountable.java
  • src/main/java/frc/spectrumLib/sim/RollerConfig.java
  • src/main/java/frc/spectrumLib/sim/RollerSim.java
  • src/main/java/frc/spectrumLib/swerve/MapleSimSwerveDrivetrain.java
  • src/main/java/frc/spectrumLib/swerve/SysID.java
  • src/main/java/frc/spectrumLib/telemetry/BatteryLogger.java
  • src/main/java/frc/spectrumLib/telemetry/Telemetry.java
  • src/main/java/frc/spectrumLib/telemetry/TuneValue.java
  • src/main/java/frc/spectrumLib/util/CachedDouble.java
  • src/main/java/frc/spectrumLib/util/CanDeviceId.java
  • src/main/java/frc/spectrumLib/util/CrashTracker.java
  • src/main/java/frc/spectrumLib/util/ExpCurve.java
  • src/main/java/frc/spectrumLib/util/Network.java
  • src/main/java/frc/spectrumLib/util/Trio.java
  • src/main/java/frc/spectrumLib/util/Util.java
  • src/main/java/frc/spectrumLib/util/exceptions/KillRobotException.java
  • src/main/java/frc/spectrumLib/vision/Limelight.java
  • src/main/java/frc/spectrumLib/vision/VisionLogger.java
  • vendordeps/Phoenix6-26.3.0.json
  • vendordeps/photonlib.json
💤 Files with no reviewable changes (38)
  • src/main/java/frc/rebuilt/Zones.java
  • src/main/java/frc/robot/swerve/controllers/TranslationXController.java
  • src/main/java/frc/spectrumLib/SpectrumSubsystem.java
  • src/main/java/frc/robot/swerve/controllers/TagDistanceAlignController.java
  • src/main/java/frc/rebuilt/offsets/HomeOffsets.java
  • src/main/java/edu/wpi/first/wpilibj2/command/button/README.md
  • src/main/java/frc/rebuilt/launchingMaps/AndyMarkMap.java
  • src/main/java/frc/rebuilt/launchingMaps/HomeMap.java
  • src/main/java/frc/robot/swerve/controllers/TranslationYController.java
  • src/main/java/frc/robot/swerve/controllers/RotationController.java
  • src/main/java/frc/robot/vision/VisionStates.java
  • src/main/java/frc/spectrumLib/SpectrumServo.java
  • src/main/java/frc/spectrumLib/TuneValue.java
  • src/main/java/frc/robot/swerve/SwerveStates.java
  • src/main/java/frc/robot/leds/CANdleLeds.java
  • src/main/java/frc/robot/swerve/controllers/TagCenterAlignController.java
  • src/main/java/frc/robot/State.java
  • src/main/java/frc/robot/indexerTower/IndexerTowerStates.java
  • src/main/java/frc/spectrumLib/SpectrumCANcoderConfig.java
  • src/main/java/frc/robot/RobotStates.java
  • src/main/java/frc/robot/operator/OperatorStates.java
  • src/main/java/frc/robot/fuelIntake/FuelIntakeStates.java
  • src/main/java/frc/robot/indexerTower/IndexerTower.java
  • src/main/java/edu/wpi/first/wpilibj2/command/button/Trigger.java
  • src/main/java/frc/robot/pilot/PilotStates.java
  • src/main/java/frc/robot/vision/VisionSystem.java
  • src/main/java/frc/robot/hood/Hood.java
  • src/main/java/frc/robot/hood/HoodStates.java
  • src/main/java/frc/robot/intakeExtension/IntakeExtensionStates.java
  • src/main/java/frc/robot/launcher/LauncherStates.java
  • src/main/java/frc/robot/indexerBed/IndexerBedStates.java
  • src/main/java/frc/rebuilt/FieldHelpers.java
  • vendordeps/photonlib.json
  • src/main/java/frc/robot/vision/Vision.java
  • src/main/java/frc/rebuilt/TagProperties.java
  • src/main/java/frc/robot/indexerBed/IndexerBed.java
  • src/main/java/frc/robot/leds/LedStates.java
  • src/main/java/frc/robot/Coordinator.java
👮 Files not reviewed due to content moderation or server errors (1)
  • advantagescope-custom-assets/Robot_FM/model_1.glb

Comment thread .vscode/settings.json
],
"java.compile.nullAnalysis.mode": "automatic",
"java.debug.settings.onBuildFailureProceed": true
"java.debug.settings.onBuildFailureProceed": true,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== .vscode/settings.json (around line 61) ==\n'
nl -ba .vscode/settings.json | sed -n '45,75p'

printf '\n== Search for related Java debug/build settings ==\n'
rg -n '"java\.debug\.settings\.onBuildFailureProceed"|"java\.jdt\.ls\.vmargs"|"java\.debug\.settings\.' .vscode settings.json . || true

Repository: Spectrum3847/2026-Spectrum

Length of output: 250


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== .vscode/settings.json (around line 61) ==\n'
awk 'NR>=45 && NR<=75 { printf "%4d  %s\n", NR, $0 }' .vscode/settings.json

printf '\n== Search for related Java debug/build settings ==\n'
rg -n '"java\.debug\.settings\.onBuildFailureProceed"|"java\.jdt\.ls\.vmargs"|"java\.debug\.settings\.' .vscode . || true

Repository: Spectrum3847/2026-Spectrum

Length of output: 1257


🌐 Web query:

Java debug settings onBuildFailureProceed last successful artifact after build failure documentation

💡 Result:

The setting java.debug.settings.onBuildFailureProceed is a configuration option specifically for the Visual Studio Code Debugger for Java extension [1][2]. It is unrelated to retrieving artifacts after a build failure [3]. ### Understanding java.debug.settings.onBuildFailureProceed This setting controls whether the VS Code Java debugger automatically continues and launches the program even if the workspace build (compilation) fails [1]. * When set to true: The debugger suppresses the "Build failed, do you want to continue?" prompt and proceeds with the launch using the previously compiled (and potentially outdated) classes [1][3]. * When set to false (default): The debugger displays a warning prompt when a build failure occurs, allowing the user to choose whether to continue, always continue (which updates the setting to true), or fix the errors [1][4][3]. This setting does not manage or retrieve build artifacts; it solely dictates the debugger's behavior in the presence of compiler errors within the IDE [3]. ### Managing Artifacts After Build Failures If you are looking to retrieve artifacts from a "last successful build" after a failure, this functionality is typically found in CI/CD platforms rather than local Java debugger settings [5][6][7]. * Jenkins: The Copy Artifact plugin allows you to select artifacts from the "Last successful build" of a project [6]. Pipeline scripts can use selectors like lastSuccessful() to target these builds [8][9]. * TeamCity: Artifact dependencies can be configured to import artifacts from the "Latest successful build" specifically [7]. If you are encountering build failures in a local VS Code environment, the java.debug.settings.onBuildFailureProceed setting will not help you access a previous successful build; it will only force the debugger to run the current, broken state of your code [3]. If you need a stable version, you should revert your source code to the last known good commit using your version control system (e.g., Git) [1][4].

Citations:


Do not proceed after a failed build
java.debug.settings.onBuildFailureProceed should be false here; when enabled, the debugger skips the build-failed prompt and can launch with stale classes, which makes validation results misleading.

Suggested setting
-  "java.debug.settings.onBuildFailureProceed": true,
+  "java.debug.settings.onBuildFailureProceed": false,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"java.debug.settings.onBuildFailureProceed": true,
"java.debug.settings.onBuildFailureProceed": false,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.vscode/settings.json at line 61, Update the
java.debug.settings.onBuildFailureProceed setting in the VS Code configuration
to false so debugging does not continue after a failed build.

Comment thread .vscode/settings.json
"java.compile.nullAnalysis.mode": "automatic",
"java.debug.settings.onBuildFailureProceed": true
"java.debug.settings.onBuildFailureProceed": true,
"java.jdt.ls.vmargs": "-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx8G -Xms100m -Xlog:disable"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'FILE: .vscode/settings.json\n'
wc -l .vscode/settings.json
printf '\n--- lines around 62 ---\n'
sed -n '50,75p' .vscode/settings.json

printf '\n--- occurrences of java.jdt.ls.vmargs ---\n'
rg -n '"java\.jdt\.ls\.vmargs"' -S .

printf '\n--- workspace docs mentioning VS Code / Java settings ---\n'
rg -n 'VS Code|vscode|java\.jdt\.ls\.vmargs|JDT LS|Gradle|Glass' -S README* .github .vscode docs . 2>/dev/null | sed -n '1,200p'

Repository: Spectrum3847/2026-Spectrum

Length of output: 805


Lower the tracked JDT LS heap. .vscode/settings.json sets java.jdt.ls.vmargs to -Xmx8G, which every contributor inherits; on smaller machines it can consume a large share of RAM. Use a smaller workspace default and let users raise it in their own settings if needed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.vscode/settings.json at line 62, Update the java.jdt.ls.vmargs setting in
the workspace configuration to replace the tracked -Xmx8G maximum heap with a
substantially smaller default, while preserving the other JVM arguments. Users
should still be able to override the heap size in their personal settings.

Comment thread docs/tools/simulation.md Outdated
4. If an auto is selected, drag `SmartDashboard/Field2d/Auto Routine` in as a trajectory/poses object so the planned path and simulated robot motion can be compared.

You can also visualize flying fuel projectiles: `RobotSim.createFuelProjectile()` publishes them to NetworkTables under `Sim/Fuel/Positions`, and you can drag those entries into the 3D field to watch shots in flight.
You can also drive things like FuelInFlight and whatnot to simulate flying fuel.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the referenced documentation and any mentions of FuelInFlight / AdvantageScope / NetworkTables.
git ls-files | rg '(^|/)docs/tools/simulation\.md$|FuelInFlight|AdvantageScope|NetworkTables|simulation'

Repository: Spectrum3847/2026-Spectrum

Length of output: 189


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the documentation file around the referenced line.
file="docs/tools/simulation.md"
wc -l "$file"
cat -n "$file" | sed -n '1,120p'

Repository: Spectrum3847/2026-Spectrum

Length of output: 6845


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for the specific term and nearby implementation details.
rg -n -C 3 'FuelInFlight|flying fuel|AdvantageScope|NetworkTables|Network Table|NT' .

Repository: Spectrum3847/2026-Spectrum

Length of output: 50385


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Read only the relevant documentation and search for implementation references.
printf '\n=== docs/tools/simulation.md ===\n'
wc -l docs/tools/simulation.md
cat -n docs/tools/simulation.md | sed -n '1,120p'

printf '\n=== FuelInFlight references ===\n'
rg -n -C 4 'FuelInFlight|flying fuel|fuel in flight|AdvantageScope|NetworkTables|Network Table|NT' . || true

Repository: Spectrum3847/2026-Spectrum

Length of output: 50385


🌐 Web query:

"FuelInFlight AdvantageScope NetworkTables path pose format simulation"

💡 Result:

Based on current technical documentation, there is no tool or standard feature named "FuelInFlight" related to AdvantageScope, NetworkTables, or robot simulation [1][2][3]. AdvantageScope is a widely used FRC data visualization and log analysis tool that supports NetworkTables (NT4), WPILOG files, and Driver Station logs [1][3][4]. For visualizing poses (such as robot odometry or trajectories) in AdvantageScope, the standard approach involves publishing structured data to NetworkTables [5][6]. Key aspects of this process include: 1. Data Format: AdvantageScope supports standard WPILib struct and protobuf serialization [5]. Developers typically use the StructPublisher class in WPILib to publish Pose2d or Pose3d objects to a specific NetworkTables path [5][6]. 2. Path Usage: You define a NetworkTables path (e.g., /MyPose) and associate it with the appropriate struct (e.g., Pose2d.struct) [5][6]. 3. Simulation Integration: AdvantageScope can connect directly to a robot simulator or read.wpilog files generated during simulation [1][3][4]. Simulation frameworks (like AdvantageKit) can automatically generate these logs, which AdvantageScope then renders for 2D or 3D visualization [7][2][4]. If "FuelInFlight" is a custom project, library, or specific simulation component, it does not appear in standard FRC or AdvantageScope documentation. You may wish to check the specific documentation for your proprietary codebase or simulation environment.

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the simulation code that publishes the fuel/flying-ball data.
ast-grep outline src/main/java/frc/robot/RobotSim.java --view expanded || true
printf '\n=== RobotSim fuel-related slice ===\n'
cat -n src/main/java/frc/robot/RobotSim.java | sed -n '1,260p'

printf '\n=== fuel / ball physics references ===\n'
rg -n -C 3 'FuelPhysicsSim|ballSim|getTotalIntaked|publish.*NT|NetworkTables|FuelInFlight|Sim/Fuel' src/main/java/frc/robot src/main/java/frc/spectrumLib

Repository: Spectrum3847/2026-Spectrum

Length of output: 33657


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate and inspect the fuel physics simulation class and any published topic names.
fuel_file=$(git ls-files | rg 'FuelPhysicsSim\.java$' | head -n 1)
printf 'Fuel file: %s\n' "$fuel_file"
wc -l "$fuel_file"
cat -n "$fuel_file" | sed -n '1,260p'

printf '\n=== references to topic/path strings in fuel simulation ===\n'
rg -n '"[^"]*(Fuel|fuel|Ball|ball|Sim/)"|Telemetry\.log|StructPublisher|Field2d|NetworkTables' "$fuel_file" src/main/java/frc/robot/Robot.java src/main/java/frc/robot/RobotSim.java || true

Repository: Spectrum3847/2026-Spectrum

Length of output: 17597


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Identify any simulation-time publications for the ball/fuel visualization.
rg -n -C 4 'Telemetry\.log\("Sim/Fuel"|Sim/Fuel|createSimBallLaunch|FuelPhysicsSim|getBallSim|getTotalIntaked|NetworkTables|StructPublisher|Field2d|Pose2d|Pose3d' src/main/java/frc/robot src/main/java/frc/spectrumLib

Repository: Spectrum3847/2026-Spectrum

Length of output: 50383


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the publishing helpers in FuelPhysicsSim around the NT API and the tick method.
file="src/main/java/frc/rebuilt/FuelPhysicsSim.java"
sed -n '760,860p' "$file"
printf '\n=== tick / publishing section ===\n'
sed -n '2260,2325p' "$file"

Repository: Spectrum3847/2026-Spectrum

Length of output: 6717


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Look for the exact topic names and data types used for the ball visualization.
rg -n -C 3 'StructArrayPublisher|DoublePublisher|IntegerPublisher|publish|create.*Publisher|tableKey|balls|Pose3d|Pose2d|trajectory|FuelInFlight' src/main/java/frc/rebuilt/FuelPhysicsSim.java

Repository: Spectrum3847/2026-Spectrum

Length of output: 28420


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
text = Path("src/main/java/frc/rebuilt/FuelPhysicsSim.java").read_text()
for needle in [
    "StructArrayPublisher",
    "tableKey",
    "Pose3d",
    "Pose2d",
    "launchBall(",
    "publish",
    "Sim/Fuel",
    "ballPos",
    "ballPositions",
]:
    idx = text.find(needle)
    print(f"--- {needle} ---")
    if idx == -1:
        print("not found")
    else:
        start = max(0, idx-400)
        end = min(len(text), idx+1200)
        print(text[start:end])
        print()
PY

Repository: Spectrum3847/2026-Spectrum

Length of output: 9973


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# If the NT publisher names are difficult to spot in the full file, extract the exact methods around the publishing section.
file="src/main/java/frc/rebuilt/FuelPhysicsSim.java"
awk 'NR>=779 && NR<=860 {print NR ":" $0}' "$file"
printf '\n=== around 2288 ===\n'
awk 'NR>=2280 && NR<=2335 {print NR ":" $0}' "$file"

Repository: Spectrum3847/2026-Spectrum

Length of output: 6202


Name the actual sim topics. Replace FuelInFlight with Sim/Fuel/InFlight (Translation3d[]) in AdvantageScope’s 3D Field flow; Sim/Fuel/LastShotArc is the other relevant topic here.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/tools/simulation.md` at line 44, Update the simulation documentation
sentence to name the actual AdvantageScope 3D Field topics: replace FuelInFlight
with Sim/Fuel/InFlight, identify its type as Translation3d[], and mention
Sim/Fuel/LastShotArc as the other relevant topic.

Comment thread simgui-window.json
Comment on lines +4 to +8
"DockNode ID=0x00000001 Pos=4,942 Size=983,285 Selected=0x48913727",
"DockNode ID=0x00000003 Pos=983,443 Size=877,514 Split=X",
"DockNode ID=0x00000004 Parent=0x00000003 SizeRef=238,497 Selected=0xFA2A8FFA",
"DockNode ID=0x00000006 Parent=0x00000003 SizeRef=235,497 Selected=0xA6A62DF3",
"DockNode ID=0x00000005 Pos=9,29 Size=2242,790 Split=X",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="simgui-window.json"

echo "== File info =="
wc -l "$file"
echo

echo "== Relevant lines =="
cat -n "$file" | sed -n '1,120p'
echo

echo "== Coordinate check =="
python3 - <<'PY'
import json, re, sys, pathlib

path = pathlib.Path("simgui-window.json")
text = path.read_text()

# Extract all quoted strings and look for common ImGui layout fields.
strings = re.findall(r'"([^"]*)"', text)

nums = []
for s in strings:
    if any(k in s for k in ("Pos=", "Size=", "SizeRef=", "MainWindow", "DockNode")):
        nums.append(s)

print("Matched strings:", len(nums))
for s in nums:
    print(s)

# Parse simple numeric extents where possible
def parse_kv(s):
    out = {}
    for key in ("Pos", "Size", "SizeRef"):
        m = re.search(rf'{key}=(-?\d+),(-?\d+)', s)
        if m:
            out[key] = (int(m.group(1)), int(m.group(2)))
    return out

xs, ys = [], []
for s in strings:
    kv = parse_kv(s)
    if "Pos" in kv:
        x, y = kv["Pos"]
        xs.append(x); ys.append(y)
    if "Size" in kv:
        w, h = kv["Size"]
        # only for strings that also have Pos
        if "Pos" in kv:
            x, y = kv["Pos"]
            xs.append(x + w); ys.append(y + h)

print()
if xs and ys:
    print("Observed x range:", min(xs), "to", max(xs))
    print("Observed y range:", min(ys), "to", max(ys))
PY

Repository: Spectrum3847/2026-Spectrum

Length of output: 6360


Keep the Glass layout within the window bounds. simgui-window.json stores dock/window positions past the 1920×974 main window (for example, the Alerts and Scheduler panes sit beyond the right edge), so this layout can reopen off-screen on a single-monitor setup. Normalize the saved coordinates before committing.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@simgui-window.json` around lines 4 - 8, Normalize the saved Glass dock layout
in simgui-window.json so all window and dock positions remain within the
1920×974 main-window bounds, especially the panes positioned beyond the right
edge. Adjust the affected Pos and Size values while preserving the existing dock
hierarchy and split relationships.

Comment on lines +193 to +206
turretAngle = turretAngle.plus(Rotation2d.fromDegrees(TURRET_ANGLE_OFFSET_DEGREES));

// Drive angular velocity (rad/s) for your position controller feedforward
if (lastDriveAngle == null) lastDriveAngle = driveAngle;
// Turret angular velocity (rot/s) for your position controller feedforward
if (lastTurretAngle == null) lastTurretAngle = turretAngle;
double deltaRot =
MathUtil.inputModulus(driveAngle.minus(lastDriveAngle).getRotations(), -0.5, 0.5);

double rawDriveOmega = deltaRot / loopPeriodSecs;
double driveAngularVelocity = driveAngleFilter.calculate(rawDriveOmega);
lastDriveAngle = driveAngle;

// Hood angle from map with offset
double hoodAngle = hoodAngleMap.get(lookaheadDistance);
if (Double.isNaN(lastHoodAngle)) lastHoodAngle = hoodAngle;
double hoodVelocity =
hoodAngleFilter.calculate((hoodAngle - lastHoodAngle) / loopPeriodSecs);
lastHoodAngle = hoodAngle;
MathUtil.inputModulus(turretAngle.minus(lastTurretAngle).getRotations(), -0.5, 0.5);

// Apply hood angle offset
hoodAngle += HOOD_ANGLE_OFFSET;
double rawOmega = deltaRot / loopPeriodSecs;
double turretAngularVelocityRotPerSec = turretOmegaFilter.calculate(rawOmega);
lastTurretAngle = turretAngle;

// Flywheel from map + preference offset (%)
double flywheelSpeed = launcherSpeedMap.get(lookaheadDistance);
double flywheelSpeed = shotFlywheelSpeedMap.get(lookaheadDistance);
flywheelSpeed += flywheelSpeed * (FLYWHEEL_SPEED_OFFSET / 100.0);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🔴 Critical | ⚡ Quick win

Tuning offsets are applied twice — once here, once at the consumers.

TURRET_ANGLE_OFFSET_DEGREES is added into turretAngle here (line 193), but per the relevant_code_snippets, Turret.java adds ShotCalculator.TURRET_ANGLE_OFFSET_DEGREES again on top of params.turretAngle().getDegrees() — doubling the same degree offset. Similarly, FLYWHEEL_SPEED_OFFSET is applied here as a percentage multiplier (line 206), but Launcher.java adds the raw FLYWHEEL_SPEED_OFFSET value again as an RPM increment on top of params.flywheelSpeed() — compounding the offset in two different units/semantics. Either remove the internal application here (leaving the offset entirely to consumers) or remove the redundant re-application in Launcher.java/Turret.java, but not both.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/frc/rebuilt/ShotCalculator.java` around lines 193 - 206, Remove
the offset applications from ShotCalculator’s calculation flow: stop adding
TURRET_ANGLE_OFFSET_DEGREES to turretAngle and stop applying
FLYWHEEL_SPEED_OFFSET to flywheelSpeed. Preserve the raw map-derived angle and
speed so Turret and Launcher remain the sole consumers applying their respective
offsets.

Comment on lines +794 to +796
Robot.getSwerve()
.addVisionMeasurement(
integratedPose, poseTimestamp, VecBuilder.fill(0.00001, 0.00001, 0.00001));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Pose-reset measurement uses a raw FPGA timestamp instead of the Phoenix time base.

Both estimate pipelines convert with Utils.fpgaToCurrentTime(...) before calling addVisionMeasurement (Lines 461 and 546), but here poseTimestamp — sourced straight from ll.getMegaTag1PoseTimestamp() in resetPoseToVision() (Line 744) — is passed through unconverted. Phoenix's pose estimator interprets it on its own clock, so the reset is applied with an arbitrary latency offset and can be discarded or mis-interpolated.

⏱️ Proposed fix
         Robot.getSwerve()
                 .addVisionMeasurement(
-                        integratedPose, poseTimestamp, VecBuilder.fill(0.00001, 0.00001, 0.00001));
+                        integratedPose,
+                        Utils.fpgaToCurrentTime(poseTimestamp),
+                        VecBuilder.fill(0.00001, 0.00001, 0.00001));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Robot.getSwerve()
.addVisionMeasurement(
integratedPose, poseTimestamp, VecBuilder.fill(0.00001, 0.00001, 0.00001));
Robot.getSwerve()
.addVisionMeasurement(
integratedPose,
Utils.fpgaToCurrentTime(poseTimestamp),
VecBuilder.fill(0.00001, 0.00001, 0.00001));
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/frc/robot/subsystems/vision/Vision.java` around lines 794 -
796, Update resetPoseToVision() so the poseTimestamp passed to
addVisionMeasurement is converted with Utils.fpgaToCurrentTime(...), matching
the timestamp handling in the other estimate pipelines. Keep the existing
integratedPose and measurement uncertainty behavior unchanged.

Comment on lines +876 to +877
@Getter
public class VisionFieldPoseEstimate {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Make VisionFieldPoseEstimate a static nested class.

It's a pure immutable data holder but is declared as an inner class, so every estimate (one or two per loop) captures an implicit Vision.this reference for no reason. A record would be even tighter.

♻️ Proposed refactor
-    `@Getter`
-    public class VisionFieldPoseEstimate {
+    `@Getter`
+    public static class VisionFieldPoseEstimate {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@Getter
public class VisionFieldPoseEstimate {
`@Getter`
public static class VisionFieldPoseEstimate {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/frc/robot/subsystems/vision/Vision.java` around lines 876 -
877, Update the VisionFieldPoseEstimate nested class declaration to be static,
preserving its immutable data-holder behavior and existing Lombok-generated
accessors; do not change how callers construct or consume estimates.

├── util/ General-purpose utilities and math helpers
├── mechanism/ Abstract TalonFX-driven mechanism base class
├── gamepads/ Xbox controller abstraction with deadbanding and rumble
├── leds/ AddressableLED wrapper with built-in pattern library

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Migrate LED documentation from AddressableLED to CANdle. The library now uses CANdle patterns and CTRE animations, but both sections document the removed AddressableLED model.

  • src/main/java/frc/spectrumLib/README.md#L17-L17: describe leds as the CANdle pattern library.
  • src/main/java/frc/spectrumLib/README.md#L99-L106: replace AddressableLED and buffer-view details with the current CANdle API and behavior.
📍 Affects 1 file
  • src/main/java/frc/spectrumLib/README.md#L17-L17 (this comment)
  • src/main/java/frc/spectrumLib/README.md#L99-L106
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/frc/spectrumLib/README.md` at line 17, Update
src/main/java/frc/spectrumLib/README.md lines 17-17 to describe leds as the
CANdle pattern library, and update lines 99-106 to document the current CANdle
API and CTRE animation behavior instead of the removed AddressableLED and
buffer-view details.

Comment on lines 175 to 179
public Limelight(String name, int pipeline, LimelightConfig config) {
this(name);
cameraName = name;
this.config = config;
setLimelightPipeline(pipeline);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use one camera identity consistently.

Pose methods query config.getName(), while target-space methods query cameraName. This constructor stores them independently, so mismatched inputs silently combine pose data from one Limelight with aiming data from another. Derive cameraName from config, or reject unequal names.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/frc/spectrumLib/vision/Limelight.java` around lines 175 - 179,
Update the Limelight constructor to enforce one camera identity: validate that
the supplied name matches config.getName(), or derive cameraName directly from
config.getName() instead of storing an independent value. Ensure pose methods
and target-space methods consistently query the same configured Limelight.

Comment on lines 402 to +407
public RawFiducial[] getRawFiducial() {
return LimelightHelpers.getBotPoseEstimate_wpiBlue(config.name).rawFiducials;
PoseEstimate est = LimelightHelpers.getBotPoseEstimate_wpiBlue(config.name);
if (est == null) {
return new RawFiducial[0];
}
return est.rawFiducials;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Honor the detached-camera empty-array contract.

getRawFiducial() bypasses isAttached(), unlike the neighboring pose methods. A detached camera can therefore query stale NetworkTables data instead of returning the documented empty array.

Proposed fix
 public RawFiducial[] getRawFiducial() {
+    if (!isAttached()) {
+        return new RawFiducial[0];
+    }
     PoseEstimate est = LimelightHelpers.getBotPoseEstimate_wpiBlue(config.name);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public RawFiducial[] getRawFiducial() {
return LimelightHelpers.getBotPoseEstimate_wpiBlue(config.name).rawFiducials;
PoseEstimate est = LimelightHelpers.getBotPoseEstimate_wpiBlue(config.name);
if (est == null) {
return new RawFiducial[0];
}
return est.rawFiducials;
public RawFiducial[] getRawFiducial() {
if (!isAttached()) {
return new RawFiducial[0];
}
PoseEstimate est = LimelightHelpers.getBotPoseEstimate_wpiBlue(config.name);
if (est == null) {
return new RawFiducial[0];
}
return est.rawFiducials;
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/frc/spectrumLib/vision/Limelight.java` around lines 402 - 407,
Update getRawFiducial() to check isAttached() before querying
LimelightHelpers.getBotPoseEstimate_wpiBlue. Return an empty RawFiducial array
immediately when the camera is detached, while preserving the existing
null-estimate handling for attached cameras.

@Project516

Copy link
Copy Markdown
Contributor Author

@coderabbitai rate limit

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Your plan includes PR reviews subject to rate limits. Reviews are available now.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review continued from previous batch...

Comment on lines +289 to +292
double blueTowerX = 1.067;
double redTowerX = 15.494;
double blueTowerY = 4.039;
double redTowerY = 4.318;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the duplicated tower geometry literals into constants.

blueTowerY = 4.039 / redTowerY = 4.318 (and halfSpacing) are re-declared verbatim in the second static block (Lines 420-422), and tower X positions are inline literals. If one copy is retuned the AABB uprights and the rung cylinders silently disagree.

♻️ Suggested extraction
+    private static final double BLUE_TOWER_X = 1.067;
+    private static final double RED_TOWER_X = 15.494;
+    private static final double BLUE_TOWER_Y = 4.039;
+    private static final double RED_TOWER_Y = 4.318;
+    private static final double TOWER_HALF_SPACING = TOWER_UPRIGHT_SPACING / 2.0;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/frc/rebuilt/FuelPhysicsSim.java` around lines 289 - 292,
Extract the shared tower geometry values used by both static blocks in
FuelPhysicsSim into named constants, including blue/red tower X and Y positions
and halfSpacing. Replace the inline literals and duplicate local declarations in
the AABB upright and rung-cylinder setup with those constants so all tower
geometry remains synchronized.

Comment on lines +722 to +737
boolean shouldIntake(SimBall ball, Pose2d robotPose, double bumperHeight) {
if (!active.getAsBoolean() || ball.pos.getZ() > bumperHeight) return false;
Translation2d relPos =
new Pose2d(ball.pos.toTranslation2d(), Rotation2d.kZero)
.relativeTo(robotPose)
.getTranslation();
boolean inside =
relPos.getX() >= xMin
&& relPos.getX() <= xMax
&& relPos.getY() >= yMin
&& relPos.getY() <= yMax;
if (inside) {
callback.run();
}
return inside;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

shouldIntake mutates state (runs callback) from a predicate.

A should* query firing the pickup callback is surprising and will misfire if a future caller ever probes without consuming. Prefer returning the decision and letting handleIntakePickup invoke intake.callback.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/frc/rebuilt/FuelPhysicsSim.java` around lines 722 - 737, Update
shouldIntake so it only computes and returns whether the ball is eligible,
removing the callback.run side effect. Move intake.callback invocation into
handleIntakePickup, executing it only after shouldIntake returns true during
actual pickup handling.

Comment on lines +984 to +986
totalLaunched++;
totalIntaked--;
lastLaunchSpeed = vel.getNorm();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

totalIntaked is used as both a lifetime counter and the live hopper count, and it can go negative. launchBall decrements it unconditionally while handleIntakePickup compares it against hopperSize and RobotSim reads it to decide how many balls to fire; once it drifts below zero the hopper gate and the launch count are both wrong.

  • src/main/java/frc/rebuilt/FuelPhysicsSim.java#L984-L986: stop decrementing below zero (or introduce a separate heldBalls field, keeping totalIntaked monotonic for telemetry).
  • src/main/java/frc/robot/RobotSim.java#L240-L251: clamp the snapshot with Math.max(0, ballSim.getTotalIntaked()) before dividing by numOfLanes, and return group1 directly instead of wrapping a single command in Commands.parallel.
📍 Affects 2 files
  • src/main/java/frc/rebuilt/FuelPhysicsSim.java#L984-L986 (this comment)
  • src/main/java/frc/robot/RobotSim.java#L240-L251
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/frc/rebuilt/FuelPhysicsSim.java` around lines 984 - 986,
Prevent launchBall in FuelPhysicsSim from decrementing totalIntaked below zero,
or introduce a separate held-ball count while preserving totalIntaked as a
monotonic telemetry counter. In RobotSim, clamp the totalIntaked snapshot with
Math.max(0, ...) before dividing by numOfLanes, and return group1 directly
instead of wrapping the single command in Commands.parallel; apply these changes
at FuelPhysicsSim.java:984-986 and RobotSim.java:240-251.

Comment on lines +1192 to +1227
if (config.sleepingEnabled) {
for (int i = 0; i < balls.size(); i++) {
updateSleepState(balls.get(i));
}
}

// Out-of-bounds cleanup (includes NaN guard, upper Z limit, and stuck-on-obstacle removal)
for (int i = 0; i < balls.size(); i++) {
SimBall ball = balls.get(i);
if (!Double.isFinite(ball.pos.getX())
|| !Double.isFinite(ball.pos.getY())
|| !Double.isFinite(ball.pos.getZ())
|| !Double.isFinite(ball.vel.getX())
|| !Double.isFinite(ball.vel.getY())
|| !Double.isFinite(ball.vel.getZ())
|| !Double.isFinite(ball.omega.getX())
|| !Double.isFinite(ball.omega.getY())
|| !Double.isFinite(ball.omega.getZ())
|| ball.pos.getX() < -2.0
|| ball.pos.getX() > FIELD_LENGTH + 2.0
|| ball.pos.getY() < -2.0
|| ball.pos.getY() > FIELD_WIDTH + 2.0
|| ball.pos.getZ() < -1.0
|| ball.pos.getZ() > 15.0) {
ball.outOfBounds = true;
}
// Remove balls stuck on elevated obstacles
if (ball.pos.getZ() > BALL_RADIUS + 0.3 && ball.vel.getNorm() < 0.5) {
ball.elevatedSlowCounter++;
if (ball.elevatedSlowCounter > 250) {
ball.outOfBounds = true;
}
} else {
ball.elevatedSlowCounter = 0;
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀 Performance & Scalability | 🟡 Minor | ⚡ Quick win

Per-frame bookkeeping is running per subtick (5× per 20 ms tick).

updateSleepState, the NaN/out-of-bounds scan, and elevatedSlowCounter all run inside stepSubtick, so sleepFrameThreshold = 10 ("consecutive frames") actually settles after 2 robot ticks, and the full-list finite/bounds scan over every ball is executed 5× per tick for no benefit. Move these passes into advancePhysics after the subtick loop.

♻️ Suggested move
     for (int tick = 0; tick < ticks; tick++) {
         stepSubtick(subDt);
     }
+
+    if (config.sleepingEnabled) {
+        for (int i = 0; i < balls.size(); i++) {
+            updateSleepState(balls.get(i));
+        }
+    }
+    cullInvalidBalls(); // NaN / OOB / stuck-elevated pass, extracted from stepSubtick
 
     // Remove flagged balls
     removeFlaggedBalls();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/frc/rebuilt/FuelPhysicsSim.java` around lines 1192 - 1227, Move
the per-frame bookkeeping from stepSubtick into advancePhysics after the subtick
loop: updateSleepState, the finite/position bounds scan, and elevatedSlowCounter
handling must each run once per 20 ms frame rather than once per subtick.
Preserve the existing checks, thresholds, and outOfBounds behavior while
removing their execution from the subtick path.

// yaw = 0° -> |cos(0)| = 1.0 -> full deceleration (straight-on, hardest to cross)
// yaw = 45° -> |cos(90°)| = 0.71 -> reduced deceleration (diagonal, easier)
// yaw = 90° -> |cos(180°)| = 1.0 -> full deceleration (sideways approach also hard)
double contactFactor = Math.abs(Math.cos(2 * robotPose2d.getRotation().getRadians()));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Fix the diagonal contact factor.

At 45°, abs(cos(2θ)) is 0, not the documented 0.71; this eliminates ramp deceleration entirely and permits diagonal ghosting.

Proposed fix
- double contactFactor = Math.abs(Math.cos(2 * robotPose2d.getRotation().getRadians()));
+ double yaw = robotPose2d.getRotation().getRadians();
+ double contactFactor = Math.max(Math.abs(Math.cos(yaw)), Math.abs(Math.sin(yaw)));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
double contactFactor = Math.abs(Math.cos(2 * robotPose2d.getRotation().getRadians()));
double yaw = robotPose2d.getRotation().getRadians();
double contactFactor = Math.max(Math.abs(Math.cos(yaw)), Math.abs(Math.sin(yaw)));
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/frc/rebuilt/RobotBumpSim.java` at line 294, Update the
contactFactor calculation in RobotBumpSim to use the documented diagonal
behavior, yielding approximately 0.71 at 45° instead of zero; preserve the
absolute-value handling and ensure diagonal collisions still apply ramp
deceleration.

Comment on lines +661 to 680
public CANdlePattern gradient(Color color1, Color color2) {
SolidColor[][] holder = new SolidColor[1][];
return (candle, startIdx, numLeds) -> {
if (holder[0] == null) {
holder[0] = new SolidColor[numLeds];
for (int i = 0; i < numLeds; i++) {
double ratio = (numLeds <= 1) ? 0.0 : (double) i / (numLeds - 1);
int r = (int) (color1.red * 255 * (1 - ratio) + color2.red * 255 * ratio);
int g = (int) (color1.green * 255 * (1 - ratio) + color2.green * 255 * ratio);
int b = (int) (color1.blue * 255 * (1 - ratio) + color2.blue * 255 * ratio);
holder[0][i] =
new SolidColor(startIdx + i, startIdx + i)
.withColor(new RGBWColor(r, g, b, 0));
}
}
for (SolidColor req : holder[0]) {
candle.setControl(req);
}
};
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀 Performance & Scalability | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find how many LEDs are configured for SpectrumLEDs instances in this repo
rg -nP --type=java -C4 'new SpectrumLEDs\.Config|new SpectrumLEDs\('

Repository: Spectrum3847/2026-Spectrum

Length of output: 164


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map SpectrumLEDs and inspect the relevant methods.
FILE="src/main/java/frc/spectrumLib/leds/SpectrumLEDs.java"
wc -l "$FILE"
ast-grep outline "$FILE" --view expanded | sed -n '1,240p'

echo '--- relevant ranges ---'
sed -n '620,780p' "$FILE"

Repository: Spectrum3847/2026-Spectrum

Length of output: 10054


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for SpectrumLEDs construction and pattern usages.
rg -n --type=java 'new SpectrumLEDs|SpectrumLEDs\.' src/main/java src/test/java 2>/dev/null || true

Repository: Spectrum3847/2026-Spectrum

Length of output: 164


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="src/main/java/frc/spectrumLib/leds/SpectrumLEDs.java"

echo '--- class and helper overview ---'
ast-grep outline "$FILE" --view expanded | sed -n '1,260p'

echo '--- surrounding pattern methods ---'
sed -n '560,780p' "$FILE"

echo '--- any docs/comments mentioning one-shot or loop resend ---'
rg -n -C2 'one-shot|resent each loop|setControl|SolidColor' "$FILE"

Repository: Spectrum3847/2026-Spectrum

Length of output: 25267


Reduce per-LED CAN traffic in software patterns

gradient, ombre, wave, countdown, and switchCountdown send one setControl(...) request per LED on every loop. That scales linearly with strip length and can consume a lot of CAN bandwidth; collapse contiguous runs where possible or move the effect to a hardware animation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/frc/spectrumLib/leds/SpectrumLEDs.java` around lines 661 - 680,
Update the software patterns gradient, ombre, wave, countdown, and
switchCountdown to reduce CAN traffic by grouping contiguous LEDs with identical
colors into range-based SolidColor controls instead of calling setControl once
per LED on each loop. Preserve each pattern’s visual output, and consider a
hardware animation where equivalent.

Comment on lines +692 to 716
public CANdlePattern edges(Color color, int length) {
RGBWColor rgbw = toRGBW(color);
SolidColor[][] holder = new SolidColor[1][];
return (candle, startIdx, numLeds) -> {
if (holder[0] == null) {
int clampedLen = Math.min(length, numLeds / 2);
int centerStart = startIdx + clampedLen;
int centerEnd = startIdx + numLeds - clampedLen - 1;
// left edge, right edge, (optional) center black
holder[0] = (centerStart <= centerEnd) ? new SolidColor[3] : new SolidColor[2];
holder[0][0] = new SolidColor(startIdx, startIdx + clampedLen - 1).withColor(rgbw);
holder[0][1] =
new SolidColor(startIdx + numLeds - clampedLen, startIdx + numLeds - 1)
.withColor(rgbw);
if (holder[0].length == 3) {
holder[0][2] =
new SolidColor(centerStart, centerEnd)
.withColor(new RGBWColor(0, 0, 0, 0));
}
}
for (SolidColor req : holder[0]) {
candle.setControl(req);
}
};
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

edges produces an inverted SolidColor range for tiny segments.

clampedLen = Math.min(length, numLeds / 2) is 0 when numLeds < 2 (or when length == 0), making Line 702 construct new SolidColor(startIdx, startIdx - 1) — an end index below the start. Guard for clampedLen <= 0 and fall back to filling the whole segment black.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/frc/spectrumLib/leds/SpectrumLEDs.java` around lines 692 - 716,
Update the edges method to handle clampedLen <= 0 before constructing edge
SolidColor ranges. In that case, configure a single SolidColor covering the
entire segment from startIdx through startIdx + numLeds - 1 with black, then
preserve the existing edge and optional-center behavior for positive lengths.

config.getMinAngle(),
config.getMaxAngle(),
false, // Simulate gravity (change back to true)
config.isSimulateGravity(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

ast-grep outline src/main/java/frc/robot/subsystems/turret/Turret.java --items all
rg -n -C 5 'new ArmConfig|setSimulatedGravity' src/main/java/frc/robot/subsystems/turret/Turret.java
rg -n -C 3 'boolean simulateGravity|setSimulatedGravity' src/main/java/frc/spectrumLib/sim/ArmConfig.java

Repository: Spectrum3847/2026-Spectrum

Length of output: 2526


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

ast-grep outline src/main/java/frc/spectrumLib/sim/ArmSim.java --items all
sed -n '1,220p' src/main/java/frc/spectrumLib/sim/ArmSim.java

sed -n '220,290p' src/main/java/frc/robot/subsystems/turret/Turret.java

Repository: Spectrum3847/2026-Spectrum

Length of output: 7963


Disable gravity for TurretSim ArmSim now forwards simulateGravity into SingleJointedArmSim, and TurretSim still uses the default true. A turret yaw axis should not be gravity-loaded, so this will make the sim bias toward settling at an angle/limit.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/frc/spectrumLib/sim/ArmSim.java` at line 50, Update the
TurretSim construction/configuration to disable gravity explicitly rather than
using the default true value. Keep ArmSim’s config.isSimulateGravity()
forwarding unchanged, and ensure the TurretSim path passes false to its
SingleJointedArmSim setup.

import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine;
import frc.robot.swerve.Swerve;
import frc.robot.subsystems.swerve.Swerve;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

frc.spectrumLib now depends on frc.robot — the dependency direction is inverted.

This PR moves SpectrumLib into structured, reusable packages, but SysID imports the robot-specific frc.robot.subsystems.swerve.Swerve, so the library can no longer be lifted into another project. The class only needs setControl(SwerveRequest) and a Subsystem handle; accept a CTRE SwerveDrivetrain/Subsystem (or a small interface) instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/frc/spectrumLib/swerve/SysID.java` at line 9, Remove the
robot-specific Swerve dependency from SysID and change its API to accept a
reusable CTRE SwerveDrivetrain/Subsystem handle, or a minimal interface exposing
setControl(SwerveRequest). Update SysID’s construction and control calls to use
that abstraction while preserving its existing behavior.

Comment on lines 20 to 21
public class SysID {
// private Swerve swerve;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Drop the commented-out swerve field and assignment.

Lines 21 and 55 are dead code; the constructor parameter is used directly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/frc/spectrumLib/swerve/SysID.java` around lines 20 - 21, Remove
the commented-out swerve field from SysID and delete the corresponding dead
assignment in its constructor; keep using the constructor parameter directly.

@Project516

Copy link
Copy Markdown
Contributor Author

@JediMasterLucy55 you want to work on this?

@JediMasterLucy55

Copy link
Copy Markdown
Contributor

sure i prbly cant until after drip

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.

4 participants