diff --git a/.vscode/settings.json b/.vscode/settings.json index 612cdd0..1745ba0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -56,5 +56,6 @@ "edu.wpi.first.math.proto.*", "edu.wpi.first.math.**.proto.*", "edu.wpi.first.math.**.struct.*", - ] + ], + "java.jdt.ls.vmargs": "-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx2G -Xms100m -Xlog:disable" } diff --git a/build.gradle b/build.gradle index 0ab3b81..dcbfde6 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { id "java" - id "edu.wpi.first.GradleRIO" version "2025.1.1" + id "edu.wpi.first.GradleRIO" version "2025.3.1" } java { @@ -33,7 +33,7 @@ deploy { frcStaticFileDeploy(getArtifactTypeClass('FileTreeArtifact')) { files = project.fileTree('src/main/deploy') directory = '/home/lvuser/deploy' - deleteOldFiles = false // Change to true to delete files on roboRIO that no + deleteOldFiles = true // Change to true to delete files on roboRIO that no // longer exist in deploy directory of this project } } @@ -47,7 +47,7 @@ def deployArtifact = deploy.targets.roborio.artifacts.frcJava wpi.java.debugJni = false // Set this to true to enable desktop support. -def includeDesktopSupport = false +def includeDesktopSupport = true // Defining my dependencies. In this case, WPILib (+ friends), and vendor libraries. // Also defines JUnit 5. diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/simgui-ds.json b/simgui-ds.json index 73cc713..4a63cc1 100644 --- a/simgui-ds.json +++ b/simgui-ds.json @@ -1,4 +1,9 @@ { + "System Joysticks": { + "window": { + "enabled": false + } + }, "keyboardJoysticks": [ { "axisConfig": [ diff --git a/src/main/deploy/pathplanner/autos/3Piece-A.auto b/src/main/deploy/pathplanner/autos/3Piece-A.auto deleted file mode 100644 index cc12487..0000000 --- a/src/main/deploy/pathplanner/autos/3Piece-A.auto +++ /dev/null @@ -1,73 +0,0 @@ -{ - "version": "2025.0", - "command": { - "type": "sequential", - "data": { - "commands": [ - { - "type": "path", - "data": { - "pathName": "A_R1" - } - }, - { - "type": "named", - "data": { - "name": "L1" - } - }, - { - "type": "path", - "data": { - "pathName": "R1_HP1" - } - }, - { - "type": "named", - "data": { - "name": "Intake" - } - }, - { - "type": "path", - "data": { - "pathName": "HP1_R2" - } - }, - { - "type": "named", - "data": { - "name": "L4" - } - }, - { - "type": "path", - "data": { - "pathName": "R2_HP1" - } - }, - { - "type": "named", - "data": { - "name": "Intake" - } - }, - { - "type": "path", - "data": { - "pathName": "HP1_R3" - } - }, - { - "type": "named", - "data": { - "name": "L1" - } - } - ] - } - }, - "resetOdom": true, - "folder": null, - "choreoAuto": false -} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/autos/A-2PieceAlgae.auto b/src/main/deploy/pathplanner/autos/A-2PieceAlgae.auto new file mode 100644 index 0000000..ce492d6 --- /dev/null +++ b/src/main/deploy/pathplanner/autos/A-2PieceAlgae.auto @@ -0,0 +1,107 @@ +{ + "version": "2025.0", + "command": { + "type": "sequential", + "data": { + "commands": [ + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "A_R3" + } + }, + { + "type": "named", + "data": { + "name": "L4" + } + } + ] + } + }, + { + "type": "named", + "data": { + "name": "Score" + } + }, + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "R3_HP1" + } + }, + { + "type": "named", + "data": { + "name": "Intake" + } + } + ] + } + }, + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "HP1_R2" + } + }, + { + "type": "named", + "data": { + "name": "L4" + } + } + ] + } + }, + { + "type": "named", + "data": { + "name": "Score" + } + }, + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "BackR2" + } + }, + { + "type": "named", + "data": { + "name": "AlgaeL2" + } + } + ] + } + }, + { + "type": "named", + "data": { + "name": "Stow" + } + } + ] + } + }, + "resetOdom": true, + "folder": "Algae Autos", + "choreoAuto": false +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/autos/A-3PieceL4-GOOD.auto b/src/main/deploy/pathplanner/autos/A-3PieceL4-GOOD.auto new file mode 100644 index 0000000..dbc301e --- /dev/null +++ b/src/main/deploy/pathplanner/autos/A-3PieceL4-GOOD.auto @@ -0,0 +1,120 @@ +{ + "version": "2025.0", + "command": { + "type": "sequential", + "data": { + "commands": [ + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "A_R3" + } + }, + { + "type": "named", + "data": { + "name": "L4" + } + } + ] + } + }, + { + "type": "named", + "data": { + "name": "Score" + } + }, + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "R3_HP1" + } + }, + { + "type": "named", + "data": { + "name": "Intake" + } + } + ] + } + }, + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "HP1_R2" + } + }, + { + "type": "named", + "data": { + "name": "L4" + } + } + ] + } + }, + { + "type": "named", + "data": { + "name": "Score" + } + }, + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "R2_HP1" + } + }, + { + "type": "named", + "data": { + "name": "Intake" + } + } + ] + } + }, + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "Fast_HP1_L.R2" + } + }, + { + "type": "named", + "data": { + "name": "Stow" + } + } + ] + } + } + ] + } + }, + "resetOdom": true, + "folder": "Reliable Autos", + "choreoAuto": false +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/autos/B-Score.auto b/src/main/deploy/pathplanner/autos/B-Score.auto new file mode 100644 index 0000000..0bca30e --- /dev/null +++ b/src/main/deploy/pathplanner/autos/B-Score.auto @@ -0,0 +1,50 @@ +{ + "version": "2025.0", + "command": { + "type": "sequential", + "data": { + "commands": [ + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "B_R4" + } + }, + { + "type": "named", + "data": { + "name": "L4" + } + } + ] + } + }, + { + "type": "named", + "data": { + "name": "Score" + } + }, + { + "type": "path", + "data": { + "pathName": "BackR4" + } + }, + { + "type": "named", + "data": { + "name": "Stow" + } + } + ] + } + }, + "resetOdom": true, + "folder": null, + "choreoAuto": false +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/autos/C-2PieceAlgae.auto b/src/main/deploy/pathplanner/autos/C-2PieceAlgae.auto new file mode 100644 index 0000000..488cbd0 --- /dev/null +++ b/src/main/deploy/pathplanner/autos/C-2PieceAlgae.auto @@ -0,0 +1,95 @@ +{ + "version": "2025.0", + "command": { + "type": "sequential", + "data": { + "commands": [ + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "named", + "data": { + "name": "L4" + } + }, + { + "type": "path", + "data": { + "pathName": "C_R5" + } + } + ] + } + }, + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "R5_HP2" + } + }, + { + "type": "named", + "data": { + "name": "Intake" + } + } + ] + } + }, + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "named", + "data": { + "name": "L4" + } + }, + { + "type": "path", + "data": { + "pathName": "HP2_R6" + } + } + ] + } + }, + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "BackR6" + } + }, + { + "type": "named", + "data": { + "name": "AlgaeL2" + } + } + ] + } + }, + { + "type": "named", + "data": { + "name": "Stow" + } + } + ] + } + }, + "resetOdom": true, + "folder": "Algae Autos", + "choreoAuto": false +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/autos/C-3PieceL4-GOOD.auto b/src/main/deploy/pathplanner/autos/C-3PieceL4-GOOD.auto new file mode 100644 index 0000000..a10abd9 --- /dev/null +++ b/src/main/deploy/pathplanner/autos/C-3PieceL4-GOOD.auto @@ -0,0 +1,108 @@ +{ + "version": "2025.0", + "command": { + "type": "sequential", + "data": { + "commands": [ + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "named", + "data": { + "name": "L4" + } + }, + { + "type": "path", + "data": { + "pathName": "C_R5" + } + } + ] + } + }, + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "R5_HP2" + } + }, + { + "type": "named", + "data": { + "name": "Intake" + } + } + ] + } + }, + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "named", + "data": { + "name": "L4" + } + }, + { + "type": "path", + "data": { + "pathName": "HP2_R6" + } + } + ] + } + }, + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "R6_HP2" + } + }, + { + "type": "named", + "data": { + "name": "Intake" + } + } + ] + } + }, + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "Fast_HP2_L.R6" + } + }, + { + "type": "named", + "data": { + "name": "Stow" + } + } + ] + } + } + ] + } + }, + "resetOdom": true, + "folder": "Reliable Autos", + "choreoAuto": false +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/autos/Fast-A-3Piece.auto b/src/main/deploy/pathplanner/autos/Fast-A-3Piece.auto new file mode 100644 index 0000000..0ca4862 --- /dev/null +++ b/src/main/deploy/pathplanner/autos/Fast-A-3Piece.auto @@ -0,0 +1,121 @@ +{ + "version": "2025.0", + "command": { + "type": "sequential", + "data": { + "commands": [ + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "Fast_A_R3" + } + }, + { + "type": "named", + "data": { + "name": "L4" + } + } + ] + } + }, + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "Fast_R3_HP1" + } + }, + { + "type": "named", + "data": { + "name": "Intake" + } + } + ] + } + }, + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "Fast_HP1_R.R2" + } + }, + { + "type": "named", + "data": { + "name": "L4" + } + } + ] + } + }, + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "Fast_R.R2_HP1" + } + }, + { + "type": "named", + "data": { + "name": "Intake" + } + } + ] + } + }, + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "Fast_HP1_L.R2" + } + }, + { + "type": "named", + "data": { + "name": "L1" + } + } + ] + } + }, + { + "type": "sequential", + "data": { + "commands": [ + { + "type": "named", + "data": { + "name": "Stow" + } + } + ] + } + } + ] + } + }, + "resetOdom": true, + "folder": "FAST AUTOS", + "choreoAuto": false +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/autos/Fast-C-3PieceL4.auto b/src/main/deploy/pathplanner/autos/Fast-C-3PieceL4.auto new file mode 100644 index 0000000..4658167 --- /dev/null +++ b/src/main/deploy/pathplanner/autos/Fast-C-3PieceL4.auto @@ -0,0 +1,140 @@ +{ + "version": "2025.0", + "command": { + "type": "sequential", + "data": { + "commands": [ + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "named", + "data": { + "name": "L4" + } + }, + { + "type": "path", + "data": { + "pathName": "C_R5" + } + } + ] + } + }, + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "R5_HP2" + } + }, + { + "type": "named", + "data": { + "name": "Intake" + } + } + ] + } + }, + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "named", + "data": { + "name": "L4" + } + }, + { + "type": "path", + "data": { + "pathName": "Fast_HP2_L.R6" + } + } + ] + } + }, + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "Fast_L.R6_HP2" + } + }, + { + "type": "named", + "data": { + "name": "Intake" + } + } + ] + } + }, + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "Fast_HP2_R.R6" + } + }, + { + "type": "named", + "data": { + "name": "L4" + } + } + ] + } + }, + { + "type": "parallel", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "Fast_R.R6_HP2" + } + }, + { + "type": "named", + "data": { + "name": "Intake" + } + } + ] + } + }, + { + "type": "sequential", + "data": { + "commands": [ + { + "type": "named", + "data": { + "name": "Stow" + } + } + ] + } + } + ] + } + }, + "resetOdom": true, + "folder": "FAST AUTOS", + "choreoAuto": false +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/autos/LeaveA.auto b/src/main/deploy/pathplanner/autos/LeaveA.auto new file mode 100644 index 0000000..c4245a5 --- /dev/null +++ b/src/main/deploy/pathplanner/autos/LeaveA.auto @@ -0,0 +1,19 @@ +{ + "version": "2025.0", + "command": { + "type": "sequential", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "LeaveA" + } + } + ] + } + }, + "resetOdom": true, + "folder": "LeaveStart", + "choreoAuto": false +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/autos/LeaveB.auto b/src/main/deploy/pathplanner/autos/LeaveB.auto new file mode 100644 index 0000000..0865a86 --- /dev/null +++ b/src/main/deploy/pathplanner/autos/LeaveB.auto @@ -0,0 +1,19 @@ +{ + "version": "2025.0", + "command": { + "type": "sequential", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "LeaveB" + } + } + ] + } + }, + "resetOdom": true, + "folder": "LeaveStart", + "choreoAuto": false +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/autos/LeaveC.auto b/src/main/deploy/pathplanner/autos/LeaveC.auto new file mode 100644 index 0000000..ef442e4 --- /dev/null +++ b/src/main/deploy/pathplanner/autos/LeaveC.auto @@ -0,0 +1,19 @@ +{ + "version": "2025.0", + "command": { + "type": "sequential", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "LeaveC" + } + } + ] + } + }, + "resetOdom": true, + "folder": "LeaveStart", + "choreoAuto": false +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/A_R1.path b/src/main/deploy/pathplanner/paths/A_R1.path index c2b9654..96197e9 100644 --- a/src/main/deploy/pathplanner/paths/A_R1.path +++ b/src/main/deploy/pathplanner/paths/A_R1.path @@ -3,45 +3,45 @@ "waypoints": [ { "anchor": { - "x": 8.141, - "y": 7.262 + "x": 7.5282786885245905, + "y": 6.188780737704917 }, "prevControl": null, "nextControl": { - "x": 7.586495221239114, - "y": 6.582720823328432 + "x": 6.041803278688524, + "y": 6.212756147540984 }, "isLocked": false, "linkedName": "A" }, { "anchor": { - "x": 3.0669902912561082, - "y": 5.371067961167508 + "x": 3.368545081967213, + "y": 5.889088114754099 }, "prevControl": { - "x": 3.368986851901508, - "y": 6.050287320862891 + "x": 3.8495277425772816, + "y": 6.521960036609454 }, "nextControl": { - "x": 2.9654216119293113, - "y": 5.142630216081872 + "x": 3.1407786885245907, + "y": 5.589395491803279 }, "isLocked": false, "linkedName": null }, { "anchor": { - "x": 2.85, - "y": 4.05 + "x": 3.2841721390676866, + "y": 3.837271284603343 }, "prevControl": { - "x": 2.784190034029836, - "y": 3.8088173961932457 + "x": 3.2992336144775223, + "y": 4.801256940341048 }, "nextControl": null, "isLocked": false, - "linkedName": "R1" + "linkedName": "ScoreR1" } ], "rotationTargets": [ @@ -54,12 +54,12 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, "nominalVoltage": 12.0, - "unlimited": false + "unlimited": true }, "goalEndState": { "velocity": 0, @@ -71,5 +71,5 @@ "velocity": 0.0, "rotation": 180.0 }, - "useDefaultConstraints": true + "useDefaultConstraints": false } \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/A_R2.path b/src/main/deploy/pathplanner/paths/A_R2.path index 62b3951..e252522 100644 --- a/src/main/deploy/pathplanner/paths/A_R2.path +++ b/src/main/deploy/pathplanner/paths/A_R2.path @@ -3,29 +3,29 @@ "waypoints": [ { "anchor": { - "x": 8.141, - "y": 7.262 + "x": 7.5282786885245905, + "y": 6.188780737704917 }, "prevControl": null, "nextControl": { - "x": 8.648750608172906, - "y": 7.408445022150453 + "x": 6.58125, + "y": 6.536424180327868 }, "isLocked": false, "linkedName": "A" }, { "anchor": { - "x": 3.7, - "y": 5.45 + "x": 3.722528569965569, + "y": 4.991511920463674 }, "prevControl": { - "x": 3.416014327133664, - "y": 5.34575096413502 + "x": 4.002446602752455, + "y": 6.041972986037444 }, "nextControl": null, "isLocked": false, - "linkedName": "R2" + "linkedName": "ScoreR2" } ], "rotationTargets": [], @@ -33,7 +33,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/A_R3.path b/src/main/deploy/pathplanner/paths/A_R3.path index 93317dd..aedd910 100644 --- a/src/main/deploy/pathplanner/paths/A_R3.path +++ b/src/main/deploy/pathplanner/paths/A_R3.path @@ -3,37 +3,56 @@ "waypoints": [ { "anchor": { - "x": 8.141, - "y": 7.262 + "x": 7.5282786885245905, + "y": 6.188780737704917 }, "prevControl": null, "nextControl": { - "x": 8.467610613658996, - "y": 7.461889236623081 + "x": 5.371895516834254, + "y": 5.469936584938475 }, "isLocked": false, "linkedName": "A" }, { "anchor": { - "x": 5.27, - "y": 5.43 + "x": 4.998872950819672, + "y": 5.181813524590163 }, "prevControl": { - "x": 5.045108479704744, - "y": 5.299100830755238 + "x": 5.248038282296709, + "y": 5.161401822310868 }, "nextControl": null, "isLocked": false, - "linkedName": "R3" + "linkedName": "ScoreR3" + } + ], + "rotationTargets": [ + { + "waypointRelativePos": 0.18780952380952365, + "rotationDegrees": -121.0 + } + ], + "constraintZones": [ + { + "name": "Constraints Zone", + "minWaypointRelativePos": 0, + "maxWaypointRelativePos": 0.22644927536231882, + "constraints": { + "maxVelocity": 10.0, + "maxAcceleration": 4.5, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + } } ], - "rotationTargets": [], - "constraintZones": [], "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 10.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, @@ -50,5 +69,5 @@ "velocity": 0.0, "rotation": 180.0 }, - "useDefaultConstraints": true + "useDefaultConstraints": false } \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/A_R4.path b/src/main/deploy/pathplanner/paths/A_R4.path index 53feb30..4f0ed62 100644 --- a/src/main/deploy/pathplanner/paths/A_R4.path +++ b/src/main/deploy/pathplanner/paths/A_R4.path @@ -3,29 +3,29 @@ "waypoints": [ { "anchor": { - "x": 8.141, - "y": 7.262 + "x": 7.5282786885245905, + "y": 6.188780737704917 }, "prevControl": null, "nextControl": { - "x": 7.5362335241468985, - "y": 6.3175303768448945 + "x": 6.923512212671489, + "y": 5.244311114549812 }, "isLocked": false, "linkedName": "A" }, { "anchor": { - "x": 6.1, - "y": 4.05 + "x": 5.658196721311475, + "y": 4.198821721311475 }, "prevControl": { - "x": 6.709660199424142, - "y": 4.994337423812124 + "x": 6.267856920735617, + "y": 5.143159145123599 }, "nextControl": null, "isLocked": false, - "linkedName": "R4" + "linkedName": "ScoreR4" } ], "rotationTargets": [], @@ -33,7 +33,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/B_R2.path b/src/main/deploy/pathplanner/paths/B_R2.path index a0ac52b..2467a94 100644 --- a/src/main/deploy/pathplanner/paths/B_R2.path +++ b/src/main/deploy/pathplanner/paths/B_R2.path @@ -3,29 +3,29 @@ "waypoints": [ { "anchor": { - "x": 8.141, - "y": 6.209 + "x": 7.564241803278687, + "y": 4.030993852459016 }, "prevControl": null, "nextControl": { - "x": 4.821990291262136, - "y": 6.1207766990291255 + "x": 6.28155737704918, + "y": 6.080891393442624 }, "isLocked": false, "linkedName": "B" }, { "anchor": { - "x": 3.7, - "y": 5.45 + "x": 3.722528569965569, + "y": 4.991511920463674 }, "prevControl": { - "x": 4.083398058252427, - "y": 6.0185436893203885 + "x": 3.8585941437360605, + "y": 6.185825445053838 }, "nextControl": null, "isLocked": false, - "linkedName": "R2" + "linkedName": "ScoreR2" } ], "rotationTargets": [ @@ -38,7 +38,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/B_R3.path b/src/main/deploy/pathplanner/paths/B_R3.path index 2eb1129..d371ede 100644 --- a/src/main/deploy/pathplanner/paths/B_R3.path +++ b/src/main/deploy/pathplanner/paths/B_R3.path @@ -3,29 +3,29 @@ "waypoints": [ { "anchor": { - "x": 8.141, - "y": 6.209 + "x": 7.564241803278687, + "y": 4.030993852459016 }, "prevControl": null, "nextControl": { - "x": 6.506300290646091, - "y": 5.905521108644577 + "x": 7.318666600733812, + "y": 4.998201937758377 }, "isLocked": false, "linkedName": "B" }, { "anchor": { - "x": 5.27, - "y": 5.43 + "x": 4.998872950819672, + "y": 5.181813524590163 }, "prevControl": { - "x": 6.309522336579676, - "y": 5.75024510478078 + "x": 7.07909565490044, + "y": 4.199688488288866 }, "nextControl": null, "isLocked": false, - "linkedName": "R3" + "linkedName": "ScoreR3" } ], "rotationTargets": [ @@ -38,7 +38,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/B_R4.path b/src/main/deploy/pathplanner/paths/B_R4.path index b7abbf9..97f04b6 100644 --- a/src/main/deploy/pathplanner/paths/B_R4.path +++ b/src/main/deploy/pathplanner/paths/B_R4.path @@ -3,29 +3,29 @@ "waypoints": [ { "anchor": { - "x": 8.141, - "y": 6.209 + "x": 7.564241803278687, + "y": 4.030993852459016 }, "prevControl": null, "nextControl": { - "x": 7.1975633821443274, - "y": 5.212845335404368 + "x": 7.132684426229508, + "y": 4.09093237704918 }, "isLocked": false, "linkedName": "B" }, { "anchor": { - "x": 6.1, - "y": 4.05 + "x": 5.658196721311475, + "y": 4.198821721311475 }, "prevControl": { - "x": 6.907920582003962, - "y": 4.909535891476532 + "x": 6.403176229508197, + "y": 4.239754098360655 }, "nextControl": null, "isLocked": false, - "linkedName": "R4" + "linkedName": "ScoreR4" } ], "rotationTargets": [], @@ -33,7 +33,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/B_R5.path b/src/main/deploy/pathplanner/paths/B_R5.path index dd7a13f..e257ca0 100644 --- a/src/main/deploy/pathplanner/paths/B_R5.path +++ b/src/main/deploy/pathplanner/paths/B_R5.path @@ -3,29 +3,29 @@ "waypoints": [ { "anchor": { - "x": 8.141, - "y": 6.209 + "x": 7.564241803278687, + "y": 4.030993852459016 }, "prevControl": null, "nextControl": { - "x": 7.06293676106582, - "y": 4.827990479111984 + "x": 4.941511198192275, + "y": 2.716734633143889 }, "isLocked": false, "linkedName": "B" }, { "anchor": { - "x": 5.301, - "y": 2.622 + "x": 5.238627049180328, + "y": 3.036014344262295 }, "prevControl": { - "x": 6.406601941747573, - "y": 3.0367475728155338 + "x": 5.487611501364296, + "y": 3.0135034009091286 }, "nextControl": null, "isLocked": false, - "linkedName": "R5" + "linkedName": "ScoreR5" } ], "rotationTargets": [ @@ -38,7 +38,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, @@ -47,7 +47,7 @@ }, "goalEndState": { "velocity": 0, - "rotation": 119.99999999999999 + "rotation": 120.9 }, "reversed": false, "folder": "Start to Reef", @@ -55,5 +55,5 @@ "velocity": 0, "rotation": 180.0 }, - "useDefaultConstraints": true + "useDefaultConstraints": false } \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/BackR1.path b/src/main/deploy/pathplanner/paths/BackR1.path new file mode 100644 index 0000000..4100421 --- /dev/null +++ b/src/main/deploy/pathplanner/paths/BackR1.path @@ -0,0 +1,54 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 3.2841721390676866, + "y": 3.837271284603343 + }, + "prevControl": null, + "nextControl": { + "x": 3.0624733393919525, + "y": 3.952811936420523 + }, + "isLocked": false, + "linkedName": "ScoreR1" + }, + { + "anchor": { + "x": 2.85, + "y": 4.05 + }, + "prevControl": { + "x": 3.083375538410217, + "y": 3.9603570523033667 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "R1" + } + ], + "rotationTargets": [], + "constraintZones": [], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 5.0, + "maxAcceleration": 3.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0, + "rotation": 0.0 + }, + "reversed": false, + "folder": "Move back from Score", + "idealStartingState": { + "velocity": 0, + "rotation": 0.0 + }, + "useDefaultConstraints": true +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/BackR2.path b/src/main/deploy/pathplanner/paths/BackR2.path new file mode 100644 index 0000000..ef0f5fe --- /dev/null +++ b/src/main/deploy/pathplanner/paths/BackR2.path @@ -0,0 +1,54 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 3.722528569965569, + "y": 4.991511920463674 + }, + "prevControl": null, + "nextControl": { + "x": 3.899144288694396, + "y": 4.814574395054563 + }, + "isLocked": false, + "linkedName": "ScoreR2" + }, + { + "anchor": { + "x": 3.7, + "y": 5.45 + }, + "prevControl": { + "x": 3.5007042638146406, + "y": 5.299065545555909 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "R2" + } + ], + "rotationTargets": [], + "constraintZones": [], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 5.0, + "maxAcceleration": 3.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0, + "rotation": -59.5 + }, + "reversed": false, + "folder": "Move back from Score", + "idealStartingState": { + "velocity": 0, + "rotation": -59.5 + }, + "useDefaultConstraints": true +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/BackR3.path b/src/main/deploy/pathplanner/paths/BackR3.path new file mode 100644 index 0000000..c266030 --- /dev/null +++ b/src/main/deploy/pathplanner/paths/BackR3.path @@ -0,0 +1,54 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 4.998872950819672, + "y": 5.181813524590163 + }, + "prevControl": null, + "nextControl": { + "x": 5.627369723689824, + "y": 5.654834176454168 + }, + "isLocked": false, + "linkedName": "ScoreR3" + }, + { + "anchor": { + "x": 5.2985655737704915, + "y": 5.42156762295082 + }, + "prevControl": { + "x": 4.861673689437825, + "y": 5.09856310846954 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "R3" + } + ], + "rotationTargets": [], + "constraintZones": [], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 5.0, + "maxAcceleration": 3.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0, + "rotation": -121.5 + }, + "reversed": false, + "folder": "Move back from Score", + "idealStartingState": { + "velocity": 0, + "rotation": -121.5 + }, + "useDefaultConstraints": true +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/BackR4.path b/src/main/deploy/pathplanner/paths/BackR4.path new file mode 100644 index 0000000..47fe882 --- /dev/null +++ b/src/main/deploy/pathplanner/paths/BackR4.path @@ -0,0 +1,54 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 5.658196721311475, + "y": 4.198821721311475 + }, + "prevControl": null, + "nextControl": { + "x": 6.363912625460174, + "y": 3.99981585297923 + }, + "isLocked": false, + "linkedName": "ScoreR4" + }, + { + "anchor": { + "x": 6.1, + "y": 4.05 + }, + "prevControl": { + "x": 5.289896564230451, + "y": 4.251800313049038 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "R4" + } + ], + "rotationTargets": [], + "constraintZones": [], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 5.0, + "maxAcceleration": 3.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0, + "rotation": 180.0 + }, + "reversed": false, + "folder": "Move back from Score", + "idealStartingState": { + "velocity": 0, + "rotation": 180.0 + }, + "useDefaultConstraints": true +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/BackR5.path b/src/main/deploy/pathplanner/paths/BackR5.path new file mode 100644 index 0000000..2c4f726 --- /dev/null +++ b/src/main/deploy/pathplanner/paths/BackR5.path @@ -0,0 +1,54 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 5.238627049180328, + "y": 3.036014344262295 + }, + "prevControl": null, + "nextControl": { + "x": 5.3738659451667194, + "y": 2.791820597066799 + }, + "isLocked": false, + "linkedName": "ScoreR5" + }, + { + "anchor": { + "x": 5.33452868852459, + "y": 2.604456967213115 + }, + "prevControl": { + "x": 5.177502002026731, + "y": 2.798988763399505 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "R5" + } + ], + "rotationTargets": [], + "constraintZones": [], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 5.0, + "maxAcceleration": 3.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0, + "rotation": 120.89912407537605 + }, + "reversed": false, + "folder": "Move back from Score", + "idealStartingState": { + "velocity": 0, + "rotation": 120.9 + }, + "useDefaultConstraints": true +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/BackR6.path b/src/main/deploy/pathplanner/paths/BackR6.path new file mode 100644 index 0000000..bf89257 --- /dev/null +++ b/src/main/deploy/pathplanner/paths/BackR6.path @@ -0,0 +1,54 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 4.039856557377049, + "y": 2.916137295081967 + }, + "prevControl": null, + "nextControl": { + "x": 4.296269996869686, + "y": 2.9573188451517094 + }, + "isLocked": false, + "linkedName": "ScoreR6" + }, + { + "anchor": { + "x": 3.6802254098360656, + "y": 2.6404200819672123 + }, + "prevControl": { + "x": 3.4458839304965028, + "y": 2.553333509747695 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "R6" + } + ], + "rotationTargets": [], + "constraintZones": [], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 5.0, + "maxAcceleration": 3.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0, + "rotation": 59.99999999999999 + }, + "reversed": false, + "folder": "Move back from Score", + "idealStartingState": { + "velocity": 0, + "rotation": 59.99999999999999 + }, + "useDefaultConstraints": true +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/C_R3.path b/src/main/deploy/pathplanner/paths/C_R3.path index 4786955..56c00d0 100644 --- a/src/main/deploy/pathplanner/paths/C_R3.path +++ b/src/main/deploy/pathplanner/paths/C_R3.path @@ -3,29 +3,29 @@ "waypoints": [ { "anchor": { - "x": 8.141, - "y": 5.058 + "x": 7.564241803278687, + "y": 1.9810963114754099 }, "prevControl": null, "nextControl": { - "x": 7.101052505681702, - "y": 5.235142414101164 + "x": 7.137153970256865, + "y": 2.807760810345652 }, "isLocked": false, "linkedName": "C" }, { "anchor": { - "x": 5.27, - "y": 5.43 + "x": 4.998872950819672, + "y": 5.181813524590163 }, "prevControl": { - "x": 6.30677323496538, - "y": 5.292850243595853 + "x": 5.9818647540983605, + "y": 5.325665983606555 }, "nextControl": null, "isLocked": false, - "linkedName": "R3" + "linkedName": "ScoreR3" } ], "rotationTargets": [], @@ -33,7 +33,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/C_R4.path b/src/main/deploy/pathplanner/paths/C_R4.path index 69bb49c..c68b571 100644 --- a/src/main/deploy/pathplanner/paths/C_R4.path +++ b/src/main/deploy/pathplanner/paths/C_R4.path @@ -3,29 +3,29 @@ "waypoints": [ { "anchor": { - "x": 8.141, - "y": 5.058 + "x": 7.564241803278687, + "y": 1.9810963114754099 }, "prevControl": null, "nextControl": { - "x": 7.201422880265144, - "y": 4.594606377694494 + "x": 7.3218440432465695, + "y": 2.3290798941036686 }, "isLocked": false, "linkedName": "C" }, { "anchor": { - "x": 6.1, - "y": 4.05 + "x": 5.658196721311475, + "y": 4.198821721311475 }, "prevControl": { - "x": 7.115829452407849, - "y": 4.6012069401364855 + "x": 5.800774701144462, + "y": 3.9926154674397427 }, "nextControl": null, "isLocked": false, - "linkedName": "R4" + "linkedName": "ScoreR4" } ], "rotationTargets": [], @@ -33,7 +33,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/C_R5.path b/src/main/deploy/pathplanner/paths/C_R5.path index 5a6d9cc..0bc25d6 100644 --- a/src/main/deploy/pathplanner/paths/C_R5.path +++ b/src/main/deploy/pathplanner/paths/C_R5.path @@ -3,42 +3,56 @@ "waypoints": [ { "anchor": { - "x": 8.141, - "y": 5.058 + "x": 7.564241803278687, + "y": 1.9810963114754099 }, "prevControl": null, "nextControl": { - "x": 8.39747272260748, - "y": 5.149606717229121 + "x": 6.158120375113414, + "y": 2.116983136133424 }, "isLocked": false, "linkedName": "C" }, { "anchor": { - "x": 5.301, - "y": 2.622 + "x": 5.238627049180328, + "y": 3.036014344262295 }, "prevControl": { - "x": 6.338446601941748, - "y": 2.8152427184466013 + "x": 5.404290481090531, + "y": 2.8487828636621195 }, "nextControl": null, "isLocked": false, - "linkedName": "R5" + "linkedName": "ScoreR5" } ], "rotationTargets": [ { - "waypointRelativePos": 0.5923371647509561, - "rotationDegrees": 119.99999999999999 + "waypointRelativePos": 0.3, + "rotationDegrees": 162.15573333673396 + } + ], + "constraintZones": [ + { + "name": "Constraints Zone", + "minWaypointRelativePos": 0, + "maxWaypointRelativePos": 0.4655797101449276, + "constraints": { + "maxVelocity": 10.0, + "maxAcceleration": 4.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + } } ], - "constraintZones": [], "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 10.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, @@ -47,7 +61,7 @@ }, "goalEndState": { "velocity": 0, - "rotation": 119.99999999999999 + "rotation": 120.9 }, "reversed": false, "folder": "Start to Reef", @@ -55,5 +69,5 @@ "velocity": 0, "rotation": 180.0 }, - "useDefaultConstraints": true + "useDefaultConstraints": false } \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/C_R6.path b/src/main/deploy/pathplanner/paths/C_R6.path index cbd1143..e1442c3 100644 --- a/src/main/deploy/pathplanner/paths/C_R6.path +++ b/src/main/deploy/pathplanner/paths/C_R6.path @@ -3,45 +3,45 @@ "waypoints": [ { "anchor": { - "x": 8.141, - "y": 5.058 + "x": 7.564241803278687, + "y": 1.9810963114754099 }, "prevControl": null, "nextControl": { - "x": 7.395457580845862, - "y": 4.270077123187671 + "x": 6.503921064781505, + "y": 2.0306848647021543 }, "isLocked": false, "linkedName": "C" }, { "anchor": { - "x": 5.179805825242718, - "y": 2.014417475728154 + "x": 5.130737704918032, + "y": 1.9810963114754099 }, "prevControl": { - "x": 6.26974843361184, - "y": 1.7804533425914806 + "x": 5.730733894125063, + "y": 1.867583518922728 }, "nextControl": { - "x": 3.3519048801310447, - "y": 2.406789750010256 + "x": 4.687192622950819, + "y": 2.0650102459016395 }, "isLocked": false, "linkedName": null }, { "anchor": { - "x": 3.696, - "y": 2.622 + "x": 4.039856557377049, + "y": 2.916137295081967 }, "prevControl": { - "x": 4.830467795017655, - "y": 2.2073128019979675 + "x": 4.5016003084856315, + "y": 2.712398613219938 }, "nextControl": null, "isLocked": false, - "linkedName": "R6" + "linkedName": "ScoreR6" } ], "rotationTargets": [ @@ -54,12 +54,12 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, "nominalVoltage": 12.0, - "unlimited": false + "unlimited": true }, "goalEndState": { "velocity": 0, @@ -71,5 +71,5 @@ "velocity": 0, "rotation": 180.0 }, - "useDefaultConstraints": true + "useDefaultConstraints": false } \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/Fast_A_R3.path b/src/main/deploy/pathplanner/paths/Fast_A_R3.path new file mode 100644 index 0000000..2b4ddaa --- /dev/null +++ b/src/main/deploy/pathplanner/paths/Fast_A_R3.path @@ -0,0 +1,59 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 7.5282786885245905, + "y": 6.188780737704917 + }, + "prevControl": null, + "nextControl": { + "x": 5.371895516834254, + "y": 5.469936584938475 + }, + "isLocked": false, + "linkedName": "A" + }, + { + "anchor": { + "x": 4.998872950819672, + "y": 5.181813524590163 + }, + "prevControl": { + "x": 5.226, + "y": 5.49725 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "ScoreR3" + } + ], + "rotationTargets": [ + { + "waypointRelativePos": 0.5, + "rotationDegrees": -121.0 + } + ], + "constraintZones": [], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 10.0, + "maxAcceleration": 3.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0, + "rotation": -121.5 + }, + "reversed": false, + "folder": "Fast A 3 Piece", + "idealStartingState": { + "velocity": 0.0, + "rotation": 180.0 + }, + "useDefaultConstraints": false +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/Fast_C_R5.path b/src/main/deploy/pathplanner/paths/Fast_C_R5.path new file mode 100644 index 0000000..0cfa84d --- /dev/null +++ b/src/main/deploy/pathplanner/paths/Fast_C_R5.path @@ -0,0 +1,73 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 7.564241803278687, + "y": 1.9810963114754099 + }, + "prevControl": null, + "nextControl": { + "x": 6.379939714782926, + "y": 2.224089085857935 + }, + "isLocked": false, + "linkedName": "C" + }, + { + "anchor": { + "x": 5.238627049180328, + "y": 3.036014344262295 + }, + "prevControl": { + "x": 5.503406048705033, + "y": 2.7758299406484523 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "ScoreR5" + } + ], + "rotationTargets": [ + { + "waypointRelativePos": 0.3, + "rotationDegrees": 162.15573333673396 + } + ], + "constraintZones": [ + { + "name": "Constraints Zone", + "minWaypointRelativePos": 0, + "maxWaypointRelativePos": 0.2605381165919283, + "constraints": { + "maxVelocity": 10.0, + "maxAcceleration": 4.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + } + } + ], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 10.0, + "maxAcceleration": 3.25, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0, + "rotation": 120.9 + }, + "reversed": false, + "folder": "Fast C 3 Piece", + "idealStartingState": { + "velocity": 0, + "rotation": 180.0 + }, + "useDefaultConstraints": false +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/Fast_HP1_L.R2.path b/src/main/deploy/pathplanner/paths/Fast_HP1_L.R2.path new file mode 100644 index 0000000..d9d85e9 --- /dev/null +++ b/src/main/deploy/pathplanner/paths/Fast_HP1_L.R2.path @@ -0,0 +1,68 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 1.6185000000000003, + "y": 7.34975 + }, + "prevControl": null, + "nextControl": { + "x": 1.8179302447703478, + "y": 7.148073150731447 + }, + "isLocked": false, + "linkedName": "HP1" + }, + { + "anchor": { + "x": 4.00725, + "y": 5.1365 + }, + "prevControl": { + "x": 3.846770712815373, + "y": 5.328193501154092 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "L.R2" + } + ], + "rotationTargets": [], + "constraintZones": [ + { + "name": "Constraints Zone", + "minWaypointRelativePos": 0, + "maxWaypointRelativePos": 0.531390134529148, + "constraints": { + "maxVelocity": 10.0, + "maxAcceleration": 5.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + } + } + ], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 10.0, + "maxAcceleration": 4.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0, + "rotation": -59.5 + }, + "reversed": false, + "folder": "Fast A 3 Piece", + "idealStartingState": { + "velocity": 0, + "rotation": -53.8 + }, + "useDefaultConstraints": false +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/Fast_HP1_R.R2.path b/src/main/deploy/pathplanner/paths/Fast_HP1_R.R2.path new file mode 100644 index 0000000..8fca783 --- /dev/null +++ b/src/main/deploy/pathplanner/paths/Fast_HP1_R.R2.path @@ -0,0 +1,68 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 1.6185000000000003, + "y": 7.34975 + }, + "prevControl": null, + "nextControl": { + "x": 1.8179302447703478, + "y": 7.148073150731447 + }, + "isLocked": false, + "linkedName": "HP1" + }, + { + "anchor": { + "x": 3.722528569965569, + "y": 4.991511920463674 + }, + "prevControl": { + "x": 3.5620492827809422, + "y": 5.1832054216177665 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "ScoreR2" + } + ], + "rotationTargets": [], + "constraintZones": [ + { + "name": "Constraints Zone", + "minWaypointRelativePos": 0, + "maxWaypointRelativePos": 0.531390134529148, + "constraints": { + "maxVelocity": 10.0, + "maxAcceleration": 5.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + } + } + ], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 10.0, + "maxAcceleration": 4.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0, + "rotation": -59.5 + }, + "reversed": false, + "folder": "Fast A 3 Piece", + "idealStartingState": { + "velocity": 0, + "rotation": -53.8 + }, + "useDefaultConstraints": false +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/Fast_HP1_R1.path b/src/main/deploy/pathplanner/paths/Fast_HP1_R1.path new file mode 100644 index 0000000..be6ada5 --- /dev/null +++ b/src/main/deploy/pathplanner/paths/Fast_HP1_R1.path @@ -0,0 +1,84 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 1.6185000000000003, + "y": 7.34975 + }, + "prevControl": null, + "nextControl": { + "x": 2.68125, + "y": 6.60875 + }, + "isLocked": false, + "linkedName": "HP1" + }, + { + "anchor": { + "x": 2.3985000000000003, + "y": 5.67275 + }, + "prevControl": { + "x": 2.348509997001, + "y": 5.917701014695101 + }, + "nextControl": { + "x": 2.4960000000000004, + "y": 5.195 + }, + "isLocked": false, + "linkedName": null + }, + { + "anchor": { + "x": 3.2841721390676866, + "y": 3.837271284603343 + }, + "prevControl": { + "x": 2.27175, + "y": 3.7812499999999996 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "ScoreR1" + } + ], + "rotationTargets": [], + "constraintZones": [ + { + "name": "Constraints Zone", + "minWaypointRelativePos": 0, + "maxWaypointRelativePos": 1.141704035874439, + "constraints": { + "maxVelocity": 10.0, + "maxAcceleration": 5.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + } + } + ], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 10.0, + "maxAcceleration": 4.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0, + "rotation": 0.0 + }, + "reversed": false, + "folder": "Fast A 3 Piece", + "idealStartingState": { + "velocity": 0, + "rotation": -53.8 + }, + "useDefaultConstraints": false +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/Fast_HP2_L.R6.path b/src/main/deploy/pathplanner/paths/Fast_HP2_L.R6.path new file mode 100644 index 0000000..78a387d --- /dev/null +++ b/src/main/deploy/pathplanner/paths/Fast_HP2_L.R6.path @@ -0,0 +1,68 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 1.599, + "y": 0.670999999999999 + }, + "prevControl": null, + "nextControl": { + "x": 3.051221402882968, + "y": 2.2464597642937965 + }, + "isLocked": false, + "linkedName": "HP2" + }, + { + "anchor": { + "x": 3.7342500000000003, + "y": 3.0694999999999997 + }, + "prevControl": { + "x": 3.565088621835697, + "y": 2.885298566368326 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "L.R6" + } + ], + "rotationTargets": [], + "constraintZones": [ + { + "name": "Constraints Zone", + "minWaypointRelativePos": 0, + "maxWaypointRelativePos": 0.48654708520179374, + "constraints": { + "maxVelocity": 10.0, + "maxAcceleration": 5.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + } + } + ], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 10.0, + "maxAcceleration": 4.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0, + "rotation": 59.99999999999999 + }, + "reversed": false, + "folder": "Fast C 3 Piece", + "idealStartingState": { + "velocity": 0, + "rotation": 53.8 + }, + "useDefaultConstraints": false +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/Fast_HP2_R.R6.path b/src/main/deploy/pathplanner/paths/Fast_HP2_R.R6.path new file mode 100644 index 0000000..b2885d2 --- /dev/null +++ b/src/main/deploy/pathplanner/paths/Fast_HP2_R.R6.path @@ -0,0 +1,73 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 1.599, + "y": 0.670999999999999 + }, + "prevControl": null, + "nextControl": { + "x": 2.9838742645740246, + "y": 2.0569625625489363 + }, + "isLocked": false, + "linkedName": "HP2" + }, + { + "anchor": { + "x": 4.039856557377049, + "y": 2.916137295081967 + }, + "prevControl": { + "x": 3.8588082879463577, + "y": 2.743737979143208 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "ScoreR6" + } + ], + "rotationTargets": [ + { + "waypointRelativePos": 0.45, + "rotationDegrees": 59.99999999999999 + } + ], + "constraintZones": [ + { + "name": "Constraints Zone", + "minWaypointRelativePos": 0, + "maxWaypointRelativePos": 0.28565022421524683, + "constraints": { + "maxVelocity": 10.0, + "maxAcceleration": 5.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + } + } + ], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 10.0, + "maxAcceleration": 3.5, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0, + "rotation": 59.99999999999999 + }, + "reversed": false, + "folder": "Fast C 3 Piece", + "idealStartingState": { + "velocity": 0, + "rotation": 53.8 + }, + "useDefaultConstraints": false +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/Fast_L.R2_HP1.path b/src/main/deploy/pathplanner/paths/Fast_L.R2_HP1.path new file mode 100644 index 0000000..f3b273a --- /dev/null +++ b/src/main/deploy/pathplanner/paths/Fast_L.R2_HP1.path @@ -0,0 +1,68 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 4.00725, + "y": 5.1365 + }, + "prevControl": null, + "nextControl": { + "x": 2.7798189688994217, + "y": 6.2871263127274535 + }, + "isLocked": true, + "linkedName": "L.R2" + }, + { + "anchor": { + "x": 1.6185000000000003, + "y": 7.34975 + }, + "prevControl": { + "x": 1.8023234741866845, + "y": 7.180312901529986 + }, + "nextControl": null, + "isLocked": true, + "linkedName": "HP1" + } + ], + "rotationTargets": [], + "constraintZones": [ + { + "name": "Constraints Zone", + "minWaypointRelativePos": 0, + "maxWaypointRelativePos": 0.45067264573991034, + "constraints": { + "maxVelocity": 10.0, + "maxAcceleration": 5.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + } + } + ], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 10.0, + "maxAcceleration": 3.5, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0.0, + "rotation": -53.8 + }, + "reversed": false, + "folder": "Fast A 3 Piece", + "idealStartingState": { + "velocity": 0, + "rotation": -59.5 + }, + "useDefaultConstraints": false +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/Fast_L.R6_HP2.path b/src/main/deploy/pathplanner/paths/Fast_L.R6_HP2.path new file mode 100644 index 0000000..4f1943f --- /dev/null +++ b/src/main/deploy/pathplanner/paths/Fast_L.R6_HP2.path @@ -0,0 +1,68 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 3.7342500000000003, + "y": 3.0694999999999997 + }, + "prevControl": null, + "nextControl": { + "x": 3.2656055412247555, + "y": 2.5711636033703953 + }, + "isLocked": false, + "linkedName": "L.R6" + }, + { + "anchor": { + "x": 1.599, + "y": 0.670999999999999 + }, + "prevControl": { + "x": 1.7602751563782437, + "y": 0.8620244066478749 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "HP2" + } + ], + "rotationTargets": [], + "constraintZones": [ + { + "name": "Constraints Zone", + "minWaypointRelativePos": 0, + "maxWaypointRelativePos": 0.5600896860986545, + "constraints": { + "maxVelocity": 10.0, + "maxAcceleration": 5.0, + "maxAngularVelocity": 600.0, + "maxAngularAcceleration": 800.0, + "nominalVoltage": 12.0, + "unlimited": false + } + } + ], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 10.0, + "maxAcceleration": 4.0, + "maxAngularVelocity": 600.0, + "maxAngularAcceleration": 800.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0, + "rotation": 53.8 + }, + "reversed": false, + "folder": "Fast C 3 Piece", + "idealStartingState": { + "velocity": 0, + "rotation": 59.99999999999999 + }, + "useDefaultConstraints": false +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/Fast_R.R2_HP1.path b/src/main/deploy/pathplanner/paths/Fast_R.R2_HP1.path new file mode 100644 index 0000000..8eb3af2 --- /dev/null +++ b/src/main/deploy/pathplanner/paths/Fast_R.R2_HP1.path @@ -0,0 +1,68 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 3.723, + "y": 4.991511920463674 + }, + "prevControl": null, + "nextControl": { + "x": 2.665728368105369, + "y": 6.223712505356056 + }, + "isLocked": true, + "linkedName": "ScoreR2" + }, + { + "anchor": { + "x": 1.6185000000000003, + "y": 7.34975 + }, + "prevControl": { + "x": 1.7860635948907588, + "y": 7.164217141273343 + }, + "nextControl": null, + "isLocked": true, + "linkedName": "HP1" + } + ], + "rotationTargets": [], + "constraintZones": [ + { + "name": "Constraints Zone", + "minWaypointRelativePos": 0, + "maxWaypointRelativePos": 0.45067264573991034, + "constraints": { + "maxVelocity": 10.0, + "maxAcceleration": 5.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + } + } + ], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 10.0, + "maxAcceleration": 4.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0.0, + "rotation": -53.8 + }, + "reversed": false, + "folder": "Fast A 3 Piece", + "idealStartingState": { + "velocity": 0, + "rotation": -59.5 + }, + "useDefaultConstraints": false +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/Fast_R.R6_HP2.path b/src/main/deploy/pathplanner/paths/Fast_R.R6_HP2.path new file mode 100644 index 0000000..c2b4ae9 --- /dev/null +++ b/src/main/deploy/pathplanner/paths/Fast_R.R6_HP2.path @@ -0,0 +1,68 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 4.039856557377049, + "y": 2.916137295081967 + }, + "prevControl": null, + "nextControl": { + "x": 3.571212098601804, + "y": 2.4178008984523625 + }, + "isLocked": false, + "linkedName": "ScoreR6" + }, + { + "anchor": { + "x": 1.599, + "y": 0.670999999999999 + }, + "prevControl": { + "x": 1.7602751563782437, + "y": 0.8620244066478749 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "HP2" + } + ], + "rotationTargets": [], + "constraintZones": [ + { + "name": "Constraints Zone", + "minWaypointRelativePos": 0, + "maxWaypointRelativePos": 0.5493273542600897, + "constraints": { + "maxVelocity": 10.0, + "maxAcceleration": 5.0, + "maxAngularVelocity": 600.0, + "maxAngularAcceleration": 800.0, + "nominalVoltage": 12.0, + "unlimited": false + } + } + ], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 10.0, + "maxAcceleration": 4.0, + "maxAngularVelocity": 600.0, + "maxAngularAcceleration": 800.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0, + "rotation": 53.8 + }, + "reversed": false, + "folder": "Fast C 3 Piece", + "idealStartingState": { + "velocity": 0, + "rotation": 59.99999999999999 + }, + "useDefaultConstraints": false +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/Fast_R3_HP1.path b/src/main/deploy/pathplanner/paths/Fast_R3_HP1.path new file mode 100644 index 0000000..4e273f5 --- /dev/null +++ b/src/main/deploy/pathplanner/paths/Fast_R3_HP1.path @@ -0,0 +1,89 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 4.998872950819672, + "y": 5.181813524590163 + }, + "prevControl": null, + "nextControl": { + "x": 5.226, + "y": 6.286999999999999 + }, + "isLocked": false, + "linkedName": "ScoreR3" + }, + { + "anchor": { + "x": 3.36375, + "y": 6.51125 + }, + "prevControl": { + "x": 3.6698795109223714, + "y": 6.373276135922312 + }, + "nextControl": { + "x": 2.6715, + "y": 6.823250000000001 + }, + "isLocked": false, + "linkedName": null + }, + { + "anchor": { + "x": 1.6185000000000003, + "y": 7.34975 + }, + "prevControl": { + "x": 1.8781417813890309, + "y": 7.256893925639328 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "HP1" + } + ], + "rotationTargets": [ + { + "waypointRelativePos": 1.417904761904762, + "rotationDegrees": -53.8 + } + ], + "constraintZones": [ + { + "name": "Constraints Zone", + "minWaypointRelativePos": 0.21135265700483089, + "maxWaypointRelativePos": 0.9553140096618359, + "constraints": { + "maxVelocity": 10.0, + "maxAcceleration": 5.0, + "maxAngularVelocity": 800.0, + "maxAngularAcceleration": 750.0, + "nominalVoltage": 12.0, + "unlimited": false + } + } + ], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 10.0, + "maxAcceleration": 3.5, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 800.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0, + "rotation": -53.8 + }, + "reversed": false, + "folder": "Fast A 3 Piece", + "idealStartingState": { + "velocity": 0, + "rotation": -121.5 + }, + "useDefaultConstraints": false +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/Fast_R5_HP2.path b/src/main/deploy/pathplanner/paths/Fast_R5_HP2.path new file mode 100644 index 0000000..e70270c --- /dev/null +++ b/src/main/deploy/pathplanner/paths/Fast_R5_HP2.path @@ -0,0 +1,89 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 5.238627049180328, + "y": 3.036014344262295 + }, + "prevControl": null, + "nextControl": { + "x": 5.8305, + "y": 2.4065 + }, + "isLocked": false, + "linkedName": "ScoreR5" + }, + { + "anchor": { + "x": 3.7635, + "y": 1.938499999999999 + }, + "prevControl": { + "x": 4.104750000000001, + "y": 1.996999999999999 + }, + "nextControl": { + "x": 2.6867941010049408, + "y": 1.7539218458865604 + }, + "isLocked": false, + "linkedName": null + }, + { + "anchor": { + "x": 1.599, + "y": 0.670999999999999 + }, + "prevControl": { + "x": 2.076692256532537, + "y": 1.0270844778675974 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "HP2" + } + ], + "rotationTargets": [ + { + "waypointRelativePos": 1.2350476190476192, + "rotationDegrees": 50.0 + } + ], + "constraintZones": [ + { + "name": "Constraints Zone", + "minWaypointRelativePos": 0.5318385650224343, + "maxWaypointRelativePos": 2.0, + "constraints": { + "maxVelocity": 10.0, + "maxAcceleration": 5.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 800.0, + "nominalVoltage": 12.0, + "unlimited": false + } + } + ], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 10.0, + "maxAcceleration": 4.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 800.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0, + "rotation": 53.8 + }, + "reversed": false, + "folder": "Fast C 3 Piece", + "idealStartingState": { + "velocity": 0, + "rotation": 120.9 + }, + "useDefaultConstraints": false +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/HP1_R1.path b/src/main/deploy/pathplanner/paths/HP1_R1.path index f362011..6a54316 100644 --- a/src/main/deploy/pathplanner/paths/HP1_R1.path +++ b/src/main/deploy/pathplanner/paths/HP1_R1.path @@ -3,59 +3,73 @@ "waypoints": [ { "anchor": { - "x": 1.247, - "y": 6.779 + "x": 1.6185000000000003, + "y": 7.34975 }, "prevControl": null, "nextControl": { - "x": 2.3313267046615067, - "y": 6.710013936271338 + "x": 2.68125, + "y": 6.60875 }, "isLocked": false, "linkedName": "HP1" }, { "anchor": { - "x": 2.737096933762121, - "y": 6.442052464223761 + "x": 2.3594999999999997, + "y": 4.6587499999999995 }, "prevControl": { - "x": 2.199338419960653, - "y": 6.907793955344957 + "x": 2.3095099970009993, + "y": 4.903701014695101 }, "nextControl": { - "x": 3.2145229946722402, - "y": 6.028563658743894 + "x": 2.457, + "y": 4.181 }, "isLocked": false, "linkedName": null }, { "anchor": { - "x": 2.85, - "y": 4.05 + "x": 3.2841721390676866, + "y": 3.837271284603343 }, "prevControl": { - "x": 2.778195881418401, - "y": 3.7155294420433176 + "x": 2.9615631901299118, + "y": 4.182839400520257 }, "nextControl": null, "isLocked": false, - "linkedName": "R1" + "linkedName": "ScoreR1" } ], "rotationTargets": [ { - "waypointRelativePos": 1.1049808429118704, + "waypointRelativePos": 0.6681904761904747, "rotationDegrees": 0.0 } ], - "constraintZones": [], + "constraintZones": [ + { + "name": "Constraints Zone", + "minWaypointRelativePos": 0, + "maxWaypointRelativePos": 0.5964125560538172, + "constraints": { + "maxVelocity": 10.0, + "maxAcceleration": 4.5, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + } + } + ], "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, - "maxAcceleration": 3.0, + "maxVelocity": 10.0, + "maxAcceleration": 3.5, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, "nominalVoltage": 12.0, @@ -71,5 +85,5 @@ "velocity": 0, "rotation": -53.8 }, - "useDefaultConstraints": true + "useDefaultConstraints": false } \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/HP1_R2.path b/src/main/deploy/pathplanner/paths/HP1_R2.path index 147af5b..16c1a6a 100644 --- a/src/main/deploy/pathplanner/paths/HP1_R2.path +++ b/src/main/deploy/pathplanner/paths/HP1_R2.path @@ -3,53 +3,64 @@ "waypoints": [ { "anchor": { - "x": 1.247, - "y": 6.779 + "x": 1.6185000000000003, + "y": 7.34975 }, "prevControl": null, "nextControl": { - "x": 1.4879523599452857, - "y": 6.712351967494925 + "x": 1.8179302447703478, + "y": 7.148073150731447 }, "isLocked": false, "linkedName": "HP1" }, { "anchor": { - "x": 2.673258196721312, - "y": 6.452510245901639 + "x": 3.722528569965569, + "y": 4.991511920463674 }, "prevControl": { - "x": 2.311791120569321, - "y": 6.587935044803319 - }, - "nextControl": { - "x": 2.9073671721106025, - "y": 6.364800567745939 - }, - "isLocked": false, - "linkedName": null - }, - { - "anchor": { - "x": 3.7, - "y": 5.45 - }, - "prevControl": { - "x": 3.864246218182973, - "y": 5.261524060388093 + "x": 3.5620492827809422, + "y": 5.1832054216177665 }, "nextControl": null, "isLocked": false, - "linkedName": "R2" + "linkedName": "ScoreR2" } ], "rotationTargets": [], - "constraintZones": [], + "constraintZones": [ + { + "name": "Constraints Zone", + "minWaypointRelativePos": 0, + "maxWaypointRelativePos": 0.481165919282511, + "constraints": { + "maxVelocity": 10.0, + "maxAcceleration": 4.5, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + } + }, + { + "name": "Constraints Zone", + "minWaypointRelativePos": 0.7484304932735449, + "maxWaypointRelativePos": 0.9959641255605383, + "constraints": { + "maxVelocity": 10.0, + "maxAcceleration": 2.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + } + } + ], "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 10.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, @@ -66,5 +77,5 @@ "velocity": 0, "rotation": -53.8 }, - "useDefaultConstraints": true + "useDefaultConstraints": false } \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/HP1_R3.path b/src/main/deploy/pathplanner/paths/HP1_R3.path index a08014b..ba9bc8d 100644 --- a/src/main/deploy/pathplanner/paths/HP1_R3.path +++ b/src/main/deploy/pathplanner/paths/HP1_R3.path @@ -3,13 +3,13 @@ "waypoints": [ { "anchor": { - "x": 1.247, - "y": 6.779 + "x": 1.6185000000000003, + "y": 7.34975 }, "prevControl": null, "nextControl": { - "x": 1.5110523892007985, - "y": 6.7071813828893925 + "x": 1.8825523892007987, + "y": 7.277931382889393 }, "isLocked": false, "linkedName": "HP1" @@ -32,16 +32,16 @@ }, { "anchor": { - "x": 5.27, - "y": 5.43 + "x": 4.998872950819672, + "y": 5.181813524590163 }, "prevControl": { - "x": 5.032070058765731, - "y": 5.506742055382024 + "x": 5.652122950819671, + "y": 5.747313524590164 }, "nextControl": null, "isLocked": false, - "linkedName": "R3" + "linkedName": "ScoreR3" } ], "rotationTargets": [ @@ -54,7 +54,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/HP1_R4.path b/src/main/deploy/pathplanner/paths/HP1_R4.path index 860a822..a7f3699 100644 --- a/src/main/deploy/pathplanner/paths/HP1_R4.path +++ b/src/main/deploy/pathplanner/paths/HP1_R4.path @@ -3,13 +3,13 @@ "waypoints": [ { "anchor": { - "x": 1.247, - "y": 6.779 + "x": 1.6185000000000003, + "y": 7.34975 }, "prevControl": null, "nextControl": { - "x": 1.6122329879569814, - "y": 6.67470666218961 + "x": 1.9837329879569816, + "y": 7.245456662189611 }, "isLocked": false, "linkedName": "HP1" @@ -32,16 +32,16 @@ }, { "anchor": { - "x": 6.1, - "y": 4.05 + "x": 5.658196721311475, + "y": 4.198821721311475 }, "prevControl": { - "x": 6.299382431398496, - "y": 4.806897065998337 + "x": 7.081696721311474, + "y": 4.091571721311475 }, "nextControl": null, "isLocked": false, - "linkedName": "R4" + "linkedName": "ScoreR4" } ], "rotationTargets": [ @@ -54,7 +54,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/HP1_R5.path b/src/main/deploy/pathplanner/paths/HP1_R5.path index 97afd75..cfbe7df 100644 --- a/src/main/deploy/pathplanner/paths/HP1_R5.path +++ b/src/main/deploy/pathplanner/paths/HP1_R5.path @@ -3,13 +3,13 @@ "waypoints": [ { "anchor": { - "x": 1.247, - "y": 6.779 + "x": 1.6185000000000003, + "y": 7.34975 }, "prevControl": null, "nextControl": { - "x": 1.9956867780812888, - "y": 5.868660610858647 + "x": 2.367186778081289, + "y": 6.439410610858648 }, "isLocked": false, "linkedName": "HP1" @@ -48,16 +48,16 @@ }, { "anchor": { - "x": 5.301, - "y": 2.622 + "x": 5.238627049180328, + "y": 3.036014344262295 }, "prevControl": { - "x": 6.051253603043067, - "y": 3.1674757763543537 + "x": 5.666348360655737, + "y": 2.5387643442622947 }, "nextControl": null, "isLocked": false, - "linkedName": "R5" + "linkedName": "ScoreR5" } ], "rotationTargets": [ @@ -70,7 +70,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, @@ -79,7 +79,7 @@ }, "goalEndState": { "velocity": 0, - "rotation": 119.99999999999999 + "rotation": 120.9 }, "reversed": false, "folder": "HP to Reef", diff --git a/src/main/deploy/pathplanner/paths/HP1_R6.path b/src/main/deploy/pathplanner/paths/HP1_R6.path index 3522805..0550f5d 100644 --- a/src/main/deploy/pathplanner/paths/HP1_R6.path +++ b/src/main/deploy/pathplanner/paths/HP1_R6.path @@ -3,45 +3,45 @@ "waypoints": [ { "anchor": { - "x": 1.247, - "y": 6.779 + "x": 1.6185000000000003, + "y": 7.34975 }, "prevControl": null, "nextControl": { - "x": 2.471821944376244, - "y": 6.861442318740352 + "x": 2.8433219443762443, + "y": 7.432192318740352 }, "isLocked": false, "linkedName": "HP1" }, { "anchor": { - "x": 2.7177259886248595, - "y": 4.018533305367078 + "x": 2.4765, + "y": 3.966499999999999 }, "prevControl": { - "x": 2.5539339198179394, - "y": 4.762454946512012 + "x": 2.31270793119308, + "y": 4.710421641144933 }, "nextControl": { - "x": 2.824202270680717, - "y": 3.534932291795547 + "x": 2.5829762820558577, + "y": 3.482898986428468 }, "isLocked": false, "linkedName": null }, { "anchor": { - "x": 3.696, - "y": 2.622 + "x": 4.039856557377049, + "y": 2.916137295081967 }, "prevControl": { - "x": 3.1282858658333375, - "y": 3.0999055801131097 + "x": 3.3963565573770484, + "y": 1.9996372950819667 }, "nextControl": null, "isLocked": false, - "linkedName": "R6" + "linkedName": "ScoreR6" } ], "rotationTargets": [ @@ -54,7 +54,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/HP2_R1.path b/src/main/deploy/pathplanner/paths/HP2_R1.path index 14932d3..781ea8e 100644 --- a/src/main/deploy/pathplanner/paths/HP2_R1.path +++ b/src/main/deploy/pathplanner/paths/HP2_R1.path @@ -3,29 +3,29 @@ "waypoints": [ { "anchor": { - "x": 1.418, - "y": 1.245 + "x": 1.599, + "y": 0.670999999999999 }, "prevControl": null, "nextControl": { - "x": 2.606941747572815, - "y": 1.213592233009707 + "x": 2.7879417475728143, + "y": 0.6395922330097061 }, "isLocked": false, "linkedName": "HP2" }, { "anchor": { - "x": 2.85, - "y": 4.05 + "x": 3.2841721390676866, + "y": 3.837271284603343 }, "prevControl": { - "x": 2.7728704117477947, - "y": 4.3210022711044775 + "x": 2.11575, + "y": 4.112749999999999 }, "nextControl": null, "isLocked": false, - "linkedName": "R1" + "linkedName": "ScoreR1" } ], "rotationTargets": [ @@ -38,7 +38,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/HP2_R2.path b/src/main/deploy/pathplanner/paths/HP2_R2.path index 2c2baee..266c29a 100644 --- a/src/main/deploy/pathplanner/paths/HP2_R2.path +++ b/src/main/deploy/pathplanner/paths/HP2_R2.path @@ -3,45 +3,45 @@ "waypoints": [ { "anchor": { - "x": 1.418, - "y": 1.245 + "x": 1.599, + "y": 0.670999999999999 }, "prevControl": null, "nextControl": { - "x": 3.390728155339805, - "y": 2.4233495145631077 + "x": 2.91525, + "y": 3.362 }, "isLocked": false, "linkedName": "HP2" }, { "anchor": { - "x": 2.709174757281553, - "y": 3.8375728155339806 + "x": 2.58375, + "y": 4.688 }, "prevControl": { - "x": 2.874165506224661, - "y": 3.177609819761547 + "x": 2.3205000000000005, + "y": 4.200499999999999 }, "nextControl": { - "x": 2.470631067961165, - "y": 4.7917475728155345 + "x": 2.852242393984349, + "y": 5.185208137008054 }, "isLocked": false, "linkedName": null }, { "anchor": { - "x": 3.7, - "y": 5.45 + "x": 3.722528569965569, + "y": 4.991511920463674 }, "prevControl": { - "x": 3.2114563106796115, - "y": 4.928058252427184 + "x": 3.22725, + "y": 5.5264999999999995 }, "nextControl": null, "isLocked": false, - "linkedName": "R2" + "linkedName": "ScoreR2" } ], "rotationTargets": [ @@ -54,7 +54,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/HP2_R3.path b/src/main/deploy/pathplanner/paths/HP2_R3.path index 488b3a0..b2758b8 100644 --- a/src/main/deploy/pathplanner/paths/HP2_R3.path +++ b/src/main/deploy/pathplanner/paths/HP2_R3.path @@ -3,13 +3,13 @@ "waypoints": [ { "anchor": { - "x": 1.418, - "y": 1.245 + "x": 1.599, + "y": 0.670999999999999 }, "prevControl": null, "nextControl": { - "x": 1.579853589087624, - "y": 1.4355345525080807 + "x": 1.7608535890876242, + "y": 0.8615345525080795 }, "isLocked": false, "linkedName": "HP2" @@ -48,16 +48,16 @@ }, { "anchor": { - "x": 5.27, - "y": 5.43 + "x": 4.998872950819672, + "y": 5.181813524590163 }, "prevControl": { - "x": 5.332471627267896, - "y": 6.459744247891212 + "x": 5.408372950819673, + "y": 6.322563524590164 }, "nextControl": null, "isLocked": false, - "linkedName": "R3" + "linkedName": "ScoreR3" } ], "rotationTargets": [ @@ -70,7 +70,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/HP2_R4.path b/src/main/deploy/pathplanner/paths/HP2_R4.path index 23f58bd..05cbed7 100644 --- a/src/main/deploy/pathplanner/paths/HP2_R4.path +++ b/src/main/deploy/pathplanner/paths/HP2_R4.path @@ -3,45 +3,45 @@ "waypoints": [ { "anchor": { - "x": 1.418, - "y": 1.245 + "x": 1.599, + "y": 0.670999999999999 }, "prevControl": null, "nextControl": { - "x": 3.2040620895951974, - "y": 0.27841135001952744 + "x": 3.1005000000000003, + "y": 1.402249999999999 }, "isLocked": false, "linkedName": "HP2" }, { "anchor": { - "x": 4.839029126213592, - "y": 1.4862135922330106 + "x": 6.298500000000001, + "y": 2.61125 }, "prevControl": { - "x": 4.617353569020709, - "y": 1.3706283538016897 + "x": 5.664750000000001, + "y": 2.104250000000001 }, "nextControl": { - "x": 5.12442779806873, - "y": 1.6350250983462242 + "x": 6.549834567430718, + "y": 2.8123176539445742 }, "isLocked": false, "linkedName": null }, { "anchor": { - "x": 6.1, - "y": 4.05 + "x": 5.658196721311475, + "y": 4.198821721311475 }, "prevControl": { - "x": 6.396, - "y": 3.1572499999999994 + "x": 6.747000000000001, + "y": 4.52225 }, "nextControl": null, "isLocked": false, - "linkedName": "R4" + "linkedName": "ScoreR4" } ], "rotationTargets": [ @@ -54,7 +54,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/HP2_R5.path b/src/main/deploy/pathplanner/paths/HP2_R5.path index 6305e1b..0f45912 100644 --- a/src/main/deploy/pathplanner/paths/HP2_R5.path +++ b/src/main/deploy/pathplanner/paths/HP2_R5.path @@ -3,29 +3,29 @@ "waypoints": [ { "anchor": { - "x": 1.418, - "y": 1.245 + "x": 1.599, + "y": 0.670999999999999 }, "prevControl": null, "nextControl": { - "x": 5.639755868499901, - "y": 2.721579715385717 + "x": 3.12975, + "y": 1.5387499999999998 }, "isLocked": false, "linkedName": "HP2" }, { "anchor": { - "x": 5.301, - "y": 2.622 + "x": 5.238627049180328, + "y": 3.036014344262295 }, "prevControl": { - "x": 5.064463112359014, - "y": 2.541066071483491 + "x": 5.9182500000000005, + "y": 2.328499999999999 }, "nextControl": null, "isLocked": false, - "linkedName": "R5" + "linkedName": "ScoreR5" } ], "rotationTargets": [ @@ -38,16 +38,16 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 10.0, "maxAcceleration": 3.0, - "maxAngularVelocity": 540.0, - "maxAngularAcceleration": 720.0, + "maxAngularVelocity": 800.0, + "maxAngularAcceleration": 800.0, "nominalVoltage": 12.0, "unlimited": false }, "goalEndState": { "velocity": 0, - "rotation": 119.99999999999999 + "rotation": 120.9 }, "reversed": false, "folder": "HP to Reef", @@ -55,5 +55,5 @@ "velocity": 0, "rotation": 53.8 }, - "useDefaultConstraints": true + "useDefaultConstraints": false } \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/HP2_R6.path b/src/main/deploy/pathplanner/paths/HP2_R6.path index c0ad666..4b8443d 100644 --- a/src/main/deploy/pathplanner/paths/HP2_R6.path +++ b/src/main/deploy/pathplanner/paths/HP2_R6.path @@ -3,29 +3,29 @@ "waypoints": [ { "anchor": { - "x": 1.418, - "y": 1.245 + "x": 1.599, + "y": 0.670999999999999 }, "prevControl": null, "nextControl": { - "x": 2.69930238937698, - "y": 2.0388538665069196 + "x": 2.9838742645740246, + "y": 2.0569625625489363 }, "isLocked": false, "linkedName": "HP2" }, { "anchor": { - "x": 3.696, - "y": 2.622 + "x": 4.039856557377049, + "y": 2.916137295081967 }, "prevControl": { - "x": 3.4801362669835636, - "y": 2.49531771374406 + "x": 3.8588082879463577, + "y": 2.743737979143208 }, "nextControl": null, "isLocked": false, - "linkedName": "R6" + "linkedName": "ScoreR6" } ], "rotationTargets": [ @@ -38,7 +38,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 10.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, @@ -55,5 +55,5 @@ "velocity": 0, "rotation": 53.8 }, - "useDefaultConstraints": true + "useDefaultConstraints": false } \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/LeaveA.path b/src/main/deploy/pathplanner/paths/LeaveA.path index 635629b..c4f8eef 100644 --- a/src/main/deploy/pathplanner/paths/LeaveA.path +++ b/src/main/deploy/pathplanner/paths/LeaveA.path @@ -3,25 +3,25 @@ "waypoints": [ { "anchor": { - "x": 8.141, - "y": 7.262 + "x": 7.5282786885245905, + "y": 6.188780737704917 }, "prevControl": null, "nextControl": { - "x": 8.390999846987176, - "y": 7.261723402117175 + "x": 7.269916778365831, + "y": 6.1808794370187305 }, "isLocked": false, "linkedName": "A" }, { "anchor": { - "x": 7.5, - "y": 7.262 + "x": 6.809016393442622, + "y": 6.188780737704917 }, "prevControl": { - "x": 7.786891826231032, - "y": 7.2620629067231155 + "x": 7.058621011277562, + "y": 6.202835443517339 }, "nextControl": null, "isLocked": false, @@ -33,7 +33,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/LeaveB.path b/src/main/deploy/pathplanner/paths/LeaveB.path index e958cd2..93fc446 100644 --- a/src/main/deploy/pathplanner/paths/LeaveB.path +++ b/src/main/deploy/pathplanner/paths/LeaveB.path @@ -3,25 +3,25 @@ "waypoints": [ { "anchor": { - "x": 8.141, - "y": 6.209 + "x": 7.564241803278687, + "y": 4.030993852459016 }, "prevControl": null, "nextControl": { - "x": 8.390999846987176, - "y": 6.208723402117175 + "x": 7.314355528955309, + "y": 4.0234539648748875 }, "isLocked": false, "linkedName": "B" }, { "anchor": { - "x": 7.5, - "y": 6.209 + "x": 6.880942622950819, + "y": 4.030993852459016 }, "prevControl": { - "x": 7.786891826231032, - "y": 6.209062906723116 + "x": 7.130742610100138, + "y": 4.020995531589988 }, "nextControl": null, "isLocked": false, @@ -33,7 +33,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/LeaveC.path b/src/main/deploy/pathplanner/paths/LeaveC.path index 13521e5..d696859 100644 --- a/src/main/deploy/pathplanner/paths/LeaveC.path +++ b/src/main/deploy/pathplanner/paths/LeaveC.path @@ -3,25 +3,25 @@ "waypoints": [ { "anchor": { - "x": 8.141, - "y": 5.058 + "x": 7.564241803278687, + "y": 1.9810963114754099 }, "prevControl": null, "nextControl": { - "x": 8.390999846987176, - "y": 5.057723402117175 + "x": 7.315948443712548, + "y": 1.9519345626362223 }, "isLocked": false, "linkedName": "C" }, { "anchor": { - "x": 7.5, - "y": 5.058 + "x": 6.749077868852458, + "y": 1.9810963114754099 }, "prevControl": { - "x": 7.786891826231032, - "y": 5.058062906723116 + "x": 6.998845717001885, + "y": 1.9918676637955703 }, "nextControl": null, "isLocked": false, @@ -33,7 +33,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/PushScore.path b/src/main/deploy/pathplanner/paths/PushScore.path new file mode 100644 index 0000000..bd78b8e --- /dev/null +++ b/src/main/deploy/pathplanner/paths/PushScore.path @@ -0,0 +1,70 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 7.5855, + "y": 4.0249999999999995 + }, + "prevControl": null, + "nextControl": { + "x": 7.975499999999999, + "y": 3.9957499999999997 + }, + "isLocked": false, + "linkedName": null + }, + { + "anchor": { + "x": 7.94625, + "y": 4.0249999999999995 + }, + "prevControl": { + "x": 8.19625, + "y": 4.0249999999999995 + }, + "nextControl": { + "x": 6.946250000000003, + "y": 4.0249999999999995 + }, + "isLocked": false, + "linkedName": null + }, + { + "anchor": { + "x": 5.658196721311475, + "y": 4.198821721311475 + }, + "prevControl": { + "x": 6.1651967213114744, + "y": 4.130571721311475 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "ScoreR4" + } + ], + "rotationTargets": [], + "constraintZones": [], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 5.0, + "maxAcceleration": 3.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0, + "rotation": 180.0 + }, + "reversed": false, + "folder": null, + "idealStartingState": { + "velocity": 0, + "rotation": 180.0 + }, + "useDefaultConstraints": true +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/R1_HP1.path b/src/main/deploy/pathplanner/paths/R1_HP1.path index 243f4d7..863af19 100644 --- a/src/main/deploy/pathplanner/paths/R1_HP1.path +++ b/src/main/deploy/pathplanner/paths/R1_HP1.path @@ -3,41 +3,41 @@ "waypoints": [ { "anchor": { - "x": 2.85, - "y": 4.05 + "x": 3.2841721390676866, + "y": 3.837271284603343 }, "prevControl": null, "nextControl": { - "x": 2.849121552272355, - "y": 4.390187198760307 + "x": 2.2230000000000003, + "y": 3.6642499999999996 }, "isLocked": false, - "linkedName": "R1" + "linkedName": "ScoreR1" }, { "anchor": { - "x": 2.85, - "y": 5.87917236641607 + "x": 2.40825, + "y": 5.516749999999999 }, "prevControl": { - "x": 3.280781993388673, - "y": 5.350200535202626 + "x": 2.8390319933886725, + "y": 4.987778168786555 }, "nextControl": { - "x": 2.506508605458991, - "y": 6.300957108501335 + "x": 2.064758605458991, + "y": 5.938534742085264 }, "isLocked": false, "linkedName": null }, { "anchor": { - "x": 1.247, - "y": 6.779 + "x": 1.6185000000000003, + "y": 7.34975 }, "prevControl": { - "x": 2.4672242627870786, - "y": 6.792890176740379 + "x": 2.8387242627870783, + "y": 7.363640176740379 }, "nextControl": null, "isLocked": false, @@ -54,7 +54,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/R1_HP2.path b/src/main/deploy/pathplanner/paths/R1_HP2.path index 56f97de..0b0ec8a 100644 --- a/src/main/deploy/pathplanner/paths/R1_HP2.path +++ b/src/main/deploy/pathplanner/paths/R1_HP2.path @@ -3,16 +3,16 @@ "waypoints": [ { "anchor": { - "x": 2.85, - "y": 4.05 + "x": 3.2841721390676866, + "y": 3.837271284603343 }, "prevControl": null, "nextControl": { - "x": 2.933014723974309, - "y": 3.482082157302947 + "x": 2.262, + "y": 3.9372499999999997 }, "isLocked": false, - "linkedName": "R1" + "linkedName": "ScoreR1" }, { "anchor": { @@ -32,12 +32,12 @@ }, { "anchor": { - "x": 1.418, - "y": 1.245 + "x": 1.599, + "y": 0.670999999999999 }, "prevControl": { - "x": 2.1468932038834954, - "y": 1.469174757281552 + "x": 2.3278932038834954, + "y": 0.8951747572815507 }, "nextControl": null, "isLocked": false, @@ -54,7 +54,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/R2_HP1.path b/src/main/deploy/pathplanner/paths/R2_HP1.path index 295b6b3..95167f3 100644 --- a/src/main/deploy/pathplanner/paths/R2_HP1.path +++ b/src/main/deploy/pathplanner/paths/R2_HP1.path @@ -3,25 +3,25 @@ "waypoints": [ { "anchor": { - "x": 3.7, - "y": 5.45 + "x": 3.723, + "y": 4.991511920463674 }, "prevControl": null, "nextControl": { - "x": 3.3930000000000002, - "y": 5.88725 + "x": 2.665728368105369, + "y": 6.223712505356056 }, "isLocked": true, - "linkedName": "R2" + "linkedName": "ScoreR2" }, { "anchor": { - "x": 1.247, - "y": 6.779 + "x": 1.6185000000000003, + "y": 7.34975 }, "prevControl": { - "x": 2.554500000000001, - "y": 7.603249999999999 + "x": 1.7860635948907588, + "y": 7.164217141273343 }, "nextControl": null, "isLocked": true, @@ -29,12 +29,26 @@ } ], "rotationTargets": [], - "constraintZones": [], + "constraintZones": [ + { + "name": "Constraints Zone", + "minWaypointRelativePos": 0, + "maxWaypointRelativePos": 0.45067264573991034, + "constraints": { + "maxVelocity": 10.0, + "maxAcceleration": 5.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + } + } + ], "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, - "maxAcceleration": 3.0, + "maxVelocity": 10.0, + "maxAcceleration": 4.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, "nominalVoltage": 12.0, @@ -50,5 +64,5 @@ "velocity": 0, "rotation": -59.5 }, - "useDefaultConstraints": true + "useDefaultConstraints": false } \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/R2_HP2.path b/src/main/deploy/pathplanner/paths/R2_HP2.path index 5906654..d821e2e 100644 --- a/src/main/deploy/pathplanner/paths/R2_HP2.path +++ b/src/main/deploy/pathplanner/paths/R2_HP2.path @@ -3,16 +3,16 @@ "waypoints": [ { "anchor": { - "x": 3.7, - "y": 5.45 + "x": 3.722528569965569, + "y": 4.991511920463674 }, "prevControl": null, "nextControl": { - "x": 2.8284466019417476, - "y": 5.064368932038835 + "x": 3.123028569965569, + "y": 5.9185946664523525 }, "isLocked": false, - "linkedName": "R2" + "linkedName": "ScoreR2" }, { "anchor": { @@ -32,12 +32,12 @@ }, { "anchor": { - "x": 1.418, - "y": 1.245 + "x": 1.599, + "y": 0.670999999999999 }, "prevControl": { - "x": 2.7943689320388345, - "y": 1.5714077669902917 + "x": 2.975368932038834, + "y": 0.9974077669902908 }, "nextControl": null, "isLocked": false, @@ -54,7 +54,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/R3_HP1.path b/src/main/deploy/pathplanner/paths/R3_HP1.path index 53a657b..6a7e121 100644 --- a/src/main/deploy/pathplanner/paths/R3_HP1.path +++ b/src/main/deploy/pathplanner/paths/R3_HP1.path @@ -3,41 +3,41 @@ "waypoints": [ { "anchor": { - "x": 5.27, - "y": 5.43 + "x": 4.998872950819672, + "y": 5.181813524590163 }, "prevControl": null, "nextControl": { - "x": 5.269121552272354, - "y": 5.770187198760307 + "x": 4.96275, + "y": 6.062749999999999 }, "isLocked": false, - "linkedName": "R3" + "linkedName": "ScoreR3" }, { "anchor": { - "x": 2.940519751329567, - "y": 6.779 + "x": 4.085249999999999, + "y": 6.238249999999999 }, "prevControl": { - "x": 3.37130174471824, - "y": 6.250028168786556 + "x": 4.391379510922372, + "y": 6.100276135922311 }, "nextControl": { - "x": 2.597028356788558, - "y": 7.200784742085265 + "x": 3.3929999999999993, + "y": 6.550249999999999 }, "isLocked": false, "linkedName": null }, { "anchor": { - "x": 1.247, - "y": 6.779 + "x": 1.6185000000000003, + "y": 7.34975 }, "prevControl": { - "x": 1.9222661575487776, - "y": 6.969162308622982 + "x": 1.8781417813890309, + "y": 7.256893925639328 }, "nextControl": null, "isLocked": false, @@ -46,16 +46,30 @@ ], "rotationTargets": [ { - "waypointRelativePos": 1.0681992337164712, + "waypointRelativePos": 1.417904761904762, "rotationDegrees": -53.8 } ], - "constraintZones": [], + "constraintZones": [ + { + "name": "Constraints Zone", + "minWaypointRelativePos": 0.0, + "maxWaypointRelativePos": 1.7282608695652175, + "constraints": { + "maxVelocity": 10.0, + "maxAcceleration": 4.5, + "maxAngularVelocity": 800.0, + "maxAngularAcceleration": 750.0, + "nominalVoltage": 12.0, + "unlimited": false + } + } + ], "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, - "maxAcceleration": 3.0, + "maxVelocity": 10.0, + "maxAcceleration": 3.5, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, "nominalVoltage": 12.0, @@ -71,5 +85,5 @@ "velocity": 0, "rotation": -121.5 }, - "useDefaultConstraints": true + "useDefaultConstraints": false } \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/R3_HP2.path b/src/main/deploy/pathplanner/paths/R3_HP2.path index 71ea67a..cac1ec6 100644 --- a/src/main/deploy/pathplanner/paths/R3_HP2.path +++ b/src/main/deploy/pathplanner/paths/R3_HP2.path @@ -3,16 +3,16 @@ "waypoints": [ { "anchor": { - "x": 5.27, - "y": 5.43 + "x": 4.998872950819672, + "y": 5.181813524590163 }, "prevControl": null, "nextControl": { - "x": 4.54124935998884, - "y": 6.801706917455025 + "x": 5.730122950819673, + "y": 6.2445635245901645 }, "isLocked": false, - "linkedName": "R3" + "linkedName": "ScoreR3" }, { "anchor": { @@ -20,40 +20,40 @@ "y": 5.576493502516883 }, "prevControl": { - "x": 3.1619672723435244, - "y": 5.822659919233285 + "x": 3.498200629049366, + "y": 6.380665289450421 }, "nextControl": { - "x": 2.589902912627433, - "y": 2.593737864084271 + "x": 2.33025, + "y": 3.9079999999999995 }, "isLocked": false, "linkedName": null }, { "anchor": { - "x": 2.453592233016892, - "y": 1.7758737864117529 + "x": 2.457, + "y": 2.279749999999999 }, "prevControl": { - "x": 2.721136619743959, - "y": 2.199101907871769 + "x": 2.7245443867270667, + "y": 2.7029781214600153 }, "nextControl": { - "x": 2.3200074722954174, - "y": 1.56455622513729 + "x": 2.3234152392785252, + "y": 2.068432438725536 }, "isLocked": false, "linkedName": null }, { "anchor": { - "x": 1.418, - "y": 1.245 + "x": 1.599, + "y": 0.670999999999999 }, "prevControl": { - "x": 1.6447906799598557, - "y": 1.3501949974254779 + "x": 1.8257906799598558, + "y": 0.7761949974254767 }, "nextControl": null, "isLocked": false, @@ -70,7 +70,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/R4_HP1.path b/src/main/deploy/pathplanner/paths/R4_HP1.path index 0add02c..aac7b48 100644 --- a/src/main/deploy/pathplanner/paths/R4_HP1.path +++ b/src/main/deploy/pathplanner/paths/R4_HP1.path @@ -3,57 +3,41 @@ "waypoints": [ { "anchor": { - "x": 6.1, - "y": 4.05 + "x": 5.658196721311475, + "y": 4.198821721311475 }, "prevControl": null, "nextControl": { - "x": 5.947382318427628, - "y": 4.5856687162071434 + "x": 6.964696721311474, + "y": 4.267071721311475 }, "isLocked": false, - "linkedName": "R4" + "linkedName": "ScoreR4" }, { "anchor": { - "x": 5.629198413591059, - "y": 5.458108455275157 + "x": 5.391749999999999, + "y": 5.653250000000001 }, "prevControl": { - "x": 5.947227462297942, - "y": 5.1430120797868195 + "x": 5.77666058421225, + "y": 5.424619197550555 }, "nextControl": { - "x": 4.736796116505998, - "y": 6.34228155340034 + "x": 4.42305158640894, + "y": 6.2286415447248435 }, "isLocked": false, "linkedName": null }, { "anchor": { - "x": 3.1181067961176496, - "y": 6.376359223303252 + "x": 1.6185000000000003, + "y": 7.34975 }, "prevControl": { - "x": 3.487827573715305, - "y": 6.109813309370754 - }, - "nextControl": { - "x": 2.4581067023021, - "y": 6.852178649370358 - }, - "isLocked": false, - "linkedName": null - }, - { - "anchor": { - "x": 1.247, - "y": 6.779 - }, - "prevControl": { - "x": 2.266705650839546, - "y": 7.380445551407007 + "x": 2.638205650839546, + "y": 7.951195551407007 }, "nextControl": null, "isLocked": false, @@ -62,7 +46,7 @@ ], "rotationTargets": [ { - "waypointRelativePos": 1.464367816091949, + "waypointRelativePos": 1.25, "rotationDegrees": -53.8 } ], @@ -70,7 +54,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/R4_HP2.path b/src/main/deploy/pathplanner/paths/R4_HP2.path index a9ce710..8c1f078 100644 --- a/src/main/deploy/pathplanner/paths/R4_HP2.path +++ b/src/main/deploy/pathplanner/paths/R4_HP2.path @@ -3,16 +3,16 @@ "waypoints": [ { "anchor": { - "x": 6.1, - "y": 4.05 + "x": 5.658196721311475, + "y": 4.198821721311475 }, "prevControl": null, "nextControl": { - "x": 5.970254952512325, - "y": 4.4576470052549215 + "x": 7.032946721311474, + "y": 4.267071721311475 }, "isLocked": false, - "linkedName": "R4" + "linkedName": "ScoreR4" }, { "anchor": { @@ -20,24 +20,24 @@ "y": 1.4862135922330106 }, "prevControl": { - "x": 6.372898260607746, - "y": 1.7692330578997566 + "x": 5.499, + "y": 1.53875 }, "nextControl": { - "x": 2.0993031068751495, - "y": 0.8354826853696199 + "x": 2.052457683064141, + "y": 1.1090934443173022 }, "isLocked": false, "linkedName": null }, { "anchor": { - "x": 1.418, - "y": 1.245 + "x": 1.599, + "y": 0.670999999999999 }, "prevControl": { - "x": 2.210700158361901, - "y": 1.3338537501867498 + "x": 2.3917001583619006, + "y": 0.7598537501867488 }, "nextControl": null, "isLocked": false, @@ -54,7 +54,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/R5_HP1.path b/src/main/deploy/pathplanner/paths/R5_HP1.path index ad4ec15..99dbcdb 100644 --- a/src/main/deploy/pathplanner/paths/R5_HP1.path +++ b/src/main/deploy/pathplanner/paths/R5_HP1.path @@ -3,16 +3,16 @@ "waypoints": [ { "anchor": { - "x": 5.301, - "y": 2.622 + "x": 5.238627049180328, + "y": 3.036014344262295 }, "prevControl": null, "nextControl": { - "x": 5.200490973792311, - "y": 3.0280121030042224 + "x": 5.637098360655738, + "y": 2.499764344262295 }, "isLocked": false, - "linkedName": "R5" + "linkedName": "ScoreR5" }, { "anchor": { @@ -20,12 +20,12 @@ "y": 2.167766990298476 }, "prevControl": { - "x": 4.508926689171617, - "y": 1.350515834104014 + "x": 4.8555, + "y": 1.645999999999999 }, "nextControl": { - "x": 2.546686845785932, - "y": 3.1055620379337188 + "x": 2.2954675427007376, + "y": 2.7058542064619293 }, "isLocked": false, "linkedName": null @@ -48,12 +48,12 @@ }, { "anchor": { - "x": 1.247, - "y": 6.779 + "x": 1.6185000000000003, + "y": 7.34975 }, "prevControl": { - "x": 1.9834831721873583, - "y": 6.897147827026787 + "x": 2.3549831721873584, + "y": 7.467897827026787 }, "nextControl": null, "isLocked": false, @@ -70,7 +70,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, @@ -85,7 +85,7 @@ "folder": "Reef to HP", "idealStartingState": { "velocity": 0, - "rotation": 119.99999999999999 + "rotation": 120.9 }, "useDefaultConstraints": true } \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/R5_HP2.path b/src/main/deploy/pathplanner/paths/R5_HP2.path index 58dcf8c..7a3f9f2 100644 --- a/src/main/deploy/pathplanner/paths/R5_HP2.path +++ b/src/main/deploy/pathplanner/paths/R5_HP2.path @@ -3,25 +3,25 @@ "waypoints": [ { "anchor": { - "x": 5.301, - "y": 2.622 + "x": 5.238627049180328, + "y": 3.036014344262295 }, "prevControl": null, "nextControl": { - "x": 2.0720937660850107, - "y": 1.4211897690928004 + "x": 4.4354508196721305, + "y": 0.49462090163934347 }, "isLocked": false, - "linkedName": "R5" + "linkedName": "ScoreR5" }, { "anchor": { - "x": 1.418, - "y": 1.245 + "x": 1.599, + "y": 0.670999999999999 }, "prevControl": { - "x": 1.6409967580939544, - "y": 1.3580152462262784 + "x": 2.076692256532537, + "y": 1.0270844778675974 }, "nextControl": null, "isLocked": false, @@ -30,18 +30,32 @@ ], "rotationTargets": [ { - "waypointRelativePos": 0.55, - "rotationDegrees": 53.8 + "waypointRelativePos": 0.3, + "rotationDegrees": 85.85745820949654 + } + ], + "constraintZones": [ + { + "name": "Constraints Zone", + "minWaypointRelativePos": 0, + "maxWaypointRelativePos": 1.0, + "constraints": { + "maxVelocity": 10.0, + "maxAcceleration": 4.5, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 800.0, + "nominalVoltage": 12.0, + "unlimited": false + } } ], - "constraintZones": [], "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, - "maxAcceleration": 3.0, + "maxVelocity": 10.0, + "maxAcceleration": 3.5, "maxAngularVelocity": 540.0, - "maxAngularAcceleration": 720.0, + "maxAngularAcceleration": 800.0, "nominalVoltage": 12.0, "unlimited": false }, @@ -53,7 +67,7 @@ "folder": "Reef to HP", "idealStartingState": { "velocity": 0, - "rotation": 119.99999999999999 + "rotation": 120.9 }, - "useDefaultConstraints": true + "useDefaultConstraints": false } \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/R6_HP1.path b/src/main/deploy/pathplanner/paths/R6_HP1.path index 338a258..f30d26d 100644 --- a/src/main/deploy/pathplanner/paths/R6_HP1.path +++ b/src/main/deploy/pathplanner/paths/R6_HP1.path @@ -3,16 +3,16 @@ "waypoints": [ { "anchor": { - "x": 3.696, - "y": 2.622 + "x": 4.039856557377049, + "y": 2.916137295081967 }, "prevControl": null, "nextControl": { - "x": 3.084029126213592, - "y": 2.764126213592233 + "x": 3.708356557377049, + "y": 1.9996372950819667 }, "isLocked": false, - "linkedName": "R6" + "linkedName": "ScoreR6" }, { "anchor": { @@ -32,12 +32,12 @@ }, { "anchor": { - "x": 1.247, - "y": 6.779 + "x": 1.6185000000000003, + "y": 7.34975 }, "prevControl": { - "x": 2.40247572815534, - "y": 7.177184466019417 + "x": 2.7739757281553397, + "y": 7.747934466019418 }, "nextControl": null, "isLocked": false, @@ -54,7 +54,7 @@ "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, + "maxVelocity": 5.0, "maxAcceleration": 3.0, "maxAngularVelocity": 540.0, "maxAngularAcceleration": 720.0, diff --git a/src/main/deploy/pathplanner/paths/R6_HP2.path b/src/main/deploy/pathplanner/paths/R6_HP2.path index 11ee9c4..0ac5890 100644 --- a/src/main/deploy/pathplanner/paths/R6_HP2.path +++ b/src/main/deploy/pathplanner/paths/R6_HP2.path @@ -3,67 +3,60 @@ "waypoints": [ { "anchor": { - "x": 3.696, - "y": 2.622 + "x": 4.039856557377049, + "y": 2.916137295081967 }, "prevControl": null, "nextControl": { - "x": 3.484284606523374, - "y": 2.993397199875651 + "x": 3.571212098601804, + "y": 2.4178008984523625 }, "isLocked": false, - "linkedName": "R6" + "linkedName": "ScoreR6" }, { "anchor": { - "x": 2.521747572815534, - "y": 3.496796116504854 + "x": 1.599, + "y": 0.670999999999999 }, "prevControl": { - "x": 2.571937204010619, - "y": 2.6310249783896342 - }, - "nextControl": { - "x": 2.385436893203884, - "y": 5.848155339805825 - }, - "isLocked": false, - "linkedName": null - }, - { - "anchor": { - "x": 1.247, - "y": 6.779 - }, - "prevControl": { - "x": 2.163932038834951, - "y": 6.870485436893204 + "x": 1.7602751563782437, + "y": 0.8620244066478749 }, "nextControl": null, "isLocked": false, - "linkedName": "HP1" + "linkedName": "HP2" } ], - "rotationTargets": [ + "rotationTargets": [], + "constraintZones": [ { - "waypointRelativePos": 1.0681992337164712, - "rotationDegrees": -53.8 + "name": "Constraints Zone", + "minWaypointRelativePos": 0, + "maxWaypointRelativePos": 0.42210144927536214, + "constraints": { + "maxVelocity": 10.0, + "maxAcceleration": 4.5, + "maxAngularVelocity": 600.0, + "maxAngularAcceleration": 800.0, + "nominalVoltage": 12.0, + "unlimited": false + } } ], - "constraintZones": [], "pointTowardsZones": [], "eventMarkers": [], "globalConstraints": { - "maxVelocity": 3.0, - "maxAcceleration": 3.0, - "maxAngularVelocity": 540.0, - "maxAngularAcceleration": 720.0, + "maxVelocity": 10.0, + "maxAcceleration": 4.0, + "maxAngularVelocity": 600.0, + "maxAngularAcceleration": 800.0, "nominalVoltage": 12.0, "unlimited": false }, "goalEndState": { "velocity": 0, - "rotation": -53.8 + "rotation": 53.8 }, "reversed": false, "folder": "Reef to HP", @@ -71,5 +64,5 @@ "velocity": 0, "rotation": 59.99999999999999 }, - "useDefaultConstraints": true + "useDefaultConstraints": false } \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/ScoreR1.path b/src/main/deploy/pathplanner/paths/ScoreR1.path new file mode 100644 index 0000000..3c2d153 --- /dev/null +++ b/src/main/deploy/pathplanner/paths/ScoreR1.path @@ -0,0 +1,54 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 2.85, + "y": 4.05 + }, + "prevControl": null, + "nextControl": { + "x": 3.0693210647773, + "y": 3.930007206279079 + }, + "isLocked": false, + "linkedName": "R1" + }, + { + "anchor": { + "x": 3.2841721390676866, + "y": 3.837271284603343 + }, + "prevControl": { + "x": 3.0477187212070858, + "y": 3.9184487518097058 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "ScoreR1" + } + ], + "rotationTargets": [], + "constraintZones": [], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 5.0, + "maxAcceleration": 3.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0, + "rotation": 0.0 + }, + "reversed": false, + "folder": "Move to Score", + "idealStartingState": { + "velocity": 0, + "rotation": 0.0 + }, + "useDefaultConstraints": true +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/ScoreR2.path b/src/main/deploy/pathplanner/paths/ScoreR2.path new file mode 100644 index 0000000..73347d0 --- /dev/null +++ b/src/main/deploy/pathplanner/paths/ScoreR2.path @@ -0,0 +1,54 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 3.7, + "y": 5.45 + }, + "prevControl": null, + "nextControl": { + "x": 3.69264400526603, + "y": 5.200108244750905 + }, + "isLocked": false, + "linkedName": "R2" + }, + { + "anchor": { + "x": 3.722528569965569, + "y": 4.991511920463674 + }, + "prevControl": { + "x": 3.7231937620492626, + "y": 5.241511035501092 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "ScoreR2" + } + ], + "rotationTargets": [], + "constraintZones": [], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 5.0, + "maxAcceleration": 3.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0, + "rotation": -59.5 + }, + "reversed": false, + "folder": "Move to Score", + "idealStartingState": { + "velocity": 0, + "rotation": -59.5 + }, + "useDefaultConstraints": true +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/ScoreR3.path b/src/main/deploy/pathplanner/paths/ScoreR3.path new file mode 100644 index 0000000..dd1ab75 --- /dev/null +++ b/src/main/deploy/pathplanner/paths/ScoreR3.path @@ -0,0 +1,54 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 5.2985655737704915, + "y": 5.42156762295082 + }, + "prevControl": null, + "nextControl": { + "x": 5.098015063530137, + "y": 5.272304456555579 + }, + "isLocked": false, + "linkedName": "R3" + }, + { + "anchor": { + "x": 4.998872950819672, + "y": 5.181813524590163 + }, + "prevControl": { + "x": 5.1918555097239345, + "y": 5.340740337805439 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "ScoreR3" + } + ], + "rotationTargets": [], + "constraintZones": [], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 5.0, + "maxAcceleration": 3.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0, + "rotation": -121.5 + }, + "reversed": false, + "folder": "Move to Score", + "idealStartingState": { + "velocity": 0, + "rotation": -121.5 + }, + "useDefaultConstraints": true +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/ScoreR4.path b/src/main/deploy/pathplanner/paths/ScoreR4.path new file mode 100644 index 0000000..1315acf --- /dev/null +++ b/src/main/deploy/pathplanner/paths/ScoreR4.path @@ -0,0 +1,54 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 6.1, + "y": 4.05 + }, + "prevControl": null, + "nextControl": { + "x": 5.865632200817294, + "y": 4.137015715283246 + }, + "isLocked": false, + "linkedName": "R4" + }, + { + "anchor": { + "x": 5.658196721311475, + "y": 4.198821721311475 + }, + "prevControl": { + "x": 5.903914768045055, + "y": 4.152749587548928 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "ScoreR4" + } + ], + "rotationTargets": [], + "constraintZones": [], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 5.0, + "maxAcceleration": 3.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0.0, + "rotation": 180.0 + }, + "reversed": false, + "folder": "Move to Score", + "idealStartingState": { + "velocity": 0, + "rotation": 180.0 + }, + "useDefaultConstraints": true +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/ScoreR5.path b/src/main/deploy/pathplanner/paths/ScoreR5.path new file mode 100644 index 0000000..e634718 --- /dev/null +++ b/src/main/deploy/pathplanner/paths/ScoreR5.path @@ -0,0 +1,54 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 5.33452868852459, + "y": 2.604456967213115 + }, + "prevControl": null, + "nextControl": { + "x": 5.180504780071455, + "y": 2.8473379695519756 + }, + "isLocked": false, + "linkedName": "R5" + }, + { + "anchor": { + "x": 5.238627049180328, + "y": 3.036014344262295 + }, + "prevControl": { + "x": 5.484980192150553, + "y": 2.887814902147897 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "ScoreR5" + } + ], + "rotationTargets": [], + "constraintZones": [], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 5.0, + "maxAcceleration": 3.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0.0, + "rotation": 120.9 + }, + "reversed": false, + "folder": "Move to Score", + "idealStartingState": { + "velocity": 0, + "rotation": 120.89912407537605 + }, + "useDefaultConstraints": true +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/paths/ScoreR6.path b/src/main/deploy/pathplanner/paths/ScoreR6.path new file mode 100644 index 0000000..e0ef623 --- /dev/null +++ b/src/main/deploy/pathplanner/paths/ScoreR6.path @@ -0,0 +1,54 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 3.6802254098360656, + "y": 2.6404200819672123 + }, + "prevControl": null, + "nextControl": { + "x": 3.8968743230212, + "y": 2.7651728310980435 + }, + "isLocked": false, + "linkedName": "R6" + }, + { + "anchor": { + "x": 4.039856557377049, + "y": 2.916137295081967 + }, + "prevControl": { + "x": 3.813005264970754, + "y": 2.8110730712301066 + }, + "nextControl": null, + "isLocked": false, + "linkedName": "ScoreR6" + } + ], + "rotationTargets": [], + "constraintZones": [], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 5.0, + "maxAcceleration": 3.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0.0, + "rotation": 59.99999999999999 + }, + "reversed": false, + "folder": "Move to Score", + "idealStartingState": { + "velocity": 0, + "rotation": 59.99999999999999 + }, + "useDefaultConstraints": true +} \ No newline at end of file diff --git a/src/main/deploy/pathplanner/settings.json b/src/main/deploy/pathplanner/settings.json index 46d6cb0..eb12f29 100644 --- a/src/main/deploy/pathplanner/settings.json +++ b/src/main/deploy/pathplanner/settings.json @@ -3,23 +3,32 @@ "robotLength": 0.9, "holonomicMode": true, "pathFolders": [ + "Fast A 3 Piece", "HP to Reef", "Leave Start", + "Move back from Score", + "Move to Score", + "Fast C 3 Piece", "Reef to HP", "Start to Reef" ], - "autoFolders": [], - "defaultMaxVel": 3.0, + "autoFolders": [ + "FAST AUTOS", + "LeaveStart", + "Algae Autos", + "Reliable Autos" + ], + "defaultMaxVel": 5.0, "defaultMaxAccel": 3.0, "defaultMaxAngVel": 540.0, "defaultMaxAngAccel": 720.0, "defaultNominalVoltage": 12.0, - "robotMass": 74.088, - "robotMOI": 6.883, + "robotMass": 50.0, + "robotMOI": 5.1, "robotTrackwidth": 0.546, - "driveWheelRadius": 0.048, - "driveGearing": 5.143, - "maxDriveSpeed": 5.45, + "driveWheelRadius": 0.049, + "driveGearing": 6.122, + "maxDriveSpeed": 5.0, "driveMotorType": "krakenX60", "driveCurrentLimit": 60.0, "wheelCOF": 1.2, diff --git a/src/main/java/frc/robot/FieldConstants.java b/src/main/java/frc/robot/FieldConstants.java new file mode 100644 index 0000000..3c0df25 --- /dev/null +++ b/src/main/java/frc/robot/FieldConstants.java @@ -0,0 +1,241 @@ +// Copyright (c) 2025 FRC 6328 +// http://github.com/Mechanical-Advantage +// +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file at +// the root directory of this project. + +package frc.robot; + +import edu.wpi.first.math.geometry.*; +import edu.wpi.first.math.util.Units; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Contains various field dimensions and useful reference points. All units are in meters and poses + * have a blue alliance origin. + */ +public class FieldConstants { + public static final double fieldLength = Units.inchesToMeters(690.876); + public static final double fieldWidth = Units.inchesToMeters(317); + public static final Translation2d fieldCenter = + new Translation2d(fieldLength / 2, fieldWidth / 2); + public static final double startingLineX = + Units.inchesToMeters(299.438); // Measured from the inside of starting + // line + + public static class Processor { + public static final Pose2d centerFace = + new Pose2d(Units.inchesToMeters(235.726), 0, Rotation2d.fromDegrees(90)); + } + + public static class Barge { + public static final Translation2d farCage = + new Translation2d(Units.inchesToMeters(345.428), Units.inchesToMeters(286.779)); + public static final Translation2d middleCage = + new Translation2d(Units.inchesToMeters(345.428), Units.inchesToMeters(242.855)); + public static final Translation2d closeCage = + new Translation2d(Units.inchesToMeters(345.428), Units.inchesToMeters(199.947)); + + // Measured from floor to bottom of cage + public static final double deepHeight = Units.inchesToMeters(3.125); + public static final double shallowHeight = Units.inchesToMeters(30.125); + } + + public static class CoralStation { + public static final Pose2d leftCenterFace = + new Pose2d( + Units.inchesToMeters(33.526), + Units.inchesToMeters(291.176), + Rotation2d.fromDegrees(90 - 144.011)); + public static final Pose2d rightCenterFace = + new Pose2d( + Units.inchesToMeters(33.526), + Units.inchesToMeters(25.824), + Rotation2d.fromDegrees(144.011 - 90)); + } + + public static class Reef { + public static final Translation2d centerOfReef = + new Translation2d(Units.inchesToMeters(176.746), Units.inchesToMeters(158.501)); + public static final double faceToZoneLine = + Units.inchesToMeters(12); // Side of the reef to the inside of the + // reef zone line + + public static final Pose2d[] centerFaces = + new Pose2d[12]; // Starting facing the driver station in clockwise + // order + public static final List> branchPositions = + new ArrayList<>(); // Starting at the right + // branch facing the + // driver station in + // clockwise + + static { + // Initialize faces + centerFaces[0] = + new Pose2d( + Units.inchesToMeters(144.003), + Units.inchesToMeters(158.500), + Rotation2d.fromDegrees(180)); + centerFaces[1] = + new Pose2d( + Units.inchesToMeters(160.373), + Units.inchesToMeters(186.857), + Rotation2d.fromDegrees(120)); + centerFaces[2] = + new Pose2d( + Units.inchesToMeters(193.116), + Units.inchesToMeters(186.858), + Rotation2d.fromDegrees(60)); + centerFaces[3] = + new Pose2d( + Units.inchesToMeters(209.489), + Units.inchesToMeters(158.502), + Rotation2d.fromDegrees(0)); + centerFaces[4] = + new Pose2d( + Units.inchesToMeters(193.118), + Units.inchesToMeters(130.145), + Rotation2d.fromDegrees(-60)); + centerFaces[5] = + new Pose2d( + Units.inchesToMeters(160.375), + Units.inchesToMeters(130.144), + Rotation2d.fromDegrees(-120)); + + centerFaces[6] = centerFaces[0].rotateAround(fieldCenter, Rotation2d.k180deg); + centerFaces[7] = centerFaces[1].rotateAround(fieldCenter, Rotation2d.k180deg); + centerFaces[8] = centerFaces[2].rotateAround(fieldCenter, Rotation2d.k180deg); + centerFaces[9] = centerFaces[3].rotateAround(fieldCenter, Rotation2d.k180deg); + centerFaces[10] = centerFaces[4].rotateAround(fieldCenter, Rotation2d.k180deg); + centerFaces[11] = centerFaces[5].rotateAround(fieldCenter, Rotation2d.k180deg); + + // Initialize branch positions + for (int face = 0; face < centerFaces.length; face++) { + Map fillRight = new HashMap<>(); + Map fillLeft = new HashMap<>(); + for (var level : ReefHeight.values()) { + Pose2d poseDirection = new Pose2d(); + if (face < 6) { + poseDirection = + new Pose2d(centerOfReef, centerFaces[face].getRotation()); + } else { + poseDirection = + new Pose2d(centerOfReef.rotateAround(fieldCenter, Rotation2d.k180deg), + centerFaces[face].getRotation()); + } + + double adjustX = Units.inchesToMeters(30.738); // Depth of branch from reef face + double adjustY = Units.inchesToMeters(6.469); // Offset from reef face + // centerline to branch + + fillRight.put( + level, + new Pose3d( + new Translation3d( + poseDirection + .transformBy( + new Transform2d(adjustX, adjustY, new Rotation2d())) + .getX(), + poseDirection + .transformBy( + new Transform2d(adjustX, adjustY, new Rotation2d())) + .getY(), + level.height), + new Rotation3d( + 0, + Units.degreesToRadians(level.pitch), + poseDirection.getRotation().getRadians()))); + fillLeft.put( + level, + new Pose3d( + new Translation3d( + poseDirection + .transformBy( + new Transform2d(adjustX, -adjustY, new Rotation2d())) + .getX(), + poseDirection + .transformBy( + new Transform2d(adjustX, -adjustY, new Rotation2d())) + .getY(), + level.height), + new Rotation3d( + 0, + Units.degreesToRadians(level.pitch), + poseDirection.getRotation().getRadians()))); + } + branchPositions.add(fillRight); + branchPositions.add(fillLeft); + } + + + } + } + + public static class StagingPositions { + // Measured from the center of the ice cream + public static final Pose2d leftIceCream = + new Pose2d(Units.inchesToMeters(48), Units.inchesToMeters(230.5), new Rotation2d()); + public static final Pose2d middleIceCream = + new Pose2d(Units.inchesToMeters(48), Units.inchesToMeters(158.5), new Rotation2d()); + public static final Pose2d rightIceCream = + new Pose2d(Units.inchesToMeters(48), Units.inchesToMeters(86.5), new Rotation2d()); + } + + public enum ReefHeight { + L4(Units.inchesToMeters(72), -90), + L3(Units.inchesToMeters(47.625), -35), + L2(Units.inchesToMeters(31.875), -35), + L1(Units.inchesToMeters(18), 0); + + ReefHeight(double height, double pitch) + { + this.height = height; + this.pitch = pitch; // in degrees + } + + public final double height; + public final double pitch; + } + + public static Pose2d getNearestReefFace(Pose2d currentPose) + { + return currentPose.nearest(List.of(FieldConstants.Reef.centerFaces)); + } + + public enum ReefSide { + LEFT, + RIGHT + } + + public static Pose2d getNearestReefBranch(Pose2d currentPose, ReefSide side) + { + return FieldConstants.Reef.branchPositions + .get(List.of(FieldConstants.Reef.centerFaces).indexOf(getNearestReefFace(currentPose)) + * 2 + (side == ReefSide.LEFT ? 1 : 0)) + .get(FieldConstants.ReefHeight.L1).toPose2d(); + } + + public static Pose2d getNearestCoralStation(Pose2d currentPose) + { + if (currentPose.getTranslation().getX() > FieldConstants.fieldLength / 2) { + if (currentPose.getTranslation().getY() > FieldConstants.fieldWidth / 2) { + return FieldConstants.CoralStation.rightCenterFace + .rotateAround(FieldConstants.fieldCenter, Rotation2d.k180deg); + } else { + return FieldConstants.CoralStation.leftCenterFace + .rotateAround(FieldConstants.fieldCenter, Rotation2d.k180deg); + } + } else { + if (currentPose.getTranslation().getY() > FieldConstants.fieldWidth / 2) { + return FieldConstants.CoralStation.leftCenterFace; + } else { + return FieldConstants.CoralStation.rightCenterFace; + } + } + } +} diff --git a/src/main/java/frc/robot/HardwareConstants.java b/src/main/java/frc/robot/HardwareConstants.java index 73ac298..648d9bc 100644 --- a/src/main/java/frc/robot/HardwareConstants.java +++ b/src/main/java/frc/robot/HardwareConstants.java @@ -24,18 +24,23 @@ public class CAN { public static final int ARM_MTR_ID = 14; public static final int INTAKE_MTR_ID = 15; - public static final int CLIMBER_MTR_ID = 1; + public static final int CLIMBER_MTR_ID = 30; public static final int PRIMARY_ELEVATOR_ID = 16; public static final int SECONDARY_ELEVATOR_ID = 17; public static final int CANDLE_ID = 50; - public static final int FEEDER_MTR_ID = 20; + public static final int LOWER_CORAL_LASERCAN_ID = 20; + public static final int UPPER_CORAL_LASERCAN_ID = 21; + public static final int ALGAE_LASERCAN_ID = 22; } public class DIO { // Add digitial I/O ports used here public static final int LIGHT_SENSOR_CHANNEL = 0; } + + // Use LoggedTunableNumbers + public static final boolean tuningMode = true; } diff --git a/src/main/java/frc/robot/Robot.java b/src/main/java/frc/robot/Robot.java index d02faca..ba50c8e 100644 --- a/src/main/java/frc/robot/Robot.java +++ b/src/main/java/frc/robot/Robot.java @@ -4,6 +4,13 @@ package frc.robot; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.BiConsumer; + import org.littletonrobotics.junction.LogFileUtil; import org.littletonrobotics.junction.LoggedRobot; import org.littletonrobotics.junction.Logger; @@ -11,35 +18,94 @@ import org.littletonrobotics.junction.wpilog.WPILOGReader; import org.littletonrobotics.junction.wpilog.WPILOGWriter; +import com.pathplanner.lib.auto.AutoBuilder; +import com.pathplanner.lib.commands.PathPlannerAuto; +import com.pathplanner.lib.path.PathPlannerPath; + +import au.grapplerobotics.CanBridge; +import edu.wpi.first.math.geometry.Pose2d; +import edu.wpi.first.math.geometry.Rotation2d; +import edu.wpi.first.math.geometry.Translation2d; +import edu.wpi.first.math.util.Units; +import edu.wpi.first.wpilibj.DriverStation; +import edu.wpi.first.wpilibj.DriverStation.Alliance; import edu.wpi.first.wpilibj.PowerDistribution; import edu.wpi.first.wpilibj.PowerDistribution.ModuleType; +import edu.wpi.first.wpilibj.smartdashboard.Field2d; +import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; import edu.wpi.first.wpilibj2.command.Command; import edu.wpi.first.wpilibj2.command.CommandScheduler; import frc.robot.HardwareConstants.CAN; +import java.io.IOException; +import org.json.simple.parser.ParseException; public class Robot extends LoggedRobot { private Command m_autonomousCommand; + private Command m_lastAutonomousCommand; + private List m_pathsToShow = new ArrayList(); + private Field2d m_autoTraj = new Field2d(); + public static final double fieldLength = Units.inchesToMeters(690.876); + public static final double fieldWidth = Units.inchesToMeters(317); + public static final Translation2d fieldCenter = new Translation2d(fieldLength / 2, fieldWidth / 2); - private final RobotContainer m_robotContainer; + private boolean ranAutonomous = false; - public Robot() { - Logger.recordMetadata("ProjectName", "ReefCode"); // Set a metadata value + private final RobotContainer m_robotContainer = new RobotContainer(); - if (isReal()) { - Logger.addDataReceiver(new WPILOGWriter()); // Log to a USB stick ("/U/logs") - Logger.addDataReceiver(new NT4Publisher()); // Publish data to NetworkTables - new PowerDistribution(CAN.PDH_ID, ModuleType.kRev); // Enables power distribution logging - } else { - setUseTiming(false); // Run as fast as possible - String logPath = LogFileUtil.findReplayLog(); // Pull the replay log from AdvantageScope (or prompt the user) - Logger.setReplaySource(new WPILOGReader(logPath)); // Read replay log - Logger.addDataReceiver(new WPILOGWriter(LogFileUtil.addPathSuffix(logPath, "_sim"))); // Save outputs to a new log + public Robot() { + CanBridge.runTCP(); + + switch (HardwareConstants.currentMode) { + case REAL: + Logger.addDataReceiver(new WPILOGWriter()); + Logger.addDataReceiver(new NT4Publisher()); + new PowerDistribution(CAN.PDH_ID, ModuleType.kRev); + break; + + case SIM: + System.out.println("SIM!!!"); + Logger.addDataReceiver(new NT4Publisher()); + break; + + case REPLAY: + setUseTiming(false); // Run as fast as possible + String logPath = LogFileUtil.findReplayLog(); + Logger.setReplaySource(new WPILOGReader(logPath)); // Read replay log + Logger.addDataReceiver(new WPILOGWriter(LogFileUtil.addPathSuffix(logPath, "_sim"))); // Save outputs to a new + // log + break; } + Logger.recordMetadata("ProjectName", "ReefCode"); // Set a metadata value + Logger.start(); // Start logging! No more data receivers, replay sources, or metadata values may // be added. - - m_robotContainer = new RobotContainer(); + + // Log active commands + Map commandCounts = new HashMap<>(); + BiConsumer logCommandFunction = (Command command, Boolean active) -> { + String name = command.getName(); + int count = commandCounts.getOrDefault(name, 0) + (active ? 1 : -1); + commandCounts.put(name, count); + Logger.recordOutput( + "CommandsUnique/" + name + "_" + Integer.toHexString(command.hashCode()), active); + Logger.recordOutput("CommandsAll/" + name, count > 0); + }; + CommandScheduler.getInstance() + .onCommandInitialize( + (Command command) -> { + logCommandFunction.accept(command, true); + }); + CommandScheduler.getInstance() + .onCommandFinish( + (Command command) -> { + logCommandFunction.accept(command, false); + }); + CommandScheduler.getInstance() + .onCommandInterrupt( + (Command command) -> { + logCommandFunction.accept(command, false); + }); } @Override @@ -50,10 +116,57 @@ public void robotPeriodic() { @Override public void disabledInit() { m_robotContainer.startIdleAnimations(); + SmartDashboard.putData("Auto Trajectory", m_autoTraj); } @Override public void disabledPeriodic() { + var m_alliance = DriverStation.getAlliance().isPresent() + && DriverStation.getAlliance().get() == Alliance.Red; + // Get currently selected command + + m_autonomousCommand = m_robotContainer.getAutonomousCommand(); + // Check if is the same as the last one + if (m_autonomousCommand != m_lastAutonomousCommand && m_autonomousCommand != null) { + // Check if its contained in the list of our autos + if (AutoBuilder.getAllAutoNames().contains(m_autonomousCommand.getName())) { + // Clear the current path + m_pathsToShow.clear(); + // Grabs all paths from the auto + try { + for (PathPlannerPath path : PathPlannerAuto + .getPathGroupFromAutoFile(m_autonomousCommand.getName())) { + // Adds all poses to master list + m_pathsToShow.addAll(path.getPathPoses()); + } + } catch (IOException | ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + // Check to see which alliance we are on Red Alliance + if (m_alliance) { + for (int i = 0; i < m_pathsToShow.size(); i++) { + m_pathsToShow.set(i, + m_pathsToShow.get(i).rotateAround(fieldCenter, Rotation2d.k180deg)); + } + } + // Displays all poses on Field2d widget + m_autoTraj.getObject("traj").setPoses(m_pathsToShow); + } + } + m_lastAutonomousCommand = m_autonomousCommand; + + if (!m_pathsToShow.isEmpty()) { + var firstPose = m_pathsToShow.get(0); + Logger.recordOutput("Alignment/StartPose", firstPose); + SmartDashboard.putBoolean("Alignment/Translation", + firstPose.getTranslation().getDistance( + m_robotContainer.getDrive().getPose().getTranslation()) <= Units + .inchesToMeters(1.5)); + SmartDashboard.putBoolean("Alignment/Rotation", + firstPose.getRotation().minus(m_robotContainer.getDrive().getPose().getRotation()) + .getDegrees() < 1); + } } @Override @@ -63,13 +176,16 @@ public void disabledExit() { @Override public void autonomousInit() { m_autonomousCommand = m_robotContainer.getAutonomousCommand(); + System.out.println(m_autonomousCommand); if (m_autonomousCommand != null) { m_autonomousCommand.schedule(); } - m_robotContainer.calibrateAndStartPIDs(); + m_robotContainer.calibrate(); m_robotContainer.startEnabledLEDs(); + + ranAutonomous = true; } @Override @@ -85,7 +201,8 @@ public void teleopInit() { if (m_autonomousCommand != null) { m_autonomousCommand.cancel(); } - m_robotContainer.calibrateAndStartPIDs(); + if (!ranAutonomous) + m_robotContainer.calibrate(); m_robotContainer.startEnabledLEDs(); } diff --git a/src/main/java/frc/robot/RobotContainer.java b/src/main/java/frc/robot/RobotContainer.java index c6cf064..1ec6761 100644 --- a/src/main/java/frc/robot/RobotContainer.java +++ b/src/main/java/frc/robot/RobotContainer.java @@ -6,28 +6,43 @@ import static edu.wpi.first.units.Units.*; +import java.io.IOException; +import java.lang.invoke.VarHandle.AccessMode; +import java.util.function.Supplier; + +import org.json.simple.parser.ParseException; +import org.littletonrobotics.junction.networktables.LoggedDashboardChooser; + +import com.ctre.phoenix6.swerve.SwerveModule.DriveRequestType; +import com.pathplanner.lib.auto.AutoBuilder; import com.pathplanner.lib.auto.NamedCommands; +import com.pathplanner.lib.util.FileVersionException; import com.ctre.phoenix6.swerve.SwerveRequest; +import edu.wpi.first.math.geometry.Pose2d; +import edu.wpi.first.math.geometry.Rotation2d; +import edu.wpi.first.wpilibj.DriverStation; import edu.wpi.first.wpilibj.GenericHID; +import edu.wpi.first.wpilibj.smartdashboard.SendableChooser; import edu.wpi.first.wpilibj2.command.Command; import edu.wpi.first.wpilibj2.command.CommandScheduler; import edu.wpi.first.wpilibj2.command.Commands; +import edu.wpi.first.wpilibj2.command.PrintCommand; import edu.wpi.first.wpilibj2.command.button.CommandXboxController; import edu.wpi.first.wpilibj2.command.button.JoystickButton; +import edu.wpi.first.wpilibj2.command.button.Trigger; import edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine.Direction; import frc.robot.subsystems.arm.Arm; import frc.robot.subsystems.arm.ArmCommands; import frc.robot.subsystems.arm.Arm.ArmPosition; -import frc.robot.subsystems.climber.Climber; -import frc.robot.subsystems.climber.ClimberCommands; -import frc.robot.subsystems.climber.RealClimberIO; -import frc.robot.subsystems.arm.RealArmIO; +import frc.robot.subsystems.arm.io.RealArmIO; +// import frc.robot.subsystems.climber.Climber; +// import frc.robot.subsystems.climber.ClimberCommands; +import frc.robot.subsystems.climber.io.RealClimberIO; import frc.robot.subsystems.drive.Drive; import frc.robot.subsystems.drive.DriveCommands; import frc.robot.subsystems.drive.Telemetry; import frc.robot.subsystems.drive.TunerConstants; -import frc.robot.subsystems.elevator.CmdElevatorCalibrate; import frc.robot.subsystems.drive.io.GyroIO; import frc.robot.subsystems.drive.io.GyroIOPigeon2; import frc.robot.subsystems.drive.io.ModuleIO; @@ -35,13 +50,21 @@ import frc.robot.subsystems.drive.io.ModuleIOTalonFX; import frc.robot.subsystems.elevator.Elevator; import frc.robot.subsystems.elevator.ElevatorCommands; -import frc.robot.subsystems.elevator.RealElevatorIO; +import frc.robot.subsystems.elevator.Elevator.ElevatorPosition; +import frc.robot.subsystems.elevator.io.RealElevatorIO; import frc.robot.subsystems.leds.LEDs; import frc.robot.subsystems.leds.LEDsCommands; -import frc.robot.subsystems.elevator.Elevator.ElevatorPosition; import frc.robot.subsystems.multisubsystemcommands.MultiSubsystemCommands; +import frc.robot.subsystems.multisubsystemcommands.MultiSubsystemCommands.GamepieceMode; import frc.robot.subsystems.multisubsystemcommands.MultiSubsystemCommands.OverallPosition; -import frc.robot.subsystems.presets.Preset; +import frc.robot.subsystems.vision.Vision; +import frc.robot.subsystems.vision.VisionIO; +import frc.robot.subsystems.vision.VisionIOPhotonVision; +import frc.robot.subsystems.vision.VisionIOPhotonVisionSim; +import edu.wpi.first.wpilibj2.command.Command; +import frc.robot.FieldConstants.ReefSide; + +import static frc.robot.subsystems.vision.VisionConstants.*; public class RobotContainer { private final Drive drive; @@ -52,21 +75,20 @@ public class RobotContainer { private final ArmCommands armCommands = new ArmCommands(armSubsystem); private final LEDsCommands LEDCommands = new LEDsCommands(LEDSubsystem); - private final Climber climber = new Climber(new RealClimberIO()); - private final ClimberCommands ClimberCommands = new ClimberCommands(climber); + // private final Climber climber = new Climber(new RealClimberIO()); + // private final ClimberCommands ClimberCommands = new ClimberCommands(climber); private final MultiSubsystemCommands multiSubsystemCommands = new MultiSubsystemCommands(elevatorSubsystem, armSubsystem, elevatorCommands, armCommands); - /** I am single :( - * hi zoe :3 - */ - private final Preset preset = new Preset(); + private final Vision vision; + private final CommandXboxController joystick = new CommandXboxController(0); + private final CommandXboxController climberstick = new CommandXboxController(3); private double MaxSpeed = TunerConstants.kSpeedAt12Volts.in(MetersPerSecond); // kSpeedAt12Volts desired top speed - private double MaxAngularRate = RotationsPerSecond.of(0.75).in(RadiansPerSecond); // 3/4 of a rotation per second max + private double MaxAngularRate = RotationsPerSecond.of(0.5).in(RadiansPerSecond); // 1/2 of a rotation per second max // angular velocity - + /* Setting up bindings for necessary control of the swerve drive platform */ // private final SwerveRequest.FieldCentric drive = new SwerveRequest.FieldCentric() // .withDeadband(MaxSpeed * 0.1).withRotationalDeadband(MaxAngularRate * 0.1) // Add a 10% deadband @@ -74,27 +96,36 @@ public class RobotContainer { private final SwerveRequest.SwerveDriveBrake brake = new SwerveRequest.SwerveDriveBrake(); private final SwerveRequest.PointWheelsAt point = new SwerveRequest.PointWheelsAt(); - private final CommandXboxController joystick = new CommandXboxController(0); - private final CommandXboxController climberstick = new CommandXboxController(1); - private final GenericHID buttonbox1 = new GenericHID(1); - private final JoystickButton L1Button = new JoystickButton(buttonbox1, 1); - private final JoystickButton L2Button = new JoystickButton(buttonbox1, 2); - private final JoystickButton StowButton = new JoystickButton(buttonbox1, 3); - private final JoystickButton L3Button = new JoystickButton(buttonbox1, 4); - private final JoystickButton L4Button = new JoystickButton(buttonbox1, 5); - private final JoystickButton LoadingButton = new JoystickButton(buttonbox1, 6); + private final GenericHID buttonbox2 = new GenericHID(2); + + private final JoystickButton StowButton = new JoystickButton(buttonbox2, 5); + private final JoystickButton L1Button = new JoystickButton(buttonbox2, 2); + private final JoystickButton L2Button = new JoystickButton(buttonbox1, 8); + private final JoystickButton L3Button = new JoystickButton(buttonbox1,5); + private final JoystickButton L4Button = new JoystickButton(buttonbox1, 1); + private final JoystickButton intakeButton = new JoystickButton(buttonbox1, 7); - private final JoystickButton L4_scoreButton = new JoystickButton(buttonbox1, 8); private final JoystickButton spitButton = new JoystickButton(buttonbox1, 9); + + private final JoystickButton gamepieceModeToggle = new JoystickButton(buttonbox1, 10); - private final GenericHID buttonbox2 = new GenericHID(2); - private final JoystickButton presetButton = new JoystickButton(buttonbox2, 2); - private final JoystickButton incrementButton = new JoystickButton(buttonbox2, 4); - private final JoystickButton decrementButton = new JoystickButton(buttonbox2, 7); + private final JoystickButton manualIntakeButton = new JoystickButton(buttonbox2, 1); + + private final JoystickButton incrementElevatorButton = new JoystickButton(buttonbox2, 4); + private final JoystickButton decrementElevatorButton = new JoystickButton(buttonbox2, 7); + + private final JoystickButton recalibrateButton = new JoystickButton(buttonbox2, 3); + + private final JoystickButton dynamic = new JoystickButton(buttonbox2, 8); + private final JoystickButton qstatic = new JoystickButton(buttonbox2, 9); + + private final LoggedDashboardChooser autoChooser; // public final CommandSwerveDrivetrain drivetrain = TunerConstants.createDrivetrain(); + private double speedMultiplier = 0.9; + private final Telemetry logger = new Telemetry(MaxSpeed); public RobotContainer() { @@ -110,12 +141,11 @@ public RobotContainer() { new ModuleIOTalonFX(TunerConstants.BackLeft), new ModuleIOTalonFX(TunerConstants.BackRight)); - // vision = - // new Vision( - // drive::addVisionMeasurement, - // new VisionIOPhotonVision(camera0Name, robotToCamera0), - // new VisionIOPhotonVision(camera1Name, robotToCamera1)); - + vision = + new Vision( + drive::addVisionMeasurement, + new VisionIOPhotonVision(camera5Name, robotToCamera5) + ); break; case SIM: @@ -128,11 +158,22 @@ public RobotContainer() { new ModuleIOSim(TunerConstants.BackLeft), new ModuleIOSim(TunerConstants.BackRight)); - // vision = - // new Vision( - // drive::addVisionMeasurement, - // new VisionIOPhotonVisionSim(camera0Name, robotToCamera0, drive::getPose), - // new VisionIOPhotonVisionSim(camera1Name, robotToCamera1, drive::getPose)); + /* We should be using this VisionIOPhotonVisionSim here but it's running too slow and + causing the a loop overrun. + vision = + new Vision( + drive::addVisionMeasurement, + new VisionIOPhotonVisionSim(camera7Name, robotToCamera7, drive::getPose), + new VisionIOPhotonVisionSim(camera8Name, robotToCamera8, drive::getPose) + ); */ + vision = + new Vision( + drive::addVisionMeasurement, + new VisionIO() {}, + new VisionIO() {}, + new VisionIO() {}, + new VisionIO() {}); + break; default: @@ -145,139 +186,183 @@ public RobotContainer() { new ModuleIO() {}, new ModuleIO() {}); - // vision = new Vision(drive::addVisionMeasurement, new VisionIO() {}, new VisionIO() {}); + vision = + new Vision( + drive::addVisionMeasurement, + new VisionIO() {}, + new VisionIO() {}, + new VisionIO() {}, + new VisionIO() {}); break; } - // All AutoAligns for reef will align to Left position //TODO: Add AutoAligns to all the commands. // AutoAlignToReef + ScoreL1 (Move to L1, score) NamedCommands.registerCommand("L1", - multiSubsystemCommands.scoreGamepieceAtPosition(OverallPosition.L1)); + multiSubsystemCommands.moveToPosition(OverallPosition.L1)); // AutoAlignToReef + ScoreL2 (Move to L2, score) NamedCommands.registerCommand("L2", - multiSubsystemCommands.scoreGamepieceAtPosition(OverallPosition.L2)); + multiSubsystemCommands.moveToPosition(OverallPosition.L2)); // AutoAlignToReef + ScoreL3 (Move to L3, score) NamedCommands.registerCommand("L3", - multiSubsystemCommands.scoreGamepieceAtPosition(OverallPosition.L3)); + multiSubsystemCommands.moveToPosition(OverallPosition.L3)); // AutoAlignToReef + Move to L4 + Score NamedCommands.registerCommand("L4", - multiSubsystemCommands.scoreGamepieceAtPosition(OverallPosition.L4)); + multiSubsystemCommands.moveToPosition(OverallPosition.L4)); // AutoAlign to Intake + Intake NamedCommands.registerCommand("Intake", - multiSubsystemCommands.loadGamepiece()); + multiSubsystemCommands.loadCoralAuto()); + + // AutoAlign + Algae Removal + NamedCommands.registerCommand("AlgaeL2", + multiSubsystemCommands.loadAlgae(OverallPosition.Algae_Loading_L2)); + + // AutoAlign + Algae Removal + NamedCommands.registerCommand("AlgaeL3", + multiSubsystemCommands.loadAlgae(OverallPosition.Algae_Loading_L3)); + + // Moves the gamepiece back + NamedCommands.registerCommand("MovePiece", + armCommands.moveGamepieceToLightSensor()); + + NamedCommands.registerCommand("Stow", + multiSubsystemCommands.moveToPosition(OverallPosition.Stow)); + + NamedCommands.registerCommand("Score", + armCommands.spit()); + + autoChooser = new LoggedDashboardChooser<>("Auto Choices", AutoBuilder.buildAutoChooser()); + // hide the joystick missing warnings + DriverStation.silenceJoystickConnectionWarning(true); configureBindings(); } + private Command joystickApproach(Supplier approachPose) + { + return DriveCommands.joystickApproach( + drive, + () -> -joystick.getLeftY() * speedMultiplier, + approachPose).alongWith(LEDCommands.aligningWithReef(() -> drive.getCloseToReef())) + .withName("AutoAlign"); + } + private void configureBindings() { // Note that X is defined as forward according to WPILib convention, // and Y is defined as to the left according to WPILib convention. + drive.setDefaultCommand( DriveCommands.joystickDrive( drive, () -> -joystick.getLeftY(), () -> -joystick.getLeftX(), - () -> -joystick.getRightX())); - - climber.setDefaultCommand( - ClimberCommands.runClimber( - () -> -climberstick.getLeftY())); + () -> -joystick.getRightX())); - - // drivetrain.setDefaultCommand( - // // Drivetrain will execute this command periodically - // drivetrain.applyRequest(() -> drive.withVelocityX(-joystick.getLeftY() * MaxSpeed) // Drive forward with - // // negative Y (forward) - // .withVelocityY(-joystick.getLeftX() * MaxSpeed) // Drive left with negative X (left) - // .withRotationalRate(-joystick.getRightX() * MaxAngularRate) // Drive counterclockwise with negative X (left) - // )); - - // joystick.a().whileTrue(drivetrain.applyRequest(() -> brake)); - // joystick.b().whileTrue(drivetrain - // .applyRequest(() -> point.withModuleDirection(new Rotation2d(-joystick.getLeftY(), -joystick.getLeftX())))); - // Run SysId routines when holding back/start and X/Y. - // Note that each routine should be run exactly once in a single log. - joystick.back().and(joystick.y()).whileTrue(drive.sysIdDynamic(Direction.kForward)); - joystick.back().and(joystick.x()).whileTrue(drive.sysIdDynamic(Direction.kReverse)); - joystick.start().and(joystick.y()).whileTrue(drive.sysIdQuasistatic(Direction.kForward)); - joystick.start().and(joystick.x()).whileTrue(drive.sysIdQuasistatic(Direction.kReverse)); + //climberstick.start().and(climberstick.y()).onTrue(getAutonomousCommand()); - //climberstick.start().and(climberstick.y()).onTrue(getAutonomousCommand()) + // climber.setDefaultCommand( + // ClimberCommands.runClimber( + // () -> climberstick.getLeftY())); // reset the field-centric heading on left bumper press // joystick.leftBumper().onTrue(drive.runOnce(() -> drive.seedFieldCentric())); // drive.registerTelemetry(logger::telemeterize); - intakeButton.onTrue(multiSubsystemCommands.loadGamepiece().raceWith(LEDCommands.intaking()).andThen(LEDCommands.hasPiece()).andThen(LEDCommands.elevatorOrArmIsMoving())); - spitButton.onTrue(armCommands.spit()); - - L1Button.onTrue(multiSubsystemCommands.setOverallSetpoint(OverallPosition.L1)); - L2Button.onTrue(multiSubsystemCommands.setOverallSetpoint(OverallPosition.L2)); - StowButton.onTrue(multiSubsystemCommands.setOverallSetpoint(OverallPosition.Stow)); - L3Button.onTrue(multiSubsystemCommands.setOverallSetpoint(OverallPosition.L3)); - L4Button.onTrue(multiSubsystemCommands.setOverallSetpoint(OverallPosition.L4)); - LoadingButton.onTrue(multiSubsystemCommands.setOverallSetpoint(OverallPosition.Loading)); - L4_scoreButton.onTrue(multiSubsystemCommands.setOverallSetpoint(OverallPosition.L4_Score)); - - // Runs the preset to score unless the preset is invalid. - joystick.rightBumper().onTrue( - multiSubsystemCommands.scoreGamepieceAtPosition(() -> preset.getLevel()).unless(() - -> !preset.isPresetValid())); - - // Resets the preset when we don't have a piece. - armSubsystem._hasPiece.onFalse(preset.resetPreset().andThen(LEDCommands.pickingUpCoral())); - - // Sets the level preset - presetButton.and(L1Button).onTrue(preset.setPresetLevelCommand(OverallPosition.L1)); - presetButton.and(L2Button).onTrue(preset.setPresetLevelCommand(OverallPosition.L2)); - presetButton.and(L3Button).onTrue(preset.setPresetLevelCommand(OverallPosition.L3)); - presetButton.and(L4Button).onTrue(preset.setPresetLevelCommand(OverallPosition.L4)); - - incrementButton.onTrue(elevatorCommands.incrementElevatorPosition()); - decrementButton.onTrue(elevatorCommands.decrementElevatorPosition()); + intakeButton.onTrue(multiSubsystemCommands.loadCoral().raceWith(LEDCommands.intaking()).andThen(LEDCommands.hasPiece()).andThen(LEDCommands.elevatorOrArmIsMoving()).unless(() -> armSubsystem.getCurrentMode() == GamepieceMode.ALGAE)); + spitButton.onTrue(armCommands.spit().andThen(Commands.either(LEDCommands.pickingUpAlgae(), LEDCommands.pickingUpCoral(), () -> armSubsystem.getCurrentMode() == GamepieceMode.ALGAE))); + + StowButton.onTrue(multiSubsystemCommands.moveToPosition(OverallPosition.Stow)); + L1Button.onTrue(multiSubsystemCommands.moveToPosition(OverallPosition.L1)); + L2Button.onTrue(Commands.either(multiSubsystemCommands.loadAlgae(OverallPosition.Algae_Loading_L2), multiSubsystemCommands.moveToPosition(OverallPosition.L2), () -> armSubsystem.getCurrentMode() == GamepieceMode.ALGAE)); + L3Button.onTrue(Commands.either(multiSubsystemCommands.loadAlgae(OverallPosition.Algae_Loading_L3), multiSubsystemCommands.moveToPosition(OverallPosition.L3), () -> armSubsystem.getCurrentMode() == GamepieceMode.ALGAE)); + L4Button.onTrue(multiSubsystemCommands.moveToPosition(OverallPosition.L4)); + + gamepieceModeToggle.whileTrue(multiSubsystemCommands.setGamepieceMode(GamepieceMode.ALGAE).alongWith(LEDCommands.pickingUpAlgae())); + gamepieceModeToggle.whileFalse(multiSubsystemCommands.setGamepieceMode(GamepieceMode.CORAL).alongWith(LEDCommands.pickingUpCoral())); + + // Run SysId routines when holding back/start and X/Y. + // Note that each routine should be run exactly once in a single log. + // dynamic.and(joystick.y()).whileTrue(drive.sysIdDynamic(Direction.kForward)); + // dynamic.and(joystick.x()).whileTrue(drive.sysIdDynamic(Direction.kReverse)); + // qstatic.and(joystick.y()).whileTrue(drive.sysIdQuasistatic(Direction.kForward)); + // qstatic.and(joystick.x()).whileTrue(drive.sysIdQuasistatic(Direction.kReverse)); + + // Driver Right Bumper: Approach Nearest Right-Side Reef Branch + joystick.rightBumper() + .whileTrue( + joystickApproach( + () -> FieldConstants.getNearestReefBranch(drive.getPose(), ReefSide.RIGHT))); + + + // Driver Left Bumper: Approach Nearest Left-Side Reef Branch + joystick.leftBumper() + .whileTrue( + joystickApproach( + () -> FieldConstants.getNearestReefBranch(drive.getPose(), ReefSide.LEFT))); + + // a -button approach reef + joystick.a() + .whileTrue( + joystickApproach( + () -> FieldConstants.getNearestReefFace(drive.getPose()))); + + // Set up robot for climb + climberstick.x() + .onTrue( + armCommands.moveArm(ArmPosition.Climbing) + .andThen(elevatorCommands.moveElevator(ElevatorPosition.Stow))); + + manualIntakeButton.whileTrue(armCommands.manualIntake()); + + incrementElevatorButton.onTrue(elevatorCommands.incrementElevatorPosition()); + decrementElevatorButton.onTrue(elevatorCommands.decrementElevatorPosition()); + + recalibrateButton.onTrue(multiSubsystemCommands.calibrate()); + /* + // Driver Left Bumper and Algae mode: Approach Nearest Reef Face + joystick.rightBumper() + .whileTrue( + joystickApproach(() -> FieldConstants.getNearestReefFace(drive.getPose()))); + + */ + + // Reset gyro to 0° when Y button is pressed + joystick.y() + .onTrue( + Commands.runOnce( + () -> + drive.setPose( + new Pose2d(drive.getPose().getTranslation(), new Rotation2d())), + drive) + .ignoringDisable(true)); + + // // reset the field-centric heading on left bumper press + // joystick.leftBumper().onTrue(drive.runOnce(() -> drive.seedFieldCentric())); + joystick.leftTrigger(0.75).onTrue(armCommands.spit()); } public Command getAutonomousCommand() { - return Commands.print("No autonomous command configured"); + return autoChooser.get(); } - public void calibrateAndStartPIDs() { - // PID commands: we only want one of them so start/stop works correctly - Command elevatorPIDCommand = elevatorCommands.runElevatorPID(); - Command armPIDCommand = armCommands.runArmPID(); - // Start elevator pid - if (elevatorSubsystem.isCalibrated()) { - elevatorCommands.runElevatorPID(); - if (!CommandScheduler.getInstance().isScheduled(elevatorPIDCommand)) { - CommandScheduler.getInstance().schedule(elevatorPIDCommand); - } - } else { - Command calibCommand = new CmdElevatorCalibrate(elevatorSubsystem).andThen(elevatorPIDCommand); - CommandScheduler.getInstance().schedule(calibCommand); - } - - // Start arm pid - if (!CommandScheduler.getInstance().isScheduled(armPIDCommand)) { - CommandScheduler.getInstance().schedule(armPIDCommand); - } - - // Set initial positions - CommandScheduler.getInstance().schedule(elevatorCommands.setElevatorSetpoint(ElevatorPosition.Stow)); - CommandScheduler.getInstance().schedule(armCommands.setArmPosition(ArmPosition.Stow)); + public Drive getDrive() { + return drive; + } + public void calibrate() { + CommandScheduler.getInstance().schedule(multiSubsystemCommands.calibrate()); } public void startIdleAnimations() { - Command disabled1 = LEDCommands.disabledAnimation1(); + Command disabled1 = ((LEDCommands.disabledAnimation1().withTimeout(20)).andThen(LEDCommands.disabledAnimation2().withTimeout(20)).repeatedly()); if (!CommandScheduler.getInstance().isScheduled(disabled1)) CommandScheduler.getInstance().schedule(disabled1); } @@ -287,4 +372,5 @@ public void startEnabledLEDs() { if (!CommandScheduler.getInstance().isScheduled(initialLEDs)) CommandScheduler.getInstance().schedule(initialLEDs); } + } diff --git a/src/main/java/frc/robot/subsystems/arm/Arm.java b/src/main/java/frc/robot/subsystems/arm/Arm.java index 8f59c7e..e2ec2a3 100644 --- a/src/main/java/frc/robot/subsystems/arm/Arm.java +++ b/src/main/java/frc/robot/subsystems/arm/Arm.java @@ -18,22 +18,29 @@ import edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine; import edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine.Config; import edu.wpi.first.wpilibj2.command.button.Trigger; +import frc.robot.subsystems.arm.io.ArmIO; +import frc.robot.subsystems.arm.io.ArmIOInputsAutoLogged; import frc.robot.subsystems.multisubsystemcommands.MultiSubsystemCommands; import frc.robot.subsystems.multisubsystemcommands.MultiSubsystemCommands.GamepieceMode; public class Arm extends SubsystemBase { public enum ArmPosition { - Stow(80), - Loading_Coral(120), - Loading_Algae(50), - Loading(120), - L4_Score(45), - Algae_Score(60); - - double angle; + Stow(114, 114), + Loading(140, 78), + L4_Score(97, 102), // 86 + Algae_Score(100, 100), + Transient(108, 108), + Climbing(50, 50); + + double coralAngle, algaeAngle; + + ArmPosition(double coralAngle, double algaeAngle) { + this.coralAngle = coralAngle; + this.algaeAngle = algaeAngle; + } - ArmPosition(double angle) { - this.angle = angle; + double getAngle(GamepieceMode mode) { + return (mode == GamepieceMode.ALGAE) ? this.algaeAngle : this.coralAngle; } } @@ -43,6 +50,7 @@ public enum ArmPosition { private ArmIOInputsAutoLogged _inputs; private boolean _prevLightSensorVal; private boolean _hasGamepiece; + private boolean _atSetpoint; private int _intakeSpikeCounter; private ArmPosition _currentPos; private ArmPosition _desiredPos; @@ -50,22 +58,16 @@ public enum ArmPosition { private ProfiledPIDController _armPidController; - private static final double KP = 0.09; - private static final double KI = 0.01; - private static final double KD = 0; - private static final double PROFILE_VEL = 160; - private static final double PROFILE_ACC = 145; + private static final double KP = 0.1;//0.09; + private static final double KI = 0.00; //0.01; + private static final double KD = 0.01; + private static final double PROFILE_VEL = 330; + private static final double PROFILE_ACC = 300; - private static final double HAS_ALGAE_CURRENT = 2; + public static final double HAS_ALGAE_CURRENT = 40; - private static final double ARM_WEIGHT_N = 3.5 * 9.81; - private static final double ARM_STALL_TORQUE_NM = 3.6; - private static final double ARM_STALL_CURRENT = 211; - private static final double ARM_KT = ARM_STALL_TORQUE_NM / ARM_STALL_CURRENT; - private static final double ARM_RESISTANCE = 0.057; - private static final double ARM_MOMENT_METERS = 0.3928; - private static final double ARM_GEARING = 17; - private static final double ARM_FEEDFORWARD_COEFF = 0.53; + private static final double ARM_FEEDFORWARD_COEFF = 0.6; + private static final double ARM_FEEDFORWARD_ANGLE_OFFSET = -22.3; SysIdRoutine routine = new SysIdRoutine(new Config(), new SysIdRoutine.Mechanism(this::setArmVoltage, this::populateLog, this)); @@ -74,75 +76,93 @@ public Arm(ArmIO io) { _io = io; _inputs = new ArmIOInputsAutoLogged(); + _currentMode = GamepieceMode.CORAL; + _armPidController = new ProfiledPIDController(KP, KI, KD, new Constraints(PROFILE_VEL, PROFILE_ACC)); - _armPidController.setTolerance(7); + _armPidController.setTolerance(5); + setArmSetpoint(ArmPosition.Stow); } public void setArmSetpoint(ArmPosition setpoint) { - if (setpoint == ArmPosition.Loading) - setpoint = (_currentMode == GamepieceMode.ALGAE) ? ArmPosition.Loading_Algae : ArmPosition.Loading_Coral; - _armPidController.reset(_inputs._armEncoderPositionDegrees); - _armPidController.setGoal(setpoint.angle); + _armPidController.setGoal(setpoint.getAngle(_currentMode)); _desiredPos = setpoint; + _atSetpoint = false; } public void setIntakeSpeed(double speed) { + if (_currentMode == GamepieceMode.ALGAE) speed *= -1; _io.setIntakeMotorSpeed(speed); } - public void setFeederSpeed(double speed) { - _io.setFeederMotorSpeed(speed); - } - public void spit() { - setIntakeSpeed(0.5); + double speed = (_currentMode == GamepieceMode.ALGAE) ? -0.5 : 0.35; + setIntakeSpeed(speed); } public void clearHasGamepiece() { _hasGamepiece = false; } + public void setHasGamepiece() { + _hasGamepiece = true; + } + + public void clearIntakeSpikeCounter() { + _intakeSpikeCounter = 0; + } + + public double getIntakeSpikeCounter() { + return _intakeSpikeCounter; + } + public void setArmVoltage(Voltage voltage) { _io.setArmMotorVoltage(voltage); } + public double getIntakeCurrent() { + return _inputs._intakeMotorCurrent; + } + public void resetIntakeEncoders() { _io.resetIntakeEncoders(); } public boolean intakeAtDesiredRotations() { - return _inputs._intakeMotorPositionRotations <= -2; + return _inputs._intakeMotorPositionRotations <= -1; } public boolean hasPiece() { - boolean hasPiece; + boolean hasPiece = false; + // boolean _hasGamepiece = false; if (_currentMode == GamepieceMode.CORAL) { - boolean currentState = _inputs._lightSensorState; - hasPiece = _prevLightSensorVal && !currentState; + boolean currentState = _inputs._upperLightSensorState; + hasPiece = (_prevLightSensorVal && !currentState) && _inputs._lowerLightSensorState; + //hasPiece = currentState; _prevLightSensorVal = currentState; } else { - if (_inputs._intakeMotorCurrent >= HAS_ALGAE_CURRENT) { - _intakeSpikeCounter++; - } - hasPiece = _intakeSpikeCounter >= 5; + hasPiece = _inputs._algaeLightSensorState; } - return hasPiece; + if (hasPiece) _hasGamepiece = true; + + return _hasGamepiece; } - public void resetIntakeSpikeCounter() { - _intakeSpikeCounter = 0; + public boolean upperLightSensorSeesGamepiece() { + return _inputs._upperLightSensorState; } - public boolean lightSensorSeesGamepiece() { - return _inputs._lightSensorState; + public boolean lowerLightSensorSeesGamepiece() { + return _inputs._lowerLightSensorState; } - public boolean armAtSetpoint() { + public boolean isAtSetpoint() { boolean atSetpoint = _armPidController.atGoal(); - if (atSetpoint) + if (atSetpoint) { _currentPos = _desiredPos; + _atSetpoint = true; + } return atSetpoint; } @@ -150,9 +170,14 @@ public ArmPosition getCurrentPos() { return _currentPos; } + public void resetPID(){ + _armPidController.setGoal(ArmPosition.Stow.getAngle(_currentMode)); + _armPidController.reset(_inputs._armEncoderPositionDegrees); + } + public void runArmPID() { - double out = (_armPidController.calculate(_inputs._armEncoderPositionDegrees) - + ARM_FEEDFORWARD_COEFF * Math.cos(Units.degreesToRadians(_inputs._armEncoderPositionDegrees))); + double out = _armPidController.calculate(_inputs._armEncoderPositionDegrees) + + (ARM_FEEDFORWARD_COEFF * Math.cos(Units.degreesToRadians(_inputs._armEncoderPositionDegrees + ARM_FEEDFORWARD_ANGLE_OFFSET))); _io.setArmMotorVoltage(Voltage.ofBaseUnits(out, Volt)); } @@ -186,9 +211,13 @@ public void periodic() { Logger.processInputs("Arm", _inputs); Logger.recordOutput("Arm/desiredPos", _armPidController.getSetpoint().position); - Logger.recordOutput("Arm/hasPiece", hasPiece()); - Logger.recordOutput("Arm/atSetpoint", armAtSetpoint()); + Logger.recordOutput("Arm/hasPiece", _hasGamepiece); + Logger.recordOutput("Arm/atSetpoint", isAtSetpoint()); Logger.recordOutput("Arm/currentPosEnum", _currentPos); Logger.recordOutput("Arm/desiredPosEnum", _desiredPos); + Logger.recordOutput("Arm/intakeSpikeCounter", _intakeSpikeCounter); + + // Run pid + runArmPID(); } } diff --git a/src/main/java/frc/robot/subsystems/arm/ArmCommands.java b/src/main/java/frc/robot/subsystems/arm/ArmCommands.java index 9dd4363..8f327c4 100644 --- a/src/main/java/frc/robot/subsystems/arm/ArmCommands.java +++ b/src/main/java/frc/robot/subsystems/arm/ArmCommands.java @@ -1,10 +1,17 @@ package frc.robot.subsystems.arm; +import org.littletonrobotics.junction.Logger; + +import edu.wpi.first.wpilibj.RobotState; import edu.wpi.first.wpilibj2.command.Command; +import edu.wpi.first.wpilibj2.command.CommandScheduler; import edu.wpi.first.wpilibj2.command.Commands; +import edu.wpi.first.wpilibj2.command.FunctionalCommand; import edu.wpi.first.wpilibj2.command.InstantCommand; import frc.robot.subsystems.arm.Arm.ArmPosition; +import frc.robot.subsystems.multisubsystemcommands.MultiSubsystemCommands.GamepieceMode; import edu.wpi.first.wpilibj2.command.StartEndCommand; +import edu.wpi.first.wpilibj2.command.WaitCommand; import edu.wpi.first.wpilibj2.command.WaitUntilCommand; public class ArmCommands { @@ -17,76 +24,224 @@ public ArmCommands(Arm arm) { public Command spit() { return new StartEndCommand( () -> { - if (_arm.getCurrentPos() == ArmPosition.L4_Score) - _arm.setArmSetpoint(ArmPosition.Stow); _arm.spit(); }, () -> { _arm.setIntakeSpeed(0); _arm.clearHasGamepiece(); - }, - _arm).withTimeout(0.5); + }, _arm).withTimeout(0.5) + .andThen(Commands.runOnce(() -> _arm.setArmSetpoint(ArmPosition.Stow), _arm) + .unless(() -> _arm.getCurrentPos() != ArmPosition.L4_Score)) + .withName("Spit"); } public Command setArmPosition(ArmPosition setpoint) { if (setpoint == ArmPosition.L4_Score) { return new InstantCommand( - () -> { - _arm.setArmSetpoint(setpoint); - }, - _arm).andThen(intakeForNumberOfRotations()); + () -> { + _arm.setArmSetpoint(setpoint); + });//.andThen(intakeForNumberOfRotations()); } return new InstantCommand( () -> { _arm.setArmSetpoint(setpoint); - }, - _arm); + }); } public Command intake() { + return Commands.either(intakeAlgae(), intakeCoralWithAdjust(), + () -> _arm.getCurrentMode() == GamepieceMode.ALGAE); + } + + private Command intakeCoralWithAdjust() { + return intakeCoral().andThen(moveArm(ArmPosition.Stow)); + } + + private Command intakeCoral() { + Command c = new Command() { + /* + * This command will run the intake at a fast speed until the lower light sensor + * detects the coral + * Then, the speed will decrease and run until both sensors detect the coral + * Then, the motor will turn off for a few cycles (~100 ms) + * Then, the motor will run at a slow speed in reverse until the upper light + * sensor detects the coral + * Then, the arm will go back to stow + * + * In the case that the lower and upper light sensors don't detect a piece when + * running reverse, + * we assume there is no piece and start running at a fast speed again + */ + boolean hasPieceDetected = false; + boolean prevHasPieceDetected = false; + boolean waiting = false; + boolean done = false; + + int counter = 0; + + @Override + public void initialize() { + // Init flags + hasPieceDetected = false; + waiting = false; + done = false; + + counter = 0; + } + + @Override + public void execute() { + // We don't think we have a piece, so try to intake it + if (!hasPieceDetected) { + if (_arm.upperLightSensorSeesGamepiece()) { + _arm.setIntakeSpeed(0.09); + } else { + _arm.setIntakeSpeed(0.22); // 0.35 + } + + // Update hasPiece + hasPieceDetected = _arm.hasPiece(); + } else { + // Check if we actually see the gamepiece on our lower sensor after waiting + if (!_arm.lowerLightSensorSeesGamepiece()) { + counter++; + } + + if (counter > 15) { + // Assume that at this point we don't have a piece + // Clear out hasPiece so normal intaking will start again + _arm.clearHasGamepiece(); + hasPieceDetected = false; + counter = 0; + } else { + // Run the motors backwards until we see the piece in the upper light sensor + _arm.setIntakeSpeed(-0.09); // changed to -0.11 to prevent dropping piece while moving, seemed + // to work well + done = _arm.upperLightSensorSeesGamepiece(); + } + } + } + + @Override + public void end(boolean interrupted) { + _arm.setIntakeSpeed(0); + } + + @Override + public boolean isFinished() { + return done; + } + }; + c.addRequirements(_arm); + return c; + } + + public Command intakeCoralAuto() { + return new Command() { + @Override + public void execute() { + if (_arm.upperLightSensorSeesGamepiece()) { + _arm.setIntakeSpeed(0.09); + } else { + _arm.setIntakeSpeed(0.22); // 0.35 + } + } + + @Override + public void end(boolean interrupted) { + _arm.setIntakeSpeed(0); + } + + @Override + public boolean isFinished() { + return _arm.hasPiece(); + } + }; + } + + private Command intakeAlgae() { + Command c = new Command() { + + @Override + public void initialize() { + this.addRequirements(_arm); + _arm.setIntakeSpeed(0.5); + } + + @Override + public void end(boolean interrupted) { + if (interrupted) { + _arm.setIntakeSpeed(0); + } else { + _arm.setIntakeSpeed(0.05); + } + } + + @Override + public boolean isFinished() { + return _arm.hasPiece(); + } + }; + c.addRequirements(_arm); + return c; + } + + public Command moveGamepieceToLightSensor() { + return new Command() { + + @Override + public void execute() { + double speed = -0.09; // -0.08 + _arm.setIntakeSpeed(speed); + } + + @Override + public void end(boolean interrupted) { + _arm.setIntakeSpeed(0); + } + + @Override + public boolean isFinished() { + return _arm.upperLightSensorSeesGamepiece(); + } + }; + } + + public Command intakeForNumberOfRotations() { return new StartEndCommand( () -> { - _arm.resetIntakeSpikeCounter(); - _arm.setIntakeSpeed(0.45); - _arm.setFeederSpeed(0.45); + _arm.resetIntakeEncoders(); + _arm.setIntakeSpeed(-0.175); // -0.1 }, () -> { _arm.setIntakeSpeed(0); - _arm.setFeederSpeed(0); - }, - _arm).until(() -> _arm.hasPiece()); + }, _arm).until(() -> _arm.intakeAtDesiredRotations()); } - public Command moveGamepieceToLightSensor() { - return new StartEndCommand( - () -> { - _arm.setIntakeSpeed(-0.3); - }, - () -> { - _arm.setIntakeSpeed(0); - }, - _arm).until(() -> _arm.lightSensorSeesGamepiece()); + public Command waitUntilAtSetpoint() { + return new WaitUntilCommand(_arm::isAtSetpoint); } - public Command runArmPID() { - return Commands.run(() -> { - _arm.runArmPID(); - }); + public Command moveArm(ArmPosition pos) { + return setArmPosition(pos).andThen(waitUntilAtSetpoint()); } - public Command intakeForNumberOfRotations() { - return new StartEndCommand(() -> { - _arm.resetIntakeEncoders(); - _arm.setIntakeSpeed(-0.3); - }, - () -> { - _arm.setIntakeSpeed(0); - }, - _arm).until(() -> _arm.intakeAtDesiredRotations()); + public Command resetArmPID() { + return Commands.runOnce(() -> _arm.resetPID()); } - public Command waitUntilAtSetpoint() { - return new WaitUntilCommand(_arm::armAtSetpoint); + public Command manualIntake() { + return Commands.either( + new StartEndCommand( + () -> _arm.setIntakeSpeed(-0.1), + () -> _arm.setIntakeSpeed(0), + _arm), + new StartEndCommand( + () -> _arm.setIntakeSpeed(0.5), + () -> _arm.setIntakeSpeed(0), + _arm), + () -> _arm.getCurrentMode() == GamepieceMode.CORAL) + .withName("ManualIntake"); } } diff --git a/src/main/java/frc/robot/subsystems/arm/RealArmIO.java b/src/main/java/frc/robot/subsystems/arm/RealArmIO.java deleted file mode 100644 index f5faa65..0000000 --- a/src/main/java/frc/robot/subsystems/arm/RealArmIO.java +++ /dev/null @@ -1,86 +0,0 @@ -package frc.robot.subsystems.arm; - -import com.revrobotics.spark.SparkAbsoluteEncoder; -import com.revrobotics.spark.SparkBase.PersistMode; -import com.revrobotics.spark.SparkBase.ResetMode; -import com.revrobotics.spark.SparkFlex; -import com.revrobotics.spark.config.SparkBaseConfig.IdleMode; -import com.revrobotics.spark.config.SparkFlexConfig; -import com.revrobotics.spark.SparkLowLevel.MotorType; -import com.revrobotics.spark.SparkMax; - -import edu.wpi.first.units.measure.Voltage; -import edu.wpi.first.wpilibj.DigitalInput; -import frc.robot.HardwareConstants.CAN; -import frc.robot.HardwareConstants.DIO; - -public class RealArmIO implements ArmIO { - - private static final double POS_AT_90 = 0.447; - private static final double POS_AT_0 = 0.701; - private static final double ENCODER_CONVERSION = (POS_AT_90 - POS_AT_0) / 90.0; - - private double INTAKE_ROTATION_CONVERSION = 1; - - private SparkFlex _armMotor; - private DigitalInput _lightSensor; - private SparkFlex _intakeMotor; - private SparkAbsoluteEncoder _armEncoder; - private SparkMax _feederMotor; - - public RealArmIO() { - _armMotor = new SparkFlex(CAN.ARM_MTR_ID, MotorType.kBrushless); - _intakeMotor = new SparkFlex(CAN.INTAKE_MTR_ID, MotorType.kBrushless); - _lightSensor = new DigitalInput(DIO.LIGHT_SENSOR_CHANNEL); - _armEncoder = _armMotor.getAbsoluteEncoder(); - - SparkFlexConfig armConfig = new SparkFlexConfig(); - armConfig.idleMode(IdleMode.kBrake); - armConfig.inverted(true); - armConfig.voltageCompensation(12); - _armMotor.configure(armConfig, ResetMode.kResetSafeParameters, PersistMode.kPersistParameters); - } - - public void updateInputs(ArmIOInputs inputs) { - inputs._armMotorSpeed = _armMotor.get(); - inputs._armMotorCurrent = _armMotor.getOutputCurrent(); - inputs._armMotorVoltage = _armMotor.getAppliedOutput() * _armMotor.getBusVoltage(); - - inputs._feederMotorSpeed = _feederMotor.get(); - inputs._feederMotorCurrent = _feederMotor.getOutputCurrent(); - inputs._feederMotorVoltage = _feederMotor.getAppliedOutput() * _feederMotor.getBusVoltage(); - - inputs._lightSensorState = !_lightSensor.get(); - inputs._intakeMotorVelocityRotationsPerMin = _intakeMotor.get(); - inputs._intakeMotorCurrent = _intakeMotor.getOutputCurrent(); - inputs._intakeMotorVoltage = _intakeMotor.getAppliedOutput() * _armMotor.getBusVoltage(); - inputs._intakeMotorPositionRotations = _intakeMotor.getEncoder().getPosition() * INTAKE_ROTATION_CONVERSION; - - inputs._armEncoderPositionDegrees = (_armEncoder.getPosition() - POS_AT_0) / ENCODER_CONVERSION; - inputs._armEncoderVelocity = _armEncoder.getVelocity(); - } - - public void setArmMotorSpeed(double speed) { - _armMotor.set(speed); - } - - public void setIntakeMotorSpeed(double speed) { - _intakeMotor.set(speed); - } - - public void setFeederMotorSpeed(double speed){ - _feederMotor.set(speed); - - } - public void resetIntakeEncoders() { - _intakeMotor.getEncoder().setPosition(0); - } - - public void setArmMotorVoltage(Voltage voltage) { - _armMotor.setVoltage(voltage); - } - - public void setFeederMotorVoltage(Voltage voltage) { - _feederMotor.setVoltage(voltage); - } -} diff --git a/src/main/java/frc/robot/subsystems/arm/ArmIO.java b/src/main/java/frc/robot/subsystems/arm/io/ArmIO.java similarity index 76% rename from src/main/java/frc/robot/subsystems/arm/ArmIO.java rename to src/main/java/frc/robot/subsystems/arm/io/ArmIO.java index 9f4ca5d..f21d2d4 100644 --- a/src/main/java/frc/robot/subsystems/arm/ArmIO.java +++ b/src/main/java/frc/robot/subsystems/arm/io/ArmIO.java @@ -1,4 +1,4 @@ -package frc.robot.subsystems.arm; +package frc.robot.subsystems.arm.io; import org.littletonrobotics.junction.AutoLog; @@ -11,10 +11,6 @@ public static class ArmIOInputs { public double _armMotorVoltage = 0.0; public double _armMotorSpeed = 0.0; - public double _feederMotorCurrent = 0.0; - public double _feederMotorVoltage = 0.0; - public double _feederMotorSpeed = 0.0; - public double _armEncoderPositionDegrees = 0.0; public double _armEncoderVelocity = 0.0; @@ -23,7 +19,9 @@ public static class ArmIOInputs { public double _intakeMotorCurrent = 0.0; public double _intakeMotorVoltage = 0.0; - public boolean _lightSensorState = false; + public boolean _upperLightSensorState = false; + public boolean _lowerLightSensorState = false; + public boolean _algaeLightSensorState = false; } public default void updateInputs(ArmIOInputs inputs) {} @@ -35,6 +33,4 @@ public default void setArmMotorSpeed(double speed) {} public default void resetIntakeEncoders() {} public default void setArmMotorVoltage(Voltage voltage) {} - - public default void setFeederMotorSpeed(double speed) {} } diff --git a/src/main/java/frc/robot/subsystems/arm/io/RealArmIO.java b/src/main/java/frc/robot/subsystems/arm/io/RealArmIO.java new file mode 100644 index 0000000..ea77a7d --- /dev/null +++ b/src/main/java/frc/robot/subsystems/arm/io/RealArmIO.java @@ -0,0 +1,117 @@ +package frc.robot.subsystems.arm.io; + +import com.revrobotics.spark.SparkAbsoluteEncoder; +import com.revrobotics.spark.SparkBase.PersistMode; +import com.revrobotics.spark.SparkBase.ResetMode; +import com.revrobotics.spark.SparkFlex; +import com.revrobotics.spark.config.SparkBaseConfig.IdleMode; +import com.revrobotics.spark.config.SparkFlexConfig; + +import au.grapplerobotics.ConfigurationFailedException; +import au.grapplerobotics.LaserCan; +import au.grapplerobotics.interfaces.LaserCanInterface.RegionOfInterest; + +import com.revrobotics.spark.SparkLowLevel.MotorType; +import com.revrobotics.spark.SparkMax; + +import edu.wpi.first.units.measure.Voltage; +import edu.wpi.first.wpilibj.DigitalInput; +import frc.robot.HardwareConstants.CAN; +import frc.robot.HardwareConstants.DIO; + +public class RealArmIO implements ArmIO { + + private static final double POS_AT_90 = 0.422; + private static final double POS_AT_0 = 0.168; + private static final double ENCODER_CONVERSION = (POS_AT_90 - POS_AT_0) / 90.0; + private static final double CORAL_LASERCAN_DISTANCE_MM = 50; + private static final double ALGAE_LASERCAN_DISTANCE_MM = 20; + + private double INTAKE_ROTATION_CONVERSION = 1; + + private SparkFlex _armMotor; + private LaserCan _upperLaserCan; + private LaserCan _lowerLaserCan; + private LaserCan _algaeLaserCan; + private SparkFlex _intakeMotor; + private SparkAbsoluteEncoder _armEncoder; + + public RealArmIO() { + _armMotor = new SparkFlex(CAN.ARM_MTR_ID, MotorType.kBrushless); + _intakeMotor = new SparkFlex(CAN.INTAKE_MTR_ID, MotorType.kBrushless); + _armEncoder = _armMotor.getAbsoluteEncoder(); + + SparkFlexConfig armConfig = new SparkFlexConfig(); + armConfig.idleMode(IdleMode.kBrake); + armConfig.inverted(true); + armConfig.voltageCompensation(12); + _armMotor.configure(armConfig, ResetMode.kResetSafeParameters, PersistMode.kPersistParameters); + + SparkFlexConfig intakeConfig = new SparkFlexConfig(); + intakeConfig.idleMode(IdleMode.kBrake); + _intakeMotor.configure(intakeConfig, ResetMode.kResetSafeParameters, PersistMode.kPersistParameters); + + _upperLaserCan = new LaserCan(CAN.UPPER_CORAL_LASERCAN_ID); + _lowerLaserCan = new LaserCan(CAN.LOWER_CORAL_LASERCAN_ID); + _algaeLaserCan = new LaserCan(CAN.ALGAE_LASERCAN_ID); + // Optionally initialise the settings of the LaserCAN, if you haven't already + // done so in GrappleHook + try { + _upperLaserCan.setRangingMode(LaserCan.RangingMode.SHORT); + _upperLaserCan.setTimingBudget(LaserCan.TimingBudget.TIMING_BUDGET_33MS); + _upperLaserCan.setRegionOfInterest(new RegionOfInterest(8, 8, 8, 8)); + _lowerLaserCan.setRangingMode(LaserCan.RangingMode.SHORT); + _lowerLaserCan.setTimingBudget(LaserCan.TimingBudget.TIMING_BUDGET_33MS); + _lowerLaserCan.setRegionOfInterest(new RegionOfInterest(8, 8, 8, 8)); + _algaeLaserCan.setRangingMode(LaserCan.RangingMode.SHORT); + _algaeLaserCan.setTimingBudget(LaserCan.TimingBudget.TIMING_BUDGET_33MS); + _algaeLaserCan.setRegionOfInterest(new RegionOfInterest(8, 8, 8, 8)); + } catch (ConfigurationFailedException e) { + System.out.println("Configuration failed! " + e); + } + } + + public void updateInputs(ArmIOInputs inputs) { + inputs._armMotorSpeed = _armMotor.get(); + inputs._armMotorCurrent = _armMotor.getOutputCurrent(); + inputs._armMotorVoltage = _armMotor.getAppliedOutput() * _armMotor.getBusVoltage(); + + LaserCan.Measurement upperMeasurement = _upperLaserCan.getMeasurement(); + if (upperMeasurement != null && upperMeasurement.status == LaserCan.LASERCAN_STATUS_VALID_MEASUREMENT) + inputs._upperLightSensorState = upperMeasurement.distance_mm <= CORAL_LASERCAN_DISTANCE_MM; + LaserCan.Measurement lowerMeasurement = _lowerLaserCan.getMeasurement(); + if (lowerMeasurement != null && lowerMeasurement.status == LaserCan.LASERCAN_STATUS_VALID_MEASUREMENT) + inputs._lowerLightSensorState = lowerMeasurement.distance_mm <= CORAL_LASERCAN_DISTANCE_MM; + LaserCan.Measurement algaeMeasurement = _algaeLaserCan.getMeasurement(); + if (algaeMeasurement != null && algaeMeasurement.status == LaserCan.LASERCAN_STATUS_VALID_MEASUREMENT) { + inputs._algaeLightSensorState = algaeMeasurement.distance_mm <= ALGAE_LASERCAN_DISTANCE_MM; + } else { + inputs._algaeLightSensorState = false; + } + + inputs._intakeMotorVelocityRotationsPerMin = _intakeMotor.get(); + inputs._intakeMotorCurrent = _intakeMotor.getOutputCurrent(); + inputs._intakeMotorVoltage = _intakeMotor.getAppliedOutput() * _armMotor.getBusVoltage(); + inputs._intakeMotorPositionRotations = _intakeMotor.getEncoder().getPosition() * INTAKE_ROTATION_CONVERSION; + + inputs._armEncoderPositionDegrees = (_armEncoder.getPosition() - POS_AT_0) / ENCODER_CONVERSION; + inputs._armEncoderVelocity = _armEncoder.getVelocity(); + } + + public void setArmMotorSpeed(double speed) { + _armMotor.set(speed); + } + + public void setIntakeMotorSpeed(double speed) { + _intakeMotor.set(speed); + } + + public void resetIntakeEncoders() { + _intakeMotor.getEncoder().setPosition(0); + } + + public void setArmMotorVoltage(Voltage voltage) { + _armMotor.setVoltage(voltage); + } + +} diff --git a/src/main/java/frc/robot/subsystems/climber/Climber.java b/src/main/java/frc/robot/subsystems/climber/Climber.java index 464f269..f4d0d79 100644 --- a/src/main/java/frc/robot/subsystems/climber/Climber.java +++ b/src/main/java/frc/robot/subsystems/climber/Climber.java @@ -3,6 +3,8 @@ import org.littletonrobotics.junction.Logger; import edu.wpi.first.wpilibj2.command.SubsystemBase; +import frc.robot.subsystems.climber.io.ClimberIO; +import frc.robot.subsystems.climber.io.ClimberIOInputsAutoLogged; public class Climber extends SubsystemBase { diff --git a/src/main/java/frc/robot/subsystems/climber/ClimberCommands.java b/src/main/java/frc/robot/subsystems/climber/ClimberCommands.java index 5474c0f..7b99f2a 100644 --- a/src/main/java/frc/robot/subsystems/climber/ClimberCommands.java +++ b/src/main/java/frc/robot/subsystems/climber/ClimberCommands.java @@ -17,6 +17,6 @@ public Command runClimber(DoubleSupplier ySupplier) { () -> { _climber.setClimberSpeed(ySupplier.getAsDouble()); }, - _climber); + _climber).unless(() -> (ySupplier.getAsDouble() < 0.05)); } } \ No newline at end of file diff --git a/src/main/java/frc/robot/subsystems/climber/ClimberIO.java b/src/main/java/frc/robot/subsystems/climber/io/ClimberIO.java similarity index 78% rename from src/main/java/frc/robot/subsystems/climber/ClimberIO.java rename to src/main/java/frc/robot/subsystems/climber/io/ClimberIO.java index 90bcb9f..09f4e65 100644 --- a/src/main/java/frc/robot/subsystems/climber/ClimberIO.java +++ b/src/main/java/frc/robot/subsystems/climber/io/ClimberIO.java @@ -1,9 +1,7 @@ -package frc.robot.subsystems.climber; +package frc.robot.subsystems.climber.io; import org.littletonrobotics.junction.AutoLog; -import frc.robot.subsystems.arm.ArmIO.ArmIOInputs; - public interface ClimberIO { @AutoLog public static class ClimberIOInputs { diff --git a/src/main/java/frc/robot/subsystems/climber/RealClimberIO.java b/src/main/java/frc/robot/subsystems/climber/io/RealClimberIO.java similarity index 96% rename from src/main/java/frc/robot/subsystems/climber/RealClimberIO.java rename to src/main/java/frc/robot/subsystems/climber/io/RealClimberIO.java index 16b4b90..533d31d 100644 --- a/src/main/java/frc/robot/subsystems/climber/RealClimberIO.java +++ b/src/main/java/frc/robot/subsystems/climber/io/RealClimberIO.java @@ -1,4 +1,4 @@ -package frc.robot.subsystems.climber; +package frc.robot.subsystems.climber.io; import com.revrobotics.spark.SparkBase.PersistMode; import com.revrobotics.spark.SparkBase.ResetMode; diff --git a/src/main/java/frc/robot/subsystems/drive/CommandSwerveDrivetrain.java b/src/main/java/frc/robot/subsystems/drive/CommandSwerveDrivetrain.java.old similarity index 100% rename from src/main/java/frc/robot/subsystems/drive/CommandSwerveDrivetrain.java rename to src/main/java/frc/robot/subsystems/drive/CommandSwerveDrivetrain.java.old diff --git a/src/main/java/frc/robot/subsystems/drive/Drive.java b/src/main/java/frc/robot/subsystems/drive/Drive.java index 5270b06..f85ce57 100644 --- a/src/main/java/frc/robot/subsystems/drive/Drive.java +++ b/src/main/java/frc/robot/subsystems/drive/Drive.java @@ -42,6 +42,7 @@ import edu.wpi.first.math.numbers.N1; import edu.wpi.first.math.numbers.N3; import edu.wpi.first.math.system.plant.DCMotor; +import edu.wpi.first.math.util.Units; import edu.wpi.first.wpilibj.Alert; import edu.wpi.first.wpilibj.Alert.AlertType; import edu.wpi.first.wpilibj.DriverStation; @@ -49,6 +50,7 @@ import edu.wpi.first.wpilibj2.command.Command; import edu.wpi.first.wpilibj2.command.SubsystemBase; import edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine; +import frc.robot.FieldConstants; import frc.robot.HardwareConstants; import frc.robot.HardwareConstants.Mode; import frc.robot.subsystems.drive.io.GyroIO; @@ -74,23 +76,13 @@ public class Drive extends SubsystemBase { Math.hypot(TunerConstants.BackLeft.LocationX, TunerConstants.BackLeft.LocationY), Math.hypot(TunerConstants.BackRight.LocationX, TunerConstants.BackRight.LocationY))); - // PathPlanner config constants - private static final double ROBOT_MASS_KG = 74.088; - private static final double ROBOT_MOI = 6.883; - private static final double WHEEL_COF = 1.2; - private static final RobotConfig PP_CONFIG = - new RobotConfig( - ROBOT_MASS_KG, - ROBOT_MOI, - new ModuleConfig( - TunerConstants.FrontLeft.WheelRadius, - TunerConstants.kSpeedAt12Volts.in(MetersPerSecond), - WHEEL_COF, - DCMotor.getKrakenX60Foc(1) - .withReduction(TunerConstants.FrontLeft.DriveMotorGearRatio), - TunerConstants.FrontLeft.SlipCurrent, - 1), - getModuleTranslations()); + // PathPlanner config constants to use if we can't read in the path planner json file + private static final double ROBOT_MASS_KG = 50.0; + private static final double ROBOT_MOI = 5.10; + private static final double WHEEL_COF = 1.13; + + // For use in getCloseToReef() method: if robot is less than this distance from the reef, LEDs turn green + private static final double MAX_DISTANCE_TO_REEF = Units.inchesToMeters(20.5); // was 19.5 static final Lock odometryLock = new ReentrantLock(); private final GyroIO gyroIO; @@ -130,6 +122,53 @@ public Drive( // Start odometry thread PhoenixOdometryThread.getInstance().start(); + + RobotConfig config; + try{ + config = RobotConfig.fromGUISettings(); + } catch (Exception e) { + // Handle exception as needed + e.printStackTrace(); + config = new RobotConfig( + ROBOT_MASS_KG, + ROBOT_MOI, + new ModuleConfig( + TunerConstants.FrontLeft.WheelRadius, + TunerConstants.kSpeedAt12Volts.in(MetersPerSecond), + WHEEL_COF, + DCMotor.getKrakenX60Foc(1) + .withReduction(TunerConstants.FrontLeft.DriveMotorGearRatio), + TunerConstants.FrontLeft.SlipCurrent, + 1), + getModuleTranslations()); + } + + // Configure AutoBuilder last + AutoBuilder.configure( + this::getPose, // Robot pose supplier + this::setPose, // Method to reset odometry (will be called if your auto has a starting pose) + this::getChassisSpeeds, // ChassisSpeeds supplier. MUST BE ROBOT RELATIVE + this::runVelocity, // Method that will drive the robot given ROBOT RELATIVE ChassisSpeeds. Also optionally outputs individual module feedforwards + new PPHolonomicDriveController( // PPHolonomicController is the built in path following controller for holonomic drive trains + new PIDConstants(5.0, 0.0, 0.0), // Translation PID constants + new PIDConstants(5.0, 0.0, 0.0) // Rotation PID constants + ), + config, // The robot configuration + () -> { + // Boolean supplier that controls when the path will be mirrored for the red alliance + // This will flip the path being followed to the red side of the field. + // THE ORIGIN WILL REMAIN ON THE BLUE SIDE + + var alliance = DriverStation.getAlliance(); + if (alliance.isPresent()) { + return alliance.get() == DriverStation.Alliance.Red; + } + return false; + }, + this // Reference to this subsystem to set requirements + ); + + /* // Configure AutoBuilder for PathPlanner AutoBuilder.configure( this::getPose, @@ -137,16 +176,19 @@ public Drive( this::getChassisSpeeds, this::runVelocity, new PPHolonomicDriveController( - new PIDConstants(5.0, 0.0, 0.0), new PIDConstants(5.0, 0.0, 0.0)), - PP_CONFIG, + new PIDConstants(3, 0.0, 0.0), new PIDConstants(5.5, 0.0, 0.0)), + PP_CONFIG, () -> DriverStation.getAlliance().orElse(Alliance.Blue) == Alliance.Red, - this); + this); */ + Pathfinding.setPathfinder(new LocalADStarAK()); + PathPlannerLogging.setLogActivePathCallback( (activePath) -> { Logger.recordOutput( "Odometry/Trajectory", activePath.toArray(new Pose2d[activePath.size()])); }); + PathPlannerLogging.setLogTargetPoseCallback( (targetPose) -> { Logger.recordOutput("Odometry/TrajectorySetpoint", targetPose); @@ -229,6 +271,7 @@ public void periodic() { * @param speeds Speeds in meters/sec */ public void runVelocity(ChassisSpeeds speeds) { + // Calculate module setpoints ChassisSpeeds discreteSpeeds = ChassisSpeeds.discretize(speeds, 0.02); SwerveModuleState[] setpointStates = kinematics.toSwerveModuleStates(discreteSpeeds); @@ -353,6 +396,20 @@ public void addVisionMeasurement( visionRobotPoseMeters, timestampSeconds, visionMeasurementStdDevs); } + public boolean getCloseToReef() { + + Pose2d currentPose = getPose(); + Pose2d reefFacePose = FieldConstants.getNearestReefFace(currentPose); + double distanceToReef = currentPose.getTranslation().getDistance(reefFacePose.getTranslation()); + + // If robot is within MAX_DISTANCE_TO_REEF from center of reef, LEDs can turn green. + if (distanceToReef <= MAX_DISTANCE_TO_REEF) { + return true; + } + + return false; + } + /** Returns the maximum linear speed in meters per sec. */ public double getMaxLinearSpeedMetersPerSec() { return TunerConstants.kSpeedAt12Volts.in(MetersPerSecond); diff --git a/src/main/java/frc/robot/subsystems/drive/DriveCommands.java b/src/main/java/frc/robot/subsystems/drive/DriveCommands.java index fb3ecca..e672165 100644 --- a/src/main/java/frc/robot/subsystems/drive/DriveCommands.java +++ b/src/main/java/frc/robot/subsystems/drive/DriveCommands.java @@ -26,6 +26,7 @@ import edu.wpi.first.wpilibj.DriverStation; import edu.wpi.first.wpilibj.DriverStation.Alliance; import edu.wpi.first.wpilibj.Timer; +import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; import edu.wpi.first.wpilibj2.command.Command; import edu.wpi.first.wpilibj2.command.Commands; import frc.robot.subsystems.drive.Drive; @@ -35,11 +36,13 @@ import java.util.List; import java.util.function.DoubleSupplier; import java.util.function.Supplier; +import frc.robot.util.TuneableProfiledPID; +import org.littletonrobotics.junction.Logger; public class DriveCommands { private static final double DEADBAND = 0.1; private static final double ANGLE_KP = 5.0; - private static final double ANGLE_KD = 0.4; + private static final double ANGLE_KD = 0.0; // 0.4 private static final double ANGLE_MAX_VELOCITY = 8.0; private static final double ANGLE_MAX_ACCELERATION = 20.0; private static final double FF_START_DELAY = 2.0; // Secs @@ -47,6 +50,14 @@ public class DriveCommands { private static final double WHEEL_RADIUS_MAX_VELOCITY = 0.25; // Rad/Sec private static final double WHEEL_RADIUS_RAMP_RATE = 0.05; // Rad/Sec^2 + public enum DriveMode { + dmJoystick, + dmAngle, + dmApproach +} + +private static DriveMode currentDriveMode = DriveMode.dmJoystick; + private DriveCommands() {} private static Translation2d getLinearVelocityFromJoysticks(double x, double y) { @@ -89,9 +100,8 @@ public static Command joystickDrive( linearVelocity.getX() * drive.getMaxLinearSpeedMetersPerSec(), linearVelocity.getY() * drive.getMaxLinearSpeedMetersPerSec(), omega * drive.getMaxAngularSpeedRadPerSec()); - boolean isFlipped = - DriverStation.getAlliance().isPresent() - && DriverStation.getAlliance().get() == Alliance.Red; + boolean isFlipped = DriverStation.getAlliance().isPresent() + && DriverStation.getAlliance().get() == Alliance.Red; drive.runVelocity( ChassisSpeeds.fromFieldRelativeSpeeds( speeds, @@ -156,6 +166,101 @@ public static Command joystickDriveAtAngle( .beforeStarting(() -> angleController.reset(drive.getRotation().getRadians())); } + /** + * Robot relative drive command using joystick for linear control towards the approach target, + * PID for aligning with the target laterally, and PID for angular control. Used for approaching + * a known target, usually from a short distance. The approachSupplier must supply a Pose2d with + * a rotation facing away from the target + */ + public static Command joystickApproach( + Drive drive, + DoubleSupplier ySupplier, + Supplier approachSupplier) + { + + // Create PID controller + TuneableProfiledPID angleController = + new TuneableProfiledPID( + "angleController", + ANGLE_KP, + 0.0, + ANGLE_KD, + ANGLE_MAX_VELOCITY, + ANGLE_MAX_ACCELERATION); + angleController.enableContinuousInput(-Math.PI, Math.PI); + + TuneableProfiledPID alignController = + new TuneableProfiledPID( + "alignController", + 0.3, + 0.0, + 0, + 20, + 8); + alignController.setGoal(0); + + // Construct command + return Commands.run( + () -> { + + //System.out.println("JOYSTICK APPROACH!!!"); + currentDriveMode = DriveMode.dmApproach; + // Name constants + Translation2d currentTranslation = drive.getPose().getTranslation(); + Translation2d approachTranslation = approachSupplier.get().getTranslation(); + double distanceToApproach = currentTranslation.getDistance(approachTranslation); + + Rotation2d alignmentDirection = approachSupplier.get().getRotation(); + + // Find lateral distance from goal + Translation2d goalTranslation = new Translation2d( + alignmentDirection.getCos() * distanceToApproach + approachTranslation.getX(), + alignmentDirection.getSin() * distanceToApproach + approachTranslation.getY()); + + Translation2d robotToGoal = currentTranslation.minus(goalTranslation); + double distanceToGoal = + Math.hypot(robotToGoal.getX(), robotToGoal.getY()); + + // Calculate lateral linear velocity + Translation2d offsetVector = + new Translation2d(alignController.calculate(distanceToGoal), 0) + .rotateBy(robotToGoal.getAngle()); + + Logger.recordOutput("AlignDebug/Current", distanceToGoal); + + // Calculate total linear velocity + Translation2d linearVelocity = + getLinearVelocityFromJoysticks(0, + ySupplier.getAsDouble()).rotateBy( + approachSupplier.get().getRotation()).rotateBy(Rotation2d.kCCW_90deg) + .plus(offsetVector); + + SmartDashboard.putData(alignController); // TODO: Calibrate PID + Logger.recordOutput("AlignDebug/approachTarget", approachTranslation); + + // Calculate angular speed + double omega = + angleController.calculate( + drive.getRotation().getRadians(), approachSupplier.get().getRotation() + .rotateBy(Rotation2d.k180deg).getRadians()); + + // Convert to field relative speeds & send command + ChassisSpeeds speeds = + new ChassisSpeeds( + linearVelocity.getX() * drive.getMaxLinearSpeedMetersPerSec(), + linearVelocity.getY() * drive.getMaxLinearSpeedMetersPerSec(), + omega); + drive.runVelocity( + ChassisSpeeds.fromFieldRelativeSpeeds( + speeds, + drive.getRotation())); + }, + drive) + + // Reset PID controller when command starts + .beforeStarting(() -> angleController.reset(drive.getRotation().getRadians())); + } + /** * Measures the velocity feedforward constants for the drive motors. * diff --git a/src/main/java/frc/robot/subsystems/drive/TunerConstants.java b/src/main/java/frc/robot/subsystems/drive/TunerConstants.java index f6cdc10..b015024 100644 --- a/src/main/java/frc/robot/subsystems/drive/TunerConstants.java +++ b/src/main/java/frc/robot/subsystems/drive/TunerConstants.java @@ -22,14 +22,14 @@ public class TunerConstants { // The steer motor uses any SwerveModule.SteerRequestType control request with the // output type specified by SwerveModuleConstants.SteerMotorClosedLoopOutput private static final Slot0Configs steerGains = new Slot0Configs() - .withKP(100).withKI(0).withKD(0.5) + .withKP(107).withKI(0).withKD(0.7) .withKS(0.1).withKV(2.66).withKA(0) .withStaticFeedforwardSign(StaticFeedforwardSignValue.UseClosedLoopSign); // When using closed-loop control, the drive motor uses the control // output type specified by SwerveModuleConstants.DriveMotorClosedLoopOutput private static final Slot0Configs driveGains = new Slot0Configs() - .withKP(0.1).withKI(0).withKD(0) - .withKS(0).withKV(0.124); + .withKP(2.3).withKI(0).withKD(0) + .withKS(0.08).withKV(0.124); // The closed-loop output type to use for the steer motors; // This affects the PID/FF gains for the steer motors @@ -72,8 +72,8 @@ public class TunerConstants { // Theoretical free speed (m/s) at 12 V applied output; // This needs to be tuned to your individual robot - public static final LinearVelocity kSpeedAt12Volts = MetersPerSecond.of(5.21*0.7); - + public static final LinearVelocity kSpeedAt12Volts = MetersPerSecond.of(5.21); + // Every 1 rotation of the azimuth results in kCoupleRatio drive motor turns; // This may need to be tuned to your individual robot private static final double kCoupleRatio = 3.5714285714285716; @@ -127,7 +127,7 @@ public class TunerConstants { private static final int kFrontLeftDriveMotorId = 1; private static final int kFrontLeftSteerMotorId = 2; private static final int kFrontLeftEncoderId = 3; - private static final Angle kFrontLeftEncoderOffset = Rotations.of(0.378662109375); + private static final Angle kFrontLeftEncoderOffset = Rotations.of(0.0239); private static final boolean kFrontLeftSteerMotorInverted = true; private static final boolean kFrontLeftEncoderInverted = false; @@ -138,7 +138,7 @@ public class TunerConstants { private static final int kFrontRightDriveMotorId = 4; private static final int kFrontRightSteerMotorId = 5; private static final int kFrontRightEncoderId = 6; - private static final Angle kFrontRightEncoderOffset = Rotations.of(-0.221435546875); + private static final Angle kFrontRightEncoderOffset = Rotations.of(0.308); private static final boolean kFrontRightSteerMotorInverted = true; private static final boolean kFrontRightEncoderInverted = false; @@ -149,7 +149,7 @@ public class TunerConstants { private static final int kBackLeftDriveMotorId = 7; private static final int kBackLeftSteerMotorId = 8; private static final int kBackLeftEncoderId = 9; - private static final Angle kBackLeftEncoderOffset = Rotations.of(0.2783203125); + private static final Angle kBackLeftEncoderOffset = Rotations.of(-0.4429); private static final boolean kBackLeftSteerMotorInverted = true; private static final boolean kBackLeftEncoderInverted = false; @@ -160,7 +160,7 @@ public class TunerConstants { private static final int kBackRightDriveMotorId = 10; private static final int kBackRightSteerMotorId = 11; private static final int kBackRightEncoderId = 12; - private static final Angle kBackRightEncoderOffset = Rotations.of(-0.142333984375); + private static final Angle kBackRightEncoderOffset = Rotations.of(0.4294); private static final boolean kBackRightSteerMotorInverted = true; private static final boolean kBackRightEncoderInverted = false; @@ -193,11 +193,12 @@ public class TunerConstants { * Creates a CommandSwerveDrivetrain instance. * This should only be called once in your robot program,. */ + /* public static CommandSwerveDrivetrain createDrivetrain() { return new CommandSwerveDrivetrain( DrivetrainConstants, FrontLeft, FrontRight, BackLeft, BackRight ); - } + } */ /** diff --git a/src/main/java/frc/robot/subsystems/elevator/CmdElevatorCalibrate.java b/src/main/java/frc/robot/subsystems/elevator/CmdElevatorCalibrate.java deleted file mode 100644 index d9163f6..0000000 --- a/src/main/java/frc/robot/subsystems/elevator/CmdElevatorCalibrate.java +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) FIRST and other WPILib contributors. -// Open Source Software; you can modify and/or share it under the terms of -// the WPILib BSD license file in the root directory of this project. - -package frc.robot.subsystems.elevator; - -import edu.wpi.first.wpilibj2.command.Command; - -public class CmdElevatorCalibrate extends Command { - - private Elevator _elevator; - private int _spikeCounter; - - public CmdElevatorCalibrate(Elevator elevator) { - _elevator = elevator; - } - - - @Override - public void initialize() { - _elevator.runMotorsDown(); - _spikeCounter = 0; - } - - - @Override - public void execute() { - if (_elevator.isAboveCurrentLimit()) { - _spikeCounter++; - } - } - - - @Override - public void end(boolean interrupted) { - _elevator.resetEncoders(); - _elevator.stopMotors(); - _elevator.setIsCalibrated(true); - } - - - @Override - public boolean isFinished() { - return _spikeCounter >= 3; - } -} diff --git a/src/main/java/frc/robot/subsystems/elevator/Elevator.java b/src/main/java/frc/robot/subsystems/elevator/Elevator.java index d5cb940..23f2343 100644 --- a/src/main/java/frc/robot/subsystems/elevator/Elevator.java +++ b/src/main/java/frc/robot/subsystems/elevator/Elevator.java @@ -9,6 +9,8 @@ import static edu.wpi.first.units.Units.MetersPerSecond; import static edu.wpi.first.units.Units.Volt; +import java.util.HashMap; + import org.littletonrobotics.junction.Logger; import edu.wpi.first.math.controller.ProfiledPIDController; @@ -19,89 +21,85 @@ import edu.wpi.first.units.measure.Voltage; import edu.wpi.first.wpilibj.sysid.SysIdRoutineLog; import edu.wpi.first.wpilibj2.command.Command; +import edu.wpi.first.wpilibj2.command.CommandScheduler; import edu.wpi.first.wpilibj2.command.SubsystemBase; import edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine; import edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine.Config; import frc.robot.subsystems.arm.Arm.ArmPosition; +import frc.robot.subsystems.elevator.io.ElevatorIO; +import frc.robot.subsystems.elevator.io.ElevatorIOInputsAutoLogged; import frc.robot.subsystems.multisubsystemcommands.MultiSubsystemCommands; import frc.robot.subsystems.multisubsystemcommands.MultiSubsystemCommands.GamepieceMode; public class Elevator extends SubsystemBase { public enum ElevatorPosition { - L1(5), - L2(9), - L3(25.5), - L4(48), - Stow(0.5); + L1(7, 5), + L2(13, 18), + L3(29, 36), + L4(51.8, 50), + Stow(0.5, 0.5); + + final double coralHeight, algaeHeight; - public final double setpoint; + ElevatorPosition(double coralHeight, double algaeHeight) { + this.coralHeight = coralHeight; + this.algaeHeight = algaeHeight; + } - private ElevatorPosition(double setpoint) { - this.setpoint = setpoint; + double getHeight(GamepieceMode mode) { + return (mode == GamepieceMode.ALGAE) ? this.algaeHeight : this.coralHeight; } } private static final double CALIBRATION_SPEED = -0.1; - private static final double HARD_STOP_CURRENT_LIMIT = 50; + private static final double HARD_STOP_CURRENT_LIMIT = 37; - private static final double INCREMENT_CONSTANT = 1; - private static final double DECREMENT_CONSTANT = 1; + private static final int INCREMENT_CONSTANT = 1; + private static final int DECREMENT_CONSTANT = 1; - private static final double ELEVATOR_MOTOR_KP = 0.75; - private static final double ELEVATOR_MOTOR_KI = 0.15; + private static final double ELEVATOR_MOTOR_KP = 1.5; //0.75; + private static final double ELEVATOR_MOTOR_KI = 0;//0.15; private static final double ELEVATOR_MOTOR_KD = 0; - private static final double ELEVATOR_PID_VEL = 220; - private static final double ELEVATOR_PID_ACC = 215; + private static final double ELEVATOR_PID_VEL = 400; + private static final double ELEVATOR_PID_ACC = 335; - private static final double ELEVATOR_MAX_INCHES = 48; - private static final double ELEVATOR_MAX_ROTATIONS = 36.4; + private static final double ELEVATOR_MAX_INCHES = 52; //48; + private static final double ELEVATOR_MAX_ROTATIONS = 87; // 36.4; private static final double MOTOR_CONVERSION = ELEVATOR_MAX_INCHES / ELEVATOR_MAX_ROTATIONS; - // In newtons - private static final double ELEVATOR_STAGE1_WEIGHT_N = 2.053 * 9.81; - private static final double ELEVATOR_STAGE2_WEIGHT_N = 7.554 * 9.81; - private static final double ELEVATOR_TOTAL_WEIGHT_N = ELEVATOR_STAGE1_WEIGHT_N + (ELEVATOR_STAGE2_WEIGHT_N); - - // In m - private static final double SPOOL_DIAMETER = 0.0527; - - private static final double ELEVATOR_STALL_TORQUE_LB_IN = 3.6; - private static final double ELEVATOR_STALL_CURRENT = 211; - private static final double ELEVATOR_KT = ELEVATOR_STALL_TORQUE_LB_IN / ELEVATOR_STALL_CURRENT; - private static final double GEAR_RATIO = 7.75; - private static final double NUMBER_OF_MOTORS = 2; - private static final double EFFECTIVE_KT = ELEVATOR_KT * NUMBER_OF_MOTORS * GEAR_RATIO; - private static final double ELEVATOR_RESISTANCE = 0.057; - - private static final double FEEDFORWARD_CONSTANT = ((ELEVATOR_TOTAL_WEIGHT_N * SPOOL_DIAMETER * ELEVATOR_RESISTANCE) / (EFFECTIVE_KT)) - 0.65; + private static final double FEEDFORWARD_CONSTANT = 0.225; private boolean _isCalibrated; + private boolean _atSetpoint; private ElevatorPosition _currentPos; private ElevatorPosition _desiredPos; + private ElevatorPosition _prevPos; private MultiSubsystemCommands.GamepieceMode _currentMode; + private HashMap _manualAdjustments; private ProfiledPIDController _elevatorMotorPID; private ElevatorIO _io; private ElevatorIOInputsAutoLogged _inputs; - - - SysIdRoutine routine = new SysIdRoutine(new Config(), - new SysIdRoutine.Mechanism(this::setElevatorVoltage, this::populateLog, this)); - public Elevator(ElevatorIO io) { _io = io; _inputs = new ElevatorIOInputsAutoLogged(); _elevatorMotorPID = new ProfiledPIDController(ELEVATOR_MOTOR_KP, ELEVATOR_MOTOR_KI, ELEVATOR_MOTOR_KD, new Constraints(ELEVATOR_PID_VEL, ELEVATOR_PID_ACC)); - _elevatorMotorPID.setTolerance(0.5); + _elevatorMotorPID.setTolerance(1); _currentPos = ElevatorPosition.Stow; _desiredPos = ElevatorPosition.Stow; + _prevPos = ElevatorPosition.Stow; + _currentMode = GamepieceMode.CORAL; + + _manualAdjustments = new HashMap<>(); + + setSetpoint(ElevatorPosition.Stow); } // Runs the motors down at the calibration speed @@ -118,34 +116,58 @@ public void setElevatorVoltage(Voltage voltage) { } public void setSetpoint(ElevatorPosition setpoint) { - setSetpoint(setpoint.setpoint); + _prevPos = _currentPos; _desiredPos = setpoint; + String key = getManualAdjustKey(); + setSetpoint(setpoint.getHeight(_currentMode) + _manualAdjustments.getOrDefault(key, 0)); } // Sets the setpoint of the PID public void setSetpoint(double setpoint) { if (setpoint < 0.25 || setpoint > ELEVATOR_MAX_INCHES) return; + _atSetpoint = false; _elevatorMotorPID.reset(getCurrentPosInches()); _elevatorMotorPID.setGoal(setpoint); } // Checks if it is at the setpoint public boolean isAtSetpoint() { - boolean atSetpoint = Math.abs(_elevatorMotorPID.getGoal().position - getCurrentPosInches()) <= 0.5; - if (atSetpoint) + boolean atSetpoint = Math.abs(_elevatorMotorPID.getGoal().position - getCurrentPosInches()) <= 1; + if (atSetpoint) { _currentPos = _desiredPos; + _atSetpoint = true; + } return atSetpoint; } + public void resetPID() { + _elevatorMotorPID.setGoal(ElevatorPosition.Stow.getHeight(_currentMode)); + _elevatorMotorPID.reset(getCurrentPosInches()); + } + + private String getManualAdjustKey() { + return _desiredPos.toString() + _currentMode.toString(); + } + // Increases elevator position public void incrementElevatorPosition() { - setSetpoint(_elevatorMotorPID.getGoal().position + INCREMENT_CONSTANT); + if (_currentPos == _desiredPos) { + String key = getManualAdjustKey(); + Integer offset = _manualAdjustments.getOrDefault(key, 0) + INCREMENT_CONSTANT; + _manualAdjustments.put(key, offset); + setSetpoint(_currentPos); + } } // Decreases elevator position public void decrementElevatorPosition() { - setSetpoint(_elevatorMotorPID.getGoal().position - DECREMENT_CONSTANT); + if (_currentPos == _desiredPos) { + String key = getManualAdjustKey(); + Integer offset = _manualAdjustments.getOrDefault(key, 0) - DECREMENT_CONSTANT; + _manualAdjustments.put(key, offset); + setSetpoint(_currentPos); + } } // Checks if above limit @@ -161,8 +183,8 @@ public void resetEncoders() { // Runs motors with PID public void runMotorsWithPID() { - // _io.setElevatorSpeed(); - _io.setElevatorVoltage(Voltage.ofBaseUnits(_elevatorMotorPID.calculate(getCurrentPosInches()) + FEEDFORWARD_CONSTANT, Volt)); + if (_isCalibrated) + _io.setElevatorVoltage(Voltage.ofBaseUnits(_elevatorMotorPID.calculate(getCurrentPosInches()) + FEEDFORWARD_CONSTANT, Volt)); } public boolean isCalibrated() { @@ -182,6 +204,10 @@ public ElevatorPosition getCurrentPos() { return _currentPos; } + public ElevatorPosition getPrevPos() { + return _prevPos; + } + public GamepieceMode getCurrentMode() { return _currentMode; } @@ -194,22 +220,6 @@ public double getElevatorMaxHeight() { return ELEVATOR_MAX_INCHES; } - public void populateLog(SysIdRoutineLog log) { - log.motor("elevator_primary") - .voltage(Voltage.ofBaseUnits(_inputs._elevatorMotorVoltage, Volt)) - .linearPosition(Distance.ofBaseUnits(Units.inchesToMeters(getCurrentPosInches()), Meters)) - .linearVelocity( - LinearVelocity.ofBaseUnits(_inputs._elevatorVelocity * SPOOL_DIAMETER * Math.PI / 60, MetersPerSecond)); - } - - public Command sysIdQuasistatic(SysIdRoutine.Direction direction) { - return routine.quasistatic(direction); - } - - public Command sysIdDynamic(SysIdRoutine.Direction direction) { - return routine.dynamic(direction); - } - @Override public void periodic() { _io.updateInputs(_inputs); @@ -225,6 +235,10 @@ public void periodic() { Logger.recordOutput("Elevator/atSetpoint", isAtSetpoint()); Logger.recordOutput("Elevator/currentPosEnum", _currentPos); Logger.recordOutput("Elevator/desiredPosEnum", _desiredPos); + Logger.recordOutput("Elevator/currentGamepieceMode", _currentMode); + + // Run pid + runMotorsWithPID(); } } diff --git a/src/main/java/frc/robot/subsystems/elevator/ElevatorCommands.java b/src/main/java/frc/robot/subsystems/elevator/ElevatorCommands.java index 38f5634..0d0b6e9 100644 --- a/src/main/java/frc/robot/subsystems/elevator/ElevatorCommands.java +++ b/src/main/java/frc/robot/subsystems/elevator/ElevatorCommands.java @@ -5,7 +5,6 @@ import edu.wpi.first.wpilibj2.command.InstantCommand; import edu.wpi.first.wpilibj2.command.WaitUntilCommand; import frc.robot.subsystems.elevator.Elevator.ElevatorPosition; -import frc.robot.subsystems.multisubsystemcommands.MultiSubsystemCommands.GamepieceMode; public final class ElevatorCommands { private Elevator _elevator; @@ -14,37 +13,72 @@ public ElevatorCommands(Elevator elevator) { _elevator = elevator; } - public Command runElevatorPID() { - return Commands.run(() -> { - _elevator.runMotorsWithPID(); - } ); + public Command calibrateElevator() { + return new Command() { + int spikeCounter = 0; + + @Override + public void initialize() { + spikeCounter = 0; + _elevator.runMotorsDown(); + _elevator.setIsCalibrated(false); + } + + @Override + public void execute() { + if (_elevator.isAboveCurrentLimit()) { + spikeCounter++; + } + } + + @Override + public void end(boolean interrupted) { + _elevator.resetEncoders(); + _elevator.stopMotors(); + _elevator.setIsCalibrated(true); + } + + @Override + public boolean isFinished() { + return spikeCounter >= 3; + } + }; } public Command decrementElevatorPosition() { return new InstantCommand( - () -> { - _elevator.decrementElevatorPosition(); - - } , _elevator); + () -> { + _elevator.decrementElevatorPosition(); + + }, _elevator) + .withName("DecrementElevator"); } - - public Command incrementElevatorPosition(){ + + public Command incrementElevatorPosition() { return new InstantCommand( - () -> { - _elevator.incrementElevatorPosition(); - - }, _elevator); - } + () -> { + _elevator.incrementElevatorPosition(); + + }, _elevator) + .withName("IncrementElevator"); + } public Command setElevatorSetpoint(ElevatorPosition setpoint) { return new InstantCommand( - () -> { - _elevator.setSetpoint(setpoint); - }, _elevator); + () -> { + _elevator.setSetpoint(setpoint); + }); } public Command waitUntilAtSetpoint() { return new WaitUntilCommand(_elevator::isAtSetpoint); } -} + public Command moveElevator(ElevatorPosition pos) { + return setElevatorSetpoint(pos).andThen(waitUntilAtSetpoint()); + } + + public Command resetElevatorPID() { + return Commands.runOnce(() -> _elevator.resetPID()); + } +} diff --git a/src/main/java/frc/robot/subsystems/elevator/ElevatorIO.java b/src/main/java/frc/robot/subsystems/elevator/io/ElevatorIO.java similarity index 94% rename from src/main/java/frc/robot/subsystems/elevator/ElevatorIO.java rename to src/main/java/frc/robot/subsystems/elevator/io/ElevatorIO.java index a681447..e354123 100644 --- a/src/main/java/frc/robot/subsystems/elevator/ElevatorIO.java +++ b/src/main/java/frc/robot/subsystems/elevator/io/ElevatorIO.java @@ -1,4 +1,4 @@ -package frc.robot.subsystems.elevator; +package frc.robot.subsystems.elevator.io; import org.littletonrobotics.junction.AutoLog; diff --git a/src/main/java/frc/robot/subsystems/elevator/RealElevatorIO.java b/src/main/java/frc/robot/subsystems/elevator/io/RealElevatorIO.java similarity index 63% rename from src/main/java/frc/robot/subsystems/elevator/RealElevatorIO.java rename to src/main/java/frc/robot/subsystems/elevator/io/RealElevatorIO.java index 5986afc..cdb6536 100644 --- a/src/main/java/frc/robot/subsystems/elevator/RealElevatorIO.java +++ b/src/main/java/frc/robot/subsystems/elevator/io/RealElevatorIO.java @@ -1,4 +1,4 @@ -package frc.robot.subsystems.elevator; +package frc.robot.subsystems.elevator.io; import com.revrobotics.spark.SparkBase.PersistMode; import com.revrobotics.spark.SparkBase.ResetMode; @@ -11,8 +11,6 @@ import com.revrobotics.spark.config.SparkFlexConfig; import frc.robot.HardwareConstants.CAN; -import frc.robot.subsystems.arm.ArmIO; -import frc.robot.subsystems.elevator.ElevatorIO.ElevatorIOInputs; public class RealElevatorIO implements ElevatorIO { private SparkFlex _primaryMotor; @@ -24,26 +22,26 @@ public RealElevatorIO() { _secondaryMotor = new SparkFlex(CAN.SECONDARY_ELEVATOR_ID, MotorType.kBrushless); SparkFlexConfig primaryConfig = new SparkFlexConfig(); - primaryConfig.inverted(false); - primaryConfig.idleMode(IdleMode.kBrake); + primaryConfig.inverted(true); + primaryConfig.idleMode(IdleMode.kCoast); _primaryMotor.configure(primaryConfig, ResetMode.kResetSafeParameters, PersistMode.kPersistParameters); SparkFlexConfig secondaryConfig = new SparkFlexConfig(); - secondaryConfig.follow(CAN.PRIMARY_ELEVATOR_ID); - secondaryConfig.idleMode(IdleMode.kBrake); + secondaryConfig.follow(CAN.PRIMARY_ELEVATOR_ID, true); + secondaryConfig.idleMode(IdleMode.kCoast); _secondaryMotor.configure(secondaryConfig, ResetMode.kResetSafeParameters, PersistMode.kPersistParameters); } public void updateInputs(ElevatorIOInputs inputs) { - inputs._elevatorMotorVoltage = _primaryMotor.getAppliedOutput() * _primaryMotor.getBusVoltage(); - inputs._elevatorMotorCurrent = _primaryMotor.getOutputCurrent(); - inputs._elevatorPosition = _primaryMotor.getEncoder().getPosition(); - inputs._elevatorSpeed = _primaryMotor.get(); - inputs._elevatorVelocity = _primaryMotor.getEncoder().getVelocity(); + inputs._elevatorMotorVoltage = _secondaryMotor.getAppliedOutput() * _secondaryMotor.getBusVoltage(); + inputs._elevatorMotorCurrent = _secondaryMotor.getOutputCurrent(); + inputs._elevatorPosition = _secondaryMotor.getEncoder().getPosition(); + inputs._elevatorSpeed = _secondaryMotor.get(); + inputs._elevatorVelocity = _secondaryMotor.getEncoder().getVelocity(); } public void setElevatorSpeed(double speed) { - _primaryMotor.set(speed); + _primaryMotor.set(speed); } public void setElevatorVoltage(Voltage voltage) { @@ -51,6 +49,6 @@ public void setElevatorVoltage(Voltage voltage) { } public void resetEncoder() { - _primaryMotor.getEncoder().setPosition(0); + _secondaryMotor.getEncoder().setPosition(0); } } diff --git a/src/main/java/frc/robot/subsystems/leds/LEDs.java b/src/main/java/frc/robot/subsystems/leds/LEDs.java index 11da210..e589382 100644 --- a/src/main/java/frc/robot/subsystems/leds/LEDs.java +++ b/src/main/java/frc/robot/subsystems/leds/LEDs.java @@ -1,6 +1,7 @@ package frc.robot.subsystems.leds; import com.ctre.phoenix.led.CANdle; +import com.ctre.phoenix.led.FireAnimation; import com.ctre.phoenix.led.LarsonAnimation; import com.ctre.phoenix.led.LarsonAnimation.BounceMode; @@ -10,10 +11,15 @@ import edu.wpi.first.wpilibj2.command.SubsystemBase; import frc.robot.HardwareConstants; import frc.robot.HardwareConstants.CAN; -import frc.robot.subsystems.elevator.Elevator; +// import frc.robot.subsystems.elevator.Elevator; +// import frc.robot.subsystems.drive.Drive; +// import frc.robot.subsystems.drive.DriveCommands; import com.ctre.phoenix.led.RainbowAnimation; import com.ctre.phoenix.led.StrobeAnimation; +import com.ctre.phoenix.led.TwinkleAnimation; + +import java.util.function.BooleanSupplier; import org.littletonrobotics.junction.Logger; @@ -26,7 +32,8 @@ public class LEDs extends SubsystemBase { boolean _alreadyRunning = false; LEDAnimation _currentAnimation = LEDAnimation.None; - Elevator _elevator; + // Drive _drive; + // Elevator _elevator; public enum LEDAnimation { None(null, null, 0), @@ -43,9 +50,9 @@ public enum LEDAnimation { PartyMode(null, new RainbowAnimation(100, 1, _numLEDs), 3), - Bounce(null, new LarsonAnimation(0, 255, 0), 3), + Bounce(null, new TwinkleAnimation(0, 255, 0), 3), - SolidTeal(new LEDColor(0, 225, 174), null, 0), + SolidTeal(new LEDColor(0, 225, 100), null, 0), SolidCoral(new LEDColor(255, 80, 15), null, 0), @@ -87,11 +94,7 @@ public void runAnimation(LEDAnimation animation) { _candle.clearAnimation(0); _candle.setLEDs(0, 0, 0); _candle.animate(animation.getAnimation()); - } else if (animation == LEDAnimation.SolidRed) { - _candle.clearAnimation(0); - LEDColor color = animation.getColor(); - _candle.setLEDs(color.getR(), color.getG(), color.getB(),0, 0, - (int) Math.round(_numLEDs/_elevator.getElevatorMaxHeight() * _elevator.getCurrentPosInches())); + } else if (animation.getAnimation() == null) { LEDColor color = animation.getColor(); _candle.clearAnimation(0); @@ -156,6 +159,17 @@ public void robotHasClimbed() { } } + public void aligningWithReefAnimation(BooleanSupplier closeToReef) { + // If close enough to reef: + if (closeToReef.getAsBoolean()) { + runAnimation(LEDAnimation.SolidGreen); + } + + else { + runAnimation(LEDAnimation.SolidRed); + } + } + public void disabledAnimation1() { if (!_alreadyRunning) { runAnimation(LEDAnimation.PartyMode); @@ -163,6 +177,13 @@ public void disabledAnimation1() { } } + public void disabledAnimation2() { + if (!_alreadyRunning) { + runAnimation(LEDAnimation.Bounce); + _alreadyRunning = false; + } + } + public void reset() { _candle.clearAnimation(0); _alreadyRunning = false; diff --git a/src/main/java/frc/robot/subsystems/leds/LEDsCommands.java b/src/main/java/frc/robot/subsystems/leds/LEDsCommands.java index 1649a9d..315355b 100644 --- a/src/main/java/frc/robot/subsystems/leds/LEDsCommands.java +++ b/src/main/java/frc/robot/subsystems/leds/LEDsCommands.java @@ -1,105 +1,146 @@ package frc.robot.subsystems.leds; +import java.util.function.BooleanSupplier; + import edu.wpi.first.wpilibj.DriverStation; import edu.wpi.first.wpilibj2.command.Command; +import edu.wpi.first.wpilibj2.command.RunCommand; import edu.wpi.first.wpilibj2.command.StartEndCommand; import edu.wpi.first.wpilibj2.command.Subsystem; import frc.robot.subsystems.leds.LEDs; //import frc.robot.subsystems.elevator.Elevator; public class LEDsCommands { - private LEDs _leds; + private static LEDs _leds; public LEDsCommands(LEDs leds) { _leds = leds; } - //Runs when intake button is pushed + // Runs when intake button is pushed public Command intaking() { - return new StartEndCommand( + return new StartEndCommand( () -> { _leds.intaking(); - }, + }, () -> { _leds.reset(); }, - _leds); + _leds); } - //Runs when we have just acquired a piece + // Runs when we have just acquired a piece public Command hasPiece() { return new StartEndCommand( - () -> { - _leds.hasPiece(); - }, - () -> { - _leds.reset(); - }, - _leds).withTimeout(3); + () -> { + _leds.hasPiece(); + }, + () -> { + _leds.reset(); + }, + _leds).withTimeout(3); } - + // Runs when we have no gamepiece and we are toggled to pick up coral public Command pickingUpCoral() { return new StartEndCommand( - () -> { - _leds.pickingUpCoral(); - }, - () -> { - _leds.reset(); - }, - _leds); + () -> { + _leds.pickingUpCoral(); + }, + () -> { + _leds.reset(); + }, + _leds); } // Runs when we have no gamepiece and we are toggled to pick up coral public Command pickingUpAlgae() { return new StartEndCommand( - () -> { - _leds.pickingUpAlgae(); - }, - () -> { - _leds.reset(); - }, - _leds); + () -> { + _leds.pickingUpAlgae(); + }, + () -> { + _leds.reset(); + }, + _leds); } - - //We have a piece and hasPiece animation has already run + + // We have a piece and hasPiece animation has already run public Command elevatorOrArmIsMoving() { return new StartEndCommand( - () -> { - _leds.elevatorOrArmIsMoving(); - }, - () -> { - _leds.reset(); - }, - _leds); + () -> { + _leds.elevatorOrArmIsMoving(); + }, + () -> { + _leds.reset(); + }, + _leds); } - //Runs when robot has finished climbing + // Runs when robot has finished climbing public Command robotHasClimbed() { return new StartEndCommand( - () -> { - _leds.robotHasClimbed(); - }, - () -> { - _leds.reset(); - }, - _leds); + () -> { + _leds.robotHasClimbed(); + }, + () -> { + _leds.reset(); + }, + _leds); } public Command disabledAnimation1() { return new StartEndCommand( - () -> { - _leds.disabledAnimation1(); - }, - () -> { - _leds.reset(); - }, - _leds) { - @Override - public boolean runsWhenDisabled() { - return true; - } - }; + () -> { + _leds.disabledAnimation1(); + }, + () -> { + _leds.reset(); + }, + _leds) { + @Override + public boolean runsWhenDisabled() { + return true; + } + }; + } + + public Command disabledAnimation2() { + return new StartEndCommand( + () -> { + _leds.disabledAnimation2(); + }, + () -> { + _leds.reset(); + }, + _leds) { + @Override + public boolean runsWhenDisabled() { + return true; + } + }; + } + + // public Command aligningWithReef(BooleanSupplier closeToReef) { + // return new StartEndCommand( + // () -> { + // _leds.aligningWithReefAnimation(closeToReef); + // }, + // () -> { + // _leds.reset(); + // }, + // _leds).repeatedly(); //{ + // // @Override + // // public boolean runsWhenDisabled() { + // // return false; + // // } + // // }; + // } + + public Command aligningWithReef(BooleanSupplier closeToReef) { + return new RunCommand( + () -> _leds.aligningWithReefAnimation(closeToReef), + _leds).finallyDo((interrupted) -> _leds.reset()); } } \ No newline at end of file diff --git a/src/main/java/frc/robot/subsystems/multisubsystemcommands/MultiSubsystemCommands.java b/src/main/java/frc/robot/subsystems/multisubsystemcommands/MultiSubsystemCommands.java index e679f13..019f463 100644 --- a/src/main/java/frc/robot/subsystems/multisubsystemcommands/MultiSubsystemCommands.java +++ b/src/main/java/frc/robot/subsystems/multisubsystemcommands/MultiSubsystemCommands.java @@ -1,12 +1,16 @@ package frc.robot.subsystems.multisubsystemcommands; +import java.util.function.DoubleSupplier; import java.util.function.Supplier; import edu.wpi.first.wpilibj2.command.Command; import edu.wpi.first.wpilibj2.command.Commands; import edu.wpi.first.wpilibj2.command.InstantCommand; +import edu.wpi.first.wpilibj2.command.WaitCommand; import frc.robot.subsystems.arm.Arm; import frc.robot.subsystems.arm.Arm.ArmPosition; +import frc.robot.subsystems.climber.Climber; +import frc.robot.subsystems.climber.ClimberCommands; import frc.robot.subsystems.arm.ArmCommands; import frc.robot.subsystems.elevator.Elevator; import frc.robot.subsystems.elevator.ElevatorCommands; @@ -15,12 +19,13 @@ public class MultiSubsystemCommands { public enum OverallPosition { Stow(ElevatorPosition.Stow, ArmPosition.Stow), - Loading(ElevatorPosition.Stow, ArmPosition.Loading_Coral), + Coral_Loading(ElevatorPosition.Stow, ArmPosition.Loading), + Algae_Loading_L2(ElevatorPosition.L2, ArmPosition.Loading), + Algae_Loading_L3(ElevatorPosition.L3, ArmPosition.Loading), L1(ElevatorPosition.L1, ArmPosition.Stow), L2(ElevatorPosition.L2, ArmPosition.Stow), L3(ElevatorPosition.L3, ArmPosition.Stow), - L4(ElevatorPosition.L4, ArmPosition.Stow), - L4_Score(ElevatorPosition.L4, ArmPosition.L4_Score); + L4(ElevatorPosition.L4, ArmPosition.L4_Score); ElevatorPosition _elevatorSetpoint; ArmPosition _armSetpoint; @@ -57,11 +62,19 @@ public MultiSubsystemCommands(Elevator elevator, Arm arm, ElevatorCommands eleva _armCommands = armCommands; } - public Command setOverallSetpoint(OverallPosition setpoint) { - return _elevatorCommands.setElevatorSetpoint(setpoint.getElevatorPosition()) - .alongWith(_armCommands.setArmPosition(setpoint.getArmPosition())) - .unless(() -> !canMoveToPos(_elevator.getCurrentPos(), setpoint.getElevatorPosition(), - _arm.getCurrentPos(), setpoint.getArmPosition())); + public Command calibrate() { + return _armCommands.setArmPosition(ArmPosition.Stow) + .andThen(_elevatorCommands.calibrateElevator()) + .andThen(_elevatorCommands.setElevatorSetpoint(ElevatorPosition.Stow)) + .withName("Calibrate"); + } + + public Command moveToPosition(OverallPosition setpoint) { + return _armCommands.moveArm(ArmPosition.Transient) + .andThen(_elevatorCommands.moveElevator(setpoint.getElevatorPosition())) + .unless(() -> _elevator.getCurrentPos() == setpoint.getElevatorPosition()) + .andThen(_armCommands.moveArm(setpoint.getArmPosition())) + .finallyDo(() -> System.out.println("MOVED TO POS")); } public Command setGamepieceMode(GamepieceMode mode) { @@ -69,142 +82,35 @@ public Command setGamepieceMode(GamepieceMode mode) { () -> { _elevator.setCurrentMode(mode); _arm.setCurrentMode(mode); - }, _elevator, _arm); - } - - public Command waitForOverallMechanism() { - return _elevatorCommands.waitUntilAtSetpoint() - .alongWith(_armCommands.waitUntilAtSetpoint()); - } - - private Command score(OverallPosition setpoint) { - if (setpoint == OverallPosition.L4) { - return setOverallSetpoint(OverallPosition.L4_Score) - .andThen(waitForOverallMechanism()) - .andThen(_armCommands.spit()) - .andThen(setOverallSetpoint(OverallPosition.L4)) - .andThen(waitForOverallMechanism()); - } else { - return _armCommands.spit(); - } - } - - public Command scoreGamepieceAtPosition(Supplier setpoint) { - return scoreGamepieceAtPosition(setpoint.get()); + }) + .withName("SetGamepieceMode"); } public Command scoreGamepieceAtPosition(OverallPosition setpoint) { - if (setpoint == OverallPosition.Stow || setpoint == OverallPosition.Loading - || setpoint == OverallPosition.L4_Score) { - throw new RuntimeException("scoreGamepieceAtPosition cannot run to stow,loading,or L4_score"); - } - return setOverallSetpoint(setpoint) - .andThen(waitForOverallMechanism()) - .andThen(score(setpoint)) - .andThen(setOverallSetpoint(OverallPosition.Stow)); - } - - public Command loadGamepiece() { - return Commands.either(loadAlgae(), loadCoral(), () -> _arm.getCurrentMode() == GamepieceMode.ALGAE); + return moveToPosition(setpoint) + .andThen(_armCommands.spit()) + .withName("ScoreAtPosition"); } public Command loadCoral() { - return setOverallSetpoint(OverallPosition.Loading) - .andThen(waitForOverallMechanism()) + return moveToPosition(OverallPosition.Coral_Loading) .andThen(_armCommands.intake()) - .andThen(setOverallSetpoint(OverallPosition.Stow)) - .andThen(_armCommands.moveGamepieceToLightSensor()) - .unless(() -> !canMoveToPos(_elevator.getCurrentPos(), ElevatorPosition.Stow, - _arm.getCurrentPos(), ArmPosition.Loading_Coral)); - + .withName("LoadCoral"); } - public Command loadAlgae() { - return setOverallSetpoint(OverallPosition.Loading) - .andThen(waitForOverallMechanism()) - .andThen(_armCommands.intake()) - .andThen(setOverallSetpoint(OverallPosition.Stow)) - .unless(() -> !canMoveToPos(_elevator.getCurrentPos(), ElevatorPosition.L2, - _arm.getCurrentPos(), ArmPosition.Loading_Algae)); + public Command loadCoralAuto() { + return moveToPosition(OverallPosition.Coral_Loading) + .andThen(_armCommands.intakeCoralAuto()); } - public boolean canMoveToPos(ElevatorPosition currentElevator, ElevatorPosition desiredElevator, - ArmPosition currentArm, ArmPosition desiredArm) { - boolean canMoveArm = false; - boolean canMoveElevator = false; - - if (_arm.getCurrentMode() == GamepieceMode.CORAL) { - switch (currentElevator) { - case L1: - case L2: - case L3: - canMoveArm = (desiredArm != ArmPosition.L4_Score) && (desiredArm != ArmPosition.Loading_Coral); - break; - case L4: - canMoveArm = (desiredArm != ArmPosition.Loading_Coral); - break; - case Stow: - canMoveArm = (desiredArm != ArmPosition.L4_Score); - break; - default: - canMoveArm = false; - break; - } - - switch (desiredElevator) { - case L1: - case L2: - case L3: - canMoveElevator = (currentArm != ArmPosition.L4_Score) && (currentArm != ArmPosition.Loading_Coral); - break; - case L4: - canMoveElevator = (currentArm != ArmPosition.Loading_Coral); - break; - case Stow: - canMoveElevator = (currentArm != ArmPosition.L4_Score); - break; - default: - canMoveElevator = false; - break; - } - } else { - switch (currentElevator) { - case L1: - case L4: - canMoveArm = false; - break; - case L2: - case L3: - canMoveArm = desiredArm != ArmPosition.Algae_Score; - break; - case Stow: - canMoveArm = desiredArm != ArmPosition.Loading_Algae; - break; - default: - canMoveArm = false; - break; - } - - switch (desiredElevator) { - case L1: - case L4: - canMoveElevator = false; - break; - case L2: - case L3: - canMoveElevator = currentArm != ArmPosition.Algae_Score; - break; - case Stow: - canMoveElevator = currentArm != ArmPosition.Loading_Algae; - break; - default: - canMoveElevator = false; - break; - } + public Command loadAlgae(OverallPosition position) { + if (position != OverallPosition.Algae_Loading_L2 && position != OverallPosition.Algae_Loading_L3) { + throw new IllegalArgumentException("Can Only Load Algae @ L2 or L3"); } - System.out.println("Arm: " + canMoveArm + " Elevator: " + canMoveElevator); - - return canMoveArm && canMoveElevator; + return moveToPosition(position) + .alongWith(_armCommands.intake()) + .andThen(_armCommands.setArmPosition(ArmPosition.Stow) + .withName("LoadAlgae")); } } \ No newline at end of file diff --git a/src/main/java/frc/robot/subsystems/presets/Preset.java b/src/main/java/frc/robot/subsystems/presets/Preset.java deleted file mode 100644 index cf0a89f..0000000 --- a/src/main/java/frc/robot/subsystems/presets/Preset.java +++ /dev/null @@ -1,61 +0,0 @@ -package frc.robot.subsystems.presets; - -import edu.wpi.first.wpilibj2.command.Command; -import edu.wpi.first.wpilibj2.command.InstantCommand; -import frc.robot.subsystems.multisubsystemcommands.MultiSubsystemCommands.OverallPosition; - -public class Preset { - public enum ReefSide { - Left, - Right; - } - - private OverallPosition _level = OverallPosition.L1; - private ReefSide _side = ReefSide.Right; - private boolean _isLevelValid = false; - private boolean _isSideValid = false; - - private void setPresetLevel(OverallPosition level) { - if (level == OverallPosition.Stow || level == OverallPosition.Loading || level == OverallPosition.L4_Score) { - throw new RuntimeException("Invalid Preset Level/Position"); - } - - _level = level; - _isLevelValid = true; - } - - private void setPresetSide(ReefSide side) { - _side = side; - _isSideValid = true; - } - - public OverallPosition getLevel() { - return _level; - } - - public ReefSide getSide() { - return _side; - } - - public boolean isPresetValid() { - return _isLevelValid && _isSideValid; - } - - public Command setPresetLevelCommand(OverallPosition level) { - return new InstantCommand( - () -> setPresetLevel(level)); - } - - public Command setPresetSideCommand(ReefSide side) { - return new InstantCommand( - () -> setPresetSide(side)); - } - - public Command resetPreset() { - return new InstantCommand( - () -> { - _isLevelValid = false; - _isSideValid = false; - }); - } -} \ No newline at end of file diff --git a/src/main/java/frc/robot/subsystems/vision/Vision.java b/src/main/java/frc/robot/subsystems/vision/Vision.java new file mode 100644 index 0000000..b379897 --- /dev/null +++ b/src/main/java/frc/robot/subsystems/vision/Vision.java @@ -0,0 +1,205 @@ +// Code modified from AdvantageKit Vision Template (v4.0.1): +// https://github.com/Mechanical-Advantage/AdvantageKit/releases +// +// Copyright 2021-2025 FRC 6328 +// http://github.com/Mechanical-Advantage +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 3 as published by the Free Software Foundation or +// available in the root directory of this project. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +package frc.robot.subsystems.vision; + +import static frc.robot.subsystems.vision.VisionConstants.*; + +import edu.wpi.first.math.Matrix; +import edu.wpi.first.math.VecBuilder; +import edu.wpi.first.math.geometry.Pose2d; +import edu.wpi.first.math.geometry.Pose3d; +import edu.wpi.first.math.geometry.Rotation2d; +import edu.wpi.first.math.numbers.N1; +import edu.wpi.first.math.numbers.N3; +import edu.wpi.first.wpilibj.Alert; +import edu.wpi.first.wpilibj.Alert.AlertType; +import edu.wpi.first.wpilibj2.command.SubsystemBase; +import frc.robot.subsystems.vision.VisionIO.PoseObservationType; +import java.util.LinkedList; +import java.util.List; +import org.littletonrobotics.junction.Logger; +import java.util.List; + + +public class Vision extends SubsystemBase { + private final VisionConsumer consumer; + private final VisionIO[] io; + private final VisionIOInputsAutoLogged[] inputs; + private final Alert[] disconnectedAlerts; + public boolean visionHasTarget = false; + private boolean seesThisTarget = false; + + public Vision(VisionConsumer consumer, VisionIO... io) { + this.consumer = consumer; + this.io = io; + + // Initialize inputs + this.inputs = new VisionIOInputsAutoLogged[io.length]; + for (int i = 0; i < inputs.length; i++) { + inputs[i] = new VisionIOInputsAutoLogged(); + } + + // Initialize disconnected alerts + this.disconnectedAlerts = new Alert[io.length]; + for (int i = 0; i < inputs.length; i++) { + disconnectedAlerts[i] = + new Alert( + "Vision camera " + Integer.toString(i) + " is disconnected.", AlertType.kWarning); + } + } + + /** + * Returns the X angle to the best target, which can be used for simple servoing with vision. + * + * @param cameraIndex The index of the camera to use. + */ + public Rotation2d getTargetX(int cameraIndex) { + return inputs[cameraIndex].latestTargetObservation.tx(); + } + + @Override + public void periodic() { + for (int i = 0; i < io.length; i++) { + io[i].updateInputs(inputs[i]); + Logger.processInputs("Vision/Camera" + Integer.toString(i), inputs[i]); + } + + // Initialize logging values + List allTagPoses = new LinkedList<>(); + List allRobotPoses = new LinkedList<>(); + List allRobotPosesAccepted = new LinkedList<>(); + List allRobotPosesRejected = new LinkedList<>(); + + // Loop over cameras + for (int cameraIndex = 0; cameraIndex < io.length; cameraIndex++) { + // Update disconnected alert + disconnectedAlerts[cameraIndex].set(!inputs[cameraIndex].connected); + + // Initialize logging values + List tagPoses = new LinkedList<>(); + List robotPoses = new LinkedList<>(); + List robotPosesAccepted = new LinkedList<>(); + List robotPosesRejected = new LinkedList<>(); + + // Add tag poses + for (int tagId : inputs[cameraIndex].tagIds) { + var tagPose = aprilTagLayout.getTagPose(tagId); + if (tagPose.isPresent() && !rejectedTags.contains(tagId)) { + tagPoses.add(tagPose.get()); + seesThisTarget = true; + } + } + + // Report to visionhas Target whether or not vision sees at least one tag + if (seesThisTarget) { + visionHasTarget = true; + // Now reset seesThisTarget for next periodic loop + seesThisTarget = false; + } else { + visionHasTarget = false; + } + + // Loop over pose observations + for (var observation : inputs[cameraIndex].poseObservations) { + // Check whether to reject pose + boolean rejectPose = + observation.tagCount() == 0 // Must have at least one tag + || (observation.tagCount() == 1 + && observation.ambiguity() > maxAmbiguity) // Cannot be high ambiguity + || Math.abs(observation.pose().getZ()) + > maxZError // Must have realistic Z coordinate + + // Must be within the field boundaries + || observation.pose().getX() < 0.0 + || observation.pose().getX() > aprilTagLayout.getFieldLength() + || observation.pose().getY() < 0.0 + || observation.pose().getY() > aprilTagLayout.getFieldWidth(); + + // Add pose to log + robotPoses.add(observation.pose()); + if (rejectPose) { + robotPosesRejected.add(observation.pose()); + } else { + robotPosesAccepted.add(observation.pose()); + } + + // Skip if rejected + if (rejectPose) { + continue; + } + + // Calculate standard deviations + double stdDevFactor = + Math.pow(observation.averageTagDistance(), 2.0) / observation.tagCount(); + double linearStdDev = linearStdDevBaseline * stdDevFactor; + double angularStdDev = angularStdDevBaseline * stdDevFactor; + if (observation.type() == PoseObservationType.MEGATAG_2) { + linearStdDev *= linearStdDevMegatag2Factor; + angularStdDev *= angularStdDevMegatag2Factor; + } + if (cameraIndex < cameraStdDevFactors.length) { + linearStdDev *= cameraStdDevFactors[cameraIndex]; + angularStdDev *= cameraStdDevFactors[cameraIndex]; + } + + // Send vision observation + consumer.accept( + observation.pose().toPose2d(), + observation.timestamp(), + VecBuilder.fill(linearStdDev, linearStdDev, angularStdDev)); + } + + // Log camera datadata + Logger.recordOutput( + "Vision/Camera" + Integer.toString(cameraIndex) + "/TagPoses", + tagPoses.toArray(new Pose3d[tagPoses.size()])); + Logger.recordOutput( + "Vision/Camera" + Integer.toString(cameraIndex) + "/RobotPoses", + robotPoses.toArray(new Pose3d[robotPoses.size()])); + Logger.recordOutput( + "Vision/Camera" + Integer.toString(cameraIndex) + "/RobotPosesAccepted", + robotPosesAccepted.toArray(new Pose3d[robotPosesAccepted.size()])); + Logger.recordOutput( + "Vision/Camera" + Integer.toString(cameraIndex) + "/RobotPosesRejected", + robotPosesRejected.toArray(new Pose3d[robotPosesRejected.size()])); + allTagPoses.addAll(tagPoses); + allRobotPoses.addAll(robotPoses); + allRobotPosesAccepted.addAll(robotPosesAccepted); + allRobotPosesRejected.addAll(robotPosesRejected); + } + + // Log summary data + Logger.recordOutput( + "Vision/Summary/TagPoses", allTagPoses.toArray(new Pose3d[allTagPoses.size()])); + Logger.recordOutput( + "Vision/Summary/RobotPoses", allRobotPoses.toArray(new Pose3d[allRobotPoses.size()])); + Logger.recordOutput( + "Vision/Summary/RobotPosesAccepted", + allRobotPosesAccepted.toArray(new Pose3d[allRobotPosesAccepted.size()])); + Logger.recordOutput( + "Vision/Summary/RobotPosesRejected", + allRobotPosesRejected.toArray(new Pose3d[allRobotPosesRejected.size()])); + } + + @FunctionalInterface + public static interface VisionConsumer { + public void accept( + Pose2d visionRobotPoseMeters, + double timestampSeconds, + Matrix visionMeasurementStdDevs); + } +} diff --git a/src/main/java/frc/robot/subsystems/vision/VisionConstants.java b/src/main/java/frc/robot/subsystems/vision/VisionConstants.java new file mode 100644 index 0000000..f0bc07e --- /dev/null +++ b/src/main/java/frc/robot/subsystems/vision/VisionConstants.java @@ -0,0 +1,85 @@ +// Code modified from AdvantageKit Vision Template (v4.0.1): +// https://github.com/Mechanical-Advantage/AdvantageKit/releases +// +// Copyright 2021-2025 FRC 6328 +// http://github.com/Mechanical-Advantage +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 3 as published by the Free Software Foundation or +// available in the root directory of this project. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +package frc.robot.subsystems.vision; + +import edu.wpi.first.apriltag.AprilTagFieldLayout; +import edu.wpi.first.apriltag.AprilTagFields; +import edu.wpi.first.math.geometry.Rotation3d; +import edu.wpi.first.math.geometry.Transform3d; +import edu.wpi.first.math.util.Units; +import java.util.List; +import java.util.Arrays; + +public class VisionConstants { + // AprilTag layout + public static AprilTagFieldLayout aprilTagLayout = + AprilTagFieldLayout.loadField(AprilTagFields.k2025ReefscapeAndyMark); + + // Camera names, must match names configured on coprocessor + + // New cameras for 2025 season are 5,6,7,8 + + public static String camera5Name = "photoncamera_5"; + public static String camera6Name = "photoncamera_6"; + public static String camera7Name = "photoncamera_7"; + public static String camera8Name = "photoncamera_8"; + + // Robot to camera transforms + // (Not used by Limelight, configure in web UI instead) + + // Note: 0.0254 multiplier converts inches to meters + + // Camera 5 + // Front right camera + public static Transform3d robotToCamera5 = + new Transform3d(Units.inchesToMeters(9.287), Units.inchesToMeters(-10.9704),Units.inchesToMeters(7.9167), + new Rotation3d(0.0, Units.degreesToRadians(-15), Units.degreesToRadians(30))); + + // Camera 6 + // Front left camera + public static Transform3d robotToCamera6 = + new Transform3d(Units.inchesToMeters(9.287), Units.inchesToMeters(10.9704), Units.inchesToMeters(7.9167), + new Rotation3d(0.0, Units.degreesToRadians(-15), Units.degreesToRadians(-30))); + + // Basic filtering thresholds + public static double maxAmbiguity = 0.3; + public static double maxZError = 0.75; + + // Standard deviation baselines, for 1 meter distance and 1 tag + // (Adjusted automatically based on distance and # of tags) + public static double linearStdDevBaseline = 0.02; // Meters + public static double angularStdDevBaseline = 0.06; // Radians + + // Standard deviation multipliers for each camera + // (Adjust to trust some cameras more than others) + public static double[] cameraStdDevFactors = + new double[] { + 1.0, // Camera 5 + 2.0, // Camera 6 + 1.0, // Camera 7 + 1.0 // Camera 8 + }; + + + // List of tags that can be rejected if we want to align solely on the reef + public static List rejectedTags = Arrays.asList(2, 3, 4, 5, 14, 15, 16); + + // Multipliers to apply for MegaTag 2 observations + public static double linearStdDevMegatag2Factor = 0.5; // More stable than full 3D solve + public static double angularStdDevMegatag2Factor = + Double.POSITIVE_INFINITY; // Ignore rotation data +} diff --git a/src/main/java/frc/robot/subsystems/vision/VisionIO.java b/src/main/java/frc/robot/subsystems/vision/VisionIO.java new file mode 100644 index 0000000..b1e70f6 --- /dev/null +++ b/src/main/java/frc/robot/subsystems/vision/VisionIO.java @@ -0,0 +1,52 @@ +// Code modified from AdvantageKit Vision Template (v4.0.1): +// https://github.com/Mechanical-Advantage/AdvantageKit/releases +// +// Copyright 2021-2025 FRC 6328 +// http://github.com/Mechanical-Advantage +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 3 as published by the Free Software Foundation or +// available in the root directory of this project. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +package frc.robot.subsystems.vision; + +import edu.wpi.first.math.geometry.Pose3d; +import edu.wpi.first.math.geometry.Rotation2d; +import org.littletonrobotics.junction.AutoLog; + +public interface VisionIO { + @AutoLog + public static class VisionIOInputs { + public boolean connected = false; + public TargetObservation latestTargetObservation = + new TargetObservation(new Rotation2d(), new Rotation2d()); + public PoseObservation[] poseObservations = new PoseObservation[0]; + public int[] tagIds = new int[0]; + } + + /** Represents the angle to a simple target, not used for pose estimation. */ + public static record TargetObservation(Rotation2d tx, Rotation2d ty) {} + + /** Represents a robot pose sample used for pose estimation. */ + public static record PoseObservation( + double timestamp, + Pose3d pose, + double ambiguity, + int tagCount, + double averageTagDistance, + PoseObservationType type) {} + + public static enum PoseObservationType { + MEGATAG_1, + MEGATAG_2, + PHOTONVISION + } + + public default void updateInputs(VisionIOInputs inputs) {} +} diff --git a/src/main/java/frc/robot/subsystems/vision/VisionIOLimelight.java b/src/main/java/frc/robot/subsystems/vision/VisionIOLimelight.java new file mode 100644 index 0000000..a09d102 --- /dev/null +++ b/src/main/java/frc/robot/subsystems/vision/VisionIOLimelight.java @@ -0,0 +1,159 @@ +// Code modified from AdvantageKit Vision Template (v4.0.1): +// https://github.com/Mechanical-Advantage/AdvantageKit/releases +// +// Copyright 2021-2025 FRC 6328 +// http://github.com/Mechanical-Advantage +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 3 as published by the Free Software Foundation or +// available in the root directory of this project. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +package frc.robot.subsystems.vision; + +import edu.wpi.first.math.geometry.Pose3d; +import edu.wpi.first.math.geometry.Rotation2d; +import edu.wpi.first.math.geometry.Rotation3d; +import edu.wpi.first.math.util.Units; +import edu.wpi.first.networktables.DoubleArrayPublisher; +import edu.wpi.first.networktables.DoubleArraySubscriber; +import edu.wpi.first.networktables.DoubleSubscriber; +import edu.wpi.first.networktables.NetworkTableInstance; +import edu.wpi.first.wpilibj.RobotController; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.function.Supplier; + +/** IO implementation for real Limelight hardware. */ +public class VisionIOLimelight implements VisionIO { + private final Supplier rotationSupplier; + private final DoubleArrayPublisher orientationPublisher; + + private final DoubleSubscriber latencySubscriber; + private final DoubleSubscriber txSubscriber; + private final DoubleSubscriber tySubscriber; + private final DoubleArraySubscriber megatag1Subscriber; + private final DoubleArraySubscriber megatag2Subscriber; + + /** + * Creates a new VisionIOLimelight. + * + * @param name The configured name of the Limelight. + * @param rotationSupplier Supplier for the current estimated rotation, used for MegaTag 2. + */ + public VisionIOLimelight(String name, Supplier rotationSupplier) { + var table = NetworkTableInstance.getDefault().getTable(name); + this.rotationSupplier = rotationSupplier; + orientationPublisher = table.getDoubleArrayTopic("robot_orientation_set").publish(); + latencySubscriber = table.getDoubleTopic("tl").subscribe(0.0); + txSubscriber = table.getDoubleTopic("tx").subscribe(0.0); + tySubscriber = table.getDoubleTopic("ty").subscribe(0.0); + megatag1Subscriber = table.getDoubleArrayTopic("botpose_wpiblue").subscribe(new double[] {}); + megatag2Subscriber = + table.getDoubleArrayTopic("botpose_orb_wpiblue").subscribe(new double[] {}); + } + + @Override + public void updateInputs(VisionIOInputs inputs) { + // Update connection status based on whether an update has been seen in the last 250ms + inputs.connected = + ((RobotController.getFPGATime() - latencySubscriber.getLastChange()) / 1000) < 250; + + // Update target observation + inputs.latestTargetObservation = + new TargetObservation( + Rotation2d.fromDegrees(txSubscriber.get()), Rotation2d.fromDegrees(tySubscriber.get())); + + // Update orientation for MegaTag 2 + orientationPublisher.accept( + new double[] {rotationSupplier.get().getDegrees(), 0.0, 0.0, 0.0, 0.0, 0.0}); + NetworkTableInstance.getDefault() + .flush(); // Increases network traffic but recommended by Limelight + + // Read new pose observations from NetworkTables + Set tagIds = new HashSet<>(); + List poseObservations = new LinkedList<>(); + for (var rawSample : megatag1Subscriber.readQueue()) { + if (rawSample.value.length == 0) continue; + for (int i = 11; i < rawSample.value.length; i += 7) { + tagIds.add((int) rawSample.value[i]); + } + poseObservations.add( + new PoseObservation( + // Timestamp, based on server timestamp of publish and latency + rawSample.timestamp * 1.0e-6 - rawSample.value[6] * 1.0e-3, + + // 3D pose estimate + parsePose(rawSample.value), + + // Ambiguity, using only the first tag because ambiguity isn't applicable for multitag + rawSample.value.length >= 18 ? rawSample.value[17] : 0.0, + + // Tag count + (int) rawSample.value[7], + + // Average tag distance + rawSample.value[9], + + // Observation type + PoseObservationType.MEGATAG_1)); + } + for (var rawSample : megatag2Subscriber.readQueue()) { + if (rawSample.value.length == 0) continue; + for (int i = 11; i < rawSample.value.length; i += 7) { + tagIds.add((int) rawSample.value[i]); + } + poseObservations.add( + new PoseObservation( + // Timestamp, based on server timestamp of publish and latency + rawSample.timestamp * 1.0e-6 - rawSample.value[6] * 1.0e-3, + + // 3D pose estimate + parsePose(rawSample.value), + + // Ambiguity, zeroed because the pose is already disambiguated + 0.0, + + // Tag count + (int) rawSample.value[7], + + // Average tag distance + rawSample.value[9], + + // Observation type + PoseObservationType.MEGATAG_2)); + } + + // Save pose observations to inputs object + inputs.poseObservations = new PoseObservation[poseObservations.size()]; + for (int i = 0; i < poseObservations.size(); i++) { + inputs.poseObservations[i] = poseObservations.get(i); + } + + // Save tag IDs to inputs objects + inputs.tagIds = new int[tagIds.size()]; + int i = 0; + for (int id : tagIds) { + inputs.tagIds[i++] = id; + } + } + + /** Parses the 3D pose from a Limelight botpose array. */ + private static Pose3d parsePose(double[] rawLLArray) { + return new Pose3d( + rawLLArray[0], + rawLLArray[1], + rawLLArray[2], + new Rotation3d( + Units.degreesToRadians(rawLLArray[3]), + Units.degreesToRadians(rawLLArray[4]), + Units.degreesToRadians(rawLLArray[5]))); + } +} diff --git a/src/main/java/frc/robot/subsystems/vision/VisionIOPhotonVision.java b/src/main/java/frc/robot/subsystems/vision/VisionIOPhotonVision.java new file mode 100644 index 0000000..94a8d53 --- /dev/null +++ b/src/main/java/frc/robot/subsystems/vision/VisionIOPhotonVision.java @@ -0,0 +1,149 @@ +// Code modified from AdvantageKit Vision Template (v4.0.1): +// https://github.com/Mechanical-Advantage/AdvantageKit/releases +// +// Copyright 2021-2025 FRC 6328 +// http://github.com/Mechanical-Advantage +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 3 as published by the Free Software Foundation or +// available in the root directory of this project. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +package frc.robot.subsystems.vision; + +import static frc.robot.subsystems.vision.VisionConstants.*; + +import edu.wpi.first.math.geometry.Pose3d; +import edu.wpi.first.math.geometry.Rotation2d; +import edu.wpi.first.math.geometry.Transform3d; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import org.photonvision.PhotonCamera; +import org.photonvision.PhotonPoseEstimator; +import org.photonvision.PhotonPoseEstimator.PoseStrategy; + +/** IO implementation for real PhotonVision hardware. */ +public class VisionIOPhotonVision implements VisionIO { + protected final PhotonCamera camera; + protected final Transform3d robotToCamera; + + /** + * Creates a new VisionIOPhotonVision. + * + * @param name The configured name of the camera. + * @param rotationSupplier The 3D position of the camera relative to the robot. + */ + public VisionIOPhotonVision(String name, Transform3d robotToCamera) { + camera = new PhotonCamera(name); + this.robotToCamera = robotToCamera; + } + + // NEW COMMENT + // SECTION 2 + @Override + public void updateInputs(VisionIOInputs inputs) { + + inputs.connected = camera.isConnected(); + + // Read new camera observations + Set tagIds = new HashSet<>(); + List poseObservations = new LinkedList<>(); + + for (var result : camera.getAllUnreadResults()) { + // Update latest target observation + if (result.hasTargets()) { + + inputs.latestTargetObservation = + new TargetObservation( + Rotation2d.fromDegrees(result.getBestTarget().getYaw()), + Rotation2d.fromDegrees(result.getBestTarget().getPitch())); + } else { + inputs.latestTargetObservation = new TargetObservation(new Rotation2d(), new Rotation2d()); + } + + // Add pose observation + if (result.multitagResult.isPresent()) { // Multitag result + var multitagResult = result.multitagResult.get(); + + // Calculate robot pose + Transform3d fieldToCamera = multitagResult.estimatedPose.best; + Transform3d fieldToRobot = fieldToCamera.plus(robotToCamera.inverse()); + Pose3d robotPose = new Pose3d(fieldToRobot.getTranslation(), fieldToRobot.getRotation()); + + + // Calculate average tag distance + double totalTagDistance = 0.0; + for (var target : result.targets) { + totalTagDistance += target.bestCameraToTarget.getTranslation().getNorm(); + } + + // Add tag IDs + tagIds.addAll(multitagResult.fiducialIDsUsed); + + // Add observation + poseObservations.add( + new PoseObservation( + result.getTimestampSeconds(), // Timestamp + robotPose, // 3D pose estimate + multitagResult.estimatedPose.ambiguity, // Ambiguity + multitagResult.fiducialIDsUsed.size(), // Tag count + totalTagDistance / result.targets.size(), // Average tag distance + PoseObservationType.PHOTONVISION)); // Observation type + + } else if (!result.targets.isEmpty()) { // Single tag result + var target = result.targets.get(0); + + // Calculate robot pose + var tagPose = aprilTagLayout.getTagPose(target.fiducialId); + //System.out.println("****** " + camera.getName() + " *********************************"); + //System.out.println("tagPose:" + tagPose); + if (tagPose.isPresent()) { + Transform3d fieldToTarget = + new Transform3d(tagPose.get().getTranslation(), tagPose.get().getRotation()); + //System.out.println("fieldToTarget:" + fieldToTarget); + Transform3d cameraToTarget = target.bestCameraToTarget; + //System.out.println("cameraToTarget:" + cameraToTarget); + Transform3d fieldToCamera = fieldToTarget.plus(cameraToTarget.inverse()); + //System.out.println("fieldToCamera:" + fieldToCamera); + Transform3d fieldToRobot = fieldToCamera.plus(robotToCamera.inverse()); + //System.out.println("fieldToRobot:" + fieldToRobot); + Pose3d robotPose = new Pose3d(fieldToRobot.getTranslation(), fieldToRobot.getRotation()); + //System.out.println("robotPose:" + robotPose); + + // Add tag ID + tagIds.add((short) target.fiducialId); + + // Add observation + poseObservations.add( + new PoseObservation( + result.getTimestampSeconds(), // Timestamp + robotPose, // 3D pose estimate + target.poseAmbiguity, // Ambiguity + 1, // Tag count + cameraToTarget.getTranslation().getNorm(), // Average tag distance + PoseObservationType.PHOTONVISION)); // Observation type + } + } + } + + // Save pose observations to inputs object + inputs.poseObservations = new PoseObservation[poseObservations.size()]; + for (int i = 0; i < poseObservations.size(); i++) { + inputs.poseObservations[i] = poseObservations.get(i); + } + + // Save tag IDs to inputs objects + inputs.tagIds = new int[tagIds.size()]; + int i = 0; + for (int id : tagIds) { + inputs.tagIds[i++] = id; + } + } +} diff --git a/src/main/java/frc/robot/subsystems/vision/VisionIOPhotonVisionSim.java b/src/main/java/frc/robot/subsystems/vision/VisionIOPhotonVisionSim.java new file mode 100644 index 0000000..a0fd43c --- /dev/null +++ b/src/main/java/frc/robot/subsystems/vision/VisionIOPhotonVisionSim.java @@ -0,0 +1,63 @@ +// Code modified from AdvantageKit Vision Template (v4.0.1): +// https://github.com/Mechanical-Advantage/AdvantageKit/releases +// +// Copyright 2021-2025 FRC 6328 +// http://github.com/Mechanical-Advantage +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 3 as published by the Free Software Foundation or +// available in the root directory of this project. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +package frc.robot.subsystems.vision; + +import static frc.robot.subsystems.vision.VisionConstants.aprilTagLayout; + +import edu.wpi.first.math.geometry.Pose2d; +import edu.wpi.first.math.geometry.Transform3d; +import java.util.function.Supplier; +import org.photonvision.simulation.PhotonCameraSim; +import org.photonvision.simulation.SimCameraProperties; +import org.photonvision.simulation.VisionSystemSim; + +/** IO implementation for physics sim using PhotonVision simulator. */ +public class VisionIOPhotonVisionSim extends VisionIOPhotonVision { + private static VisionSystemSim visionSim; + + private final Supplier poseSupplier; + private final PhotonCameraSim cameraSim; + + /** + * Creates a new VisionIOPhotonVisionSim. + * + * @param name The name of the camera. + * @param poseSupplier Supplier for the robot pose to use in simulation. + */ + public VisionIOPhotonVisionSim( + String name, Transform3d robotToCamera, Supplier poseSupplier) { + super(name, robotToCamera); + this.poseSupplier = poseSupplier; + + // Initialize vision sim + if (visionSim == null) { + visionSim = new VisionSystemSim("main"); + visionSim.addAprilTags(aprilTagLayout); + } + + // Add sim camera + var cameraProperties = new SimCameraProperties(); + cameraSim = new PhotonCameraSim(camera, cameraProperties); + visionSim.addCamera(cameraSim, robotToCamera); + } + + @Override + public void updateInputs(VisionIOInputs inputs) { + visionSim.update(poseSupplier.get()); + super.updateInputs(inputs); + } +} diff --git a/src/main/java/frc/robot/util/LoggedTunableNumber.java b/src/main/java/frc/robot/util/LoggedTunableNumber.java new file mode 100644 index 0000000..5574778 --- /dev/null +++ b/src/main/java/frc/robot/util/LoggedTunableNumber.java @@ -0,0 +1,133 @@ +// Copyright (c) 2023 FRC 6328 +// http://github.com/Mechanical-Advantage +// +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file at +// the root directory of this project. + +package frc.robot.util; + +import frc.robot.HardwareConstants; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.DoubleSupplier; +import org.littletonrobotics.junction.networktables.LoggedNetworkNumber; + +/** + * Class for a tunable number. Gets value from dashboard in tuning mode, returns default if not or + * value not in dashboard. + */ +@SuppressWarnings("UnusedVariable") +public class LoggedTunableNumber implements DoubleSupplier { + private static final String tableKey = "TunableNumbers"; + + private final String key; + private boolean hasDefault = false; + private double defaultValue; + private LoggedNetworkNumber dashboardNumber; + private Map lastHasChangedValues = new HashMap<>(); + + /** + * Create a new LoggedTunableNumber + * + * @param dashboardKey Key on dashboard + */ + public LoggedTunableNumber(String dashboardKey) + { + this.key = tableKey + "/" + dashboardKey; + } + + /** + * Create a new LoggedTunableNumber with the default value + * + * @param dashboardKey Key on dashboard + * @param defaultValue Default value + */ + public LoggedTunableNumber(String dashboardKey, double defaultValue) + { + this(dashboardKey); + initDefault(defaultValue); + } + + /** + * Set the default value of the number. The default value can only be set once. + * + * @param defaultValue The default value + */ + public void initDefault(double defaultValue) + { + if (!hasDefault) { + hasDefault = true; + this.defaultValue = defaultValue; + if (HardwareConstants.tuningMode) { + dashboardNumber = new LoggedNetworkNumber(key, defaultValue); + } + } + } + + /** + * Get the current value, from dashboard if available and in tuning mode. + * + * @return The current value + */ + public double get() + { + if (!hasDefault) { + return 0.0; + } else { + return HardwareConstants.tuningMode ? dashboardNumber.get() : defaultValue; + } + } + + /** + * Checks whether the number has changed since our last check + * + * @param id Unique identifier for the caller to avoid conflicts when shared between multiple + * objects. Recommended approach is to pass the result of "hashCode()" + * @return True if the number has changed since the last time this method was called, false + * otherwise. + */ + public boolean hasChanged(int id) + { + double currentValue = get(); + Double lastValue = lastHasChangedValues.get(id); + if (lastValue == null || currentValue != lastValue) { + lastHasChangedValues.put(id, currentValue); + return true; + } + + return false; + } + + /** + * Runs action if any of the tunableNumbers have changed + * + * @param id Unique identifier for the caller to avoid conflicts when shared between multiple * + * objects. Recommended approach is to pass the result of "hashCode()" + * @param action Callback to run when any of the tunable numbers have changed. Access tunable + * numbers in order inputted in method + * @param tunableNumbers All tunable numbers to check + */ + public static void ifChanged( + int id, Consumer action, LoggedTunableNumber... tunableNumbers) + { + if (Arrays.stream(tunableNumbers).anyMatch(tunableNumber -> tunableNumber.hasChanged(id))) { + action.accept( + Arrays.stream(tunableNumbers).mapToDouble(LoggedTunableNumber::get).toArray()); + } + } + + /** Runs action if any of the tunableNumbers have changed */ + public static void ifChanged(int id, Runnable action, LoggedTunableNumber... tunableNumbers) + { + ifChanged(id, values -> action.run(), tunableNumbers); + } + + @Override + public double getAsDouble() + { + return get(); + } +} diff --git a/src/main/java/frc/robot/util/TuneableProfiledPID.java b/src/main/java/frc/robot/util/TuneableProfiledPID.java new file mode 100644 index 0000000..1972576 --- /dev/null +++ b/src/main/java/frc/robot/util/TuneableProfiledPID.java @@ -0,0 +1,51 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +package frc.robot.util; + +import edu.wpi.first.math.controller.ProfiledPIDController; +import edu.wpi.first.math.trajectory.TrapezoidProfile; + +/** Add your docs here. */ +public class TuneableProfiledPID extends ProfiledPIDController { + + // Instance name for tagging log values + String m_name; + + // Tunable numbers + private LoggedTunableNumber m_kP, m_kI, m_kD, m_maxV, m_maxA; + + public TuneableProfiledPID(String name, double kP, double kI, + double kD, double maxV, double maxA) + { + super(kP, kI, kD, new TrapezoidProfile.Constraints(maxV, maxA)); + + m_name = name; + + // Tunable numbers for PID and motion gain constants + m_kP = new LoggedTunableNumber(m_name + "/kP", kP); + m_kI = new LoggedTunableNumber(m_name + "/kI", kI); + m_kD = new LoggedTunableNumber(m_name + "/kD", kD); + + m_maxV = new LoggedTunableNumber(m_name + "/maxV", maxV); + m_maxA = new LoggedTunableNumber(m_name + "/maxA", maxA); + + } + + public void updatePID() + { + // If changed, update controller constants from Tuneable Numbers + if (m_kP.hasChanged(hashCode()) + || m_kI.hasChanged(hashCode()) + || m_kD.hasChanged(hashCode())) { + this.setPID(m_kP.get(), m_kI.get(), m_kD.get()); + } + + if (m_maxV.hasChanged(hashCode()) + || m_maxA.hasChanged(hashCode())) { + this.setConstraints(new TrapezoidProfile.Constraints(m_maxV.get(), m_maxA.get())); + } + } + +} diff --git a/vendordeps/PathplannerLib-2025.2.1.json b/vendordeps/PathplannerLib-2025.2.5.json similarity index 87% rename from vendordeps/PathplannerLib-2025.2.1.json rename to vendordeps/PathplannerLib-2025.2.5.json index 71e25f3..b2a7265 100644 --- a/vendordeps/PathplannerLib-2025.2.1.json +++ b/vendordeps/PathplannerLib-2025.2.5.json @@ -1,7 +1,7 @@ { - "fileName": "PathplannerLib-2025.2.1.json", + "fileName": "PathplannerLib-2025.2.5.json", "name": "PathplannerLib", - "version": "2025.2.1", + "version": "2025.2.5", "uuid": "1b42324f-17c6-4875-8e77-1c312bc8c786", "frcYear": "2025", "mavenUrls": [ @@ -12,7 +12,7 @@ { "groupId": "com.pathplanner.lib", "artifactId": "PathplannerLib-java", - "version": "2025.2.1" + "version": "2025.2.5" } ], "jniDependencies": [], @@ -20,7 +20,7 @@ { "groupId": "com.pathplanner.lib", "artifactId": "PathplannerLib-cpp", - "version": "2025.2.1", + "version": "2025.2.5", "libName": "PathplannerLib", "headerClassifier": "headers", "sharedLibrary": false, diff --git a/vendordeps/Phoenix6-25.2.1.json b/vendordeps/Phoenix6-25.3.1.json similarity index 86% rename from vendordeps/Phoenix6-25.2.1.json rename to vendordeps/Phoenix6-25.3.1.json index 1397da1..a216d97 100644 --- a/vendordeps/Phoenix6-25.2.1.json +++ b/vendordeps/Phoenix6-25.3.1.json @@ -1,7 +1,7 @@ { - "fileName": "Phoenix6-25.2.1.json", + "fileName": "Phoenix6-25.3.1.json", "name": "CTRE-Phoenix (v6)", - "version": "25.2.1", + "version": "25.3.1", "frcYear": "2025", "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", "mavenUrls": [ @@ -19,14 +19,14 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "wpiapi-java", - "version": "25.2.1" + "version": "25.3.1" } ], "jniDependencies": [ { "groupId": "com.ctre.phoenix6", "artifactId": "api-cpp", - "version": "25.2.1", + "version": "25.3.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -40,7 +40,7 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "tools", - "version": "25.2.1", + "version": "25.3.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -54,7 +54,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "api-cpp-sim", - "version": "25.2.1", + "version": "25.3.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -68,7 +68,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "tools-sim", - "version": "25.2.1", + "version": "25.3.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -82,7 +82,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simTalonSRX", - "version": "25.2.1", + "version": "25.3.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -96,7 +96,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simVictorSPX", - "version": "25.2.1", + "version": "25.3.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -110,7 +110,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simPigeonIMU", - "version": "25.2.1", + "version": "25.3.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -124,7 +124,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simCANCoder", - "version": "25.2.1", + "version": "25.3.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -138,7 +138,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProTalonFX", - "version": "25.2.1", + "version": "25.3.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -152,7 +152,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProTalonFXS", - "version": "25.2.1", + "version": "25.3.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -166,7 +166,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANcoder", - "version": "25.2.1", + "version": "25.3.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -180,7 +180,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProPigeon2", - "version": "25.2.1", + "version": "25.3.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -194,7 +194,21 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANrange", - "version": "25.2.1", + "version": "25.3.1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdi", + "version": "25.3.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -210,7 +224,7 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "wpiapi-cpp", - "version": "25.2.1", + "version": "25.3.1", "libName": "CTRE_Phoenix6_WPI", "headerClassifier": "headers", "sharedLibrary": true, @@ -226,7 +240,7 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "tools", - "version": "25.2.1", + "version": "25.3.1", "libName": "CTRE_PhoenixTools", "headerClassifier": "headers", "sharedLibrary": true, @@ -242,7 +256,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "wpiapi-cpp-sim", - "version": "25.2.1", + "version": "25.3.1", "libName": "CTRE_Phoenix6_WPISim", "headerClassifier": "headers", "sharedLibrary": true, @@ -258,7 +272,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "tools-sim", - "version": "25.2.1", + "version": "25.3.1", "libName": "CTRE_PhoenixTools_Sim", "headerClassifier": "headers", "sharedLibrary": true, @@ -274,7 +288,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simTalonSRX", - "version": "25.2.1", + "version": "25.3.1", "libName": "CTRE_SimTalonSRX", "headerClassifier": "headers", "sharedLibrary": true, @@ -290,7 +304,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simVictorSPX", - "version": "25.2.1", + "version": "25.3.1", "libName": "CTRE_SimVictorSPX", "headerClassifier": "headers", "sharedLibrary": true, @@ -306,7 +320,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simPigeonIMU", - "version": "25.2.1", + "version": "25.3.1", "libName": "CTRE_SimPigeonIMU", "headerClassifier": "headers", "sharedLibrary": true, @@ -322,7 +336,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simCANCoder", - "version": "25.2.1", + "version": "25.3.1", "libName": "CTRE_SimCANCoder", "headerClassifier": "headers", "sharedLibrary": true, @@ -338,7 +352,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProTalonFX", - "version": "25.2.1", + "version": "25.3.1", "libName": "CTRE_SimProTalonFX", "headerClassifier": "headers", "sharedLibrary": true, @@ -354,7 +368,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProTalonFXS", - "version": "25.2.1", + "version": "25.3.1", "libName": "CTRE_SimProTalonFXS", "headerClassifier": "headers", "sharedLibrary": true, @@ -370,7 +384,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANcoder", - "version": "25.2.1", + "version": "25.3.1", "libName": "CTRE_SimProCANcoder", "headerClassifier": "headers", "sharedLibrary": true, @@ -386,7 +400,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProPigeon2", - "version": "25.2.1", + "version": "25.3.1", "libName": "CTRE_SimProPigeon2", "headerClassifier": "headers", "sharedLibrary": true, @@ -402,7 +416,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANrange", - "version": "25.2.1", + "version": "25.3.1", "libName": "CTRE_SimProCANrange", "headerClassifier": "headers", "sharedLibrary": true, @@ -414,6 +428,22 @@ "osxuniversal" ], "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdi", + "version": "25.3.1", + "libName": "CTRE_SimProCANdi", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" } ] } \ No newline at end of file diff --git a/vendordeps/REVLib-2025.0.1.json b/vendordeps/REVLib.json similarity index 90% rename from vendordeps/REVLib-2025.0.1.json rename to vendordeps/REVLib.json index c998054..ac62be8 100644 --- a/vendordeps/REVLib-2025.0.1.json +++ b/vendordeps/REVLib.json @@ -1,7 +1,7 @@ { - "fileName": "REVLib-2025.0.1.json", + "fileName": "REVLib.json", "name": "REVLib", - "version": "2025.0.1", + "version": "2025.0.3", "frcYear": "2025", "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", "mavenUrls": [ @@ -12,14 +12,14 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-java", - "version": "2025.0.1" + "version": "2025.0.3" } ], "jniDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2025.0.1", + "version": "2025.0.3", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -36,7 +36,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-cpp", - "version": "2025.0.1", + "version": "2025.0.3", "libName": "REVLib", "headerClassifier": "headers", "sharedLibrary": false, @@ -53,7 +53,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2025.0.1", + "version": "2025.0.3", "libName": "REVLibDriver", "headerClassifier": "headers", "sharedLibrary": false, diff --git a/vendordeps/libgrapplefrc2025.json b/vendordeps/libgrapplefrc2025.json new file mode 100644 index 0000000..a49af31 --- /dev/null +++ b/vendordeps/libgrapplefrc2025.json @@ -0,0 +1,74 @@ +{ + "fileName": "libgrapplefrc2025.json", + "name": "libgrapplefrc", + "version": "2025.1.3", + "frcYear": "2025", + "uuid": "8ef3423d-9532-4665-8339-206dae1d7168", + "mavenUrls": [ + "https://storage.googleapis.com/grapple-frc-maven" + ], + "jsonUrl": "https://storage.googleapis.com/grapple-frc-maven/libgrapplefrc2025.json", + "javaDependencies": [ + { + "groupId": "au.grapplerobotics", + "artifactId": "libgrapplefrcjava", + "version": "2025.1.3" + } + ], + "jniDependencies": [ + { + "groupId": "au.grapplerobotics", + "artifactId": "libgrapplefrcdriver", + "version": "2025.1.3", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "windowsx86", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "au.grapplerobotics", + "artifactId": "libgrapplefrccpp", + "version": "2025.1.3", + "libName": "grapplefrc", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "windowsx86", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "au.grapplerobotics", + "artifactId": "libgrapplefrcdriver", + "version": "2025.1.3", + "libName": "grapplefrcdriver", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "windowsx86", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/vendordeps/photonlib.json b/vendordeps/photonlib.json new file mode 100644 index 0000000..1219919 --- /dev/null +++ b/vendordeps/photonlib.json @@ -0,0 +1,71 @@ +{ + "fileName": "photonlib.json", + "name": "photonlib", + "version": "v2025.2.1", + "uuid": "515fe07e-bfc6-11fa-b3de-0242ac130004", + "frcYear": "2025", + "mavenUrls": [ + "https://maven.photonvision.org/repository/internal", + "https://maven.photonvision.org/repository/snapshots" + ], + "jsonUrl": "https://maven.photonvision.org/repository/internal/org/photonvision/photonlib-json/1.0/photonlib-json-1.0.json", + "jniDependencies": [ + { + "groupId": "org.photonvision", + "artifactId": "photontargeting-cpp", + "version": "v2025.2.1", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxathena", + "linuxx86-64", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "org.photonvision", + "artifactId": "photonlib-cpp", + "version": "v2025.2.1", + "libName": "photonlib", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxathena", + "linuxx86-64", + "osxuniversal" + ] + }, + { + "groupId": "org.photonvision", + "artifactId": "photontargeting-cpp", + "version": "v2025.2.1", + "libName": "photontargeting", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxathena", + "linuxx86-64", + "osxuniversal" + ] + } + ], + "javaDependencies": [ + { + "groupId": "org.photonvision", + "artifactId": "photonlib-java", + "version": "v2025.2.1" + }, + { + "groupId": "org.photonvision", + "artifactId": "photontargeting-java", + "version": "v2025.2.1" + } + ] +} \ No newline at end of file