Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
1a2570f
swerve angle drift test
jmmaloney3 Feb 7, 2026
7f5e4a0
fix bugs
jmmaloney3 Feb 7, 2026
46ce5d8
fixed bug
jmmaloney3 Feb 7, 2026
53092d7
eliminate CAN ID conflict - causes sim to crash
jmmaloney3 Feb 12, 2026
7cce25e
Add simulation support:
jmmaloney3 Feb 13, 2026
44d354c
use setDesiredState to match production, add some network table values
jmmaloney3 Feb 14, 2026
4a8e4f2
Merge jmm-sim-support into jmm-sim-test-support
jmmaloney3 Feb 14, 2026
ffc0291
remove duplicate method definition
jmmaloney3 Feb 14, 2026
5d61e93
remove duplicate CAN ID
jmmaloney3 Feb 14, 2026
b89ce35
Improve swerve module simulation support and test architecture
jmmaloney3 Feb 16, 2026
c8380f5
Improve swerve **single** module simulation support
jmmaloney3 Feb 16, 2026
8b183b5
Improve swerve angle drift test with hold time and SmartDashboard org…
jmmaloney3 Feb 16, 2026
cda5a6c
fix off by one error
jmmaloney3 Feb 16, 2026
8bff516
design for the diagnostic testign framework
jmmaloney3 Feb 17, 2026
71b8278
initial commit for DiaghnosticTest interface
jmmaloney3 Feb 17, 2026
5435554
Merge commit 5b8851e (Rebuilt drive base #17) into jmm-test-support
jmmaloney3 Feb 17, 2026
57ca041
Merge commit 5b8851e (Rebuilt drive base #17) into jmm-sim-support
jmmaloney3 Feb 17, 2026
29c711d
Merge commit 69fd851 (Light subsystem #18) into jmm-sim-support
jmmaloney3 Feb 17, 2026
3052a0e
Merge commit 69fd851 (Light subsystem #18) into jmm-test-support
jmmaloney3 Feb 17, 2026
3a9bdaa
Clean up main: remove unnecessary files and fix CAN ID conflict
jmmaloney3 Feb 17, 2026
712e370
partial framework: add registry class
jmmaloney3 Feb 18, 2026
d2c0d9d
partial implementation: added test manager
jmmaloney3 Feb 18, 2026
4838317
ignore CTRE simulation files
jmmaloney3 Feb 18, 2026
9282cf1
partial implementation: integrate test manager into Robot.java
jmmaloney3 Feb 18, 2026
c3abaab
Fix method naming conventions in CandleSubsystem
jmmaloney3 Feb 18, 2026
5ae0a2f
expose CandleSubsystem for testing and fix method names to follow cam…
jmmaloney3 Feb 18, 2026
8d0cf4a
add LedStateTestCommand as example of using the diagnostic test frame…
jmmaloney3 Feb 18, 2026
0b14dfc
partial migration of SwerveAngleDrifTest to new framework
jmmaloney3 Feb 18, 2026
e19056f
partial migration to new test framework
jmmaloney3 Feb 18, 2026
c66dfdd
move location of params and results in smart dashboard
jmmaloney3 Feb 18, 2026
84eeb78
move location of params and results in smart dashboard
jmmaloney3 Feb 18, 2026
846ed3b
rename and reorg SwerveAngleDriftTest results to be easier to read
jmmaloney3 Feb 18, 2026
f89869d
remove obsolete SwerveDriftTestManager class
jmmaloney3 Feb 18, 2026
cd7e52b
remove unnecessary helper class
jmmaloney3 Feb 18, 2026
f9a0a33
modify getModules to return clone of modules array to prevent acciden…
jmmaloney3 Feb 18, 2026
6c5093a
minor formatting change
jmmaloney3 Feb 18, 2026
eb53c85
partial impl: add helper class
jmmaloney3 Feb 18, 2026
a6e81a1
updated to use new TestDashboard helper class
jmmaloney3 Feb 18, 2026
62544f5
add design document for test dashboard helper
jmmaloney3 Feb 19, 2026
4725f3c
add 2024-2026 comparison report
jmmaloney3 Feb 19, 2026
40d5124
Add SwerveAlignmentTest and SwerveStraightLineTest diagnostic commands
jmmaloney3 Feb 19, 2026
a7d3c00
add debugging methodology document - generated by AI - needs review
jmmaloney3 Feb 19, 2026
0aaa3df
Merge jmm-sim-support into jmm-sim-test-support
jmmaloney3 Feb 20, 2026
7f83fab
Merge jmm-test-support into jmm-sim-test-support
jmmaloney3 Feb 20, 2026
1c32bee
use consistent header for sim and test support methods
jmmaloney3 Feb 20, 2026
6328380
merge jmm-sim-support into jmm-sim-test-support
jmmaloney3 Feb 20, 2026
421637a
use consistent header for sim and test support methods
jmmaloney3 Feb 20, 2026
d535fcf
merge jmm-test-support into jmm-sim-test-support
jmmaloney3 Feb 20, 2026
ecfcd39
updated unit test to test diasgnostic test framework
jmmaloney3 Feb 20, 2026
42fdcf9
group test params/results together under Test:
jmmaloney3 Feb 20, 2026
819da95
add support for calcelling test - in case the robot does somethign un…
jmmaloney3 Feb 20, 2026
70ac756
update JavaDoc comments to be more accurate
jmmaloney3 Feb 20, 2026
65ced04
simplify logic - remove unnecessary null check
jmmaloney3 Feb 20, 2026
323fe25
remove redundant description - use DiagnosticTest.getDescription instead
jmmaloney3 Feb 20, 2026
2d0634a
rearrange fields for improved UX and add description
jmmaloney3 Feb 20, 2026
e0e025a
merge jmm-test-support into jmm-sim-test-support
jmmaloney3 Feb 20, 2026
dd54c29
Nono auto (#22)
frankeljm Feb 20, 2026
5106d2d
Merge origin/main into jmm-sim-test-support
jmmaloney3 Feb 20, 2026
850bbc7
Merge jmm-clean-up into jmm-sim-test-support
jmmaloney3 Feb 20, 2026
8558f97
Add standalone 2024 auto mode assessment document (extracted from com…
jmmaloney3 Feb 20, 2026
33824d0
added filename and line numbers to code examples
jmmaloney3 Feb 20, 2026
63e30cb
upgrade to WPILib 2026.2.1
jmmaloney3 Feb 21, 2026
fec7741
Add SendableChooserUtil for enum-based chooser creation
jmmaloney3 Feb 21, 2026
50ebd0f
Fix spinning robot in AdvantageScope by publishing Robot Pose NT4 struct
jmmaloney3 Feb 22, 2026
e1f7111
Fix PathPlanner trajectory generation: use physical max speed in Modu…
jmmaloney3 Feb 23, 2026
68407bf
supress debug output from unit test
jmmaloney3 Feb 23, 2026
3c01680
allow joystick warnings to be supressed in sim mode with user-specifi…
jmmaloney3 Feb 23, 2026
e851f45
Add OdometryResetTestCommand diagnostic test
jmmaloney3 Feb 23, 2026
c09851b
Merge branch 'NonoAuto' into jmm-sim-test-support
Seqii Feb 23, 2026
ff3a1b7
removed error
Seqii Feb 23, 2026
36d1530
Revert "removed error"
Seqii Feb 23, 2026
5a1b868
Revert "Merge branch 'NonoAuto' into jmm-sim-test-support"
Seqii Feb 23, 2026
0b6e48c
add sim-auto analysis documents, add RobotState recommendation to cod…
jmmaloney3 Feb 24, 2026
1b4aa7e
added prompt to filename to ensure its purpose is clear
jmmaloney3 Feb 24, 2026
8a5db32
Merge NonoAuto auto routines into jmm-sim-test-support
jmmaloney3 Feb 24, 2026
5537190
sim: add disabled-state guard to prevent simulated robot drift
jmmaloney3 Feb 24, 2026
6a76f02
sim: tighten dt clamping to prevent phantom motion and pose jumps
jmmaloney3 Feb 24, 2026
083f295
documented data and code execution flow for simulation framework
jmmaloney3 Feb 24, 2026
6ac0b5e
simplified code and removed unused imports
jmmaloney3 Feb 24, 2026
f1c8453
clarified role of DriverStation integration provided by RobotSimulation
jmmaloney3 Feb 24, 2026
3af857b
add guidance for unit testing with HAL simulator
jmmaloney3 Feb 25, 2026
72fe2a1
update assessment of reset sim capability
jmmaloney3 Feb 25, 2026
ba42a94
remove duplicate ctre_sim entry
jmmaloney3 Feb 26, 2026
068a292
make diagnistic test manager compatible with elastic UI
jmmaloney3 Feb 26, 2026
4542374
switch supress-joystick-warnings in sim to false to align with WPILib…
jmmaloney3 Feb 27, 2026
0dac138
prevent test running outside test mode
jmmaloney3 Feb 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ bin/
# Simulator runtime files
networktables.json
simgui*.json
ctre_sim/

# JVM crash logs
hs_err_pid*.log
Expand Down
7 changes: 0 additions & 7 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@ java {
targetCompatibility = JavaVersion.VERSION_17
}

repositories {
mavenCentral()
maven {
url = uri("https://maven.ctr-electronics.com/release/")
}
}

def ROBOT_MAIN_CLASS = "frc.robot.Main"

// Define my targets (RoboRIO) and artifacts (deployable files)
Expand Down
Binary file removed ctre_sim/CANCoder vers. H - 010 - 0 - ext.dat
Binary file not shown.
Binary file removed ctre_sim/CANCoder vers. H - 013 - 0 - ext.dat
Binary file not shown.
Binary file removed ctre_sim/CANCoder vers. H - 016 - 0 - ext.dat
Binary file not shown.
Binary file removed ctre_sim/CANCoder vers. H - 019 - 0 - ext.dat
Binary file not shown.
Binary file removed ctre_sim/CANCoder vers. H - 020 - 0 - ext.dat
Binary file not shown.
Binary file removed ctre_sim/CANCoder vers. H - 021 - 0 - ext.dat
Binary file not shown.
Binary file removed ctre_sim/CANCoder vers. H - 022 - 0 - ext.dat
Binary file not shown.
Binary file removed ctre_sim/CANCoder vers. H - 07 - 0 - ext.dat
Binary file not shown.
Binary file removed ctre_sim/Pigeon 2 - 017 - 0 - ext.dat
Binary file not shown.
Binary file removed ctre_sim/Pigeon 2 - 023 - 0 - ext.dat
Binary file not shown.
1,409 changes: 1,409 additions & 0 deletions docs/2024-26-comparison-report.md

Large diffs are not rendered by default.

179 changes: 179 additions & 0 deletions docs/2024-auto-mode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
# Autonomous Mode Assessment — 2024 Infrastructure vs 2026 Gaps

## 1. Why This Matters

The drift and jitter issues are frustrating in teleop, but a human driver can compensate. In autonomous mode, the robot relies entirely on odometry and path-following software to navigate. If the drivebase has a persistent directional error (drift) or a module that oscillates (jitter), every path segment accumulates error. The strategy team's planned auto routine — shoot 8 preloaded fuel, drive to the depot for more, return to the shooting band and shoot again — requires precise navigation to multiple field locations within 20 seconds. Even small per-segment errors compound into missed alignment with the hub, failed depot pickups, and wasted time.

The 2024 team achieved a top-tier autonomous routine (one of the best at that year's competition). That was possible because of a **three-layer compensation system** that actively fought against drift and odometry error in real-time. The 2026 codebase is currently missing nearly all of this infrastructure.

## 2. How 2024 Autonomous Navigation Worked

The 2024 code did NOT blindly trust PathPlanner. It used three layers of compensation working together every 20ms cycle:

### Layer 1: Vision-Fused Pose Estimation (continuous during auto)

The `periodic()` method in `SwerveSubsystem` runs every robot cycle, **including during autonomous**. It continuously fuses encoder-based odometry with AprilTag vision from **two Limelights**:

```java
// File: 2024-Season/src/main/java/frc/robot/subsystems/SwerveSubsystem.java
// Method: periodic(), lines 332–374 (condensed — SmartDashboard calls omitted)

332 public void periodic() {
// ...
336 odometry.update(getYaw(), getPositions()); // encoder + gyro update
338 LimelightHelpers.PoseEstimate estimateA = LimelightHelpers.getBotPoseEstimate_wpiBlue("limelight-a");
339 LimelightHelpers.PoseEstimate estimateB = LimelightHelpers.getBotPoseEstimate_wpiBlue("limelight-b");
// ...
// If both cameras see one tag each, trust the combined estimate
352 if(estimateA.tagCount == 1 && estimateB.tagCount == 1 && AisValid && BisValid){
355 odometry.addVisionMeasurement(estimateA.pose, estimateA.timestampSeconds);
356 odometry.addVisionMeasurement(estimateB.pose, estimateB.timestampSeconds);
357 }
358 else{
// If either camera sees 2+ tags, trust that camera alone
360 if(AisValid){
361 if(estimateA.tagCount >= 2){
362 odometry.addVisionMeasurement(estimateA.pose, estimateA.timestampSeconds);
}
}
// ... (similar check for limelight-b, lines 366–371)
372 }
// Sanity check: snap position back if it drifts outside field bounds
374 keepOdometryOnField();
```

This means every time PathPlanner asked "where am I?" via `getPose()`, it got a **vision-corrected answer** — not just raw wheel odometry.

### Layer 2: PathPlanner Configuration with Active Correction

PathPlanner was configured with translation and rotation PID controllers, plus replanning:

```java
// File: 2024-Season/src/main/java/frc/robot/Constants.java
// Class: AutoConstants, lines 135–164

137 public static final HolonomicPathFollowerConfig pathConfig = new HolonomicPathFollowerConfig(
138 new PIDConstants(5.0, 0.00001, 0.0), // Translation PID (P=5.0, I=0.00001)
139 new PIDConstants(5.0, 0.0005, 0.001), // Rotation PID (P=5.0, I=0.0005, D=0.001)
140 SwerveConstants.maxSpeed, // 5 m/s max module speed
141 SwerveConstants.driveBaseRadius, // Drive base radius in meters
142 new ReplanningConfig() // enables on-the-fly replanning when robot deviates
143 );
```

```java
// File: 2024-Season/src/main/java/frc/robot/subsystems/SwerveSubsystem.java
// Method: configPathPlanner(), lines 223–233

223 public void configPathPlanner(){
224 AutoBuilder.configureHolonomic(
225 this::getPose, // ← pose supplier (returns vision-fused estimate)
226 this::resetOdometry, // ← pose reset
227 this::getRobotRelativeSpeed, // ← current chassis speeds
228 this::closedLoopDrive, // ← drive consumer (closed-loop, not open-loop)
229 AutoConstants.pathConfig, // ← PID + replanning config
230 () -> (DriverStation.getAlliance().get() == Alliance.Red),
231 this
232 );
233 }
```

Key design decisions:
- **`this::getPose`** feeds the vision-corrected pose to PathPlanner, so its error calculations are based on the best available position estimate
- **`ReplanningConfig()`** (default) enables on-the-fly replanning — if the robot deviates from the planned path, PathPlanner regenerates the trajectory from the robot's current position rather than trying to drive back to the old trajectory
- **P=5.0 for both translation and rotation** — these are aggressive gains that correct for errors quickly
- **Non-zero I terms** — ensure even small persistent errors (like the drift you're experiencing) are eventually eliminated

### Layer 3: Closed-Loop Velocity Control During Auto

PathPlanner drove the robot through `closedLoopDrive()`, which used PID + feedforward motor control:

```java
// File: 2024-Season/src/main/java/frc/robot/subsystems/SwerveSubsystem.java
// Method: closedLoopDrive(), lines 96–98

96 public void closedLoopDrive(ChassisSpeeds speeds){
97 driveFromChassisSpeeds(speeds, false); // false = closed-loop
98 }
```

In closed-loop mode, each drive motor uses its onboard PID controller + feedforward to hit the exact commanded velocity. In teleop, the robot uses open-loop (voltage percentage) for driver feel. The closed-loop mode during auto ensures each wheel actually spins at the speed PathPlanner requests, not just "approximately" that speed.

### The Complete Feedback Loop

Every 20ms during autonomous:

```
1. periodic() updates pose from wheel encoders + Pigeon gyro
2. periodic() fuses in AprilTag vision corrections from both Limelights
3. periodic() clamps pose to field boundaries (keepOdometryOnField)
4. PathPlanner calls getPose() → gets vision-corrected position
5. PathPlanner compares actual vs. desired position on the path
6. PathPlanner's PID controllers compute translational + rotational corrections
7. If deviation exceeds threshold, ReplanningConfig triggers a full path replan
8. closedLoopDrive() sends corrected velocities to each module
9. Drive motor onboard PID ensures actual wheel speeds match commanded speeds
10. Repeat
```

This is why the 2024 auto was so effective — the robot was **never more than one or two cycles behind** on correcting for any drift or disturbance.

## 3. What 2026 Has and What It's Missing

| Component | 2024 Status | 2026 Status | Severity |
|-----------|-------------|-------------|----------|
| `SwerveDrivePoseEstimator` (odometry + vision fusion) | ✅ Present | ✅ Present | — |
| Dual Limelight vision integration in `periodic()` | ✅ MegaTag1, dual cameras | ✅ MegaTag2, dual cameras | OK |
| `configPathPlanner()` / `AutoBuilder` setup | ✅ Called in constructor | ❌ **Missing entirely** | 🔴 CRITICAL |
| `AutoConstants` class (path PID, replanning config) | ✅ P=5.0 translation, P=5.0 rotation | ❌ **Doesn't exist** | 🔴 CRITICAL |
| `closedLoopDrive(ChassisSpeeds)` method | ✅ Present, used by PathPlanner | ❌ **Missing** | 🔴 CRITICAL |
| `getRobotRelativeSpeed()` method | ✅ Present | ❌ **Missing** | 🔴 CRITICAL |
| `followPathFromFile(String)` convenience method | ✅ Present | ❌ **Missing** | 🔴 CRITICAL |
| `startAutoAt(x, y, heading)` method | ✅ Sets starting pose + gyro | ❌ **Missing** | 🔴 CRITICAL |
| `backupCommand()` (dynamic path generation) | ✅ Present | ❌ **Missing** | MODERATE |
| Auto mode selector (`AutoModeSelector` class) | ✅ 11 routines (various strategies) | ❌ Returns `"No autonomous command configured"` | 🔴 CRITICAL |
| `keepOdometryOnField()` sanity check | ✅ Present | ❌ **Removed** | MODERATE |
| `isOdometryValid()` encoder error check | ✅ Present (skips update on error) | ❌ **Removed** | MODERATE |
| PathPlanner vendordep | ✅ Present | ⚠️ **Verify** — not imported in any Java file | ⚠️ Verify |

## 4. Impact of Current Drivebase Bugs on Autonomous

Even with the full PathPlanner infrastructure ported, the currently identified drivebase issues would severely degrade autonomous performance:

| Issue | Impact on Auto | Why Compensation Can't Fully Fix It |
|-------|---------------|-------------------------------------|
| **Bad angle offsets** (§2.3) | Robot physically drives at an angle to the intended direction | Vision corrects the pose *estimate*, but the correction command is also misdirected because the modules are pointing wrong. PathPlanner would see the error and try to correct, but each correction is itself slightly off. This creates jerky, oscillatory path following. |
| **Module jitter** (§2.3, §1.5) | Jittering module introduces vibration and inconsistent wheel contact | PathPlanner expects smooth module responses. A jittering module provides inconsistent wheel speed data, corrupting the odometry that feeds the pose estimator. Vision can partially compensate, but the robot will follow a wobbly path instead of a smooth one. |
| **CAN signal bug** (§9.1) | Possible stale encoder data during fast maneuvers | PathPlanner commands velocity changes every 20ms. If encoder data is delayed due to CAN congestion, the drive motor PID in closed-loop mode reacts to stale data, causing velocity oscillation. |

**For the planned autonomous routine:** The timing margin is tight — shoot 8 preloads, drive to depot, collect fuel, drive back, and shoot again, all in 20 seconds. Even if PathPlanner successfully compensates for drift, the compensation itself costs time — every correction is distance the robot travels that isn't along the optimal path. A clean drivebase that drives straight without correction saves ~0.2–0.5 seconds per path segment. Over the five segments of the planned routine (start → band, align + shoot, band → depot, depot → band, align + shoot), those savings add up to 1–2.5 seconds — often the difference between completing the depot cycle or running out of time after the first volley.

## 5. Recommended Path to a Competitive Autonomous

**Phase 1 — Fix the drivebase (prerequisite, do first):**
1. Clear WPILib Preferences and verify angle offsets (§2.3, §1.5)
2. Fix CANSparkUtil signal names (§9.1)
3. Verify angleInvert and Pigeon orientation (§1.3, §1.2)
4. Test: robot should drive straight with no drift and no jittering at rest

**Phase 2 — Port PathPlanner infrastructure from 2024:**
1. Verify PathPlanner is in `vendordeps/` (if not, add the PathPlannerLib JSON)
2. Create `AutoConstants` class in 2026 `Constants.java` with path-following PID constants — start with the 2024 values but adjust `maxSpeed` to 3 m/s (or increase `maxSpeed` once the drivebase is verified)
3. Add `closedLoopDrive()` and `getRobotRelativeSpeed()` to `SwerveSubsystem`
4. Add `configPathPlanner()` to `SwerveSubsystem` — **note: the PathPlanner API changed between 2024 and 2026**; `configureHolonomic()` was renamed and the configuration object changed. Use the 2026 PathPlanner docs for the exact API.
5. Add `followPathFromFile()` and `startAutoAt()` convenience methods
6. Re-add `keepOdometryOnField()` to `periodic()` as a safety net
7. Consider re-adding `isOdometryValid()` to skip odometry updates during encoder errors

**Phase 3 — Build and test the planned auto routine incrementally:**
1. Phase 1 only: drive from start into shooting band, align with hub, shoot 8 preloaded fuel. Validates path following and hub alignment.
2. Add Phase 2: after shooting, drive to depot and collect fuel. Validates multi-segment navigation.
3. Add Phase 3: drive back to shooting band, re-align, shoot depot fuel. Completes the full planned routine.
4. Use AdvantageScope or Shuffleboard to compare desired vs. actual path in real-time
5. Tune PathPlanner PID constants if the robot overshoots or oscillates during path following

**Phase 4 — Optimize for competition:**
1. Increase `maxSpeed` (currently capped at 3 m/s, 2024 used 5 m/s)
2. Remove the `* 0.5` speed multiplier in `RobotContainer`
3. Tune path constraints (max velocity, max acceleration) for each path segment
4. Consider adding path-specific vision rejection (e.g., ignore vision updates during fast maneuvers to avoid pose jumps)
Loading