Conversation
Signed-off-by: Jade Turner <spacey-sooty@proton.me>
There was a problem hiding this comment.
Pull request overview
Adds new “static shot” solving + offload entrypoints, and introduces a new Shuttle Recovery mode that uses predictive selection of recovery points and an offloaded FieldTracker endpoint.
Changes:
- Expose a new DragShotPlanner static-position solve API (local/async/offloaded) and add the corresponding offload task ID + entrypoint.
- Add shuttle recovery point selection (DTOs + predictive local/offloaded entrypoints) and a new FieldTracker API to request the next shuttle recovery goal.
- Introduce
SHUTTLE_RECOVERY_MODEwith a newShuttleRecoveryBehaviour, and update reasoning/behaviour selection wiring.
Reviewed changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/test/java/org/curtinfrc/frc2026/util/Repulsor/Offload/ShuttleRecoveryOffloadApiTest.java | Reflection-based API checks for new shuttle recovery offload wrappers/task IDs. |
| src/test/java/org/curtinfrc/frc2026/util/Repulsor/Offload/DragShotStaticPositionApiTest.java | Reflection-based API checks for new static-shot solve API and generated offload wrapper methods. |
| src/main/java/org/curtinfrc/frc2026/util/Repulsor/Tracking/FieldTrackerLocalAccess.java | Local fallback implementation for shuttle recovery goal computation (via predictive runtime). |
| src/main/java/org/curtinfrc/frc2026/util/Repulsor/Tracking/FieldTrackerCore.java | Adds recovery-dynamics snapshot + new offloaded nextAllianceShuttleRecoveryGoalBlue API. |
| src/main/java/org/curtinfrc/frc2026/util/Repulsor/Shooting/DragShotPlannerStaticPositionSearch.java | New static-position shot solve (coarse + refinement) implementation. |
| src/main/java/org/curtinfrc/frc2026/util/Repulsor/Shooting/DragShotPlannerLocalAccess.java | Adds local-access wrapper for static-position solve. |
| src/main/java/org/curtinfrc/frc2026/util/Repulsor/Shooting/DragShotPlannerCore.java | Adds core-level static-position solve entrypoint. |
| src/main/java/org/curtinfrc/frc2026/util/Repulsor/Shooting/DragShotPlanner.java | Public API for static-position solve (offloaded/async/local). |
| src/main/java/org/curtinfrc/frc2026/util/Repulsor/Reasoning/Rebuilt2026Reasoner.java | Adds shuttle recovery signals/phases and changes behaviour selection logic. |
| src/main/java/org/curtinfrc/frc2026/util/Repulsor/Predictive/PredictiveFieldStateRuntime.java | Adds local/offloaded shuttle recovery point selection APIs. |
| src/main/java/org/curtinfrc/frc2026/util/Repulsor/Predictive/PredictiveFieldStateLocalAccess.java | Implements local shuttle recovery point selection using predictive ranking. |
| src/main/java/org/curtinfrc/frc2026/util/Repulsor/Offload/ShuttleRecoveryPointDTO.java | DTO for shuttle recovery point selection result. |
| src/main/java/org/curtinfrc/frc2026/util/Repulsor/Offload/ShuttleRecoveryDynamicObjectDTO.java | DTO for dynamic-object snapshots used by shuttle recovery selection. |
| src/main/java/org/curtinfrc/frc2026/util/Repulsor/Offload/PredictiveFieldStateOffloadEntrypoints.java | Offloadable entrypoint for selecting shuttle recovery point. |
| src/main/java/org/curtinfrc/frc2026/util/Repulsor/Offload/OffloadTaskIds.java | Adds new task IDs for static shot + shuttle recovery selection and goal. |
| src/main/java/org/curtinfrc/frc2026/util/Repulsor/Offload/FieldTrackerOffloadEntrypoints.java | Offloadable entrypoint for shuttle recovery goal selection. |
| src/main/java/org/curtinfrc/frc2026/util/Repulsor/Offload/DragShotPlannerOffloadEntrypoints.java | Adds offloadable entrypoint for static-position shot solve. |
| src/main/java/org/curtinfrc/frc2026/util/Repulsor/Behaviours/ShuttleRecoveryBehaviour.java | New behaviour for shuttle recovery mode (collect + shoot routing and shot solve integration). |
| src/main/java/org/curtinfrc/frc2026/util/Repulsor/Behaviours/ShuttleBehaviour.java | Refactor/updates to shuttle mode behaviour, including shot solve integration. |
| src/main/java/org/curtinfrc/frc2026/util/Repulsor/Behaviours/BehaviourFlag.java | Adds SHUTTLE_RECOVERY_MODE. |
| src/main/java/org/curtinfrc/frc2026/util/Repulsor/Behaviours/AutoPathBehaviour.java | Tightens shouldRun to require AUTOPATH_MODE. |
| src/main/java/org/curtinfrc/frc2026/Robot.java | Wires in ShuttleRecoveryBehaviour and disables reasoner “testing” by default. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| EnumSet<BehaviourFlag> out = | ||
| hubActive | ||
| ? EnumSet.of(BehaviourFlag.SHUTTLE_RECOVERY_MODE) | ||
| : EnumSet.of(BehaviourFlag.SHUTTLE_MODE); |
There was a problem hiding this comment.
update() no longer calls seq.update(ctx) and instead always returns either SHUTTLE_MODE or SHUTTLE_RECOVERY_MODE (except TESTING). This makes the configured phases/transitions (autopath/defense/endgame + NT-controlled transitions) effectively dead code and prevents those modes from ever being selected via the reasoner. Consider restoring EnumSet<BehaviourFlag> out = seq.update(ctx) after updating the signals (e.g., set WANT_SHUTTLE/WANT_SHUTTLE_RECOVERY from hubActive but still let the SequenceReasoner choose the phase), or remove the sequence machinery entirely if it’s intentionally unused.
| EnumSet<BehaviourFlag> out = | |
| hubActive | |
| ? EnumSet.of(BehaviourFlag.SHUTTLE_RECOVERY_MODE) | |
| : EnumSet.of(BehaviourFlag.SHUTTLE_MODE); | |
| EnumSet<BehaviourFlag> out = seq.update(ctx); |
| public final class ShuttleRecoveryBehaviour extends Behaviour { | ||
| private static final double SHOOT_BEHIND_HUB_METERS = 2.95; | ||
| private static final double SHOOT_LATERAL_STEP_METERS = 0.45; | ||
| private static final double SHOOT_POS_TOL_METERS = 0.34; | ||
| private static final double SHOOT_YAW_TOL_DEG = 13.0; | ||
| private static final double FIELD_MARGIN_METERS = 0.28; | ||
|
|
||
| private static final double MOTION_COMP_LATENCY_SEC = 0.08; | ||
| private static final double MOTION_COMP_MIN_LEAD_SEC = 0.10; | ||
| private static final double MOTION_COMP_MAX_LEAD_SEC = 0.45; | ||
| private static final double MOTION_COMP_MAX_SPEED_MPS = 4.5; | ||
| private static final double DEFAULT_TIME_TO_PLANE_SEC = 0.18; | ||
| private static final long MAGAZINE_CAPACITY = 16L; | ||
| private static final int RECOVERY_GOAL_UNITS = 2; | ||
|
|
||
| private static final double[] SHOOT_LATERAL_OFFSETS = | ||
| new double[] {0.0, SHOOT_LATERAL_STEP_METERS, -SHOOT_LATERAL_STEP_METERS, 0.9, -0.9}; | ||
|
|
||
| private static final GamePiecePhysics SHUTTLE_GAME_PIECE = loadShuttleGamePiece(); | ||
|
|
||
| private final int prio; | ||
| private final Supplier<Boolean> hasPiece; | ||
| private final Supplier<Double> ourSpeedCap; | ||
|
|
||
| private final NetworkTablesValue<Double> shotAngle = | ||
| NetworkTablesValue.ofDouble( | ||
| NetworkTableInstance.getDefault(), NetworkTablesValue.toAdvantageKit("/ShotAngle"), 0.0); | ||
| private final NetworkTablesValue<Double> shotSpeed = | ||
| NetworkTablesValue.ofDouble( | ||
| NetworkTableInstance.getDefault(), NetworkTablesValue.toAdvantageKit("/ShotSpeed"), 0.0); | ||
| private final NetworkTablesValue<Boolean> shooterPassthrough = | ||
| NetworkTablesValue.ofBoolean( | ||
| NetworkTableInstance.getDefault(), | ||
| NetworkTablesValue.toAdvantageKit("/ShooterPassthrough"), | ||
| false); | ||
| private final NetworkTablesValue<Long> pieceCount = | ||
| NetworkTablesValue.ofInteger(NetworkTableInstance.getDefault(), "/PieceCount", 0L); |
There was a problem hiding this comment.
ShuttleRecoveryBehaviour duplicates a large amount of logic/constants/helper methods from ShuttleBehaviour (shot solving, motion compensation, NetworkTables outputs, clamp helpers, etc.). This duplication will be hard to keep consistent as tuning changes land. Consider extracting the shared aiming/shot-selection code into a shared helper (or a base class) that both behaviours can call, leaving only the collect-goal selection differences in each behaviour.
| static Optional<ShotSolution> calculateShotAngleAndSpeedFromStaticPosition( | ||
| GamePiecePhysics gamePiece, | ||
| Translation2d shooterFieldPosition, | ||
| Translation2d targetFieldPosition, | ||
| double targetHeightMeters, | ||
| double shooterReleaseHeightMeters, | ||
| Constraints constraints) { | ||
|
|
||
| AutoCloseable _p = Profiler.section("DragShotPlanner.calculateStaticShotAngleAndSpeed"); | ||
| try { | ||
| if (constraints == null) { | ||
| Profiler.counterAdd("DragShotPlanner.static.constraints_null", 1); | ||
| return Optional.empty(); | ||
| } | ||
|
|
||
| double minSpeed = constraints.minLaunchSpeedMetersPerSecond(); | ||
| double maxSpeed = constraints.maxLaunchSpeedMetersPerSecond(); | ||
| double minAngleDeg = constraints.minLaunchAngleDeg(); | ||
| double maxAngleDeg = constraints.maxLaunchAngleDeg(); | ||
| Constraints.ShotStyle shotStyle = constraints.shotStyle(); | ||
| boolean fixedAngle = Math.abs(maxAngleDeg - minAngleDeg) < 1e-6; | ||
|
|
||
| if (minSpeed <= 0.0 || maxSpeed <= minSpeed) { | ||
| Profiler.counterAdd("DragShotPlanner.static.bad_speed_range", 1); | ||
| return Optional.empty(); | ||
| } | ||
| if (!fixedAngle && maxAngleDeg <= minAngleDeg) { | ||
| Profiler.counterAdd("DragShotPlanner.static.bad_angle_range", 1); | ||
| return Optional.empty(); | ||
| } | ||
|
|
||
| double acceptableError = DragShotPlannerConstants.ACCEPTABLE_VERTICAL_ERROR_METERS; | ||
| ShotSolution coarse = | ||
| DragShotPlannerSolveAtPosition.solveBestAtShooterPosition( | ||
| gamePiece, | ||
| shooterFieldPosition, | ||
| targetFieldPosition, | ||
| targetHeightMeters, | ||
| shooterReleaseHeightMeters, | ||
| minSpeed, | ||
| maxSpeed, | ||
| minAngleDeg, | ||
| maxAngleDeg, | ||
| fixedAngle, | ||
| acceptableError, | ||
| shotStyle, | ||
| 0.35, | ||
| 0.6); | ||
| if (coarse == null) { | ||
| return Optional.empty(); | ||
| } | ||
|
|
||
| double coarseErrorAbs = Math.abs(coarse.verticalErrorMeters()); | ||
| if (coarseErrorAbs <= acceptableError) { | ||
| return Optional.of(coarse); | ||
| } | ||
|
|
There was a problem hiding this comment.
The new static-position solver (calculateShotAngleAndSpeedFromStaticPosition) adds non-trivial selection/refinement logic, but the tests added in this PR only assert API/wrapper presence via reflection. Adding at least one unit test that exercises the solver (e.g., known shooter/target geometry + constraints) would help catch regressions and validate that the coarse/refine steps behave as intended.
TunerConstants already includes an instance of the Drive CANBus, using it is a bit clearer and should reduce memory usage ever so slightly. Signed-off-by: Jade Turner <spacey-sooty@proton.me>
We had these enabled last year. Signed-off-by: Jade Turner <spacey-sooty@proton.me>
Signed-off-by: Jade Turner <spacey-sooty@proton.me>
Signed-off-by: Jade Turner <spacey-sooty@proton.me>
* feature: add ball sim Co-authored-by: Jade <spacey-sooty@proton.me> * feature: implement ball sim in shooter sim --------- Co-authored-by: Jade <spacey-sooty@proton.me>
Co-authored-by: Jade Turner <spacey-sooty@proton.me>
Co-authored-by: Jason <jy201016@gmail.com>
* Created MagIOComp layer, added a second constructor to Mag.java to account for B-Bot, along with if-else statements to change between those constructors in the Commands, and integrated it into Robot.java * Fixed one formatting issue
* Added IntakeIOComp layer and integrated it into Robot.java * Pulled from main * Built code
Signed-off-by: Jade Turner <spacey-sooty@proton.me>
Signed-off-by: Jade Turner <spacey-sooty@proton.me>
Signed-off-by: Jade Turner <spacey-sooty@proton.me>
…ous hub facing based on location (#85) * Added IntakeIOComp layer and integrated it into Robot.java * Pulled from main * Built code * Attempted to create a trigger to only allow shooting when facing the target location. Not finished * Not finished * Autonomous facing hub when in Alliance Zone * Added new tuning file, tested driving, and added triggers for autonomous hub facing
Signed-off-by: Jade Turner <spacey-sooty@proton.me>
Signed-off-by: Jade Turner <spacey-sooty@proton.me>
* chore: do review comments * fix: update hood gear ratios * fix: remove sysid and add recalc hood feedforward values * fix: add recalc gains for hooded shooter * chore: move magic numbers into constants * feature: pid gains and general values for hoodedshooter * fix: hood pid --------- Co-authored-by: prawny-boy <seanyk.chan@gmail.com>
ef33086 to
28c140a
Compare
No description provided.