From 2386846cac10ec3ca9c2f5d91c589473e182d489 Mon Sep 17 00:00:00 2001 From: T Grinch <10247070+thenetworkgrinch@users.noreply.github.com> Date: Tue, 30 Dec 2025 20:44:34 -0600 Subject: [PATCH 01/62] origin/2026 (#6) * Begin working on 2026. * Added minion support, explicitly disallowed pulsar support. * Added 2026 support. * Updated example gradle and vdeps to beta --------- Co-authored-by: thenetworkgrinch --- .../.wpilib/wpilib_preferences.json | 2 +- examples/clock_drive_drivebase/build.gradle | 16 +- .../clock_drive_drivebase/settings.gradle | 6 +- .../vendordeps/Phoenix5-frc2025-latest.json | 171 - .../Phoenix5-replay-5.36.0-beta-1.json | 221 + .../Phoenix6-replay-26.0.0-beta-1.json} | 162 +- .../vendordeps/REVLib.json | 76 +- .../vendordeps/ReduxLib-2025.0.1.json | 72 - .../vendordeps/Studica-2025.0.1.json | 71 - .../vendordeps/Studica-2026.0.0-beta.json | 71 + .../vendordeps/StudicaLib.json | 71 + .../vendordeps/ThriftyLib.json | 8 +- .../vendordeps/WPILibNewCommands.json | 3 +- .../vendordeps/maple-sim.json | 26 - .../vendordeps/photonlib.json | 71 - .../vendordeps/yagsl-2025.7.2.json | 64 - .../.wpilib/wpilib_preferences.json | 2 +- examples/drivebase_only/build.gradle | 16 +- examples/drivebase_only/settings.gradle | 6 +- .../vendordeps/Phoenix5-frc2025-latest.json | 171 - .../Phoenix5-replay-5.36.0-beta-1.json | 221 + .../Phoenix6-replay-26.0.0-beta-1.json} | 162 +- .../drivebase_only/vendordeps/REVLib.json | 76 +- .../vendordeps/ReduxLib-2025.0.1.json | 72 - .../vendordeps/Studica-2025.0.1.json | 71 - .../vendordeps/Studica-2026.0.0-beta.json | 71 + .../drivebase_only/vendordeps/StudicaLib.json | 71 + .../drivebase_only/vendordeps/ThriftyLib.json | 8 +- .../vendordeps/WPILibNewCommands.json | 3 +- .../drivebase_only/vendordeps/maple-sim.json | 26 - .../drivebase_only/vendordeps/photonlib.json | 71 - .../vendordeps/yagsl-2025.7.2.json | 64 - examples/drivebase_only_2026/.gitignore | 187 + .../drivebase_only_2026/.vscode/launch.json | 21 + .../drivebase_only_2026/.vscode/settings.json | 61 + .../.wpilib/wpilib_preferences.json | 6 + .../drivebase_only_2026/WPILib-License.md | 24 + examples/drivebase_only_2026/build.gradle | 114 + .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43583 bytes .../gradle/wrapper/gradle-wrapper.properties | 7 + examples/drivebase_only_2026/gradlew | 252 + examples/drivebase_only_2026/gradlew.bat | 94 + examples/drivebase_only_2026/settings.gradle | 30 + .../src/main/deploy/example.txt | 3 + .../main/deploy/pathplanner/SamplePath.path | 76 + .../deploy/pathplanner/autos/New Auto.auto | 19 + .../generatedJSON/New Path.wpilib.json | 9002 +++++++++++++++++ .../generatedJSON/SamplePath.wpilib.json | 9002 +++++++++++++++++ .../src/main/deploy/pathplanner/navgrid.json | 1656 +++ .../deploy/pathplanner/paths/New Path.path | 70 + .../src/main/deploy/pathplanner/settings.json | 32 + .../swerve/falcon/controllerproperties.json | 8 + .../swerve/falcon/modules/backleft.json | 26 + .../swerve/falcon/modules/backright.json | 26 + .../swerve/falcon/modules/frontleft.json | 26 + .../swerve/falcon/modules/frontright.json | 26 + .../falcon/modules/physicalproperties.json | 23 + .../swerve/falcon/modules/pidfproperties.json | 16 + .../deploy/swerve/falcon/swervedrive.json | 15 + .../maxSwerve/controllerproperties.json | 8 + .../swerve/maxSwerve/modules/backleft.json | 27 + .../swerve/maxSwerve/modules/backright.json | 27 + .../swerve/maxSwerve/modules/frontleft.json | 27 + .../swerve/maxSwerve/modules/frontright.json | 27 + .../maxSwerve/modules/physicalproperties.json | 23 + .../maxSwerve/modules/pidfproperties.json | 16 + .../deploy/swerve/maxSwerve/swervedrive.json | 14 + .../swerve/neo/controllerproperties.json | 8 + .../deploy/swerve/neo/modules/backleft.json | 26 + .../deploy/swerve/neo/modules/backright.json | 26 + .../deploy/swerve/neo/modules/frontleft.json | 26 + .../deploy/swerve/neo/modules/frontright.json | 26 + .../neo/modules/physicalproperties.json | 23 + .../swerve/neo/modules/pidfproperties.json | 16 + .../main/deploy/swerve/neo/swervedrive.json | 15 + .../src/main/java/frc/robot/Constants.java | 51 + .../src/main/java/frc/robot/Main.java | 29 + .../src/main/java/frc/robot/Robot.java | 178 + .../main/java/frc/robot/RobotContainer.java | 205 + .../swervedrive/auto/AutoBalanceCommand.java | 86 + .../swervedrive/drivebase/AbsoluteDrive.java | 120 + .../drivebase/AbsoluteDriveAdv.java | 154 + .../drivebase/AbsoluteFieldDrive.java | 95 + .../swervedrive/SwerveSubsystem.java | 486 + .../Phoenix5-replay-5.36.0-beta-1.json | 221 + .../Phoenix6-replay-26.0.0-beta-1.json} | 162 +- .../vendordeps/REVLib.json | 133 + .../vendordeps/Studica-2026.0.0-beta.json | 71 + .../vendordeps/StudicaLib.json | 71 + .../vendordeps/ThriftyLib.json | 20 + .../vendordeps/WPILibNewCommands.json | 39 + .../.wpilib/wpilib_preferences.json | 2 +- .../drivebase_with_PathPlanner/build.gradle | 16 +- .../settings.gradle | 6 +- .../vendordeps/PathplannerLib.json | 38 - .../vendordeps/Phoenix5-frc2025-latest.json | 171 - .../Phoenix5-replay-5.36.0-beta-1.json | 221 + .../Phoenix6-replay-26.0.0-beta-1.json} | 162 +- .../vendordeps/REVLib.json | 76 +- .../vendordeps/ReduxLib-2025.0.1.json | 72 - .../vendordeps/Studica-2025.0.1.json | 71 - .../vendordeps/Studica-2026.0.0-beta.json | 71 + .../vendordeps/StudicaLib.json | 71 + .../vendordeps/ThriftyLib.json | 8 +- .../vendordeps/WPILibNewCommands.json | 3 +- .../vendordeps/maple-sim.json | 26 - .../vendordeps/photonlib.json | 71 - .../vendordeps/yagsl-2025.7.2.json | 64 - .../.wpilib/wpilib_preferences.json | 4 +- .../drivebase_with_PhotonVision/build.gradle | 16 +- .../settings.gradle | 6 +- .../vendordeps/PathplannerLib.json | 38 - .../vendordeps/Phoenix5-frc2025-latest.json | 171 - .../Phoenix5-replay-5.36.0-beta-1.json | 221 + .../Phoenix6-replay-26.0.0-beta-1.json | 453 + .../vendordeps/REVLib.json | 76 +- .../vendordeps/ReduxLib-2025.0.1.json | 72 - .../vendordeps/Studica-2025.0.1.json | 71 - .../vendordeps/Studica-2026.0.0-beta.json | 71 + .../vendordeps/StudicaLib.json | 71 + .../vendordeps/ThriftyLib.json | 8 +- .../vendordeps/WPILibNewCommands.json | 3 +- .../vendordeps/maple-sim.json | 26 - .../vendordeps/photonlib.json | 71 - .../vendordeps/yagsl-2025.7.2.json | 64 - .../.wpilib/wpilib_preferences.json | 2 +- .../field_oriented_drivebase/build.gradle | 16 +- .../field_oriented_drivebase/settings.gradle | 6 +- .../vendordeps/Phoenix5-frc2025-latest.json | 171 - .../Phoenix5-replay-5.36.0-beta-1.json | 221 + .../vendordeps/Phoenix6-frc2025-latest.json | 479 - .../Phoenix6-replay-26.0.0-beta-1.json | 453 + .../vendordeps/REVLib.json | 76 +- .../vendordeps/ReduxLib-2025.0.1.json | 72 - .../vendordeps/Studica-2025.0.1.json | 71 - .../vendordeps/Studica-2026.0.0-beta.json | 71 + .../vendordeps/StudicaLib.json | 71 + .../vendordeps/ThriftyLib.json | 8 +- .../vendordeps/WPILibNewCommands.json | 3 +- .../vendordeps/maple-sim.json | 26 - .../vendordeps/photonlib.json | 71 - .../vendordeps/yagsl-2025.7.2.json | 64 - .../.wpilib/wpilib_preferences.json | 2 +- examples/full_example/build.gradle | 16 +- examples/full_example/settings.gradle | 6 +- .../vendordeps/PathplannerLib.json | 38 - .../vendordeps/Phoenix5-frc2025-latest.json | 171 - .../Phoenix5-replay-5.36.0-beta-1.json | 221 + .../vendordeps/Phoenix6-frc2025-latest.json | 479 - .../Phoenix6-replay-26.0.0-beta-1.json | 453 + examples/full_example/vendordeps/REVLib.json | 76 +- .../vendordeps/ReduxLib-2025.0.1.json | 72 - .../vendordeps/Studica-2025.0.1.json | 71 - .../vendordeps/Studica-2026.0.0-beta.json | 71 + .../full_example/vendordeps/StudicaLib.json | 71 + .../full_example/vendordeps/ThriftyLib.json | 8 +- .../vendordeps/WPILibNewCommands.json | 3 +- .../full_example/vendordeps/maple-sim.json | 26 - .../full_example/vendordeps/photonlib.json | 71 - .../vendordeps/yagsl-2025.7.2.json | 64 - .../.wpilib/wpilib_preferences.json | 2 +- .../robot_relative_drivebase/build.gradle | 16 +- .../robot_relative_drivebase/settings.gradle | 6 +- .../vendordeps/Phoenix5-frc2025-latest.json | 171 - .../Phoenix5-replay-5.36.0-beta-1.json | 221 + .../vendordeps/Phoenix6-frc2025-latest.json | 479 - .../Phoenix6-replay-26.0.0-beta-1.json | 453 + .../vendordeps/REVLib.json | 76 +- .../vendordeps/ReduxLib-2025.0.1.json | 72 - .../vendordeps/Studica-2025.0.1.json | 71 - .../vendordeps/Studica-2026.0.0-beta.json | 71 + .../vendordeps/StudicaLib.json | 71 + .../vendordeps/ThriftyLib.json | 8 +- .../vendordeps/WPILibNewCommands.json | 3 +- .../vendordeps/maple-sim.json | 26 - .../vendordeps/photonlib.json | 71 - .../vendordeps/yagsl-2025.7.2.json | 64 - vendordep/build.gradle | 33 +- vendordep/publish.gradle | 4 +- .../vendordeps/Phoenix5-frc2025-latest.json | 171 - .../Phoenix5-replay-5.36.0-beta-1.json | 221 + .../vendordeps/Phoenix6-frc2025-latest.json | 449 - .../Phoenix6-replay-26.0.0-beta-1.json | 453 + vendordep/vendordeps/REVLib.json | 76 +- vendordep/vendordeps/ReduxLib-2025.0.1.json | 72 - vendordep/vendordeps/Studica-2025.0.1.json | 71 - .../vendordeps/Studica-2026.0.0-beta.json | 71 + vendordep/vendordeps/StudicaLib.json | 71 + vendordep/vendordeps/ThriftyLib.json | 8 +- vendordep/vendordeps/WPILibNewCommands.json | 3 +- vendordep/vendordeps/maple-sim.json | 26 - vendordep/vendordeps/photonlib.json | 71 - vendordep/yagsl.json | 40 +- yagsl/java/swervelib/SwerveDrive.java | 10 +- yagsl/java/swervelib/SwerveModule.java | 6 +- .../swervelib/encoders/CanAndMagSwerve.java | 226 +- .../encoders/SparkMaxAnalogEncoderSwerve.java | 2 +- .../encoders/SparkMaxEncoderSwerve.java | 1 - .../encoders/ThriftyNovaEncoderSwerve.java | 20 +- .../java/swervelib/imu/CanandgyroSwerve.java | 282 +- .../swervelib/motors/SparkFlexSwerve.java | 2 +- .../motors/SparkMaxBrushedMotorSwerve.java | 8 +- .../java/swervelib/motors/SparkMaxSwerve.java | 2 +- .../java/swervelib/motors/TalonFXSSwerve.java | 25 + .../swervelib/motors/ThriftyNovaSwerve.java | 24 +- .../parser/SwerveDriveConfiguration.java | 4 +- .../swervelib/parser/json/DeviceJson.java | 32 +- .../simulation/SwerveIMUSimulation.java | 2 +- .../simulation/SwerveModuleSimulation.java | 8 +- .../simulation/ironmaple/LICENSE-Dyn4j.md | 27 + .../simulation/ironmaple/simulation/Goal.java | 297 + .../simulation/IntakeSimulation.java | 406 + .../ironmaple/simulation/SimulatedArena.java | 760 ++ .../AbstractDriveTrainSimulation.java | 170 + .../ironmaple/simulation/drivesims/COTS.java | 404 + .../simulation/drivesims/GyroSimulation.java | 212 + .../SelfControlledSwerveDriveSimulation.java | 580 ++ .../drivesims/SwerveDriveSimulation.java | 368 + .../drivesims/SwerveModuleSimulation.java | 541 + .../drivesims/configs/BoundingCheck.java | 12 + .../configs/DriveTrainSimulationConfig.java | 323 + .../configs/SwerveModuleSimulationConfig.java | 128 + .../simulation/gamepieces/GamePiece.java | 56 + .../GamePieceOnFieldSimulation.java | 183 + .../gamepieces/GamePieceProjectile.java | 639 ++ .../simulation/motorsims/MapleMotorSim.java | 194 + .../simulation/motorsims/SimMotorConfigs.java | 203 + .../simulation/motorsims/SimMotorState.java | 95 + .../motorsims/SimulatedBattery.java | 138 + .../motorsims/SimulatedMotorController.java | 108 + .../crescendo2024/Arena2024Crescendo.java | 210 + .../crescendo2024/CrescendoAmp.java | 68 + .../CrescendoHumanPlayerSimulation.java | 36 + .../crescendo2024/CrescendoNoteOnField.java | 21 + .../crescendo2024/CrescendoSpeaker.java | 68 + .../crescendo2024/NoteOnFly.java | 57 + .../evergreen/ArenaEvergreen.java | 70 + .../reefscape2025/Arena2025Reefscape.java | 173 + .../reefscape2025/ReefscapeAlgaeOnField.java | 26 + .../reefscape2025/ReefscapeAlgaeOnFly.java | 58 + .../ReefscapeBargeSimulation.java | 75 + .../ReefscapeCoralAlgaeStack.java | 146 + .../reefscape2025/ReefscapeCoralOnField.java | 27 + .../reefscape2025/ReefscapeCoralOnFly.java | 98 + .../ReefscapeProcessorSimulation.java | 87 + .../reefscape2025/ReefscapeReefBranch.java | 220 + .../ReefscapeReefSimulation.java | 105 + .../ironmaple/utils/FieldMirroringUtils.java | 55 + .../utils/LegacyFieldMirroringUtils2024.java | 61 + .../utils/mathutils/GeometryConvertor.java | 53 + .../utils/mathutils/MapleCommonMath.java | 61 + .../mathutils/SwerveStateProjection.java | 26 + 252 files changed, 37304 insertions(+), 6607 deletions(-) delete mode 100644 examples/clock_drive_drivebase/vendordeps/Phoenix5-frc2025-latest.json create mode 100644 examples/clock_drive_drivebase/vendordeps/Phoenix5-replay-5.36.0-beta-1.json rename examples/{drivebase_only/vendordeps/Phoenix6-frc2025-latest.json => clock_drive_drivebase/vendordeps/Phoenix6-replay-26.0.0-beta-1.json} (81%) delete mode 100644 examples/clock_drive_drivebase/vendordeps/ReduxLib-2025.0.1.json delete mode 100644 examples/clock_drive_drivebase/vendordeps/Studica-2025.0.1.json create mode 100644 examples/clock_drive_drivebase/vendordeps/Studica-2026.0.0-beta.json create mode 100644 examples/clock_drive_drivebase/vendordeps/StudicaLib.json delete mode 100644 examples/clock_drive_drivebase/vendordeps/maple-sim.json delete mode 100644 examples/clock_drive_drivebase/vendordeps/photonlib.json delete mode 100644 examples/clock_drive_drivebase/vendordeps/yagsl-2025.7.2.json delete mode 100644 examples/drivebase_only/vendordeps/Phoenix5-frc2025-latest.json create mode 100644 examples/drivebase_only/vendordeps/Phoenix5-replay-5.36.0-beta-1.json rename examples/{clock_drive_drivebase/vendordeps/Phoenix6-frc2025-latest.json => drivebase_only/vendordeps/Phoenix6-replay-26.0.0-beta-1.json} (81%) delete mode 100644 examples/drivebase_only/vendordeps/ReduxLib-2025.0.1.json delete mode 100644 examples/drivebase_only/vendordeps/Studica-2025.0.1.json create mode 100644 examples/drivebase_only/vendordeps/Studica-2026.0.0-beta.json create mode 100644 examples/drivebase_only/vendordeps/StudicaLib.json delete mode 100644 examples/drivebase_only/vendordeps/maple-sim.json delete mode 100644 examples/drivebase_only/vendordeps/photonlib.json delete mode 100644 examples/drivebase_only/vendordeps/yagsl-2025.7.2.json create mode 100644 examples/drivebase_only_2026/.gitignore create mode 100644 examples/drivebase_only_2026/.vscode/launch.json create mode 100644 examples/drivebase_only_2026/.vscode/settings.json create mode 100644 examples/drivebase_only_2026/.wpilib/wpilib_preferences.json create mode 100644 examples/drivebase_only_2026/WPILib-License.md create mode 100644 examples/drivebase_only_2026/build.gradle create mode 100644 examples/drivebase_only_2026/gradle/wrapper/gradle-wrapper.jar create mode 100644 examples/drivebase_only_2026/gradle/wrapper/gradle-wrapper.properties create mode 100644 examples/drivebase_only_2026/gradlew create mode 100644 examples/drivebase_only_2026/gradlew.bat create mode 100644 examples/drivebase_only_2026/settings.gradle create mode 100644 examples/drivebase_only_2026/src/main/deploy/example.txt create mode 100644 examples/drivebase_only_2026/src/main/deploy/pathplanner/SamplePath.path create mode 100644 examples/drivebase_only_2026/src/main/deploy/pathplanner/autos/New Auto.auto create mode 100644 examples/drivebase_only_2026/src/main/deploy/pathplanner/generatedJSON/New Path.wpilib.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/pathplanner/generatedJSON/SamplePath.wpilib.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/pathplanner/navgrid.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/pathplanner/paths/New Path.path create mode 100644 examples/drivebase_only_2026/src/main/deploy/pathplanner/settings.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/falcon/controllerproperties.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/backleft.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/backright.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/frontleft.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/frontright.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/physicalproperties.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/pidfproperties.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/falcon/swervedrive.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/controllerproperties.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/backleft.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/backright.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/frontleft.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/frontright.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/physicalproperties.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/pidfproperties.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/swervedrive.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/neo/controllerproperties.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/backleft.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/backright.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/frontleft.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/frontright.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/physicalproperties.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/pidfproperties.json create mode 100644 examples/drivebase_only_2026/src/main/deploy/swerve/neo/swervedrive.json create mode 100644 examples/drivebase_only_2026/src/main/java/frc/robot/Constants.java create mode 100644 examples/drivebase_only_2026/src/main/java/frc/robot/Main.java create mode 100644 examples/drivebase_only_2026/src/main/java/frc/robot/Robot.java create mode 100644 examples/drivebase_only_2026/src/main/java/frc/robot/RobotContainer.java create mode 100644 examples/drivebase_only_2026/src/main/java/frc/robot/commands/swervedrive/auto/AutoBalanceCommand.java create mode 100644 examples/drivebase_only_2026/src/main/java/frc/robot/commands/swervedrive/drivebase/AbsoluteDrive.java create mode 100644 examples/drivebase_only_2026/src/main/java/frc/robot/commands/swervedrive/drivebase/AbsoluteDriveAdv.java create mode 100644 examples/drivebase_only_2026/src/main/java/frc/robot/commands/swervedrive/drivebase/AbsoluteFieldDrive.java create mode 100644 examples/drivebase_only_2026/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java create mode 100644 examples/drivebase_only_2026/vendordeps/Phoenix5-replay-5.36.0-beta-1.json rename examples/{drivebase_with_PathPlanner/vendordeps/Phoenix6-frc2025-latest.json => drivebase_only_2026/vendordeps/Phoenix6-replay-26.0.0-beta-1.json} (81%) create mode 100644 examples/drivebase_only_2026/vendordeps/REVLib.json create mode 100644 examples/drivebase_only_2026/vendordeps/Studica-2026.0.0-beta.json create mode 100644 examples/drivebase_only_2026/vendordeps/StudicaLib.json create mode 100644 examples/drivebase_only_2026/vendordeps/ThriftyLib.json create mode 100644 examples/drivebase_only_2026/vendordeps/WPILibNewCommands.json delete mode 100644 examples/drivebase_with_PathPlanner/vendordeps/PathplannerLib.json delete mode 100644 examples/drivebase_with_PathPlanner/vendordeps/Phoenix5-frc2025-latest.json create mode 100644 examples/drivebase_with_PathPlanner/vendordeps/Phoenix5-replay-5.36.0-beta-1.json rename examples/{drivebase_with_PhotonVision/vendordeps/Phoenix6-frc2025-latest.json => drivebase_with_PathPlanner/vendordeps/Phoenix6-replay-26.0.0-beta-1.json} (81%) delete mode 100644 examples/drivebase_with_PathPlanner/vendordeps/ReduxLib-2025.0.1.json delete mode 100644 examples/drivebase_with_PathPlanner/vendordeps/Studica-2025.0.1.json create mode 100644 examples/drivebase_with_PathPlanner/vendordeps/Studica-2026.0.0-beta.json create mode 100644 examples/drivebase_with_PathPlanner/vendordeps/StudicaLib.json delete mode 100644 examples/drivebase_with_PathPlanner/vendordeps/maple-sim.json delete mode 100644 examples/drivebase_with_PathPlanner/vendordeps/photonlib.json delete mode 100644 examples/drivebase_with_PathPlanner/vendordeps/yagsl-2025.7.2.json delete mode 100644 examples/drivebase_with_PhotonVision/vendordeps/PathplannerLib.json delete mode 100644 examples/drivebase_with_PhotonVision/vendordeps/Phoenix5-frc2025-latest.json create mode 100644 examples/drivebase_with_PhotonVision/vendordeps/Phoenix5-replay-5.36.0-beta-1.json create mode 100644 examples/drivebase_with_PhotonVision/vendordeps/Phoenix6-replay-26.0.0-beta-1.json delete mode 100644 examples/drivebase_with_PhotonVision/vendordeps/ReduxLib-2025.0.1.json delete mode 100644 examples/drivebase_with_PhotonVision/vendordeps/Studica-2025.0.1.json create mode 100644 examples/drivebase_with_PhotonVision/vendordeps/Studica-2026.0.0-beta.json create mode 100644 examples/drivebase_with_PhotonVision/vendordeps/StudicaLib.json delete mode 100644 examples/drivebase_with_PhotonVision/vendordeps/maple-sim.json delete mode 100644 examples/drivebase_with_PhotonVision/vendordeps/photonlib.json delete mode 100644 examples/drivebase_with_PhotonVision/vendordeps/yagsl-2025.7.2.json delete mode 100644 examples/field_oriented_drivebase/vendordeps/Phoenix5-frc2025-latest.json create mode 100644 examples/field_oriented_drivebase/vendordeps/Phoenix5-replay-5.36.0-beta-1.json delete mode 100644 examples/field_oriented_drivebase/vendordeps/Phoenix6-frc2025-latest.json create mode 100644 examples/field_oriented_drivebase/vendordeps/Phoenix6-replay-26.0.0-beta-1.json delete mode 100644 examples/field_oriented_drivebase/vendordeps/ReduxLib-2025.0.1.json delete mode 100644 examples/field_oriented_drivebase/vendordeps/Studica-2025.0.1.json create mode 100644 examples/field_oriented_drivebase/vendordeps/Studica-2026.0.0-beta.json create mode 100644 examples/field_oriented_drivebase/vendordeps/StudicaLib.json delete mode 100644 examples/field_oriented_drivebase/vendordeps/maple-sim.json delete mode 100644 examples/field_oriented_drivebase/vendordeps/photonlib.json delete mode 100644 examples/field_oriented_drivebase/vendordeps/yagsl-2025.7.2.json delete mode 100644 examples/full_example/vendordeps/PathplannerLib.json delete mode 100644 examples/full_example/vendordeps/Phoenix5-frc2025-latest.json create mode 100644 examples/full_example/vendordeps/Phoenix5-replay-5.36.0-beta-1.json delete mode 100644 examples/full_example/vendordeps/Phoenix6-frc2025-latest.json create mode 100644 examples/full_example/vendordeps/Phoenix6-replay-26.0.0-beta-1.json delete mode 100644 examples/full_example/vendordeps/ReduxLib-2025.0.1.json delete mode 100644 examples/full_example/vendordeps/Studica-2025.0.1.json create mode 100644 examples/full_example/vendordeps/Studica-2026.0.0-beta.json create mode 100644 examples/full_example/vendordeps/StudicaLib.json delete mode 100644 examples/full_example/vendordeps/maple-sim.json delete mode 100644 examples/full_example/vendordeps/photonlib.json delete mode 100644 examples/full_example/vendordeps/yagsl-2025.7.2.json delete mode 100644 examples/robot_relative_drivebase/vendordeps/Phoenix5-frc2025-latest.json create mode 100644 examples/robot_relative_drivebase/vendordeps/Phoenix5-replay-5.36.0-beta-1.json delete mode 100644 examples/robot_relative_drivebase/vendordeps/Phoenix6-frc2025-latest.json create mode 100644 examples/robot_relative_drivebase/vendordeps/Phoenix6-replay-26.0.0-beta-1.json delete mode 100644 examples/robot_relative_drivebase/vendordeps/ReduxLib-2025.0.1.json delete mode 100644 examples/robot_relative_drivebase/vendordeps/Studica-2025.0.1.json create mode 100644 examples/robot_relative_drivebase/vendordeps/Studica-2026.0.0-beta.json create mode 100644 examples/robot_relative_drivebase/vendordeps/StudicaLib.json delete mode 100644 examples/robot_relative_drivebase/vendordeps/maple-sim.json delete mode 100644 examples/robot_relative_drivebase/vendordeps/photonlib.json delete mode 100644 examples/robot_relative_drivebase/vendordeps/yagsl-2025.7.2.json delete mode 100644 vendordep/vendordeps/Phoenix5-frc2025-latest.json create mode 100644 vendordep/vendordeps/Phoenix5-replay-5.36.0-beta-1.json delete mode 100644 vendordep/vendordeps/Phoenix6-frc2025-latest.json create mode 100644 vendordep/vendordeps/Phoenix6-replay-26.0.0-beta-1.json delete mode 100644 vendordep/vendordeps/ReduxLib-2025.0.1.json delete mode 100644 vendordep/vendordeps/Studica-2025.0.1.json create mode 100644 vendordep/vendordeps/Studica-2026.0.0-beta.json create mode 100644 vendordep/vendordeps/StudicaLib.json delete mode 100644 vendordep/vendordeps/maple-sim.json delete mode 100644 vendordep/vendordeps/photonlib.json create mode 100644 yagsl/java/swervelib/simulation/ironmaple/LICENSE-Dyn4j.md create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/IntakeSimulation.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/AbstractDriveTrainSimulation.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/COTS.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/GyroSimulation.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SelfControlledSwerveDriveSimulation.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SwerveDriveSimulation.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SwerveModuleSimulation.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/configs/BoundingCheck.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/configs/DriveTrainSimulationConfig.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/configs/SwerveModuleSimulationConfig.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePiece.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceOnFieldSimulation.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceProjectile.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/MapleMotorSim.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimMotorConfigs.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimMotorState.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimulatedBattery.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimulatedMotorController.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/Arena2024Crescendo.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoAmp.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoHumanPlayerSimulation.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoNoteOnField.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoSpeaker.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/NoteOnFly.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/evergreen/ArenaEvergreen.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/Arena2025Reefscape.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeAlgaeOnField.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeAlgaeOnFly.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeBargeSimulation.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralAlgaeStack.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralOnField.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralOnFly.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeProcessorSimulation.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefBranch.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefSimulation.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/utils/FieldMirroringUtils.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/utils/LegacyFieldMirroringUtils2024.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/GeometryConvertor.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/MapleCommonMath.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/SwerveStateProjection.java diff --git a/examples/clock_drive_drivebase/.wpilib/wpilib_preferences.json b/examples/clock_drive_drivebase/.wpilib/wpilib_preferences.json index 83517dd..f727ea3 100644 --- a/examples/clock_drive_drivebase/.wpilib/wpilib_preferences.json +++ b/examples/clock_drive_drivebase/.wpilib/wpilib_preferences.json @@ -1,6 +1,6 @@ { "enableCppIntellisense": false, "currentLanguage": "java", - "projectYear": "2025", + "projectYear": "2026beta", "teamNumber": 3481 } \ No newline at end of file diff --git a/examples/clock_drive_drivebase/build.gradle b/examples/clock_drive_drivebase/build.gradle index fdf6d52..4233229 100644 --- a/examples/clock_drive_drivebase/build.gradle +++ b/examples/clock_drive_drivebase/build.gradle @@ -1,6 +1,6 @@ plugins { id "java" - id "edu.wpi.first.GradleRIO" version "2025.3.1" + id "edu.wpi.first.GradleRIO" version "2026.1.1-beta-1" } java { @@ -8,6 +8,14 @@ java { targetCompatibility = JavaVersion.VERSION_17 } +sourceSets { + main { + java { + srcDir '../../yagsl/java/' + } + } +} + def ROBOT_MAIN_CLASS = "frc.robot.Main" // Define my targets (RoboRIO) and artifacts (deployable files) @@ -34,7 +42,7 @@ deploy { files = project.fileTree('src/main/deploy') directory = '/home/lvuser/deploy' deleteOldFiles = false // Change to true to delete files on roboRIO that no - // longer exist in deploy directory of this project + // longer exist in deploy directory of this project } } } @@ -43,7 +51,8 @@ deploy { def deployArtifact = deploy.targets.roborio.artifacts.frcJava -// Set to true to use debug for JNI. +// Set to true to use debug for all targets including JNI, which will drastically impact +// performance. wpi.java.debugJni = false // Set this to true to enable desktop support. @@ -69,6 +78,7 @@ dependencies { nativeRelease wpi.java.deps.wpilibJniRelease(wpi.platforms.desktop) nativeRelease wpi.java.vendor.jniRelease(wpi.platforms.desktop) simulationRelease wpi.sim.enableRelease() + implementation 'org.dyn4j:dyn4j:5.0.2' testImplementation 'org.junit.jupiter:junit-jupiter:5.10.1' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' diff --git a/examples/clock_drive_drivebase/settings.gradle b/examples/clock_drive_drivebase/settings.gradle index 969c7b0..25f6f6e 100644 --- a/examples/clock_drive_drivebase/settings.gradle +++ b/examples/clock_drive_drivebase/settings.gradle @@ -4,7 +4,7 @@ pluginManagement { repositories { mavenLocal() gradlePluginPortal() - String frcYear = '2025' + String frcYear = '2026' File frcHome if (OperatingSystem.current().isWindows()) { String publicFolder = System.getenv('PUBLIC') @@ -20,8 +20,8 @@ pluginManagement { } def frcHomeMaven = new File(frcHome, 'maven') maven { - name 'frcHome' - url frcHomeMaven + name = 'frcHome' + url = frcHomeMaven } } } diff --git a/examples/clock_drive_drivebase/vendordeps/Phoenix5-frc2025-latest.json b/examples/clock_drive_drivebase/vendordeps/Phoenix5-frc2025-latest.json deleted file mode 100644 index 3cbc8f6..0000000 --- a/examples/clock_drive_drivebase/vendordeps/Phoenix5-frc2025-latest.json +++ /dev/null @@ -1,171 +0,0 @@ -{ - "fileName": "Phoenix5-frc2025-latest.json", - "name": "CTRE-Phoenix (v5)", - "version": "5.35.1", - "frcYear": "2025", - "uuid": "ab676553-b602-441f-a38d-f1296eff6537", - "mavenUrls": [ - "https://maven.ctr-electronics.com/release/" - ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-frc2025-latest.json", - "requires": [ - { - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", - "offlineFileName": "Phoenix6-frc2025-latest.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json" - } - ], - "conflictsWith": [ - { - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", - "errorMessage": "Users must use the Phoenix 5 replay vendordep when using the Phoenix 6 replay vendordep.", - "offlineFileName": "Phoenix6-replay-frc2025-latest.json" - }, - { - "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", - "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", - "offlineFileName": "Phoenix5-replay-frc2025-latest.json" - } - ], - "javaDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "api-java", - "version": "5.35.1" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "wpiapi-java", - "version": "5.35.1" - } - ], - "jniDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "cci", - "version": "5.35.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "cci-sim", - "version": "5.35.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ], - "cppDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "wpiapi-cpp", - "version": "5.35.1", - "libName": "CTRE_Phoenix_WPI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "api-cpp", - "version": "5.35.1", - "libName": "CTRE_Phoenix", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "cci", - "version": "5.35.1", - "libName": "CTRE_PhoenixCCI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "wpiapi-cpp-sim", - "version": "5.35.1", - "libName": "CTRE_Phoenix_WPISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "api-cpp-sim", - "version": "5.35.1", - "libName": "CTRE_PhoenixSim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "cci-sim", - "version": "5.35.1", - "libName": "CTRE_PhoenixCCISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ] -} \ No newline at end of file diff --git a/examples/clock_drive_drivebase/vendordeps/Phoenix5-replay-5.36.0-beta-1.json b/examples/clock_drive_drivebase/vendordeps/Phoenix5-replay-5.36.0-beta-1.json new file mode 100644 index 0000000..4a78551 --- /dev/null +++ b/examples/clock_drive_drivebase/vendordeps/Phoenix5-replay-5.36.0-beta-1.json @@ -0,0 +1,221 @@ +{ + "fileName": "Phoenix5-replay-5.36.0-beta-1.json", + "name": "CTRE-Phoenix (v5)", + "version": "5.36.0-beta-1", + "frcYear": "2026beta", + "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", + "mavenUrls": [ + "https://maven.ctr-electronics.com/release/" + ], + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-beta-latest.json", + "requires": [ + { + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", + "offlineFileName": "Phoenix6-replay-frc2026-beta-latest.json", + "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json" + } + ], + "conflictsWith": [ + { + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "errorMessage": "Users must use the regular Phoenix 5 vendordep when using the regular Phoenix 6 vendordep.", + "offlineFileName": "Phoenix6-frc2026-beta-latest.json" + }, + { + "uuid": "ab676553-b602-441f-a38d-f1296eff6537", + "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", + "offlineFileName": "Phoenix5-frc2026-beta-latest.json" + } + ], + "javaDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-java", + "version": "5.36.0-beta-1" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-java", + "version": "5.36.0-beta-1" + } + ], + "jniDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "cci-replay", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ], + "cppDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-cpp", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-cpp", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "wpiapi-cpp-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "api-cpp-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "cci-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "wpiapi-cpp-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "api-cpp-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixSim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ] +} \ No newline at end of file diff --git a/examples/drivebase_only/vendordeps/Phoenix6-frc2025-latest.json b/examples/clock_drive_drivebase/vendordeps/Phoenix6-replay-26.0.0-beta-1.json similarity index 81% rename from examples/drivebase_only/vendordeps/Phoenix6-frc2025-latest.json rename to examples/clock_drive_drivebase/vendordeps/Phoenix6-replay-26.0.0-beta-1.json index 6f40c84..5312c86 100644 --- a/examples/drivebase_only/vendordeps/Phoenix6-frc2025-latest.json +++ b/examples/clock_drive_drivebase/vendordeps/Phoenix6-replay-26.0.0-beta-1.json @@ -1,38 +1,35 @@ { - "fileName": "Phoenix6-frc2025-latest.json", - "name": "CTRE-Phoenix (v6)", - "version": "25.4.0", - "frcYear": "2025", - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "fileName": "Phoenix6-replay-26.0.0-beta-1.json", + "name": "CTRE-Phoenix (v6) Replay", + "version": "26.0.0-beta-1", + "frcYear": "2026beta", + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", "mavenUrls": [ "https://maven.ctr-electronics.com/release/" ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json", + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json", "conflictsWith": [ { - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", "errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.", - "offlineFileName": "Phoenix6-replay-frc2025-latest.json" + "offlineFileName": "Phoenix6-frc2026-beta-latest.json" } ], "javaDependencies": [ { "groupId": "com.ctre.phoenix6", "artifactId": "wpiapi-java", - "version": "25.4.0" + "version": "26.0.0-beta-1" } ], "jniDependencies": [ { "groupId": "com.ctre.phoenix6", "artifactId": "api-cpp", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", "linuxathena" ], "simMode": "hwsim" @@ -40,21 +37,18 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "tools", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", "linuxathena" ], "simMode": "hwsim" }, { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "api-cpp-sim", - "version": "25.4.0", + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "api-cpp-replay", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -63,12 +57,12 @@ "linuxarm64", "osxuniversal" ], - "simMode": "swsim" + "simMode": "hwsim" }, { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "tools-sim", - "version": "25.4.0", + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "tools-replay", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -77,12 +71,12 @@ "linuxarm64", "osxuniversal" ], - "simMode": "swsim" + "simMode": "hwsim" }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simTalonSRX", - "version": "25.4.0", + "artifactId": "api-cpp-sim", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -95,8 +89,8 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simVictorSPX", - "version": "25.4.0", + "artifactId": "tools-sim", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -109,8 +103,8 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simPigeonIMU", - "version": "25.4.0", + "artifactId": "simTalonSRX", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -123,8 +117,8 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simCANCoder", - "version": "25.4.0", + "artifactId": "simVictorSPX", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -138,21 +132,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProTalonFX", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFXS", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -166,7 +146,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANcoder", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -180,7 +160,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProPigeon2", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -194,7 +174,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANrange", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -208,7 +188,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdi", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -222,7 +202,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdle", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -238,15 +218,12 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "wpiapi-cpp", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_Phoenix6_WPI", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", "linuxathena" ], "simMode": "hwsim" @@ -254,24 +231,21 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "tools", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_PhoenixTools", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", "linuxathena" ], "simMode": "hwsim" }, { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "wpiapi-cpp-sim", - "version": "25.4.0", - "libName": "CTRE_Phoenix6_WPISim", + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "wpiapi-cpp-replay", + "version": "26.0.0-beta-1", + "libName": "CTRE_Phoenix6_WPIReplay", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -281,13 +255,13 @@ "linuxarm64", "osxuniversal" ], - "simMode": "swsim" + "simMode": "hwsim" }, { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "tools-sim", - "version": "25.4.0", - "libName": "CTRE_PhoenixTools_Sim", + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "tools-replay", + "version": "26.0.0-beta-1", + "libName": "CTRE_PhoenixTools_Replay", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -297,13 +271,13 @@ "linuxarm64", "osxuniversal" ], - "simMode": "swsim" + "simMode": "hwsim" }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simTalonSRX", - "version": "25.4.0", - "libName": "CTRE_SimTalonSRX", + "artifactId": "wpiapi-cpp-sim", + "version": "26.0.0-beta-1", + "libName": "CTRE_Phoenix6_WPISim", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -317,9 +291,9 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simVictorSPX", - "version": "25.4.0", - "libName": "CTRE_SimVictorSPX", + "artifactId": "tools-sim", + "version": "26.0.0-beta-1", + "libName": "CTRE_PhoenixTools_Sim", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -333,9 +307,9 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simPigeonIMU", - "version": "25.4.0", - "libName": "CTRE_SimPigeonIMU", + "artifactId": "simTalonSRX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimTalonSRX", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -349,9 +323,9 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simCANCoder", - "version": "25.4.0", - "libName": "CTRE_SimCANCoder", + "artifactId": "simVictorSPX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimVictorSPX", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -365,9 +339,9 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFX", - "version": "25.4.0", - "libName": "CTRE_SimProTalonFX", + "artifactId": "simPigeonIMU", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimPigeonIMU", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -381,9 +355,9 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFXS", - "version": "25.4.0", - "libName": "CTRE_SimProTalonFXS", + "artifactId": "simProTalonFX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProTalonFX", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -398,7 +372,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANcoder", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_SimProCANcoder", "headerClassifier": "headers", "sharedLibrary": true, @@ -414,7 +388,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProPigeon2", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_SimProPigeon2", "headerClassifier": "headers", "sharedLibrary": true, @@ -430,7 +404,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANrange", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_SimProCANrange", "headerClassifier": "headers", "sharedLibrary": true, @@ -446,7 +420,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdi", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_SimProCANdi", "headerClassifier": "headers", "sharedLibrary": true, @@ -462,7 +436,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdle", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_SimProCANdle", "headerClassifier": "headers", "sharedLibrary": true, diff --git a/examples/clock_drive_drivebase/vendordeps/REVLib.json b/examples/clock_drive_drivebase/vendordeps/REVLib.json index 5546ea8..0f666c9 100644 --- a/examples/clock_drive_drivebase/vendordeps/REVLib.json +++ b/examples/clock_drive_drivebase/vendordeps/REVLib.json @@ -1,25 +1,55 @@ { "fileName": "REVLib.json", "name": "REVLib", - "version": "2025.0.3", - "frcYear": "2025", + "version": "2026.0.0-beta-1", + "frcYear": "2026beta", "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", "mavenUrls": [ "https://maven.revrobotics.com/" ], - "jsonUrl": "https://software-metadata.revrobotics.com/REVLib-2025.json", + "jsonUrl": "https://software-metadata.revrobotics.com/REVLib-2026.json", "javaDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-java", - "version": "2025.0.3" + "version": "2026.0.0-beta-1" } ], "jniDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibBackendDriver", + "version": "2026.0.0-beta-1", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibWpiBackendDriver", + "version": "2026.0.0-beta-1", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -36,7 +66,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-cpp", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", "libName": "REVLib", "headerClassifier": "headers", "sharedLibrary": false, @@ -53,7 +83,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", "libName": "REVLibDriver", "headerClassifier": "headers", "sharedLibrary": false, @@ -66,6 +96,38 @@ "linuxarm32", "osxuniversal" ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibBackendDriver", + "version": "2026.0.0-beta-1", + "libName": "BackendDriver", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibWpiBackendDriver", + "version": "2026.0.0-beta-1", + "libName": "REVLibWpi", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] } ] } \ No newline at end of file diff --git a/examples/clock_drive_drivebase/vendordeps/ReduxLib-2025.0.1.json b/examples/clock_drive_drivebase/vendordeps/ReduxLib-2025.0.1.json deleted file mode 100644 index 007f97f..0000000 --- a/examples/clock_drive_drivebase/vendordeps/ReduxLib-2025.0.1.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "fileName": "ReduxLib-2025.0.1.json", - "name": "ReduxLib", - "version": "2025.0.1", - "frcYear": "2025", - "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", - "mavenUrls": [ - "https://maven.reduxrobotics.com/" - ], - "jsonUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2025.json", - "javaDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-java", - "version": "2025.0.1" - } - ], - "jniDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-driver", - "version": "2025.0.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - } - ], - "cppDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-cpp", - "version": "2025.0.1", - "libName": "ReduxLib", - "headerClassifier": "headers", - "sourcesClassifier": "sources", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - }, - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-driver", - "version": "2025.0.1", - "libName": "ReduxCore", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - } - ] -} \ No newline at end of file diff --git a/examples/clock_drive_drivebase/vendordeps/Studica-2025.0.1.json b/examples/clock_drive_drivebase/vendordeps/Studica-2025.0.1.json deleted file mode 100644 index e0b50d7..0000000 --- a/examples/clock_drive_drivebase/vendordeps/Studica-2025.0.1.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "Studica-2025.0.1.json", - "name": "Studica", - "version": "2025.0.1", - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", - "frcYear": "2025", - "mavenUrls": [ - "https://dev.studica.com/maven/release/2025/" - ], - "jsonUrl": "https://dev.studica.com/releases/2025/Studica-2025.0.1.json", - "cppDependencies": [ - { - "artifactId": "Studica-cpp", - "binaryPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "groupId": "com.studica.frc", - "headerClassifier": "headers", - "libName": "Studica", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "version": "2025.0.1" - }, - { - "artifactId": "Studica-driver", - "binaryPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "groupId": "com.studica.frc", - "headerClassifier": "headers", - "libName": "StudicaDriver", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "version": "2025.0.1" - } - ], - "javaDependencies": [ - { - "artifactId": "Studica-java", - "groupId": "com.studica.frc", - "version": "2025.0.1" - } - ], - "jniDependencies": [ - { - "artifactId": "Studica-driver", - "groupId": "com.studica.frc", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "version": "2025.0.1" - } - ] -} \ No newline at end of file diff --git a/examples/clock_drive_drivebase/vendordeps/Studica-2026.0.0-beta.json b/examples/clock_drive_drivebase/vendordeps/Studica-2026.0.0-beta.json new file mode 100644 index 0000000..c5d48c7 --- /dev/null +++ b/examples/clock_drive_drivebase/vendordeps/Studica-2026.0.0-beta.json @@ -0,0 +1,71 @@ +{ + "fileName": "Studica-2026.0.0-beta.json", + "name": "Studica", + "version": "2026.0.0-beta", + "frcYear": "2026beta", + "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0-beta.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-java", + "version": "2026.0.0-beta" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0-beta", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-cpp", + "version": "2026.0.0-beta", + "libName": "Studica", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0-beta", + "libName": "StudicaDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/examples/clock_drive_drivebase/vendordeps/StudicaLib.json b/examples/clock_drive_drivebase/vendordeps/StudicaLib.json new file mode 100644 index 0000000..b6ed33e --- /dev/null +++ b/examples/clock_drive_drivebase/vendordeps/StudicaLib.json @@ -0,0 +1,71 @@ +{ + "fileName": "StudicaLib.json", + "name": "StudicaLib", + "version": "2026.0.1-beta", + "frcYear": "2026beta", + "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.1-beta.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-java", + "version": "2026.0.1-beta" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.1-beta", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-cpp", + "version": "2026.0.1-beta", + "libName": "StudicaLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.1-beta", + "libName": "StudicaLibDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/examples/clock_drive_drivebase/vendordeps/ThriftyLib.json b/examples/clock_drive_drivebase/vendordeps/ThriftyLib.json index 887721f..1e59797 100644 --- a/examples/clock_drive_drivebase/vendordeps/ThriftyLib.json +++ b/examples/clock_drive_drivebase/vendordeps/ThriftyLib.json @@ -1,8 +1,8 @@ { "fileName": "ThriftyLib.json", "name": "ThriftyLib", - "version": "2025.1.1", - "frcYear": "2025", + "version": "2026.0.0", + "frcYear": "2026beta", "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", "mavenUrls": [ "https://docs.home.thethriftybot.com" @@ -12,9 +12,9 @@ { "groupId": "com.thethriftybot.frc", "artifactId": "ThriftyLib-java", - "version": "2025.1.1" + "version": "2026.0.0" } ], "jniDependencies": [], "cppDependencies": [] -} \ No newline at end of file +} diff --git a/examples/clock_drive_drivebase/vendordeps/WPILibNewCommands.json b/examples/clock_drive_drivebase/vendordeps/WPILibNewCommands.json index 3718e0a..7ebc954 100644 --- a/examples/clock_drive_drivebase/vendordeps/WPILibNewCommands.json +++ b/examples/clock_drive_drivebase/vendordeps/WPILibNewCommands.json @@ -3,7 +3,7 @@ "name": "WPILib-New-Commands", "version": "1.0.0", "uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266", - "frcYear": "2025", + "frcYear": "2026beta", "mavenUrls": [], "jsonUrl": "", "javaDependencies": [ @@ -25,6 +25,7 @@ "sharedLibrary": true, "skipInvalidPlatforms": true, "binaryPlatforms": [ + "linuxsystemcore", "linuxathena", "linuxarm32", "linuxarm64", diff --git a/examples/clock_drive_drivebase/vendordeps/maple-sim.json b/examples/clock_drive_drivebase/vendordeps/maple-sim.json deleted file mode 100644 index 73c812f..0000000 --- a/examples/clock_drive_drivebase/vendordeps/maple-sim.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "fileName": "maple-sim.json", - "name": "maplesim", - "version": "0.3.14", - "frcYear": "2025", - "uuid": "c39481e8-4a63-4a4c-9df6-48d91e4da37b", - "mavenUrls": [ - "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/repos/releases", - "https://repo1.maven.org/maven2" - ], - "jsonUrl": "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/maple-sim.json", - "javaDependencies": [ - { - "groupId": "org.ironmaple", - "artifactId": "maplesim-java", - "version": "0.3.14" - }, - { - "groupId": "org.dyn4j", - "artifactId": "dyn4j", - "version": "5.0.2" - } - ], - "jniDependencies": [], - "cppDependencies": [] -} \ No newline at end of file diff --git a/examples/clock_drive_drivebase/vendordeps/photonlib.json b/examples/clock_drive_drivebase/vendordeps/photonlib.json deleted file mode 100644 index 5c6484d..0000000 --- a/examples/clock_drive_drivebase/vendordeps/photonlib.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "photonlib.json", - "name": "photonlib", - "version": "v2025.3.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.3.1", - "skipInvalidPlatforms": true, - "isJar": false, - "validPlatforms": [ - "windowsx86-64", - "linuxathena", - "linuxx86-64", - "osxuniversal" - ] - } - ], - "cppDependencies": [ - { - "groupId": "org.photonvision", - "artifactId": "photonlib-cpp", - "version": "v2025.3.1", - "libName": "photonlib", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxathena", - "linuxx86-64", - "osxuniversal" - ] - }, - { - "groupId": "org.photonvision", - "artifactId": "photontargeting-cpp", - "version": "v2025.3.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.3.1" - }, - { - "groupId": "org.photonvision", - "artifactId": "photontargeting-java", - "version": "v2025.3.1" - } - ] -} \ No newline at end of file diff --git a/examples/clock_drive_drivebase/vendordeps/yagsl-2025.7.2.json b/examples/clock_drive_drivebase/vendordeps/yagsl-2025.7.2.json deleted file mode 100644 index 9fb6a48..0000000 --- a/examples/clock_drive_drivebase/vendordeps/yagsl-2025.7.2.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "fileName": "yagsl-2025.7.2.json", - "name": "YAGSL", - "version": "2025.7.2", - "frcYear": "2025", - "uuid": "1ccce5a4-acd2-4d18-bca3-4b8047188400", - "mavenUrls": [ - "https://broncbotz3481.github.io/YAGSL-Lib/yagsl/repos" - ], - "jsonUrl": "https://broncbotz3481.github.io/YAGSL-Lib/yagsl/yagsl.json", - "javaDependencies": [ - { - "groupId": "swervelib", - "artifactId": "YAGSL-java", - "version": "2025.7.2" - } - ], - "requires": [ - { - "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", - "errorMessage": "REVLib is required!", - "offlineFileName": "REVLib-2025.0.0.json", - "onlineUrl": "https://software-metadata.revrobotics.com/REVLib-2025.json" - }, - { - "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", - "errorMessage": "ReduxLib is required!", - "offlineFileName": "ReduxLib-2025.0.0.json", - "onlineUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2025.json" - }, - { - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "errorMessage": "Phoenix6 is required!", - "offlineFileName": "Phoenix6-25.1.0.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json" - }, - { - "uuid": "ab676553-b602-441f-a38d-f1296eff6537", - "errorMessage": "Phoenix5 is required!", - "offlineFileName": "Phoenix5-5.35.0.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-frc2025-latest.json" - }, - { - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", - "errorMessage": "Studica is required!", - "offlineFileName": "Studica-2025.0.0.json", - "onlineUrl": "https://dev.studica.com/releases/2025/Studica-2025.0.0.json" - }, - { - "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", - "errorMessage": "ThriftyLib is required!", - "offlineFileName": "ThriftyLib.json", - "onlineUrl": "https://docs.home.thethriftybot.com/ThriftyLib.json" - }, - { - "uuid": "c39481e8-4a63-4a4c-9df6-48d91e4da37b", - "errorMessage": "maple-sim is required for simulation", - "offlineFileName": "maple-sim.json", - "onlineUrl": "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/maple-sim.json" - } - ], - "jniDependencies": [], - "cppDependencies": [] -} \ No newline at end of file diff --git a/examples/drivebase_only/.wpilib/wpilib_preferences.json b/examples/drivebase_only/.wpilib/wpilib_preferences.json index 83517dd..f727ea3 100644 --- a/examples/drivebase_only/.wpilib/wpilib_preferences.json +++ b/examples/drivebase_only/.wpilib/wpilib_preferences.json @@ -1,6 +1,6 @@ { "enableCppIntellisense": false, "currentLanguage": "java", - "projectYear": "2025", + "projectYear": "2026beta", "teamNumber": 3481 } \ No newline at end of file diff --git a/examples/drivebase_only/build.gradle b/examples/drivebase_only/build.gradle index fdf6d52..4233229 100644 --- a/examples/drivebase_only/build.gradle +++ b/examples/drivebase_only/build.gradle @@ -1,6 +1,6 @@ plugins { id "java" - id "edu.wpi.first.GradleRIO" version "2025.3.1" + id "edu.wpi.first.GradleRIO" version "2026.1.1-beta-1" } java { @@ -8,6 +8,14 @@ java { targetCompatibility = JavaVersion.VERSION_17 } +sourceSets { + main { + java { + srcDir '../../yagsl/java/' + } + } +} + def ROBOT_MAIN_CLASS = "frc.robot.Main" // Define my targets (RoboRIO) and artifacts (deployable files) @@ -34,7 +42,7 @@ deploy { files = project.fileTree('src/main/deploy') directory = '/home/lvuser/deploy' deleteOldFiles = false // Change to true to delete files on roboRIO that no - // longer exist in deploy directory of this project + // longer exist in deploy directory of this project } } } @@ -43,7 +51,8 @@ deploy { def deployArtifact = deploy.targets.roborio.artifacts.frcJava -// Set to true to use debug for JNI. +// Set to true to use debug for all targets including JNI, which will drastically impact +// performance. wpi.java.debugJni = false // Set this to true to enable desktop support. @@ -69,6 +78,7 @@ dependencies { nativeRelease wpi.java.deps.wpilibJniRelease(wpi.platforms.desktop) nativeRelease wpi.java.vendor.jniRelease(wpi.platforms.desktop) simulationRelease wpi.sim.enableRelease() + implementation 'org.dyn4j:dyn4j:5.0.2' testImplementation 'org.junit.jupiter:junit-jupiter:5.10.1' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' diff --git a/examples/drivebase_only/settings.gradle b/examples/drivebase_only/settings.gradle index 969c7b0..25f6f6e 100644 --- a/examples/drivebase_only/settings.gradle +++ b/examples/drivebase_only/settings.gradle @@ -4,7 +4,7 @@ pluginManagement { repositories { mavenLocal() gradlePluginPortal() - String frcYear = '2025' + String frcYear = '2026' File frcHome if (OperatingSystem.current().isWindows()) { String publicFolder = System.getenv('PUBLIC') @@ -20,8 +20,8 @@ pluginManagement { } def frcHomeMaven = new File(frcHome, 'maven') maven { - name 'frcHome' - url frcHomeMaven + name = 'frcHome' + url = frcHomeMaven } } } diff --git a/examples/drivebase_only/vendordeps/Phoenix5-frc2025-latest.json b/examples/drivebase_only/vendordeps/Phoenix5-frc2025-latest.json deleted file mode 100644 index 3cbc8f6..0000000 --- a/examples/drivebase_only/vendordeps/Phoenix5-frc2025-latest.json +++ /dev/null @@ -1,171 +0,0 @@ -{ - "fileName": "Phoenix5-frc2025-latest.json", - "name": "CTRE-Phoenix (v5)", - "version": "5.35.1", - "frcYear": "2025", - "uuid": "ab676553-b602-441f-a38d-f1296eff6537", - "mavenUrls": [ - "https://maven.ctr-electronics.com/release/" - ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-frc2025-latest.json", - "requires": [ - { - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", - "offlineFileName": "Phoenix6-frc2025-latest.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json" - } - ], - "conflictsWith": [ - { - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", - "errorMessage": "Users must use the Phoenix 5 replay vendordep when using the Phoenix 6 replay vendordep.", - "offlineFileName": "Phoenix6-replay-frc2025-latest.json" - }, - { - "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", - "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", - "offlineFileName": "Phoenix5-replay-frc2025-latest.json" - } - ], - "javaDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "api-java", - "version": "5.35.1" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "wpiapi-java", - "version": "5.35.1" - } - ], - "jniDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "cci", - "version": "5.35.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "cci-sim", - "version": "5.35.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ], - "cppDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "wpiapi-cpp", - "version": "5.35.1", - "libName": "CTRE_Phoenix_WPI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "api-cpp", - "version": "5.35.1", - "libName": "CTRE_Phoenix", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "cci", - "version": "5.35.1", - "libName": "CTRE_PhoenixCCI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "wpiapi-cpp-sim", - "version": "5.35.1", - "libName": "CTRE_Phoenix_WPISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "api-cpp-sim", - "version": "5.35.1", - "libName": "CTRE_PhoenixSim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "cci-sim", - "version": "5.35.1", - "libName": "CTRE_PhoenixCCISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ] -} \ No newline at end of file diff --git a/examples/drivebase_only/vendordeps/Phoenix5-replay-5.36.0-beta-1.json b/examples/drivebase_only/vendordeps/Phoenix5-replay-5.36.0-beta-1.json new file mode 100644 index 0000000..4a78551 --- /dev/null +++ b/examples/drivebase_only/vendordeps/Phoenix5-replay-5.36.0-beta-1.json @@ -0,0 +1,221 @@ +{ + "fileName": "Phoenix5-replay-5.36.0-beta-1.json", + "name": "CTRE-Phoenix (v5)", + "version": "5.36.0-beta-1", + "frcYear": "2026beta", + "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", + "mavenUrls": [ + "https://maven.ctr-electronics.com/release/" + ], + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-beta-latest.json", + "requires": [ + { + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", + "offlineFileName": "Phoenix6-replay-frc2026-beta-latest.json", + "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json" + } + ], + "conflictsWith": [ + { + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "errorMessage": "Users must use the regular Phoenix 5 vendordep when using the regular Phoenix 6 vendordep.", + "offlineFileName": "Phoenix6-frc2026-beta-latest.json" + }, + { + "uuid": "ab676553-b602-441f-a38d-f1296eff6537", + "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", + "offlineFileName": "Phoenix5-frc2026-beta-latest.json" + } + ], + "javaDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-java", + "version": "5.36.0-beta-1" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-java", + "version": "5.36.0-beta-1" + } + ], + "jniDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "cci-replay", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ], + "cppDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-cpp", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-cpp", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "wpiapi-cpp-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "api-cpp-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "cci-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "wpiapi-cpp-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "api-cpp-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixSim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ] +} \ No newline at end of file diff --git a/examples/clock_drive_drivebase/vendordeps/Phoenix6-frc2025-latest.json b/examples/drivebase_only/vendordeps/Phoenix6-replay-26.0.0-beta-1.json similarity index 81% rename from examples/clock_drive_drivebase/vendordeps/Phoenix6-frc2025-latest.json rename to examples/drivebase_only/vendordeps/Phoenix6-replay-26.0.0-beta-1.json index 6f40c84..5312c86 100644 --- a/examples/clock_drive_drivebase/vendordeps/Phoenix6-frc2025-latest.json +++ b/examples/drivebase_only/vendordeps/Phoenix6-replay-26.0.0-beta-1.json @@ -1,38 +1,35 @@ { - "fileName": "Phoenix6-frc2025-latest.json", - "name": "CTRE-Phoenix (v6)", - "version": "25.4.0", - "frcYear": "2025", - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "fileName": "Phoenix6-replay-26.0.0-beta-1.json", + "name": "CTRE-Phoenix (v6) Replay", + "version": "26.0.0-beta-1", + "frcYear": "2026beta", + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", "mavenUrls": [ "https://maven.ctr-electronics.com/release/" ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json", + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json", "conflictsWith": [ { - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", "errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.", - "offlineFileName": "Phoenix6-replay-frc2025-latest.json" + "offlineFileName": "Phoenix6-frc2026-beta-latest.json" } ], "javaDependencies": [ { "groupId": "com.ctre.phoenix6", "artifactId": "wpiapi-java", - "version": "25.4.0" + "version": "26.0.0-beta-1" } ], "jniDependencies": [ { "groupId": "com.ctre.phoenix6", "artifactId": "api-cpp", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", "linuxathena" ], "simMode": "hwsim" @@ -40,21 +37,18 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "tools", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", "linuxathena" ], "simMode": "hwsim" }, { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "api-cpp-sim", - "version": "25.4.0", + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "api-cpp-replay", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -63,12 +57,12 @@ "linuxarm64", "osxuniversal" ], - "simMode": "swsim" + "simMode": "hwsim" }, { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "tools-sim", - "version": "25.4.0", + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "tools-replay", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -77,12 +71,12 @@ "linuxarm64", "osxuniversal" ], - "simMode": "swsim" + "simMode": "hwsim" }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simTalonSRX", - "version": "25.4.0", + "artifactId": "api-cpp-sim", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -95,8 +89,8 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simVictorSPX", - "version": "25.4.0", + "artifactId": "tools-sim", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -109,8 +103,8 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simPigeonIMU", - "version": "25.4.0", + "artifactId": "simTalonSRX", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -123,8 +117,8 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simCANCoder", - "version": "25.4.0", + "artifactId": "simVictorSPX", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -138,21 +132,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProTalonFX", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFXS", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -166,7 +146,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANcoder", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -180,7 +160,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProPigeon2", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -194,7 +174,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANrange", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -208,7 +188,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdi", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -222,7 +202,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdle", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -238,15 +218,12 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "wpiapi-cpp", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_Phoenix6_WPI", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", "linuxathena" ], "simMode": "hwsim" @@ -254,24 +231,21 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "tools", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_PhoenixTools", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", "linuxathena" ], "simMode": "hwsim" }, { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "wpiapi-cpp-sim", - "version": "25.4.0", - "libName": "CTRE_Phoenix6_WPISim", + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "wpiapi-cpp-replay", + "version": "26.0.0-beta-1", + "libName": "CTRE_Phoenix6_WPIReplay", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -281,13 +255,13 @@ "linuxarm64", "osxuniversal" ], - "simMode": "swsim" + "simMode": "hwsim" }, { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "tools-sim", - "version": "25.4.0", - "libName": "CTRE_PhoenixTools_Sim", + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "tools-replay", + "version": "26.0.0-beta-1", + "libName": "CTRE_PhoenixTools_Replay", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -297,13 +271,13 @@ "linuxarm64", "osxuniversal" ], - "simMode": "swsim" + "simMode": "hwsim" }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simTalonSRX", - "version": "25.4.0", - "libName": "CTRE_SimTalonSRX", + "artifactId": "wpiapi-cpp-sim", + "version": "26.0.0-beta-1", + "libName": "CTRE_Phoenix6_WPISim", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -317,9 +291,9 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simVictorSPX", - "version": "25.4.0", - "libName": "CTRE_SimVictorSPX", + "artifactId": "tools-sim", + "version": "26.0.0-beta-1", + "libName": "CTRE_PhoenixTools_Sim", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -333,9 +307,9 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simPigeonIMU", - "version": "25.4.0", - "libName": "CTRE_SimPigeonIMU", + "artifactId": "simTalonSRX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimTalonSRX", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -349,9 +323,9 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simCANCoder", - "version": "25.4.0", - "libName": "CTRE_SimCANCoder", + "artifactId": "simVictorSPX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimVictorSPX", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -365,9 +339,9 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFX", - "version": "25.4.0", - "libName": "CTRE_SimProTalonFX", + "artifactId": "simPigeonIMU", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimPigeonIMU", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -381,9 +355,9 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFXS", - "version": "25.4.0", - "libName": "CTRE_SimProTalonFXS", + "artifactId": "simProTalonFX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProTalonFX", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -398,7 +372,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANcoder", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_SimProCANcoder", "headerClassifier": "headers", "sharedLibrary": true, @@ -414,7 +388,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProPigeon2", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_SimProPigeon2", "headerClassifier": "headers", "sharedLibrary": true, @@ -430,7 +404,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANrange", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_SimProCANrange", "headerClassifier": "headers", "sharedLibrary": true, @@ -446,7 +420,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdi", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_SimProCANdi", "headerClassifier": "headers", "sharedLibrary": true, @@ -462,7 +436,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdle", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_SimProCANdle", "headerClassifier": "headers", "sharedLibrary": true, diff --git a/examples/drivebase_only/vendordeps/REVLib.json b/examples/drivebase_only/vendordeps/REVLib.json index 5546ea8..0f666c9 100644 --- a/examples/drivebase_only/vendordeps/REVLib.json +++ b/examples/drivebase_only/vendordeps/REVLib.json @@ -1,25 +1,55 @@ { "fileName": "REVLib.json", "name": "REVLib", - "version": "2025.0.3", - "frcYear": "2025", + "version": "2026.0.0-beta-1", + "frcYear": "2026beta", "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", "mavenUrls": [ "https://maven.revrobotics.com/" ], - "jsonUrl": "https://software-metadata.revrobotics.com/REVLib-2025.json", + "jsonUrl": "https://software-metadata.revrobotics.com/REVLib-2026.json", "javaDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-java", - "version": "2025.0.3" + "version": "2026.0.0-beta-1" } ], "jniDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibBackendDriver", + "version": "2026.0.0-beta-1", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibWpiBackendDriver", + "version": "2026.0.0-beta-1", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -36,7 +66,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-cpp", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", "libName": "REVLib", "headerClassifier": "headers", "sharedLibrary": false, @@ -53,7 +83,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", "libName": "REVLibDriver", "headerClassifier": "headers", "sharedLibrary": false, @@ -66,6 +96,38 @@ "linuxarm32", "osxuniversal" ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibBackendDriver", + "version": "2026.0.0-beta-1", + "libName": "BackendDriver", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibWpiBackendDriver", + "version": "2026.0.0-beta-1", + "libName": "REVLibWpi", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] } ] } \ No newline at end of file diff --git a/examples/drivebase_only/vendordeps/ReduxLib-2025.0.1.json b/examples/drivebase_only/vendordeps/ReduxLib-2025.0.1.json deleted file mode 100644 index 007f97f..0000000 --- a/examples/drivebase_only/vendordeps/ReduxLib-2025.0.1.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "fileName": "ReduxLib-2025.0.1.json", - "name": "ReduxLib", - "version": "2025.0.1", - "frcYear": "2025", - "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", - "mavenUrls": [ - "https://maven.reduxrobotics.com/" - ], - "jsonUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2025.json", - "javaDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-java", - "version": "2025.0.1" - } - ], - "jniDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-driver", - "version": "2025.0.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - } - ], - "cppDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-cpp", - "version": "2025.0.1", - "libName": "ReduxLib", - "headerClassifier": "headers", - "sourcesClassifier": "sources", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - }, - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-driver", - "version": "2025.0.1", - "libName": "ReduxCore", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - } - ] -} \ No newline at end of file diff --git a/examples/drivebase_only/vendordeps/Studica-2025.0.1.json b/examples/drivebase_only/vendordeps/Studica-2025.0.1.json deleted file mode 100644 index e0b50d7..0000000 --- a/examples/drivebase_only/vendordeps/Studica-2025.0.1.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "Studica-2025.0.1.json", - "name": "Studica", - "version": "2025.0.1", - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", - "frcYear": "2025", - "mavenUrls": [ - "https://dev.studica.com/maven/release/2025/" - ], - "jsonUrl": "https://dev.studica.com/releases/2025/Studica-2025.0.1.json", - "cppDependencies": [ - { - "artifactId": "Studica-cpp", - "binaryPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "groupId": "com.studica.frc", - "headerClassifier": "headers", - "libName": "Studica", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "version": "2025.0.1" - }, - { - "artifactId": "Studica-driver", - "binaryPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "groupId": "com.studica.frc", - "headerClassifier": "headers", - "libName": "StudicaDriver", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "version": "2025.0.1" - } - ], - "javaDependencies": [ - { - "artifactId": "Studica-java", - "groupId": "com.studica.frc", - "version": "2025.0.1" - } - ], - "jniDependencies": [ - { - "artifactId": "Studica-driver", - "groupId": "com.studica.frc", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "version": "2025.0.1" - } - ] -} \ No newline at end of file diff --git a/examples/drivebase_only/vendordeps/Studica-2026.0.0-beta.json b/examples/drivebase_only/vendordeps/Studica-2026.0.0-beta.json new file mode 100644 index 0000000..c5d48c7 --- /dev/null +++ b/examples/drivebase_only/vendordeps/Studica-2026.0.0-beta.json @@ -0,0 +1,71 @@ +{ + "fileName": "Studica-2026.0.0-beta.json", + "name": "Studica", + "version": "2026.0.0-beta", + "frcYear": "2026beta", + "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0-beta.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-java", + "version": "2026.0.0-beta" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0-beta", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-cpp", + "version": "2026.0.0-beta", + "libName": "Studica", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0-beta", + "libName": "StudicaDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/examples/drivebase_only/vendordeps/StudicaLib.json b/examples/drivebase_only/vendordeps/StudicaLib.json new file mode 100644 index 0000000..b6ed33e --- /dev/null +++ b/examples/drivebase_only/vendordeps/StudicaLib.json @@ -0,0 +1,71 @@ +{ + "fileName": "StudicaLib.json", + "name": "StudicaLib", + "version": "2026.0.1-beta", + "frcYear": "2026beta", + "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.1-beta.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-java", + "version": "2026.0.1-beta" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.1-beta", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-cpp", + "version": "2026.0.1-beta", + "libName": "StudicaLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.1-beta", + "libName": "StudicaLibDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/examples/drivebase_only/vendordeps/ThriftyLib.json b/examples/drivebase_only/vendordeps/ThriftyLib.json index 887721f..1e59797 100644 --- a/examples/drivebase_only/vendordeps/ThriftyLib.json +++ b/examples/drivebase_only/vendordeps/ThriftyLib.json @@ -1,8 +1,8 @@ { "fileName": "ThriftyLib.json", "name": "ThriftyLib", - "version": "2025.1.1", - "frcYear": "2025", + "version": "2026.0.0", + "frcYear": "2026beta", "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", "mavenUrls": [ "https://docs.home.thethriftybot.com" @@ -12,9 +12,9 @@ { "groupId": "com.thethriftybot.frc", "artifactId": "ThriftyLib-java", - "version": "2025.1.1" + "version": "2026.0.0" } ], "jniDependencies": [], "cppDependencies": [] -} \ No newline at end of file +} diff --git a/examples/drivebase_only/vendordeps/WPILibNewCommands.json b/examples/drivebase_only/vendordeps/WPILibNewCommands.json index 3718e0a..7ebc954 100644 --- a/examples/drivebase_only/vendordeps/WPILibNewCommands.json +++ b/examples/drivebase_only/vendordeps/WPILibNewCommands.json @@ -3,7 +3,7 @@ "name": "WPILib-New-Commands", "version": "1.0.0", "uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266", - "frcYear": "2025", + "frcYear": "2026beta", "mavenUrls": [], "jsonUrl": "", "javaDependencies": [ @@ -25,6 +25,7 @@ "sharedLibrary": true, "skipInvalidPlatforms": true, "binaryPlatforms": [ + "linuxsystemcore", "linuxathena", "linuxarm32", "linuxarm64", diff --git a/examples/drivebase_only/vendordeps/maple-sim.json b/examples/drivebase_only/vendordeps/maple-sim.json deleted file mode 100644 index 73c812f..0000000 --- a/examples/drivebase_only/vendordeps/maple-sim.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "fileName": "maple-sim.json", - "name": "maplesim", - "version": "0.3.14", - "frcYear": "2025", - "uuid": "c39481e8-4a63-4a4c-9df6-48d91e4da37b", - "mavenUrls": [ - "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/repos/releases", - "https://repo1.maven.org/maven2" - ], - "jsonUrl": "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/maple-sim.json", - "javaDependencies": [ - { - "groupId": "org.ironmaple", - "artifactId": "maplesim-java", - "version": "0.3.14" - }, - { - "groupId": "org.dyn4j", - "artifactId": "dyn4j", - "version": "5.0.2" - } - ], - "jniDependencies": [], - "cppDependencies": [] -} \ No newline at end of file diff --git a/examples/drivebase_only/vendordeps/photonlib.json b/examples/drivebase_only/vendordeps/photonlib.json deleted file mode 100644 index 5c6484d..0000000 --- a/examples/drivebase_only/vendordeps/photonlib.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "photonlib.json", - "name": "photonlib", - "version": "v2025.3.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.3.1", - "skipInvalidPlatforms": true, - "isJar": false, - "validPlatforms": [ - "windowsx86-64", - "linuxathena", - "linuxx86-64", - "osxuniversal" - ] - } - ], - "cppDependencies": [ - { - "groupId": "org.photonvision", - "artifactId": "photonlib-cpp", - "version": "v2025.3.1", - "libName": "photonlib", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxathena", - "linuxx86-64", - "osxuniversal" - ] - }, - { - "groupId": "org.photonvision", - "artifactId": "photontargeting-cpp", - "version": "v2025.3.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.3.1" - }, - { - "groupId": "org.photonvision", - "artifactId": "photontargeting-java", - "version": "v2025.3.1" - } - ] -} \ No newline at end of file diff --git a/examples/drivebase_only/vendordeps/yagsl-2025.7.2.json b/examples/drivebase_only/vendordeps/yagsl-2025.7.2.json deleted file mode 100644 index 9fb6a48..0000000 --- a/examples/drivebase_only/vendordeps/yagsl-2025.7.2.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "fileName": "yagsl-2025.7.2.json", - "name": "YAGSL", - "version": "2025.7.2", - "frcYear": "2025", - "uuid": "1ccce5a4-acd2-4d18-bca3-4b8047188400", - "mavenUrls": [ - "https://broncbotz3481.github.io/YAGSL-Lib/yagsl/repos" - ], - "jsonUrl": "https://broncbotz3481.github.io/YAGSL-Lib/yagsl/yagsl.json", - "javaDependencies": [ - { - "groupId": "swervelib", - "artifactId": "YAGSL-java", - "version": "2025.7.2" - } - ], - "requires": [ - { - "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", - "errorMessage": "REVLib is required!", - "offlineFileName": "REVLib-2025.0.0.json", - "onlineUrl": "https://software-metadata.revrobotics.com/REVLib-2025.json" - }, - { - "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", - "errorMessage": "ReduxLib is required!", - "offlineFileName": "ReduxLib-2025.0.0.json", - "onlineUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2025.json" - }, - { - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "errorMessage": "Phoenix6 is required!", - "offlineFileName": "Phoenix6-25.1.0.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json" - }, - { - "uuid": "ab676553-b602-441f-a38d-f1296eff6537", - "errorMessage": "Phoenix5 is required!", - "offlineFileName": "Phoenix5-5.35.0.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-frc2025-latest.json" - }, - { - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", - "errorMessage": "Studica is required!", - "offlineFileName": "Studica-2025.0.0.json", - "onlineUrl": "https://dev.studica.com/releases/2025/Studica-2025.0.0.json" - }, - { - "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", - "errorMessage": "ThriftyLib is required!", - "offlineFileName": "ThriftyLib.json", - "onlineUrl": "https://docs.home.thethriftybot.com/ThriftyLib.json" - }, - { - "uuid": "c39481e8-4a63-4a4c-9df6-48d91e4da37b", - "errorMessage": "maple-sim is required for simulation", - "offlineFileName": "maple-sim.json", - "onlineUrl": "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/maple-sim.json" - } - ], - "jniDependencies": [], - "cppDependencies": [] -} \ No newline at end of file diff --git a/examples/drivebase_only_2026/.gitignore b/examples/drivebase_only_2026/.gitignore new file mode 100644 index 0000000..34cbaac --- /dev/null +++ b/examples/drivebase_only_2026/.gitignore @@ -0,0 +1,187 @@ +# This gitignore has been specially created by the WPILib team. +# If you remove items from this file, intellisense might break. + +### C++ ### +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +### Java ### +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +### Gradle ### +.gradle +/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + +# # VS Code Specific Java Settings +# DO NOT REMOVE .classpath and .project +.classpath +.project +.settings/ +bin/ + +# IntelliJ +*.iml +*.ipr +*.iws +.idea/ +out/ + +# Fleet +.fleet + +# Simulation GUI and other tools window save file +networktables.json +simgui.json +*-window.json + +# Simulation data log directory +logs/ + +# Folder that has CTRE Phoenix Sim device config storage +ctre_sim/ + +# clangd +/.cache +compile_commands.json + +# Eclipse generated file for annotation processors +.factorypath diff --git a/examples/drivebase_only_2026/.vscode/launch.json b/examples/drivebase_only_2026/.vscode/launch.json new file mode 100644 index 0000000..c9c9713 --- /dev/null +++ b/examples/drivebase_only_2026/.vscode/launch.json @@ -0,0 +1,21 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + + { + "type": "wpilib", + "name": "WPILib Desktop Debug", + "request": "launch", + "desktop": true, + }, + { + "type": "wpilib", + "name": "WPILib roboRIO Debug", + "request": "launch", + "desktop": false, + } + ] +} diff --git a/examples/drivebase_only_2026/.vscode/settings.json b/examples/drivebase_only_2026/.vscode/settings.json new file mode 100644 index 0000000..5e6ede8 --- /dev/null +++ b/examples/drivebase_only_2026/.vscode/settings.json @@ -0,0 +1,61 @@ +{ + "java.configuration.updateBuildConfiguration": "automatic", + "java.server.launchMode": "Standard", + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true, + "bin/": true, + "**/.classpath": true, + "**/.project": true, + "**/.settings": true, + "**/.factorypath": true, + "**/*~": true + }, + "java.test.config": [ + { + "name": "WPIlibUnitTests", + "workingDirectory": "${workspaceFolder}/build/jni/release", + "vmargs": [ "-Djava.library.path=${workspaceFolder}/build/jni/release" ], + "env": { + "LD_LIBRARY_PATH": "${workspaceFolder}/build/jni/release" , + "DYLD_LIBRARY_PATH": "${workspaceFolder}/build/jni/release" + } + }, + ], + "java.test.defaultConfig": "WPIlibUnitTests", + "java.import.gradle.annotationProcessing.enabled": false, + "java.completion.favoriteStaticMembers": [ + "org.junit.Assert.*", + "org.junit.Assume.*", + "org.junit.jupiter.api.Assertions.*", + "org.junit.jupiter.api.Assumptions.*", + "org.junit.jupiter.api.DynamicContainer.*", + "org.junit.jupiter.api.DynamicTest.*", + "org.mockito.Mockito.*", + "org.mockito.ArgumentMatchers.*", + "org.mockito.Answers.*", + "edu.wpi.first.units.Units.*" + ], + "java.completion.filteredTypes": [ + "java.awt.*", + "com.sun.*", + "sun.*", + "jdk.*", + "org.graalvm.*", + "io.micrometer.shaded.*", + "java.beans.*", + "java.util.Base64.*", + "java.util.Timer", + "java.sql.*", + "javax.swing.*", + "javax.management.*", + "javax.smartcardio.*", + "edu.wpi.first.math.proto.*", + "edu.wpi.first.math.**.proto.*", + "edu.wpi.first.math.**.struct.*", + ], + "java.dependency.enableDependencyCheckup": false +} diff --git a/examples/drivebase_only_2026/.wpilib/wpilib_preferences.json b/examples/drivebase_only_2026/.wpilib/wpilib_preferences.json new file mode 100644 index 0000000..f727ea3 --- /dev/null +++ b/examples/drivebase_only_2026/.wpilib/wpilib_preferences.json @@ -0,0 +1,6 @@ +{ + "enableCppIntellisense": false, + "currentLanguage": "java", + "projectYear": "2026beta", + "teamNumber": 3481 +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/WPILib-License.md b/examples/drivebase_only_2026/WPILib-License.md new file mode 100644 index 0000000..645e542 --- /dev/null +++ b/examples/drivebase_only_2026/WPILib-License.md @@ -0,0 +1,24 @@ +Copyright (c) 2009-2024 FIRST and other WPILib contributors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of FIRST, WPILib, nor the names of other WPILib + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY FIRST AND OTHER WPILIB CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY NONINFRINGEMENT AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FIRST OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/examples/drivebase_only_2026/build.gradle b/examples/drivebase_only_2026/build.gradle new file mode 100644 index 0000000..4233229 --- /dev/null +++ b/examples/drivebase_only_2026/build.gradle @@ -0,0 +1,114 @@ +plugins { + id "java" + id "edu.wpi.first.GradleRIO" version "2026.1.1-beta-1" +} + +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} + +sourceSets { + main { + java { + srcDir '../../yagsl/java/' + } + } +} + +def ROBOT_MAIN_CLASS = "frc.robot.Main" + +// Define my targets (RoboRIO) and artifacts (deployable files) +// This is added by GradleRIO's backing project DeployUtils. +deploy { + targets { + roborio(getTargetTypeClass('RoboRIO')) { + // Team number is loaded either from the .wpilib/wpilib_preferences.json + // or from command line. If not found an exception will be thrown. + // You can use getTeamOrDefault(team) instead of getTeamNumber if you + // want to store a team number in this file. + team = project.frc.getTeamNumber() + debug = project.frc.getDebugOrDefault(false) + + artifacts { + // First part is artifact name, 2nd is artifact type + // getTargetTypeClass is a shortcut to get the class type using a string + + frcJava(getArtifactTypeClass('FRCJavaArtifact')) { + } + + // Static files artifact + 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 + // longer exist in deploy directory of this project + } + } + } + } +} + +def deployArtifact = deploy.targets.roborio.artifacts.frcJava + +// Set to true to use debug for all targets including JNI, which will drastically impact +// performance. +wpi.java.debugJni = false + +// Set this to true to enable desktop support. +def includeDesktopSupport = true + +// Defining my dependencies. In this case, WPILib (+ friends), and vendor libraries. +// Also defines JUnit 5. +dependencies { + annotationProcessor wpi.java.deps.wpilibAnnotations() + implementation wpi.java.deps.wpilib() + implementation wpi.java.vendor.java() + + roborioDebug wpi.java.deps.wpilibJniDebug(wpi.platforms.roborio) + roborioDebug wpi.java.vendor.jniDebug(wpi.platforms.roborio) + + roborioRelease wpi.java.deps.wpilibJniRelease(wpi.platforms.roborio) + roborioRelease wpi.java.vendor.jniRelease(wpi.platforms.roborio) + + nativeDebug wpi.java.deps.wpilibJniDebug(wpi.platforms.desktop) + nativeDebug wpi.java.vendor.jniDebug(wpi.platforms.desktop) + simulationDebug wpi.sim.enableDebug() + + nativeRelease wpi.java.deps.wpilibJniRelease(wpi.platforms.desktop) + nativeRelease wpi.java.vendor.jniRelease(wpi.platforms.desktop) + simulationRelease wpi.sim.enableRelease() + implementation 'org.dyn4j:dyn4j:5.0.2' + + testImplementation 'org.junit.jupiter:junit-jupiter:5.10.1' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' +} + +test { + useJUnitPlatform() + systemProperty 'junit.jupiter.extensions.autodetection.enabled', 'true' +} + +// Simulation configuration (e.g. environment variables). +wpi.sim.addGui().defaultEnabled = true +wpi.sim.addDriverstation() + +// Setting up my Jar File. In this case, adding all libraries into the main jar ('fat jar') +// in order to make them all available at runtime. Also adding the manifest so WPILib +// knows where to look for our Robot Class. +jar { + from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } + from sourceSets.main.allSource + manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) + duplicatesStrategy = DuplicatesStrategy.INCLUDE +} + +// Configure jar and deploy tasks +deployArtifact.jarTask = jar +wpi.java.configureExecutableTasks(jar) +wpi.java.configureTestTasks(test) + +// Configure string concat to always inline compile +tasks.withType(JavaCompile) { + options.compilerArgs.add '-XDstringConcat=inline' +} diff --git a/examples/drivebase_only_2026/gradle/wrapper/gradle-wrapper.jar b/examples/drivebase_only_2026/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..a4b76b9530d66f5e68d973ea569d8e19de379189 GIT binary patch literal 43583 zcma&N1CXTcmMvW9vTb(Rwr$&4wr$(C?dmSu>@vG-+vuvg^_??!{yS%8zW-#zn-LkA z5&1^$^{lnmUON?}LBF8_K|(?T0Ra(xUH{($5eN!MR#ZihR#HxkUPe+_R8Cn`RRs(P z_^*#_XlXmGv7!4;*Y%p4nw?{bNp@UZHv1?Um8r6)Fei3p@ClJn0ECfg1hkeuUU@Or zDaPa;U3fE=3L}DooL;8f;P0ipPt0Z~9P0)lbStMS)ag54=uL9ia-Lm3nh|@(Y?B`; zx_#arJIpXH!U{fbCbI^17}6Ri*H<>OLR%c|^mh8+)*h~K8Z!9)DPf zR2h?lbDZQ`p9P;&DQ4F0sur@TMa!Y}S8irn(%d-gi0*WxxCSk*A?3lGh=gcYN?FGl z7D=Js!i~0=u3rox^eO3i@$0=n{K1lPNU zwmfjRVmLOCRfe=seV&P*1Iq=^i`502keY8Uy-WNPwVNNtJFx?IwAyRPZo2Wo1+S(xF37LJZ~%i)kpFQ3Fw=mXfd@>%+)RpYQLnr}B~~zoof(JVm^^&f zxKV^+3D3$A1G;qh4gPVjhrC8e(VYUHv#dy^)(RoUFM?o%W-EHxufuWf(l*@-l+7vt z=l`qmR56K~F|v<^Pd*p~1_y^P0P^aPC##d8+HqX4IR1gu+7w#~TBFphJxF)T$2WEa zxa?H&6=Qe7d(#tha?_1uQys2KtHQ{)Qco)qwGjrdNL7thd^G5i8Os)CHqc>iOidS} z%nFEDdm=GXBw=yXe1W-ShHHFb?Cc70+$W~z_+}nAoHFYI1MV1wZegw*0y^tC*s%3h zhD3tN8b=Gv&rj}!SUM6|ajSPp*58KR7MPpI{oAJCtY~JECm)*m_x>AZEu>DFgUcby z1Qaw8lU4jZpQ_$;*7RME+gq1KySGG#Wql>aL~k9tLrSO()LWn*q&YxHEuzmwd1?aAtI zBJ>P=&$=l1efe1CDU;`Fd+_;&wI07?V0aAIgc(!{a z0Jg6Y=inXc3^n!U0Atk`iCFIQooHqcWhO(qrieUOW8X(x?(RD}iYDLMjSwffH2~tB z)oDgNBLB^AJBM1M^c5HdRx6fBfka`(LD-qrlh5jqH~);#nw|iyp)()xVYak3;Ybik z0j`(+69aK*B>)e_p%=wu8XC&9e{AO4c~O1U`5X9}?0mrd*m$_EUek{R?DNSh(=br# z#Q61gBzEpmy`$pA*6!87 zSDD+=@fTY7<4A?GLqpA?Pb2z$pbCc4B4zL{BeZ?F-8`s$?>*lXXtn*NC61>|*w7J* z$?!iB{6R-0=KFmyp1nnEmLsA-H0a6l+1uaH^g%c(p{iT&YFrbQ$&PRb8Up#X3@Zsk zD^^&LK~111%cqlP%!_gFNa^dTYT?rhkGl}5=fL{a`UViaXWI$k-UcHJwmaH1s=S$4 z%4)PdWJX;hh5UoK?6aWoyLxX&NhNRqKam7tcOkLh{%j3K^4Mgx1@i|Pi&}<^5>hs5 zm8?uOS>%)NzT(%PjVPGa?X%`N2TQCKbeH2l;cTnHiHppPSJ<7y-yEIiC!P*ikl&!B z%+?>VttCOQM@ShFguHVjxX^?mHX^hSaO_;pnyh^v9EumqSZTi+#f&_Vaija0Q-e*| z7ulQj6Fs*bbmsWp{`auM04gGwsYYdNNZcg|ph0OgD>7O}Asn7^Z=eI>`$2*v78;sj-}oMoEj&@)9+ycEOo92xSyY344^ z11Hb8^kdOvbf^GNAK++bYioknrpdN>+u8R?JxG=!2Kd9r=YWCOJYXYuM0cOq^FhEd zBg2puKy__7VT3-r*dG4c62Wgxi52EMCQ`bKgf*#*ou(D4-ZN$+mg&7$u!! z-^+Z%;-3IDwqZ|K=ah85OLwkO zKxNBh+4QHh)u9D?MFtpbl)us}9+V!D%w9jfAMYEb>%$A;u)rrI zuBudh;5PN}_6J_}l55P3l_)&RMlH{m!)ai-i$g)&*M`eN$XQMw{v^r@-125^RRCF0 z^2>|DxhQw(mtNEI2Kj(;KblC7x=JlK$@78`O~>V!`|1Lm-^JR$-5pUANAnb(5}B}JGjBsliK4& zk6y(;$e&h)lh2)L=bvZKbvh@>vLlreBdH8No2>$#%_Wp1U0N7Ank!6$dFSi#xzh|( zRi{Uw%-4W!{IXZ)fWx@XX6;&(m_F%c6~X8hx=BN1&q}*( zoaNjWabE{oUPb!Bt$eyd#$5j9rItB-h*5JiNi(v^e|XKAj*8(k<5-2$&ZBR5fF|JA z9&m4fbzNQnAU}r8ab>fFV%J0z5awe#UZ|bz?Ur)U9bCIKWEzi2%A+5CLqh?}K4JHi z4vtM;+uPsVz{Lfr;78W78gC;z*yTch~4YkLr&m-7%-xc ztw6Mh2d>_iO*$Rd8(-Cr1_V8EO1f*^@wRoSozS) zy1UoC@pruAaC8Z_7~_w4Q6n*&B0AjOmMWa;sIav&gu z|J5&|{=a@vR!~k-OjKEgPFCzcJ>#A1uL&7xTDn;{XBdeM}V=l3B8fE1--DHjSaxoSjNKEM9|U9#m2<3>n{Iuo`r3UZp;>GkT2YBNAh|b z^jTq-hJp(ebZh#Lk8hVBP%qXwv-@vbvoREX$TqRGTgEi$%_F9tZES@z8Bx}$#5eeG zk^UsLBH{bc2VBW)*EdS({yw=?qmevwi?BL6*=12k9zM5gJv1>y#ML4!)iiPzVaH9% zgSImetD@dam~e>{LvVh!phhzpW+iFvWpGT#CVE5TQ40n%F|p(sP5mXxna+Ev7PDwA zamaV4m*^~*xV+&p;W749xhb_X=$|LD;FHuB&JL5?*Y2-oIT(wYY2;73<^#46S~Gx| z^cez%V7x$81}UWqS13Gz80379Rj;6~WdiXWOSsdmzY39L;Hg3MH43o*y8ibNBBH`(av4|u;YPq%{R;IuYow<+GEsf@R?=@tT@!}?#>zIIn0CoyV!hq3mw zHj>OOjfJM3F{RG#6ujzo?y32m^tgSXf@v=J$ELdJ+=5j|=F-~hP$G&}tDZsZE?5rX ztGj`!S>)CFmdkccxM9eGIcGnS2AfK#gXwj%esuIBNJQP1WV~b~+D7PJTmWGTSDrR` zEAu4B8l>NPuhsk5a`rReSya2nfV1EK01+G!x8aBdTs3Io$u5!6n6KX%uv@DxAp3F@{4UYg4SWJtQ-W~0MDb|j-$lwVn znAm*Pl!?Ps&3wO=R115RWKb*JKoexo*)uhhHBncEDMSVa_PyA>k{Zm2(wMQ(5NM3# z)jkza|GoWEQo4^s*wE(gHz?Xsg4`}HUAcs42cM1-qq_=+=!Gk^y710j=66(cSWqUe zklbm8+zB_syQv5A2rj!Vbw8;|$@C!vfNmNV!yJIWDQ>{+2x zKjuFX`~~HKG~^6h5FntRpnnHt=D&rq0>IJ9#F0eM)Y-)GpRjiN7gkA8wvnG#K=q{q z9dBn8_~wm4J<3J_vl|9H{7q6u2A!cW{bp#r*-f{gOV^e=8S{nc1DxMHFwuM$;aVI^ zz6A*}m8N-&x8;aunp1w7_vtB*pa+OYBw=TMc6QK=mbA-|Cf* zvyh8D4LRJImooUaSb7t*fVfih<97Gf@VE0|z>NcBwBQze);Rh!k3K_sfunToZY;f2 z^HmC4KjHRVg+eKYj;PRN^|E0>Gj_zagfRbrki68I^#~6-HaHg3BUW%+clM1xQEdPYt_g<2K+z!$>*$9nQ>; zf9Bei{?zY^-e{q_*|W#2rJG`2fy@{%6u0i_VEWTq$*(ZN37|8lFFFt)nCG({r!q#9 z5VK_kkSJ3?zOH)OezMT{!YkCuSSn!K#-Rhl$uUM(bq*jY? zi1xbMVthJ`E>d>(f3)~fozjg^@eheMF6<)I`oeJYx4*+M&%c9VArn(OM-wp%M<-`x z7sLP1&3^%Nld9Dhm@$3f2}87!quhI@nwd@3~fZl_3LYW-B?Ia>ui`ELg z&Qfe!7m6ze=mZ`Ia9$z|ARSw|IdMpooY4YiPN8K z4B(ts3p%2i(Td=tgEHX z0UQ_>URBtG+-?0E;E7Ld^dyZ;jjw0}XZ(}-QzC6+NN=40oDb2^v!L1g9xRvE#@IBR zO!b-2N7wVfLV;mhEaXQ9XAU+>=XVA6f&T4Z-@AX!leJ8obP^P^wP0aICND?~w&NykJ#54x3_@r7IDMdRNy4Hh;h*!u(Ol(#0bJdwEo$5437-UBjQ+j=Ic>Q2z` zJNDf0yO6@mr6y1#n3)s(W|$iE_i8r@Gd@!DWDqZ7J&~gAm1#~maIGJ1sls^gxL9LLG_NhU!pTGty!TbhzQnu)I*S^54U6Yu%ZeCg`R>Q zhBv$n5j0v%O_j{QYWG!R9W?5_b&67KB$t}&e2LdMvd(PxN6Ir!H4>PNlerpBL>Zvyy!yw z-SOo8caEpDt(}|gKPBd$qND5#a5nju^O>V&;f890?yEOfkSG^HQVmEbM3Ugzu+UtH zC(INPDdraBN?P%kE;*Ae%Wto&sgw(crfZ#Qy(<4nk;S|hD3j{IQRI6Yq|f^basLY; z-HB&Je%Gg}Jt@={_C{L$!RM;$$|iD6vu#3w?v?*;&()uB|I-XqEKqZPS!reW9JkLewLb!70T7n`i!gNtb1%vN- zySZj{8-1>6E%H&=V}LM#xmt`J3XQoaD|@XygXjdZ1+P77-=;=eYpoEQ01B@L*a(uW zrZeZz?HJsw_4g0vhUgkg@VF8<-X$B8pOqCuWAl28uB|@r`19DTUQQsb^pfqB6QtiT z*`_UZ`fT}vtUY#%sq2{rchyfu*pCg;uec2$-$N_xgjZcoumE5vSI{+s@iLWoz^Mf; zuI8kDP{!XY6OP~q5}%1&L}CtfH^N<3o4L@J@zg1-mt{9L`s^z$Vgb|mr{@WiwAqKg zp#t-lhrU>F8o0s1q_9y`gQNf~Vb!F%70f}$>i7o4ho$`uciNf=xgJ>&!gSt0g;M>*x4-`U)ysFW&Vs^Vk6m%?iuWU+o&m(2Jm26Y(3%TL; zA7T)BP{WS!&xmxNw%J=$MPfn(9*^*TV;$JwRy8Zl*yUZi8jWYF>==j~&S|Xinsb%c z2?B+kpet*muEW7@AzjBA^wAJBY8i|#C{WtO_or&Nj2{=6JTTX05}|H>N2B|Wf!*3_ z7hW*j6p3TvpghEc6-wufFiY!%-GvOx*bZrhZu+7?iSrZL5q9}igiF^*R3%DE4aCHZ zqu>xS8LkW+Auv%z-<1Xs92u23R$nk@Pk}MU5!gT|c7vGlEA%G^2th&Q*zfg%-D^=f z&J_}jskj|Q;73NP4<4k*Y%pXPU2Thoqr+5uH1yEYM|VtBPW6lXaetokD0u z9qVek6Q&wk)tFbQ8(^HGf3Wp16gKmr>G;#G(HRBx?F`9AIRboK+;OfHaLJ(P>IP0w zyTbTkx_THEOs%Q&aPrxbZrJlio+hCC_HK<4%f3ZoSAyG7Dn`=X=&h@m*|UYO-4Hq0 z-Bq&+Ie!S##4A6OGoC~>ZW`Y5J)*ouaFl_e9GA*VSL!O_@xGiBw!AF}1{tB)z(w%c zS1Hmrb9OC8>0a_$BzeiN?rkPLc9%&;1CZW*4}CDDNr2gcl_3z+WC15&H1Zc2{o~i) z)LLW=WQ{?ricmC`G1GfJ0Yp4Dy~Ba;j6ZV4r{8xRs`13{dD!xXmr^Aga|C=iSmor% z8hi|pTXH)5Yf&v~exp3o+sY4B^^b*eYkkCYl*T{*=-0HniSA_1F53eCb{x~1k3*`W zr~};p1A`k{1DV9=UPnLDgz{aJH=-LQo<5%+Em!DNN252xwIf*wF_zS^!(XSm(9eoj z=*dXG&n0>)_)N5oc6v!>-bd(2ragD8O=M|wGW z!xJQS<)u70m&6OmrF0WSsr@I%T*c#Qo#Ha4d3COcX+9}hM5!7JIGF>7<~C(Ear^Sn zm^ZFkV6~Ula6+8S?oOROOA6$C&q&dp`>oR-2Ym3(HT@O7Sd5c~+kjrmM)YmgPH*tL zX+znN>`tv;5eOfX?h{AuX^LK~V#gPCu=)Tigtq9&?7Xh$qN|%A$?V*v=&-2F$zTUv z`C#WyIrChS5|Kgm_GeudCFf;)!WH7FI60j^0o#65o6`w*S7R@)88n$1nrgU(oU0M9 zx+EuMkC>(4j1;m6NoGqEkpJYJ?vc|B zOlwT3t&UgL!pX_P*6g36`ZXQ; z9~Cv}ANFnJGp(;ZhS(@FT;3e)0)Kp;h^x;$*xZn*k0U6-&FwI=uOGaODdrsp-!K$Ac32^c{+FhI-HkYd5v=`PGsg%6I`4d9Jy)uW0y%) zm&j^9WBAp*P8#kGJUhB!L?a%h$hJgQrx!6KCB_TRo%9{t0J7KW8!o1B!NC)VGLM5! zpZy5Jc{`r{1e(jd%jsG7k%I+m#CGS*BPA65ZVW~fLYw0dA-H_}O zrkGFL&P1PG9p2(%QiEWm6x;U-U&I#;Em$nx-_I^wtgw3xUPVVu zqSuKnx&dIT-XT+T10p;yjo1Y)z(x1fb8Dzfn8e yu?e%!_ptzGB|8GrCfu%p?(_ zQccdaaVK$5bz;*rnyK{_SQYM>;aES6Qs^lj9lEs6_J+%nIiuQC*fN;z8md>r_~Mfl zU%p5Dt_YT>gQqfr@`cR!$NWr~+`CZb%dn;WtzrAOI>P_JtsB76PYe*<%H(y>qx-`Kq!X_; z<{RpAqYhE=L1r*M)gNF3B8r(<%8mo*SR2hu zccLRZwGARt)Hlo1euqTyM>^!HK*!Q2P;4UYrysje@;(<|$&%vQekbn|0Ruu_Io(w4#%p6ld2Yp7tlA`Y$cciThP zKzNGIMPXX%&Ud0uQh!uQZz|FB`4KGD?3!ND?wQt6!n*f4EmCoJUh&b?;B{|lxs#F- z31~HQ`SF4x$&v00@(P+j1pAaj5!s`)b2RDBp*PB=2IB>oBF!*6vwr7Dp%zpAx*dPr zb@Zjq^XjN?O4QcZ*O+8>)|HlrR>oD*?WQl5ri3R#2?*W6iJ>>kH%KnnME&TT@ZzrHS$Q%LC?n|e>V+D+8D zYc4)QddFz7I8#}y#Wj6>4P%34dZH~OUDb?uP%-E zwjXM(?Sg~1!|wI(RVuxbu)-rH+O=igSho_pDCw(c6b=P zKk4ATlB?bj9+HHlh<_!&z0rx13K3ZrAR8W)!@Y}o`?a*JJsD+twZIv`W)@Y?Amu_u zz``@-e2X}27$i(2=9rvIu5uTUOVhzwu%mNazS|lZb&PT;XE2|B&W1>=B58#*!~D&) zfVmJGg8UdP*fx(>Cj^?yS^zH#o-$Q-*$SnK(ZVFkw+er=>N^7!)FtP3y~Xxnu^nzY zikgB>Nj0%;WOltWIob|}%lo?_C7<``a5hEkx&1ku$|)i>Rh6@3h*`slY=9U}(Ql_< zaNG*J8vb&@zpdhAvv`?{=zDedJ23TD&Zg__snRAH4eh~^oawdYi6A3w8<Ozh@Kw)#bdktM^GVb zrG08?0bG?|NG+w^&JvD*7LAbjED{_Zkc`3H!My>0u5Q}m!+6VokMLXxl`Mkd=g&Xx z-a>m*#G3SLlhbKB!)tnzfWOBV;u;ftU}S!NdD5+YtOjLg?X}dl>7m^gOpihrf1;PY zvll&>dIuUGs{Qnd- zwIR3oIrct8Va^Tm0t#(bJD7c$Z7DO9*7NnRZorrSm`b`cxz>OIC;jSE3DO8`hX955ui`s%||YQtt2 z5DNA&pG-V+4oI2s*x^>-$6J?p=I>C|9wZF8z;VjR??Icg?1w2v5Me+FgAeGGa8(3S z4vg*$>zC-WIVZtJ7}o9{D-7d>zCe|z#<9>CFve-OPAYsneTb^JH!Enaza#j}^mXy1 z+ULn^10+rWLF6j2>Ya@@Kq?26>AqK{A_| zQKb*~F1>sE*=d?A?W7N2j?L09_7n+HGi{VY;MoTGr_)G9)ot$p!-UY5zZ2Xtbm=t z@dpPSGwgH=QtIcEulQNI>S-#ifbnO5EWkI;$A|pxJd885oM+ zGZ0_0gDvG8q2xebj+fbCHYfAXuZStH2j~|d^sBAzo46(K8n59+T6rzBwK)^rfPT+B zyIFw)9YC-V^rhtK`!3jrhmW-sTmM+tPH+;nwjL#-SjQPUZ53L@A>y*rt(#M(qsiB2 zx6B)dI}6Wlsw%bJ8h|(lhkJVogQZA&n{?Vgs6gNSXzuZpEyu*xySy8ro07QZ7Vk1!3tJphN_5V7qOiyK8p z#@jcDD8nmtYi1^l8ml;AF<#IPK?!pqf9D4moYk>d99Im}Jtwj6c#+A;f)CQ*f-hZ< z=p_T86jog%!p)D&5g9taSwYi&eP z#JuEK%+NULWus;0w32-SYFku#i}d~+{Pkho&^{;RxzP&0!RCm3-9K6`>KZpnzS6?L z^H^V*s!8<>x8bomvD%rh>Zp3>Db%kyin;qtl+jAv8Oo~1g~mqGAC&Qi_wy|xEt2iz zWAJEfTV%cl2Cs<1L&DLRVVH05EDq`pH7Oh7sR`NNkL%wi}8n>IXcO40hp+J+sC!W?!krJf!GJNE8uj zg-y~Ns-<~D?yqbzVRB}G>0A^f0!^N7l=$m0OdZuqAOQqLc zX?AEGr1Ht+inZ-Qiwnl@Z0qukd__a!C*CKuGdy5#nD7VUBM^6OCpxCa2A(X;e0&V4 zM&WR8+wErQ7UIc6LY~Q9x%Sn*Tn>>P`^t&idaOEnOd(Ufw#>NoR^1QdhJ8s`h^|R_ zXX`c5*O~Xdvh%q;7L!_!ohf$NfEBmCde|#uVZvEo>OfEq%+Ns7&_f$OR9xsihRpBb z+cjk8LyDm@U{YN>+r46?nn{7Gh(;WhFw6GAxtcKD+YWV?uge>;+q#Xx4!GpRkVZYu zzsF}1)7$?%s9g9CH=Zs+B%M_)+~*j3L0&Q9u7!|+T`^O{xE6qvAP?XWv9_MrZKdo& z%IyU)$Q95AB4!#hT!_dA>4e@zjOBD*Y=XjtMm)V|+IXzjuM;(l+8aA5#Kaz_$rR6! zj>#&^DidYD$nUY(D$mH`9eb|dtV0b{S>H6FBfq>t5`;OxA4Nn{J(+XihF(stSche7$es&~N$epi&PDM_N`As;*9D^L==2Q7Z2zD+CiU(|+-kL*VG+&9!Yb3LgPy?A zm7Z&^qRG_JIxK7-FBzZI3Q<;{`DIxtc48k> zc|0dmX;Z=W$+)qE)~`yn6MdoJ4co;%!`ddy+FV538Y)j(vg}5*k(WK)KWZ3WaOG!8 z!syGn=s{H$odtpqFrT#JGM*utN7B((abXnpDM6w56nhw}OY}0TiTG1#f*VFZr+^-g zbP10`$LPq_;PvrA1XXlyx2uM^mrjTzX}w{yuLo-cOClE8MMk47T25G8M!9Z5ypOSV zAJUBGEg5L2fY)ZGJb^E34R2zJ?}Vf>{~gB!8=5Z) z9y$>5c)=;o0HeHHSuE4U)#vG&KF|I%-cF6f$~pdYJWk_dD}iOA>iA$O$+4%@>JU08 zS`ep)$XLPJ+n0_i@PkF#ri6T8?ZeAot$6JIYHm&P6EB=BiaNY|aA$W0I+nz*zkz_z zkEru!tj!QUffq%)8y0y`T&`fuus-1p>=^hnBiBqD^hXrPs`PY9tU3m0np~rISY09> z`P3s=-kt_cYcxWd{de@}TwSqg*xVhp;E9zCsnXo6z z?f&Sv^U7n4`xr=mXle94HzOdN!2kB~4=%)u&N!+2;z6UYKUDqi-s6AZ!haB;@&B`? z_TRX0%@suz^TRdCb?!vNJYPY8L_}&07uySH9%W^Tc&1pia6y1q#?*Drf}GjGbPjBS zbOPcUY#*$3sL2x4v_i*Y=N7E$mR}J%|GUI(>WEr+28+V z%v5{#e!UF*6~G&%;l*q*$V?&r$Pp^sE^i-0$+RH3ERUUdQ0>rAq2(2QAbG}$y{de( z>{qD~GGuOk559Y@%$?N^1ApVL_a704>8OD%8Y%8B;FCt%AoPu8*D1 zLB5X>b}Syz81pn;xnB}%0FnwazlWfUV)Z-~rZg6~b z6!9J$EcE&sEbzcy?CI~=boWA&eeIa%z(7SE^qgVLz??1Vbc1*aRvc%Mri)AJaAG!p z$X!_9Ds;Zz)f+;%s&dRcJt2==P{^j3bf0M=nJd&xwUGlUFn?H=2W(*2I2Gdu zv!gYCwM10aeus)`RIZSrCK=&oKaO_Ry~D1B5!y0R=%!i2*KfXGYX&gNv_u+n9wiR5 z*e$Zjju&ODRW3phN925%S(jL+bCHv6rZtc?!*`1TyYXT6%Ju=|X;6D@lq$8T zW{Y|e39ioPez(pBH%k)HzFITXHvnD6hw^lIoUMA;qAJ^CU?top1fo@s7xT13Fvn1H z6JWa-6+FJF#x>~+A;D~;VDs26>^oH0EI`IYT2iagy23?nyJ==i{g4%HrAf1-*v zK1)~@&(KkwR7TL}L(A@C_S0G;-GMDy=MJn2$FP5s<%wC)4jC5PXoxrQBFZ_k0P{{s@sz+gX`-!=T8rcB(=7vW}^K6oLWMmp(rwDh}b zwaGGd>yEy6fHv%jM$yJXo5oMAQ>c9j`**}F?MCry;T@47@r?&sKHgVe$MCqk#Z_3S z1GZI~nOEN*P~+UaFGnj{{Jo@16`(qVNtbU>O0Hf57-P>x8Jikp=`s8xWs^dAJ9lCQ z)GFm+=OV%AMVqVATtN@|vp61VVAHRn87}%PC^RAzJ%JngmZTasWBAWsoAqBU+8L8u z4A&Pe?fmTm0?mK-BL9t+{y7o(7jm+RpOhL9KnY#E&qu^}B6=K_dB}*VlSEiC9fn)+V=J;OnN)Ta5v66ic1rG+dGAJ1 z1%Zb_+!$=tQ~lxQrzv3x#CPb?CekEkA}0MYSgx$Jdd}q8+R=ma$|&1a#)TQ=l$1tQ z=tL9&_^vJ)Pk}EDO-va`UCT1m#Uty1{v^A3P~83_#v^ozH}6*9mIjIr;t3Uv%@VeW zGL6(CwCUp)Jq%G0bIG%?{_*Y#5IHf*5M@wPo6A{$Um++Co$wLC=J1aoG93&T7Ho}P z=mGEPP7GbvoG!uD$k(H3A$Z))+i{Hy?QHdk>3xSBXR0j!11O^mEe9RHmw!pvzv?Ua~2_l2Yh~_!s1qS`|0~0)YsbHSz8!mG)WiJE| z2f($6TQtt6L_f~ApQYQKSb=`053LgrQq7G@98#igV>y#i==-nEjQ!XNu9 z~;mE+gtj4IDDNQJ~JVk5Ux6&LCSFL!y=>79kE9=V}J7tD==Ga+IW zX)r7>VZ9dY=V&}DR))xUoV!u(Z|%3ciQi_2jl}3=$Agc(`RPb z8kEBpvY>1FGQ9W$n>Cq=DIpski};nE)`p3IUw1Oz0|wxll^)4dq3;CCY@RyJgFgc# zKouFh!`?Xuo{IMz^xi-h=StCis_M7yq$u) z?XHvw*HP0VgR+KR6wI)jEMX|ssqYvSf*_3W8zVTQzD?3>H!#>InzpSO)@SC8q*ii- z%%h}_#0{4JG;Jm`4zg};BPTGkYamx$Xo#O~lBirRY)q=5M45n{GCfV7h9qwyu1NxOMoP4)jjZMxmT|IQQh0U7C$EbnMN<3)Kk?fFHYq$d|ICu>KbY_hO zTZM+uKHe(cIZfEqyzyYSUBZa8;Fcut-GN!HSA9ius`ltNebF46ZX_BbZNU}}ZOm{M2&nANL9@0qvih15(|`S~z}m&h!u4x~(%MAO$jHRWNfuxWF#B)E&g3ghSQ9|> z(MFaLQj)NE0lowyjvg8z0#m6FIuKE9lDO~Glg}nSb7`~^&#(Lw{}GVOS>U)m8bF}x zVjbXljBm34Cs-yM6TVusr+3kYFjr28STT3g056y3cH5Tmge~ASxBj z%|yb>$eF;WgrcOZf569sDZOVwoo%8>XO>XQOX1OyN9I-SQgrm;U;+#3OI(zrWyow3 zk==|{lt2xrQ%FIXOTejR>;wv(Pb8u8}BUpx?yd(Abh6? zsoO3VYWkeLnF43&@*#MQ9-i-d0t*xN-UEyNKeyNMHw|A(k(_6QKO=nKMCxD(W(Yop zsRQ)QeL4X3Lxp^L%wzi2-WVSsf61dqliPUM7srDB?Wm6Lzn0&{*}|IsKQW;02(Y&| zaTKv|`U(pSzuvR6Rduu$wzK_W-Y-7>7s?G$)U}&uK;<>vU}^^ns@Z!p+9?St1s)dG zK%y6xkPyyS1$~&6v{kl?Md6gwM|>mt6Upm>oa8RLD^8T{0?HC!Z>;(Bob7el(DV6x zi`I)$&E&ngwFS@bi4^xFLAn`=fzTC;aimE^!cMI2n@Vo%Ae-ne`RF((&5y6xsjjAZ zVguVoQ?Z9uk$2ON;ersE%PU*xGO@T*;j1BO5#TuZKEf(mB7|g7pcEA=nYJ{s3vlbg zd4-DUlD{*6o%Gc^N!Nptgay>j6E5;3psI+C3Q!1ZIbeCubW%w4pq9)MSDyB{HLm|k zxv-{$$A*pS@csolri$Ge<4VZ}e~78JOL-EVyrbxKra^d{?|NnPp86!q>t<&IP07?Z z^>~IK^k#OEKgRH+LjllZXk7iA>2cfH6+(e&9ku5poo~6y{GC5>(bRK7hwjiurqAiZ zg*DmtgY}v83IjE&AbiWgMyFbaRUPZ{lYiz$U^&Zt2YjG<%m((&_JUbZcfJ22(>bi5 z!J?<7AySj0JZ&<-qXX;mcV!f~>G=sB0KnjWca4}vrtunD^1TrpfeS^4dvFr!65knK zZh`d;*VOkPs4*-9kL>$GP0`(M!j~B;#x?Ba~&s6CopvO86oM?-? zOw#dIRc;6A6T?B`Qp%^<U5 z19x(ywSH$_N+Io!6;e?`tWaM$`=Db!gzx|lQ${DG!zb1Zl&|{kX0y6xvO1o z220r<-oaS^^R2pEyY;=Qllqpmue|5yI~D|iI!IGt@iod{Opz@*ml^w2bNs)p`M(Io z|E;;m*Xpjd9l)4G#KaWfV(t8YUn@A;nK^#xgv=LtnArX|vWQVuw3}B${h+frU2>9^ z!l6)!Uo4`5k`<<;E(ido7M6lKTgWezNLq>U*=uz&s=cc$1%>VrAeOoUtA|T6gO4>UNqsdK=NF*8|~*sl&wI=x9-EGiq*aqV!(VVXA57 zw9*o6Ir8Lj1npUXvlevtn(_+^X5rzdR>#(}4YcB9O50q97%rW2me5_L=%ffYPUSRc z!vv?Kv>dH994Qi>U(a<0KF6NH5b16enCp+mw^Hb3Xs1^tThFpz!3QuN#}KBbww`(h z7GO)1olDqy6?T$()R7y%NYx*B0k_2IBiZ14&8|JPFxeMF{vW>HF-Vi3+ZOI=+qP}n zw(+!WcTd~4ZJX1!ZM&y!+uyt=&i!+~d(V%GjH;-NsEEv6nS1TERt|RHh!0>W4+4pp z1-*EzAM~i`+1f(VEHI8So`S`akPfPTfq*`l{Fz`hS%k#JS0cjT2mS0#QLGf=J?1`he3W*;m4)ce8*WFq1sdP=~$5RlH1EdWm|~dCvKOi4*I_96{^95p#B<(n!d?B z=o`0{t+&OMwKcxiBECznJcfH!fL(z3OvmxP#oWd48|mMjpE||zdiTBdWelj8&Qosv zZFp@&UgXuvJw5y=q6*28AtxZzo-UUpkRW%ne+Ylf!V-0+uQXBW=5S1o#6LXNtY5!I z%Rkz#(S8Pjz*P7bqB6L|M#Er{|QLae-Y{KA>`^} z@lPjeX>90X|34S-7}ZVXe{wEei1<{*e8T-Nbj8JmD4iwcE+Hg_zhkPVm#=@b$;)h6 z<<6y`nPa`f3I6`!28d@kdM{uJOgM%`EvlQ5B2bL)Sl=|y@YB3KeOzz=9cUW3clPAU z^sYc}xf9{4Oj?L5MOlYxR{+>w=vJjvbyO5}ptT(o6dR|ygO$)nVCvNGnq(6;bHlBd zl?w-|plD8spjDF03g5ip;W3Z z><0{BCq!Dw;h5~#1BuQilq*TwEu)qy50@+BE4bX28+7erX{BD4H)N+7U`AVEuREE8 z;X?~fyhF-x_sRfHIj~6f(+^@H)D=ngP;mwJjxhQUbUdzk8f94Ab%59-eRIq?ZKrwD z(BFI=)xrUlgu(b|hAysqK<}8bslmNNeD=#JW*}^~Nrswn^xw*nL@Tx!49bfJecV&KC2G4q5a!NSv)06A_5N3Y?veAz;Gv+@U3R% z)~UA8-0LvVE{}8LVDOHzp~2twReqf}ODIyXMM6=W>kL|OHcx9P%+aJGYi_Om)b!xe zF40Vntn0+VP>o<$AtP&JANjXBn7$}C@{+@3I@cqlwR2MdwGhVPxlTIcRVu@Ho-wO` z_~Or~IMG)A_`6-p)KPS@cT9mu9RGA>dVh5wY$NM9-^c@N=hcNaw4ITjm;iWSP^ZX| z)_XpaI61<+La+U&&%2a z0za$)-wZP@mwSELo#3!PGTt$uy0C(nTT@9NX*r3Ctw6J~7A(m#8fE)0RBd`TdKfAT zCf@$MAxjP`O(u9s@c0Fd@|}UQ6qp)O5Q5DPCeE6mSIh|Rj{$cAVIWsA=xPKVKxdhg zLzPZ`3CS+KIO;T}0Ip!fAUaNU>++ZJZRk@I(h<)RsJUhZ&Ru9*!4Ptn;gX^~4E8W^TSR&~3BAZc#HquXn)OW|TJ`CTahk+{qe`5+ixON^zA9IFd8)kc%*!AiLu z>`SFoZ5bW-%7}xZ>gpJcx_hpF$2l+533{gW{a7ce^B9sIdmLrI0)4yivZ^(Vh@-1q zFT!NQK$Iz^xu%|EOK=n>ug;(7J4OnS$;yWmq>A;hsD_0oAbLYhW^1Vdt9>;(JIYjf zdb+&f&D4@4AS?!*XpH>8egQvSVX`36jMd>$+RgI|pEg))^djhGSo&#lhS~9%NuWfX zDDH;3T*GzRT@5=7ibO>N-6_XPBYxno@mD_3I#rDD?iADxX`! zh*v8^i*JEMzyN#bGEBz7;UYXki*Xr(9xXax(_1qVW=Ml)kSuvK$coq2A(5ZGhs_pF z$*w}FbN6+QDseuB9=fdp_MTs)nQf!2SlROQ!gBJBCXD&@-VurqHj0wm@LWX-TDmS= z71M__vAok|@!qgi#H&H%Vg-((ZfxPAL8AI{x|VV!9)ZE}_l>iWk8UPTGHs*?u7RfP z5MC&=c6X;XlUzrz5q?(!eO@~* zoh2I*%J7dF!!_!vXoSIn5o|wj1#_>K*&CIn{qSaRc&iFVxt*^20ngCL;QonIS>I5^ zMw8HXm>W0PGd*}Ko)f|~dDd%;Wu_RWI_d;&2g6R3S63Uzjd7dn%Svu-OKpx*o|N>F zZg=-~qLb~VRLpv`k zWSdfHh@?dp=s_X`{yxOlxE$4iuyS;Z-x!*E6eqmEm*j2bE@=ZI0YZ5%Yj29!5+J$4h{s($nakA`xgbO8w zi=*r}PWz#lTL_DSAu1?f%-2OjD}NHXp4pXOsCW;DS@BC3h-q4_l`<))8WgzkdXg3! zs1WMt32kS2E#L0p_|x+x**TFV=gn`m9BWlzF{b%6j-odf4{7a4y4Uaef@YaeuPhU8 zHBvRqN^;$Jizy+ z=zW{E5<>2gp$pH{M@S*!sJVQU)b*J5*bX4h>5VJve#Q6ga}cQ&iL#=(u+KroWrxa%8&~p{WEUF0il=db;-$=A;&9M{Rq`ouZ5m%BHT6%st%saGsD6)fQgLN}x@d3q>FC;=f%O3Cyg=Ke@Gh`XW za@RajqOE9UB6eE=zhG%|dYS)IW)&y&Id2n7r)6p_)vlRP7NJL(x4UbhlcFXWT8?K=%s7;z?Vjts?y2+r|uk8Wt(DM*73^W%pAkZa1Jd zNoE)8FvQA>Z`eR5Z@Ig6kS5?0h;`Y&OL2D&xnnAUzQz{YSdh0k zB3exx%A2TyI)M*EM6htrxSlep!Kk(P(VP`$p0G~f$smld6W1r_Z+o?=IB@^weq>5VYsYZZR@` z&XJFxd5{|KPZmVOSxc@^%71C@;z}}WhbF9p!%yLj3j%YOlPL5s>7I3vj25 z@xmf=*z%Wb4;Va6SDk9cv|r*lhZ`(y_*M@>q;wrn)oQx%B(2A$9(74>;$zmQ!4fN; z>XurIk-7@wZys<+7XL@0Fhe-f%*=(weaQEdR9Eh6>Kl-EcI({qoZqyzziGwpg-GM#251sK_ z=3|kitS!j%;fpc@oWn65SEL73^N&t>Ix37xgs= zYG%eQDJc|rqHFia0!_sm7`@lvcv)gfy(+KXA@E{3t1DaZ$DijWAcA)E0@X?2ziJ{v z&KOYZ|DdkM{}t+@{@*6ge}m%xfjIxi%qh`=^2Rwz@w0cCvZ&Tc#UmCDbVwABrON^x zEBK43FO@weA8s7zggCOWhMvGGE`baZ62cC)VHyy!5Zbt%ieH+XN|OLbAFPZWyC6)p z4P3%8sq9HdS3=ih^0OOlqTPbKuzQ?lBEI{w^ReUO{V?@`ARsL|S*%yOS=Z%sF)>-y z(LAQdhgAcuF6LQjRYfdbD1g4o%tV4EiK&ElLB&^VZHbrV1K>tHTO{#XTo>)2UMm`2 z^t4s;vnMQgf-njU-RVBRw0P0-m#d-u`(kq7NL&2T)TjI_@iKuPAK-@oH(J8?%(e!0Ir$yG32@CGUPn5w4)+9@8c&pGx z+K3GKESI4*`tYlmMHt@br;jBWTei&(a=iYslc^c#RU3Q&sYp zSG){)V<(g7+8W!Wxeb5zJb4XE{I|&Y4UrFWr%LHkdQ;~XU zgy^dH-Z3lmY+0G~?DrC_S4@=>0oM8Isw%g(id10gWkoz2Q%7W$bFk@mIzTCcIB(K8 zc<5h&ZzCdT=9n-D>&a8vl+=ZF*`uTvQviG_bLde*k>{^)&0o*b05x$MO3gVLUx`xZ z43j+>!u?XV)Yp@MmG%Y`+COH2?nQcMrQ%k~6#O%PeD_WvFO~Kct za4XoCM_X!c5vhRkIdV=xUB3xI2NNStK*8_Zl!cFjOvp-AY=D;5{uXj}GV{LK1~IE2 z|KffUiBaStRr;10R~K2VVtf{TzM7FaPm;Y(zQjILn+tIPSrJh&EMf6evaBKIvi42-WYU9Vhj~3< zZSM-B;E`g_o8_XTM9IzEL=9Lb^SPhe(f(-`Yh=X6O7+6ALXnTcUFpI>ekl6v)ZQeNCg2 z^H|{SKXHU*%nBQ@I3It0m^h+6tvI@FS=MYS$ZpBaG7j#V@P2ZuYySbp@hA# ze(kc;P4i_-_UDP?%<6>%tTRih6VBgScKU^BV6Aoeg6Uh(W^#J^V$Xo^4#Ekp ztqQVK^g9gKMTHvV7nb64UU7p~!B?>Y0oFH5T7#BSW#YfSB@5PtE~#SCCg3p^o=NkMk$<8- z6PT*yIKGrvne7+y3}_!AC8NNeI?iTY(&nakN>>U-zT0wzZf-RuyZk^X9H-DT_*wk= z;&0}6LsGtfVa1q)CEUPlx#(ED@-?H<1_FrHU#z5^P3lEB|qsxEyn%FOpjx z3S?~gvoXy~L(Q{Jh6*i~=f%9kM1>RGjBzQh_SaIDfSU_9!<>*Pm>l)cJD@wlyxpBV z4Fmhc2q=R_wHCEK69<*wG%}mgD1=FHi4h!98B-*vMu4ZGW~%IrYSLGU{^TuseqVgV zLP<%wirIL`VLyJv9XG_p8w@Q4HzNt-o;U@Au{7%Ji;53!7V8Rv0^Lu^Vf*sL>R(;c zQG_ZuFl)Mh-xEIkGu}?_(HwkB2jS;HdPLSxVU&Jxy9*XRG~^HY(f0g8Q}iqnVmgjI zfd=``2&8GsycjR?M%(zMjn;tn9agcq;&rR!Hp z$B*gzHsQ~aXw8c|a(L^LW(|`yGc!qOnV(ZjU_Q-4z1&0;jG&vAKuNG=F|H?@m5^N@ zq{E!1n;)kNTJ>|Hb2ODt-7U~-MOIFo%9I)_@7fnX+eMMNh>)V$IXesJpBn|uo8f~#aOFytCT zf9&%MCLf8mp4kwHTcojWmM3LU=#|{3L>E}SKwOd?%{HogCZ_Z1BSA}P#O(%H$;z7XyJ^sjGX;j5 zrzp>|Ud;*&VAU3x#f{CKwY7Vc{%TKKqmB@oTHA9;>?!nvMA;8+Jh=cambHz#J18x~ zs!dF>$*AnsQ{{82r5Aw&^7eRCdvcgyxH?*DV5(I$qXh^zS>us*I66_MbL8y4d3ULj z{S(ipo+T3Ag!+5`NU2sc+@*m{_X|&p#O-SAqF&g_n7ObB82~$p%fXA5GLHMC+#qqL zdt`sJC&6C2)=juQ_!NeD>U8lDVpAOkW*khf7MCcs$A(wiIl#B9HM%~GtQ^}yBPjT@ z+E=|A!Z?A(rwzZ;T}o6pOVqHzTr*i;Wrc%&36kc@jXq~+w8kVrs;%=IFdACoLAcCAmhFNpbP8;s`zG|HC2Gv?I~w4ITy=g$`0qMQdkijLSOtX6xW%Z9Nw<;M- zMN`c7=$QxN00DiSjbVt9Mi6-pjv*j(_8PyV-il8Q-&TwBwH1gz1uoxs6~uU}PrgWB zIAE_I-a1EqlIaGQNbcp@iI8W1sm9fBBNOk(k&iLBe%MCo#?xI$%ZmGA?=)M9D=0t7 zc)Q0LnI)kCy{`jCGy9lYX%mUsDWwsY`;jE(;Us@gmWPqjmXL+Hu#^;k%eT>{nMtzj zsV`Iy6leTA8-PndszF;N^X@CJrTw5IIm!GPeu)H2#FQitR{1p;MasQVAG3*+=9FYK zw*k!HT(YQorfQj+1*mCV458(T5=fH`um$gS38hw(OqVMyunQ;rW5aPbF##A3fGH6h z@W)i9Uff?qz`YbK4c}JzQpuxuE3pcQO)%xBRZp{zJ^-*|oryTxJ-rR+MXJ)!f=+pp z10H|DdGd2exhi+hftcYbM0_}C0ZI-2vh+$fU1acsB-YXid7O|=9L!3e@$H*6?G*Zp z%qFB(sgl=FcC=E4CYGp4CN>=M8#5r!RU!u+FJVlH6=gI5xHVD&k;Ta*M28BsxfMV~ zLz+@6TxnfLhF@5=yQo^1&S}cmTN@m!7*c6z;}~*!hNBjuE>NLVl2EwN!F+)0$R1S! zR|lF%n!9fkZ@gPW|x|B={V6x3`=jS*$Pu0+5OWf?wnIy>Y1MbbGSncpKO0qE(qO=ts z!~@&!N`10S593pVQu4FzpOh!tvg}p%zCU(aV5=~K#bKi zHdJ1>tQSrhW%KOky;iW+O_n;`l9~omqM%sdxdLtI`TrJzN6BQz+7xOl*rM>xVI2~# z)7FJ^Dc{DC<%~VS?@WXzuOG$YPLC;>#vUJ^MmtbSL`_yXtNKa$Hk+l-c!aC7gn(Cg ze?YPYZ(2Jw{SF6MiO5(%_pTo7j@&DHNW`|lD`~{iH+_eSTS&OC*2WTT*a`?|9w1dh zh1nh@$a}T#WE5$7Od~NvSEU)T(W$p$s5fe^GpG+7fdJ9=enRT9$wEk+ZaB>G3$KQO zgq?-rZZnIv!p#>Ty~}c*Lb_jxJg$eGM*XwHUwuQ|o^}b3^T6Bxx{!?va8aC@-xK*H ztJBFvFfsSWu89%@b^l3-B~O!CXs)I6Y}y#0C0U0R0WG zybjroj$io0j}3%P7zADXOwHwafT#uu*zfM!oD$6aJx7+WL%t-@6^rD_a_M?S^>c;z zMK580bZXo1f*L$CuMeM4Mp!;P@}b~$cd(s5*q~FP+NHSq;nw3fbWyH)i2)-;gQl{S zZO!T}A}fC}vUdskGSq&{`oxt~0i?0xhr6I47_tBc`fqaSrMOzR4>0H^;A zF)hX1nfHs)%Zb-(YGX;=#2R6C{BG;k=?FfP?9{_uFLri~-~AJ;jw({4MU7e*d)?P@ zXX*GkNY9ItFjhwgAIWq7Y!ksbMzfqpG)IrqKx9q{zu%Mdl+{Dis#p9q`02pr1LG8R z@As?eG!>IoROgS!@J*to<27coFc1zpkh?w=)h9CbYe%^Q!Ui46Y*HO0mr% zEff-*$ndMNw}H2a5@BsGj5oFfd!T(F&0$<{GO!Qdd?McKkorh=5{EIjDTHU`So>8V zBA-fqVLb2;u7UhDV1xMI?y>fe3~4urv3%PX)lDw+HYa;HFkaLqi4c~VtCm&Ca+9C~ zge+67hp#R9`+Euq59WhHX&7~RlXn=--m8$iZ~~1C8cv^2(qO#X0?vl91gzUKBeR1J z^p4!!&7)3#@@X&2aF2-)1Ffcc^F8r|RtdL2X%HgN&XU-KH2SLCbpw?J5xJ*!F-ypZ zMG%AJ!Pr&}`LW?E!K~=(NJxuSVTRCGJ$2a*Ao=uUDSys!OFYu!Vs2IT;xQ6EubLIl z+?+nMGeQQhh~??0!s4iQ#gm3!BpMpnY?04kK375e((Uc7B3RMj;wE?BCoQGu=UlZt!EZ1Q*auI)dj3Jj{Ujgt zW5hd~-HWBLI_3HuO) zNrb^XzPsTIb=*a69wAAA3J6AAZZ1VsYbIG}a`=d6?PjM)3EPaDpW2YP$|GrBX{q*! z$KBHNif)OKMBCFP5>!1d=DK>8u+Upm-{hj5o|Wn$vh1&K!lVfDB&47lw$tJ?d5|=B z^(_9=(1T3Fte)z^>|3**n}mIX;mMN5v2F#l(q*CvU{Ga`@VMp#%rQkDBy7kYbmb-q z<5!4iuB#Q_lLZ8}h|hPODI^U6`gzLJre9u3k3c#%86IKI*^H-@I48Bi*@avYm4v!n0+v zWu{M{&F8#p9cx+gF0yTB_<2QUrjMPo9*7^-uP#~gGW~y3nfPAoV%amgr>PSyVAd@l)}8#X zR5zV6t*uKJZL}?NYvPVK6J0v4iVpwiN|>+t3aYiZSp;m0!(1`bHO}TEtWR1tY%BPB z(W!0DmXbZAsT$iC13p4f>u*ZAy@JoLAkJhzFf1#4;#1deO8#8d&89}en&z!W&A3++^1(;>0SB1*54d@y&9Pn;^IAf3GiXbfT`_>{R+Xv; zQvgL>+0#8-laO!j#-WB~(I>l0NCMt_;@Gp_f0#^c)t?&#Xh1-7RR0@zPyBz!U#0Av zT?}n({(p?p7!4S2ZBw)#KdCG)uPnZe+U|0{BW!m)9 zi_9$F?m<`2!`JNFv+w8MK_K)qJ^aO@7-Ig>cM4-r0bi=>?B_2mFNJ}aE3<+QCzRr*NA!QjHw# z`1OsvcoD0?%jq{*7b!l|L1+Tw0TTAM4XMq7*ntc-Ived>Sj_ZtS|uVdpfg1_I9knY z2{GM_j5sDC7(W&}#s{jqbybqJWyn?{PW*&cQIU|*v8YGOKKlGl@?c#TCnmnAkAzV- zmK={|1G90zz=YUvC}+fMqts0d4vgA%t6Jhjv?d;(Z}(Ep8fTZfHA9``fdUHkA+z3+ zhh{ohP%Bj?T~{i0sYCQ}uC#5BwN`skI7`|c%kqkyWIQ;!ysvA8H`b-t()n6>GJj6xlYDu~8qX{AFo$Cm3d|XFL=4uvc?Keb zzb0ZmMoXca6Mob>JqkNuoP>B2Z>D`Q(TvrG6m`j}-1rGP!g|qoL=$FVQYxJQjFn33lODt3Wb1j8VR zlR++vIT6^DtYxAv_hxupbLLN3e0%A%a+hWTKDV3!Fjr^cWJ{scsAdfhpI)`Bms^M6 zQG$waKgFr=c|p9Piug=fcJvZ1ThMnNhQvBAg-8~b1?6wL*WyqXhtj^g(Ke}mEfZVM zJuLNTUVh#WsE*a6uqiz`b#9ZYg3+2%=C(6AvZGc=u&<6??!slB1a9K)=VL zY9EL^mfyKnD zSJyYBc_>G;5RRnrNgzJz#Rkn3S1`mZgO`(r5;Hw6MveN(URf_XS-r58Cn80K)ArH4 z#Rrd~LG1W&@ttw85cjp8xV&>$b%nSXH_*W}7Ch2pg$$c0BdEo-HWRTZcxngIBJad> z;C>b{jIXjb_9Jis?NZJsdm^EG}e*pR&DAy0EaSGi3XWTa(>C%tz1n$u?5Fb z1qtl?;_yjYo)(gB^iQq?=jusF%kywm?CJP~zEHi0NbZ);$(H$w(Hy@{i>$wcVRD_X|w-~(0Z9BJyh zhNh;+eQ9BEIs;tPz%jSVnfCP!3L&9YtEP;svoj_bNzeGSQIAjd zBss@A;)R^WAu-37RQrM%{DfBNRx>v!G31Z}8-El9IOJlb_MSoMu2}GDYycNaf>uny z+8xykD-7ONCM!APry_Lw6-yT>5!tR}W;W`C)1>pxSs5o1z#j7%m=&=7O4hz+Lsqm` z*>{+xsabZPr&X=}G@obTb{nPTkccJX8w3CG7X+1+t{JcMabv~UNv+G?txRqXib~c^Mo}`q{$`;EBNJ;#F*{gvS12kV?AZ%O0SFB$^ zn+}!HbmEj}w{Vq(G)OGAzH}R~kS^;(-s&=ectz8vN!_)Yl$$U@HNTI-pV`LSj7Opu zTZ5zZ)-S_{GcEQPIQXLQ#oMS`HPu{`SQiAZ)m1at*Hy%3xma|>o`h%E%8BEbi9p0r zVjcsh<{NBKQ4eKlXU|}@XJ#@uQw*$4BxKn6#W~I4T<^f99~(=}a`&3(ur8R9t+|AQ zWkQx7l}wa48-jO@ft2h+7qn%SJtL%~890FG0s5g*kNbL3I&@brh&f6)TlM`K^(bhr zJWM6N6x3flOw$@|C@kPi7yP&SP?bzP-E|HSXQXG>7gk|R9BTj`e=4de9C6+H7H7n# z#GJeVs1mtHhLDmVO?LkYRQc`DVOJ_vdl8VUihO-j#t=0T3%Fc1f9F73ufJz*adn*p zc%&vi(4NqHu^R>sAT_0EDjVR8bc%wTz#$;%NU-kbDyL_dg0%TFafZwZ?5KZpcuaO54Z9hX zD$u>q!-9`U6-D`E#`W~fIfiIF5_m6{fvM)b1NG3xf4Auw;Go~Fu7cth#DlUn{@~yu z=B;RT*dp?bO}o%4x7k9v{r=Y@^YQ^UUm(Qmliw8brO^=NP+UOohLYiaEB3^DB56&V zK?4jV61B|1Uj_5fBKW;8LdwOFZKWp)g{B%7g1~DgO&N& z#lisxf?R~Z@?3E$Mms$$JK8oe@X`5m98V*aV6Ua}8Xs2#A!{x?IP|N(%nxsH?^c{& z@vY&R1QmQs83BW28qAmJfS7MYi=h(YK??@EhjL-t*5W!p z^gYX!Q6-vBqcv~ruw@oMaU&qp0Fb(dbVzm5xJN%0o_^@fWq$oa3X?9s%+b)x4w-q5Koe(@j6Ez7V@~NRFvd zfBH~)U5!ix3isg`6be__wBJp=1@yfsCMw1C@y+9WYD9_C%{Q~7^0AF2KFryfLlUP# zwrtJEcH)jm48!6tUcxiurAMaiD04C&tPe6DI0#aoqz#Bt0_7_*X*TsF7u*zv(iEfA z;$@?XVu~oX#1YXtceQL{dSneL&*nDug^OW$DSLF0M1Im|sSX8R26&)<0Fbh^*l6!5wfSu8MpMoh=2l z^^0Sr$UpZp*9oqa23fcCfm7`ya2<4wzJ`Axt7e4jJrRFVf?nY~2&tRL* zd;6_njcz01c>$IvN=?K}9ie%Z(BO@JG2J}fT#BJQ+f5LFSgup7i!xWRKw6)iITjZU z%l6hPZia>R!`aZjwCp}I zg)%20;}f+&@t;(%5;RHL>K_&7MH^S+7<|(SZH!u zznW|jz$uA`P9@ZWtJgv$EFp>)K&Gt+4C6#*khZQXS*S~6N%JDT$r`aJDs9|uXWdbg zBwho$phWx}x!qy8&}6y5Vr$G{yGSE*r$^r{}pw zVTZKvikRZ`J_IJrjc=X1uw?estdwm&bEahku&D04HD+0Bm~q#YGS6gp!KLf$A{%Qd z&&yX@Hp>~(wU{|(#U&Bf92+1i&Q*-S+=y=3pSZy$#8Uc$#7oiJUuO{cE6=tsPhwPe| zxQpK>`Dbka`V)$}e6_OXKLB%i76~4N*zA?X+PrhH<&)}prET;kel24kW%+9))G^JI zsq7L{P}^#QsZViX%KgxBvEugr>ZmFqe^oAg?{EI=&_O#e)F3V#rc z8$4}0Zr19qd3tE4#$3_f=Bbx9oV6VO!d3(R===i-7p=Vj`520w0D3W6lQfY48}!D* z&)lZMG;~er2qBoI2gsX+Ts-hnpS~NYRDtPd^FPzn!^&yxRy#CSz(b&E*tL|jIkq|l zf%>)7Dtu>jCf`-7R#*GhGn4FkYf;B$+9IxmqH|lf6$4irg{0ept__%)V*R_OK=T06 zyT_m-o@Kp6U{l5h>W1hGq*X#8*y@<;vsOFqEjTQXFEotR+{3}ODDnj;o0@!bB5x=N z394FojuGOtVKBlVRLtHp%EJv_G5q=AgF)SKyRN5=cGBjDWv4LDn$IL`*=~J7u&Dy5 zrMc83y+w^F&{?X(KOOAl-sWZDb{9X9#jrQtmrEXD?;h-}SYT7yM(X_6qksM=K_a;Z z3u0qT0TtaNvDER_8x*rxXw&C^|h{P1qxK|@pS7vdlZ#P z7PdB7MmC2}%sdzAxt>;WM1s0??`1983O4nFK|hVAbHcZ3x{PzytQLkCVk7hA!Lo` zEJH?4qw|}WH{dc4z%aB=0XqsFW?^p=X}4xnCJXK%c#ItOSjdSO`UXJyuc8bh^Cf}8 z@Ht|vXd^6{Fgai8*tmyRGmD_s_nv~r^Fy7j`Bu`6=G)5H$i7Q7lvQnmea&TGvJp9a|qOrUymZ$6G|Ly z#zOCg++$3iB$!6!>215A4!iryregKuUT344X)jQb3|9qY>c0LO{6Vby05n~VFzd?q zgGZv&FGlkiH*`fTurp>B8v&nSxNz)=5IF$=@rgND4d`!AaaX;_lK~)-U8la_Wa8i?NJC@BURO*sUW)E9oyv3RG^YGfN%BmxzjlT)bp*$<| zX3tt?EAy<&K+bhIuMs-g#=d1}N_?isY)6Ay$mDOKRh z4v1asEGWoAp=srraLW^h&_Uw|6O+r;wns=uwYm=JN4Q!quD8SQRSeEcGh|Eb5Jg8m zOT}u;N|x@aq)=&;wufCc^#)5U^VcZw;d_wwaoh9$p@Xrc{DD6GZUqZ ziC6OT^zSq@-lhbgR8B+e;7_Giv;DK5gn^$bs<6~SUadiosfewWDJu`XsBfOd1|p=q zE>m=zF}!lObA%ePey~gqU8S6h-^J2Y?>7)L2+%8kV}Gp=h`Xm_}rlm)SyUS=`=S7msKu zC|T!gPiI1rWGb1z$Md?0YJQ;%>uPLOXf1Z>N~`~JHJ!^@D5kSXQ4ugnFZ>^`zH8CAiZmp z6Ms|#2gcGsQ{{u7+Nb9sA?U>(0e$5V1|WVwY`Kn)rsnnZ4=1u=7u!4WexZD^IQ1Jk zfF#NLe>W$3m&C^ULjdw+5|)-BSHwpegdyt9NYC{3@QtMfd8GrIWDu`gd0nv-3LpGCh@wgBaG z176tikL!_NXM+Bv#7q^cyn9$XSeZR6#!B4JE@GVH zoobHZN_*RF#@_SVYKkQ_igme-Y5U}cV(hkR#k1c{bQNMji zU7aE`?dHyx=1`kOYZo_8U7?3-7vHOp`Qe%Z*i+FX!s?6huNp0iCEW-Z7E&jRWmUW_ z67j>)Ew!yq)hhG4o?^z}HWH-e=es#xJUhDRc4B51M4~E-l5VZ!&zQq`gWe`?}#b~7w1LH4Xa-UCT5LXkXQWheBa2YJYbyQ zl1pXR%b(KCXMO0OsXgl0P0Og<{(@&z1aokU-Pq`eQq*JYgt8xdFQ6S z6Z3IFSua8W&M#`~*L#r>Jfd6*BzJ?JFdBR#bDv$_0N!_5vnmo@!>vULcDm`MFU823 zpG9pqjqz^FE5zMDoGqhs5OMmC{Y3iVcl>F}5Rs24Y5B^mYQ;1T&ks@pIApHOdrzXF z-SdX}Hf{X;TaSxG_T$0~#RhqKISGKNK47}0*x&nRIPtmdwxc&QT3$8&!3fWu1eZ_P zJveQj^hJL#Sn!*4k`3}(d(aasl&7G0j0-*_2xtAnoX1@9+h zO#c>YQg60Z;o{Bi=3i7S`Ic+ZE>K{(u|#)9y}q*j8uKQ1^>+(BI}m%1v3$=4ojGBc zm+o1*!T&b}-lVvZqIUBc8V}QyFEgm#oyIuC{8WqUNV{Toz`oxhYpP!_p2oHHh5P@iB*NVo~2=GQm+8Yrkm2Xjc_VyHg1c0>+o~@>*Qzo zHVBJS>$$}$_4EniTI;b1WShX<5-p#TPB&!;lP!lBVBbLOOxh6FuYloD%m;n{r|;MU3!q4AVkua~fieeWu2 zQAQ$ue(IklX6+V;F1vCu-&V?I3d42FgWgsb_e^29ol}HYft?{SLf>DrmOp9o!t>I^ zY7fBCk+E8n_|apgM|-;^=#B?6RnFKlN`oR)`e$+;D=yO-(U^jV;rft^G_zl`n7qnM zL z*-Y4Phq+ZI1$j$F-f;`CD#|`-T~OM5Q>x}a>B~Gb3-+9i>Lfr|Ca6S^8g*{*?_5!x zH_N!SoRP=gX1?)q%>QTY!r77e2j9W(I!uAz{T`NdNmPBBUzi2{`XMB^zJGGwFWeA9 z{fk33#*9SO0)DjROug+(M)I-pKA!CX;IY(#gE!UxXVsa)X!UftIN98{pt#4MJHOhY zM$_l}-TJlxY?LS6Nuz1T<44m<4i^8k@D$zuCPrkmz@sdv+{ciyFJG2Zwy&%c7;atIeTdh!a(R^QXnu1Oq1b42*OQFWnyQ zWeQrdvP|w_idy53Wa<{QH^lFmEd+VlJkyiC>6B#s)F;w-{c;aKIm;Kp50HnA-o3lY z9B~F$gJ@yYE#g#X&3ADx&tO+P_@mnQTz9gv30_sTsaGXkfNYXY{$(>*PEN3QL>I!k zp)KibPhrfX3%Z$H6SY`rXGYS~143wZrG2;=FLj50+VM6soI~up_>fU(2Wl@{BRsMi zO%sL3x?2l1cXTF)k&moNsHfQrQ+wu(gBt{sk#CU=UhrvJIncy@tJX5klLjgMn>~h= zg|FR&;@eh|C7`>s_9c~0-{IAPV){l|Ts`i=)AW;d9&KPc3fMeoTS%8@V~D8*h;&(^>yjT84MM}=%#LS7shLAuuj(0VAYoozhWjq z4LEr?wUe2^WGwdTIgWBkDUJa>YP@5d9^Rs$kCXmMRxuF*YMVrn?0NFyPl}>`&dqZb z<5eqR=ZG3>n2{6v6BvJ`YBZeeTtB88TAY(x0a58EWyuf>+^|x8Qa6wA|1Nb_p|nA zWWa}|z8a)--Wj`LqyFk_a3gN2>5{Rl_wbW?#by7&i*^hRknK%jwIH6=dQ8*-_{*x0j^DUfMX0`|K@6C<|1cgZ~D(e5vBFFm;HTZF(!vT8=T$K+|F)x3kqzBV4-=p1V(lzi(s7jdu0>LD#N=$Lk#3HkG!a zIF<7>%B7sRNzJ66KrFV76J<2bdYhxll0y2^_rdG=I%AgW4~)1Nvz=$1UkE^J%BxLo z+lUci`UcU062os*=`-j4IfSQA{w@y|3}Vk?i;&SSdh8n+$iHA#%ERL{;EpXl6u&8@ zzg}?hkEOUOJt?ZL=pWZFJ19mI1@P=$U5*Im1e_8Z${JsM>Ov?nh8Z zP5QvI!{Jy@&BP48%P2{Jr_VgzW;P@7)M9n|lDT|Ep#}7C$&ud&6>C^5ZiwKIg2McPU(4jhM!BD@@L(Gd*Nu$ji(ljZ<{FIeW_1Mmf;76{LU z-ywN~=uNN)Xi6$<12A9y)K%X|(W0p|&>>4OXB?IiYr||WKDOJPxiSe01NSV-h24^L z_>m$;|C+q!Mj**-qQ$L-*++en(g|hw;M!^%_h-iDjFHLo-n3JpB;p?+o2;`*jpvJU zLY^lt)Un4joij^^)O(CKs@7E%*!w>!HA4Q?0}oBJ7Nr8NQ7QmY^4~jvf0-`%waOLn zdNjAPaC0_7c|RVhw)+71NWjRi!y>C+Bl;Z`NiL^zn2*0kmj5gyhCLCxts*cWCdRI| zjsd=sT5BVJc^$GxP~YF$-U{-?kW6r@^vHXB%{CqYzU@1>dzf#3SYedJG-Rm6^RB7s zGM5PR(yKPKR)>?~vpUIeTP7A1sc8-knnJk*9)3t^e%izbdm>Y=W{$wm(cy1RB-19i za#828DMBY+ps#7Y8^6t)=Ea@%Nkt)O6JCx|ybC;Ap}Z@Zw~*}3P>MZLPb4Enxz9Wf zssobT^(R@KuShj8>@!1M7tm|2%-pYYDxz-5`rCbaTCG5{;Uxm z*g=+H1X8{NUvFGzz~wXa%Eo};I;~`37*WrRU&K0dPSB$yk(Z*@K&+mFal^?c zurbqB-+|Kb5|sznT;?Pj!+kgFY1#Dr;_%A(GIQC{3ct|{*Bji%FNa6c-thbpBkA;U zURV!Dr&X{0J}iht#-Qp2=xzuh(fM>zRoiGrYl5ttw2#r34gC41CCOC31m~^UPTK@s z6;A@)7O7_%C)>bnAXerYuAHdE93>j2N}H${zEc6&SbZ|-fiG*-qtGuy-qDelH(|u$ zorf8_T6Zqe#Ub!+e3oSyrskt_HyW_^5lrWt#30l)tHk|j$@YyEkXUOV;6B51L;M@=NIWZXU;GrAa(LGxO%|im%7F<-6N;en0Cr zLH>l*y?pMwt`1*cH~LdBPFY_l;~`N!Clyfr;7w<^X;&(ZiVdF1S5e(+Q%60zgh)s4 zn2yj$+mE=miVERP(g8}G4<85^-5f@qxh2ec?n+$A_`?qN=iyT1?U@t?V6DM~BIlBB z>u~eXm-aE>R0sQy!-I4xtCNi!!qh?R1!kKf6BoH2GG{L4%PAz0{Sh6xpuyI%*~u)s z%rLuFl)uQUCBQAtMyN;%)zFMx4loh7uTfKeB2Xif`lN?2gq6NhWhfz0u5WP9J>=V2 zo{mLtSy&BA!mSzs&CrKWq^y40JF5a&GSXIi2= z{EYb59J4}VwikL4P=>+mc6{($FNE@e=VUwG+KV21;<@lrN`mnz5jYGASyvz7BOG_6(p^eTxD-4O#lROgon;R35=|nj#eHIfJBYPWG>H>`dHKCDZ3`R{-?HO0mE~(5_WYcFmp8sU?wr*UkAQiNDGc6T zA%}GOLXlOWqL?WwfHO8MB#8M8*~Y*gz;1rWWoVSXP&IbKxbQ8+s%4Jnt?kDsq7btI zCDr0PZ)b;B%!lu&CT#RJzm{l{2fq|BcY85`w~3LSK<><@(2EdzFLt9Y_`;WXL6x`0 zDoQ?=?I@Hbr;*VVll1Gmd8*%tiXggMK81a+T(5Gx6;eNb8=uYn z5BG-0g>pP21NPn>$ntBh>`*})Fl|38oC^9Qz>~MAazH%3Q~Qb!ALMf$srexgPZ2@&c~+hxRi1;}+)-06)!#Mq<6GhP z-Q?qmgo${aFBApb5p}$1OJKTClfi8%PpnczyVKkoHw7Ml9e7ikrF0d~UB}i3vizos zXW4DN$SiEV9{faLt5bHy2a>33K%7Td-n5C*N;f&ZqAg#2hIqEb(y<&f4u5BWJ>2^4 z414GosL=Aom#m&=x_v<0-fp1r%oVJ{T-(xnomNJ(Dryv zh?vj+%=II_nV+@NR+(!fZZVM&(W6{6%9cm+o+Z6}KqzLw{(>E86uA1`_K$HqINlb1 zKelh3-jr2I9V?ych`{hta9wQ2c9=MM`2cC{m6^MhlL2{DLv7C^j z$xXBCnDl_;l|bPGMX@*tV)B!c|4oZyftUlP*?$YU9C_eAsuVHJ58?)zpbr30P*C`T z7y#ao`uE-SOG(Pi+`$=e^mle~)pRrdwL5)N;o{gpW21of(QE#U6w%*C~`v-z0QqBML!!5EeYA5IQB0 z^l01c;L6E(iytN!LhL}wfwP7W9PNAkb+)Cst?qg#$n;z41O4&v+8-zPs+XNb-q zIeeBCh#ivnFLUCwfS;p{LC0O7tm+Sf9Jn)~b%uwP{%69;QC)Ok0t%*a5M+=;y8j=v z#!*pp$9@!x;UMIs4~hP#pnfVc!%-D<+wsG@R2+J&%73lK|2G!EQC)O05TCV=&3g)C!lT=czLpZ@Sa%TYuoE?v8T8`V;e$#Zf2_Nj6nvBgh1)2 GZ~q4|mN%#X literal 0 HcmV?d00001 diff --git a/examples/drivebase_only_2026/gradle/wrapper/gradle-wrapper.properties b/examples/drivebase_only_2026/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..34bd9ce --- /dev/null +++ b/examples/drivebase_only_2026/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=permwrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=permwrapper/dists diff --git a/examples/drivebase_only_2026/gradlew b/examples/drivebase_only_2026/gradlew new file mode 100644 index 0000000..f5feea6 --- /dev/null +++ b/examples/drivebase_only_2026/gradlew @@ -0,0 +1,252 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/examples/drivebase_only_2026/gradlew.bat b/examples/drivebase_only_2026/gradlew.bat new file mode 100644 index 0000000..9d21a21 --- /dev/null +++ b/examples/drivebase_only_2026/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/examples/drivebase_only_2026/settings.gradle b/examples/drivebase_only_2026/settings.gradle new file mode 100644 index 0000000..25f6f6e --- /dev/null +++ b/examples/drivebase_only_2026/settings.gradle @@ -0,0 +1,30 @@ +import org.gradle.internal.os.OperatingSystem + +pluginManagement { + repositories { + mavenLocal() + gradlePluginPortal() + String frcYear = '2026' + File frcHome + if (OperatingSystem.current().isWindows()) { + String publicFolder = System.getenv('PUBLIC') + if (publicFolder == null) { + publicFolder = "C:\\Users\\Public" + } + def homeRoot = new File(publicFolder, "wpilib") + frcHome = new File(homeRoot, frcYear) + } else { + def userFolder = System.getProperty("user.home") + def homeRoot = new File(userFolder, "wpilib") + frcHome = new File(homeRoot, frcYear) + } + def frcHomeMaven = new File(frcHome, 'maven') + maven { + name = 'frcHome' + url = frcHomeMaven + } + } +} + +Properties props = System.getProperties(); +props.setProperty("org.gradle.internal.native.headers.unresolved.dependencies.ignore", "true"); diff --git a/examples/drivebase_only_2026/src/main/deploy/example.txt b/examples/drivebase_only_2026/src/main/deploy/example.txt new file mode 100644 index 0000000..bb82515 --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/example.txt @@ -0,0 +1,3 @@ +Files placed in this directory will be deployed to the RoboRIO into the +'deploy' directory in the home folder. Use the 'Filesystem.getDeployDirectory' wpilib function +to get a proper path relative to the deploy directory. \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/pathplanner/SamplePath.path b/examples/drivebase_only_2026/src/main/deploy/pathplanner/SamplePath.path new file mode 100644 index 0000000..d9df9e5 --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/pathplanner/SamplePath.path @@ -0,0 +1,76 @@ +{ + "waypoints": [ + { + "anchorPoint": { + "x": 0.8409049675242211, + "y": 3.593000471715229 + }, + "prevControl": null, + "nextControl": { + "x": 1.8409049675242182, + "y": 3.593000471715229 + }, + "holonomicAngle": 0, + "isReversal": false, + "velOverride": null, + "isLocked": false, + "isStopPoint": false, + "stopEvent": { + "names": [], + "executionBehavior": "parallel", + "waitBehavior": "none", + "waitTime": 0 + } + }, + { + "anchorPoint": { + "x": 3.0, + "y": 5.0 + }, + "prevControl": { + "x": 3.0, + "y": 3.8506044103316963 + }, + "nextControl": { + "x": 3.0, + "y": 3.8506044103316963 + }, + "holonomicAngle": 90.0, + "isReversal": true, + "velOverride": null, + "isLocked": false, + "isStopPoint": true, + "stopEvent": { + "names": [ + "marker1" + ], + "executionBehavior": "parallel", + "waitBehavior": "after", + "waitTime": 2.0 + } + }, + { + "anchorPoint": { + "x": 5.0, + "y": 3.0 + }, + "prevControl": { + "x": 4.0, + "y": 3.0 + }, + "nextControl": null, + "holonomicAngle": 0, + "isReversal": false, + "velOverride": null, + "isLocked": false, + "isStopPoint": false, + "stopEvent": { + "names": [], + "executionBehavior": "parallel", + "waitBehavior": "none", + "waitTime": 0 + } + } + ], + "markers": [] +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/pathplanner/autos/New Auto.auto b/examples/drivebase_only_2026/src/main/deploy/pathplanner/autos/New Auto.auto new file mode 100644 index 0000000..268147b --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/pathplanner/autos/New Auto.auto @@ -0,0 +1,19 @@ +{ + "version": "2025.0", + "command": { + "type": "sequential", + "data": { + "commands": [ + { + "type": "path", + "data": { + "pathName": "New Path" + } + } + ] + } + }, + "resetOdom": true, + "folder": null, + "choreoAuto": false +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/pathplanner/generatedJSON/New Path.wpilib.json b/examples/drivebase_only_2026/src/main/deploy/pathplanner/generatedJSON/New Path.wpilib.json new file mode 100644 index 0000000..71f0fcd --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/pathplanner/generatedJSON/New Path.wpilib.json @@ -0,0 +1,9002 @@ +[ + { + "time": 0.0, + "pose": { + "rotation": { + "radians": 0.003994666723425411 + }, + "translation": { + "x": 1.0, + "y": 3.0 + } + }, + "velocity": 0, + "acceleration": 3.0, + "curvature": 0.6639756640813854, + "holonomicRotation": 0.0, + "angularVelocity": 0.0, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.08944283740393223, + "pose": { + "rotation": { + "radians": 0.003994666723425411 + }, + "translation": { + "x": 1.011999936, + "y": 3.000047936 + } + }, + "velocity": 0.2683285122117967, + "acceleration": 3.0, + "curvature": 0.6639756640813854, + "holonomicRotation": 0.0, + "angularVelocity": 0.21506066046275568, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.12649227216974931, + "pose": { + "rotation": { + "radians": 0.011962542633933815 + }, + "translation": { + "x": 1.023999488, + "y": 3.000191488 + } + }, + "velocity": 0.37947681650924797, + "acceleration": 3.0000000000000004, + "curvature": 0.6612478412834536, + "holonomicRotation": 0.0, + "angularVelocity": 0.2791196654351322, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.15492278103446244, + "pose": { + "rotation": { + "radians": 0.019898056756403104 + }, + "translation": { + "x": 1.035998272, + "y": 3.000430272 + } + }, + "velocity": 0.4647683431033873, + "acceleration": 2.999999999999999, + "curvature": 0.6584819160891061, + "holonomicRotation": 0.0, + "angularVelocity": 0.3297027488703112, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.1788926532379475, + "pose": { + "rotation": { + "radians": 0.027800989511962193 + }, + "translation": { + "x": 1.047995904, + "y": 3.000763904 + } + }, + "velocity": 0.5366779597138426, + "acceleration": 3.000000000000002, + "curvature": 0.6556801390904735, + "holonomicRotation": 0.0, + "angularVelocity": 0.3726393102517324, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.20001267329763361, + "pose": { + "rotation": { + "radians": 0.035671139219506376 + }, + "translation": { + "x": 1.059992, + "y": 3.001192 + } + }, + "velocity": 0.600038019892901, + "acceleration": 3.0000000000000027, + "curvature": 0.6528447360474213, + "holonomicRotation": 0.0, + "angularVelocity": 0.41040227730614015, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.21910901626437457, + "pose": { + "rotation": { + "radians": 0.043508321861275956 + }, + "translation": { + "x": 1.071986176, + "y": 3.001714176 + } + }, + "velocity": 0.6573270487931238, + "acceleration": 2.999999999999997, + "curvature": 0.6499779059037429, + "holonomicRotation": 0.0, + "angularVelocity": 0.44433343266184905, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.23667251341123324, + "pose": { + "rotation": { + "radians": 0.05131237083808626 + }, + "translation": { + "x": 1.083978048, + "y": 3.0023300479999997 + } + }, + "velocity": 0.7100175402336998, + "acceleration": 3.0, + "curvature": 0.6470818190817624, + "holonomicRotation": 0.0, + "angularVelocity": 0.4752620325524382, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.2530230008132736, + "pose": { + "rotation": { + "radians": 0.059083136714003004 + }, + "translation": { + "x": 1.095967232, + "y": 3.0030392320000003 + } + }, + "velocity": 0.7590690024398208, + "acceleration": 2.9999999999999933, + "curvature": 0.6441586157879952, + "holonomicRotation": 0.0, + "angularVelocity": 0.503744881604611, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.2683826610691287, + "pose": { + "rotation": { + "radians": 0.06682048695107579 + }, + "translation": { + "x": 1.107953344, + "y": 3.003841344 + } + }, + "velocity": 0.8051479832073861, + "acceleration": 3.0, + "curvature": 0.6412104045031461, + "holonomicRotation": 0.0, + "angularVelocity": 0.5301782294749301, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.28291328163710894, + "pose": { + "rotation": { + "radians": 0.07452430563697954 + }, + "translation": { + "x": 1.119936, + "y": 3.004736 + } + }, + "velocity": 0.8487398449113267, + "acceleration": 2.999999999999996, + "curvature": 0.6382392605344197, + "holonomicRotation": 0.0, + "angularVelocity": 0.5548565565084475, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.29673701224983334, + "pose": { + "rotation": { + "radians": 0.08219449320285621 + }, + "translation": { + "x": 1.131914816, + "y": 3.005722816 + } + }, + "velocity": 0.8902110367494999, + "acceleration": 2.999999999999996, + "curvature": 0.6352472246423004, + "holonomicRotation": 0.0, + "angularVelocity": 0.578006214771147, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.3099487610809687, + "pose": { + "rotation": { + "radians": 0.08983096613524788 + }, + "translation": { + "x": 1.1438894080000002, + "y": 3.0068014080000003 + } + }, + "velocity": 0.9298462832429059, + "acceleration": 2.999999999999996, + "curvature": 0.6322363019942066, + "holonomicRotation": 0.0, + "angularVelocity": 0.5998059641247867, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.32262401107954614, + "pose": { + "rotation": { + "radians": 0.09743365668116732 + }, + "translation": { + "x": 1.1558593920000002, + "y": 3.007971392 + } + }, + "velocity": 0.9678720332386382, + "acceleration": 3.0000000000000044, + "curvature": 0.6292084609699508, + "holonomicRotation": 0.0, + "angularVelocity": 0.6204001606264152, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.33482396902093875, + "pose": { + "rotation": { + "radians": 0.10500251254764281 + }, + "translation": { + "x": 1.1678243840000002, + "y": 3.009232384 + } + }, + "velocity": 1.004471907062816, + "acceleration": 3.0, + "curvature": 0.6261656322069515, + "holonomicRotation": 0.0, + "angularVelocity": 0.6399075802749538, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.34659908199060496, + "pose": { + "rotation": { + "radians": 0.11253749659552614 + }, + "translation": { + "x": 1.1797840000000002, + "y": 3.010584 + } + }, + "velocity": 1.0397972459718146, + "acceleration": 2.999999999999986, + "curvature": 0.6231097077741713, + "holonomicRotation": 0.0, + "angularVelocity": 0.6584275258643302, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.35799151265261864, + "pose": { + "rotation": { + "radians": 0.12003858652989674 + }, + "translation": { + "x": 1.191737856, + "y": 3.012025856 + } + }, + "velocity": 1.0739745379578558, + "acceleration": 3.0000000000000195, + "curvature": 0.6200425403858878, + "holonomicRotation": 0.0, + "angularVelocity": 0.6760441751840484, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.3690369270353713, + "pose": { + "rotation": { + "radians": 0.12750577458585077 + }, + "translation": { + "x": 1.203685568, + "y": 3.013557568 + } + }, + "velocity": 1.1071107811061136, + "acceleration": 2.99999999999999, + "curvature": 0.6169659427566434, + "holonomicRotation": 0.0, + "angularVelocity": 0.6928297531996462, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.3797658147476807, + "pose": { + "rotation": { + "radians": 0.1349390672116768 + }, + "translation": { + "x": 1.2156267520000001, + "y": 3.0151787519999997 + } + }, + "velocity": 1.1392974442430417, + "acceleration": 2.99999999999999, + "curvature": 0.6138816870208452, + "holonomicRotation": 0.0, + "angularVelocity": 0.7088468950979862, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.39020448294066074, + "pose": { + "rotation": { + "radians": 0.14233848474922883 + }, + "translation": { + "x": 1.2275610240000001, + "y": 3.016889024 + } + }, + "velocity": 1.170613448821982, + "acceleration": 3.0000000000000053, + "curvature": 0.6107915042289077, + "holonomicRotation": 0.0, + "angularVelocity": 0.7241504390542802, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.40037581746696743, + "pose": { + "rotation": { + "radians": 0.1497040611122218 + }, + "translation": { + "x": 1.2394880000000001, + "y": 3.018688 + } + }, + "velocity": 1.2011274524009021, + "acceleration": 3.000000000000011, + "curvature": 0.6076970841012796, + "holonomicRotation": 0.0, + "angularVelocity": 0.7387888084367961, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.4102998746100373, + "pose": { + "rotation": { + "radians": 0.15703584346380906 + }, + "translation": { + "x": 1.2514072960000002, + "y": 3.020575296 + } + }, + "velocity": 1.2308996238301118, + "acceleration": 3.0, + "curvature": 0.6046000745612534, + "holonomicRotation": 0.0, + "angularVelocity": 0.7528050925445897, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.4199943473238247, + "pose": { + "rotation": { + "radians": 0.16433389189228276 + }, + "translation": { + "x": 1.263318528, + "y": 3.022550528 + } + }, + "velocity": 1.2599830419714737, + "acceleration": 2.9999999999999827, + "curvature": 0.6015020816536292, + "holonomicRotation": 0.0, + "angularVelocity": 0.7662379027190784, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.4294749370586641, + "pose": { + "rotation": { + "radians": 0.17159827908724612 + }, + "translation": { + "x": 1.2752213120000002, + "y": 3.024613312 + } + }, + "velocity": 1.288424811175992, + "acceleration": 3.0000000000000058, + "curvature": 0.598404669370064, + "holonomicRotation": 0.0, + "angularVelocity": 0.7791220580680622, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.4387556535437481, + "pose": { + "rotation": { + "radians": 0.178829090015451 + }, + "translation": { + "x": 1.2871152640000003, + "y": 3.026763264 + } + }, + "velocity": 1.316266960631244, + "acceleration": 2.9999999999999942, + "curvature": 0.595309359586865, + "holonomicRotation": 0.0, + "angularVelocity": 0.7914891405693073, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.4478490588896583, + "pose": { + "rotation": { + "radians": 0.1860264215975338 + }, + "translation": { + "x": 1.2990000000000002, + "y": 3.0290000000000004 + } + }, + "velocity": 1.3435471766689746, + "acceleration": 3.0, + "curvature": 0.5922176320623258, + "holonomicRotation": 0.0, + "angularVelocity": 0.8033679485304233, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.4567664681550803, + "pose": { + "rotation": { + "radians": 0.19319038238530206 + }, + "translation": { + "x": 1.3108751360000002, + "y": 3.031323136 + } + }, + "velocity": 1.3702994044652408, + "acceleration": 3.0000000000000187, + "curvature": 0.5891309246519478, + "holonomicRotation": 0.0, + "angularVelocity": 0.8147848704001008, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.4655181155102056, + "pose": { + "rotation": { + "radians": 0.2003210922413352 + }, + "translation": { + "x": 1.3227402880000003, + "y": 3.033732288 + } + }, + "velocity": 1.3965543465306167, + "acceleration": 3.000000000000006, + "curvature": 0.586050633250819, + "holonomicRotation": 0.0, + "angularVelocity": 0.8257641950388135, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.4741132929479354, + "pose": { + "rotation": { + "radians": 0.20741868201941793 + }, + "translation": { + "x": 1.3345950720000002, + "y": 3.036227072 + } + }, + "velocity": 1.4223398788438062, + "acceleration": 3.0000000000000067, + "curvature": 0.5829781121894732, + "holonomicRotation": 0.0, + "angularVelocity": 0.8363283714373475, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.48256046689262294, + "pose": { + "rotation": { + "radians": 0.21448329324782645 + }, + "translation": { + "x": 1.3464391040000003, + "y": 3.038807104 + } + }, + "velocity": 1.4476814006778689, + "acceleration": 3.0000000000000133, + "curvature": 0.5799146744073622, + "holonomicRotation": 0.0, + "angularVelocity": 0.8464982273774265, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.4908673768658824, + "pose": { + "rotation": { + "radians": 0.22151507781517443 + }, + "translation": { + "x": 1.3582720000000004, + "y": 3.041472 + } + }, + "velocity": 1.472602130597647, + "acceleration": 2.9999999999999867, + "curvature": 0.576861591813293, + "holonomicRotation": 0.0, + "angularVelocity": 0.8562931546703403, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.49904111947427243, + "pose": { + "rotation": { + "radians": 0.22851419765877612 + }, + "translation": { + "x": 1.3700933760000003, + "y": 3.044221376 + } + }, + "velocity": 1.4971233584228174, + "acceleration": 3.0000000000000204, + "curvature": 0.5738200956320813, + "holonomicRotation": 0.0, + "angularVelocity": 0.865731267137874, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.5070882203039146, + "pose": { + "rotation": { + "radians": 0.2354808244568085 + }, + "translation": { + "x": 1.3819028480000004, + "y": 3.047054848 + } + }, + "velocity": 1.521264660911744, + "acceleration": 2.9999999999999862, + "curvature": 0.5707913768705666, + "holonomicRotation": 0.0, + "angularVelocity": 0.8748295358184321, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.5150146957856219, + "pose": { + "rotation": { + "radians": 0.24241513932314662 + }, + "translation": { + "x": 1.3937000320000004, + "y": 3.0499720320000003 + } + }, + "velocity": 1.5450440873568656, + "acceleration": 3.0, + "curvature": 0.5677765867125653, + "holonomicRotation": 0.0, + "angularVelocity": 0.8836039055955357, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.5228261066903811, + "pose": { + "rotation": { + "radians": 0.24931733250680344 + }, + "translation": { + "x": 1.4054845440000003, + "y": 3.0529725439999997 + } + }, + "velocity": 1.5684783200711434, + "acceleration": 3.000000000000014, + "curvature": 0.5647768371119535, + "holonomicRotation": 0.0, + "angularVelocity": 0.8920693959970966, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.5305276045997832, + "pose": { + "rotation": { + "radians": 0.2561876030951167 + }, + "translation": { + "x": 1.4172560000000003, + "y": 3.0560560000000003 + } + }, + "velocity": 1.5915828137993497, + "acceleration": 3.0, + "curvature": 0.5617932012303706, + "holonomicRotation": 0.0, + "angularVelocity": 0.9002401887205707, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.5381239724478855, + "pose": { + "rotation": { + "radians": 0.2630261587202831 + }, + "translation": { + "x": 1.4290140160000004, + "y": 3.059222016 + } + }, + "velocity": 1.6143719173436566, + "acceleration": 3.0000000000000147, + "curvature": 0.5588267141256478, + "holonomicRotation": 0.0, + "angularVelocity": 0.9081297043799728, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.545619660034259, + "pose": { + "rotation": { + "radians": 0.26983321527222115 + }, + "translation": { + "x": 1.4407582080000003, + "y": 3.062470208 + } + }, + "velocity": 1.636858980102777, + "acceleration": 2.9999999999999853, + "curvature": 0.5558783732950194, + "holonomicRotation": 0.0, + "angularVelocity": 0.9157506692832025, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.5530188152508757, + "pose": { + "rotation": { + "radians": 0.2766089966139682 + }, + "translation": { + "x": 1.4524881920000003, + "y": 3.065800192 + } + }, + "velocity": 1.6590564457526273, + "acceleration": 3.000000000000015, + "curvature": 0.5529491392614916, + "holonomicRotation": 0.0, + "angularVelocity": 0.9231151746218296, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.5603253116392223, + "pose": { + "rotation": { + "radians": 0.2833537343033705 + }, + "translation": { + "x": 1.4642035840000003, + "y": 3.069211584 + } + }, + "velocity": 1.680975934917667, + "acceleration": 2.999999999999985, + "curvature": 0.550039936396451, + "holonomicRotation": 0.0, + "angularVelocity": 0.930234728482705, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.5675427727919045, + "pose": { + "rotation": { + "radians": 0.2900676673190703 + }, + "translation": { + "x": 1.4759040000000003, + "y": 3.072704 + } + }, + "velocity": 1.7026283183757136, + "acceleration": 3.0000000000000155, + "curvature": 0.5471516534114057, + "holonomicRotation": 0.0, + "angularVelocity": 0.9371203020376715, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.5746745940299195, + "pose": { + "rotation": { + "radians": 0.29675104179171763 + }, + "translation": { + "x": 1.4875890560000005, + "y": 3.0762770560000003 + } + }, + "velocity": 1.7240237820897588, + "acceleration": 3.0000000000000155, + "curvature": 0.5442851441519642, + "holonomicRotation": 0.0, + "angularVelocity": 0.9437823705764029, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.5817239617188056, + "pose": { + "rotation": { + "radians": 0.30340411074019924 + }, + "translation": { + "x": 1.4992583680000005, + "y": 3.0799303680000003 + } + }, + "velocity": 1.745171885156417, + "acceleration": 3.0, + "curvature": 0.5414412284047404, + "holonomicRotation": 0.0, + "angularVelocity": 0.9502309502250106, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.5886938705309835, + "pose": { + "rotation": { + "radians": 0.3100271338137768 + }, + "translation": { + "x": 1.5109115520000005, + "y": 3.083663552 + } + }, + "velocity": 1.766081611592951, + "acceleration": 3.0, + "curvature": 0.538620692477182, + "holonomicRotation": 0.0, + "angularVelocity": 0.9564756306438044, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.595587138915401, + "pose": { + "rotation": { + "radians": 0.3166203770389595 + }, + "translation": { + "x": 1.5225482240000003, + "y": 3.087476224 + } + }, + "velocity": 1.7867614167462034, + "acceleration": 2.999999999999984, + "curvature": 0.5358242899805497, + "holonomicRotation": 0.0, + "angularVelocity": 0.9625256044965456, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.6024064229972305, + "pose": { + "rotation": { + "radians": 0.32318411257205604 + }, + "translation": { + "x": 1.5341680000000004, + "y": 3.091368 + } + }, + "velocity": 1.8072192689916917, + "acceleration": 3.0000000000000164, + "curvature": 0.5330527427341295, + "holonomicRotation": 0.0, + "angularVelocity": 0.9683896940146024, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.609154229098364, + "pose": { + "rotation": { + "radians": 0.32971861845760264 + }, + "translation": { + "x": 1.5457704960000005, + "y": 3.095338496 + } + }, + "velocity": 1.8274626872950925, + "acceleration": 3.0000000000000164, + "curvature": 0.530306741366546, + "holonomicRotation": 0.0, + "angularVelocity": 0.9740763749015857, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.6158329250426408, + "pose": { + "rotation": { + "radians": 0.33622417839207364 + }, + "translation": { + "x": 1.5573553280000003, + "y": 3.099387328 + } + }, + "velocity": 1.8474987751279226, + "acceleration": 2.9999999999999836, + "curvature": 0.5275869461466284, + "holonomicRotation": 0.0, + "angularVelocity": 0.9795937980259228, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.6224447503871835, + "pose": { + "rotation": { + "radians": 0.3427010814932183 + }, + "translation": { + "x": 1.5689221120000005, + "y": 3.103514112 + } + }, + "velocity": 1.867334251161551, + "acceleration": 3.000000000000017, + "curvature": 0.5248939877909048, + "holonomicRotation": 0.0, + "angularVelocity": 0.9849498091847217, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.6289918257021776, + "pose": { + "rotation": { + "radians": 0.34914962207543976 + }, + "translation": { + "x": 1.5804704640000005, + "y": 3.1077184640000004 + } + }, + "velocity": 1.8869754771065332, + "acceleration": 3.0, + "curvature": 0.5222284682600525, + "holonomicRotation": 0.0, + "angularVelocity": 0.9901519669517042, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.6354761610052784, + "pose": { + "rotation": { + "radians": 0.35557009943017936 + }, + "translation": { + "x": 1.5920000000000005, + "y": 3.112 + } + }, + "velocity": 1.9064284830158356, + "acceleration": 3.0, + "curvature": 0.5195909614569448, + "holonomicRotation": 0.0, + "angularVelocity": 0.995207559235847, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.6418996634430969, + "pose": { + "rotation": { + "radians": 0.36196281761306626 + }, + "translation": { + "x": 1.6035103360000005, + "y": 3.1163583360000002 + } + }, + "velocity": 1.925698990329291, + "acceleration": 2.9999999999999654, + "curvature": 0.5169820141397625, + "holonomicRotation": 0.0, + "angularVelocity": 1.0001236180941289, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.6482641443004898, + "pose": { + "rotation": { + "radians": 0.3683280852354529 + }, + "translation": { + "x": 1.6150010880000005, + "y": 3.120793088 + } + }, + "velocity": 1.9447924329014699, + "acceleration": 3.0000000000000173, + "curvature": 0.5144021466205864, + "holonomicRotation": 0.0, + "angularVelocity": 1.0049069337160952, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.654571325408339, + "pose": { + "rotation": { + "radians": 0.37466621526293364 + }, + "translation": { + "x": 1.6264718720000004, + "y": 3.1253038720000004 + } + }, + "velocity": 1.963713976225017, + "acceleration": 2.9999999999999822, + "curvature": 0.5118518535480218, + "holonomicRotation": 0.0, + "angularVelocity": 1.0095640669411767, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.6608228450118765, + "pose": { + "rotation": { + "radians": 0.3809775248184435 + }, + "translation": { + "x": 1.6379223040000006, + "y": 3.1298903040000003 + } + }, + "velocity": 1.9824685350356297, + "acceleration": 3.0, + "curvature": 0.5093316047891678, + "holonomicRotation": 0.0, + "angularVelocity": 1.0141013611142926, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.6670202631541803, + "pose": { + "rotation": { + "radians": 0.3872623349919482 + }, + "translation": { + "x": 1.6493520000000006, + "y": 3.1345520000000002 + } + }, + "velocity": 2.001060789462541, + "acceleration": 2.9999999999999822, + "curvature": 0.5068418460483123, + "holonomicRotation": 0.0, + "angularVelocity": 1.0185249527914209, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.6731650666230385, + "pose": { + "rotation": { + "radians": 0.3935209706549796 + }, + "translation": { + "x": 1.6607605760000006, + "y": 3.139288576 + } + }, + "velocity": 2.019495199869116, + "acceleration": 3.000000000000036, + "curvature": 0.5043829997706955, + "holonomicRotation": 0.0, + "angularVelocity": 1.0228407818457754, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.6792586735038131, + "pose": { + "rotation": { + "radians": 0.3997537602811718 + }, + "translation": { + "x": 1.6721476480000006, + "y": 3.144099648 + } + }, + "velocity": 2.0377760205114397, + "acceleration": 3.000000000000018, + "curvature": 0.5019554658535227, + "holonomicRotation": 0.0, + "angularVelocity": 1.0270546007967487, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.6853024373760951, + "pose": { + "rotation": { + "radians": 0.4059610357723282 + }, + "translation": { + "x": 1.6835128320000006, + "y": 3.1489848320000005 + } + }, + "velocity": 2.055907312128286, + "acceleration": 3.000000000000018, + "curvature": 0.4995596223797258, + "holonomicRotation": 0.0, + "angularVelocity": 1.0311719834309776, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.6912976511877287, + "pose": { + "rotation": { + "radians": 0.41214313228956323 + }, + "translation": { + "x": 1.6948557440000005, + "y": 3.153943744 + } + }, + "velocity": 2.073892953563187, + "acceleration": 3.0000000000000555, + "curvature": 0.497195826433042, + "holonomicRotation": 0.0, + "angularVelocity": 1.0351983330346652, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.6972455508361, + "pose": { + "rotation": { + "radians": 0.41830038809061465 + }, + "translation": { + "x": 1.7061760000000006, + "y": 3.158976 + } + }, + "velocity": 2.0917366525083008, + "acceleration": 3.0, + "curvature": 0.49486441475959786, + "holonomicRotation": 0.0, + "angularVelocity": 1.0391388898355578, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.7031473184833589, + "pose": { + "rotation": { + "radians": 0.4244331443716547 + }, + "translation": { + "x": 1.7174732160000006, + "y": 3.164081216 + } + }, + "velocity": 2.1094419554500776, + "acceleration": 3.0000000000000187, + "curvature": 0.49256570452373255, + "holonomicRotation": 0.0, + "angularVelocity": 1.0429987382017707, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.7090040856294209, + "pose": { + "rotation": { + "radians": 0.4305417451149389 + }, + "translation": { + "x": 1.7287470080000005, + "y": 3.1692590080000005 + } + }, + "velocity": 2.1270122568882632, + "acceleration": 2.999999999999943, + "curvature": 0.4902999940555179, + "holonomicRotation": 0.0, + "angularVelocity": 1.0467828132720296, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.7148169359641001, + "pose": { + "rotation": { + "radians": 0.43662653694140374 + }, + "translation": { + "x": 1.7399969920000007, + "y": 3.1745089920000003 + } + }, + "velocity": 2.144450807892301, + "acceleration": 3.0, + "curvature": 0.48806756353004915, + "holonomicRotation": 0.0, + "angularVelocity": 1.0504959073278146, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.7205869080175377, + "pose": { + "rotation": { + "radians": 0.44268786896893575 + }, + "translation": { + "x": 1.7512227840000005, + "y": 3.1798307840000004 + } + }, + "velocity": 2.1617607240526135, + "acceleration": 2.999999999999981, + "curvature": 0.48586867565117137, + "holonomicRotation": 0.0, + "angularVelocity": 1.0541426755241503, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.7263149976261485, + "pose": { + "rotation": { + "radians": 0.44872609267459884 + }, + "translation": { + "x": 1.7624240000000007, + "y": 3.1852240000000003 + } + }, + "velocity": 2.178944992878446, + "acceleration": 3.0000000000000195, + "curvature": 0.4837035763245057, + "holonomicRotation": 0.0, + "angularVelocity": 1.057727641711773, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.7320021602295974, + "pose": { + "rotation": { + "radians": 0.45474156176317626 + }, + "translation": { + "x": 1.7736002560000006, + "y": 3.190688256 + } + }, + "velocity": 2.196006480688793, + "acceleration": 3.0, + "curvature": 0.48157249540881814, + "holonomicRotation": 0.0, + "angularVelocity": 1.0612552035501235, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.7376493130127955, + "pose": { + "rotation": { + "radians": 0.46073463203958775 + }, + "translation": { + "x": 1.7847511680000006, + "y": 3.1962231680000004 + } + }, + "velocity": 2.212947939038387, + "acceleration": 2.9999999999999605, + "curvature": 0.47947564724702235, + "holonomicRotation": 0.0, + "angularVelocity": 1.064729637583078, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.7432573369055535, + "pose": { + "rotation": { + "radians": 0.4667056612864813 + }, + "translation": { + "x": 1.7958763520000005, + "y": 3.2018283520000006 + } + }, + "velocity": 2.229772010716661, + "acceleration": 3.0, + "curvature": 0.4774132314234743, + "holonomicRotation": 0.0, + "angularVelocity": 1.0681551040334438, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.7488270784513326, + "pose": { + "rotation": { + "radians": 0.4726550091467523 + }, + "translation": { + "x": 1.8069754240000007, + "y": 3.2075034240000004 + } + }, + "velocity": 2.246481235353998, + "acceleration": 2.99999999999994, + "curvature": 0.47538543331431704, + "holonomicRotation": 0.0, + "angularVelocity": 1.0715356512801077, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.7543593515554528, + "pose": { + "rotation": { + "radians": 0.47858303701043514 + }, + "translation": { + "x": 1.8180480000000006, + "y": 3.2132480000000005 + } + }, + "velocity": 2.2630780546663583, + "acceleration": 2.99999999999998, + "curvature": 0.47339242474423837, + "holonomicRotation": 0.0, + "angularVelocity": 1.0748752201197043, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.7598549391221702, + "pose": { + "rotation": { + "radians": 0.48449010790589764 + }, + "translation": { + "x": 1.8290936960000006, + "y": 3.2190616960000002 + } + }, + "velocity": 2.2795648173665106, + "acceleration": 3.00000000000002, + "curvature": 0.4714343645997835, + "holonomicRotation": 0.0, + "angularVelocity": 1.078177648009616, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.7653145945891694, + "pose": { + "rotation": { + "radians": 0.4903765863962497 + }, + "translation": { + "x": 1.8401121280000006, + "y": 3.2249441280000006 + } + }, + "velocity": 2.2959437837675085, + "acceleration": 3.000000000000041, + "curvature": 0.46951139933779384, + "holonomicRotation": 0.0, + "angularVelocity": 1.081446672778329, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.7707390433672545, + "pose": { + "rotation": { + "radians": 0.49624283847896633 + }, + "translation": { + "x": 1.8511029120000007, + "y": 3.230894912 + } + }, + "velocity": 2.312217130101764, + "acceleration": 3.0000000000000204, + "curvature": 0.4676236637211531, + "holonomicRotation": 0.0, + "angularVelocity": 1.084685936629946, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.7761289841923315, + "pose": { + "rotation": { + "radians": 0.5020892314911949 + }, + "translation": { + "x": 1.8620656640000006, + "y": 3.2369136640000002 + } + }, + "velocity": 2.328386952576995, + "acceleration": 3.0000000000000617, + "curvature": 0.465771281161275, + "holonomicRotation": 0.0, + "angularVelocity": 1.087898989421331, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.7814850903961527, + "pose": { + "rotation": { + "radians": 0.5079161340175653 + }, + "translation": { + "x": 1.8730000000000007, + "y": 3.2430000000000003 + } + }, + "velocity": 2.3444552711884588, + "acceleration": 3.0, + "curvature": 0.4639543644847911, + "holonomicRotation": 0.0, + "angularVelocity": 1.091089292363366, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.78680801110174, + "pose": { + "rotation": { + "radians": 0.5137239158035309 + }, + "translation": { + "x": 1.8839055360000008, + "y": 3.249153536 + } + }, + "velocity": 2.360424033305221, + "acceleration": 3.0, + "curvature": 0.462173016289964, + "holonomicRotation": 0.0, + "angularVelocity": 1.0942602211599142, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.7920983723488966, + "pose": { + "rotation": { + "radians": 0.5195129476718603 + }, + "translation": { + "x": 1.8947818880000007, + "y": 3.2553738880000003 + } + }, + "velocity": 2.376295117046691, + "acceleration": 3.000000000000063, + "curvature": 0.4604273295606459, + "holonomicRotation": 0.0, + "angularVelocity": 1.0974150691626414, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.7973567781547642, + "pose": { + "rotation": { + "radians": 0.5252836014429918 + }, + "translation": { + "x": 1.9056286720000006, + "y": 3.2616606720000005 + } + }, + "velocity": 2.392070334464294, + "acceleration": 3.0000000000000213, + "curvature": 0.4587173881423953, + "holonomicRotation": 0.0, + "angularVelocity": 1.1005570504763318, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.8025838115139726, + "pose": { + "rotation": { + "radians": 0.5310362498595436 + }, + "translation": { + "x": 1.9164455040000006, + "y": 3.2680135040000002 + } + }, + "velocity": 2.407751434541919, + "acceleration": 3.0, + "curvature": 0.45704326727847255, + "holonomicRotation": 0.0, + "angularVelocity": 1.103689302847837, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.8077800353425552, + "pose": { + "rotation": { + "radians": 0.5367712665143531 + }, + "translation": { + "x": 1.9272320000000007, + "y": 3.2744320000000005 + } + }, + "velocity": 2.4233401060276667, + "acceleration": 3.0, + "curvature": 0.4554050339448593, + "holonomicRotation": 0.0, + "angularVelocity": 1.106814890388444, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.8129459933694659, + "pose": { + "rotation": { + "radians": 0.5424890257816597 + }, + "translation": { + "x": 1.9379877760000008, + "y": 3.2809157760000005 + } + }, + "velocity": 2.4388379801083993, + "acceleration": 3.000000000000043, + "curvature": 0.45380274753675837, + "holonomicRotation": 0.0, + "angularVelocity": 1.1099368064146276, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.8180822109792315, + "pose": { + "rotation": { + "radians": 0.5481899027524935 + }, + "translation": { + "x": 1.9487124480000007, + "y": 3.2874644480000006 + } + }, + "velocity": 2.454246632937696, + "acceleration": 3.0, + "curvature": 0.45223646009204105, + "holonomicRotation": 0.0, + "angularVelocity": 1.1130579759190018, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.8231891960089878, + "pose": { + "rotation": { + "radians": 0.5538742731727626 + }, + "translation": { + "x": 1.9594056320000008, + "y": 3.2940776320000005 + } + }, + "velocity": 2.469567588026965, + "acceleration": 3.0000000000000435, + "curvature": 0.45070621683540724, + "holonomicRotation": 0.0, + "angularVelocity": 1.1161812581904715, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.8282674395029013, + "pose": { + "rotation": { + "radians": 0.5595425133851966 + }, + "translation": { + "x": 1.9700669440000007, + "y": 3.3007549440000004 + } + }, + "velocity": 2.484802318508706, + "acceleration": 3.0000000000000657, + "curvature": 0.44921205667481234, + "holonomicRotation": 0.0, + "angularVelocity": 1.1193094491211109, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.833317416426745, + "pose": { + "rotation": { + "radians": 0.5651950002738984 + }, + "translation": { + "x": 1.980696000000001, + "y": 3.3074960000000004 + } + }, + "velocity": 2.499952249280237, + "acceleration": 3.0, + "curvature": 0.4477540124322439, + "holonomicRotation": 0.0, + "angularVelocity": 1.1224452836441048, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.8383395863451837, + "pose": { + "rotation": { + "radians": 0.5708321112125092 + }, + "translation": { + "x": 1.9912924160000007, + "y": 3.3143004160000005 + } + }, + "velocity": 2.515018759035553, + "acceleration": 3.0, + "curvature": 0.44633211133455136, + "holonomicRotation": 0.0, + "angularVelocity": 1.1255914379185776, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.8433343940641395, + "pose": { + "rotation": { + "radians": 0.5764542240150154 + }, + "translation": { + "x": 2.0018558080000006, + "y": 3.3211678080000007 + } + }, + "velocity": 2.5300031821924205, + "acceleration": 3.000000000000022, + "curvature": 0.4449463754713489, + "holonomicRotation": 0.0, + "angularVelocity": 1.1287505315367143, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.8483022702404226, + "pose": { + "rotation": { + "radians": 0.5820617168896036 + }, + "translation": { + "x": 2.012385792000001, + "y": 3.3280977920000003 + } + }, + "velocity": 2.54490681072127, + "acceleration": 2.999999999999978, + "curvature": 0.44359682198548334, + "holonomicRotation": 0.0, + "angularVelocity": 1.1319251296711867, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.8532436319606614, + "pose": { + "rotation": { + "radians": 0.5876549683955372 + }, + "translation": { + "x": 2.022881984000001, + "y": 3.3350899840000006 + } + }, + "velocity": 2.559730895881986, + "acceleration": 2.9999999999999325, + "curvature": 0.44228346357140413, + "holonomicRotation": 0.0, + "angularVelocity": 1.1351177449809835, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.8581588832914108, + "pose": { + "rotation": { + "radians": 0.5932343574021122 + }, + "translation": { + "x": 2.0333440000000005, + "y": 3.3421440000000007 + } + }, + "velocity": 2.574476649874234, + "acceleration": 3.0000000000000453, + "curvature": 0.44100630878383207, + "holonomicRotation": 0.0, + "angularVelocity": 1.138330839718644, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.8630484158021899, + "pose": { + "rotation": { + "radians": 0.598800263050939 + }, + "translation": { + "x": 2.043771456000001, + "y": 3.3492594560000004 + } + }, + "velocity": 2.589145247406572, + "acceleration": 3.0000000000000453, + "curvature": 0.43976536240568537, + "holonomicRotation": 0.0, + "angularVelocity": 1.1415668276354243, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.8679126090630681, + "pose": { + "rotation": { + "radians": 0.6043530647207653 + }, + "translation": { + "x": 2.0541639680000006, + "y": 3.356435968000001 + } + }, + "velocity": 2.603737827189206, + "acceleration": 2.9999999999999543, + "curvature": 0.43856062556178693, + "holonomicRotation": 0.0, + "angularVelocity": 1.1448280756028915, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.8727518311183128, + "pose": { + "rotation": { + "radians": 0.6098931419936862 + }, + "translation": { + "x": 2.0645211520000006, + "y": 3.3636731520000005 + } + }, + "velocity": 2.6182554933549405, + "acceleration": 3.0000000000000457, + "curvature": 0.43739209639321713, + "holonomicRotation": 0.0, + "angularVelocity": 1.1458505886525359, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.8775759614950274, + "pose": { + "rotation": { + "radians": 0.6154208746255811 + }, + "translation": { + "x": 2.074842624000001, + "y": 3.3709706240000004 + } + }, + "velocity": 2.622334232261645, + "acceleration": 0.8454868729070896, + "curvature": 0.4362597700073285, + "holonomicRotation": 0.0, + "angularVelocity": 1.1445003863931786, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.8823953289299136, + "pose": { + "rotation": { + "radians": 0.6209366425169791 + }, + "translation": { + "x": 2.085128000000001, + "y": 3.3783280000000007 + } + }, + "velocity": 2.625634845989314, + "acceleration": 0.6848645122545891, + "curvature": 0.43516363895714666, + "holonomicRotation": 0.0, + "angularVelocity": 1.1430465952169684, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.8872106909573768, + "pose": { + "rotation": { + "radians": 0.626440825687208 + }, + "translation": { + "x": 2.0953768960000008, + "y": 3.3857448960000003 + } + }, + "velocity": 2.6288383813504206, + "acceleration": 0.6652740422913254, + "curvature": 0.4341036934661007, + "holonomicRotation": 0.0, + "angularVelocity": 1.1416385324626965, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.8920221776120565, + "pose": { + "rotation": { + "radians": 0.6319338042506204 + }, + "translation": { + "x": 2.105588928000001, + "y": 3.3932209280000003 + } + }, + "velocity": 2.6319437458571184, + "acceleration": 0.6454064470235114, + "curvature": 0.4330799216330578, + "holonomicRotation": 0.0, + "angularVelocity": 1.1402763514325127, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.8968299192939927, + "pose": { + "rotation": { + "radians": 0.6374159583943286 + }, + "translation": { + "x": 2.1157637120000006, + "y": 3.4007557120000005 + } + }, + "velocity": 2.6349498803219897, + "acceleration": 0.6252695472733159, + "curvature": 0.4320923098070697, + "holonomicRotation": 0.0, + "angularVelocity": 1.1389601981623954, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.9016340467540943, + "pose": { + "rotation": { + "radians": 0.6428876683582834 + }, + "translation": { + "x": 2.125900864000001, + "y": 3.4083488640000006 + } + }, + "velocity": 2.6378557595292262, + "acceleration": 0.6048713801558966, + "curvature": 0.4311408427216499, + "holonomicRotation": 0.0, + "angularVelocity": 1.1376902117011674, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.906434691079727, + "pose": { + "rotation": { + "radians": 0.6483493144174144 + }, + "translation": { + "x": 2.136000000000001, + "y": 3.4160000000000004 + } + }, + "velocity": 2.640660392350118, + "acceleration": 0.584220081857935, + "curvature": 0.4302255037988389, + "holonomicRotation": 0.0, + "angularVelocity": 1.1364665242198737, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.9112319836804512, + "pose": { + "rotation": { + "radians": 0.6538012768650252 + }, + "translation": { + "x": 2.146060736000001, + "y": 3.4237087360000005 + } + }, + "velocity": 2.6433628223610883, + "acceleration": 0.5633239904028693, + "curvature": 0.4293462752752821, + "holonomicRotation": 0.0, + "angularVelocity": 1.135289261297001, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.9160260562739342, + "pose": { + "rotation": { + "radians": 0.6592439359982847 + }, + "translation": { + "x": 2.1560826880000006, + "y": 3.4314746880000007 + } + }, + "velocity": 2.6459621279004737, + "acceleration": 0.5421915268698363, + "curvature": 0.4285031384986032, + "holonomicRotation": 0.0, + "angularVelocity": 1.134158542054684, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.9208170408723271, + "pose": { + "rotation": { + "radians": 0.6646776721054044 + }, + "translation": { + "x": 2.1660654720000005, + "y": 3.4392974720000007 + } + }, + "velocity": 2.648457422337088, + "acceleration": 0.5208312373726626, + "curvature": 0.42769607414071226, + "holonomicRotation": 0.0, + "angularVelocity": 1.133074479392834, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.9256050697685123, + "pose": { + "rotation": { + "radians": 0.6701028654542673 + }, + "translation": { + "x": 2.176008704000001, + "y": 3.4471767040000008 + } + }, + "velocity": 2.6508478547544363, + "acceleration": 0.49925187779313374, + "curvature": 0.42692506226405785, + "holonomicRotation": 0.0, + "angularVelocity": 1.132037180125681, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.9303902755226879, + "pose": { + "rotation": { + "radians": 0.6755198962825455 + }, + "translation": { + "x": 2.185912000000001, + "y": 3.4551120000000006 + } + }, + "velocity": 2.653132609673996, + "acceleration": 0.47746221101694586, + "curvature": 0.4261900826856946, + "holonomicRotation": 0.0, + "angularVelocity": 1.1310467451481108, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.9351727909491765, + "pose": { + "rotation": { + "radians": 0.680929144789296 + }, + "translation": { + "x": 2.195774976000001, + "y": 3.463102976000001 + } + }, + "velocity": 2.655310907833249, + "acceleration": 0.4554712248680483, + "curvature": 0.42549111498766573, + "holonomicRotation": 0.0, + "angularVelocity": 1.1301032696261668, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.9399527491031683, + "pose": { + "rotation": { + "radians": 0.6863309911277984 + }, + "translation": { + "x": 2.205597248000001, + "y": 3.4711492480000006 + } + }, + "velocity": 2.657382006198557, + "acceleration": 0.4332879700166909, + "curvature": 0.42482813876175346, + "holonomicRotation": 0.0, + "angularVelocity": 1.1292068432179385, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.9447302832677758, + "pose": { + "rotation": { + "radians": 0.6917258154001806 + }, + "translation": { + "x": 2.215378432000001, + "y": 3.4792504320000006 + } + }, + "velocity": 2.6593451982965712, + "acceleration": 0.41092162407919103, + "curvature": 0.424201133738781, + "holonomicRotation": 0.0, + "angularVelocity": 1.1283575500272023, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.9495055269412395, + "pose": { + "rotation": { + "radians": 0.697113997652353 + }, + "translation": { + "x": 2.225118144000001, + "y": 3.487406144000001 + } + }, + "velocity": 2.6611998143698017, + "acceleration": 0.38838145235114474, + "curvature": 0.42361007996169614, + "holonomicRotation": 0.0, + "angularVelocity": 1.1275554689255944, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.954278613824305, + "pose": { + "rotation": { + "radians": 0.7024959178710106 + }, + "translation": { + "x": 2.234816000000001, + "y": 3.495616000000001 + } + }, + "velocity": 2.6629452216557663, + "acceleration": 0.3656768311000486, + "curvature": 0.42305495790658737, + "holonomicRotation": 0.0, + "angularVelocity": 1.1268006736112952, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.9590496778075177, + "pose": { + "rotation": { + "radians": 0.7078719559811373 + }, + "translation": { + "x": 2.244471616000001, + "y": 3.5038796160000008 + } + }, + "velocity": 2.6645808247919645, + "acceleration": 0.34281727135773626, + "curvature": 0.42253574855162407, + "holonomicRotation": 0.0, + "angularVelocity": 1.1260932327968134, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.9638188529587666, + "pose": { + "rotation": { + "radians": 0.7132424918449813 + }, + "translation": { + "x": 2.2540846080000008, + "y": 3.512196608000001 + } + }, + "velocity": 2.6661060656923015, + "acceleration": 0.3198123054754257, + "curvature": 0.4220524336016502, + "holonomicRotation": 0.0, + "angularVelocity": 1.1254332101237627, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.9685862735110955, + "pose": { + "rotation": { + "radians": 0.7186079052611989 + }, + "translation": { + "x": 2.263654592000001, + "y": 3.5205665920000007 + } + }, + "velocity": 2.6675204238998145, + "acceleration": 0.29667158413832084, + "curvature": 0.4216049955488846, + "holonomicRotation": 0.0, + "angularVelocity": 1.124820664571741, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.9733520738504342, + "pose": { + "rotation": { + "radians": 0.7239685759661101 + }, + "translation": { + "x": 2.2731811840000007, + "y": 3.5289891840000007 + } + }, + "velocity": 2.6688234168146447, + "acceleration": 0.27340484746599136, + "curvature": 0.4211934177613658, + "holonomicRotation": 0.0, + "angularVelocity": 1.1242556502653611, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.9781163885034462, + "pose": { + "rotation": { + "radians": 0.7293248836344008 + }, + "translation": { + "x": 2.282664000000001, + "y": 3.5374640000000004 + } + }, + "velocity": 2.6700145997957936, + "acceleration": 0.2500218956772268, + "curvature": 0.4208176845991983, + "holonomicRotation": 0.0, + "angularVelocity": 1.123738216844328, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.9828793521254612, + "pose": { + "rotation": { + "radians": 0.7346772078818984 + }, + "translation": { + "x": 2.292102656000001, + "y": 3.5459906560000007 + } + }, + "velocity": 2.671093566389595, + "acceleration": 0.22653261276539288, + "curvature": 0.4204777814786742, + "holonomicRotation": 0.0, + "angularVelocity": 1.1232684092819534, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.9876410994884608, + "pose": { + "rotation": { + "radians": 0.7400259282677375 + }, + "translation": { + "x": 2.3014967680000007, + "y": 3.5545687680000007 + } + }, + "velocity": 2.6720599484322793, + "acceleration": 0.20294693712507567, + "curvature": 0.42017369496416096, + "holonomicRotation": 0.0, + "angularVelocity": 1.1228462681894709, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.9924017654693136, + "pose": { + "rotation": { + "radians": 0.7453714242984346 + }, + "translation": { + "x": 2.310845952000001, + "y": 3.563197952000001 + } + }, + "velocity": 2.672913416024821, + "acceleration": 0.17927483170934566, + "curvature": 0.4199054128880666, + "holonomicRotation": 0.0, + "angularVelocity": 1.1224718297170306, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 0.997161485037997, + "pose": { + "rotation": { + "radians": 0.7507140754316346 + }, + "translation": { + "x": 2.320149824000001, + "y": 3.571877824000001 + } + }, + "velocity": 2.6736536778913673, + "acceleration": 0.15552636155641372, + "curvature": 0.4196729243382383, + "holonomicRotation": 0.0, + "angularVelocity": 1.1221451257033959, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.0019203932456864, + "pose": { + "rotation": { + "radians": 0.7560542610805632 + }, + "translation": { + "x": 2.329408000000001, + "y": 3.5806080000000007 + } + }, + "velocity": 2.6742804814591006, + "acceleration": 0.1317116322438141, + "curvature": 0.41947621972129306, + "holonomicRotation": 0.0, + "angularVelocity": 1.1218661837350683, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.0066786252132192, + "pose": { + "rotation": { + "radians": 0.7613923606193054 + }, + "translation": { + "x": 2.338620096000001, + "y": 3.5893880960000004 + } + }, + "velocity": 2.674793612605643, + "acceleration": 0.10784071689727757, + "curvature": 0.419315290918276, + "holonomicRotation": 0.0, + "angularVelocity": 1.1216350272072997, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.0114363161192206, + "pose": { + "rotation": { + "radians": 0.7667287533881022 + }, + "translation": { + "x": 2.3477857280000007, + "y": 3.598217728000001 + } + }, + "velocity": 2.6751928965083205, + "acceleration": 0.08392388462520017, + "curvature": 0.4191901310828717, + "holonomicRotation": 0.0, + "angularVelocity": 1.1214516752369148, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.0161936011885375, + "pose": { + "rotation": { + "radians": 0.7720638186986672 + }, + "translation": { + "x": 2.3569045120000007, + "y": 3.607096512000001 + } + }, + "velocity": 2.6754781966265213, + "acceleration": 0.05997120501374331, + "curvature": 0.4191007350133541, + "holonomicRotation": 0.0, + "angularVelocity": 1.1213161429216323, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.020950615680859, + "pose": { + "rotation": { + "radians": 0.7773979358410195 + }, + "translation": { + "x": 2.3659760640000007, + "y": 3.616024064000001 + } + }, + "velocity": 2.6756494156563497, + "acceleration": 0.03599295947170036, + "curvature": 0.4190470988943057, + "holonomicRotation": 0.0, + "angularVelocity": 1.1212284410937938, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.0257074948789369, + "pose": { + "rotation": { + "radians": 0.7827314840887518 + }, + "translation": { + "x": 2.375000000000001, + "y": 3.625000000000001 + } + }, + "velocity": 2.675706495129876, + "acceleration": 0.011999353178753079, + "curvature": 0.41902922045158014, + "holonomicRotation": 0.0, + "angularVelocity": 1.1211885766455594, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.030464374077015, + "pose": { + "rotation": { + "radians": 0.7880648427061199 + }, + "translation": { + "x": 2.383975936000001, + "y": 3.634023936000001 + } + }, + "velocity": 2.67564941565635, + "acceleration": -0.011999353178659161, + "curvature": 0.4190470988943055, + "holonomicRotation": 0.0, + "angularVelocity": 1.1211965522473806, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.0352213885693364, + "pose": { + "rotation": { + "radians": 0.7933983909539015 + }, + "translation": { + "x": 2.392903488000001, + "y": 3.643095488000001 + } + }, + "velocity": 2.675478196626521, + "acceleration": -0.03599295947188707, + "curvature": 0.41910073501335415, + "holonomicRotation": 0.0, + "angularVelocity": 1.1212523665452967, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.0399786736386536, + "pose": { + "rotation": { + "radians": 0.798732508096204 + }, + "translation": { + "x": 2.401782272000001, + "y": 3.652214272000001 + } + }, + "velocity": 2.675192896508296, + "acceleration": -0.05997120501878138, + "curvature": 0.4191901310828794, + "holonomicRotation": 0.0, + "angularVelocity": 1.1213560141038383, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.0447363645446093, + "pose": { + "rotation": { + "radians": 0.8040675734068445 + }, + "translation": { + "x": 2.410611904000001, + "y": 3.661379904000001 + } + }, + "velocity": 2.674793612656831, + "acceleration": -0.08392387386188453, + "curvature": 0.4193152909022269, + "holonomicRotation": 0.0, + "angularVelocity": 1.1215074853712201, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.0494945965121423, + "pose": { + "rotation": { + "radians": 0.8094039661755654 + }, + "translation": { + "x": 2.419392000000001, + "y": 3.670592000000001 + } + }, + "velocity": 2.6742804814079513, + "acceleration": -0.10784073840468338, + "curvature": 0.41947621973733923, + "holonomicRotation": 0.0, + "angularVelocity": 1.1217067667100076, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.054253504719877, + "pose": { + "rotation": { + "radians": 0.8147420657143334 + }, + "translation": { + "x": 2.428122176000001, + "y": 3.679850176000001 + } + }, + "velocity": 2.673653677891392, + "acceleration": -0.13171162148921356, + "curvature": 0.4196729243382304, + "holonomicRotation": 0.0, + "angularVelocity": 1.1219538403138642, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.0590132242886061, + "pose": { + "rotation": { + "radians": 0.8200822513632859 + }, + "translation": { + "x": 2.436802048000001, + "y": 3.689154048000001 + } + }, + "velocity": 2.6729134159737282, + "acceleration": -0.15552637229458416, + "curvature": 0.4199054129041197, + "holonomicRotation": 0.0, + "angularVelocity": 1.1222486842418435, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.0637738902695042, + "pose": { + "rotation": { + "radians": 0.8254249024964637 + }, + "translation": { + "x": 2.4454312320000007, + "y": 3.698503232000001 + } + }, + "velocity": 2.672059948432254, + "acceleration": -0.17927482098065445, + "curvature": 0.42017369496416906, + "holonomicRotation": 0.0, + "angularVelocity": 1.1225912723143032, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.068535637632504, + "pose": { + "rotation": { + "radians": 0.8307703985271329 + }, + "translation": { + "x": 2.454009344000001, + "y": 3.707897344000001 + } + }, + "velocity": 2.6710935663895956, + "acceleration": -0.20294693711966175, + "curvature": 0.42047778147867415, + "holonomicRotation": 0.0, + "angularVelocity": 1.1229815741545088, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.073298601254519, + "pose": { + "rotation": { + "radians": 0.8361191189130239 + }, + "translation": { + "x": 2.462536000000001, + "y": 3.717336000000001 + } + }, + "velocity": 2.6700145997957936, + "acceleration": -0.2265326127654861, + "curvature": 0.4208176845991983, + "holonomicRotation": 0.0, + "angularVelocity": 1.1234195550165338, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.078062915907531, + "pose": { + "rotation": { + "radians": 0.8414714431604695 + }, + "translation": { + "x": 2.471010816000001, + "y": 3.726818816000001 + } + }, + "velocity": 2.6688234168146683, + "acceleration": -0.2500218956722808, + "curvature": 0.4211934177613584, + "holonomicRotation": 0.0, + "angularVelocity": 1.1239051758218945, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.0828287162468697, + "pose": { + "rotation": { + "radians": 0.846827750828786 + }, + "translation": { + "x": 2.479433408000001, + "y": 3.736345408000001 + } + }, + "velocity": 2.6675204238998145, + "acceleration": -0.27340484747093, + "curvature": 0.42160499554888453, + "holonomicRotation": 0.0, + "angularVelocity": 1.124438393072715, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.0875961367991533, + "pose": { + "rotation": { + "radians": 0.8521884215336977 + }, + "translation": { + "x": 2.487803392000001, + "y": 3.745915392000001 + } + }, + "velocity": 2.6661060657428792, + "acceleration": -0.2966715735320978, + "curvature": 0.42205243358563704, + "holonomicRotation": 0.0, + "angularVelocity": 1.125019158687412, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.0923653119503571, + "pose": { + "rotation": { + "radians": 0.8575538349499379 + }, + "translation": { + "x": 2.496120384000001, + "y": 3.755528384000001 + } + }, + "velocity": 2.6645808247919636, + "acceleration": -0.31981231608377336, + "curvature": 0.4225357485516242, + "holonomicRotation": 0.0, + "angularVelocity": 1.1256474200922537, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.0971363759335697, + "pose": { + "rotation": { + "radians": 0.8629243708137362 + }, + "translation": { + "x": 2.504384000000001, + "y": 3.765184000000001 + } + }, + "velocity": 2.6629452216557663, + "acceleration": -0.3428172713575581, + "curvature": 0.4230549579065874, + "holonomicRotation": 0.0, + "angularVelocity": 1.1263231199908168, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.1019094628166803, + "pose": { + "rotation": { + "radians": 0.8683004089239086 + }, + "translation": { + "x": 2.512593856000001, + "y": 3.7748818560000013 + } + }, + "velocity": 2.6611998143196263, + "acceleration": -0.36567684160874825, + "curvature": 0.42361007997767003, + "holonomicRotation": 0.0, + "angularVelocity": 1.1270461963058591, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.106684706490189, + "pose": { + "rotation": { + "radians": 0.8736823291425702 + }, + "translation": { + "x": 2.5207495680000007, + "y": 3.7846215680000013 + } + }, + "velocity": 2.6593451982965486, + "acceleration": -0.38838144184482565, + "curvature": 0.42420113373878826, + "holonomicRotation": 0.0, + "angularVelocity": 1.1278165820374502, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.1114622406548413, + "pose": { + "rotation": { + "radians": 0.8790705113947155 + }, + "translation": { + "x": 2.5288507520000008, + "y": 3.794402752000001 + } + }, + "velocity": 2.6573820061486866, + "acceleration": -0.41092163450910085, + "curvature": 0.42482813877769865, + "holonomicRotation": 0.0, + "angularVelocity": 1.1286342052595717, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.116242198808878, + "pose": { + "rotation": { + "radians": 0.8844653356670706 + }, + "translation": { + "x": 2.536897024000001, + "y": 3.8042250240000013 + } + }, + "velocity": 2.6553109078332495, + "acceleration": -0.4332879595793174, + "curvature": 0.4254911149876656, + "holonomicRotation": 0.0, + "angularVelocity": 1.1294989888873823, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.1210247142353664, + "pose": { + "rotation": { + "radians": 0.8898671820056276 + }, + "translation": { + "x": 2.5448880000000007, + "y": 3.8140880000000013 + } + }, + "velocity": 2.6531326096739956, + "acceleration": -0.4554712248682446, + "curvature": 0.42619008268569475, + "holonomicRotation": 0.0, + "angularVelocity": 1.1304108505628179, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.1258099199895422, + "pose": { + "rotation": { + "radians": 0.8952764305123235 + }, + "translation": { + "x": 2.552823296000001, + "y": 3.8239912960000013 + } + }, + "velocity": 2.6508478547544305, + "acceleration": -0.4774622110180485, + "curvature": 0.4269250622640598, + "holonomicRotation": 0.0, + "angularVelocity": 1.1313697025929383, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.1305979488857274, + "pose": { + "rotation": { + "radians": 0.900693461340607 + }, + "translation": { + "x": 2.560702528000001, + "y": 3.8339345280000012 + } + }, + "velocity": 2.648457422337061, + "acceleration": -0.49925187779758573, + "curvature": 0.427696074140721, + "holonomicRotation": 0.0, + "angularVelocity": 1.1323754517400342, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.1353889334841203, + "pose": { + "rotation": { + "radians": 0.9061186546894917 + }, + "translation": { + "x": 2.568525312000001, + "y": 3.843917312000001 + } + }, + "velocity": 2.645962127900453, + "acceleration": -0.5208312373713648, + "curvature": 0.42850313849861, + "holonomicRotation": 0.0, + "angularVelocity": 1.133427999095026, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.1401830060776033, + "pose": { + "rotation": { + "radians": 0.9115523907966394 + }, + "translation": { + "x": 2.576291264000001, + "y": 3.853939264000001 + } + }, + "velocity": 2.643362822361095, + "acceleration": -0.542191526864093, + "curvature": 0.42934627527527985, + "holonomicRotation": 0.0, + "angularVelocity": 1.1345272398916992, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.1449802986783277, + "pose": { + "rotation": { + "radians": 0.9169950499298922 + }, + "translation": { + "x": 2.584000000000001, + "y": 3.864000000000001 + } + }, + "velocity": 2.6406603923501453, + "acceleration": -0.5633239903985849, + "curvature": 0.43022550379883, + "holonomicRotation": 0.0, + "angularVelocity": 1.1356730633905898, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.1497809430040045, + "pose": { + "rotation": { + "radians": 0.9224470123774822 + }, + "translation": { + "x": 2.5916511360000007, + "y": 3.874099136000001 + } + }, + "velocity": 2.6378557594807597, + "acceleration": -0.5842200919540596, + "curvature": 0.43114084273749304, + "holonomicRotation": 0.0, + "angularVelocity": 1.1368653526407893, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.15458507046415, + "pose": { + "rotation": { + "radians": 0.9279086584365919 + }, + "translation": { + "x": 2.599244288000001, + "y": 3.884236288000001 + } + }, + "velocity": 2.6349498803219897, + "acceleration": -0.6048713700618353, + "curvature": 0.43209230980706964, + "holonomicRotation": 0.0, + "angularVelocity": 1.1381039843726668, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.1593928121460426, + "pose": { + "rotation": { + "radians": 0.9333803684005884 + }, + "translation": { + "x": 2.606779072000001, + "y": 3.8944110720000014 + } + }, + "velocity": 2.6319437459051516, + "acceleration": -0.6252695372882013, + "curvature": 0.4330799216172504, + "holonomicRotation": 0.0, + "angularVelocity": 1.139388828711607, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.164204298800591, + "pose": { + "rotation": { + "radians": 0.9388625225442757 + }, + "translation": { + "x": 2.614255104000001, + "y": 3.9046231040000015 + } + }, + "velocity": 2.628838381445997, + "acceleration": -0.6454064371599206, + "curvature": 0.4341036934345355, + "holonomicRotation": 0.0, + "angularVelocity": 1.1407197490356886, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.1690196608279666, + "pose": { + "rotation": { + "radians": 0.9443555011076596 + }, + "translation": { + "x": 2.621672000000001, + "y": 3.9148720000000012 + } + }, + "velocity": 2.625634845989314, + "acceleration": -0.6652740621516621, + "curvature": 0.43516363895714666, + "holonomicRotation": 0.0, + "angularVelocity": 1.141368679059864, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.173842101877269, + "pose": { + "rotation": { + "radians": 0.9498596842779459 + }, + "translation": { + "x": 2.629029376000001, + "y": 3.9251573760000014 + } + }, + "velocity": 2.618989404766512, + "acceleration": -1.3780243563088321, + "curvature": 0.43625977000734745, + "holonomicRotation": 0.0, + "angularVelocity": 1.1396328812838714, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.1786820533931346, + "pose": { + "rotation": { + "radians": 0.9553754521692461 + }, + "translation": { + "x": 2.6363268480000013, + "y": 3.9354788480000007 + } + }, + "velocity": 2.604469550218915, + "acceleration": -3.0, + "curvature": 0.437392096408939, + "holonomicRotation": 0.0, + "angularVelocity": 1.1362290451451276, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.1835470343189463, + "pose": { + "rotation": { + "radians": 0.9609031848012304 + }, + "translation": { + "x": 2.643564032000001, + "y": 3.945836032000001 + } + }, + "velocity": 2.5898746074414802, + "acceleration": -2.9999999999999085, + "curvature": 0.4385606255617841, + "holonomicRotation": 0.0, + "angularVelocity": 1.1328524486335545, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.1884374128317103, + "pose": { + "rotation": { + "radians": 0.9664432620741601 + }, + "translation": { + "x": 2.650740544000001, + "y": 3.956228544000001 + } + }, + "velocity": 2.5752034719031878, + "acceleration": -3.0000000000000453, + "curvature": 0.4397653623900097, + "holonomicRotation": 0.0, + "angularVelocity": 1.1295007542703375, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.1933535686189238, + "pose": { + "rotation": { + "radians": 0.9719960637439282 + }, + "translation": { + "x": 2.657856000000001, + "y": 3.9666560000000013 + } + }, + "velocity": 2.5604550045415473, + "acceleration": -3.0, + "curvature": 0.4410063087994853, + "holonomicRotation": 0.0, + "angularVelocity": 1.1261715790988696, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.1982958933518377, + "pose": { + "rotation": { + "radians": 0.9775619693928133 + }, + "translation": { + "x": 2.6649100160000008, + "y": 3.977118016000001 + } + }, + "velocity": 2.5456280303428054, + "acceleration": -3.000000000000045, + "curvature": 0.4422834635714009, + "holonomicRotation": 0.0, + "angularVelocity": 1.1228624931602014, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.2032647911826513, + "pose": { + "rotation": { + "radians": 0.9831413583993789 + }, + "translation": { + "x": 2.671902208000001, + "y": 3.9876142080000014 + } + }, + "velocity": 2.5307213368503647, + "acceleration": -3.0, + "curvature": 0.4435968219542736, + "holonomicRotation": 0.0, + "angularVelocity": 1.1195710174570126, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.208260679267134, + "pose": { + "rotation": { + "radians": 0.9887346099052245 + }, + "translation": { + "x": 2.678832192000001, + "y": 3.9981441920000007 + } + }, + "velocity": 2.5157336725969164, + "acceleration": -3.0000000000000444, + "curvature": 0.4449463754713487, + "holonomicRotation": 0.0, + "angularVelocity": 1.116294622142275, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.213283988314313, + "pose": { + "rotation": { + "radians": 0.994342102779949 + }, + "translation": { + "x": 2.685699584000001, + "y": 4.0087075840000015 + } + }, + "velocity": 2.500663745455379, + "acceleration": -3.0000000000000884, + "curvature": 0.44633211131899053, + "holonomicRotation": 0.0, + "angularVelocity": 1.1130307242686392, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.2183351631649564, + "pose": { + "rotation": { + "radians": 0.9999642155823683 + }, + "translation": { + "x": 2.692504000000001, + "y": 4.019304000000001 + } + }, + "velocity": 2.4855102209034485, + "acceleration": -3.000000000000044, + "curvature": 0.4477540124322387, + "holonomicRotation": 0.0, + "angularVelocity": 1.1097766860870264, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.2234146634007506, + "pose": { + "rotation": { + "radians": 1.0056013265210262 + }, + "translation": { + "x": 2.699245056000001, + "y": 4.029933056000002 + } + }, + "velocity": 2.470271720196066, + "acceleration": -3.0000000000000435, + "curvature": 0.44921205667481756, + "holonomicRotation": 0.0, + "angularVelocity": 1.1065298124299, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.2285229639861848, + "pose": { + "rotation": { + "radians": 1.0112538134096622 + }, + "translation": { + "x": 2.705922368000001, + "y": 4.040594368000001 + } + }, + "velocity": 2.4549468184397636, + "acceleration": -2.999999999999913, + "curvature": 0.4507062168508919, + "holonomicRotation": 0.0, + "angularVelocity": 1.1032873489277657, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.2336605559453493, + "pose": { + "rotation": { + "radians": 1.0169220536221615 + }, + "translation": { + "x": 2.7125355520000007, + "y": 4.051287552000002 + } + }, + "velocity": 2.43953404256227, + "acceleration": -3.000000000000043, + "curvature": 0.45223646007658325, + "holonomicRotation": 0.0, + "angularVelocity": 1.1000464792593154, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.2388279470759953, + "pose": { + "rotation": { + "radians": 1.0226064240423844 + }, + "translation": { + "x": 2.719084224000001, + "y": 4.062012224000001 + } + }, + "velocity": 2.4240318691703315, + "acceleration": -3.000000000000043, + "curvature": 0.4538027475367534, + "holonomicRotation": 0.0, + "angularVelocity": 1.0968043231892513, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.2440256627034307, + "pose": { + "rotation": { + "radians": 1.028307301013264 + }, + "translation": { + "x": 2.725568000000001, + "y": 4.072768000000002 + } + }, + "velocity": 2.4084387222880252, + "acceleration": -3.0, + "curvature": 0.4554050339448751, + "holonomicRotation": 0.0, + "angularVelocity": 1.093557933627122, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.2492542464770038, + "pose": { + "rotation": { + "radians": 1.0340250602804888 + }, + "translation": { + "x": 2.731986496000001, + "y": 4.0835544960000005 + } + }, + "velocity": 2.392752970967306, + "acceleration": -3.0000000000000426, + "curvature": 0.45704326729385686, + "holonomicRotation": 0.0, + "angularVelocity": 1.0903042944971009, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.2545142612121893, + "pose": { + "rotation": { + "radians": 1.0397600769353796 + }, + "translation": { + "x": 2.738339328000001, + "y": 4.094371328000001 + } + }, + "velocity": 2.3769729267617494, + "acceleration": -2.999999999999958, + "curvature": 0.45871738815772506, + "holonomicRotation": 0.0, + "angularVelocity": 1.087040317564224, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.2598062897815119, + "pose": { + "rotation": { + "radians": 1.045512725351935 + }, + "translation": { + "x": 2.7446261120000006, + "y": 4.105218112000001 + } + }, + "velocity": 2.3610968410537816, + "acceleration": -3.0000000000000417, + "curvature": 0.4604273295453317, + "holonomicRotation": 0.0, + "angularVelocity": 1.0837628401270711, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.2651309360578522, + "pose": { + "rotation": { + "radians": 1.0512833791230536 + }, + "translation": { + "x": 2.7508464640000008, + "y": 4.1160944640000015 + } + }, + "velocity": 2.345122902224761, + "acceleration": -2.9999999999999165, + "curvature": 0.4621730162746951, + "holonomicRotation": 0.0, + "angularVelocity": 1.0804686217426966, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.270488825913959, + "pose": { + "rotation": { + "radians": 1.0570724109913305 + }, + "translation": { + "x": 2.7570000000000006, + "y": 4.127000000000001 + } + }, + "velocity": 2.3290492326564407, + "acceleration": -2.9999999999999587, + "curvature": 0.4639543644847909, + "holonomicRotation": 0.0, + "angularVelocity": 1.0771543414066895, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.2758806082823524, + "pose": { + "rotation": { + "radians": 1.0628801927773655 + }, + "translation": { + "x": 2.7630863360000006, + "y": 4.137934336000002 + } + }, + "velocity": 2.312873885551261, + "acceleration": -2.9999999999999587, + "curvature": 0.4657712811612695, + "holonomicRotation": 0.0, + "angularVelocity": 1.0738165942689333, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.2813069562801476, + "pose": { + "rotation": { + "radians": 1.068707095303676 + }, + "translation": { + "x": 2.7691050880000008, + "y": 4.148897088000001 + } + }, + "velocity": 2.2965948415578756, + "acceleration": -2.999999999999959, + "curvature": 0.46762366370596037, + "holonomicRotation": 0.0, + "angularVelocity": 1.0704518885397352, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.286768568403775, + "pose": { + "rotation": { + "radians": 1.0745534883158845 + }, + "translation": { + "x": 2.775055872000001, + "y": 4.159887872000001 + } + }, + "velocity": 2.280210005186993, + "acceleration": -3.000000000000041, + "curvature": 0.46951139935295344, + "holonomicRotation": 0.0, + "angularVelocity": 1.0670566418127445, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.2922661697989868, + "pose": { + "rotation": { + "radians": 1.0804197403986842 + }, + "translation": { + "x": 2.7809383040000006, + "y": 4.170906304000001 + } + }, + "velocity": 2.2637172010013575, + "acceleration": -3.0000000000000404, + "curvature": 0.4714343645997839, + "holonomicRotation": 0.0, + "angularVelocity": 1.0636271776953912, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.2978005136120798, + "pose": { + "rotation": { + "radians": 1.0863062188890003 + }, + "translation": { + "x": 2.786752000000001, + "y": 4.181952000000002 + } + }, + "velocity": 2.2471141695620784, + "acceleration": -3.0, + "curvature": 0.4733924247442271, + "holonomicRotation": 0.0, + "angularVelocity": 1.0601597219446663, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.303372382428791, + "pose": { + "rotation": { + "radians": 1.092213289784437 + }, + "translation": { + "x": 2.792496576000001, + "y": 4.193024576000001 + } + }, + "velocity": 2.2303985631119447, + "acceleration": -3.0, + "curvature": 0.47538543332938343, + "holonomicRotation": 0.0, + "angularVelocity": 1.05665039864859, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.3089825898079743, + "pose": { + "rotation": { + "radians": 1.0981413176481523 + }, + "translation": { + "x": 2.7981716480000007, + "y": 4.204123648000001 + } + }, + "velocity": 2.213567940974395, + "acceleration": -2.9999999999999605, + "curvature": 0.4774132314234743, + "holonomicRotation": 0.0, + "angularVelocity": 1.0530952259318735, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.314631981917819, + "pose": { + "rotation": { + "radians": 1.1040906655084468 + }, + "translation": { + "x": 2.8037768320000005, + "y": 4.215248832000001 + } + }, + "velocity": 2.1966197646448617, + "acceleration": -2.9999999999999214, + "curvature": 0.4794756472470108, + "holonomicRotation": 0.0, + "angularVelocity": 1.0494901118766216, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.3203214392831757, + "pose": { + "rotation": { + "radians": 1.1100616947553323 + }, + "translation": { + "x": 2.809311744000001, + "y": 4.226399744000002 + } + }, + "velocity": 2.1795513925487917, + "acceleration": -2.999999999999961, + "curvature": 0.48157249539387187, + "holonomicRotation": 0.0, + "angularVelocity": 1.0458308498080762, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.3260518786533824, + "pose": { + "rotation": { + "radians": 1.1160547650316492 + }, + "translation": { + "x": 2.814776000000001, + "y": 4.237576000000001 + } + }, + "velocity": 2.1623600744381717, + "acceleration": -3.0, + "curvature": 0.4837035763394283, + "holonomicRotation": 0.0, + "angularVelocity": 1.0421131136383825, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.3318242550009647, + "pose": { + "rotation": { + "radians": 1.1220702341203208 + }, + "translation": { + "x": 2.820169216000001, + "y": 4.2487772160000015 + } + }, + "velocity": 2.1450429453954247, + "acceleration": -3.0, + "curvature": 0.4858686756511655, + "holonomicRotation": 0.0, + "angularVelocity": 1.0383324526570552, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.3376395636626297, + "pose": { + "rotation": { + "radians": 1.1281084578259453 + }, + "translation": { + "x": 2.825491008000001, + "y": 4.260003008000001 + } + }, + "velocity": 2.1275970194104294, + "acceleration": -3.000000000000038, + "curvature": 0.48806756354488817, + "holonomicRotation": 0.0, + "angularVelocity": 1.0344842865366874, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.343498842635211, + "pose": { + "rotation": { + "radians": 1.1341697898535155 + }, + "translation": { + "x": 2.830740992000001, + "y": 4.271252992000002 + } + }, + "velocity": 2.1100191824926853, + "acceleration": -3.0000000000000377, + "curvature": 0.49029999405552943, + "holonomicRotation": 0.0, + "angularVelocity": 1.0305638993094042, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.3494031750405304, + "pose": { + "rotation": { + "radians": 1.1402545816799603 + }, + "translation": { + "x": 2.835918784000001, + "y": 4.282526784000001 + } + }, + "velocity": 2.0923061852767266, + "acceleration": -3.000000000000075, + "curvature": 0.49256570453850973, + "holonomicRotation": 0.0, + "angularVelocity": 1.026566433840469, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.3553536917747062, + "pose": { + "rotation": { + "radians": 1.1463631824232712 + }, + "translation": { + "x": 2.841024000000001, + "y": 4.293824000000002 + } + }, + "velocity": 2.074454635074199, + "acceleration": -3.0000000000000746, + "curvature": 0.4948644147448579, + "holonomicRotation": 0.0, + "angularVelocity": 1.0224868851113715, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.3613515743591078, + "pose": { + "rotation": { + "radians": 1.1524959387042597 + }, + "translation": { + "x": 2.8460562560000007, + "y": 4.305144256000001 + } + }, + "velocity": 2.0564609873209942, + "acceleration": -2.999999999999963, + "curvature": 0.49719582643303056, + "holonomicRotation": 0.0, + "angularVelocity": 1.0183200938587464, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.3673980580121383, + "pose": { + "rotation": { + "radians": 1.158653194505329 + }, + "translation": { + "x": 2.851015168000001, + "y": 4.316487168000002 + } + }, + "velocity": 2.0383215363619027, + "acceleration": -3.0, + "curvature": 0.49955962237973184, + "holonomicRotation": 0.0, + "angularVelocity": 1.014060739171566, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.3734944349631748, + "pose": { + "rotation": { + "radians": 1.1648352910225657 + }, + "translation": { + "x": 2.855900352000001, + "y": 4.327852352000001 + } + }, + "velocity": 2.0200324055087933, + "acceleration": -3.0, + "curvature": 0.5019554658535155, + "holonomicRotation": 0.0, + "angularVelocity": 1.009703331056945, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.3796420580325273, + "pose": { + "rotation": { + "radians": 1.1710425665137734 + }, + "translation": { + "x": 2.8607114240000007, + "y": 4.339239424000002 + } + }, + "velocity": 2.001589536300736, + "acceleration": -3.0, + "curvature": 0.5043829997560954, + "holonomicRotation": 0.0, + "angularVelocity": 1.005242202071386, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.385842344504059, + "pose": { + "rotation": { + "radians": 1.1772753561398894 + }, + "translation": { + "x": 2.8654480000000007, + "y": 4.350648000000001 + } + }, + "velocity": 1.9829886768861407, + "acceleration": -2.999999999999964, + "curvature": 0.5068418460483195, + "holonomicRotation": 0.0, + "angularVelocity": 1.000671498890062, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.3920967803203892, + "pose": { + "rotation": { + "radians": 1.1835339918029282 + }, + "translation": { + "x": 2.870109696000001, + "y": 4.362077696000002 + } + }, + "velocity": 1.9642253694371505, + "acceleration": -2.9999999999999645, + "curvature": 0.5093316047891755, + "holonomicRotation": 0.0, + "angularVelocity": 0.9959851725933427, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.3984069246342183, + "pose": { + "rotation": { + "radians": 1.1898188019764262 + }, + "translation": { + "x": 2.874696128000001, + "y": 4.373528128000001 + } + }, + "velocity": 1.9452949364956633, + "acceleration": -2.999999999999965, + "curvature": 0.5118518535624833, + "holonomicRotation": 0.0, + "angularVelocity": 0.9911769688340709, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.4047744147535932, + "pose": { + "rotation": { + "radians": 1.196130111532029 + }, + "translation": { + "x": 2.879206912000001, + "y": 4.384998912000002 + } + }, + "velocity": 1.9261924661375385, + "acceleration": -3.000000000000035, + "curvature": 0.5144021466205787, + "holonomicRotation": 0.0, + "angularVelocity": 0.9862404167758717, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.4112009715237113, + "pose": { + "rotation": { + "radians": 1.2024682415594241 + }, + "translation": { + "x": 2.8836416640000007, + "y": 4.3964896640000015 + } + }, + "velocity": 1.9069127958271843, + "acceleration": -3.0, + "curvature": 0.5169820141541447, + "holonomicRotation": 0.0, + "angularVelocity": 0.9811688175075026, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.41768840519348, + "pose": { + "rotation": { + "radians": 1.2088335091818494 + }, + "translation": { + "x": 2.888000000000001, + "y": 4.408000000000002 + } + }, + "velocity": 1.8874504948178785, + "acceleration": -2.999999999999966, + "curvature": 0.5195909614569449, + "holonomicRotation": 0.0, + "angularVelocity": 0.9759552310949556, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.4242386218214258, + "pose": { + "rotation": { + "radians": 1.2152262273646983 + }, + "translation": { + "x": 2.8922815360000005, + "y": 4.4195295360000015 + } + }, + "velocity": 1.867799844934041, + "acceleration": -3.0, + "curvature": 0.5222284682600655, + "holonomicRotation": 0.0, + "angularVelocity": 0.9705924628872844, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.4308536302830257, + "pose": { + "rotation": { + "radians": 1.2216467047194628 + }, + "translation": { + "x": 2.896485888000001, + "y": 4.431077888000002 + } + }, + "velocity": 1.847954819549241, + "acceleration": -3.0000000000000338, + "curvature": 0.5248939878051837, + "holonomicRotation": 0.0, + "angularVelocity": 0.9650730483864461, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.4375355499501146, + "pose": { + "rotation": { + "radians": 1.2280952453016536 + }, + "translation": { + "x": 2.9006126720000007, + "y": 4.442644672000001 + } + }, + "velocity": 1.8279090605479742, + "acceleration": -3.0000000000000333, + "curvature": 0.527586946160825, + "holonomicRotation": 0.0, + "angularVelocity": 0.9593892367630158, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.4442866191231065, + "pose": { + "rotation": { + "radians": 1.2345721484028647 + }, + "translation": { + "x": 2.904661504000001, + "y": 4.454229504000002 + } + }, + "velocity": 1.8076558530289983, + "acceleration": -3.0, + "curvature": 0.5303067413665304, + "holonomicRotation": 0.0, + "angularVelocity": 0.9535329728703047, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.4511092043084484, + "pose": { + "rotation": { + "radians": 1.2410777083373046 + }, + "translation": { + "x": 2.9086320000000003, + "y": 4.465832000000002 + } + }, + "velocity": 1.787188097472973, + "acceleration": -2.9999999999999676, + "curvature": 0.533052742734141, + "holonomicRotation": 0.0, + "angularVelocity": 0.9474958775078474, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.4580058104475067, + "pose": { + "rotation": { + "radians": 1.2476122142228576 + }, + "translation": { + "x": 2.9125237760000005, + "y": 4.477451776000002 + } + }, + "velocity": 1.766498279055798, + "acceleration": -3.000000000000032, + "curvature": 0.5358242899805569, + "holonomicRotation": 0.0, + "angularVelocity": 0.9412692255924726, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.4649790922191754, + "pose": { + "rotation": { + "radians": 1.2541759497559144 + }, + "translation": { + "x": 2.9163364480000005, + "y": 4.489088448000001 + } + }, + "velocity": 1.7455784337407918, + "acceleration": -2.999999999999968, + "curvature": 0.53862069246313, + "holonomicRotation": 0.0, + "angularVelocity": 0.9348439222379099, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.472031866557601, + "pose": { + "rotation": { + "radians": 1.2607691929811071 + }, + "translation": { + "x": 2.9200696320000006, + "y": 4.500741632000002 + } + }, + "velocity": 1.724420110725515, + "acceleration": -2.9999999999999685, + "curvature": 0.5414412283907459, + "holonomicRotation": 0.0, + "angularVelocity": 0.9282104760898124, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.4791671265489101, + "pose": { + "rotation": { + "radians": 1.2673922160546647 + }, + "translation": { + "x": 2.9237229440000005, + "y": 4.512410944000001 + } + }, + "velocity": 1.7030143307515877, + "acceleration": -3.000000000000031, + "curvature": 0.5442851441519826, + "holonomicRotation": 0.0, + "angularVelocity": 0.9213589699954693, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.4863880568977, + "pose": { + "rotation": { + "radians": 1.2740452850032347 + }, + "translation": { + "x": 2.9272960000000006, + "y": 4.524096000000002 + } + }, + "velocity": 1.6813515397052183, + "acceleration": -3.0, + "curvature": 0.5471516533835759, + "holonomicRotation": 0.0, + "angularVelocity": 0.9142790279992806, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.4936980511859816, + "pose": { + "rotation": { + "radians": 1.2807286594758052 + }, + "translation": { + "x": 2.9307884160000004, + "y": 4.535796416000001 + } + }, + "velocity": 1.6594215568403732, + "acceleration": -3.0, + "curvature": 0.5500399363964437, + "holonomicRotation": 0.0, + "angularVelocity": 0.9069597788904717, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.5011007311857052, + "pose": { + "rotation": { + "radians": 1.2874425924915514 + }, + "translation": { + "x": 2.9341998080000002, + "y": 4.547511808000002 + } + }, + "velocity": 1.6372135168412023, + "acceleration": -3.00000000000003, + "curvature": 0.5529491392614659, + "holonomicRotation": 0.0, + "angularVelocity": 0.8993898149606812, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.508599968532113, + "pose": { + "rotation": { + "radians": 1.2941873301808833 + }, + "translation": { + "x": 2.9375297920000008, + "y": 4.559241792000002 + } + }, + "velocity": 1.6147158048019792, + "acceleration": -2.9999999999999702, + "curvature": 0.5558783732812413, + "holonomicRotation": 0.0, + "angularVelocity": 0.8915571460678879, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.516199909121133, + "pose": { + "rotation": { + "radians": 1.3009631115227154 + }, + "translation": { + "x": 2.9407779840000003, + "y": 4.570985984000002 + } + }, + "velocity": 1.5919159830349192, + "acceleration": -3.0000000000000293, + "curvature": 0.5588267141256481, + "holonomicRotation": 0.0, + "angularVelocity": 0.8834491473354206, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.5239050006619295, + "pose": { + "rotation": { + "radians": 1.3077701680745735 + }, + "translation": { + "x": 2.9439440000000006, + "y": 4.582744000000002 + } + }, + "velocity": 1.5688007084125297, + "acceleration": -2.999999999999971, + "curvature": 0.5617932012303778, + "holonomicRotation": 0.0, + "angularVelocity": 0.875052500540059, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.5317200238988449, + "pose": { + "rotation": { + "radians": 1.314608723699815 + }, + "translation": { + "x": 2.9470274560000007, + "y": 4.594515456000002 + } + }, + "velocity": 1.545355638701783, + "acceleration": -3.000000000000057, + "curvature": 0.5647768371119463, + "holonomicRotation": 0.0, + "angularVelocity": 0.866353126952262, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.539650128119067, + "pose": { + "rotation": { + "radians": 1.3214789942880618 + }, + "translation": { + "x": 2.9500279680000006, + "y": 4.606299968000002 + } + }, + "velocity": 1.5215653260411162, + "acceleration": -3.000000000000028, + "curvature": 0.5677765867261405, + "holonomicRotation": 0.0, + "angularVelocity": 0.8573361111436658, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.5477008716886214, + "pose": { + "rotation": { + "radians": 1.3283811874717983 + }, + "translation": { + "x": 2.9529451520000003, + "y": 4.6180971520000025 + } + }, + "velocity": 1.4974130953324531, + "acceleration": -3.0000000000000275, + "curvature": 0.5707913768706009, + "holonomicRotation": 0.0, + "angularVelocity": 0.8479856135548375, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.55587826851637, + "pose": { + "rotation": { + "radians": 1.335315502338058 + }, + "translation": { + "x": 2.9557786240000006, + "y": 4.629906624000001 + } + }, + "velocity": 1.472880904849207, + "acceleration": -3.000000000000054, + "curvature": 0.5738200956456002, + "holonomicRotation": 0.0, + "angularVelocity": 0.8382847700393716, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.5641888415424363, + "pose": { + "rotation": { + "radians": 1.3422821291361096 + }, + "translation": { + "x": 2.9585280000000007, + "y": 4.641728000000002 + } + }, + "velocity": 1.4479491857710078, + "acceleration": -3.0, + "curvature": 0.576861591813262, + "holonomicRotation": 0.0, + "angularVelocity": 0.8282155756134849, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.5726396845955335, + "pose": { + "rotation": { + "radians": 1.3492812489797497 + }, + "translation": { + "x": 2.9611928960000005, + "y": 4.653560896000002 + } + }, + "velocity": 1.4225966566117165, + "acceleration": -2.999999999999974, + "curvature": 0.5799146744073892, + "holonomicRotation": 0.0, + "angularVelocity": 0.8177587498554331, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.5812385342789634, + "pose": { + "rotation": { + "radians": 1.3563130335470661 + }, + "translation": { + "x": 2.9637729280000005, + "y": 4.665404928000002 + } + }, + "velocity": 1.3968001075614265, + "acceleration": -3.0000000000000258, + "curvature": 0.5829781121894888, + "holonomicRotation": 0.0, + "angularVelocity": 0.8068935795489924, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.5899938539486989, + "pose": { + "rotation": { + "radians": 1.3633776447754746 + }, + "translation": { + "x": 2.9662677120000005, + "y": 4.6772597120000015 + } + }, + "velocity": 1.37053414855222, + "acceleration": -3.0000000000000253, + "curvature": 0.5860506332508155, + "holonomicRotation": 0.0, + "angularVelocity": 0.7955977342737229, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.5989149323684775, + "pose": { + "rotation": { + "radians": 1.3704752345535287 + }, + "translation": { + "x": 2.9686768640000007, + "y": 4.689124864000002 + } + }, + "velocity": 1.3437709132928843, + "acceleration": -2.999999999999975, + "curvature": 0.5891309246386679, + "holonomicRotation": 0.0, + "angularVelocity": 0.7838470488111148, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.608012000306507, + "pose": { + "rotation": { + "radians": 1.3776059444095874 + }, + "translation": { + "x": 2.9710000000000005, + "y": 4.701000000000001 + } + }, + "velocity": 1.316479709478796, + "acceleration": -2.9999999999999756, + "curvature": 0.5922176320623127, + "holonomicRotation": 0.0, + "angularVelocity": 0.7716152648033403, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.6172963692331, + "pose": { + "rotation": { + "radians": 1.3847699051974123 + }, + "translation": { + "x": 2.9732367360000005, + "y": 4.712884736000002 + } + }, + "velocity": 1.288626602699017, + "acceleration": -3.000000000000024, + "curvature": 0.5953093595736683, + "holonomicRotation": 0.0, + "angularVelocity": 0.7588737220632151, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.6267805974686687, + "pose": { + "rotation": { + "radians": 1.3919672367794353 + }, + "translation": { + "x": 2.9753866880000004, + "y": 4.724778688000002 + } + }, + "velocity": 1.2601739179923108, + "acceleration": -3.0, + "curvature": 0.5984046693700557, + "holonomicRotation": 0.0, + "angularVelocity": 0.7455909869329629, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.636478690732875, + "pose": { + "rotation": { + "radians": 1.3991980477076629 + }, + "translation": { + "x": 2.9774494720000004, + "y": 4.736681472000003 + } + }, + "velocity": 1.2310796381996918, + "acceleration": -3.0, + "curvature": 0.6015020816536214, + "holonomicRotation": 0.0, + "angularVelocity": 0.7317324013974611, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.6464063462269714, + "pose": { + "rotation": { + "radians": 1.4064624349026047 + }, + "translation": { + "x": 2.9794247040000004, + "y": 4.748592704000002 + } + }, + "velocity": 1.201296671717403, + "acceleration": -2.999999999999978, + "curvature": 0.60460007456127, + "holonomicRotation": 0.0, + "angularVelocity": 0.717259531383458, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.6565812523929566, + "pose": { + "rotation": { + "radians": 1.41376048333109 + }, + "translation": { + "x": 2.9813120000000004, + "y": 4.760512000000002 + } + }, + "velocity": 1.1707719532194472, + "acceleration": -3.0, + "curvature": 0.6076970841012796, + "holonomicRotation": 0.0, + "angularVelocity": 0.7021294852003354, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.6670234607122523, + "pose": { + "rotation": { + "radians": 1.4210922656826717 + }, + "translation": { + "x": 2.9831109760000003, + "y": 4.772438976000002 + } + }, + "velocity": 1.1394453282615602, + "acceleration": -3.0, + "curvature": 0.6107915042418585, + "holonomicRotation": 0.0, + "angularVelocity": 0.6862940629818453, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.6777558519135327, + "pose": { + "rotation": { + "radians": 1.428457842045709 + }, + "translation": { + "x": 2.9848212480000003, + "y": 4.784373248000002 + } + }, + "velocity": 1.107248154657719, + "acceleration": -2.999999999999979, + "curvature": 0.6138816870079442, + "holonomicRotation": 0.0, + "angularVelocity": 0.6696986828773126, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.6888047276641542, + "pose": { + "rotation": { + "radians": 1.4358572595831753 + }, + "translation": { + "x": 2.9864424320000005, + "y": 4.796314432000002 + } + }, + "velocity": 1.0741015274058545, + "acceleration": -3.0, + "curvature": 0.6169659427695113, + "holonomicRotation": 0.0, + "angularVelocity": 0.652281008129766, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.7002005716841848, + "pose": { + "rotation": { + "radians": 1.4432905522090504 + }, + "translation": { + "x": 2.9879741440000003, + "y": 4.808262144000002 + } + }, + "velocity": 1.039913995345763, + "acceleration": -2.9999999999999805, + "curvature": 0.6200425403987194, + "holonomicRotation": 0.0, + "angularVelocity": 0.6339691664027446, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.7119790436535878, + "pose": { + "rotation": { + "radians": 1.450757740264991 + }, + "translation": { + "x": 2.9894160000000003, + "y": 4.820216000000001 + } + }, + "velocity": 1.004578579437554, + "acceleration": -3.0000000000000187, + "curvature": 0.623109707774154, + "holonomicRotation": 0.0, + "angularVelocity": 0.6146794031013213, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.724182299361434, + "pose": { + "rotation": { + "radians": 1.4582588301993826 + }, + "translation": { + "x": 2.9907676160000003, + "y": 4.8321756160000024 + } + }, + "velocity": 0.9679688123140158, + "acceleration": -2.9999999999999636, + "curvature": 0.6261656322069277, + "holonomicRotation": 0.0, + "angularVelocity": 0.5943129313748706, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.7368607784086099, + "pose": { + "rotation": { + "radians": 1.4657938142472846 + }, + "translation": { + "x": 2.992028608, + "y": 4.844140608000002 + } + }, + "velocity": 0.9299333751724882, + "acceleration": -2.999999999999991, + "curvature": 0.6292084609699685, + "holonomicRotation": 0.0, + "angularVelocity": 0.5727516148206816, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.7500756793718817, + "pose": { + "rotation": { + "radians": 1.473362670113694 + }, + "translation": { + "x": 2.993198592, + "y": 4.856110592000002 + } + }, + "velocity": 0.8902886722826729, + "acceleration": -2.999999999999983, + "curvature": 0.6322363020068372, + "holonomicRotation": 0.0, + "angularVelocity": 0.549851904665754, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.763902476153777, + "pose": { + "rotation": { + "radians": 1.4809653606596453 + }, + "translation": { + "x": 2.9942771840000004, + "y": 4.868085184000002 + } + }, + "velocity": 0.8488082819369874, + "acceleration": -2.999999999999984, + "curvature": 0.6352472246674356, + "holonomicRotation": 0.0, + "angularVelocity": 0.5254360802848803, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.7784360668586583, + "pose": { + "rotation": { + "radians": 1.488601833592083 + }, + "translation": { + "x": 2.995264, + "y": 4.880064000000003 + } + }, + "velocity": 0.8052075098223431, + "acceleration": -3.000000000000015, + "curvature": 0.6382392605344301, + "holonomicRotation": 0.0, + "angularVelocity": 0.49927915802747, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.7937985898931266, + "pose": { + "rotation": { + "radians": 1.49627202115791 + }, + "translation": { + "x": 2.996158656, + "y": 4.8920466560000015 + } + }, + "velocity": 0.759119940718938, + "acceleration": -3.0000000000000218, + "curvature": 0.6412104045156426, + "holonomicRotation": 0.0, + "angularVelocity": 0.4710885081646315, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.81015181981141, + "pose": { + "rotation": { + "radians": 1.5039758398437872 + }, + "translation": { + "x": 2.996960768, + "y": 4.904032768000002 + } + }, + "velocity": 0.7100602509640875, + "acceleration": -3.0000000000000204, + "curvature": 0.6441586157880042, + "holonomicRotation": 0.0, + "angularVelocity": 0.44047046706200677, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.8277179242740946, + "pose": { + "rotation": { + "radians": 1.511713190080926 + }, + "translation": { + "x": 2.9976699520000003, + "y": 4.916021952000001 + } + }, + "velocity": 0.6573619375760337, + "acceleration": -2.9999999999999876, + "curvature": 0.6470818190817547, + "holonomicRotation": 0.0, + "angularVelocity": 0.40687199814347647, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.8468167217124687, + "pose": { + "rotation": { + "radians": 1.5194839559568147 + }, + "translation": { + "x": 2.998285824, + "y": 4.928013824000002 + } + }, + "velocity": 0.6000655452609113, + "acceleration": -3.0000000000000115, + "curvature": 0.6499779058913984, + "holonomicRotation": 0.0, + "angularVelocity": 0.3694696536402002, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.8679390220148424, + "pose": { + "rotation": { + "radians": 1.527288004933617 + }, + "translation": { + "x": 2.998808, + "y": 4.9400080000000015 + } + }, + "velocity": 0.5366986443537898, + "acceleration": -3.000000000000016, + "curvature": 0.6528447360474303, + "holonomicRotation": 0.0, + "angularVelocity": 0.3269313584685308, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.891910973431456, + "pose": { + "rotation": { + "radians": 1.5351251875753922 + }, + "translation": { + "x": 2.999236096, + "y": 4.952004096000002 + } + }, + "velocity": 0.4647827901039487, + "acceleration": -3.000000000000002, + "curvature": 0.6556801391027219, + "holonomicRotation": 0.0, + "angularVelocity": 0.2768026259312415, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.9203433254767548, + "pose": { + "rotation": { + "radians": 1.5429953372829324 + }, + "translation": { + "x": 2.999569728, + "y": 4.964001728000001 + } + }, + "velocity": 0.3794857339680527, + "acceleration": -2.999999999999996, + "curvature": 0.6584819160890972, + "holonomicRotation": 0.0, + "angularVelocity": 0.21329879823738362, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 1.9573943207044333, + "pose": { + "rotation": { + "radians": 1.5508982700384952 + }, + "translation": { + "x": 2.999808512, + "y": 4.976000512000002 + } + }, + "velocity": 0.26833274828501735, + "acceleration": -2.9999999999999942, + "curvature": 0.6612478412834537, + "holonomicRotation": 0.0, + "angularVelocity": 0.0887202271044126, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.0468385701327723, + "pose": { + "rotation": { + "radians": 1.5588337841609612 + }, + "translation": { + "x": 2.999952064, + "y": 4.988000064000001 + } + }, + "velocity": 0, + "acceleration": -3.0000000000000058, + "curvature": 0.6612478412834537, + "holonomicRotation": 0.0, + "angularVelocity": 0.0, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.0468385701327723, + "pose": { + "rotation": { + "radians": 1.5747909935183229 + }, + "translation": { + "x": 3.0, + "y": 5.0 + } + }, + "velocity": 0, + "acceleration": -3.0, + "curvature": -0.663975664093471, + "holonomicRotation": 0.0, + "angularVelocity": 0.0, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.1362814075366994, + "pose": { + "rotation": { + "radians": 1.5747909935183229 + }, + "translation": { + "x": 3.000047936, + "y": 4.988000064000001 + } + }, + "velocity": -0.26832851221178183, + "acceleration": -3.0, + "curvature": -0.663975664093471, + "holonomicRotation": 0.0, + "angularVelocity": 0.21506066046267544, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.1733308423025224, + "pose": { + "rotation": { + "radians": 1.5827588694288295 + }, + "translation": { + "x": 3.000191488, + "y": 4.976000512 + } + }, + "velocity": -0.37947681650924975, + "acceleration": -2.999999999999999, + "curvature": -0.6612478412834536, + "holonomicRotation": 0.0, + "angularVelocity": 0.2791196654352754, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.201761351167232, + "pose": { + "rotation": { + "radians": 1.5906943835513019 + }, + "translation": { + "x": 3.000430272, + "y": 4.964001728000001 + } + }, + "velocity": -0.4647683431033788, + "acceleration": -2.999999999999999, + "curvature": -0.6584819160890969, + "holonomicRotation": 0.0, + "angularVelocity": 0.32970274886998213, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.2257312233707207, + "pose": { + "rotation": { + "radians": 1.5985973163068543 + }, + "translation": { + "x": 3.000763904, + "y": 4.952004096 + } + }, + "velocity": -0.536677959713845, + "acceleration": -2.9999999999999956, + "curvature": -0.6556801391026855, + "holonomicRotation": 0.0, + "angularVelocity": 0.37263931025212366, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.2468512434304047, + "pose": { + "rotation": { + "radians": 1.606467466014406 + }, + "translation": { + "x": 3.001192, + "y": 4.940008000000001 + } + }, + "velocity": -0.6000380198928976, + "acceleration": -3.0000000000000013, + "curvature": -0.6528447360474302, + "holonomicRotation": 0.0, + "angularVelocity": 0.41040227730578355, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.2659475863971474, + "pose": { + "rotation": { + "radians": 1.6143046486561694 + }, + "translation": { + "x": 3.001714176, + "y": 4.928013824 + } + }, + "velocity": -0.6573270487931249, + "acceleration": -3.000000000000003, + "curvature": -0.6499779059037698, + "holonomicRotation": 0.0, + "angularVelocity": 0.4443334326624615, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.2835110835440036, + "pose": { + "rotation": { + "radians": 1.6221086976329895 + }, + "translation": { + "x": 3.0023300479999997, + "y": 4.916021952000001 + } + }, + "velocity": -0.7100175402336942, + "acceleration": -3.0, + "curvature": -0.6470818190817534, + "holonomicRotation": 0.0, + "angularVelocity": 0.47526203255141736, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.2998615709460464, + "pose": { + "rotation": { + "radians": 1.6298794635088907 + }, + "translation": { + "x": 3.0030392320000003, + "y": 4.9040327679999995 + } + }, + "velocity": -0.7590690024398227, + "acceleration": -3.000000000000005, + "curvature": -0.6441586157755366, + "holonomicRotation": 0.0, + "angularVelocity": 0.5037448816056413, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.3152212312019, + "pose": { + "rotation": { + "radians": 1.6376168137459786 + }, + "translation": { + "x": 3.003841344, + "y": 4.892046656000001 + } + }, + "velocity": -0.8051479832073837, + "acceleration": -3.0, + "curvature": -0.6412104045031639, + "holonomicRotation": 0.0, + "angularVelocity": 0.5301782294741988, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.329751851769881, + "pose": { + "rotation": { + "radians": 1.645320632431872 + }, + "translation": { + "x": 3.004736, + "y": 4.880064 + } + }, + "velocity": -0.8487398449113267, + "acceleration": -3.000000000000004, + "curvature": -0.6382392605344286, + "holonomicRotation": 0.0, + "angularVelocity": 0.5548565565092586, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.3435755823826048, + "pose": { + "rotation": { + "radians": 1.6529908199977594 + }, + "translation": { + "x": 3.005722816, + "y": 4.868085184000001 + } + }, + "velocity": -0.8902110367494969, + "acceleration": -2.999999999999996, + "curvature": -0.6352472246548937, + "holonomicRotation": 0.0, + "angularVelocity": 0.5780062147703856, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.3567873312137406, + "pose": { + "rotation": { + "radians": 1.6606272929301413 + }, + "translation": { + "x": 3.0068014080000003, + "y": 4.856110592 + } + }, + "velocity": -0.9298462832429044, + "acceleration": -3.0, + "curvature": -0.6322363020068388, + "holonomicRotation": 0.0, + "angularVelocity": 0.5998059641255189, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.3694625812123173, + "pose": { + "rotation": { + "radians": 1.6682299834760697 + }, + "translation": { + "x": 3.007971392, + "y": 4.844140608000001 + } + }, + "velocity": -0.9678720332386348, + "acceleration": -3.0000000000000044, + "curvature": -0.629208460982605, + "holonomicRotation": 0.0, + "angularVelocity": 0.6204001606251212, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.381662539153711, + "pose": { + "rotation": { + "radians": 1.67579883934253 + }, + "translation": { + "x": 3.009232384, + "y": 4.832175616 + } + }, + "velocity": -1.004471907062816, + "acceleration": -3.000000000000009, + "curvature": -0.6261656322196447, + "holonomicRotation": 0.0, + "angularVelocity": 0.639907580276147, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.3934376521233767, + "pose": { + "rotation": { + "radians": 1.6833338233904271 + }, + "translation": { + "x": 3.010584, + "y": 4.820216 + } + }, + "velocity": -1.0397972459718132, + "acceleration": -2.999999999999986, + "curvature": -0.623109707774154, + "holonomicRotation": 0.0, + "angularVelocity": 0.6584275258631126, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.404830082785391, + "pose": { + "rotation": { + "radians": 1.6908349133247844 + }, + "translation": { + "x": 3.012025856, + "y": 4.8082621439999995 + } + }, + "velocity": -1.0739745379578567, + "acceleration": -2.999999999999995, + "curvature": -0.6200425403987191, + "holonomicRotation": 0.0, + "angularVelocity": 0.6760441751862138, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.4158754971681424, + "pose": { + "rotation": { + "radians": 1.6983021013807615 + }, + "translation": { + "x": 3.013557568, + "y": 4.796314432000001 + } + }, + "velocity": -1.107110781106111, + "acceleration": -3.0, + "curvature": -0.6169659427566521, + "holonomicRotation": 0.0, + "angularVelocity": 0.6928297531971396, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.426604384880453, + "pose": { + "rotation": { + "radians": 1.7057353940065614 + }, + "translation": { + "x": 3.0151787519999997, + "y": 4.784373248 + } + }, + "velocity": -1.1392974442430421, + "acceleration": -3.0, + "curvature": -0.6138816870079441, + "holonomicRotation": 0.0, + "angularVelocity": 0.7088468951007417, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.437043053073432, + "pose": { + "rotation": { + "radians": 1.7131348115441414 + }, + "translation": { + "x": 3.016889024, + "y": 4.772438976000001 + } + }, + "velocity": -1.170613448821979, + "acceleration": -3.0000000000000053, + "curvature": -0.6107915042418562, + "holonomicRotation": 0.0, + "angularVelocity": 0.7241504390507798, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.44721438759974, + "pose": { + "rotation": { + "radians": 1.7205003879070997 + }, + "translation": { + "x": 3.018688, + "y": 4.760511999999999 + } + }, + "velocity": -1.201127452400903, + "acceleration": -2.999999999999989, + "curvature": -0.6076970841012463, + "holonomicRotation": 0.0, + "angularVelocity": 0.7387888084396566, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.4571384447428093, + "pose": { + "rotation": { + "radians": 1.727832170258715 + }, + "translation": { + "x": 3.020575296, + "y": 4.748592704 + } + }, + "velocity": -1.230899623830111, + "acceleration": -3.000000000000011, + "curvature": -0.60460007456127, + "holonomicRotation": 0.0, + "angularVelocity": 0.7528050925433399, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.466832917456597, + "pose": { + "rotation": { + "radians": 1.7351302186871767 + }, + "translation": { + "x": 3.022550528, + "y": 4.736681472 + } + }, + "velocity": -1.2599830419714737, + "acceleration": -3.0, + "curvature": -0.6015020816667189, + "holonomicRotation": 0.0, + "angularVelocity": 0.7662379027193594, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.476313507191436, + "pose": { + "rotation": { + "radians": 1.7423946058821427 + }, + "translation": { + "x": 3.024613312, + "y": 4.724778688 + } + }, + "velocity": -1.288424811175992, + "acceleration": -3.0000000000000058, + "curvature": -0.5984046693700557, + "holonomicRotation": 0.0, + "angularVelocity": 0.7791220580677133, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.4855942236765203, + "pose": { + "rotation": { + "radians": 1.7496254168103444 + }, + "translation": { + "x": 3.026763264, + "y": 4.7128847359999995 + } + }, + "velocity": -1.3162669606312447, + "acceleration": -3.000000000000012, + "curvature": -0.5953093595736652, + "holonomicRotation": 0.0, + "angularVelocity": 0.791489140569654, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.4946876290224305, + "pose": { + "rotation": { + "radians": 1.7568227483924304 + }, + "translation": { + "x": 3.0290000000000004, + "y": 4.701 + } + }, + "velocity": -1.3435471766689753, + "acceleration": -3.000000000000018, + "curvature": -0.5922176320623417, + "holonomicRotation": 0.0, + "angularVelocity": 0.8033679485311952, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.5036050382878523, + "pose": { + "rotation": { + "radians": 1.7639867091802053 + }, + "translation": { + "x": 3.031323136, + "y": 4.689124864 + } + }, + "velocity": -1.3702994044652403, + "acceleration": -2.9999999999999876, + "curvature": -0.589130924651956, + "holonomicRotation": 0.0, + "angularVelocity": 0.8147848703989182, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.5123566856429775, + "pose": { + "rotation": { + "radians": 1.7711174190362282 + }, + "translation": { + "x": 3.033732288, + "y": 4.677259712 + } + }, + "velocity": -1.3965543465306167, + "acceleration": -3.0, + "curvature": -0.586050633250819, + "holonomicRotation": 0.0, + "angularVelocity": 0.8257641950397024, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.5209518630807075, + "pose": { + "rotation": { + "radians": 1.7782150088143185 + }, + "translation": { + "x": 3.036227072, + "y": 4.665404928 + } + }, + "velocity": -1.4223398788438055, + "acceleration": -2.9999999999999676, + "curvature": -0.5829781121894888, + "holonomicRotation": 0.0, + "angularVelocity": 0.8363283714374167, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.529399037025395, + "pose": { + "rotation": { + "radians": 1.7852796200427274 + }, + "translation": { + "x": 3.038807104, + "y": 4.653560896 + } + }, + "velocity": -1.4476814006778675, + "acceleration": -2.9999999999999933, + "curvature": -0.5799146744073547, + "holonomicRotation": 0.0, + "angularVelocity": 0.8464982273758479, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.5377059469986545, + "pose": { + "rotation": { + "radians": 1.7923114046100626 + }, + "translation": { + "x": 3.041472, + "y": 4.641728 + } + }, + "velocity": -1.4726021305976469, + "acceleration": -3.00000000000002, + "curvature": -0.5768615917997932, + "holonomicRotation": 0.0, + "angularVelocity": 0.8562931546703597, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.545879689607045, + "pose": { + "rotation": { + "radians": 1.7993105244536647 + }, + "translation": { + "x": 3.044221376, + "y": 4.629906623999999 + } + }, + "velocity": -1.497123358422818, + "acceleration": -3.0000000000000067, + "curvature": -0.5738200956456038, + "holonomicRotation": 0.0, + "angularVelocity": 0.8657312671405707, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.5539267904366865, + "pose": { + "rotation": { + "radians": 1.8062771512517184 + }, + "translation": { + "x": 3.047054848, + "y": 4.618097152 + } + }, + "velocity": -1.5212646609117435, + "acceleration": -3.0000000000000138, + "curvature": -0.5707913768570366, + "holonomicRotation": 0.0, + "angularVelocity": 0.87482953581738, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.5618532659183937, + "pose": { + "rotation": { + "radians": 1.813211466118048 + }, + "translation": { + "x": 3.0499720320000003, + "y": 4.606299968 + } + }, + "velocity": -1.5450440873568647, + "acceleration": -2.999999999999986, + "curvature": -0.5677765867125653, + "holonomicRotation": 0.0, + "angularVelocity": 0.8836039055943861, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.569664676823153, + "pose": { + "rotation": { + "radians": 1.820113659301696 + }, + "translation": { + "x": 3.0529725439999997, + "y": 4.594515456 + } + }, + "velocity": -1.5684783200711427, + "acceleration": -3.0, + "curvature": -0.5647768371119459, + "holonomicRotation": 0.0, + "angularVelocity": 0.8920693959976156, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.577366174732555, + "pose": { + "rotation": { + "radians": 1.8269839298900132 + }, + "translation": { + "x": 3.0560560000000003, + "y": 4.582744 + } + }, + "velocity": -1.591582813799349, + "acceleration": -3.0, + "curvature": -0.5617932012303779, + "holonomicRotation": 0.0, + "angularVelocity": 0.9002401887212853, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.5849625425806573, + "pose": { + "rotation": { + "radians": 1.833822485515185 + }, + "translation": { + "x": 3.059222016, + "y": 4.570985984 + } + }, + "velocity": -1.6143719173436557, + "acceleration": -3.0000000000000293, + "curvature": -0.5588267141256478, + "holonomicRotation": 0.0, + "angularVelocity": 0.9081297043785966, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.592458230167031, + "pose": { + "rotation": { + "radians": 1.8406295420671128 + }, + "translation": { + "x": 3.062470208, + "y": 4.559241792 + } + }, + "velocity": -1.6368589801027766, + "acceleration": -3.0, + "curvature": -0.5558783732812124, + "holonomicRotation": 0.0, + "angularVelocity": 0.9157506692825748, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.5998573853836477, + "pose": { + "rotation": { + "radians": 1.8474053234088554 + }, + "translation": { + "x": 3.065800192, + "y": 4.547511807999999 + } + }, + "velocity": -1.6590564457526276, + "acceleration": -3.000000000000015, + "curvature": -0.5529491392614698, + "holonomicRotation": 0.0, + "angularVelocity": 0.9231151746224233, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.607163881771995, + "pose": { + "rotation": { + "radians": 1.8541500610982622 + }, + "translation": { + "x": 3.069211584, + "y": 4.535796415999999 + } + }, + "velocity": -1.6809759349176676, + "acceleration": -3.0, + "curvature": -0.5500399363825702, + "holonomicRotation": 0.0, + "angularVelocity": 0.9302347284834435, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.614381342924677, + "pose": { + "rotation": { + "radians": 1.8608639941139673 + }, + "translation": { + "x": 3.072704, + "y": 4.524095999999999 + } + }, + "velocity": -1.7026283183757143, + "acceleration": -3.0000000000000155, + "curvature": -0.5471516533975169, + "holonomicRotation": 0.0, + "angularVelocity": 0.9371203020405943, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.6215131641626916, + "pose": { + "rotation": { + "radians": 1.867547368586635 + }, + "translation": { + "x": 3.0762770560000003, + "y": 4.512410944 + } + }, + "velocity": -1.7240237820897581, + "acceleration": -3.0000000000000155, + "curvature": -0.5442851441519785, + "holonomicRotation": 0.0, + "angularVelocity": 0.9437823705718374, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.6285625318515775, + "pose": { + "rotation": { + "radians": 1.8742004375350847 + }, + "translation": { + "x": 3.0799303680000003, + "y": 4.5007416319999995 + } + }, + "velocity": -1.7451718851564173, + "acceleration": -3.0000000000000315, + "curvature": -0.5414412284047262, + "holonomicRotation": 0.0, + "angularVelocity": 0.9502309502266035, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.6355324406637557, + "pose": { + "rotation": { + "radians": 1.8808234606086733 + }, + "translation": { + "x": 3.083663552, + "y": 4.4890884479999995 + } + }, + "velocity": -1.7660816115929512, + "acceleration": -3.0, + "curvature": -0.538620692477182, + "holonomicRotation": 0.0, + "angularVelocity": 0.9564756306438044, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.6424257090481733, + "pose": { + "rotation": { + "radians": 1.887416703833856 + }, + "translation": { + "x": 3.087476224, + "y": 4.477451776 + } + }, + "velocity": -1.7867614167462036, + "acceleration": -2.999999999999984, + "curvature": -0.5358242899805565, + "holonomicRotation": 0.0, + "angularVelocity": 0.9625256044974729, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.6492449931300026, + "pose": { + "rotation": { + "radians": 1.8939804393669588 + }, + "translation": { + "x": 3.091368, + "y": 4.465832 + } + }, + "velocity": -1.8072192689916917, + "acceleration": -3.0000000000000324, + "curvature": -0.5330527427341364, + "holonomicRotation": 0.0, + "angularVelocity": 0.9683896940137469, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.655992799231136, + "pose": { + "rotation": { + "radians": 1.9005149452524996 + }, + "translation": { + "x": 3.095338496, + "y": 4.454229504 + } + }, + "velocity": -1.8274626872950925, + "acceleration": -3.0000000000000164, + "curvature": -0.5303067413665257, + "holonomicRotation": 0.0, + "angularVelocity": 0.9740763748988773, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.662671495175413, + "pose": { + "rotation": { + "radians": 1.9070205051869529 + }, + "translation": { + "x": 3.099387328, + "y": 4.442644671999999 + } + }, + "velocity": -1.8474987751279237, + "acceleration": -3.0, + "curvature": -0.527586946146635, + "holonomicRotation": 0.0, + "angularVelocity": 0.9795937980323695, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.6692833205199555, + "pose": { + "rotation": { + "radians": 1.9134974082881397 + }, + "translation": { + "x": 3.103514112, + "y": 4.431077888 + } + }, + "velocity": -1.8673342511615505, + "acceleration": -2.999999999999983, + "curvature": -0.5248939878051837, + "holonomicRotation": 0.0, + "angularVelocity": 0.9849498091799569, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.6758303958349496, + "pose": { + "rotation": { + "radians": 1.91994594887033 + }, + "translation": { + "x": 3.1077184640000004, + "y": 4.419529536 + } + }, + "velocity": -1.886975477106533, + "acceleration": -2.999999999999983, + "curvature": -0.5222284682600391, + "holonomicRotation": 0.0, + "angularVelocity": 0.9901519669516187, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.6823147311380504, + "pose": { + "rotation": { + "radians": 1.9263664262250693 + }, + "translation": { + "x": 3.112, + "y": 4.4079999999999995 + } + }, + "velocity": -1.9064284830158356, + "acceleration": -2.9999999999999827, + "curvature": -0.5195909614569447, + "holonomicRotation": 0.0, + "angularVelocity": 0.9952075592378692, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.6887382335758687, + "pose": { + "rotation": { + "radians": 1.932759144407969 + }, + "translation": { + "x": 3.1163583360000002, + "y": 4.396489664 + } + }, + "velocity": -1.9256989903292907, + "acceleration": -2.9999999999999827, + "curvature": -0.5169820141397626, + "holonomicRotation": 0.0, + "angularVelocity": 1.0001236180920878, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.695102714433262, + "pose": { + "rotation": { + "radians": 1.9391244120303428 + }, + "translation": { + "x": 3.120793088, + "y": 4.3849989119999995 + } + }, + "velocity": -1.9447924329014699, + "acceleration": -3.0, + "curvature": -0.5144021466205735, + "holonomicRotation": 0.0, + "angularVelocity": 1.0049069337160776, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.7014098955411114, + "pose": { + "rotation": { + "radians": 1.9454625420578235 + }, + "translation": { + "x": 3.1253038720000004, + "y": 4.373528127999999 + } + }, + "velocity": -1.9637139762250175, + "acceleration": -3.0, + "curvature": -0.5118518535624782, + "holonomicRotation": 0.0, + "angularVelocity": 1.009564066942242, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.7076614151446488, + "pose": { + "rotation": { + "radians": 1.95177385161334 + }, + "translation": { + "x": 3.1298903040000003, + "y": 4.362077695999999 + } + }, + "velocity": -1.9824685350356301, + "acceleration": -3.0, + "curvature": -0.5093316047891807, + "holonomicRotation": 0.0, + "angularVelocity": 1.0141013611165504, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.7138588332869524, + "pose": { + "rotation": { + "radians": 1.9580586617868585 + }, + "translation": { + "x": 3.1345520000000002, + "y": 4.350648 + } + }, + "velocity": -2.001060789462541, + "acceleration": -3.0000000000000178, + "curvature": -0.506841846048325, + "holonomicRotation": 0.0, + "angularVelocity": 1.018524952789108, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.7200036367558105, + "pose": { + "rotation": { + "radians": 1.9643172974498757 + }, + "translation": { + "x": 3.139288576, + "y": 4.339239424 + } + }, + "velocity": -2.019495199869116, + "acceleration": -3.000000000000036, + "curvature": -0.5043829997561204, + "holonomicRotation": 0.0, + "angularVelocity": 1.0228407818470144, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.726097243636585, + "pose": { + "rotation": { + "radians": 1.9705500870760755 + }, + "translation": { + "x": 3.144099648, + "y": 4.327852352 + } + }, + "velocity": -2.0377760205114392, + "acceleration": -2.9999999999999454, + "curvature": -0.5019554658388903, + "holonomicRotation": 0.0, + "angularVelocity": 1.027054600792063, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.7321410075088677, + "pose": { + "rotation": { + "radians": 1.976757362567204 + }, + "translation": { + "x": 3.1489848320000005, + "y": 4.316487167999999 + } + }, + "velocity": -2.0559073121282863, + "acceleration": -3.0, + "curvature": -0.49955962237970714, + "holonomicRotation": 0.0, + "angularVelocity": 1.0311719834343849, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.738136221320501, + "pose": { + "rotation": { + "radians": 1.9829394590844593 + }, + "translation": { + "x": 3.153943744, + "y": 4.305144255999999 + } + }, + "velocity": -2.0738929535631874, + "acceleration": -3.0000000000000555, + "curvature": -0.4971958264330603, + "holonomicRotation": 0.0, + "angularVelocity": 1.0351983330386056, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.744084120968872, + "pose": { + "rotation": { + "radians": 1.9890967148855339 + }, + "translation": { + "x": 3.158976, + "y": 4.293824 + } + }, + "velocity": -2.0917366525083003, + "acceleration": -3.0000000000000187, + "curvature": -0.4948644147448579, + "holonomicRotation": 0.0, + "angularVelocity": 1.0391388898266953, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.7499858886161315, + "pose": { + "rotation": { + "radians": 1.995229471166522 + }, + "translation": { + "x": 3.164081216, + "y": 4.282526783999999 + } + }, + "velocity": -2.109441955450078, + "acceleration": -3.0, + "curvature": -0.49256570452370857, + "holonomicRotation": 0.0, + "angularVelocity": 1.0429987382066992, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.7558426557621933, + "pose": { + "rotation": { + "radians": 2.001338071909835 + }, + "translation": { + "x": 3.1692590080000005, + "y": 4.271252991999999 + } + }, + "velocity": -2.1270122568882637, + "acceleration": -2.999999999999943, + "curvature": -0.49029999405552377, + "holonomicRotation": 0.0, + "angularVelocity": 1.0467828132733483, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.761655506096872, + "pose": { + "rotation": { + "radians": 2.0074228637363074 + }, + "translation": { + "x": 3.1745089920000003, + "y": 4.260003007999999 + } + }, + "velocity": -2.144450807892301, + "acceleration": -2.999999999999981, + "curvature": -0.4880675635449118, + "holonomicRotation": 0.0, + "angularVelocity": 1.0504959073292972, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.76742547815031, + "pose": { + "rotation": { + "radians": 2.013484195763848 + }, + "translation": { + "x": 3.1798307840000004, + "y": 4.248777216 + } + }, + "velocity": -2.161760724052613, + "acceleration": -2.9999999999999614, + "curvature": -0.4858686756363079, + "holonomicRotation": 0.0, + "angularVelocity": 1.0541426755227752, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.7731535677589205, + "pose": { + "rotation": { + "radians": 2.019522419469503 + }, + "translation": { + "x": 3.1852240000000003, + "y": 4.237576 + } + }, + "velocity": -2.1789449928784457, + "acceleration": -3.0000000000000777, + "curvature": -0.4837035763095772, + "holonomicRotation": 0.0, + "angularVelocity": 1.0577276417062655, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.7788407303623694, + "pose": { + "rotation": { + "radians": 2.0255378885580493 + }, + "translation": { + "x": 3.190688256, + "y": 4.226399743999999 + } + }, + "velocity": -2.1960064806887933, + "acceleration": -3.000000000000039, + "curvature": -0.4815724954088063, + "holonomicRotation": 0.0, + "angularVelocity": 1.0612552035558065, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.7844878831455677, + "pose": { + "rotation": { + "radians": 2.0315309588344928 + }, + "translation": { + "x": 3.1962231680000004, + "y": 4.2152488319999994 + } + }, + "velocity": -2.2129479390383873, + "acceleration": -3.0000000000000195, + "curvature": -0.47947564724702796, + "holonomicRotation": 0.0, + "angularVelocity": 1.0647296375816526, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.7900959070383258, + "pose": { + "rotation": { + "radians": 2.0375019880813783 + }, + "translation": { + "x": 3.2018283520000006, + "y": 4.2041236479999995 + } + }, + "velocity": -2.2297720107166614, + "acceleration": -3.0, + "curvature": -0.47741323142346864, + "holonomicRotation": 0.0, + "angularVelocity": 1.0681551040319075, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.7956656485841047, + "pose": { + "rotation": { + "radians": 2.043451335941641 + }, + "translation": { + "x": 3.2075034240000004, + "y": 4.193024575999999 + } + }, + "velocity": -2.2464812353539987, + "acceleration": -2.99999999999996, + "curvature": -0.4753854333143056, + "holonomicRotation": 0.0, + "angularVelocity": 1.0715356512800862, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.801197921688225, + "pose": { + "rotation": { + "radians": 2.0493793638053237 + }, + "translation": { + "x": 3.2132480000000005, + "y": 4.181951999999999 + } + }, + "velocity": -2.2630780546663596, + "acceleration": -3.0, + "curvature": -0.4733924247442328, + "holonomicRotation": 0.0, + "angularVelocity": 1.0748752201213205, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.8066935092549423, + "pose": { + "rotation": { + "radians": 2.055286434700795 + }, + "translation": { + "x": 3.2190616960000002, + "y": 4.170906303999999 + } + }, + "velocity": -2.279564817366512, + "acceleration": -3.00000000000002, + "curvature": -0.47143436459980015, + "holonomicRotation": 0.0, + "angularVelocity": 1.0781776480141334, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.8121531647219413, + "pose": { + "rotation": { + "radians": 2.0611729131911716 + }, + "translation": { + "x": 3.2249441280000006, + "y": 4.159887872 + } + }, + "velocity": -2.295943783767509, + "acceleration": -3.0, + "curvature": -0.46951139935295344, + "holonomicRotation": 0.0, + "angularVelocity": 1.0814466727704475, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.817577613500027, + "pose": { + "rotation": { + "radians": 2.0670391652738456 + }, + "translation": { + "x": 3.230894912, + "y": 4.148897087999999 + } + }, + "velocity": -2.312217130101765, + "acceleration": -3.000000000000041, + "curvature": -0.4676236637363229, + "holonomicRotation": 0.0, + "angularVelocity": 1.084685936631654, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.822967554325104, + "pose": { + "rotation": { + "radians": 2.0728855582860835 + }, + "translation": { + "x": 3.2369136640000002, + "y": 4.137934335999999 + } + }, + "velocity": -2.328386952576996, + "acceleration": -3.0, + "curvature": -0.46577128117650907, + "holonomicRotation": 0.0, + "angularVelocity": 1.087898989429441, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.8283236605289246, + "pose": { + "rotation": { + "radians": 2.078712460812497 + }, + "translation": { + "x": 3.2430000000000003, + "y": 4.127 + } + }, + "velocity": -2.3444552711884588, + "acceleration": -3.000000000000021, + "curvature": -0.46395436448481275, + "holonomicRotation": 0.0, + "angularVelocity": 1.0910892923568585, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.833646581234512, + "pose": { + "rotation": { + "radians": 2.084520242598428 + }, + "translation": { + "x": 3.249153536, + "y": 4.116094464 + } + }, + "velocity": -2.360424033305221, + "acceleration": -3.0, + "curvature": -0.4621730162899535, + "holonomicRotation": 0.0, + "angularVelocity": 1.0942602211565104, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.838936942481669, + "pose": { + "rotation": { + "radians": 2.0903092744667395 + }, + "translation": { + "x": 3.2553738880000003, + "y": 4.105218111999999 + } + }, + "velocity": -2.376295117046691, + "acceleration": -2.999999999999937, + "curvature": -0.46042732956063537, + "holonomicRotation": 0.0, + "angularVelocity": 1.0974150691660196, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.8441953482875366, + "pose": { + "rotation": { + "radians": 2.096079928237889 + }, + "translation": { + "x": 3.2616606720000005, + "y": 4.094371327999999 + } + }, + "velocity": -2.392070334464294, + "acceleration": -3.0000000000000213, + "curvature": -0.45871738814240054, + "holonomicRotation": 0.0, + "angularVelocity": 1.1005570504780544, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.849422381646745, + "pose": { + "rotation": { + "radians": 2.1018325766544494 + }, + "translation": { + "x": 3.2680135040000002, + "y": 4.083554496 + } + }, + "velocity": -2.4077514345419186, + "acceleration": -2.9999999999999787, + "curvature": -0.45704326726309885, + "holonomicRotation": 0.0, + "angularVelocity": 1.1036893028426855, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.8546186054753275, + "pose": { + "rotation": { + "radians": 2.1075675933092324 + }, + "translation": { + "x": 3.2744320000000005, + "y": 4.072767999999999 + } + }, + "velocity": -2.4233401060276667, + "acceleration": -3.0000000000000213, + "curvature": -0.4554050339602513, + "holonomicRotation": 0.0, + "angularVelocity": 1.1068148903936257, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.859784563502238, + "pose": { + "rotation": { + "radians": 2.1132853525765656 + }, + "translation": { + "x": 3.2809157760000005, + "y": 4.062012223999999 + } + }, + "velocity": -2.438837980108399, + "acceleration": -3.0000000000000213, + "curvature": -0.4538027475367536, + "holonomicRotation": 0.0, + "angularVelocity": 1.1099368064092427, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.8649207811120037, + "pose": { + "rotation": { + "radians": 2.118986229547372 + }, + "translation": { + "x": 3.2874644480000006, + "y": 4.051287551999999 + } + }, + "velocity": -2.454246632937696, + "acceleration": -3.0000000000000218, + "curvature": -0.45223646007658297, + "holonomicRotation": 0.0, + "angularVelocity": 1.113057975924393, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.87002776614176, + "pose": { + "rotation": { + "radians": 2.1246705999676685 + }, + "translation": { + "x": 3.2940776320000005, + "y": 4.040594367999999 + } + }, + "velocity": -2.469567588026965, + "acceleration": -3.0000000000000435, + "curvature": -0.4507062168354121, + "holonomicRotation": 0.0, + "angularVelocity": 1.1161812581885475, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.8751060096356733, + "pose": { + "rotation": { + "radians": 2.1303388401800927 + }, + "translation": { + "x": 3.3007549440000004, + "y": 4.029933055999999 + } + }, + "velocity": -2.484802318508706, + "acceleration": -3.0000000000000657, + "curvature": -0.4492120566748173, + "holonomicRotation": 0.0, + "angularVelocity": 1.119309449123158, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.880155986559517, + "pose": { + "rotation": { + "radians": 2.1359913270688047 + }, + "translation": { + "x": 3.3074960000000004, + "y": 4.019303999999999 + } + }, + "velocity": -2.499952249280237, + "acceleration": -3.000000000000066, + "curvature": -0.44775401243225865, + "holonomicRotation": 0.0, + "angularVelocity": 1.1224452836459866, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.8851781564779557, + "pose": { + "rotation": { + "radians": 2.141628438007425 + }, + "translation": { + "x": 3.3143004160000005, + "y": 4.008707584 + } + }, + "velocity": -2.5150187590355526, + "acceleration": -2.999999999999978, + "curvature": -0.4463321113345515, + "holonomicRotation": 0.0, + "angularVelocity": 1.1255914379109953, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.8901729641969114, + "pose": { + "rotation": { + "radians": 2.1472505508098934 + }, + "translation": { + "x": 3.3211678080000007, + "y": 3.9981441919999994 + } + }, + "velocity": -2.5300031821924205, + "acceleration": -3.0000000000000444, + "curvature": -0.4449463754557567, + "holonomicRotation": 0.0, + "angularVelocity": 1.1287505315403796, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.8951408403731946, + "pose": { + "rotation": { + "radians": 2.1528580436844997 + }, + "translation": { + "x": 3.3280977920000003, + "y": 3.987614207999999 + } + }, + "velocity": -2.54490681072127, + "acceleration": -2.999999999999978, + "curvature": -0.44359682198548334, + "holonomicRotation": 0.0, + "angularVelocity": 1.1319251296711867, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.900082202093434, + "pose": { + "rotation": { + "radians": 2.1584512951904333 + }, + "translation": { + "x": 3.3350899840000006, + "y": 3.977118015999999 + } + }, + "velocity": -2.559730895881986, + "acceleration": -2.9999999999999325, + "curvature": -0.44228346357140413, + "holonomicRotation": 0.0, + "angularVelocity": 1.1351177449810737, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.904997453424183, + "pose": { + "rotation": { + "radians": 2.1640306841970087 + }, + "translation": { + "x": 3.3421440000000007, + "y": 3.9666559999999995 + } + }, + "velocity": -2.574476649874234, + "acceleration": -3.0000000000000453, + "curvature": -0.44100630878383207, + "holonomicRotation": 0.0, + "angularVelocity": 1.1383308397188256, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.9098869859349623, + "pose": { + "rotation": { + "radians": 2.1695965898458365 + }, + "translation": { + "x": 3.3492594560000004, + "y": 3.956228543999999 + } + }, + "velocity": -2.589145247406572, + "acceleration": -3.0000000000000453, + "curvature": -0.43976536240568537, + "holonomicRotation": 0.0, + "angularVelocity": 1.1415668276352418, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.9147511791958403, + "pose": { + "rotation": { + "radians": 2.175149391515662 + }, + "translation": { + "x": 3.356435968000001, + "y": 3.9458360319999994 + } + }, + "velocity": -2.603737827189206, + "acceleration": -2.9999999999999543, + "curvature": -0.43856062556178693, + "holonomicRotation": 0.0, + "angularVelocity": 1.1448280756029832, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.919590401251085, + "pose": { + "rotation": { + "radians": 2.180689468788583 + }, + "translation": { + "x": 3.3636731520000005, + "y": 3.9354788479999994 + } + }, + "velocity": -2.6182554933549405, + "acceleration": -3.0000000000000457, + "curvature": -0.43739209639321713, + "holonomicRotation": 0.0, + "angularVelocity": 1.145850588652444, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.9244145316277996, + "pose": { + "rotation": { + "radians": 2.1862172014204777 + }, + "translation": { + "x": 3.3709706240000004, + "y": 3.925157375999999 + } + }, + "velocity": -2.622334232261645, + "acceleration": -0.8454868729070896, + "curvature": -0.4362597700073285, + "holonomicRotation": 0.0, + "angularVelocity": 1.1445003863930865, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.9292338990626856, + "pose": { + "rotation": { + "radians": 2.1917329693118752 + }, + "translation": { + "x": 3.3783280000000007, + "y": 3.914871999999999 + } + }, + "velocity": -2.625634845989314, + "acceleration": -0.6848645122545891, + "curvature": -0.43516363895714666, + "holonomicRotation": 0.0, + "angularVelocity": 1.1430465952170605, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.934049261090149, + "pose": { + "rotation": { + "radians": 2.1972371524821046 + }, + "translation": { + "x": 3.3857448960000003, + "y": 3.9046231039999992 + } + }, + "velocity": -2.6288383813504206, + "acceleration": -0.6652740422913254, + "curvature": -0.4341036934661007, + "holonomicRotation": 0.0, + "angularVelocity": 1.141638532462789, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.9388607477448287, + "pose": { + "rotation": { + "radians": 2.2027301310455174 + }, + "translation": { + "x": 3.3932209280000003, + "y": 3.894411071999999 + } + }, + "velocity": -2.6319437458571184, + "acceleration": -0.6454064470235114, + "curvature": -0.4330799216330578, + "holonomicRotation": 0.0, + "angularVelocity": 1.1402763514325127, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.9436684894267646, + "pose": { + "rotation": { + "radians": 2.2082122851892256 + }, + "translation": { + "x": 3.4007557120000005, + "y": 3.8842362879999994 + } + }, + "velocity": -2.6349498803219897, + "acceleration": -0.6252695472733159, + "curvature": -0.4320923098070697, + "holonomicRotation": 0.0, + "angularVelocity": 1.138960198162488, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.9484726168868667, + "pose": { + "rotation": { + "radians": 2.213683995153181 + }, + "translation": { + "x": 3.4083488640000006, + "y": 3.874099135999999 + } + }, + "velocity": -2.6378557595292262, + "acceleration": -0.6048713801558966, + "curvature": -0.4311408427216499, + "holonomicRotation": 0.0, + "angularVelocity": 1.1376902117009824, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.953273261212499, + "pose": { + "rotation": { + "radians": 2.219145641212311 + }, + "translation": { + "x": 3.4160000000000004, + "y": 3.863999999999999 + } + }, + "velocity": -2.640660392350118, + "acceleration": -0.584220081857935, + "curvature": -0.4302255037988389, + "holonomicRotation": 0.0, + "angularVelocity": 1.1364665242199663, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.9580705538132235, + "pose": { + "rotation": { + "radians": 2.224597603659922 + }, + "translation": { + "x": 3.4237087360000005, + "y": 3.853939263999999 + } + }, + "velocity": -2.6433628223610883, + "acceleration": -0.5633239904028693, + "curvature": -0.4293462752752821, + "holonomicRotation": 0.0, + "angularVelocity": 1.135289261297001, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.9628646264067062, + "pose": { + "rotation": { + "radians": 2.2300402627931817 + }, + "translation": { + "x": 3.4314746880000007, + "y": 3.8439173119999994 + } + }, + "velocity": -2.6459621279004737, + "acceleration": -0.5421915268698363, + "curvature": -0.4285031384986032, + "holonomicRotation": 0.0, + "angularVelocity": 1.1341585420547766, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.967655611005099, + "pose": { + "rotation": { + "radians": 2.235473998900302 + }, + "translation": { + "x": 3.4392974720000007, + "y": 3.8339345279999995 + } + }, + "velocity": -2.648457422337088, + "acceleration": -0.5208312373726626, + "curvature": -0.42769607414071226, + "holonomicRotation": 0.0, + "angularVelocity": 1.133074479392834, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.9724436399012846, + "pose": { + "rotation": { + "radians": 2.240899192249165 + }, + "translation": { + "x": 3.4471767040000008, + "y": 3.823991295999999 + } + }, + "velocity": -2.6508478547544363, + "acceleration": -0.49925187779313374, + "curvature": -0.42692506226405785, + "holonomicRotation": 0.0, + "angularVelocity": 1.1320371801254954, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.97722884565546, + "pose": { + "rotation": { + "radians": 2.246316223077442 + }, + "translation": { + "x": 3.4551120000000006, + "y": 3.814087999999999 + } + }, + "velocity": -2.653132609673996, + "acceleration": -0.47746221101694586, + "curvature": -0.4261900826856946, + "holonomicRotation": 0.0, + "angularVelocity": 1.1310467451481108, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.9820113610819488, + "pose": { + "rotation": { + "radians": 2.2517254715841926 + }, + "translation": { + "x": 3.463102976000001, + "y": 3.804225023999999 + } + }, + "velocity": -2.655310907833249, + "acceleration": -0.4554712248680483, + "curvature": -0.42549111498766573, + "holonomicRotation": 0.0, + "angularVelocity": 1.1301032696261668, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.9867913192359405, + "pose": { + "rotation": { + "radians": 2.257127317922695 + }, + "translation": { + "x": 3.4711492480000006, + "y": 3.794402751999999 + } + }, + "velocity": -2.657382006198557, + "acceleration": -0.4332879700166909, + "curvature": -0.42482813876175346, + "holonomicRotation": 0.0, + "angularVelocity": 1.1292068432180316, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.991568853400548, + "pose": { + "rotation": { + "radians": 2.2625221421950776 + }, + "translation": { + "x": 3.4792504320000006, + "y": 3.784621567999999 + } + }, + "velocity": -2.6593451982965712, + "acceleration": -0.41092162407919103, + "curvature": -0.424201133738781, + "holonomicRotation": 0.0, + "angularVelocity": 1.1283575500272023, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.9963440970740116, + "pose": { + "rotation": { + "radians": 2.26791032444725 + }, + "translation": { + "x": 3.487406144000001, + "y": 3.774881855999999 + } + }, + "velocity": -2.6611998143698017, + "acceleration": -0.38838145235114474, + "curvature": -0.42361007996169614, + "holonomicRotation": 0.0, + "angularVelocity": 1.1275554689254084, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.001117183957077, + "pose": { + "rotation": { + "radians": 2.2732922446659067 + }, + "translation": { + "x": 3.495616000000001, + "y": 3.765183999999999 + } + }, + "velocity": -2.6629452216557663, + "acceleration": -0.3656768311000486, + "curvature": -0.42305495790658737, + "holonomicRotation": 0.0, + "angularVelocity": 1.1268006736114815, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.0058882479402897, + "pose": { + "rotation": { + "radians": 2.2786682827760343 + }, + "translation": { + "x": 3.5038796160000008, + "y": 3.755528383999999 + } + }, + "velocity": -2.6645808247919645, + "acceleration": -0.34281727135773626, + "curvature": -0.42253574855162407, + "holonomicRotation": 0.0, + "angularVelocity": 1.1260932327968134, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.010657423091539, + "pose": { + "rotation": { + "radians": 2.2840388186398783 + }, + "translation": { + "x": 3.512196608000001, + "y": 3.7459153919999992 + } + }, + "velocity": -2.6661060656923015, + "acceleration": -0.3198123054754257, + "curvature": -0.4220524336016502, + "holonomicRotation": 0.0, + "angularVelocity": 1.1254332101236695, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.0154248436438675, + "pose": { + "rotation": { + "radians": 2.2894042320560954 + }, + "translation": { + "x": 3.5205665920000007, + "y": 3.736345407999999 + } + }, + "velocity": -2.6675204238998145, + "acceleration": -0.29667158413832084, + "curvature": -0.4216049955488846, + "holonomicRotation": 0.0, + "angularVelocity": 1.1248206645718342, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.0201906439832062, + "pose": { + "rotation": { + "radians": 2.294764902761007 + }, + "translation": { + "x": 3.5289891840000007, + "y": 3.7268188159999993 + } + }, + "velocity": -2.6688234168146447, + "acceleration": -0.27340484746599136, + "curvature": -0.4211934177613658, + "holonomicRotation": 0.0, + "angularVelocity": 1.1242556502653611, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.0249549586362185, + "pose": { + "rotation": { + "radians": 2.300121210429298 + }, + "translation": { + "x": 3.5374640000000004, + "y": 3.717335999999999 + } + }, + "velocity": -2.6700145997957936, + "acceleration": -0.2500218956772268, + "curvature": -0.4208176845991983, + "holonomicRotation": 0.0, + "angularVelocity": 1.123738216844328, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.029717922258233, + "pose": { + "rotation": { + "radians": 2.3054735346767954 + }, + "translation": { + "x": 3.5459906560000007, + "y": 3.707897343999999 + } + }, + "velocity": -2.671093566389595, + "acceleration": -0.22653261276539288, + "curvature": -0.4204777814786742, + "holonomicRotation": 0.0, + "angularVelocity": 1.1232684092818601, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.034479669621233, + "pose": { + "rotation": { + "radians": 2.310822255062634 + }, + "translation": { + "x": 3.5545687680000007, + "y": 3.6985032319999993 + } + }, + "velocity": -2.6720599484322793, + "acceleration": -0.20294693712507567, + "curvature": -0.42017369496416096, + "holonomicRotation": 0.0, + "angularVelocity": 1.1228462681895641, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.0392403356020856, + "pose": { + "rotation": { + "radians": 2.3161677510933316 + }, + "translation": { + "x": 3.563197952000001, + "y": 3.689154047999999 + } + }, + "velocity": -2.672913416024821, + "acceleration": -0.17927483170934566, + "curvature": -0.4199054128880666, + "holonomicRotation": 0.0, + "angularVelocity": 1.1224718297169374, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.044000055170769, + "pose": { + "rotation": { + "radians": 2.321510402226531 + }, + "translation": { + "x": 3.571877824000001, + "y": 3.679850175999999 + } + }, + "velocity": -2.6736536778913673, + "acceleration": -0.15552636155641372, + "curvature": -0.4196729243382383, + "holonomicRotation": 0.0, + "angularVelocity": 1.122145125703422, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.048758963378458, + "pose": { + "rotation": { + "radians": 2.3268505878754597 + }, + "translation": { + "x": 3.5806080000000007, + "y": 3.670591999999999 + } + }, + "velocity": -2.6742804814591006, + "acceleration": -0.13171163224381718, + "curvature": -0.41947621972129306, + "holonomicRotation": 0.0, + "angularVelocity": 1.1218661837351616, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.053517195345991, + "pose": { + "rotation": { + "radians": 2.3321886874142024 + }, + "translation": { + "x": 3.5893880960000004, + "y": 3.661379903999999 + } + }, + "velocity": -2.674793612605643, + "acceleration": -0.10784071689727757, + "curvature": -0.419315290918276, + "holonomicRotation": 0.0, + "angularVelocity": 1.1216350272072997, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.0582748862519926, + "pose": { + "rotation": { + "radians": 2.337525080182999 + }, + "translation": { + "x": 3.598217728000001, + "y": 3.6522142719999993 + } + }, + "velocity": -2.6751928965083205, + "acceleration": -0.08392388462520017, + "curvature": -0.4191901310828717, + "holonomicRotation": 0.0, + "angularVelocity": 1.1214516752368215, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.06303217132131, + "pose": { + "rotation": { + "radians": 2.342860145493564 + }, + "translation": { + "x": 3.607096512000001, + "y": 3.6430954879999993 + } + }, + "velocity": -2.6754781966265213, + "acceleration": -0.05997120501374331, + "curvature": -0.4191007350133541, + "holonomicRotation": 0.0, + "angularVelocity": 1.1213161429216323, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.067789185813631, + "pose": { + "rotation": { + "radians": 2.348194262635916 + }, + "translation": { + "x": 3.616024064000001, + "y": 3.6340239359999993 + } + }, + "velocity": -2.6756494156563497, + "acceleration": -0.03599295947170036, + "curvature": -0.4190470988943057, + "holonomicRotation": 0.0, + "angularVelocity": 1.121228441093887, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.072546065011709, + "pose": { + "rotation": { + "radians": 2.353527810883649 + }, + "translation": { + "x": 3.625000000000001, + "y": 3.624999999999999 + } + }, + "velocity": -2.675706495129876, + "acceleration": -0.011999353178753079, + "curvature": -0.41902922045158014, + "holonomicRotation": 0.0, + "angularVelocity": 1.1211885766455594, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.0773029442097872, + "pose": { + "rotation": { + "radians": 2.358861169501017 + }, + "translation": { + "x": 3.634023936000001, + "y": 3.616024063999999 + } + }, + "velocity": -2.67564941565635, + "acceleration": 0.011999353178659161, + "curvature": -0.4190470988943055, + "holonomicRotation": 0.0, + "angularVelocity": 1.1211965522473806, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.0820599587021085, + "pose": { + "rotation": { + "radians": 2.3641947177487985 + }, + "translation": { + "x": 3.643095488000001, + "y": 3.607096511999999 + } + }, + "velocity": -2.675478196626521, + "acceleration": 0.03599295947188707, + "curvature": -0.41910073501335415, + "holonomicRotation": 0.0, + "angularVelocity": 1.1212523665345682, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.0868172437714714, + "pose": { + "rotation": { + "radians": 2.369528834891101 + }, + "translation": { + "x": 3.652214272000001, + "y": 3.598217727999999 + } + }, + "velocity": -2.675192896457028, + "acceleration": 0.059971215794916974, + "curvature": -0.4191901310989462, + "holonomicRotation": 0.0, + "angularVelocity": 1.1213560140984302, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.0915749346774724, + "pose": { + "rotation": { + "radians": 2.374863900201767 + }, + "translation": { + "x": 3.661379904000001, + "y": 3.5893880959999995 + } + }, + "velocity": -2.674793612656831, + "acceleration": 0.08392386308529144, + "curvature": -0.4193152909022269, + "holonomicRotation": 0.0, + "angularVelocity": 1.121507485349945, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.096333166645051, + "pose": { + "rotation": { + "radians": 2.3802002929704376 + }, + "translation": { + "x": 3.670592000000001, + "y": 3.580607999999999 + } + }, + "velocity": -2.674280481356777, + "acceleration": 0.10784074915852378, + "curvature": -0.4194762197533931, + "holonomicRotation": 0.0, + "angularVelocity": 1.1217067667098233, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.101092074852831, + "pose": { + "rotation": { + "radians": 2.3855383925092557 + }, + "translation": { + "x": 3.679850176000001, + "y": 3.5718778239999995 + } + }, + "velocity": -2.6736536778913917, + "acceleration": 0.13171161073470328, + "curvature": -0.4196729243382305, + "holonomicRotation": 0.0, + "angularVelocity": 1.121953840313771, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.1058517944215147, + "pose": { + "rotation": { + "radians": 2.3908785781581567 + }, + "translation": { + "x": 3.689154048000001, + "y": 3.563197951999999 + } + }, + "velocity": -2.672913416024821, + "acceleration": 0.15552636156154168, + "curvature": -0.4199054128880666, + "holonomicRotation": 0.0, + "angularVelocity": 1.1222486842580777, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.1106124604023675, + "pose": { + "rotation": { + "radians": 2.3962212292913607 + }, + "translation": { + "x": 3.698503232000001, + "y": 3.5545687679999993 + } + }, + "velocity": -2.672059948432254, + "acceleration": 0.17927483171467115, + "curvature": -0.42017369496416906, + "holonomicRotation": 0.0, + "angularVelocity": 1.1225912723143032, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.1153742077653668, + "pose": { + "rotation": { + "radians": 2.40156672532203 + }, + "translation": { + "x": 3.707897344000001, + "y": 3.545990655999999 + } + }, + "velocity": -2.671093566389572, + "acceleration": 0.20294693712460463, + "curvature": -0.42047778147868153, + "holonomicRotation": 0.0, + "angularVelocity": 1.1229815741706488, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.1201371713873365, + "pose": { + "rotation": { + "radians": 2.4069154457079467 + }, + "translation": { + "x": 3.717336000000001, + "y": 3.5374639999999995 + } + }, + "velocity": -2.670014599846641, + "acceleration": 0.22653260208714474, + "curvature": -0.4208176845831703, + "holonomicRotation": 0.0, + "angularVelocity": 1.123419555016309, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.1249014860403035, + "pose": { + "rotation": { + "radians": 2.4122677699553403 + }, + "translation": { + "x": 3.726818816000001, + "y": 3.528989183999999 + } + }, + "velocity": -2.6688234168146687, + "acceleration": 0.2500219063471021, + "curvature": -0.4211934177613582, + "holonomicRotation": 0.0, + "angularVelocity": 1.1239051758329424, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.1296672863796418, + "pose": { + "rotation": { + "radians": 2.4176240776237092 + }, + "translation": { + "x": 3.736345408000001, + "y": 3.5205665919999993 + } + }, + "velocity": -2.6675204238998145, + "acceleration": 0.27340484747103594, + "curvature": -0.42160499554888453, + "holonomicRotation": 0.0, + "angularVelocity": 1.1244383930403559, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.1344347069320158, + "pose": { + "rotation": { + "radians": 2.4229847483285685 + }, + "translation": { + "x": 3.745915392000001, + "y": 3.512196607999999 + } + }, + "velocity": -2.666106065641778, + "acceleration": 0.2966715947331795, + "curvature": -0.42205243361764627, + "holonomicRotation": 0.0, + "angularVelocity": 1.1250191586770815, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.13920388208331, + "pose": { + "rotation": { + "radians": 2.428350161744861 + }, + "translation": { + "x": 3.755528384000001, + "y": 3.5038796159999994 + } + }, + "velocity": -2.6645808247919636, + "acceleration": 0.31981229487879587, + "curvature": -0.4225357485516243, + "holonomicRotation": 0.0, + "angularVelocity": 1.1256474200811772, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.143974946066523, + "pose": { + "rotation": { + "radians": 2.4337206976086065 + }, + "translation": { + "x": 3.765184000000001, + "y": 3.495615999999999 + } + }, + "velocity": -2.6629452216557663, + "acceleration": 0.3428172713575581, + "curvature": -0.4230549579065874, + "holonomicRotation": 0.0, + "angularVelocity": 1.1263231200018886, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.1487480329496336, + "pose": { + "rotation": { + "radians": 2.439096735718832 + }, + "translation": { + "x": 3.7748818560000013, + "y": 3.4874061439999995 + } + }, + "velocity": -2.661199814319626, + "acceleration": 0.3656768416088413, + "curvature": -0.42361007997767014, + "holonomicRotation": 0.0, + "angularVelocity": 1.1270461962946063, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.153523276623142, + "pose": { + "rotation": { + "radians": 2.4444786559374396 + }, + "translation": { + "x": 3.7846215680000013, + "y": 3.4792504319999993 + } + }, + "velocity": -2.659345198296571, + "acceleration": 0.3883814418400827, + "curvature": -0.42420113373878104, + "holonomicRotation": 0.0, + "angularVelocity": 1.1278165820431203, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.1583008107877943, + "pose": { + "rotation": { + "radians": 2.449866838189612 + }, + "translation": { + "x": 3.794402752000001, + "y": 3.4711492479999992 + } + }, + "velocity": -2.6573820061486866, + "acceleration": 0.4109216345137485, + "curvature": -0.42482813877769865, + "holonomicRotation": 0.0, + "angularVelocity": 1.1286342052597576, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.163080768941831, + "pose": { + "rotation": { + "radians": 2.455261662461968 + }, + "translation": { + "x": 3.8042250240000013, + "y": 3.463102975999999 + } + }, + "velocity": -2.6553109078332495, + "acceleration": 0.4332879595793174, + "curvature": -0.4254911149876656, + "holonomicRotation": 0.0, + "angularVelocity": 1.1294989888871036, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.1678632843683197, + "pose": { + "rotation": { + "radians": 2.4606635088005238 + }, + "translation": { + "x": 3.8140880000000013, + "y": 3.4551119999999993 + } + }, + "velocity": -2.6531326096739956, + "acceleration": 0.4554712248682446, + "curvature": -0.42619008268569475, + "holonomicRotation": 0.0, + "angularVelocity": 1.1304108505629107, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.172648490122495, + "pose": { + "rotation": { + "radians": 2.46607275730722 + }, + "translation": { + "x": 3.8239912960000013, + "y": 3.447176703999999 + } + }, + "velocity": -2.650847854754409, + "acceleration": 0.4774622110225031, + "curvature": -0.4269250622640667, + "holonomicRotation": 0.0, + "angularVelocity": 1.1313697026092349, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.1774365190186358, + "pose": { + "rotation": { + "radians": 2.471489788135531 + }, + "translation": { + "x": 3.8339345280000012, + "y": 3.4392974719999994 + } + }, + "velocity": -2.6484574223862847, + "acceleration": 0.49925186751720285, + "curvature": -0.4276960741248228, + "holonomicRotation": 0.0, + "angularVelocity": 1.1323754517286329, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.1822275036170287, + "pose": { + "rotation": { + "radians": 2.476914981484361 + }, + "translation": { + "x": 3.843917312000001, + "y": 3.431474687999999 + } + }, + "velocity": -2.6459621278514356, + "acceleration": 0.5208312578767472, + "curvature": -0.4285031385144863, + "holonomicRotation": 0.0, + "angularVelocity": 1.13342799909027, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.1870215762105563, + "pose": { + "rotation": { + "radians": 2.4823487175915364 + }, + "translation": { + "x": 3.853939264000001, + "y": 3.423708735999999 + } + }, + "velocity": -2.643362822361095, + "acceleration": 0.5421915166345206, + "curvature": -0.42934627527527985, + "holonomicRotation": 0.0, + "angularVelocity": 1.1345272398917918, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.1918188688112803, + "pose": { + "rotation": { + "radians": 2.4877913767247897 + }, + "translation": { + "x": 3.864000000000001, + "y": 3.415999999999999 + } + }, + "velocity": -2.6406603923501453, + "acceleration": 0.5633239903985849, + "curvature": -0.43022550379883, + "holonomicRotation": 0.0, + "angularVelocity": 1.1356730633904046, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.196619513136957, + "pose": { + "rotation": { + "radians": 2.4932433391723787 + }, + "translation": { + "x": 3.874099136000001, + "y": 3.4083488639999993 + } + }, + "velocity": -2.6378557594807597, + "acceleration": 0.5842200919540596, + "curvature": -0.43114084273749304, + "holonomicRotation": 0.0, + "angularVelocity": 1.1368653526407893, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.2014236405971026, + "pose": { + "rotation": { + "radians": 2.4987049852314884 + }, + "translation": { + "x": 3.884236288000001, + "y": 3.400755711999999 + } + }, + "velocity": -2.6349498803219897, + "acceleration": 0.6048713700618353, + "curvature": -0.43209230980706964, + "holonomicRotation": 0.0, + "angularVelocity": 1.1381039843727592, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.2062313822789954, + "pose": { + "rotation": { + "radians": 2.5041766951954854 + }, + "translation": { + "x": 3.8944110720000014, + "y": 3.393220927999999 + } + }, + "velocity": -2.6319437459051516, + "acceleration": 0.6252695372882013, + "curvature": -0.4330799216172504, + "holonomicRotation": 0.0, + "angularVelocity": 1.1393888286909821, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.2110428689336312, + "pose": { + "rotation": { + "radians": 2.509658849339173 + }, + "translation": { + "x": 3.9046231040000015, + "y": 3.385744895999999 + } + }, + "velocity": -2.6288383813504206, + "acceleration": 0.6454064570124066, + "curvature": -0.4341036934661007, + "holonomicRotation": 0.0, + "angularVelocity": 1.1407197490207739, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.2158582309610946, + "pose": { + "rotation": { + "radians": 2.515151827902585 + }, + "translation": { + "x": 3.9148720000000012, + "y": 3.3783279999999993 + } + }, + "velocity": -2.625634845989314, + "acceleration": 0.6652740422913407, + "curvature": -0.43516363895714666, + "holonomicRotation": 0.0, + "angularVelocity": 1.1413686790480242, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.220680672010397, + "pose": { + "rotation": { + "radians": 2.5206560110728145 + }, + "translation": { + "x": 3.9251573760000014, + "y": 3.370970623999999 + } + }, + "velocity": -2.618989404766512, + "acceleration": 1.3780243563087686, + "curvature": -0.4362597700073408, + "holonomicRotation": 0.0, + "angularVelocity": 1.1396328812896521, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.2255206235262626, + "pose": { + "rotation": { + "radians": 2.5261717789641427 + }, + "translation": { + "x": 3.9354788480000007, + "y": 3.3636731519999987 + } + }, + "velocity": -2.604469550218915, + "acceleration": 3.0, + "curvature": -0.437392096408939, + "holonomicRotation": 0.0, + "angularVelocity": 1.1362290451451276, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.2303856044520742, + "pose": { + "rotation": { + "radians": 2.531699511596127 + }, + "translation": { + "x": 3.945836032000001, + "y": 3.356435967999999 + } + }, + "velocity": -2.5898746074414802, + "acceleration": 2.9999999999999085, + "curvature": -0.4385606255617841, + "holonomicRotation": 0.0, + "angularVelocity": 1.1328524486334637, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.235275982964838, + "pose": { + "rotation": { + "radians": 2.537239588869056 + }, + "translation": { + "x": 3.956228544000001, + "y": 3.349259455999999 + } + }, + "velocity": -2.5752034719031878, + "acceleration": 3.0000000000000453, + "curvature": -0.4397653623900097, + "holonomicRotation": 0.0, + "angularVelocity": 1.1295007542704276, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.240192138752052, + "pose": { + "rotation": { + "radians": 2.5427923905388248 + }, + "translation": { + "x": 3.9666560000000013, + "y": 3.342143999999999 + } + }, + "velocity": -2.5604550045415473, + "acceleration": 3.0, + "curvature": -0.4410063087994853, + "holonomicRotation": 0.0, + "angularVelocity": 1.1261715790987796, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.2451344634849657, + "pose": { + "rotation": { + "radians": 2.5483582961877094 + }, + "translation": { + "x": 3.977118016000001, + "y": 3.3350899839999992 + } + }, + "velocity": -2.5456280303428054, + "acceleration": 3.000000000000045, + "curvature": -0.4422834635714009, + "holonomicRotation": 0.0, + "angularVelocity": 1.1228624931603801, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.2501033613157793, + "pose": { + "rotation": { + "radians": 2.553937685194276 + }, + "translation": { + "x": 3.9876142080000014, + "y": 3.328097791999999 + } + }, + "velocity": -2.5307213368503647, + "acceleration": 3.0, + "curvature": -0.4435968219542736, + "holonomicRotation": 0.0, + "angularVelocity": 1.1195710174568347, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.2550992494002617, + "pose": { + "rotation": { + "radians": 2.5595309367001207 + }, + "translation": { + "x": 3.9981441920000007, + "y": 3.321167807999999 + } + }, + "velocity": -2.5157336725969164, + "acceleration": 3.0000000000000444, + "curvature": -0.4449463754713487, + "holonomicRotation": 0.0, + "angularVelocity": 1.1162946221424517, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.260122558447441, + "pose": { + "rotation": { + "radians": 2.565138429574846 + }, + "translation": { + "x": 4.0087075840000015, + "y": 3.314300415999999 + } + }, + "velocity": -2.500663745455379, + "acceleration": 3.0000000000000884, + "curvature": -0.44633211131899053, + "holonomicRotation": 0.0, + "angularVelocity": 1.1130307242685513, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.2651737332980844, + "pose": { + "rotation": { + "radians": 2.570760542377265 + }, + "translation": { + "x": 4.019304000000001, + "y": 3.307495999999999 + } + }, + "velocity": -2.4855102209034485, + "acceleration": 3.000000000000044, + "curvature": -0.4477540124322387, + "holonomicRotation": 0.0, + "angularVelocity": 1.109776686086939, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.2702532335338788, + "pose": { + "rotation": { + "radians": 2.5763976533159223 + }, + "translation": { + "x": 4.029933056000002, + "y": 3.300754943999999 + } + }, + "velocity": -2.470271720196066, + "acceleration": 3.0000000000000435, + "curvature": -0.44921205667481756, + "holonomicRotation": 0.0, + "angularVelocity": 1.1065298124301608, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.2753615341193125, + "pose": { + "rotation": { + "radians": 2.5820501402045597 + }, + "translation": { + "x": 4.040594368000001, + "y": 3.294077631999999 + } + }, + "velocity": -2.4549468184397636, + "acceleration": 2.999999999999913, + "curvature": -0.4507062168508919, + "holonomicRotation": 0.0, + "angularVelocity": 1.103287348927679, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.2804991260784773, + "pose": { + "rotation": { + "radians": 2.5877183804170585 + }, + "translation": { + "x": 4.051287552000002, + "y": 3.2874644479999993 + } + }, + "velocity": -2.43953404256227, + "acceleration": 3.000000000000043, + "curvature": -0.45223646007658325, + "holonomicRotation": 0.0, + "angularVelocity": 1.1000464792593154, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.2856665172091235, + "pose": { + "rotation": { + "radians": 2.5934027508372814 + }, + "translation": { + "x": 4.062012224000001, + "y": 3.280915775999999 + } + }, + "velocity": -2.4240318691703315, + "acceleration": 3.000000000000043, + "curvature": -0.4538027475367534, + "holonomicRotation": 0.0, + "angularVelocity": 1.0968043231891658, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.290864232836559, + "pose": { + "rotation": { + "radians": 2.5991036278081605 + }, + "translation": { + "x": 4.072768000000002, + "y": 3.274431999999999 + } + }, + "velocity": -2.4084387222880252, + "acceleration": 3.0, + "curvature": -0.4554050339448751, + "holonomicRotation": 0.0, + "angularVelocity": 1.0935579336272918, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.2960928166101318, + "pose": { + "rotation": { + "radians": 2.6048213870753862 + }, + "translation": { + "x": 4.0835544960000005, + "y": 3.268013503999999 + } + }, + "velocity": -2.392752970967306, + "acceleration": 3.0000000000000426, + "curvature": -0.45704326729385686, + "holonomicRotation": 0.0, + "angularVelocity": 1.0903042944970165, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.3013528313453175, + "pose": { + "rotation": { + "radians": 2.6105564037302766 + }, + "translation": { + "x": 4.094371328000001, + "y": 3.261660671999999 + } + }, + "velocity": -2.3769729267617494, + "acceleration": 2.999999999999958, + "curvature": -0.45871738815772506, + "holonomicRotation": 0.0, + "angularVelocity": 1.087040317564224, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.30664485991464, + "pose": { + "rotation": { + "radians": 2.616309052146832 + }, + "translation": { + "x": 4.105218112000001, + "y": 3.2553738879999994 + } + }, + "velocity": -2.3610968410537816, + "acceleration": 3.0000000000000417, + "curvature": -0.4604273295453317, + "holonomicRotation": 0.0, + "angularVelocity": 1.0837628401271546, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.31196950619098, + "pose": { + "rotation": { + "radians": 2.622079705917951 + }, + "translation": { + "x": 4.1160944640000015, + "y": 3.2491535359999992 + } + }, + "velocity": -2.345122902224761, + "acceleration": 2.9999999999999165, + "curvature": -0.4621730162746951, + "holonomicRotation": 0.0, + "angularVelocity": 1.0804686217425308, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.3173273960470873, + "pose": { + "rotation": { + "radians": 2.627868737786227 + }, + "translation": { + "x": 4.127000000000001, + "y": 3.2429999999999994 + } + }, + "velocity": -2.3290492326564407, + "acceleration": 2.9999999999999587, + "curvature": -0.4639543644847909, + "holonomicRotation": 0.0, + "angularVelocity": 1.0771543414066895, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.3227191784154804, + "pose": { + "rotation": { + "radians": 2.633676519572262 + }, + "translation": { + "x": 4.137934336000002, + "y": 3.2369136639999994 + } + }, + "velocity": -2.312873885551261, + "acceleration": 2.9999999999999587, + "curvature": -0.4657712811612695, + "holonomicRotation": 0.0, + "angularVelocity": 1.0738165942689333, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.3281455264132758, + "pose": { + "rotation": { + "radians": 2.6395034220985725 + }, + "translation": { + "x": 4.148897088000001, + "y": 3.2308949119999992 + } + }, + "velocity": -2.2965948415578756, + "acceleration": 2.999999999999959, + "curvature": -0.46762366370596037, + "holonomicRotation": 0.0, + "angularVelocity": 1.0704518885397352, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.333607138536903, + "pose": { + "rotation": { + "radians": 2.645349815110781 + }, + "translation": { + "x": 4.159887872000001, + "y": 3.224944127999999 + } + }, + "velocity": -2.280210005186993, + "acceleration": 3.000000000000041, + "curvature": -0.46951139935295344, + "holonomicRotation": 0.0, + "angularVelocity": 1.0670566418128253, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.3391047399321145, + "pose": { + "rotation": { + "radians": 2.651216067193581 + }, + "translation": { + "x": 4.170906304000001, + "y": 3.2190616959999994 + } + }, + "velocity": -2.2637172010013575, + "acceleration": 3.0000000000000404, + "curvature": -0.4714343645997839, + "holonomicRotation": 0.0, + "angularVelocity": 1.0636271776952306, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.344639083745208, + "pose": { + "rotation": { + "radians": 2.6571025456838964 + }, + "translation": { + "x": 4.181952000000002, + "y": 3.213247999999999 + } + }, + "velocity": -2.2471141695620784, + "acceleration": 3.0, + "curvature": -0.4733924247442271, + "holonomicRotation": 0.0, + "angularVelocity": 1.0601597219448258, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.350210952561919, + "pose": { + "rotation": { + "radians": 2.663009616579334 + }, + "translation": { + "x": 4.193024576000001, + "y": 3.207503423999999 + } + }, + "velocity": -2.2303985631119447, + "acceleration": 3.0, + "curvature": -0.47538543332938343, + "holonomicRotation": 0.0, + "angularVelocity": 1.056650398648511, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.3558211599411023, + "pose": { + "rotation": { + "radians": 2.668937644443049 + }, + "translation": { + "x": 4.204123648000001, + "y": 3.2018283519999993 + } + }, + "velocity": -2.213567940974395, + "acceleration": 2.9999999999999605, + "curvature": -0.4774132314234743, + "holonomicRotation": 0.0, + "angularVelocity": 1.0530952259318735, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.361470552050947, + "pose": { + "rotation": { + "radians": 2.6748869923033434 + }, + "translation": { + "x": 4.215248832000001, + "y": 3.1962231679999995 + } + }, + "velocity": -2.1966197646448617, + "acceleration": 2.9999999999999214, + "curvature": -0.4794756472470108, + "holonomicRotation": 0.0, + "angularVelocity": 1.0494901118766216, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.3671600094163034, + "pose": { + "rotation": { + "radians": 2.680858021550229 + }, + "translation": { + "x": 4.226399744000002, + "y": 3.190688255999999 + } + }, + "velocity": -2.1795513925487917, + "acceleration": 2.999999999999961, + "curvature": -0.48157249539387187, + "holonomicRotation": 0.0, + "angularVelocity": 1.0458308498079987, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.37289044878651, + "pose": { + "rotation": { + "radians": 2.6868510918265454 + }, + "translation": { + "x": 4.237576000000001, + "y": 3.185223999999999 + } + }, + "velocity": -2.1623600744381717, + "acceleration": 3.0, + "curvature": -0.4837035763394283, + "holonomicRotation": 0.0, + "angularVelocity": 1.0421131136385364, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.378662825134093, + "pose": { + "rotation": { + "radians": 2.692866560915218 + }, + "translation": { + "x": 4.2487772160000015, + "y": 3.179830783999999 + } + }, + "velocity": -2.1450429453954247, + "acceleration": 3.0, + "curvature": -0.4858686756511655, + "holonomicRotation": 0.0, + "angularVelocity": 1.0383324526569788, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.3844781337957577, + "pose": { + "rotation": { + "radians": 2.698904784620842 + }, + "translation": { + "x": 4.260003008000001, + "y": 3.174508991999999 + } + }, + "velocity": -2.1275970194104294, + "acceleration": 3.000000000000038, + "curvature": -0.48806756354488817, + "holonomicRotation": 0.0, + "angularVelocity": 1.0344842865367634, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.390337412768339, + "pose": { + "rotation": { + "radians": 2.7049661166484125 + }, + "translation": { + "x": 4.271252992000002, + "y": 3.169259007999999 + } + }, + "velocity": -2.1100191824926853, + "acceleration": 3.0000000000000377, + "curvature": -0.49029999405552943, + "holonomicRotation": 0.0, + "angularVelocity": 1.0305638993092536, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.3962417451736586, + "pose": { + "rotation": { + "radians": 2.7110509084748564 + }, + "translation": { + "x": 4.282526784000001, + "y": 3.164081215999999 + } + }, + "velocity": -2.0923061852767266, + "acceleration": 3.000000000000075, + "curvature": -0.49256570453850973, + "holonomicRotation": 0.0, + "angularVelocity": 1.0265664338405436, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.4021922619078344, + "pose": { + "rotation": { + "radians": 2.7171595092181677 + }, + "translation": { + "x": 4.293824000000002, + "y": 3.158975999999999 + } + }, + "velocity": -2.074454635074199, + "acceleration": 3.0000000000000746, + "curvature": -0.4948644147448579, + "holonomicRotation": 0.0, + "angularVelocity": 1.0224868851114455, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.408190144492236, + "pose": { + "rotation": { + "radians": 2.7232922654991567 + }, + "translation": { + "x": 4.305144256000001, + "y": 3.1539437439999993 + } + }, + "velocity": -2.0564609873209942, + "acceleration": 2.999999999999963, + "curvature": -0.49719582643303056, + "holonomicRotation": 0.0, + "angularVelocity": 1.0183200938587098, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.4142366281452663, + "pose": { + "rotation": { + "radians": 2.729449521300226 + }, + "translation": { + "x": 4.316487168000002, + "y": 3.148984831999999 + } + }, + "velocity": -2.0383215363619027, + "acceleration": 3.0, + "curvature": -0.49955962237973184, + "holonomicRotation": 0.0, + "angularVelocity": 1.0140607391716023, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.420333005096303, + "pose": { + "rotation": { + "radians": 2.7356316178174627 + }, + "translation": { + "x": 4.327852352000001, + "y": 3.144099647999999 + } + }, + "velocity": -2.0200324055087933, + "acceleration": 3.0, + "curvature": -0.5019554658535155, + "holonomicRotation": 0.0, + "angularVelocity": 1.0097033310569088, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.4264806281656552, + "pose": { + "rotation": { + "radians": 2.74183889330867 + }, + "translation": { + "x": 4.339239424000002, + "y": 3.1392885759999993 + } + }, + "velocity": -2.001589536300736, + "acceleration": 3.0, + "curvature": -0.5043829997560954, + "holonomicRotation": 0.0, + "angularVelocity": 1.0052422020712786, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.432680914637187, + "pose": { + "rotation": { + "radians": 2.7480716829347855 + }, + "translation": { + "x": 4.350648000000001, + "y": 3.1345519999999993 + } + }, + "velocity": -1.9829886768861407, + "acceleration": 2.999999999999964, + "curvature": -0.5068418460483195, + "holonomicRotation": 0.0, + "angularVelocity": 1.0006714988901686, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.438935350453517, + "pose": { + "rotation": { + "radians": 2.754330318597825 + }, + "translation": { + "x": 4.362077696000002, + "y": 3.129890303999999 + } + }, + "velocity": -1.9642253694371505, + "acceleration": 2.9999999999999645, + "curvature": -0.5093316047891755, + "holonomicRotation": 0.0, + "angularVelocity": 0.9959851725933427, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.445245494767346, + "pose": { + "rotation": { + "radians": 2.760615128771323 + }, + "translation": { + "x": 4.373528128000001, + "y": 3.125303871999999 + } + }, + "velocity": -1.9452949364956633, + "acceleration": 2.999999999999965, + "curvature": -0.5118518535624833, + "holonomicRotation": 0.0, + "angularVelocity": 0.9911769688340359, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.4516129848867214, + "pose": { + "rotation": { + "radians": 2.7669264383269256 + }, + "translation": { + "x": 4.384998912000002, + "y": 3.120793087999999 + } + }, + "velocity": -1.9261924661375385, + "acceleration": 3.000000000000035, + "curvature": -0.5144021466205787, + "holonomicRotation": 0.0, + "angularVelocity": 0.9862404167759408, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.4580395416568392, + "pose": { + "rotation": { + "radians": 2.773264568354321 + }, + "translation": { + "x": 4.3964896640000015, + "y": 3.1163583359999993 + } + }, + "velocity": -1.9069127958271843, + "acceleration": 3.0, + "curvature": -0.5169820141541447, + "holonomicRotation": 0.0, + "angularVelocity": 0.9811688175075026, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.464526975326608, + "pose": { + "rotation": { + "radians": 2.7796298359767464 + }, + "translation": { + "x": 4.408000000000002, + "y": 3.111999999999999 + } + }, + "velocity": -1.8874504948178785, + "acceleration": 2.999999999999966, + "curvature": -0.5195909614569449, + "holonomicRotation": 0.0, + "angularVelocity": 0.9759552310949895, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.4710771919545538, + "pose": { + "rotation": { + "radians": 2.7860225541595955 + }, + "translation": { + "x": 4.4195295360000015, + "y": 3.1077184639999995 + } + }, + "velocity": -1.867799844934041, + "acceleration": 3.0, + "curvature": -0.5222284682600655, + "holonomicRotation": 0.0, + "angularVelocity": 0.9705924628872172, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.4776922004161537, + "pose": { + "rotation": { + "radians": 2.7924430315143596 + }, + "translation": { + "x": 4.431077888000002, + "y": 3.103514111999999 + } + }, + "velocity": -1.847954819549241, + "acceleration": 3.0000000000000338, + "curvature": -0.5248939878051837, + "holonomicRotation": 0.0, + "angularVelocity": 0.9650730483865126, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.4843741200832428, + "pose": { + "rotation": { + "radians": 2.798891572096551 + }, + "translation": { + "x": 4.442644672000001, + "y": 3.0993873279999993 + } + }, + "velocity": -1.8279090605479742, + "acceleration": 3.0000000000000333, + "curvature": -0.527586946160825, + "holonomicRotation": 0.0, + "angularVelocity": 0.9593892367629828, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.4911251892562345, + "pose": { + "rotation": { + "radians": 2.8053684751977617 + }, + "translation": { + "x": 4.454229504000002, + "y": 3.095338495999999 + } + }, + "velocity": -1.8076558530289983, + "acceleration": 3.0, + "curvature": -0.5303067413665304, + "holonomicRotation": 0.0, + "angularVelocity": 0.9535329728703047, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.4979477744415766, + "pose": { + "rotation": { + "radians": 2.8118740351322016 + }, + "translation": { + "x": 4.465832000000002, + "y": 3.0913679999999997 + } + }, + "velocity": -1.787188097472973, + "acceleration": 2.9999999999999676, + "curvature": -0.533052742734141, + "holonomicRotation": 0.0, + "angularVelocity": 0.9474958775078796, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.504844380580635, + "pose": { + "rotation": { + "radians": 2.818408541017755 + }, + "translation": { + "x": 4.477451776000002, + "y": 3.0874762239999995 + } + }, + "velocity": -1.766498279055798, + "acceleration": 3.000000000000032, + "curvature": -0.5358242899805569, + "holonomicRotation": 0.0, + "angularVelocity": 0.9412692255924409, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.5118176623523034, + "pose": { + "rotation": { + "radians": 2.8249722765508114 + }, + "translation": { + "x": 4.489088448000001, + "y": 3.0836635519999995 + } + }, + "velocity": -1.7455784337407918, + "acceleration": 2.999999999999968, + "curvature": -0.53862069246313, + "holonomicRotation": 0.0, + "angularVelocity": 0.9348439222378784, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.518870436690729, + "pose": { + "rotation": { + "radians": 2.831565519776004 + }, + "translation": { + "x": 4.500741632000002, + "y": 3.0799303679999994 + } + }, + "velocity": -1.724420110725515, + "acceleration": 2.9999999999999685, + "curvature": -0.5414412283907459, + "holonomicRotation": 0.0, + "angularVelocity": 0.9282104760898124, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.526005696682038, + "pose": { + "rotation": { + "radians": 2.8381885428495615 + }, + "translation": { + "x": 4.512410944000001, + "y": 3.0762770559999995 + } + }, + "velocity": -1.7030143307515877, + "acceleration": 3.000000000000031, + "curvature": -0.5442851441519826, + "holonomicRotation": 0.0, + "angularVelocity": 0.9213589699954078, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.533226627030828, + "pose": { + "rotation": { + "radians": 2.844841611798131 + }, + "translation": { + "x": 4.524096000000002, + "y": 3.0727039999999994 + } + }, + "velocity": -1.6813515397052183, + "acceleration": 3.0, + "curvature": -0.5471516533835759, + "holonomicRotation": 0.0, + "angularVelocity": 0.9142790279993414, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.5405366213191094, + "pose": { + "rotation": { + "radians": 2.851524986270702 + }, + "translation": { + "x": 4.535796416000001, + "y": 3.0692115839999996 + } + }, + "velocity": -1.6594215568403732, + "acceleration": 3.0, + "curvature": -0.5500399363964437, + "holonomicRotation": 0.0, + "angularVelocity": 0.9069597788904417, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.5479393013188334, + "pose": { + "rotation": { + "radians": 2.858238919286448 + }, + "translation": { + "x": 4.547511808000002, + "y": 3.0658001919999998 + } + }, + "velocity": -1.6372135168412023, + "acceleration": 3.00000000000003, + "curvature": -0.5529491392614659, + "holonomicRotation": 0.0, + "angularVelocity": 0.8993898149607107, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.555438538665241, + "pose": { + "rotation": { + "radians": 2.86498365697578 + }, + "translation": { + "x": 4.559241792000002, + "y": 3.0624702079999992 + } + }, + "velocity": -1.6147158048019792, + "acceleration": 2.9999999999999702, + "curvature": -0.5558783732812413, + "holonomicRotation": 0.0, + "angularVelocity": 0.8915571460679171, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.563038479254261, + "pose": { + "rotation": { + "radians": 2.8717594383176124 + }, + "translation": { + "x": 4.570985984000002, + "y": 3.0592220159999997 + } + }, + "velocity": -1.5919159830349192, + "acceleration": 3.0000000000000293, + "curvature": -0.5588267141256481, + "holonomicRotation": 0.0, + "angularVelocity": 0.883449147335363, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.5707435707950577, + "pose": { + "rotation": { + "radians": 2.87856649486947 + }, + "translation": { + "x": 4.582744000000002, + "y": 3.0560559999999994 + } + }, + "velocity": -1.5688007084125297, + "acceleration": 2.999999999999971, + "curvature": -0.5617932012303778, + "holonomicRotation": 0.0, + "angularVelocity": 0.8750525005400022, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.578558594031973, + "pose": { + "rotation": { + "radians": 2.885405050494711 + }, + "translation": { + "x": 4.594515456000002, + "y": 3.0529725439999993 + } + }, + "velocity": -1.545355638701783, + "acceleration": 3.000000000000057, + "curvature": -0.5647768371119463, + "holonomicRotation": 0.0, + "angularVelocity": 0.866353126952402, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.586488698252195, + "pose": { + "rotation": { + "radians": 2.892275321082959 + }, + "translation": { + "x": 4.606299968000002, + "y": 3.0499720319999994 + } + }, + "velocity": -1.5215653260411162, + "acceleration": 3.000000000000028, + "curvature": -0.5677765867261405, + "holonomicRotation": 0.0, + "angularVelocity": 0.857336111143583, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.594539441821749, + "pose": { + "rotation": { + "radians": 2.899177514266695 + }, + "translation": { + "x": 4.6180971520000025, + "y": 3.0470548479999997 + } + }, + "velocity": -1.4974130953324531, + "acceleration": 3.0000000000000275, + "curvature": -0.5707913768706009, + "holonomicRotation": 0.0, + "angularVelocity": 0.847985613554919, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.602716838649498, + "pose": { + "rotation": { + "radians": 2.9061118291329553 + }, + "translation": { + "x": 4.629906624000001, + "y": 3.0442213759999994 + } + }, + "velocity": -1.472880904849207, + "acceleration": 3.000000000000054, + "curvature": -0.5738200956456002, + "holonomicRotation": 0.0, + "angularVelocity": 0.8382847700393182, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.6110274116755643, + "pose": { + "rotation": { + "radians": 2.9130784559310063 + }, + "translation": { + "x": 4.641728000000002, + "y": 3.0414719999999993 + } + }, + "velocity": -1.4479491857710078, + "acceleration": 3.0, + "curvature": -0.576861591813262, + "holonomicRotation": 0.0, + "angularVelocity": 0.8282155756135112, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.6194782547286612, + "pose": { + "rotation": { + "radians": 2.9200775757746467 + }, + "translation": { + "x": 4.653560896000002, + "y": 3.0388071039999995 + } + }, + "velocity": -1.4225966566117165, + "acceleration": 2.999999999999974, + "curvature": -0.5799146744073892, + "holonomicRotation": 0.0, + "angularVelocity": 0.8177587498553298, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.6280771044120916, + "pose": { + "rotation": { + "radians": 2.9271093603419622 + }, + "translation": { + "x": 4.665404928000002, + "y": 3.0362270719999995 + } + }, + "velocity": -1.3968001075614265, + "acceleration": 3.0000000000000258, + "curvature": -0.5829781121894888, + "holonomicRotation": 0.0, + "angularVelocity": 0.8068935795491445, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.6368324240818266, + "pose": { + "rotation": { + "radians": 2.934173971570372 + }, + "translation": { + "x": 4.6772597120000015, + "y": 3.0337322879999995 + } + }, + "velocity": -1.37053414855222, + "acceleration": 3.0000000000000253, + "curvature": -0.5860506332508155, + "holonomicRotation": 0.0, + "angularVelocity": 0.7955977342736981, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.6457535025016057, + "pose": { + "rotation": { + "radians": 2.941271561348426 + }, + "translation": { + "x": 4.689124864000002, + "y": 3.0313231359999993 + } + }, + "velocity": -1.3437709132928843, + "acceleration": 2.999999999999975, + "curvature": -0.5891309246386679, + "holonomicRotation": 0.0, + "angularVelocity": 0.7838470488110904, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.654850570439635, + "pose": { + "rotation": { + "radians": 2.9484022712044844 + }, + "translation": { + "x": 4.701000000000001, + "y": 3.0289999999999995 + } + }, + "velocity": -1.316479709478796, + "acceleration": 2.9999999999999756, + "curvature": -0.5922176320623127, + "holonomicRotation": 0.0, + "angularVelocity": 0.7716152648033164, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.664134939366228, + "pose": { + "rotation": { + "radians": 2.955566231992309 + }, + "translation": { + "x": 4.712884736000002, + "y": 3.0267632639999995 + } + }, + "velocity": -1.288626602699017, + "acceleration": 3.000000000000024, + "curvature": -0.5953093595736683, + "holonomicRotation": 0.0, + "angularVelocity": 0.7588737220632854, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.673619167601797, + "pose": { + "rotation": { + "radians": 2.962763563574333 + }, + "translation": { + "x": 4.724778688000002, + "y": 3.0246133119999996 + } + }, + "velocity": -1.2601739179923108, + "acceleration": 3.0, + "curvature": -0.5984046693700557, + "holonomicRotation": 0.0, + "angularVelocity": 0.7455909869329629, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.683317260866003, + "pose": { + "rotation": { + "radians": 2.9699943745025603 + }, + "translation": { + "x": 4.736681472000003, + "y": 3.0225505279999996 + } + }, + "velocity": -1.2310796381996918, + "acceleration": 3.0, + "curvature": -0.6015020816536214, + "holonomicRotation": 0.0, + "angularVelocity": 0.731732401397394, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.6932449163600993, + "pose": { + "rotation": { + "radians": 2.9772587616975015 + }, + "translation": { + "x": 4.748592704000002, + "y": 3.0205752959999996 + } + }, + "velocity": -1.201296671717403, + "acceleration": 2.999999999999978, + "curvature": -0.60460007456127, + "holonomicRotation": 0.0, + "angularVelocity": 0.7172595313835017, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.703419822526085, + "pose": { + "rotation": { + "radians": 2.984556810125987 + }, + "translation": { + "x": 4.760512000000002, + "y": 3.0186879999999996 + } + }, + "velocity": -1.1707719532194472, + "acceleration": 3.0, + "curvature": -0.6076970841012796, + "holonomicRotation": 0.0, + "angularVelocity": 0.7021294852003142, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.7138620308453802, + "pose": { + "rotation": { + "radians": 2.9918885924775687 + }, + "translation": { + "x": 4.772438976000002, + "y": 3.0168890239999997 + } + }, + "velocity": -1.1394453282615602, + "acceleration": 3.0, + "curvature": -0.6107915042418585, + "holonomicRotation": 0.0, + "angularVelocity": 0.6862940629818453, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.7245944220466605, + "pose": { + "rotation": { + "radians": 2.999254168840606 + }, + "translation": { + "x": 4.784373248000002, + "y": 3.0151787519999997 + } + }, + "velocity": -1.107248154657719, + "acceleration": 2.999999999999979, + "curvature": -0.6138816870079442, + "holonomicRotation": 0.0, + "angularVelocity": 0.6696986828773126, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.7356432977972824, + "pose": { + "rotation": { + "radians": 3.0066535863780723 + }, + "translation": { + "x": 4.796314432000002, + "y": 3.0135575679999995 + } + }, + "velocity": -1.0741015274058545, + "acceleration": 3.0, + "curvature": -0.6169659427695113, + "holonomicRotation": 0.0, + "angularVelocity": 0.6522810081297855, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.7470391418173126, + "pose": { + "rotation": { + "radians": 3.0140868790039477 + }, + "translation": { + "x": 4.808262144000002, + "y": 3.0120258559999997 + } + }, + "velocity": -1.039913995345763, + "acceleration": 2.9999999999999805, + "curvature": -0.6200425403987194, + "holonomicRotation": 0.0, + "angularVelocity": 0.6339691664026881, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.7588176137867158, + "pose": { + "rotation": { + "radians": 3.0215540670598875 + }, + "translation": { + "x": 4.820216000000001, + "y": 3.0105839999999997 + } + }, + "velocity": -1.004578579437554, + "acceleration": 3.0000000000000187, + "curvature": -0.623109707774154, + "holonomicRotation": 0.0, + "angularVelocity": 0.6146794031013395, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.7710208694945617, + "pose": { + "rotation": { + "radians": 3.0290551569942794 + }, + "translation": { + "x": 4.8321756160000024, + "y": 3.0092323839999997 + } + }, + "velocity": -0.9679688123140158, + "acceleration": 2.9999999999999636, + "curvature": -0.6261656322069277, + "holonomicRotation": 0.0, + "angularVelocity": 0.5943129313748355, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.783699348541738, + "pose": { + "rotation": { + "radians": 3.036590141042181 + }, + "translation": { + "x": 4.844140608000002, + "y": 3.007971392 + } + }, + "velocity": -0.9299333751724882, + "acceleration": 2.999999999999991, + "curvature": -0.6292084609699685, + "holonomicRotation": 0.0, + "angularVelocity": 0.5727516148207152, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.7969142495050097, + "pose": { + "rotation": { + "radians": 3.0441589969085907 + }, + "translation": { + "x": 4.856110592000002, + "y": 3.006801408 + } + }, + "velocity": -0.8902886722826729, + "acceleration": 2.999999999999983, + "curvature": -0.6322363020068372, + "holonomicRotation": 0.0, + "angularVelocity": 0.549851904665754, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.810741046286905, + "pose": { + "rotation": { + "radians": 3.051761687454542 + }, + "translation": { + "x": 4.868085184000002, + "y": 3.0057228159999996 + } + }, + "velocity": -0.8488082819369874, + "acceleration": 2.999999999999984, + "curvature": -0.6352472246674356, + "holonomicRotation": 0.0, + "angularVelocity": 0.5254360802848955, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.8252746369917863, + "pose": { + "rotation": { + "radians": 3.05939816038698 + }, + "translation": { + "x": 4.880064000000003, + "y": 3.004736 + } + }, + "velocity": -0.8052075098223431, + "acceleration": 3.000000000000015, + "curvature": -0.6382392605344301, + "holonomicRotation": 0.0, + "angularVelocity": 0.49927915802747, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.8406371600262545, + "pose": { + "rotation": { + "radians": 3.067068347952807 + }, + "translation": { + "x": 4.8920466560000015, + "y": 3.003841344 + } + }, + "velocity": -0.759119940718938, + "acceleration": 3.0000000000000218, + "curvature": -0.6412104045156426, + "holonomicRotation": 0.0, + "angularVelocity": 0.4710885081646451, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.8569903899445377, + "pose": { + "rotation": { + "radians": 3.0747721666386845 + }, + "translation": { + "x": 4.904032768000002, + "y": 3.003039232 + } + }, + "velocity": -0.7100602509640875, + "acceleration": 3.0000000000000204, + "curvature": -0.6441586157880042, + "holonomicRotation": 0.0, + "angularVelocity": 0.4404704670619436, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.874556494407223, + "pose": { + "rotation": { + "radians": 3.082509516875822 + }, + "translation": { + "x": 4.916021952000001, + "y": 3.0023300479999997 + } + }, + "velocity": -0.6573619375760337, + "acceleration": 2.9999999999999876, + "curvature": -0.6470818190817547, + "holonomicRotation": 0.0, + "angularVelocity": 0.40687199814352293, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.8936552918455964, + "pose": { + "rotation": { + "radians": 3.0902802827517117 + }, + "translation": { + "x": 4.928013824000002, + "y": 3.001714176 + } + }, + "velocity": -0.6000655452609113, + "acceleration": 3.0000000000000115, + "curvature": -0.6499779058913984, + "holonomicRotation": 0.0, + "angularVelocity": 0.3694696536401581, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.9147775921479706, + "pose": { + "rotation": { + "radians": 3.098084331728513 + }, + "translation": { + "x": 4.9400080000000015, + "y": 3.001192 + } + }, + "velocity": -0.5366986443537898, + "acceleration": 3.000000000000016, + "curvature": -0.6528447360474303, + "holonomicRotation": 0.0, + "angularVelocity": 0.3269313584685586, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.938749543564584, + "pose": { + "rotation": { + "radians": 3.105921514370289 + }, + "translation": { + "x": 4.952004096000002, + "y": 3.000763904 + } + }, + "velocity": -0.4647827901039487, + "acceleration": 3.000000000000002, + "curvature": -0.6556801391027219, + "holonomicRotation": 0.0, + "angularVelocity": 0.2768026259312415, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 3.9671818956098828, + "pose": { + "rotation": { + "radians": 3.113791664077829 + }, + "translation": { + "x": 4.964001728000001, + "y": 3.000430272 + } + }, + "velocity": -0.3794857339680527, + "acceleration": 2.999999999999996, + "curvature": -0.6584819160890972, + "holonomicRotation": 0.0, + "angularVelocity": 0.21329879823738962, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 4.004232890837561, + "pose": { + "rotation": { + "radians": 3.1216945968333922 + }, + "translation": { + "x": 4.976000512000002, + "y": 3.000191488 + } + }, + "velocity": -0.26833274828501735, + "acceleration": 2.9999999999999942, + "curvature": -0.6612478412834537, + "holonomicRotation": 0.0, + "angularVelocity": 0.08872022710441509, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 4.0936771402659, + "pose": { + "rotation": { + "radians": 3.1296301109558584 + }, + "translation": { + "x": 4.988000064000001, + "y": 3.000047936 + } + }, + "velocity": 0, + "acceleration": 3.0000000000000058, + "curvature": -0.6612478412834537, + "holonomicRotation": 0.0, + "angularVelocity": 0.0, + "holonomicAngularVelocity": 0.0 + } +] \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/pathplanner/generatedJSON/SamplePath.wpilib.json b/examples/drivebase_only_2026/src/main/deploy/pathplanner/generatedJSON/SamplePath.wpilib.json new file mode 100644 index 0000000..c667a9f --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/pathplanner/generatedJSON/SamplePath.wpilib.json @@ -0,0 +1,9002 @@ +[ + { + "time": 0.0, + "pose": { + "rotation": { + "radians": 0.001033147509964305 + }, + "translation": { + "x": 0.8409049675242211, + "y": 3.593000471715229 + } + }, + "velocity": 0, + "acceleration": 3.0, + "curvature": 0.17278306017897527, + "holonomicRotation": 0.0, + "angularVelocity": 0.0, + "holonomicAngularVelocity": 0.03971136388020405 + }, + { + "time": 0.08947088392615327, + "pose": { + "rotation": { + "radians": 0.001033147509964305 + }, + "translation": { + "x": 0.8529125197216157, + "y": 3.5930128772922965 + } + }, + "velocity": 0.2684126517784598, + "acceleration": 3.0, + "curvature": 0.17278306017897527, + "holonomicRotation": 0.0035530108282749717, + "angularVelocity": 0.05595780204105875, + "holonomicAngularVelocity": 0.2872974144043468 + }, + { + "time": 0.12656996971265755, + "pose": { + "rotation": { + "radians": 0.003109130808309768 + }, + "translation": { + "x": 0.8649348388571431, + "y": 3.593050256375552 + } + }, + "velocity": 0.3797099091379727, + "acceleration": 3.0000000000000013, + "curvature": 0.17384777875567378, + "holonomicRotation": 0.014211482251502705, + "angularVelocity": 0.07339801897523364, + "holonomicAngularVelocity": 0.6233950140939789 + }, + { + "time": 0.15506273677111426, + "pose": { + "rotation": { + "radians": 0.005200443465523286 + }, + "translation": { + "x": 0.8769714187458183, + "y": 3.5931128524930784 + } + }, + "velocity": 0.4651882103133429, + "acceleration": 3.0000000000000018, + "curvature": 0.17493225912360005, + "holonomicRotation": 0.031973731173485787, + "angularVelocity": 0.08763419519836242, + "holonomicAngularVelocity": 1.0341918462716129 + }, + { + "time": 0.17910394502987506, + "pose": { + "rotation": { + "radians": 0.007307275402876012 + }, + "translation": { + "x": 0.8890217532026562, + "y": 3.5932009091729564 + } + }, + "velocity": 0.5373118350896253, + "acceleration": 3.0000000000000013, + "curvature": 0.17603670832924992, + "holonomicRotation": 0.05683695272921396, + "angularVelocity": 0.10012823022338202, + "holonomicAngularVelocity": 1.507684277812072 + }, + { + "time": 0.20030219486832673, + "pose": { + "rotation": { + "radians": 0.009429818643033272 + }, + "translation": { + "x": 0.9010853360426722, + "y": 3.5933146699432683 + } + }, + "velocity": 0.6009065846049804, + "acceleration": 3.0000000000000013, + "curvature": 0.1771613391262139, + "holonomicRotation": 0.08879722072777985, + "angularVelocity": 0.11149423879801537, + "holonomicAngularVelocity": 2.0361034769837696 + }, + { + "time": 0.21948209804419289, + "pose": { + "rotation": { + "radians": 0.011568267347846106 + }, + "translation": { + "x": 0.9131616610808811, + "y": 3.593454378332095 + } + }, + "velocity": 0.6584462941325788, + "acceleration": 3.0, + "curvature": 0.178306370195383, + "holonomicRotation": 0.12784948827237297, + "angularVelocity": 0.1220626987297335, + "holonomicAngularVelocity": 2.6138821118678917 + }, + { + "time": 0.23713327675473306, + "pose": { + "rotation": { + "radians": 0.013722817857015457 + }, + "translation": { + "x": 0.925250222132298, + "y": 3.5936202778675184 + } + }, + "velocity": 0.7113998302641993, + "acceleration": 2.999999999999997, + "curvature": 0.1794720262645367, + "holonomicRotation": 0.17398758855723728, + "angularVelocity": 0.13203637709398355, + "holonomicAngularVelocity": 3.2367646293136128 + }, + { + "time": 0.25357458570945307, + "pose": { + "rotation": { + "radians": 0.015893668726079557 + }, + "translation": { + "x": 0.9373505130119382, + "y": 3.59381261207762 + } + }, + "velocity": 0.7607237571283594, + "acceleration": 3.0000000000000036, + "curvature": 0.18065853783088526, + "holonomicRotation": 0.22720423584149219, + "angularVelocity": 0.14155054256928343, + "holonomicAngularVelocity": 3.901350943412706 + }, + { + "time": 0.2690273844021526, + "pose": { + "rotation": { + "radians": 0.018081020765245093 + }, + "translation": { + "x": 0.9494620275348163, + "y": 3.5940316244904813 + } + }, + "velocity": 0.807082153206458, + "acceleration": 3.0, + "curvature": 0.18186614145581717, + "holonomicRotation": 0.2874910265996222, + "angularVelocity": 0.1507009024564452, + "holonomicAngularVelocity": 4.604835206383188 + }, + { + "time": 0.28365275343935875, + "pose": { + "rotation": { + "radians": 0.020285077077910607 + }, + "translation": { + "x": 0.9615842595159476, + "y": 3.594277558634184 + } + }, + "velocity": 0.8509582603180764, + "acceleration": 3.0, + "curvature": 0.18309507957524826, + "holonomicRotation": 0.3548384408484956, + "angularVelocity": 0.1595582172890896, + "holonomicAngularVelocity": 5.344844021463974 + }, + { + "time": 0.297572224709883, + "pose": { + "rotation": { + "radians": 0.022506043099442152 + }, + "translation": { + "x": 0.9737167027703473, + "y": 3.5945506580368094 + } + }, + "velocity": 0.8927166741296492, + "acceleration": 3.000000000000004, + "curvature": 0.1843456007826043, + "holonomicRotation": 0.42923584365069656, + "angularVelocity": 0.16817663067487754, + "holonomicAngularVelocity": 6.11933015643093 + }, + { + "time": 0.3108801589218642, + "pose": { + "rotation": { + "radians": 0.024744126636456087 + }, + "translation": { + "x": 0.9858588511130302, + "y": 3.59485116622644 + } + }, + "velocity": 0.9326404767655929, + "acceleration": 3.000000000000004, + "curvature": 0.18561795951179086, + "holonomicRotation": 0.5106714867938722, + "angularVelocity": 0.17659873477805743, + "holonomicAngularVelocity": 6.926499439766466 + }, + { + "time": 0.32365154865795415, + "pose": { + "rotation": { + "radians": 0.02699953790520704 + }, + "translation": { + "x": 0.9980101983590115, + "y": 3.595179326731156 + } + }, + "velocity": 0.9709546459738628, + "acceleration": 3.000000000000009, + "curvature": 0.1869124166040281, + "holonomicRotation": 0.5991325106459383, + "angularVelocity": 0.1848588118153447, + "holonomicAngularVelocity": 7.764758597682022 + }, + { + "time": 0.33594715763777777, + "pose": { + "rotation": { + "radians": 0.029272489571763316 + }, + "translation": { + "x": 1.0101702383233062, + "y": 3.59553538307904 + } + }, + "velocity": 1.0078414729133338, + "acceleration": 3.000000000000009, + "curvature": 0.1882292385335524, + "holonomicRotation": 0.6946049461857601, + "angularVelocity": 0.1929849951641493, + "holonomicAngularVelocity": 8.632676895489821 + }, + { + "time": 0.3478170297833208, + "pose": { + "rotation": { + "radians": 0.03156319679037001 + }, + "translation": { + "x": 1.0223384648209295, + "y": 3.595919578798173 + } + }, + "velocity": 1.043451089349963, + "acceleration": 3.0, + "curvature": 0.1895686982557005, + "holonomicRotation": 0.7970737172090075, + "angularVelocity": 0.20100076046015578, + "holonomicAngularVelocity": 9.528957212034914 + }, + { + "time": 0.35930295873278145, + "pose": { + "rotation": { + "radians": 0.03387187724380292 + }, + "translation": { + "x": 1.0345143716668963, + "y": 3.596332157416637 + } + }, + "velocity": 1.0779088761983449, + "acceleration": 3.0, + "curvature": 0.1909310748431833, + "holonomicRotation": 0.9065226427088913, + "angularVelocity": 0.208925983886048, + "holonomicAngularVelocity": 10.452413757552776 + }, + { + "time": 0.3704402710725541, + "pose": { + "rotation": { + "radians": 0.036198751182236144 + }, + "translation": { + "x": 1.0466974526762218, + "y": 3.596773362462513 + } + }, + "velocity": 1.1113208132176626, + "acceleration": 2.99999999999998, + "curvature": 0.1923166534196862, + "holonomicRotation": 1.0229344394312934, + "angularVelocity": 0.21677771226045245, + "holonomicAngularVelocity": 11.401954592092753 + }, + { + "time": 0.38125914288759216, + "pose": { + "rotation": { + "radians": 0.03854404146353918 + }, + "translation": { + "x": 1.058887201663921, + "y": 3.5972434374638835 + } + }, + "velocity": 1.1437774286627767, + "acceleration": 2.99999999999999, + "curvature": 0.19372572545101252, + "holonomicRotation": 1.1462907246040293, + "angularVelocity": 0.22457073506166303, + "holonomicAngularVelocity": 12.376567690501977 + }, + { + "time": 0.39178559072786273, + "pose": { + "rotation": { + "radians": 0.040907973592617 + }, + "translation": { + "x": 1.0710831124450086, + "y": 3.597742625948829 + } + }, + "velocity": 1.1753567721835882, + "acceleration": 2.9999999999999893, + "curvature": 0.1951585886678108, + "holonomicRotation": 1.2765720188396763, + "angularVelocity": 0.23231801754627757, + "holonomicAngularVelocity": 13.375309678614832 + }, + { + "time": 0.4020422302874884, + "pose": { + "rotation": { + "radians": 0.04329077576179596 + }, + "translation": { + "x": 1.0832846788345003, + "y": 3.598271171445432 + } + }, + "velocity": 1.2061266908624655, + "acceleration": 3.0000000000000164, + "curvature": 0.19661554710751872, + "holonomicRotation": 1.4137577492116016, + "angularVelocity": 0.2400310338015318, + "holonomicAngularVelocity": 14.397296615747562 + }, + { + "time": 0.41204886605642116, + "pose": { + "rotation": { + "radians": 0.045692678890288274 + }, + "translation": { + "x": 1.0954913946474107, + "y": 3.5988293174817736 + } + }, + "velocity": 1.2361465981692639, + "acceleration": 3.0000000000000164, + "curvature": 0.19809691103775634, + "holonomicRotation": 1.5578262525026754, + "angularVelocity": 0.2477200268917496, + "holonomicAngularVelocity": 15.441696368515231 + }, + { + "time": 0.4218229558015866, + "pose": { + "rotation": { + "radians": 0.048113916664803025 + }, + "translation": { + "x": 1.1077027536987554, + "y": 3.5994173075859357 + } + }, + "velocity": 1.2654688674047603, + "acceleration": 3.000000000000017, + "curvature": 0.19960299718679397, + "holonomicRotation": 1.7087547786261381, + "angularVelocity": 0.25539421439292753, + "holonomicAngularVelocity": 16.50772223888046 + }, + { + "time": 0.4313799808901459, + "pose": { + "rotation": { + "radians": 0.05055472557922913 + }, + "translation": { + "x": 1.1199182498035485, + "y": 3.600035385285999 + } + }, + "velocity": 1.2941399426704383, + "acceleration": 3.0000000000000058, + "curvature": 0.20113412869661867, + "holonomicRotation": 1.8665194942180874, + "angularVelocity": 0.26306195299790774, + "holonomicAngularVelocity": 17.594627592697993 + }, + { + "time": 0.4407337447772134, + "pose": { + "rotation": { + "radians": 0.05301534497524241 + }, + "translation": { + "x": 1.132137376776806, + "y": 3.6006837941100462 + } + }, + "velocity": 1.3222012343316407, + "acceleration": 2.9999999999999942, + "curvature": 0.20269063507705265, + "holonomicRotation": 2.031095486401067, + "angularVelocity": 0.27073087146300023, + "holonomicAngularVelocity": 18.701701295088498 + }, + { + "time": 0.4498966159841248, + "pose": { + "rotation": { + "radians": 0.05549601708219276 + }, + "translation": { + "x": 1.1443596284335424, + "y": 3.6013627775861585 + } + }, + "velocity": 1.349689847952375, + "acceleration": 3.0, + "curvature": 0.2042728523829029, + "holonomicRotation": 2.202456766718091, + "angularVelocity": 0.2784079792538743, + "holonomicAngularVelocity": 19.828263802885605 + }, + { + "time": 0.458879727682109, + "pose": { + "rotation": { + "radians": 0.057996987057440386 + }, + "translation": { + "x": 1.156584498588773, + "y": 3.602072579242417 + } + }, + "velocity": 1.3766391830463274, + "acceleration": 2.9999999999999813, + "curvature": 0.20588112312325477, + "holonomicRotation": 2.3805762752365096, + "angularVelocity": 0.28609975601445164, + "holonomicAngularVelocity": 20.97366379705548 + }, + { + "time": 0.46769314299062287, + "pose": { + "rotation": { + "radians": 0.06051850302686024 + }, + "translation": { + "x": 1.1688114810575128, + "y": 3.602813442606904 + } + }, + "velocity": 1.403079428971869, + "acceleration": 3.0000000000000124, + "curvature": 0.20751579628291553, + "holonomicRotation": 2.5654258848211016, + "angularVelocity": 0.29381222575858285, + "holonomicAngularVelocity": 22.137275262484405 + }, + { + "time": 0.47634599292284474, + "pose": { + "rotation": { + "radians": 0.06306081612460135 + }, + "translation": { + "x": 1.1810400696547767, + "y": 3.6035856112077007 + } + }, + "velocity": 1.4290379787685348, + "acceleration": 3.000000000000006, + "curvature": 0.2091772275932128, + "holonomicRotation": 2.7569764055756667, + "angularVelocity": 0.30155101908780385, + "holonomicAngularVelocity": 23.318494941239045 + }, + { + "time": 0.48484659231299837, + "pose": { + "rotation": { + "radians": 0.06562418053355934 + }, + "translation": { + "x": 1.1932697581955802, + "y": 3.604389328572888 + } + }, + "velocity": 1.4545397769389956, + "acceleration": 2.9999999999999933, + "curvature": 0.21086577917913393, + "holonomicRotation": 2.955197589452464, + "angularVelocity": 0.30932142554000075, + "holonomicAngularVelocity": 24.516740099768963 + }, + { + "time": 0.49320253787274904, + "pose": { + "rotation": { + "radians": 0.06820885352583606 + }, + "translation": { + "x": 1.2055000404949379, + "y": 3.605224838230549 + } + }, + "velocity": 1.4796076136182474, + "acceleration": 2.99999999999998, + "curvature": 0.2125818197893795, + "holonomicRotation": 3.1600581350286894, + "angularVelocity": 0.3171284377955142, + "holonomicAngularVelocity": 25.731446561727278 + }, + { + "time": 0.5014207916313713, + "pose": { + "rotation": { + "radians": 0.07081509550171505 + }, + "translation": { + "x": 1.217730410367865, + "y": 3.6060923837087637 + } + }, + "velocity": 1.5042623748941144, + "acceleration": 3.0000000000000133, + "curvature": 0.21432572497715796, + "holonomicRotation": 3.371525692449393, + "angularVelocity": 0.32497678982298894, + "holonomicAngularVelocity": 26.962066966824505 + }, + { + "time": 0.5095077523363771, + "pose": { + "rotation": { + "radians": 0.0734431700310525 + }, + "translation": { + "x": 1.2299603616293766, + "y": 3.606992208535615 + } + }, + "velocity": 1.5285232570091318, + "acceleration": 3.0, + "curvature": 0.21609787681652287, + "holonomicRotation": 3.589566868535838, + "angularVelocity": 0.3328709889911717, + "holonomicAngularVelocity": 28.20806922315502 + }, + { + "time": 0.5174693168711992, + "pose": { + "rotation": { + "radians": 0.07609334389167577 + }, + "translation": { + "x": 1.2421893880944879, + "y": 3.6079245562391833 + } + }, + "velocity": 1.5524079506135984, + "acceleration": 3.000000000000028, + "curvature": 0.21789866414830383, + "holonomicRotation": 3.814147232058716, + "angularVelocity": 0.3408153443469722, + "holonomicAngularVelocity": 29.468935125899826 + }, + { + "time": 0.5253109333439094, + "pose": { + "rotation": { + "radians": 0.07876588711005938 + }, + "translation": { + "x": 1.2544169835782135, + "y": 3.6088896703475513 + } + }, + "velocity": 1.575932800031729, + "acceleration": 3.0, + "curvature": 0.21972848239994464, + "holonomicRotation": 4.0452313191752, + "angularVelocity": 0.34881399063156393, + "holonomicAngularVelocity": 30.744159119871735 + }, + { + "time": 0.5330376471866174, + "pose": { + "rotation": { + "radians": 0.08146107300000249 + }, + "translation": { + "x": 1.2666426418955692, + "y": 3.6098877943888 + } + }, + "velocity": 1.5991129415598528, + "acceleration": 3.0, + "curvature": 0.2215877338186406, + "holonomicRotation": 4.282782639029129, + "angularVelocity": 0.35687090951375877, + "holonomicAngularVelocity": 32.03324718691037 + }, + { + "time": 0.5406541413578321, + "pose": { + "rotation": { + "radians": 0.08417917820219012 + }, + "translation": { + "x": 1.2788658568615694, + "y": 3.6109191718910107 + } + }, + "velocity": 1.6219624240734969, + "acceleration": 3.0, + "curvature": 0.22347682738654667, + "holonomicRotation": 4.526763679513311, + "angularVelocity": 0.36498994798864565, + "holonomicAngularVelocity": 33.33571584213352 + }, + { + "time": 0.5481647715439514, + "pose": { + "rotation": { + "radians": 0.08692048272318376 + }, + "translation": { + "x": 1.2910861222912293, + "y": 3.6119840463822657 + } + }, + "velocity": 1.6444943146318547, + "acceleration": 2.9999999999999853, + "curvature": 0.225396178703331, + "holonomicRotation": 4.777135913193135, + "angularVelocity": 0.37317483448183175, + "holonomicAngularVelocity": 34.65109122547071 + }, + { + "time": 0.5555735970994554, + "pose": { + "rotation": { + "radians": 0.08968526997356374 + }, + "translation": { + "x": 1.3033029319995642, + "y": 3.6130826613906457 + } + }, + "velocity": 1.6667207912983668, + "acceleration": 3.0, + "curvature": 0.22734621016862638, + "holonomicRotation": 5.033859803390504, + "angularVelocity": 0.3814291932276495, + "holonomicAngularVelocity": 35.97890827687574 + }, + { + "time": 0.5628844083395413, + "pose": { + "rotation": { + "radians": 0.09247382680670935 + }, + "translation": { + "x": 1.315515779801589, + "y": 3.614215260444233 + } + }, + "velocity": 1.6886532250186246, + "acceleration": 3.0, + "curvature": 0.22932735098729715, + "holonomicRotation": 5.296894810427108, + "angularVelocity": 0.3897565567330589, + "holonomicAngularVelocity": 37.318709985335744 + }, + { + "time": 0.5701007506971646, + "pose": { + "rotation": { + "radians": 0.09528644355622351 + }, + "translation": { + "x": 1.3277241595123186, + "y": 3.615382087071109 + } + }, + "velocity": 1.7103022520914943, + "acceleration": 3.0, + "curvature": 0.2313400369423704, + "holonomicRotation": 5.566199398026144, + "angularVelocity": 0.3981603770417206, + "holonomicAngularVelocity": 38.670046703091636 + }, + { + "time": 0.5772259461736723, + "pose": { + "rotation": { + "radians": 0.09812341407364578 + }, + "translation": { + "x": 1.3399275649467683, + "y": 3.6165833847993554 + } + }, + "velocity": 1.7316778385210174, + "acceleration": 3.0, + "curvature": 0.23338471062629995, + "holonomicRotation": 5.841731039871354, + "angularVelocity": 0.40664403557729134, + "holonomicAngularVelocity": 40.032475517762556 + }, + { + "time": 0.5842631124444932, + "pose": { + "rotation": { + "radians": 0.10098503576504081 + }, + "translation": { + "x": 1.352125489919953, + "y": 3.617819397157053 + } + }, + "velocity": 1.7527893373334802, + "acceleration": 2.999999999999984, + "curvature": 0.23546182136796504, + "holonomicRotation": 6.123446226322418, + "angularVelocity": 0.41521085211936093, + "holonomicAngularVelocity": 41.40555967593165 + }, + { + "time": 0.5912151799256765, + "pose": { + "rotation": { + "radians": 0.10387160962789421 + }, + "translation": { + "x": 1.3643174282468882, + "y": 3.619090367672284 + } + }, + "velocity": 1.7736455397770299, + "acceleration": 2.999999999999984, + "curvature": 0.2375718250628036, + "holonomicRotation": 6.411300471285656, + "angularVelocity": 0.4238640925660133, + "holonomicAngularVelocity": 42.7888680526676 + }, + { + "time": 0.5980849070610476, + "pose": { + "rotation": { + "radians": 0.10678344028630438 + }, + "translation": { + "x": 1.3765028737425884, + "y": 3.62039653987313 + } + }, + "velocity": 1.794254721183143, + "acceleration": 3.0, + "curvature": 0.23971518428892508, + "holonomicRotation": 6.705248319238877, + "angularVelocity": 0.43260697617490873, + "holonomicAngularVelocity": 44.18197466210464 + }, + { + "time": 0.6048748940515513, + "pose": { + "rotation": { + "radians": 0.10972083602653315 + }, + "translation": { + "x": 1.3886813202220687, + "y": 3.621738157287673 + } + }, + "velocity": 1.8146246821546541, + "acceleration": 3.0, + "curvature": 0.24189236838038028, + "holonomicRotation": 7.005243352409332, + "angularVelocity": 0.44144268185248914, + "holonomicAngularVelocity": 45.58445820485198 + }, + { + "time": 0.6115875952164789, + "pose": { + "rotation": { + "radians": 0.11268410883125313 + }, + "translation": { + "x": 1.400852261500344, + "y": 3.6231154634439937 + } + }, + "velocity": 1.834762785649437, + "acceleration": 3.0000000000000164, + "curvature": 0.24410385296432457, + "holonomicRotation": 7.311238198103636, + "angularVelocity": 0.4503743539059442, + "holonomicAngularVelocity": 46.9959016484623 + }, + { + "time": 0.6182253301495848, + "pose": { + "rotation": { + "radians": 0.11567357441314963 + }, + "translation": { + "x": 1.4130151913924303, + "y": 3.6245287018701737 + } + }, + "velocity": 1.8546759904487549, + "acceleration": 3.0, + "curvature": 0.24635012043498902, + "holonomicRotation": 7.623184536188445, + "angularVelocity": 0.45940510725794936, + "holonomicAngularVelocity": 48.415891837714405 + }, + { + "time": 0.6247902938106432, + "pose": { + "rotation": { + "radians": 0.1186895522480027 + }, + "translation": { + "x": 1.4251696037133417, + "y": 3.625978116094295 + } + }, + "velocity": 1.87437088143193, + "acceleration": 2.999999999999983, + "curvature": 0.24863165957534217, + "holonomicRotation": 7.9410331067207744, + "angularVelocity": 0.46853803201309485, + "holonomicAngularVelocity": 49.84401913173306 + }, + { + "time": 0.6312845656740427, + "pose": { + "rotation": { + "radians": 0.1217323656062379 + }, + "translation": { + "x": 1.437314992278094, + "y": 3.6274639496444396 + } + }, + "velocity": 1.8938536970221285, + "acceleration": 3.000000000000017, + "curvature": 0.25094896537060735, + "holonomicRotation": 8.264733717726733, + "angularVelocity": 0.4777761977161289, + "holonomicAngularVelocity": 51.27987706542535 + }, + { + "time": 0.6377101180399395, + "pose": { + "rotation": { + "radians": 0.12480234158384196 + }, + "translation": { + "x": 1.4494508509017014, + "y": 3.628986446048688 + } + }, + "velocity": 1.9131303541198188, + "acceleration": 2.9999999999999827, + "curvature": 0.2533025394819179, + "holonomicRotation": 8.594235253127374, + "angularVelocity": 0.4871226572145231, + "holonomicAngularVelocity": 52.72306203291004 + }, + { + "time": 0.6440688235998314, + "pose": { + "rotation": { + "radians": 0.12789981113262128 + }, + "translation": { + "x": 1.4615766733991795, + "y": 3.6305458488351228 + } + }, + "velocity": 1.9322064707994946, + "acceleration": 3.0, + "curvature": 0.25569288941062784, + "holonomicRotation": 8.929485680810567, + "angularVelocity": 0.49658044992512607, + "holonomicAngularVelocity": 54.1731729909019 + }, + { + "time": 0.6503624623367412, + "pose": { + "rotation": { + "radians": 0.13102510908826215 + }, + "translation": { + "x": 1.4736919535855433, + "y": 3.6321424015318247 + } + }, + "velocity": 1.951087387010224, + "acceleration": 3.0000000000000178, + "curvature": 0.2581205291382108, + "holonomicRotation": 9.270432060847423, + "angularVelocity": 0.5061526051228734, + "holonomicAngularVelocity": 55.62981118023849 + }, + { + "time": 0.6565927278302157, + "pose": { + "rotation": { + "radians": 0.1341785741983914 + }, + "translation": { + "x": 1.4857961852758077, + "y": 3.6337763476668763 + } + }, + "velocity": 1.9697781834906476, + "acceleration": 3.0, + "curvature": 0.2605859783513634, + "holonomicRotation": 9.617020553852164, + "angularVelocity": 0.515842144530513, + "holonomicAngularVelocity": 57.0925798639063 + }, + { + "time": 0.6627612330277614, + "pose": { + "rotation": { + "radians": 0.13736054914804097 + }, + "translation": { + "x": 1.497888862284988, + "y": 3.6354479307683576 + } + }, + "velocity": 1.9882836990832846, + "acceleration": 3.000000000000018, + "curvature": 0.2630897628253225, + "holonomicRotation": 9.96919642948396, + "angularVelocity": 0.5256520850758009, + "holonomicAngularVelocity": 58.56108408011048 + }, + { + "time": 0.6688695155369478, + "pose": { + "rotation": { + "radians": 0.1405713805852269 + }, + "translation": { + "x": 1.5099694784280993, + "y": 3.637157394364352 + } + }, + "velocity": 2.006608546610844, + "acceleration": 3.0, + "curvature": 0.2656324140586707, + "holonomicRotation": 10.326904075089498, + "angularVelocity": 0.535585440834627, + "holonomicAngularVelocity": 60.034930409087174 + }, + { + "time": 0.6749190424860186, + "pose": { + "rotation": { + "radians": 0.14381141914308593 + }, + "translation": { + "x": 1.5220375275201565, + "y": 3.63890498198294 + } + }, + "velocity": 2.0247571274580562, + "acceleration": 2.999999999999963, + "curvature": 0.26821446914236624, + "holonomicRotation": 10.69008700448486, + "angularVelocity": 0.5456452253632049, + "holonomicAngularVelocity": 61.51372675245395 + }, + { + "time": 0.6809112149953159, + "pose": { + "rotation": { + "radians": 0.14708101946233665 + }, + "translation": { + "x": 1.5340925033761743, + "y": 3.640690937152203 + } + }, + "velocity": 2.0427336449859483, + "acceleration": 3.000000000000037, + "curvature": 0.2708364706228389, + "holonomicRotation": 11.05868786687534, + "angularVelocity": 0.5558344532631501, + "holonomicAngularVelocity": 62.99708212405171 + }, + { + "time": 0.6868473722970159, + "pose": { + "rotation": { + "radians": 0.1503805402106111 + }, + "translation": { + "x": 1.5461338998111684, + "y": 3.6425155034002232 + } + }, + "velocity": 2.0605421168910483, + "acceleration": 3.0000000000000187, + "curvature": 0.27349896630261744, + "holonomicRotation": 11.43264845591182, + "angularVelocity": 0.5661561418797494, + "holonomicAngularVelocity": 64.48460645132965 + }, + { + "time": 0.6927287955364773, + "pose": { + "rotation": { + "radians": 0.15371034410062645 + }, + "translation": { + "x": 1.5581612106401537, + "y": 3.6443789242550824 + } + }, + "velocity": 2.078186386609432, + "acceleration": 2.999999999999943, + "curvature": 0.2762025090925794, + "holonomicRotation": 11.811909718882193, + "angularVelocity": 0.5766133126207268, + "holonomicAngularVelocity": 65.9759103863855 + }, + { + "time": 0.698556711284854, + "pose": { + "rotation": { + "radians": 0.15707079790597245 + }, + "translation": { + "x": 1.5701739296781445, + "y": 3.6462814432448614 + } + }, + "velocity": 2.0956701338545622, + "acceleration": 3.0, + "curvature": 0.2789476567183776, + "holonomicRotation": 12.1964117660365, + "angularVelocity": 0.5872089922494581, + "holonomicAngularVelocity": 67.4706051258612 + }, + { + "time": 0.7043322947894155, + "pose": { + "rotation": { + "radians": 0.16046227247533862 + }, + "translation": { + "x": 1.582171550740157, + "y": 3.648223303897642 + } + }, + "velocity": 2.112996884368247, + "acceleration": 3.000000000000019, + "curvature": 0.2817349716179003, + "holonomicRotation": 12.586093880044208, + "angularVelocity": 0.5979462138251876, + "holonomicAngularVelocity": 68.96830223906366 + }, + { + "time": 0.7100566729852058, + "pose": { + "rotation": { + "radians": 0.1638851427440149 + }, + "translation": { + "x": 1.5941535676412057, + "y": 3.6502047497415058 + } + }, + "velocity": 2.1301700189556176, + "acceleration": 2.9999999999999614, + "curvature": 0.28456502063684747, + "holonomicRotation": 12.98089452558218, + "angularVelocity": 0.6088280175906541, + "holonomicAngularVelocity": 70.46861350355422 + }, + { + "time": 0.7157309272892082, + "pose": { + "rotation": { + "radians": 0.1673397877432259 + }, + "translation": { + "x": 1.6061194741963056, + "y": 3.6522260243045346 + } + }, + "velocity": 2.147192781867625, + "acceleration": 3.0000000000000195, + "curvature": 0.2874383746404486, + "holonomicRotation": 13.380751359051802, + "angularVelocity": 0.6198574516656178, + "holonomicAngularVelocity": 71.97115074772233 + }, + { + "time": 0.7213560961959983, + "pose": { + "rotation": { + "radians": 0.17082659060697747 + }, + "translation": { + "x": 1.6180687642204723, + "y": 3.65428737111481 + } + }, + "velocity": 2.164068288587995, + "acceleration": 3.0, + "curvature": 0.2903556083940122, + "holonomicRotation": 13.785601238423792, + "angularVelocity": 0.6310375725674175, + "holonomicAngularVelocity": 73.47552569976867 + }, + { + "time": 0.7269331776919463, + "pose": { + "rotation": { + "radians": 0.17434593857619118 + }, + "translation": { + "x": 1.6300009315287198, + "y": 3.656389033700413 + } + }, + "velocity": 2.1807995330758394, + "acceleration": 3.00000000000002, + "curvature": 0.29331730027060743, + "holonomicRotation": 14.195380233209027, + "angularVelocity": 0.6423714456238293, + "holonomicAngularVelocity": 74.98134984260406 + }, + { + "time": 0.7324631315033312, + "pose": { + "rotation": { + "radians": 0.1778982230002435 + }, + "translation": { + "x": 1.6419154699360639, + "y": 3.6585312555894256 + } + }, + "velocity": 2.197389394509994, + "acceleration": 2.99999999999996, + "curvature": 0.2963240316619205, + "holonomicRotation": 14.610023634553919, + "angularVelocity": 0.6538621451108233, + "holonomicAngularVelocity": 76.48823427430644 + }, + { + "time": 0.7379468811922121, + "pose": { + "rotation": { + "radians": 0.18148383933506596 + }, + "translation": { + "x": 1.6538118732575198, + "y": 3.660714280309929 + } + }, + "velocity": 2.2138406435766362, + "acceleration": 2.9999999999999596, + "curvature": 0.29937638705136754, + "holonomicRotation": 15.029465965458694, + "angularVelocity": 0.665512754437001, + "holonomicAngularVelocity": 77.99578957364865 + }, + { + "time": 0.7433853161125709, + "pose": { + "rotation": { + "radians": 0.1851031871387403 + }, + "translation": { + "x": 1.665689635308102, + "y": 3.662938351390006 + } + }, + "velocity": 2.2301559483377127, + "acceleration": 3.0000000000000204, + "curvature": 0.3024749530991072, + "holonomicRotation": 15.45364099111698, + "angularVelocity": 0.6773263659089981, + "holonomicAngularVelocity": 79.50362567038812 + }, + { + "time": 0.7487792932380414, + "pose": { + "rotation": { + "radians": 0.1887566700629315 + }, + "translation": { + "x": 1.6775482499028262, + "y": 3.665203712357737 + } + }, + "velocity": 2.2463378797141242, + "acceleration": 3.0, + "curvature": 0.30562031875355833, + "holonomicRotation": 15.882481729375025, + "angularVelocity": 0.6893060807149793, + "holonomicAngularVelocity": 81.01135172003737 + }, + { + "time": 0.7541296388714762, + "pose": { + "rotation": { + "radians": 0.19244469584198498 + }, + "translation": { + "x": 1.689387210856707, + "y": 3.6675106067412035 + } + }, + "velocity": 2.262388916614429, + "acceleration": 3.000000000000021, + "curvature": 0.3088130744624381, + "holonomicRotation": 16.31592046130898, + "angularVelocity": 0.7014550083142539, + "holonomicAngularVelocity": 82.51857598273511 + }, + { + "time": 0.7594371502456564, + "pose": { + "rotation": { + "radians": 0.19616767627708853 + }, + "translation": { + "x": 1.7012060119847596, + "y": 3.6698592780684876 + } + }, + "velocity": 2.2783114507369695, + "acceleration": 3.000000000000021, + "curvature": 0.31205381190339315, + "holonomicRotation": 16.753888741918498, + "angularVelocity": 0.7137762660898251, + "holonomicAngularVelocity": 84.02490570606173 + }, + { + "time": 0.7647025970235938, + "pose": { + "rotation": { + "radians": 0.19992602721753938 + }, + "translation": { + "x": 1.7130041471019988, + "y": 3.672249969867671 + } + }, + "velocity": 2.2941077910707817, + "acceleration": 3.0, + "curvature": 0.3153431232712081, + "holonomicRotation": 17.196317410934974, + "angularVelocity": 0.7262729785212538, + "holonomicAngularVelocity": 85.52994701147115 + }, + { + "time": 0.7699267227061208, + "pose": { + "rotation": { + "radians": 0.2037201685371577 + }, + "translation": { + "x": 1.7247811100234403, + "y": 3.674682925666835 + } + }, + "velocity": 2.3097801681183627, + "acceleration": 2.9999999999999787, + "curvature": 0.31868160109621285, + "holonomicRotation": 17.64313660374278, + "angularVelocity": 0.7389482764615447, + "holonomicAngularVelocity": 87.03330478423526 + }, + { + "time": 0.7751102459537709, + "pose": { + "rotation": { + "radians": 0.20755052410700703 + }, + "translation": { + "x": 1.7365363945640986, + "y": 3.6771583889940604 + } + }, + "velocity": 2.3253307378613126, + "acceleration": 2.9999999999999574, + "curvature": 0.32206983737018163, + "holonomicRotation": 18.094275762411673, + "angularVelocity": 0.7518052961123932, + "holonomicAngularVelocity": 88.53458256661038 + }, + { + "time": 0.7802538618293463, + "pose": { + "rotation": { + "radians": 0.21141752176343243 + }, + "translation": { + "x": 1.7482694945389885, + "y": 3.6796766033774304 + } + }, + "velocity": 2.3407615854880386, + "acceleration": 2.999999999999935, + "curvature": 0.32550842300216626, + "holonomicRotation": 18.549663646838734, + "angularVelocity": 0.7648471777350144, + "holonomicAngularVelocity": 90.03338245416519 + }, + { + "time": 0.7853582429670116, + "pose": { + "rotation": { + "radians": 0.21532159327065958 + }, + "translation": { + "x": 1.759979903763126, + "y": 3.6822378123450257 + } + }, + "velocity": 2.3560747289010346, + "acceleration": 3.0000000000000218, + "curvature": 0.3289979473654669, + "holonomicRotation": 19.009228345997983, + "angularVelocity": 0.7780770645594818, + "holonomicAngularVelocity": 91.52930499509503 + }, + { + "time": 0.7904240406732528, + "pose": { + "rotation": { + "radians": 0.21926317427958386 + }, + "translation": { + "x": 1.7716671160515254, + "y": 3.684842259424927 + } + }, + "velocity": 2.371272122019758, + "acceleration": 3.0, + "curvature": 0.332538997417837, + "holonomicRotation": 19.472897289295982, + "angularVelocity": 0.7914981011534582, + "holonomicAngularVelocity": 93.0219490923428 + }, + { + "time": 0.7954518859645968, + "pose": { + "rotation": { + "radians": 0.22324270428057602 + }, + "translation": { + "x": 1.783330625219202, + "y": 3.6874901881452176 + } + }, + "velocity": 2.38635565789379, + "acceleration": 2.999999999999978, + "curvature": 0.33613215718878975, + "holonomicRotation": 19.940597258031563, + "angularVelocity": 0.805113431703494, + "holonomicAngularVelocity": 94.51091190859103 + }, + { + "time": 0.8004423905465707, + "pose": { + "rotation": { + "radians": 0.22726062655050105 + }, + "translation": { + "x": 1.794969925081171, + "y": 3.6901818420339785 + } + }, + "velocity": 2.401327171639712, + "acceleration": 3.000000000000022, + "curvature": 0.33977800684591697, + "holonomicRotation": 20.41225439695792, + "angularVelocity": 0.8189261983273711, + "holonomicAngularVelocity": 95.99578877384728 + }, + { + "time": 0.8053961477380197, + "pose": { + "rotation": { + "radians": 0.23131738809473124 + }, + "translation": { + "x": 1.8065845094524469, + "y": 3.69291746461929 + } + }, + "velocity": 2.4161884432140592, + "acceleration": 3.000000000000067, + "curvature": 0.34347712200275476, + "holonomicRotation": 20.887794225945182, + "angularVelocity": 0.832939539021313, + "holonomicAngularVelocity": 97.47617309569827 + }, + { + "time": 0.8103137333445651, + "pose": { + "rotation": { + "radians": 0.23541343958294503 + }, + "translation": { + "x": 1.8181738721480456, + "y": 3.6956972994292356 + } + }, + "velocity": 2.4309412000336956, + "acceleration": 3.0000000000000226, + "curvature": 0.34723007290001834, + "holonomicRotation": 21.36714165174172, + "angularVelocity": 0.8471565852901716, + "holonomicAngularVelocity": 98.9516562722208 + }, + { + "time": 0.8151957064846765, + "pose": { + "rotation": { + "radians": 0.23954923527780014 + }, + "translation": { + "x": 1.8297375069829815, + "y": 3.6985215899918953 + } + }, + "velocity": 2.44558711945403, + "acceleration": 3.0000000000000226, + "curvature": 0.351037423417464, + "holonomicRotation": 21.850220979832237, + "angularVelocity": 0.8615804600176101, + "holonomicAngularVelocity": 100.42182760730242 + }, + { + "time": 0.8200426103715678, + "pose": { + "rotation": { + "radians": 0.24372523295832904 + }, + "translation": { + "x": 1.8412749077722699, + "y": 3.7013905798353517 + } + }, + "velocity": 2.4601278311147037, + "acceleration": 3.0, + "curvature": 0.3548997302495343, + "holonomicRotation": 22.336955926390793, + "angularVelocity": 0.8762142745937123, + "holonomicAngularVelocity": 101.88627422867015 + }, + { + "time": 0.8248549730538627, + "pose": { + "rotation": { + "radians": 0.24794189383507792 + }, + "translation": { + "x": 1.852785568330926, + "y": 3.704304512487686 + } + }, + "velocity": 2.4745649191615886, + "acceleration": 3.000000000000046, + "curvature": 0.35881754198039423, + "holonomicRotation": 22.82726963032691, + "angularVelocity": 0.8910611263198046, + "holonomicAngularVelocity": 103.34458100839828 + }, + { + "time": 0.8296333081177574, + "pose": { + "rotation": { + "radians": 0.25219968245904534 + }, + "translation": { + "x": 1.8642689824739647, + "y": 3.70726363147698 + } + }, + "velocity": 2.4888999243532726, + "acceleration": 2.999999999999977, + "curvature": 0.3627913978312969, + "holonomicRotation": 23.321084665422845, + "angularVelocity": 0.9061240952935538, + "holonomicAngularVelocity": 104.7963304860019 + }, + { + "time": 0.8343781153531943, + "pose": { + "rotation": { + "radians": 0.2564990666225979 + }, + "translation": { + "x": 1.8757246440164008, + "y": 3.710268180331315 + } + }, + "velocity": 2.5031343460595834, + "acceleration": 3.0000000000000235, + "curvature": 0.36682182668811725, + "holonomicRotation": 23.818323052560064, + "angularVelocity": 0.9214062411363679, + "holonomicAngularVelocity": 106.24110279417981 + }, + { + "time": 0.8390898813863725, + "pose": { + "rotation": { + "radians": 0.2608405172523427 + }, + "translation": { + "x": 1.8871520467732499, + "y": 3.713318402578772 + } + }, + "velocity": 2.5172696441591182, + "acceleration": 3.0000000000000235, + "curvature": 0.37090934612145404, + "holonomicRotation": 24.31890627203308, + "angularVelocity": 0.9369105996727586, + "holonomicAngularVelocity": 107.67847558721752 + }, + { + "time": 0.8437690802807457, + "pose": { + "rotation": { + "radians": 0.265224508294458 + }, + "translation": { + "x": 1.8985506845595264, + "y": 3.716414541747434 + } + }, + "velocity": 2.5313072408422377, + "acceleration": 2.9999999999999765, + "curvature": 0.37505446099249756, + "holonomicRotation": 24.822755275948577, + "angularVelocity": 0.9526401790487136, + "holonomicAngularVelocity": 109.1080239721245 + }, + { + "time": 0.8484161741085013, + "pose": { + "rotation": { + "radians": 0.2696515165905873 + }, + "translation": { + "x": 1.909920051190246, + "y": 3.7195568413653817 + } + }, + "velocity": 2.5452485223255046, + "acceleration": 3.0, + "curvature": 0.37925766213227546, + "holonomicRotation": 25.32979050070805, + "angularVelocity": 0.9685979559362367, + "holonomicAngularVelocity": 110.52932044265238 + }, + { + "time": 0.8530316134943646, + "pose": { + "rotation": { + "radians": 0.27412202174548206 + }, + "translation": { + "x": 1.9212596404804234, + "y": 3.7227455449606963 + } + }, + "velocity": 2.5590948404830947, + "acceleration": 3.000000000000048, + "curvature": 0.3835194253104217, + "holonomicRotation": 25.839931879571772, + "angularVelocity": 0.9847868713264119, + "holonomicAngularVelocity": 111.94193481613654 + }, + { + "time": 0.8576158381334451, + "pose": { + "rotation": { + "radians": 0.2786365059852596 + }, + "translation": { + "x": 1.932568946245074, + "y": 3.7259808960614604 + } + }, + "velocity": 2.5728475144003364, + "acceleration": 3.000000000000073, + "curvature": 0.3878402095521523, + "holonomicRotation": 26.353098855302246, + "angularVelocity": 1.001209825967563, + "holonomicAngularVelocity": 113.34543417355982 + }, + { + "time": 0.8621692772847097, + "pose": { + "rotation": { + "radians": 0.2831954540054511 + }, + "translation": { + "x": 1.9438474622992123, + "y": 3.7292631381957544 + } + }, + "velocity": 2.5865078318541306, + "acceleration": 3.0000000000000733, + "curvature": 0.39222045599243144, + "holonomicRotation": 26.86921039288522, + "angularVelocity": 1.0178696758847163, + "holonomicAngularVelocity": 114.73938280258619 + }, + { + "time": 0.8666923502415655, + "pose": { + "rotation": { + "radians": 0.28779935281004887 + }, + "translation": { + "x": 1.955094682457854, + "y": 3.7325925148916608 + } + }, + "velocity": 2.6000770507246984, + "acceleration": 3.0000000000000737, + "curvature": 0.3966605860226018, + "holonomicRotation": 27.388184992325925, + "angularVelocity": 1.0347692271435858, + "holonomicAngularVelocity": 116.12334214411754 + }, + { + "time": 0.8711854667809218, + "pose": { + "rotation": { + "radians": 0.2924486915389446 + }, + "translation": { + "x": 1.9663101005360133, + "y": 3.7359692696772613 + } + }, + "velocity": 2.613556400342767, + "acceleration": 2.9999999999999507, + "curvature": 0.40116099996983984, + "holonomicRotation": 27.909940701518984, + "angularVelocity": 1.051911230753245, + "holonomicAngularVelocity": 117.49687074220618 + }, + { + "time": 0.8756490275920111, + "pose": { + "rotation": { + "radians": 0.29714396128527953 + }, + "translation": { + "x": 1.977493210348706, + "y": 3.7393936460806363 + } + }, + "velocity": 2.626947082776035, + "acceleration": 2.999999999999975, + "curvature": 0.4057220754674419, + "holonomicRotation": 28.434395129189525, + "angularVelocity": 1.0692983771740423, + "holonomicAngularVelocity": 118.85952419769865 + }, + { + "time": 0.8800834246861603, + "pose": { + "rotation": { + "radians": 0.30188565490179853 + }, + "translation": { + "x": 1.988643505710947, + "y": 3.742865887629869 + } + }, + "velocity": 2.640250274058482, + "acceleration": 2.99999999999995, + "curvature": 0.4103441654649296, + "holonomicRotation": 28.961465457903753, + "angularVelocity": 1.086933290206177, + "holonomicAngularVelocity": 120.2108551257639 + }, + { + "time": 0.8844890417886171, + "pose": { + "rotation": { + "radians": 0.3066742667943605 + }, + "translation": { + "x": 1.9997604804377516, + "y": 3.7463862378530393 + } + }, + "velocity": 2.6534671253658524, + "acceleration": 2.9999999999999747, + "curvature": 0.415027596780641, + "holonomicRotation": 29.491068457146774, + "angularVelocity": 1.1025750395539304, + "holonomicAngularVelocity": 121.30358876060048 + }, + { + "time": 0.8888751613152941, + "pose": { + "rotation": { + "radians": 0.31151029270497466 + }, + "translation": { + "x": 2.010843628344134, + "y": 3.7499549402782297 + } + }, + "velocity": 2.655795659422093, + "acceleration": 0.5308870499488159, + "curvature": 0.4197726679935436, + "holonomicRotation": 30.02312049646564, + "angularVelocity": 1.1129123544597121, + "holonomicAngularVelocity": 121.77867532899292 + }, + { + "time": 0.893263590248079, + "pose": { + "rotation": { + "radians": 0.3163942294809394 + }, + "translation": { + "x": 2.02189244324511, + "y": 3.753572238433522 + } + }, + "velocity": 2.642630372623738, + "acceleration": -3.0, + "curvature": 0.4245796475376652, + "holonomicRotation": 30.557537558675612, + "angularVelocity": 1.1200604476801486, + "holonomicAngularVelocity": 121.875865767175 + }, + { + "time": 0.8976672323561652, + "pose": { + "rotation": { + "radians": 0.3213265748319456 + }, + "translation": { + "x": 2.032906418955695, + "y": 3.757238375846997 + } + }, + "velocity": 2.6294194462994795, + "acceleration": -3.0, + "curvature": 0.42944877184255026, + "holonomicRotation": 31.094235253127405, + "angularVelocity": 1.1272248224221166, + "holonomicAngularVelocity": 121.94809376065527 + }, + { + "time": 0.9020862729437429, + "pose": { + "rotation": { + "radians": 0.326307827073554 + }, + "translation": { + "x": 2.043885049290903, + "y": 3.760953596046737 + } + }, + "velocity": 2.6161623245367465, + "acceleration": -3.0, + "curvature": 0.4343802430219193, + "holonomicRotation": 31.63312882903347, + "angularVelocity": 1.1344026062952288, + "holonomicAngularVelocity": 121.99532988592229 + }, + { + "time": 0.9065209046654943, + "pose": { + "rotation": { + "radians": 0.3313384848566683 + }, + "translation": { + "x": 2.0548278280657497, + "y": 3.7647181425608234 + } + }, + "velocity": 2.602858429371492, + "acceleration": -3.00000000000005, + "curvature": 0.43937422680447413, + "holonomicRotation": 32.17413318885111, + "angularVelocity": 1.1415907828044285, + "holonomicAngularVelocity": 122.01754683195679 + }, + { + "time": 0.91097132779699, + "pose": { + "rotation": { + "radians": 0.3364190468831634 + }, + "translation": { + "x": 2.06573424909525, + "y": 3.7685322589173373 + } + }, + "velocity": 2.589507159977005, + "acceleration": -2.9999999999999503, + "curvature": 0.4444308503282336, + "holonomicRotation": 32.71716290172041, + "angularVelocity": 1.1487861865184061, + "holonomicAngularVelocity": 122.01471948451228 + }, + { + "time": 0.9154377505166148, + "pose": { + "rotation": { + "radians": 0.34155001160662035 + }, + "translation": { + "x": 2.076603806194419, + "y": 3.772396188644361 + } + }, + "velocity": 2.576107891818131, + "acceleration": -2.999999999999975, + "curvature": 0.4495501996821507, + "holonomicRotation": 33.26213221695468, + "angularVelocity": 1.1559854981829414, + "holonomicAngularVelocity": 121.98682501486593 + }, + { + "time": 0.9199203891996058, + "pose": { + "rotation": { + "radians": 0.34673187691775187 + }, + "translation": { + "x": 2.0874359931782718, + "y": 3.7763101752699755 + } + }, + "velocity": 2.562659975769158, + "acceleration": -2.9999999999999503, + "curvature": 0.4547323176058648, + "holonomicRotation": 33.80895507758158, + "angularVelocity": 1.1631852399490095, + "holonomicAngularVelocity": 121.93384297290179 + }, + { + "time": 0.9244194687248265, + "pose": { + "rotation": { + "radians": 0.35196513981484534 + }, + "translation": { + "x": 2.0982303038618237, + "y": 3.7802744623222626 + } + }, + "velocity": 2.549162737193496, + "acceleration": -3.0, + "curvature": 0.45997720094103783, + "holonomicRotation": 34.35754513393243, + "angularVelocity": 1.1703817702780115, + "holonomicAngularVelocity": 121.8557553849208 + }, + { + "time": 0.9289352227949338, + "pose": { + "rotation": { + "radians": 0.35725029605755765 + }, + "translation": { + "x": 2.108986232060089, + "y": 3.7842892933293037 + } + }, + "velocity": 2.535615474983174, + "acceleration": -3.0, + "curvature": 0.46528479796284883, + "holonomicRotation": 34.90781575727789, + "angularVelocity": 1.1775712790493746, + "holonomicAngularVelocity": 121.75254685600395 + }, + { + "time": 0.9334678942706475, + "pose": { + "rotation": { + "radians": 0.3625878398047244 + }, + "translation": { + "x": 2.1197032715880835, + "y": 3.788354911819181 + } + }, + "velocity": 2.5220174605560333, + "acceleration": -2.999999999999951, + "curvature": 0.4706550059298928, + "holonomicRotation": 35.45968005350759, + "angularVelocity": 1.1847497824518636, + "holonomicAngularVelocity": 121.6242046774087 + }, + { + "time": 0.9380177355198616, + "pose": { + "rotation": { + "radians": 0.36797826323492133 + }, + "translation": { + "x": 2.130380916260822, + "y": 3.792471561319975 + } + }, + "velocity": 2.508367936808391, + "acceleration": -2.9999999999999756, + "curvature": 0.47608766817867815, + "holonomicRotation": 36.01305087685172, + "angularVelocity": 1.191913118109341, + "holonomicAngularVelocity": 121.47071893885429 + }, + { + "time": 0.9425850087823997, + "pose": { + "rotation": { + "radians": 0.3734220561505306 + }, + "translation": { + "x": 2.14101865989332, + "y": 3.7966394853597683 + } + }, + "velocity": 2.4946661170207767, + "acceleration": -3.0, + "curvature": 0.4815825712862567, + "holonomicRotation": 36.567840843642436, + "angularVelocity": 1.1990569397193662, + "holonomicAngularVelocity": 121.29208264592796 + }, + { + "time": 0.9471699865512587, + "pose": { + "rotation": { + "radians": 0.37891970556274 + }, + "translation": { + "x": 2.1516159963005914, + "y": 3.8008589274666416 + } + }, + "velocity": 2.4809111837141997, + "acceleration": -2.9999999999999756, + "curvature": 0.4871394423167028, + "holonomicRotation": 37.12396234611263, + "angularVelocity": 1.2061767123340414, + "holonomicAngularVelocity": 121.08829184271038 + }, + { + "time": 0.9517729519712488, + "pose": { + "rotation": { + "radians": 0.3844716952600109 + }, + "translation": { + "x": 2.162172419297652, + "y": 3.805130131168677 + } + }, + "velocity": 2.4671022874542294, + "acceleration": -3.000000000000024, + "curvature": 0.4927579457268436, + "holonomicRotation": 37.68132756623029, + "angularVelocity": 1.21326770704613, + "holonomicAngularVelocity": 120.85934573977968 + }, + { + "time": 0.9563941992559911, + "pose": { + "rotation": { + "radians": 0.3900785053568634 + }, + "translation": { + "x": 2.1726874226995174, + "y": 3.8094533399939565 + } + }, + "velocity": 2.4532385456000023, + "acceleration": -3.000000000000024, + "curvature": 0.4984376803646599, + "holonomicRotation": 38.23984848956598, + "angularVelocity": 1.220324996056866, + "holonomicAngularVelocity": 120.60524684760273 + }, + { + "time": 0.961034034124307, + "pose": { + "rotation": { + "radians": 0.39574061182424547 + }, + "translation": { + "x": 2.183160500321202, + "y": 3.8138287974705607 + } + }, + "velocity": 2.4393190409950547, + "acceleration": -3.0, + "curvature": 0.5041781763296166, + "holonomicRotation": 38.79943691919133, + "angularVelocity": 1.2273594995345545, + "holonomicAngularVelocity": 120.32757479526596 + }, + { + "time": 0.9656927133287107, + "pose": { + "rotation": { + "radians": 0.4014584860010544 + }, + "translation": { + "x": 2.1935911459777206, + "y": 3.818256747126572 + } + }, + "velocity": 2.425406442924914, + "acceleration": -2.986382504506831, + "curvature": 0.5099788918334808, + "holonomicRotation": 39.36000448960636, + "angularVelocity": 1.2344056650303263, + "holonomicAngularVelocity": 120.03016944871452 + }, + { + "time": 0.9703703555720377, + "pose": { + "rotation": { + "radians": 0.4072325940852024 + }, + "translation": { + "x": 2.2039788534840885, + "y": 3.8227374324900714 + } + }, + "velocity": 2.411589876401709, + "acceleration": -2.9537458840326973, + "curvature": 0.515839209876031, + "holonomicRotation": 39.92146268069337, + "angularVelocity": 1.2414839156218722, + "holonomicAngularVelocity": 119.71541334139856 + }, + { + "time": 0.9750669951718074, + "pose": { + "rotation": { + "radians": 0.4130633966057893 + }, + "translation": { + "x": 2.214323116655321, + "y": 3.827271097089141 + } + }, + "velocity": 2.3978714010210127, + "acceleration": -2.9209129398323563, + "curvature": 0.5217584349674527, + "holonomicRotation": 40.48372283169538, + "angularVelocity": 1.248592889108532, + "holonomicAngularVelocity": 119.38354385696823 + }, + { + "time": 0.979782664562521, + "pose": { + "rotation": { + "radians": 0.4189513478744211 + }, + "translation": { + "x": 2.2246234293064333, + "y": 3.8318579844518617 + } + }, + "velocity": 2.38425308569492, + "acceleration": -2.887885938931768, + "curvature": 0.5277357897683702, + "holonomicRotation": 41.04669615521661, + "angularVelocity": 1.2557311548634056, + "holonomicAngularVelocity": 119.03479959258911 + }, + { + "time": 0.9845173942210365, + "pose": { + "rotation": { + "radians": 0.4248968954164747 + }, + "translation": { + "x": 2.23487928525244, + "y": 3.836498338106315 + } + }, + "velocity": 2.370737008561894, + "acceleration": -2.854667131568365, + "curvature": 0.5337704117079999, + "holonomicRotation": 41.61029375124308, + "angularVelocity": 1.2628972121620219, + "holonomicAngularVelocity": 118.6694202733467 + }, + { + "time": 0.989271212590069, + "pose": { + "rotation": { + "radians": 0.4309004793818505 + }, + "translation": { + "x": 2.2450901783083568, + "y": 3.8411924015805843 + } + }, + "velocity": 2.3573252573892143, + "acceleration": -2.821258645481045, + "curvature": 0.5398613493301961, + "holonomicRotation": 42.174426621180956, + "angularVelocity": 1.2700894881479043, + "holonomicAngularVelocity": 118.2876466477837 + }, + { + "time": 0.9940441460005254, + "pose": { + "rotation": { + "radians": 0.43696253193410106 + }, + "translation": { + "x": 2.2552556022891976, + "y": 3.8459404184027486 + } + }, + "velocity": 2.3440199287650296, + "acceleration": -2.787662739026658, + "curvature": 0.5460075591396993, + "holonomicRotation": 42.73900568191042, + "angularVelocity": 1.2773063364563315, + "holonomicAngularVelocity": 117.88972039477449 + }, + { + "time": 0.9988362185921881, + "pose": { + "rotation": { + "radians": 0.44308347662019054 + }, + "translation": { + "x": 2.2653750510099786, + "y": 3.8507426321008915 + } + }, + "velocity": 2.3308231289954664, + "acceleration": -2.7538814400522993, + "curvature": 0.5522079016400215, + "holonomicRotation": 43.303941779853, + "angularVelocity": 1.2845460351181257, + "holonomicAngularVelocity": 117.47588402985137 + }, + { + "time": 1.0036474522327303, + "pose": { + "rotation": { + "radians": 0.44926372771717604 + }, + "translation": { + "x": 2.275448018285714, + "y": 3.855599286203093 + } + }, + "velocity": 2.3177369733019524, + "acceleration": -2.71991690098823, + "curvature": 0.5584611381164556, + "holonomicRotation": 43.86914570504986, + "angularVelocity": 1.2918067851196746, + "holonomicAngularVelocity": 117.04638079070317 + }, + { + "time": 1.0084778664358856, + "pose": { + "rotation": { + "radians": 0.4555036895597504 + }, + "translation": { + "x": 2.28547399793142, + "y": 3.8605106242374356 + } + }, + "velocity": 2.3047635859336775, + "acceleration": -2.6857712035958974, + "curvature": 0.5647659269857161, + "holonomicRotation": 44.43452820524919, + "angularVelocity": 1.2990867085650026, + "holonomicAngularVelocity": 116.6014545495639 + }, + { + "time": 1.013327478277653, + "pose": { + "rotation": { + "radians": 0.4618037558450898 + }, + "translation": { + "x": 2.2954524837621104, + "y": 3.865476889732001 + } + }, + "velocity": 2.291905100460139, + "acceleration": -2.6514463204651553, + "curvature": 0.5711208200358487, + "holonomicRotation": 45.00000000000005, + "angularVelocity": 1.3063838471897808, + "holonomicAngularVelocity": 116.14134970547647 + }, + { + "time": 1.0181963023113398, + "pose": { + "rotation": { + "radians": 0.4681643089175078 + }, + "translation": { + "x": 2.305382969592801, + "y": 3.87049832621487 + } + }, + "velocity": 2.279163659116622, + "acceleration": -2.6169443083915382, + "curvature": 0.577524259126085, + "holonomicRotation": 45.56547179475091, + "angularVelocity": 1.3136961607432687, + "holonomicAngularVelocity": 115.66631107512583 + }, + { + "time": 1.0230843504814946, + "pose": { + "rotation": { + "radians": 0.4745857190321683 + }, + "translation": { + "x": 2.3152649492385065, + "y": 3.8755751772141256 + } + }, + "velocity": 2.2665414130747012, + "acceleration": -2.582267114098703, + "curvature": 0.5839745724478352, + "holonomicRotation": 46.13085429495023, + "angularVelocity": 1.3210215253598987, + "holonomicAngularVelocity": 115.17658379068665 + }, + { + "time": 1.027991632036433, + "pose": { + "rotation": { + "radians": 0.4810683435972436 + }, + "translation": { + "x": 2.3250979165142422, + "y": 3.8807076862578476 + } + }, + "velocity": 2.254040522088207, + "acceleration": -2.5474167003753343, + "curvature": 0.5904699711152717, + "holonomicRotation": 46.696058220147094, + "angularVelocity": 1.328357732343505, + "holonomicAngularVelocity": 114.67241318996534 + }, + { + "time": 1.032918153439682, + "pose": { + "rotation": { + "radians": 0.4876125263968052 + }, + "translation": { + "x": 2.334881365235023, + "y": 3.8858960968741183 + } + }, + "velocity": 2.2416631544886365, + "acceleration": -2.512394971309341, + "curvature": 0.5970085456160249, + "holonomicRotation": 47.26099431808967, + "angularVelocity": 1.3357024865477265, + "holonomicAngularVelocity": 114.15404470903117 + }, + { + "time": 1.0378639182802407, + "pose": { + "rotation": { + "radians": 0.4942185967922197 + }, + "translation": { + "x": 2.344614789215864, + "y": 3.8911406525910204 + } + }, + "velocity": 2.2294114869513537, + "acceleration": -2.477203816245118, + "curvature": 0.6035882624271405, + "holonomicRotation": 47.82557337881916, + "angularVelocity": 1.3430534051522829, + "holonomicAngularVelocity": 113.62172376696698 + }, + { + "time": 1.0428289271820144, + "pose": { + "rotation": { + "radians": 0.5008868689043582 + }, + "translation": { + "x": 2.3542976822717803, + "y": 3.8964415969366333 + } + }, + "velocity": 2.2172877042031023, + "acceleration": -2.441845118126668, + "curvature": 0.6102069607302846, + "holonomicRotation": 48.389706248757015, + "angularVelocity": 1.3504080166046994, + "holonomicAngularVelocity": 113.07569565838182 + }, + { + "time": 1.0478131777121122, + "pose": { + "rotation": { + "radians": 0.5076176407769686 + }, + "translation": { + "x": 2.3639295382177874, + "y": 3.9017991734390405 + } + }, + "velocity": 2.2052939991133176, + "acceleration": -2.4063206729596667, + "curvature": 0.6168623489972463, + "holonomicRotation": 48.95330384478349, + "angularVelocity": 1.3577637592114598, + "holonomicAngularVelocity": 112.51620543704176 + }, + { + "time": 1.0528166642884191, + "pose": { + "rotation": { + "radians": 0.5144111935199791 + }, + "translation": { + "x": 2.3735098508688997, + "y": 3.9072136256263224 + } + }, + "velocity": 2.1934325720653676, + "acceleration": -2.37063233148614, + "curvature": 0.6235520020647222, + "holonomicRotation": 49.51627716830472, + "angularVelocity": 1.3651179803976707, + "holonomicAngularVelocity": 111.94349779995073 + }, + { + "time": 1.057839378086471, + "pose": { + "rotation": { + "radians": 0.5212677904360912 + }, + "translation": { + "x": 2.383038114040132, + "y": 3.912685197026561 + } + }, + "velocity": 2.1817056310849785, + "acceleration": -2.3347818434204934, + "curvature": 0.6302733579072911, + "holonomicRotation": 50.07853731930672, + "angularVelocity": 1.37246793566263, + "holonomicAngularVelocity": 111.3578169758298 + }, + { + "time": 1.062881306945483, + "pose": { + "rotation": { + "radians": 0.5281876761289772 + }, + "translation": { + "x": 2.3925138215465003, + "y": 3.9182141311678382 + } + }, + "velocity": 2.1701153913885043, + "acceleration": -2.298770970510162, + "curvature": 0.6370237148626468, + "holonomicRotation": 50.63999551039373, + "angularVelocity": 1.3798107878877686, + "holonomicAngularVelocity": 110.75940660188803 + }, + { + "time": 1.0679424352741127, + "pose": { + "rotation": { + "radians": 0.5351710755957049 + }, + "translation": { + "x": 2.401936467203019, + "y": 3.923800671578235 + } + }, + "velocity": 2.1586640750615573, + "acceleration": -2.262601456313476, + "curvature": 0.6438002289410851, + "holonomicRotation": 51.20056308080876, + "angularVelocity": 1.3871436066633136, + "holonomicAngularVelocity": 110.14850960775404 + }, + { + "time": 1.0730227439557107, + "pose": { + "rotation": { + "radians": 0.5422181933032597 + }, + "translation": { + "x": 2.411305544824703, + "y": 3.9294450617858336 + } + }, + "velocity": 2.1473539108942203, + "acceleration": -2.2262749915777413, + "curvature": 0.6505999112142703, + "holonomicRotation": 51.76015151043412, + "angularVelocity": 1.394463367787446, + "holonomicAngularVelocity": 109.5253680946616 + }, + { + "time": 1.0781222102533539, + "pose": { + "rotation": { + "radians": 0.5493292122505897 + }, + "translation": { + "x": 2.4206205482265686, + "y": 3.935147545318714 + } + }, + "velocity": 2.1361871338676965, + "acceleration": -2.189793279285885, + "curvature": 0.6574196256038366, + "holonomicRotation": 52.318672433769805, + "angularVelocity": 1.4017669531365187, + "holonomicAngularVelocity": 108.89022321711077 + }, + { + "time": 1.0832408077146372, + "pose": { + "rotation": { + "radians": 0.5565042930182251 + }, + "translation": { + "x": 2.4298809712236293, + "y": 3.94090836570496 + } + }, + "velocity": 2.125165985087164, + "acceleration": -2.153157942951349, + "curvature": 0.6642560866170671, + "holonomicRotation": 52.87603765388748, + "angularVelocity": 1.4090511501061669, + "holonomicAngularVelocity": 108.24331505807763 + }, + { + "time": 1.0883785060766265, + "pose": { + "rotation": { + "radians": 0.5637435728040847 + }, + "translation": { + "x": 2.439086307630901, + "y": 3.946727766472652 + } + }, + "velocity": 2.1142927110054988, + "acceleration": -2.116370661639031, + "curvature": 0.671105857754649, + "holonomicRotation": 53.432159156357656, + "angularVelocity": 1.4163126520875524, + "holonomicAngularVelocity": 107.58488250693321 + }, + { + "time": 1.0935352711709692, + "pose": { + "rotation": { + "radians": 0.5710471644510458 + }, + "translation": { + "x": 2.448236051263399, + "y": 3.952605991149871 + } + }, + "velocity": 2.1035695634481897, + "acceleration": -2.079433009091889, + "curvature": 0.6779653496872295, + "holonomicRotation": 53.98694912314837, + "angularVelocity": 1.4235480584824276, + "holonomicAngularVelocity": 106.9151631380171 + }, + { + "time": 1.098711064829253, + "pose": { + "rotation": { + "radians": 0.5784151554644015 + }, + "translation": { + "x": 2.4573296959361373, + "y": 3.9585432832647 + } + }, + "velocity": 2.092998798846448, + "acceleration": -2.0423466041431677, + "curvature": 0.684830819211508, + "holonomicRotation": 54.54031994649251, + "angularVelocity": 1.4307538750320115, + "holonomicAngularVelocity": 106.23439308674577 + }, + { + "time": 1.1039058447888757, + "pose": { + "rotation": { + "radians": 0.5858476070215701 + }, + "translation": { + "x": 2.466366735464131, + "y": 3.96453988634522 + } + }, + "velocity": 2.0825826781433334, + "acceleration": -2.005112975732495, + "curvature": 0.6916983680903239, + "holonomicRotation": 55.092184242722205, + "angularVelocity": 1.4379265145967277, + "holonomicAngularVelocity": 105.54280692289525 + }, + { + "time": 1.1091195645997147, + "pose": { + "rotation": { + "radians": 0.5933445529772539 + }, + "translation": { + "x": 2.475346663662397, + "y": 3.970596043919512 + } + }, + "velocity": 2.0723234658855545, + "acceleration": -1.9677337160409976, + "curvature": 0.6985639427568586, + "holonomicRotation": 55.642454866067666, + "angularVelocity": 1.4450622981042924, + "holonomicAngularVelocity": 104.84063752676244 + }, + { + "time": 1.114352173531636, + "pose": { + "rotation": { + "radians": 0.600905998865497 + }, + "translation": { + "x": 2.484268974345949, + "y": 3.9767119995156586 + } + }, + "velocity": 2.062223430211611, + "acceleration": -1.9302103033782358, + "curvature": 0.7054233337930159, + "holonomicRotation": 56.19104492241852, + "angularVelocity": 1.4521574553278018, + "holonomicAngularVelocity": 104.128115966359 + }, + { + "time": 1.1196036164829668, + "pose": { + "rotation": { + "radians": 0.6085319208985007 + }, + "translation": { + "x": 2.4931331613298013, + "y": 3.9828879966617396 + } + }, + "velocity": 2.052284841943108, + "acceleration": -1.8925442703294657, + "curvature": 0.7122721763885163, + "holonomicRotation": 56.73786778304542, + "angularVelocity": 1.4592081266024142, + "holonomicAngularVelocity": 103.40547136831155 + }, + { + "time": 1.1248738338904498, + "pose": { + "rotation": { + "radians": 0.6162222649684614 + }, + "translation": { + "x": 2.501938718428971, + "y": 3.9891242788858388 + } + }, + "velocity": 2.042509974283066, + "acceleration": -1.8547370827933478, + "curvature": 0.7191059508084997, + "holonomicRotation": 57.28283709827968, + "angularVelocity": 1.4662103641391377, + "holonomicAngularVelocity": 102.6729307941759 + }, + { + "time": 1.1301627616406267, + "pose": { + "rotation": { + "radians": 0.6239769456509539 + }, + "translation": { + "x": 2.510685139458471, + "y": 3.9954210897160363 + } + }, + "velocity": 2.0329011020603422, + "acceleration": -1.8167902222530004, + "curvature": 0.7259199836089303, + "holonomicRotation": 57.825866811148984, + "angularVelocity": 1.4731601340928637, + "holonomicAngularVelocity": 101.93071911786525 + }, + { + "time": 1.1354703309828194, + "pose": { + "rotation": { + "radians": 0.6317958452148056 + }, + "translation": { + "x": 2.519371918233318, + "y": 4.001778672680414 + } + }, + "velocity": 2.023460501427057, + "acceleration": -1.7787050954260963, + "curvature": 0.7327094489985542, + "holonomicRotation": 58.36687117096662, + "angularVelocity": 1.4800533186565177, + "holonomicAngularVelocity": 101.17905889902231 + }, + { + "time": 1.1407964684441678, + "pose": { + "rotation": { + "radians": 0.6396788126400952 + }, + "translation": { + "x": 2.527998548568526, + "y": 4.008197271307054 + } + }, + "velocity": 2.0141904488627254, + "acceleration": -1.7404831609405098, + "curvature": 0.7394693711805369, + "holonomicRotation": 58.905764746872684, + "angularVelocity": 1.4868857184770778, + "holonomicAngularVelocity": 100.41817025860232 + }, + { + "time": 1.1461410957468727, + "pose": { + "rotation": { + "radians": 0.6476256626470698 + }, + "translation": { + "x": 2.53656452427911, + "y": 4.0146771291240375 + } + }, + "velocity": 2.005093220898503, + "acceleration": -1.7021257889428896, + "curvature": 0.7461946266930923, + "holonomicRotation": 59.44246244132448, + "angularVelocity": 1.4936530554391196, + "holonomicAngularVelocity": 99.64827075825995 + }, + { + "time": 1.1515041297277275, + "pose": { + "rotation": { + "radians": 0.6556361747389974 + }, + "translation": { + "x": 2.5450693391800865, + "y": 4.021218489659446 + } + }, + "velocity": 1.9961710931849446, + "acceleration": -1.6636343803543105, + "curvature": 0.752879947758616, + "holonomicRotation": 59.97687950353445, + "angularVelocity": 1.500350975697925, + "holonomicAngularVelocity": 98.86957527277421 + }, + { + "time": 1.1568854822606072, + "pose": { + "rotation": { + "radians": 0.6637100922622778 + }, + "translation": { + "x": 2.5535124870864694, + "y": 4.02782159644136 + } + }, + "velocity": 1.9874263398522192, + "acceleration": -1.6250103072221436, + "curvature": 0.7595199259827242, + "holonomicRotation": 60.508931542853325, + "angularVelocity": 1.5069750531000181, + "holonomicAngularVelocity": 98.08229587625448 + }, + { + "time": 1.162285060181491, + "pose": { + "rotation": { + "radians": 0.6718471214863193 + }, + "translation": { + "x": 2.5618934618132734, + "y": 4.034486692997864 + } + }, + "velocity": 1.9788612330364417, + "acceleration": -1.5862548779323185, + "curvature": 0.766109016499769, + "holonomicRotation": 61.038534542096336, + "angularVelocity": 1.5135207926411571, + "holonomicAngularVelocity": 97.2866417166188 + }, + { + "time": 1.167702765216983, + "pose": { + "rotation": { + "radians": 0.6800469307059331 + }, + "translation": { + "x": 2.5702117571755148, + "y": 4.041214022857036 + } + }, + "velocity": 1.970478041658806, + "acceleration": -1.5473694715228203, + "curvature": 0.7726415432872881, + "holonomicRotation": 61.56560487081057, + "angularVelocity": 1.5199836349511098, + "holonomicAngularVelocity": 96.48281889831824 + }, + { + "time": 1.173138493916237, + "pose": { + "rotation": { + "radians": 0.6883091493728335 + }, + "translation": { + "x": 2.578466866988207, + "y": 4.0480038295469605 + } + }, + "velocity": 1.9622790311765919, + "acceleration": -1.508355353227819, + "curvature": 0.7791117043521054, + "holonomicRotation": 62.090059298481094, + "angularVelocity": 1.526358960058976, + "holonomicAngularVelocity": 95.67103036918452 + }, + { + "time": 1.178592137586423, + "pose": { + "rotation": { + "radians": 0.6966333672537908 + }, + "translation": { + "x": 2.586658285066367, + "y": 4.054856356595717 + } + }, + "velocity": 1.9542664624020496, + "acceleration": -1.4692138429111983, + "curvature": 0.7855135782652968, + "holonomicRotation": 62.61181500767417, + "angularVelocity": 1.5326420925587887, + "holonomicAngularVelocity": 94.85147580198162 + }, + { + "time": 1.18406358223241, + "pose": { + "rotation": { + "radians": 0.7050191336253357 + }, + "translation": { + "x": 2.5947855052250084, + "y": 4.061771847531389 + } + }, + "velocity": 1.946442590910683, + "acceleration": -1.4299462020702385, + "curvature": 0.791841130883845, + "holonomicRotation": 63.13078960711488, + "angularVelocity": 1.538828306323637, + "holonomicAngularVelocity": 94.02435148577685 + }, + { + "time": 1.189552708500524, + "pose": { + "rotation": { + "radians": 0.7134659565036943 + }, + "translation": { + "x": 2.6028480212791467, + "y": 4.068750545882057 + } + }, + "velocity": 1.9388096661170229, + "acceleration": -1.3905536912129923, + "curvature": 0.7980882229865759, + "holonomicRotation": 63.64690114469784, + "angularVelocity": 1.5449128300065775, + "holonomicAngularVelocity": 93.18985021411004 + }, + { + "time": 1.1950593916269745, + "pose": { + "rotation": { + "radians": 0.7219733019165284 + }, + "translation": { + "x": 2.6108453270437972, + "y": 4.075792695175802 + } + }, + "velocity": 1.9313699304026128, + "acceleration": -1.3510375562876273, + "curvature": 0.8042486185327693, + "holonomicRotation": 64.16006812042833, + "angularVelocity": 1.5508908527558884, + "holonomicAngularVelocity": 92.34816117906108 + }, + { + "time": 1.2005835013910504, + "pose": { + "rotation": { + "radians": 0.7305405932192532 + }, + "translation": { + "x": 2.618776916333975, + "y": 4.082898538940706 + } + }, + "velocity": 1.924125618274244, + "acceleration": -1.31139901952701, + "curvature": 0.8103159935614521, + "holonomicRotation": 64.67020949929204, + "angularVelocity": 1.5567575301253238, + "holonomicAngularVelocity": 91.49946986965955 + }, + { + "time": 1.206124902073281, + "pose": { + "rotation": { + "radians": 0.7391672104587572 + }, + "translation": { + "x": 2.6266422829646943, + "y": 4.0900683207048525 + } + }, + "velocity": 1.917078955499023, + "acceleration": -1.271639280266702, + "curvature": 0.8162839457746397, + "holonomicRotation": 65.1772447240515, + "angularVelocity": 1.5625079904987484, + "holonomicAngularVelocity": 90.6439579687776 + }, + { + "time": 1.2116834524191191, + "pose": { + "rotation": { + "radians": 0.747852489789719 + }, + "translation": { + "x": 2.634440920750971, + "y": 4.09730228399632 + } + }, + "velocity": 1.9102321580214021, + "acceleration": -1.2317595508957315, + "curvature": 0.8221460049700963, + "holonomicRotation": 65.681093727967, + "angularVelocity": 1.5681373419540958, + "holonomicAngularVelocity": 89.78180325772642 + }, + { + "time": 1.2172590056081773, + "pose": { + "rotation": { + "radians": 0.7565957229475324 + }, + "translation": { + "x": 2.6421723235078196, + "y": 4.104600672343191 + } + }, + "velocity": 1.9035874312272603, + "acceleration": -1.1917609910316764, + "curvature": 0.8278956438384681, + "holonomicRotation": 66.18167694744001, + "angularVelocity": 1.573640678936801, + "holonomicAngularVelocity": 88.91317952568637 + }, + { + "time": 1.2228514092292129, + "pose": { + "rotation": { + "radians": 0.7653961567786274 + }, + "translation": { + "x": 2.649835985050256, + "y": 4.1119637292735485 + } + }, + "velocity": 1.8971469688632474, + "acceleration": -1.1516447668024896, + "curvature": 0.8335262896990334, + "holonomicRotation": 66.67891533457724, + "angularVelocity": 1.579013089939411, + "holonomicAngularVelocity": 88.03825647813974 + }, + { + "time": 1.2284605052614423, + "pose": { + "rotation": { + "radians": 0.7742529928362449 + }, + "translation": { + "x": 2.6574313991932947, + "y": 4.119391698315472 + } + }, + "velocity": 1.890912952045104, + "acceleration": -1.111412031871654, + "curvature": 0.8390313367951864, + "holonomicRotation": 67.17273036967318, + "angularVelocity": 1.5842496649074382, + "holonomicAngularVelocity": 87.15719965492562 + }, + { + "time": 1.234086130062117, + "pose": { + "rotation": { + "radians": 0.7831653870416089 + }, + "translation": { + "x": 2.6649580597519504, + "y": 4.126884822997045 + } + }, + "velocity": 1.884887548364822, + "acceleration": -1.0710639073475614, + "curvature": 0.8444041591150093, + "holonomicRotation": 67.66304407360929, + "angularVelocity": 1.589345503179362, + "holonomicAngularVelocity": 86.27017034976315 + }, + { + "time": 1.2397281143608059, + "pose": { + "rotation": { + "radians": 0.7921324494157385 + }, + "translation": { + "x": 2.6724154605412394, + "y": 4.134443346846348 + } + }, + "velocity": 1.8790729107255957, + "acceleration": -1.0306015280080867, + "curvature": 0.8496381240420783, + "holonomicRotation": 68.14977902016786, + "angularVelocity": 1.5942957218618874, + "holonomicAngularVelocity": 85.37732553857849 + }, + { + "time": 1.245386283260372, + "pose": { + "rotation": { + "radians": 0.8011532438858886 + }, + "translation": { + "x": 2.679803095376175, + "y": 4.142067513391463 + } + }, + "velocity": 1.8734711765865795, + "acceleration": -0.9900259674902657, + "curvature": 0.8547266062009597, + "holonomicRotation": 68.63285834825837, + "angularVelocity": 1.5990954640501065, + "holonomicAngularVelocity": 84.47881780955483 + }, + { + "time": 1.2510604562450975, + "pose": { + "rotation": { + "radians": 0.810226788167999 + }, + "translation": { + "x": 2.6871204580717736, + "y": 4.1497575661604715 + } + }, + "velocity": 1.86808446661834, + "acceleration": -0.949338341065735, + "curvature": 0.8596630023597044, + "holonomicRotation": 69.1122057740549, + "angularVelocity": 1.6037399075864955, + "holonomicAngularVelocity": 83.57479529775051 + }, + { + "time": 1.2567504471962336, + "pose": { + "rotation": { + "radians": 0.819352053730142 + }, + "translation": { + "x": 2.6943670424430497, + "y": 4.157513748681454 + } + }, + "velocity": 1.862914883876036, + "acceleration": -0.9085397124000278, + "curvature": 0.8644407463563594, + "holonomicRotation": 69.58774560304215, + "angularVelocity": 1.6082242740958255, + "holonomicAngularVelocity": 82.66540163083593 + }, + { + "time": 1.2624560644148213, + "pose": { + "rotation": { + "radians": 0.8285279658397737 + }, + "translation": { + "x": 2.701542342305019, + "y": 4.165336304482494 + } + }, + "velocity": 1.8579645126741293, + "acceleration": -0.867631145282505, + "curvature": 0.8690533247412898, + "holonomicRotation": 70.05940274196851, + "angularVelocity": 1.6125438378778367, + "holonomicAngularVelocity": 81.75077587745383 + }, + { + "time": 1.2681771106521889, + "pose": { + "rotation": { + "radians": 0.837753403696055 + }, + "translation": { + "x": 2.708645851472695, + "y": 4.173225477091672 + } + }, + "velocity": 1.8532354175856258, + "acceleration": -0.826613680836024, + "curvature": 0.8734942927047408, + "holonomicRotation": 70.5271027107041, + "angularVelocity": 1.6166939352853913, + "holonomicAngularVelocity": 80.83105250208973 + }, + { + "time": 1.273913383148282, + "pose": { + "rotation": { + "radians": 0.8470272006516333 + }, + "translation": { + "x": 2.715677063761095, + "y": 4.18118151003707 + } + }, + "velocity": 1.8487296423162756, + "acceleration": -0.7854883589332607, + "curvature": 0.8777572904677117, + "holonomicRotation": 70.9907716540021, + "angularVelocity": 1.6206699741819475, + "holonomicAngularVelocity": 79.90636132658405 + }, + { + "time": 1.279664673677968, + "pose": { + "rotation": { + "radians": 0.8563481445258923 + }, + "translation": { + "x": 2.7226354729852322, + "y": 4.189204646846768 + } + }, + "velocity": 1.8444492086921047, + "acceleration": -0.7442561981657716, + "curvature": 0.881836059857402, + "holonomicRotation": 71.45033635316135, + "angularVelocity": 1.624467443317504, + "holonomicAngularVelocity": 78.97682749979187 + }, + { + "time": 1.2854307686053472, + "pose": { + "rotation": { + "radians": 0.865714978010498 + }, + "translation": { + "x": 2.729520572960122, + "y": 4.1972951310488495 + } + }, + "velocity": 1.8403961155928805, + "acceleration": -0.7029182055222216, + "curvature": 0.8857244611617751, + "holonomicRotation": 71.9057242375884, + "angularVelocity": 1.6280819220161982, + "holonomicAngularVelocity": 78.04257147270275 + }, + { + "time": 1.2912114489462903, + "pose": { + "rotation": { + "radians": 0.8751263991705418 + }, + "translation": { + "x": 2.7363318575007805, + "y": 4.205453206171397 + } + }, + "velocity": 1.8365723378633072, + "acceleration": -0.661475380759339, + "curvature": 0.8894164901698529, + "holonomicRotation": 72.3568633962573, + "angularVelocity": 1.631509089802121, + "holonomicAngularVelocity": 77.10370898187273 + }, + { + "time": 1.297006490439208, + "pose": { + "rotation": { + "radians": 0.8845810620420176 + }, + "translation": { + "x": 2.7430688204222218, + "y": 4.213679115742488 + } + }, + "velocity": 1.832979825296675, + "acceleration": -0.619928704742282, + "curvature": 0.8929062952374428, + "holonomicRotation": 72.8036825890651, + "angularVelocity": 1.6347447361535672, + "holonomicAngularVelocity": 76.16035104140812 + }, + { + "time": 1.3028156636240313, + "pose": { + "rotation": { + "radians": 0.894077577327312 + }, + "translation": { + "x": 2.7497309555394613, + "y": 4.221973103290208 + } + }, + "velocity": 1.8296205016132843, + "acceleration": -0.5782791417145218, + "curvature": 0.8961881943792127, + "holonomicRotation": 73.24611125808158, + "angularVelocity": 1.6377847699871186, + "holonomicAngularVelocity": 75.21260394021503 + }, + { + "time": 1.30863873392961, + "pose": { + "rotation": { + "radians": 0.9036145131883528 + }, + "translation": { + "x": 2.7563177566675137, + "y": 4.230335412342637 + } + }, + "velocity": 1.826496263335565, + "acceleration": -0.5365276587380652, + "curvature": 0.8992566924089129, + "holonomicRotation": 73.6840795386911, + "angularVelocity": 1.6406252293242067, + "holonomicAngularVelocity": 74.26056924841903 + }, + { + "time": 1.314475461769441, + "pose": { + "rotation": { + "radians": 0.9131903961390786 + }, + "translation": { + "x": 2.7628287176213946, + "y": 4.238766286427857 + } + }, + "velocity": 1.8236089788536598, + "acceleration": -0.49467519492716594, + "curvature": 0.9021064977629244, + "holonomicRotation": 74.11751827062504, + "angularVelocity": 1.643262290855695, + "holonomicAngularVelocity": 73.30434383206303 + }, + { + "time": 1.320325602645683, + "pose": { + "rotation": { + "radians": 0.9228037120372008 + }, + "translation": { + "x": 2.7692633322161186, + "y": 4.247265969073948 + } + }, + "velocity": 1.8209604873361642, + "acceleration": -0.45272269053405195, + "curvature": 0.9047325392640337, + "holonomicRotation": 74.5463590088831, + "angularVelocity": 1.6456922792088542, + "holonomicAngularVelocity": 72.34401987525794 + }, + { + "time": 1.3261889072614577, + "pose": { + "rotation": { + "radians": 0.9324529071740306 + }, + "translation": { + "x": 2.7756210942667012, + "y": 4.255834703808993 + } + }, + "velocity": 1.8185525977962105, + "acceleration": -0.4106710631195233, + "curvature": 0.9071299824396285, + "holonomicRotation": 74.97053403454139, + "angularVelocity": 1.6479116761303385, + "holonomicAngularVelocity": 71.3796849104472 + }, + { + "time": 1.3320651216413755, + "pose": { + "rotation": { + "radians": 0.9421363894621422 + }, + "translation": { + "x": 2.781901497588157, + "y": 4.264472734161075 + } + }, + "velocity": 1.8163870880234456, + "acceleration": -0.3685212336986165, + "curvature": 0.9092942455973303, + "holonomicRotation": 75.38997636544616, + "angularVelocity": 1.6499171295340616, + "holonomicAngularVelocity": 70.4114218583858 + }, + { + "time": 1.3379539872600648, + "pose": { + "rotation": { + "radians": 0.9518525297199418 + }, + "translation": { + "x": 2.788104035995501, + "y": 4.273180303658273 + } + }, + "velocity": 1.8144657037678693, + "acceleration": -0.32627408740292496, + "curvature": 0.9112210151912336, + "holonomicRotation": 75.80461976679103, + "angularVelocity": 1.6517054622237413, + "holonomicAngularVelocity": 69.439309074703 + }, + { + "time": 1.343855241178712, + "pose": { + "rotation": { + "radians": 0.9615996630513406 + }, + "translation": { + "x": 2.7942282033037484, + "y": 4.281957655828669 + } + }, + "velocity": 1.8127901576232959, + "acceleration": -0.28393052860832513, + "curvature": 0.9129062609469006, + "holonomicRotation": 76.21439876157628, + "angularVelocity": 1.6532736802559593, + "holonomicAngularVelocity": 68.46342040422189 + }, + { + "time": 1.3497686161895086, + "pose": { + "rotation": { + "radians": 0.9713760903181741 + }, + "translation": { + "x": 2.800273493327915, + "y": 4.290805034200345 + } + }, + "velocity": 1.8113621282279633, + "acceleration": -0.24149143132733641, + "curvature": 0.914346250046392, + "holonomicRotation": 76.61924864094827, + "angularVelocity": 1.6546189811787644, + "holonomicAngularVelocity": 67.48382524759128 + }, + { + "time": 1.3556938409674844, + "pose": { + "rotation": { + "radians": 0.9811800797035635 + }, + "translation": { + "x": 2.8062393998830153, + "y": 4.299722682301384 + } + }, + "velocity": 1.8101832594033358, + "acceleration": -0.19895765457023182, + "curvature": 0.9155375606708208, + "holonomicRotation": 77.01910547441788, + "angularVelocity": 1.655738761630261, + "holonomicAngularVelocity": 66.50058863161212 + }, + { + "time": 1.3616306402298943, + "pose": { + "rotation": { + "radians": 0.9910098683623536 + }, + "translation": { + "x": 2.8121254167840637, + "y": 4.308710843659867 + } + }, + "velocity": 1.8092551591757633, + "acceleration": -0.15633006718771086, + "curvature": 0.9164770948804419, + "holonomicRotation": 77.41390611995587, + "angularVelocity": 1.6566306247801388, + "holonomicAngularVelocity": 65.51377128920768 + }, + { + "time": 1.3675787349028061, + "pose": { + "rotation": { + "radians": 1.000863664156591 + }, + "translation": { + "x": 2.8179310378460762, + "y": 4.3177697618038735 + } + }, + "velocity": 1.8085793990451318, + "acceleration": -0.11360951158175212, + "curvature": 0.9171620903893286, + "holonomicRotation": 77.80358823396357, + "angularVelocity": 1.6572923872679133, + "holonomicAngularVelocity": 64.52342974920651 + }, + { + "time": 1.3735378422944748, + "pose": { + "rotation": { + "radians": 1.0107396474717154 + }, + "translation": { + "x": 2.8236557568840674, + "y": 4.326899680261486 + } + }, + "velocity": 1.8081575131573642, + "acceleration": -0.0707968257725009, + "curvature": 0.917590131509392, + "holonomicRotation": 78.18809028111788, + "angularVelocity": 1.657722085504442, + "holonomicAngularVelocity": 63.52961643318937 + }, + { + "time": 1.37950767627528, + "pose": { + "rotation": { + "radians": 1.020635973108491 + }, + "translation": { + "x": 2.8292990677130523, + "y": 4.336100842560788 + } + }, + "velocity": 1.807990997598541, + "acceleration": -0.027892829073383706, + "curvature": 0.9177591589767008, + "holonomicRotation": 78.56735154408825, + "angularVelocity": 1.6579179816540077, + "holonomicAngularVelocity": 62.53237975938081 + }, + { + "time": 1.3854879474639896, + "pose": { + "rotation": { + "radians": 1.03055077224742 + }, + "translation": { + "x": 2.834860464148046, + "y": 4.345373492229859 + } + }, + "velocity": 1.8080813095853832, + "acceleration": 0.015101654087621652, + "curvature": 0.9176674788264284, + "holonomicRotation": 78.94131213312473, + "angularVelocity": 1.6578785690903888, + "holonomicAngularVelocity": 61.53176425402279 + }, + { + "time": 1.391478363420028, + "pose": { + "rotation": { + "radians": 1.0404821544808733 + }, + "translation": { + "x": 2.8403394400040645, + "y": 4.354717872796781 + } + }, + "velocity": 1.8084298668271106, + "acceleration": 0.05818581619129324, + "curvature": 0.9173137699807672, + "holonomicRotation": 79.30991299551522, + "angularVelocity": 1.6576025771005691, + "holonomicAngularVelocity": 60.527810672655114 + }, + { + "time": 1.39747862884115, + "pose": { + "rotation": { + "radians": 1.0504282099062126 + }, + "translation": { + "x": 2.8457354890961217, + "y": 4.364134227789636 + } + }, + "velocity": 1.8090380469286687, + "acceleration": 0.10135886646233248, + "curvature": 0.9166970906312715, + "holonomicRotation": 79.67309592491057, + "angularVelocity": 1.6570889751192701, + "holonomicAngularVelocity": 59.52055612693776 + }, + { + "time": 1.403488445766292, + "pose": { + "rotation": { + "radians": 1.0603870112753504 + }, + "translation": { + "x": 2.8510481052392325, + "y": 4.373622800736505 + } + }, + "velocity": 1.8099071867381205, + "acceleration": 0.14462001426628804, + "curvature": 0.9158168834705848, + "holonomicRotation": 80.0308035705161, + "angularVelocity": 1.6563369764275115, + "holonomicAngularVelocity": 58.510034217747226 + }, + { + "time": 1.409507513783261, + "pose": { + "rotation": { + "radians": 1.0703566161954883 + }, + "translation": { + "x": 2.856276782248413, + "y": 4.38318383516547 + } + }, + "velocity": 1.8110385817969141, + "acceleration": 0.18796847877512687, + "curvature": 0.9146729795756269, + "holonomicRotation": 80.3829794461479, + "angularVelocity": 1.655346041048964, + "holonomicAngularVelocity": 57.49627517669591 + }, + { + "time": 1.4155355302406682, + "pose": { + "rotation": { + "radians": 1.0803350693736355 + }, + "translation": { + "x": 2.8614210139386773, + "y": 4.392817574604613 + } + }, + "velocity": 1.8124334858675517, + "acceleration": 0.2314034940836123, + "curvature": 0.913265600939143, + "holonomicRotation": 80.72956793915264, + "angularVelocity": 1.6541158780443799, + "holonomicAngularVelocity": 56.47930601365878 + }, + { + "time": 1.4215721904636955, + "pose": { + "rotation": { + "radians": 1.090320404898904 + }, + "translation": { + "x": 2.866480294125041, + "y": 4.4025242625820145 + } + }, + "velocity": 1.814093110459821, + "acceleration": 0.27492430101309223, + "curvature": 0.9115953617080983, + "holonomicRotation": 81.07051431918948, + "angularVelocity": 1.6526464472421345, + "holonomicAngularVelocity": 55.45915066950544 + }, + { + "time": 1.4276171879733226, + "pose": { + "rotation": { + "radians": 1.1003106485567766 + }, + "translation": { + "x": 2.8714541166225196, + "y": 4.412304142625757 + } + }, + "velocity": 1.8160186243942888, + "acceleration": 0.3185301451987892, + "curvature": 0.9096632680760596, + "holonomicRotation": 81.40576474687268, + "angularVelocity": 1.6509379601583025, + "holonomicAngularVelocity": 54.43583017529773 + }, + { + "time": 1.4336702147084632, + "pose": { + "rotation": { + "radians": 1.1103038201676734 + }, + "translation": { + "x": 2.876341975246127, + "y": 4.422157458263921 + } + }, + "velocity": 1.818211153470297, + "acceleration": 0.36222028613874074, + "curvature": 0.9074707167569798, + "holonomicRotation": 81.73526628227333, + "angularVelocity": 1.6489908802443665, + "holonomicAngularVelocity": 53.409362817062245 + }, + { + "time": 1.439730961250501, + "pose": { + "rotation": { + "radians": 1.1202979359429661 + }, + "translation": { + "x": 2.881143363810879, + "y": 4.43208445302459 + } + }, + "velocity": 1.8206717801454617, + "acceleration": 0.4059939906903755, + "curvature": 0.9050194921374667, + "holonomicRotation": 82.05896689327928, + "angularVelocity": 1.646805922558907, + "holonomicAngularVelocity": 52.379764305061734 + }, + { + "time": 1.4457991170497746, + "pose": { + "rotation": { + "radians": 1.1302910108522202 + }, + "translation": { + "x": 2.8858577761317905, + "y": 4.442085370435843 + } + }, + "velocity": 1.8234015432666075, + "acceleration": 0.4498505330849536, + "curvature": 0.9023117620787452, + "holonomicRotation": 82.37681546381162, + "angularVelocity": 1.6393738158270388, + "holonomicAngularVelocity": 51.19059978089827 + }, + { + "time": 1.4518929377789702, + "pose": { + "rotation": { + "radians": 1.1402810609940075 + }, + "translation": { + "x": 2.8904847060238765, + "y": 4.452160454025765 + } + }, + "velocity": 1.8152809351623431, + "acceleration": -1.332597144736865, + "curvature": 0.8993500723685289, + "holonomicRotation": 82.68876180189642, + "angularVelocity": 1.6219775507255298, + "holonomicAngularVelocity": 49.70601253218088 + }, + { + "time": 1.4580490309778806, + "pose": { + "rotation": { + "radians": 1.1502661059628143 + }, + "translation": { + "x": 2.8950236473021524, + "y": 4.462309947322433 + } + }, + "velocity": 1.7968126555656119, + "acceleration": -3.0, + "curvature": 0.8961373399400934, + "holonomicRotation": 82.99475664759073, + "angularVelocity": 1.5994721218793286, + "holonomicAngularVelocity": 48.088850948024216 + }, + { + "time": 1.4642873799352032, + "pose": { + "rotation": { + "radians": 1.1602441712066067 + }, + "translation": { + "x": 2.8994740937816323, + "y": 4.472534093853932 + } + }, + "velocity": 1.7780976086936442, + "acceleration": -3.0, + "curvature": 0.8926768446185156, + "holonomicRotation": 83.29475168076118, + "angularVelocity": 1.5764262934325932, + "holonomicAngularVelocity": 46.482252747741015 + }, + { + "time": 1.470611252608683, + "pose": { + "rotation": { + "radians": 1.1702132903654001 + }, + "translation": { + "x": 2.9038355392773325, + "y": 4.482833137148344 + } + }, + "velocity": 1.7591259906732046, + "acceleration": -3.000000000000035, + "curvature": 0.8889722200024526, + "holonomicRotation": 83.5886995287144, + "angularVelocity": 1.5528541730227239, + "holonomicAngularVelocity": 44.88711739884929 + }, + { + "time": 1.4770241002505906, + "pose": { + "rotation": { + "radians": 1.1801715075870953 + }, + "translation": { + "x": 2.9081074776042675, + "y": 4.493207320733747 + } + }, + "velocity": 1.7398874477474815, + "acceleration": -3.0000000000000346, + "curvature": 0.8850274427968513, + "holonomicRotation": 83.87655377367764, + "angularVelocity": 1.5287702004538215, + "holonomicAngularVelocity": 43.30434018507438 + }, + { + "time": 1.4835295725715414, + "pose": { + "rotation": { + "radians": 1.190116879811242 + }, + "translation": { + "x": 2.9122894025774526, + "y": 4.503656888138226 + } + }, + "velocity": 1.7203710307846292, + "acceleration": -3.0, + "curvature": 0.8808468212891777, + "holonomicRotation": 84.15826896012868, + "angularVelocity": 1.504189078344182, + "holonomicAngularVelocity": 41.734811554628145 + }, + { + "time": 1.4901315346166932, + "pose": { + "rotation": { + "radians": 1.2000474790152023 + }, + "translation": { + "x": 2.9163808080119025, + "y": 4.514182082889862 + } + }, + "velocity": 1.7005651446491736, + "acceleration": -3.0, + "curvature": 0.8764349826621125, + "holonomicRotation": 84.4338006019739, + "angularVelocity": 1.4791256986724945, + "holonomicAngularVelocity": 40.179416523208545 + }, + { + "time": 1.496834085596832, + "pose": { + "rotation": { + "radians": 1.2099613944165881 + }, + "translation": { + "x": 2.920381187722632, + "y": 4.524783148516736 + } + }, + "velocity": 1.6804574917087571, + "acceleration": -3.0, + "curvature": 0.8717968593211561, + "holonomicRotation": 84.70310518957294, + "angularVelocity": 1.4535950649122817, + "holonomicAngularVelocity": 38.639034138616516 + }, + { + "time": 1.50364157995844, + "pose": { + "rotation": { + "radians": 1.2198567346250395 + }, + "translation": { + "x": 2.9242900355246566, + "y": 4.535460328546927 + } + }, + "velocity": 1.6600350086239335, + "acceleration": -3.0, + "curvature": 0.8669376744563995, + "holonomicRotation": 84.96614019660954, + "angularVelocity": 1.4276122098245985, + "holonomicAngularVelocity": 37.11453701340954 + }, + { + "time": 1.5105586510269702, + "pose": { + "rotation": { + "radians": 1.2297316297386978 + }, + "translation": { + "x": 2.9281068452329917, + "y": 4.546213866508522 + } + }, + "velocity": 1.639283795418343, + "acceleration": -2.999999999999968, + "curvature": 0.8618629265041059, + "holonomicRotation": 85.2228640868069, + "angularVelocity": 1.4011921081103897, + "holonomicAngularVelocity": 35.60679093330834 + }, + { + "time": 1.5175902376181007, + "pose": { + "rotation": { + "radians": 1.2395842333776848 + }, + "translation": { + "x": 2.9318311106626513, + "y": 4.5570440059295985 + } + }, + "velocity": 1.618189035644951, + "acceleration": -3.0000000000000315, + "curvature": 0.856578373185448, + "holonomicRotation": 85.47323632048673, + "angularVelocity": 1.3743495841726672, + "holonomicAngularVelocity": 34.116654548705206 + }, + { + "time": 1.5247416140854468, + "pose": { + "rotation": { + "radians": 1.249412724651844 + }, + "translation": { + "x": 2.935462325628652, + "y": 4.56795099033824 + } + }, + "velocity": 1.5967349062429128, + "acceleration": -3.0, + "curvature": 0.8510900147003576, + "holonomicRotation": 85.71721736097092, + "angularVelocity": 1.347099213871016, + "holonomicAngularVelocity": 32.644979158266835 + }, + { + "time": 1.532018424363139, + "pose": { + "rotation": { + "radians": 1.2592153100564116 + }, + "translation": { + "x": 2.9389999839460073, + "y": 4.578935063262526 + } + }, + "velocity": 1.5749044754098365, + "acceleration": -3.0, + "curvature": 0.8454040763550249, + "holonomicRotation": 85.95476868082484, + "angularVelocity": 1.3194552197086669, + "holonomicAngularVelocity": 31.19260859353292 + }, + { + "time": 1.5394267206722971, + "pose": { + "rotation": { + "radians": 1.2689902252906788 + }, + "translation": { + "x": 2.9424435794297326, + "y": 4.58999646823054 + } + }, + "velocity": 1.552679586482362, + "acceleration": -3.0, + "curvature": 0.8395269907945926, + "holonomicRotation": 86.18585276794133, + "angularVelocity": 1.2914313587824056, + "holonomicAngularVelocity": 29.760379215041628 + }, + { + "time": 1.546973007697073, + "pose": { + "rotation": { + "radians": 1.278735736996847 + }, + "translation": { + "x": 2.9457926058948445, + "y": 4.601135448770364 + } + }, + "velocity": 1.5300407254080348, + "acceleration": -2.9999999999999707, + "curvature": 0.833465379886221, + "holonomicRotation": 86.4104331314642, + "angularVelocity": 1.263040802049618, + "holonomicAngularVelocity": 28.349120031543038 + }, + { + "time": 1.5546642932058943, + "pose": { + "rotation": { + "radians": 1.2884501444147014 + }, + "translation": { + "x": 2.9490465571563558, + "y": 4.612352248410078 + } + }, + "velocity": 1.5069668688815712, + "acceleration": -2.9999999999999423, + "curvature": 0.8272260361053153, + "holonomicRotation": 86.62847430755065, + "angularVelocity": 1.2342960033859218, + "holonomicAngularVelocity": 26.959652955290828 + }, + { + "time": 1.562508146306355, + "pose": { + "rotation": { + "radians": 1.2981317809477464 + }, + "translation": { + "x": 2.952204927029283, + "y": 4.623647110677764 + } + }, + "velocity": 1.4834353095801889, + "acceleration": -3.0, + "curvature": 0.8208159040072, + "holonomicRotation": 86.83994186497135, + "angularVelocity": 1.2052085570168602, + "holonomicAngularVelocity": 25.592793208687993 + }, + { + "time": 1.5705127647903852, + "pose": { + "rotation": { + "radians": 1.3077790156403548 + }, + "translation": { + "x": 2.9552672093286407, + "y": 4.635020279101503 + } + }, + "velocity": 1.4594214541280985, + "acceleration": -3.0, + "curvature": 0.8142420613900655, + "holonomicRotation": 87.04480241054758, + "angularVelocity": 1.175789040240505, + "holonomicAngularVelocity": 24.24934989960506 + }, + { + "time": 1.5786870533670874, + "pose": { + "rotation": { + "radians": 1.3173902545606044 + }, + "translation": { + "x": 2.9582328978694443, + "y": 4.646471997209379 + } + }, + "velocity": 1.4348985883979921, + "acceleration": -2.999999999999973, + "curvature": 0.8075117004620126, + "holonomicRotation": 87.24302359442437, + "angularVelocity": 1.1460468390736178, + "holonomicAngularVelocity": 22.930126786042262 + }, + { + "time": 1.5870407150167543, + "pose": { + "rotation": { + "radians": 1.3269639420888957 + }, + "translation": { + "x": 2.9611014864667085, + "y": 4.65800250852947 + } + }, + "velocity": 1.4098376034489917, + "acceleration": -2.9999999999999734, + "curvature": 0.8006321092309213, + "holonomicRotation": 87.43457411517893, + "angularVelocity": 1.115989952587679, + "holonomicAngularVelocity": 21.635923254361483 + }, + { + "time": 1.595584358262823, + "pose": { + "rotation": { + "radians": 1.336498562110002 + }, + "translation": { + "x": 2.963872468935448, + "y": 4.669612056589861 + } + }, + "velocity": 1.3842066737107854, + "acceleration": -2.999999999999974, + "curvature": 0.7936106527983469, + "holonomicRotation": 87.61942372476352, + "angularVelocity": 1.0856247710293516, + "holonomicAngularVelocity": 20.367535540449826 + }, + { + "time": 1.6043296238922686, + "pose": { + "rotation": { + "radians": 1.3459926391065598 + }, + "translation": { + "x": 2.9665453390906786, + "y": 4.68130088491863 + } + }, + "velocity": 1.3579708768224485, + "acceleration": -3.0000000000000253, + "curvature": 0.7864547551434554, + "holonomicRotation": 87.79754323328193, + "angularVelocity": 1.0549558217086663, + "holonomicAngularVelocity": 19.125758228972256 + }, + { + "time": 1.613289335620583, + "pose": { + "rotation": { + "radians": 1.3554447391551765 + }, + "translation": { + "x": 2.969119590747415, + "y": 4.693069237043862 + } + }, + "velocity": 1.3310917416375052, + "acceleration": -3.0, + "curvature": 0.7791718809381487, + "holonomicRotation": 87.96890451359896, + "angularVelocity": 1.0239854739651646, + "holonomicAngularVelocity": 17.91138607403565 + }, + { + "time": 1.622477680481373, + "pose": { + "rotation": { + "radians": 1.3648534708224078 + }, + "translation": { + "x": 2.9715947177206727, + "y": 4.704917356493637 + } + }, + "velocity": 1.3035267070551353, + "acceleration": -3.000000000000024, + "curvature": 0.7717695180203282, + "holonomicRotation": 88.13348050578195, + "angularVelocity": 0.9927135930553639, + "holonomicAngularVelocity": 16.725216194464355 + }, + { + "time": 1.63191042644756, + "pose": { + "rotation": { + "radians": 1.3742174859628797 + }, + "translation": { + "x": 2.973970213825466, + "y": 4.716845486796037 + } + }, + "velocity": 1.2752284691565743, + "acceleration": -3.0000000000000235, + "curvature": 0.7642551600626761, + "holonomicRotation": 88.29124522137388, + "angularVelocity": 0.9611371284041571, + "holonomicAngularVelocity": 15.56805071013536 + }, + { + "time": 1.6416051871426292, + "pose": { + "rotation": { + "radians": 1.383535480417904 + }, + "translation": { + "x": 2.97624557287681, + "y": 4.728853871479143 + } + }, + "velocity": 1.2461441870713668, + "acceleration": -2.999999999999977, + "curvature": 0.7566362899300489, + "holonomicRotation": 88.44217374749735, + "angularVelocity": 0.9292496179521041, + "holonomicAngularVelocity": 14.440699902870017 + }, + { + "time": 1.6515817467457017, + "pose": { + "rotation": { + "radians": 1.3928061946175356 + }, + "translation": { + "x": 2.978420288689721, + "y": 4.740942754071038 + } + }, + "velocity": 1.2162145082621492, + "acceleration": -3.0, + "curvature": 0.7489203635027577, + "holonomicRotation": 88.58624225078842, + "angularVelocity": 0.8970405829253777, + "holonomicAngularVelocity": 13.343986008255815 + }, + { + "time": 1.6618624627391885, + "pose": { + "rotation": { + "radians": 1.4020284140852233 + }, + "translation": { + "x": 2.980493855079212, + "y": 4.753112378099801 + } + }, + "velocity": 1.1853723602816888, + "acceleration": -3.0, + "curvature": 0.7411147940451478, + "holonomicRotation": 88.72342798116036, + "angularVelocity": 0.8644947789010164, + "holonomicAngularVelocity": 12.278747774850764 + }, + { + "time": 1.672472770616225, + "pose": { + "rotation": { + "radians": 1.4112009698474537 + }, + "translation": { + "x": 2.9824657658603, + "y": 4.765362987093515 + } + }, + "velocity": 1.153541436650579, + "acceleration": -3.000000000000021, + "curvature": 0.7332269374608648, + "holonomicRotation": 88.853709275396, + "angularVelocity": 0.8315912554192696, + "holonomicAngularVelocity": 11.245845968659761 + }, + { + "time": 1.6834418240352835, + "pose": { + "rotation": { + "radians": 1.4203227387509696 + }, + "translation": { + "x": 2.984335514847999, + "y": 4.777694824580263 + } + }, + "velocity": 1.1206342763934034, + "acceleration": -3.0, + "curvature": 0.725264077949128, + "holonomicRotation": 88.97706556056873, + "angularVelocity": 0.7983021566049804, + "holonomicAngularVelocity": 10.246170056824981 + }, + { + "time": 1.6948033177521344, + "pose": { + "rotation": { + "radians": 1.4293926436873856 + }, + "translation": { + "x": 2.9861025958573246, + "y": 4.7901081340881255 + } + }, + "velocity": 1.0865497952428504, + "acceleration": -3.0000000000000195, + "curvature": 0.7172334145932396, + "holonomicRotation": 89.09347735729114, + "angularVelocity": 0.7645911667003292, + "holonomicAngularVelocity": 9.280646383290382 + }, + { + "time": 1.70659656156077, + "pose": { + "rotation": { + "radians": 1.4384096537302118 + }, + "translation": { + "x": 2.987766502703291, + "y": 4.802603159145181 + } + }, + "velocity": 1.0511700638169434, + "acceleration": -3.0, + "curvature": 0.7091420486074421, + "holonomicRotation": 89.20292628279101, + "angularVelocity": 0.730411458422808, + "holonomicAngularVelocity": 8.350248260396057 + }, + { + "time": 1.7188679058163951, + "pose": { + "rotation": { + "radians": 1.4473727841847712 + }, + "translation": { + "x": 2.9893267292009145, + "y": 4.815180143279516 + } + }, + "velocity": 1.0143560310500683, + "acceleration": -3.0, + "curvature": 0.7009969714592601, + "holonomicRotation": 89.30539505381427, + "angularVelocity": 0.6957029316515805, + "holonomicAngularVelocity": 7.456008561063265 + }, + { + "time": 1.7316726705585361, + "pose": { + "rotation": { + "radians": 1.4562810965549875 + }, + "translation": { + "x": 2.9907827691652096, + "y": 4.82783933001921 + } + }, + "velocity": 0.9759417368236457, + "acceleration": -2.999999999999974, + "curvature": 0.692805053609917, + "holonomicRotation": 89.40086748935407, + "angularVelocity": 0.660388413677914, + "holonomicAngularVelocity": 6.599035632827374 + }, + { + "time": 1.7450778146999044, + "pose": { + "rotation": { + "radians": 1.4651336984296295 + }, + "translation": { + "x": 2.992134116411191, + "y": 4.840580962892344 + } + }, + "velocity": 0.9357263043995407, + "acceleration": -3.0000000000000084, + "curvature": 0.6845730342358501, + "holonomicRotation": 89.48932851320615, + "angularVelocity": 0.6243682973153083, + "holonomicAngularVelocity": 5.780533711561292 + }, + { + "time": 1.7591657254719308, + "pose": { + "rotation": { + "radians": 1.4739297432910896 + }, + "translation": { + "x": 2.9933802647538736, + "y": 4.853405285426999 + } + }, + "velocity": 0.8934625720834616, + "acceleration": -2.999999999999992, + "curvature": 0.6763075116811156, + "holonomicRotation": 89.57076415634931, + "angularVelocity": 0.587512750883515, + "holonomicAngularVelocity": 5.001829563513309 + }, + { + "time": 1.7740397634329392, + "pose": { + "rotation": { + "radians": 1.4826684302503075 + }, + "translation": { + "x": 2.9945207080082734, + "y": 4.866312541151259 + } + }, + "velocity": 0.8488404582004362, + "acceleration": -3.000000000000015, + "curvature": 0.6680149347162724, + "holonomicRotation": 89.6451615591515, + "angularVelocity": 0.5496500045273275, + "holonomicAngularVelocity": 4.264407957958817 + }, + { + "time": 1.78983267417526, + "pose": { + "rotation": { + "radians": 1.4913490037113237 + }, + "translation": { + "x": 2.995554939989405, + "y": 4.879302973593203 + } + }, + "velocity": 0.801461725973474, + "acceleration": -3.000000000000007, + "curvature": 0.6597015946752146, + "holonomicRotation": 89.71250897340039, + "angularVelocity": 0.5105479920421858, + "holonomicAngularVelocity": 3.569959998904688 + }, + { + "time": 1.8067199196280448, + "pose": { + "rotation": { + "radians": 1.4999707529683666 + }, + "translation": { + "x": 2.9964824545122832, + "y": 4.892376826280915 + } + }, + "velocity": 0.7507999896151193, + "acceleration": -3.0000000000000067, + "curvature": 0.6513736182652573, + "holonomicRotation": 89.77279576415852, + "angularVelocity": 0.4698840718376818, + "holonomicAngularVelocity": 2.9204507340812516 + }, + { + "time": 1.8249419860588283, + "pose": { + "rotation": { + "radians": 1.5085330117401599 + }, + "translation": { + "x": 2.9973027453919228, + "y": 4.905534342742476 + } + }, + "velocity": 0.6961337903227689, + "acceleration": -2.999999999999994, + "curvature": 0.6430369613174203, + "holonomicRotation": 89.82601241144278, + "angularVelocity": 0.4271917365972208, + "holonomicAngularVelocity": 2.318216531133641 + }, + { + "time": 1.8448443979626472, + "pose": { + "rotation": { + "radians": 1.5170351576438255 + }, + "translation": { + "x": 2.99801530644334, + "y": 4.918775766505965 + } + }, + "velocity": 0.6364265546113125, + "acceleration": -2.999999999999983, + "curvature": 0.6346974032758499, + "holonomicRotation": 89.87215051172764, + "angularVelocity": 0.38175841711322217, + "holonomicAngularVelocity": 1.7661094753355508 + }, + { + "time": 1.8669564290060066, + "pose": { + "rotation": { + "radians": 1.5254766116140968 + }, + "translation": { + "x": 2.9986196314815485, + "y": 4.932101341099467 + } + }, + "velocity": 0.5700904614812343, + "acceleration": -3.000000000000005, + "curvature": 0.6263605423064249, + "holonomicRotation": 89.91120277927223, + "angularVelocity": 0.3324044885642192, + "holonomicAngularVelocity": 1.2677148535800413 + }, + { + "time": 1.8921673570852195, + "pose": { + "rotation": { + "radians": 1.5338568372684969 + }, + "translation": { + "x": 2.9991152143215647, + "y": 4.945511310051062 + } + }, + "velocity": 0.4944576772435955, + "acceleration": -2.9999999999999933, + "curvature": 0.6180317914296721, + "holonomicRotation": 89.94316304727079, + "angularVelocity": 0.2769089779627116, + "holonomicAngularVelocity": 0.8276548442472411 + }, + { + "time": 1.9222079249965291, + "pose": { + "rotation": { + "radians": 1.542175340226237 + }, + "translation": { + "x": 2.9995015487784027, + "y": 4.959005916888831 + } + }, + "velocity": 0.4043359735096668, + "acceleration": -2.9999999999999964, + "curvature": 0.6097163750781969, + "holonomicRotation": 89.96802626882652, + "angularVelocity": 0.20992359095393126, + "holonomicAngularVelocity": 0.45161910465029553 + }, + { + "time": 1.9615380789671784, + "pose": { + "rotation": { + "radians": 1.5504316673805267 + }, + "translation": { + "x": 2.999778128667078, + "y": 4.9725854051408565 + } + }, + "velocity": 0.2863455115977193, + "acceleration": -2.9999999999999973, + "curvature": 0.6014193265576269, + "holonomicRotation": 89.9857885177485, + "angularVelocity": 0.08584460121184416, + "holonomicAngularVelocity": 0.11166724455106 + }, + { + "time": 2.0569865828330847, + "pose": { + "rotation": { + "radians": 1.5586254061311626 + }, + "translation": { + "x": 2.9999444478026054, + "y": 4.9862500183352205 + } + }, + "velocity": 0, + "acceleration": -3.000000000000004, + "curvature": 0.6014193265576269, + "holonomicRotation": 89.99644698917173, + "angularVelocity": 0.0, + "holonomicAngularVelocity": 0.0 + }, + { + "time": 2.0569865828330847, + "pose": { + "rotation": { + "radians": 1.5742753890751118 + }, + "translation": { + "x": 3.0, + "y": 5.0 + } + }, + "velocity": 0, + "acceleration": -3.0, + "curvature": -0.5057336661187407, + "holonomicRotation": 90.0, + "angularVelocity": 0.0, + "holonomicAngularVelocity": -0.03707165103584605 + }, + { + "time": 2.1528283036357116, + "pose": { + "rotation": { + "radians": 1.5742753890751118 + }, + "translation": { + "x": 3.000047936, + "y": 4.986221630216636 + } + }, + "velocity": -0.287525162407881, + "acceleration": -2.9999999999999996, + "curvature": -0.5057336661187407, + "holonomicRotation": 89.99644698917173, + "angularVelocity": 0.17565459412480444, + "holonomicAngularVelocity": -0.26895297967861 + }, + { + "time": 2.192457801088997, + "pose": { + "rotation": { + "radians": 1.5812364923656386 + }, + "translation": { + "x": 3.000191488, + "y": 4.972472156282768 + } + }, + "velocity": -0.4064136547677368, + "acceleration": -3.0, + "curvature": -0.5068077788280827, + "holonomicRotation": 89.9857885177485, + "angularVelocity": 0.22928766634703351, + "holonomicAngularVelocity": -0.5850105091967069 + }, + { + "time": 2.2228200743178532, + "pose": { + "rotation": { + "radians": 1.588198187139274 + }, + "translation": { + "x": 3.000430272, + "y": 4.958751790094678 + } + }, + "velocity": -0.4975004744543062, + "acceleration": -3.000000000000001, + "curvature": -0.5078447188468552, + "holonomicRotation": 89.96802626882652, + "angularVelocity": 0.27239456891071173, + "holonomicAngularVelocity": -0.9728038942611524 + }, + { + "time": 2.248378382320534, + "pose": { + "rotation": { + "radians": 1.5951601314297514 + }, + "translation": { + "x": 3.000763904, + "y": 4.9450607435486456 + } + }, + "velocity": -0.5741753984623478, + "acceleration": -2.999999999999998, + "curvature": -0.508844493249413, + "holonomicRotation": 89.94316304727079, + "angularVelocity": 0.3096323802410236, + "holonomicAngularVelocity": -1.4214508491667075 + }, + { + "time": 2.270862640581948, + "pose": { + "rotation": { + "radians": 1.602121985833187 + }, + "translation": { + "x": 3.001192, + "y": 4.931399228540954 + } + }, + "velocity": -0.6416281732465902, + "acceleration": -3.0000000000000013, + "curvature": -0.5098071295921854, + "holonomicRotation": 89.91120277927222, + "angularVelocity": 0.3429615754353077, + "holonomicAngularVelocity": -1.9239482966682593 + }, + { + "time": 2.291160622399972, + "pose": { + "rotation": { + "radians": 1.6090834136556538 + }, + "translation": { + "x": 3.001714176, + "y": 4.917767456967881 + } + }, + "velocity": -0.7025221187006625, + "acceleration": -3.0, + "curvature": -0.5107326758902916, + "holonomicRotation": 89.87215051172763, + "angularVelocity": 0.37343784439063415, + "holonomicAngularVelocity": -2.475296076666404 + }, + { + "time": 2.3098000493031976, + "pose": { + "rotation": { + "radians": 1.616044081059071 + }, + "translation": { + "x": 3.0023300479999997, + "y": 4.904165640725709 + } + }, + "velocity": -0.7584403994103386, + "acceleration": -2.9999999999999987, + "curvature": -0.5116212004719533, + "holonomicRotation": 89.82601241144276, + "angularVelocity": 0.4017085053948185, + "holonomicAngularVelocity": -3.0716784178770995 + }, + { + "time": 2.327124990278309, + "pose": { + "rotation": { + "radians": 1.6230036572042366 + }, + "translation": { + "x": 3.0030392320000003, + "y": 4.890593991710718 + } + }, + "velocity": -0.8104152223356732, + "acceleration": -2.999999999999997, + "curvature": -0.5124727917725321, + "holonomicRotation": 89.77279576415852, + "angularVelocity": 0.4282045821605271, + "holonomicAngularVelocity": -3.71004554133979 + }, + { + "time": 2.3433745996392688, + "pose": { + "rotation": { + "radians": 1.629961814390918 + }, + "translation": { + "x": 3.003841344, + "y": 4.87705272181919 + } + }, + "velocity": -0.8591640504185518, + "acceleration": -3.0, + "curvature": -0.5132875582522389, + "holonomicRotation": 89.71250897340038, + "angularVelocity": 0.45323008286571875, + "holonomicAngularVelocity": -4.387874987552203 + }, + { + "time": 2.358723125848408, + "pose": { + "rotation": { + "radians": 1.6369182281965529 + }, + "translation": { + "x": 3.004736, + "y": 4.863542042947403 + } + }, + "velocity": -0.9052096290459696, + "acceleration": -3.0000000000000036, + "curvature": -0.5140656281361321, + "holonomicRotation": 89.6451615591515, + "angularVelocity": 0.477008781354567, + "holonomicAngularVelocity": -5.103024356948047 + }, + { + "time": 2.373302206330536, + "pose": { + "rotation": { + "radians": 1.643872577610603 + }, + "translation": { + "x": 3.005722816, + "y": 4.85006216699164 + } + }, + "velocity": -0.9489468704923536, + "acceleration": -2.999999999999996, + "curvature": -0.5148071492013819, + "holonomicRotation": 89.5707641563493, + "angularVelocity": 0.49971092182910903, + "holonomicAngularVelocity": -5.853634956609349 + }, + { + "time": 2.3872141847416968, + "pose": { + "rotation": { + "radians": 1.6508245451669108 + }, + "translation": { + "x": 3.0068014080000003, + "y": 4.83661330584818 + } + }, + "velocity": -0.9906828057258363, + "acceleration": -2.999999999999996, + "curvature": -0.5155122885814692, + "holonomicRotation": 89.48932851320613, + "angularVelocity": 0.5214694818560188, + "holonomicAngularVelocity": -6.638065814143911 + }, + { + "time": 2.400540509958839, + "pose": { + "rotation": { + "radians": 1.6577738170729388 + }, + "translation": { + "x": 3.007971392, + "y": 4.823195671413306 + } + }, + "velocity": -1.0306617813772634, + "acceleration": -3.000000000000004, + "curvature": -0.5161812324778612, + "holonomicRotation": 89.40086748935406, + "angularVelocity": 0.542390592745728, + "holonomicAngularVelocity": -7.45484681173555 + }, + { + "time": 2.4133472701714718, + "pose": { + "rotation": { + "radians": 1.6647200833358209 + }, + "translation": { + "x": 3.009232384, + "y": 4.809809475583298 + } + }, + "velocity": -1.0690820620151604, + "acceleration": -2.999999999999991, + "curvature": -0.516814185876635, + "holonomicRotation": 89.30539505381425, + "angularVelocity": 0.5625604962136552, + "holonomicAngularVelocity": -8.30264439528027 + }, + { + "time": 2.425688973145226, + "pose": { + "rotation": { + "radians": 1.6716630378848576 + }, + "translation": { + "x": 3.010584, + "y": 4.796454930254436 + } + }, + "velocity": -1.106107170936423, + "acceleration": -2.9999999999999956, + "curvature": -0.5174113722714463, + "holonomicRotation": 89.202926282791, + "angularVelocity": 0.5820503490649594, + "holonomicAngularVelocity": -9.180235856393876 + }, + { + "time": 2.437611207738323, + "pose": { + "rotation": { + "radians": 1.6786023786914042 + }, + "translation": { + "x": 3.012025856, + "y": 4.7831322473230005 + } + }, + "velocity": -1.1418738747157147, + "acceleration": -3.0000000000000044, + "curvature": -0.5179730333484562, + "holonomicRotation": 89.0934773572911, + "angularVelocity": 0.6009196375531689, + "holonomicAngularVelocity": -10.086489637904608 + }, + { + "time": 2.4491525666155414, + "pose": { + "rotation": { + "radians": 1.6855378078847734 + }, + "translation": { + "x": 3.013557568, + "y": 4.769841638685271 + } + }, + "velocity": -1.1764979513473701, + "acceleration": -2.9999999999999902, + "curvature": -0.5184994287118657, + "holonomicRotation": 88.9770655605687, + "angularVelocity": 0.6192186636953354, + "holonomicAngularVelocity": -11.020349981504285 + }, + { + "time": 2.460346066402732, + "pose": { + "rotation": { + "radians": 1.6924690318650715 + }, + "translation": { + "x": 3.0151787519999997, + "y": 4.756583316237531 + } + }, + "velocity": -1.2100784507089415, + "acceleration": -2.999999999999995, + "curvature": -0.5189908354035975, + "holonomicRotation": 88.85370927539597, + "angularVelocity": 0.636990394203234, + "holonomicAngularVelocity": -11.980824775627683 + }, + { + "time": 2.4712202171123465, + "pose": { + "rotation": { + "radians": 1.6993957614122142 + }, + "translation": { + "x": 3.016889024, + "y": 4.74335749187606 + } + }, + "velocity": -1.242700902837785, + "acceleration": -3.000000000000005, + "curvature": -0.5194475476872736, + "holonomicRotation": 88.72342798116031, + "angularVelocity": 0.6542718609777953, + "holonomicAngularVelocity": -12.966975807849181 + }, + { + "time": 2.4817998412594715, + "pose": { + "rotation": { + "radians": 1.7063177117913995 + }, + "translation": { + "x": 3.018688, + "y": 4.73016437749714 + } + }, + "velocity": -1.2744397752791607, + "acceleration": -2.9999999999999893, + "curvature": -0.5198698765939959, + "holonomicRotation": 88.5862422507884, + "angularVelocity": 0.6710952392501868, + "holonomicAngularVelocity": -13.977910854785828 + }, + { + "time": 2.4921067107757953, + "pose": { + "rotation": { + "radians": 1.713234602855377 + }, + "translation": { + "x": 3.020575296, + "y": 4.717004184997049 + } + }, + "velocity": -1.3053603838281316, + "acceleration": -3.0000000000000053, + "curvature": -0.5202581495425616, + "holonomicRotation": 88.44217374749732, + "angularVelocity": 0.6874886894244737, + "holonomicAngularVelocity": -15.012777197368143 + }, + { + "time": 2.502160048951621, + "pose": { + "rotation": { + "radians": 1.7201461591422165 + }, + "translation": { + "x": 3.022550528, + "y": 4.703877126272069 + } + }, + "velocity": -1.3355203983556083, + "acceleration": -2.9999999999999947, + "curvature": -0.5206127099914765, + "holonomicRotation": 88.29124522137386, + "angularVelocity": 0.7034770231023145, + "holonomicAngularVelocity": -16.07075625679041 + }, + { + "time": 2.5119769308127515, + "pose": { + "rotation": { + "radians": 1.7270521099700318 + }, + "translation": { + "x": 3.024613312, + "y": 4.69078341321848 + } + }, + "velocity": -1.3649710439390004, + "acceleration": -3.0000000000000058, + "curvature": -0.520933916894771, + "holonomicRotation": 88.13348050578192, + "angularVelocity": 0.7190822359132523, + "holonomicAngularVelocity": -17.151059122085808 + }, + { + "time": 2.5215726059842662, + "pose": { + "rotation": { + "radians": 1.7339521895274617 + }, + "translation": { + "x": 3.026763264, + "y": 4.6777232577325645 + } + }, + "velocity": -1.3937580694535436, + "acceleration": -2.9999999999999942, + "curvature": -0.5212221444517889, + "holonomicRotation": 87.96890451359894, + "angularVelocity": 0.7343239383776761, + "holonomicAngularVelocity": -18.25292279485364 + }, + { + "time": 2.530960761637088, + "pose": { + "rotation": { + "radians": 1.7408461369605446 + }, + "translation": { + "x": 3.0290000000000004, + "y": 4.664696871710602 + } + }, + "velocity": -1.4219225364120098, + "acceleration": -3.000000000000012, + "curvature": -0.521477781524844, + "holonomicRotation": 87.79754323328191, + "angularVelocity": 0.7492197075330436, + "holonomicAngularVelocity": -19.375607016536954 + }, + { + "time": 2.5401537385779607, + "pose": { + "rotation": { + "radians": 1.7477336964555432 + }, + "translation": { + "x": 3.031323136, + "y": 4.651704467048874 + } + }, + "velocity": -1.449501467234628, + "acceleration": -3.000000000000018, + "curvature": -0.5217012312954975, + "holonomicRotation": 87.61942372476348, + "angularVelocity": 0.763785376451716, + "holonomicAngularVelocity": -20.518391573003203 + }, + { + "time": 2.54916271030593, + "pose": { + "rotation": { + "radians": 1.754614617318233 + }, + "translation": { + "x": 3.033732288, + "y": 4.638746255643659 + } + }, + "velocity": -1.476528382418536, + "acceleration": -3.0000000000000187, + "curvature": -0.5218929107130195, + "holonomicRotation": 87.43457411517889, + "angularVelocity": 0.7780352743756296, + "holonomicAngularVelocity": -21.6805739935594 + }, + { + "time": 2.5579978325130934, + "pose": { + "rotation": { + "radians": 1.7614886540488257 + }, + "translation": { + "x": 3.036227072, + "y": 4.62582244939124 + } + }, + "velocity": -1.5030337490400265, + "acceleration": -3.0000000000000253, + "curvature": -0.5220532500924302, + "holonomicRotation": 87.24302359442434, + "angularVelocity": 0.7919824274550814, + "holonomicAngularVelocity": -22.86146757815466 + }, + { + "time": 2.566668368785499, + "pose": { + "rotation": { + "radians": 1.7683555664131827 + }, + "translation": { + "x": 3.038807104, + "y": 4.612933260187897 + } + }, + "velocity": -1.529045357857243, + "acceleration": -3.000000000000013, + "curvature": -0.5221826926786177, + "holonomicRotation": 87.04480241054753, + "angularVelocity": 0.8056387276148198, + "holonomicAngularVelocity": -24.06039969965495 + }, + { + "time": 2.5751827969801044, + "pose": { + "rotation": { + "radians": 1.7752151195102526 + }, + "translation": { + "x": 3.041472, + "y": 4.600078899929912 + } + }, + "velocity": -1.5545886424410602, + "acceleration": -3.000000000000026, + "curvature": -0.5222816940473599, + "holonomicRotation": 86.83994186497131, + "angularVelocity": 0.819015075408048, + "holonomicAngularVelocity": -25.27671033811035 + }, + { + "time": 2.5835488997914293, + "pose": { + "rotation": { + "radians": 1.7820670838351411 + }, + "translation": { + "x": 3.044221376, + "y": 4.587259580513562 + } + }, + "velocity": -1.5796869508750342, + "acceleration": -3.0, + "curvature": -0.5223507217767429, + "holonomicRotation": 86.6284743075506, + "angularVelocity": 0.8321215017430816, + "holonomicAngularVelocity": -26.509750811682704 + }, + { + "time": 2.591773842290336, + "pose": { + "rotation": { + "radians": 1.7889112353390821 + }, + "translation": { + "x": 3.047054848, + "y": 4.574475513835131 + } + }, + "velocity": -1.6043617783717554, + "acceleration": -3.0000000000000133, + "curvature": -0.5223902548388374, + "holonomicRotation": 86.41043313146416, + "angularVelocity": 0.8449672717787239, + "holonomicAngularVelocity": -27.758882675285424 + }, + { + "time": 2.5998642386564272, + "pose": { + "rotation": { + "radians": 1.7957473554841465 + }, + "translation": { + "x": 3.0499720320000003, + "y": 4.5617269117909 + } + }, + "velocity": -1.6286329674700286, + "acceleration": -3.0000000000000275, + "curvature": -0.5224007831335928, + "holonomicRotation": 86.18585276794128, + "angularVelocity": 0.8575609745438143, + "holonomicAngularVelocity": -29.023476762925224 + }, + { + "time": 2.607826209891096, + "pose": { + "rotation": { + "radians": 1.8025752312954388 + }, + "translation": { + "x": 3.0529725439999997, + "y": 4.5490139862771475 + } + }, + "velocity": -1.6525188811740348, + "acceleration": -3.0000000000000138, + "curvature": -0.5223828070623401, + "holonomicRotation": 85.9547686808248, + "angularVelocity": 0.8699106001067596, + "holonomicAngularVelocity": -30.302912353676327 + }, + { + "time": 2.615665433959112, + "pose": { + "rotation": { + "radians": 1.809394655408818 + }, + "translation": { + "x": 3.0560560000000003, + "y": 4.536336949190155 + } + }, + "velocity": -1.6760365533780828, + "acceleration": -2.9999999999999716, + "curvature": -0.5223368369618795, + "holonomicRotation": 85.71721736097088, + "angularVelocity": 0.8820236064459887, + "holonomicAngularVelocity": -31.596576444504613 + }, + { + "time": 2.6233871895395846, + "pose": { + "rotation": { + "radians": 1.816205426114001 + }, + "translation": { + "x": 3.059222016, + "y": 4.523696012426204 + } + }, + "velocity": -1.699201820119501, + "acceleration": -3.0, + "curvature": -0.5222633926490773, + "holonomicRotation": 85.47323632048669, + "angularVelocity": 0.8939069779563974, + "holonomicAngularVelocity": -32.90386311573669 + }, + { + "time": 2.630996394355419, + "pose": { + "rotation": { + "radians": 1.823007347395575 + }, + "translation": { + "x": 3.062470208, + "y": 4.511091387881574 + } + }, + "velocity": -1.7220294345670046, + "acceleration": -2.9999999999999853, + "curvature": -0.5221630028621961, + "holonomicRotation": 85.22286408680687, + "angularVelocity": 0.9055672761180343, + "holonomicAngularVelocity": -34.22417297723497 + }, + { + "time": 2.6384976388812733, + "pose": { + "rotation": { + "radians": 1.829800228968348 + }, + "translation": { + "x": 3.065800192, + "y": 4.498523287452546 + } + }, + "velocity": -1.7445331681445666, + "acceleration": -3.0, + "curvature": -0.5220362048391741, + "holonomicRotation": 84.9661401966095, + "angularVelocity": 0.9170106842737414, + "holonomicAngularVelocity": -35.556912684970456 + }, + { + "time": 2.6458952160940945, + "pose": { + "rotation": { + "radians": 1.8365838863102448 + }, + "translation": { + "x": 3.069211584, + "y": 4.485991923035402 + } + }, + "velocity": -1.76672589978303, + "acceleration": -3.000000000000015, + "curvature": -0.5218835437565383, + "holonomicRotation": 84.7031051895729, + "angularVelocity": 0.9282430467271324, + "holonomicAngularVelocity": -36.9014945192324 + }, + { + "time": 2.653193147820374, + "pose": { + "rotation": { + "radians": 1.8433581406906532 + }, + "translation": { + "x": 3.072704, + "y": 4.473497506526421 + } + }, + "velocity": -1.7886196949618687, + "acceleration": -3.0, + "curvature": -0.521705572307682, + "holonomicRotation": 84.43380060197386, + "angularVelocity": 0.9392699033985431, + "holonomicAngularVelocity": -38.2573360170749 + }, + { + "time": 2.660395208144758, + "pose": { + "rotation": { + "radians": 1.850122819195808 + }, + "translation": { + "x": 3.0762770560000003, + "y": 4.461040249821885 + } + }, + "velocity": -1.810225875935021, + "acceleration": -3.0, + "curvature": -0.5215028501053297, + "holonomicRotation": 84.15826896012865, + "angularVelocity": 0.9500965202307644, + "holonomicAngularVelocity": -39.623859652300446 + }, + { + "time": 2.6675049442715038, + "pose": { + "rotation": { + "radians": 1.856877754749588 + }, + "translation": { + "x": 3.0799303680000003, + "y": 4.4486203648180735 + } + }, + "velocity": -1.8315550843152586, + "acceleration": -3.000000000000031, + "curvature": -0.5212759433218822, + "holonomicRotation": 83.87655377367759, + "angularVelocity": 0.9607279164011417, + "holonomicAngularVelocity": -41.00049255752908 + }, + { + "time": 2.674525695170029, + "pose": { + "rotation": { + "radians": 1.8636227861318995 + }, + "translation": { + "x": 3.083663552, + "y": 4.436238063411268 + } + }, + "velocity": -1.8526173370108336, + "acceleration": -2.999999999999984, + "curvature": -0.5210254240939713, + "holonomicRotation": 83.58869952871434, + "angularVelocity": 0.9711688882073912, + "holonomicAngularVelocity": -42.38666628337523 + }, + { + "time": 2.6814606082860557, + "pose": { + "rotation": { + "radians": 1.8703577579926058 + }, + "translation": { + "x": 3.087476224, + "y": 4.423893557497749 + } + }, + "velocity": -1.8734220763589131, + "acceleration": -2.999999999999968, + "curvature": -0.5207518700684239, + "holonomicRotation": 83.29475168076112, + "angularVelocity": 0.981424030448601, + "holonomicAngularVelocity": -43.78181659045681 + }, + { + "time": 2.6883126545585223, + "pose": { + "rotation": { + "radians": 1.8770825208621504 + }, + "translation": { + "x": 3.091368, + "y": 4.411587058973797 + } + }, + "velocity": -1.8939782151763134, + "acceleration": -3.000000000000016, + "curvature": -0.5204558639450751, + "holonomicRotation": 82.99475664759066, + "angularVelocity": 0.9914977555239444, + "holonomicAngularVelocity": -45.18538327053407 + }, + { + "time": 2.695084641947945, + "pose": { + "rotation": { + "radians": 1.8837969311591998 + }, + "translation": { + "x": 3.095338496, + "y": 4.399318779735693 + } + }, + "velocity": -1.914294177344582, + "acceleration": -2.999999999999967, + "curvature": -0.5201379930167327, + "holonomicRotation": 82.68876180189636, + "angularVelocity": 1.0013943103829934, + "holonomicAngularVelocity": -46.596809993490176 + }, + { + "time": 2.7017792276530264, + "pose": { + "rotation": { + "radians": 1.8905008511946395 + }, + "translation": { + "x": 3.099387328, + "y": 4.387088931679718 + } + }, + "velocity": -1.934377934459826, + "acceleration": -3.0, + "curvature": -0.5197988486561339, + "holonomicRotation": 82.37681546381155, + "angularVelocity": 1.0111177916912393, + "holonomicAngularVelocity": -48.01554417719809 + }, + { + "time": 2.708398929168005, + "pose": { + "rotation": { + "radians": 1.8971941491721198 + }, + "translation": { + "x": 3.103514112, + "y": 4.3748977267021525 + } + }, + "velocity": -1.9542370390047616, + "acceleration": -2.999999999999983, + "curvature": -0.5194390259123196, + "holonomicRotation": 82.05896689327923, + "angularVelocity": 1.0206721594876074, + "holonomicAngularVelocity": -49.4410368778254 + }, + { + "time": 2.714946134312709, + "pose": { + "rotation": { + "radians": 1.9038766991857727 + }, + "translation": { + "x": 3.1077184640000004, + "y": 4.362745376699276 + } + }, + "velocity": -1.9738786544388722, + "acceleration": -3.0, + "curvature": -0.5190591229932082, + "holonomicRotation": 81.73526628227326, + "angularVelocity": 1.030061249349988, + "holonomicAngularVelocity": -50.8727426982381 + }, + { + "time": 2.7214231103498596, + "pose": { + "rotation": { + "radians": 1.9105483812146105 + }, + "translation": { + "x": 3.112, + "y": 4.350632093567372 + } + }, + "velocity": -1.9933095825503253, + "acceleration": -3.0, + "curvature": -0.5186597408707463, + "holonomicRotation": 81.40576474687262, + "angularVelocity": 1.0392887833198277, + "holonomicAngularVelocity": -52.31011971248371 + }, + { + "time": 2.7278320122894053, + "pose": { + "rotation": { + "radians": 1.9172090811137767 + }, + "translation": { + "x": 3.1163583360000002, + "y": 4.338558089202717 + } + }, + "velocity": -2.012536288368962, + "acceleration": -3.0000000000000346, + "curvature": -0.518241482848376, + "holonomicRotation": 81.07051431918943, + "angularVelocity": 1.0483583797739298, + "holonomicAngularVelocity": -53.75262940469507 + }, + { + "time": 2.7341748904669525, + "pose": { + "rotation": { + "radians": 1.923858690603094 + }, + "translation": { + "x": 3.120793088, + "y": 4.326523575501596 + } + }, + "velocity": -2.0315649229016044, + "acceleration": -2.9999999999999827, + "curvature": -0.5178049541021739, + "holonomicRotation": 80.72956793915259, + "angularVelocity": 1.057273562202763, + "holonomicAngularVelocity": -55.19973662061289 + }, + { + "time": 2.7404536974726246, + "pose": { + "rotation": { + "radians": 1.9304971072523642 + }, + "translation": { + "x": 3.1253038720000004, + "y": 4.314528764360286 + } + }, + "velocity": -2.0504013439186197, + "acceleration": -2.9999999999999645, + "curvature": -0.5173507612460925, + "holonomicRotation": 80.38297944614784, + "angularVelocity": 1.0660377671971724, + "holonomicAngularVelocity": -56.65090953051544 + }, + { + "time": 2.7466702944972865, + "pose": { + "rotation": { + "radians": 1.9371242344640995 + }, + "translation": { + "x": 3.1298903040000003, + "y": 4.302573867675071 + } + }, + "velocity": -2.069051134992606, + "acceleration": -3.0000000000000178, + "curvature": -0.5168795119868999, + "holonomicRotation": 80.03080357051604, + "angularVelocity": 1.0746543515953761, + "holonomicAngularVelocity": -58.10561960214269 + }, + { + "time": 2.7528264571551295, + "pose": { + "rotation": { + "radians": 1.9437399814534793 + }, + "translation": { + "x": 3.1345520000000002, + "y": 4.29065909734223 + } + }, + "velocity": -2.0875196229661346, + "acceleration": -3.000000000000036, + "curvature": -0.5163918146518766, + "holonomicRotation": 79.67309592491051, + "angularVelocity": 1.0831265989126386, + "holonomicAngularVelocity": -59.563341582570494 + }, + { + "time": 2.7589238808346237, + "pose": { + "rotation": { + "radians": 1.9503442632255794 + }, + "translation": { + "x": 3.139288576, + "y": 4.278784665258044 + } + }, + "velocity": -2.105811894004618, + "acceleration": -3.0000000000000364, + "curvature": -0.5158882778577482, + "holonomicRotation": 79.30991299551513, + "angularVelocity": 1.0914577251328634, + "holonomicAngularVelocity": -61.02355348789271 + }, + { + "time": 2.764964185623882, + "pose": { + "rotation": { + "radians": 1.9569370005499724 + }, + "translation": { + "x": 3.144099648, + "y": 4.266950783318793 + } + }, + "velocity": -2.123932808372393, + "acceleration": -3.0, + "curvature": -0.5153695100652415, + "holonomicRotation": 78.94131213312465, + "angularVelocity": 1.0996508839876262, + "holonomicAngularVelocity": -62.485736599971624 + }, + { + "time": 2.7709489208512275, + "pose": { + "rotation": { + "radians": 1.9635181199331546 + }, + "translation": { + "x": 3.1489848320000005, + "y": 4.255157663420759 + } + }, + "velocity": -2.1418870140544293, + "acceleration": -3.0000000000000555, + "curvature": -0.51483611928948, + "holonomicRotation": 78.56735154408818, + "angularVelocity": 1.1077091715727203, + "holonomicAngularVelocity": -63.94937546922451 + }, + { + "time": 2.7768795692772295, + "pose": { + "rotation": { + "radians": 1.9700875535880105 + }, + "translation": { + "x": 3.153943744, + "y": 4.243405517460222 + } + }, + "velocity": -2.1596789593324357, + "acceleration": -3.0000000000000187, + "curvature": -0.5142887126180925, + "holonomicRotation": 78.18809028111781, + "angularVelocity": 1.1156356307027255, + "holonomicAngularVelocity": -65.41395792283565 + }, + { + "time": 2.7827575509704925, + "pose": { + "rotation": { + "radians": 1.9766452394016332 + }, + "translation": { + "x": 3.158976, + "y": 4.231694557333463 + } + }, + "velocity": -2.1773129044122252, + "acceleration": -3.000000000000019, + "curvature": -0.5137278959903189, + "holonomicRotation": 77.8035882339635, + "angularVelocity": 1.1234332546485775, + "holonomicAngularVelocity": -66.87897507773808 + }, + { + "time": 2.7885842268959946, + "pose": { + "rotation": { + "radians": 1.9831911209004023 + }, + "translation": { + "x": 3.164081216, + "y": 4.220024994936762 + } + }, + "velocity": -2.194792932188731, + "acceleration": -3.000000000000038, + "curvature": -0.5131542737842859, + "holonomicRotation": 77.4139061199558, + "angularVelocity": 1.1311049906097959, + "holonomicAngularVelocity": -68.34392135764897 + }, + { + "time": 2.7943609022417353, + "pose": { + "rotation": { + "radians": 1.9897251472131021 + }, + "translation": { + "x": 3.1692590080000005, + "y": 4.2083970421664 + } + }, + "velocity": -2.212122958225953, + "acceleration": -3.0, + "curvature": -0.512568448497083, + "holonomicRotation": 77.01910547441783, + "angularVelocity": 1.1386537427992665, + "holonomicAngularVelocity": -69.80829451368561 + }, + { + "time": 2.800088829506757, + "pose": { + "rotation": { + "radians": 1.9962472730319014 + }, + "translation": { + "x": 3.1745089920000003, + "y": 4.196810910918658 + } + }, + "velocity": -2.2293067400210194, + "acceleration": -3.0000000000000195, + "curvature": -0.5119710204146639, + "holonomicRotation": 76.6192486409482, + "angularVelocity": 1.146082375300637, + "holonomicAngularVelocity": -71.27159564806851 + }, + { + "time": 2.8057692113712394, + "pose": { + "rotation": { + "radians": 2.002757458571762 + }, + "translation": { + "x": 3.1798307840000004, + "y": 4.185266813089816 + } + }, + "velocity": -2.246347885614466, + "acceleration": -3.0, + "curvature": -0.5113625873507105, + "holonomicRotation": 76.2143987615762, + "angularVelocity": 1.1533937144450512, + "holonomicAngularVelocity": -72.73332924047713 + }, + { + "time": 2.811403203367266, + "pose": { + "rotation": { + "radians": 2.009255669527213 + }, + "translation": { + "x": 3.1852240000000003, + "y": 4.173764960576157 + } + }, + "velocity": -2.263249861602546, + "acceleration": -2.999999999999941, + "curvature": -0.5107437442964814, + "holonomicRotation": 75.80461976679098, + "angularVelocity": 1.1605905511796997, + "holonomicAngularVelocity": -74.1930031765793 + }, + { + "time": 2.816991916367036, + "pose": { + "rotation": { + "radians": 2.0157418770280007 + }, + "translation": { + "x": 3.190688256, + "y": 4.162305565273958 + } + }, + "velocity": -2.280016000601855, + "acceleration": -2.99999999999998, + "curvature": -0.5101150831929077, + "holonomicRotation": 75.38997636544607, + "angularVelocity": 1.167675643067086, + "holonomicAngularVelocity": -75.65012877847903 + }, + { + "time": 2.8225364189036144, + "pose": { + "rotation": { + "radians": 2.022216057592887 + }, + "translation": { + "x": 3.1962231680000004, + "y": 4.150888839079503 + } + }, + "velocity": -2.2966495082115905, + "acceleration": -3.0, + "curvature": -0.5094771925471605, + "holonomicRotation": 74.9705340345413, + "angularVelocity": 1.1746517159963967, + "holonomicAngularVelocity": -77.10422083667376 + }, + { + "time": 2.8280377393378977, + "pose": { + "rotation": { + "radians": 2.028678193081264 + }, + "translation": { + "x": 3.2018283520000006, + "y": 4.13951499388907 + } + }, + "velocity": -2.3131534695144405, + "acceleration": -3.0, + "curvature": -0.5088306573722707, + "holonomicRotation": 74.54635900888302, + "angularVelocity": 1.1815214660057185, + "holonomicAngularVelocity": -78.55479764327413 + }, + { + "time": 2.833496867884132, + "pose": { + "rotation": { + "radians": 2.035128270644324 + }, + "translation": { + "x": 3.2075034240000004, + "y": 4.128184241598942 + } + }, + "velocity": -2.3295308551531426, + "acceleration": -3.000000000000041, + "curvature": -0.5081760586777138, + "holonomicRotation": 74.11751827062498, + "angularVelocity": 1.1882875605163865, + "holonomicAngularVelocity": -80.00138102615517 + }, + { + "time": 2.838914758505198, + "pose": { + "rotation": { + "radians": 2.0415662826735756 + }, + "translation": { + "x": 3.2132480000000005, + "y": 4.116896794105398 + } + }, + "velocity": -2.3457845270163418, + "acceleration": -3.0000000000000204, + "curvature": -0.5075139734310048, + "holonomicRotation": 73.68407953869102, + "angularVelocity": 1.1949526397867256, + "holonomicAngularVelocity": -81.4434963839311 + }, + { + "time": 2.844292330687818, + "pose": { + "rotation": { + "radians": 2.047992226748841 + }, + "translation": { + "x": 3.2190616960000002, + "y": 4.105652863304721 + } + }, + "velocity": -2.3619172435642013, + "acceleration": -3.0000000000000204, + "curvature": -0.5068449742568512, + "holonomicRotation": 73.2461112580815, + "angularVelocity": 1.2015193179741286, + "holonomicAngularVelocity": -82.8806727213178 + }, + { + "time": 2.8496304711069254, + "pose": { + "rotation": { + "radians": 2.054406105584457 + }, + "translation": { + "x": 3.2249441280000006, + "y": 4.094452661093189 + } + }, + "velocity": -2.3779316648215234, + "acceleration": -2.999999999999979, + "curvature": -0.5061696291938161, + "holonomicRotation": 72.80368258906502, + "angularVelocity": 1.2079901842417025, + "holonomicAngularVelocity": -84.31244268503457 + }, + { + "time": 2.8549300351876026, + "pose": { + "rotation": { + "radians": 2.0608079269746753 + }, + "translation": { + "x": 3.230894912, + "y": 4.083296399367084 + } + }, + "velocity": -2.393830357063556, + "acceleration": -2.999999999999979, + "curvature": -0.5054885015363642, + "holonomicRotation": 72.35686339625722, + "angularVelocity": 1.2143678036086012, + "holonomicAngularVelocity": -85.73834259958811 + }, + { + "time": 2.860191848572261, + "pose": { + "rotation": { + "radians": 2.067197703737601 + }, + "translation": { + "x": 3.2369136640000002, + "y": 4.072184290022687 + } + }, + "velocity": -2.40961579721753, + "acceleration": -2.999999999999958, + "curvature": -0.5048021496278324, + "holonomicRotation": 71.90572423758832, + "angularVelocity": 1.2206547177528895, + "holonomicAngularVelocity": -87.15791250329711 + }, + { + "time": 2.8654167085000366, + "pose": { + "rotation": { + "radians": 2.073575453658038 + }, + "translation": { + "x": 3.2430000000000003, + "y": 4.061116544956278 + } + }, + "velocity": -2.425290377000857, + "acceleration": -3.000000000000064, + "curvature": -0.5041111265899505, + "holonomicRotation": 71.45033635316126, + "angularVelocity": 1.2268534457939924, + "holonomicAngularVelocity": -88.57069618405971 + }, + { + "time": 2.870605385104816, + "pose": { + "rotation": { + "radians": 2.0799411994297223 + }, + "translation": { + "x": 3.249153536, + "y": 4.050093376064137 + } + }, + "velocity": -2.440856406815195, + "acceleration": -3.0, + "curvature": -0.5034159803157897, + "holonomicRotation": 70.99077165400202, + "angularVelocity": 1.229578840879155, + "holonomicAngularVelocity": -89.72902648596558 + }, + { + "time": 2.87577282045385, + "pose": { + "rotation": { + "radians": 2.0862949685965058 + }, + "translation": { + "x": 3.2553738880000003, + "y": 4.039114995242547 + } + }, + "velocity": -2.442860865424066, + "acceleration": -0.3879020197603165, + "curvature": -0.5027172531268748, + "holonomicRotation": 70.52710271070401, + "angularVelocity": 1.2287989005424262, + "holonomicAngularVelocity": -90.62205545373247 + }, + { + "time": 2.880933815383769, + "pose": { + "rotation": { + "radians": 2.0926367934920957 + }, + "translation": { + "x": 3.2616606720000005, + "y": 4.028181614387787 + } + }, + "velocity": -2.444567716338234, + "acceleration": -0.330721292569582, + "curvature": -0.5020154817355811, + "holonomicRotation": 70.05940274196843, + "angularVelocity": 1.2279368134428386, + "holonomicAngularVelocity": -91.49647637683879 + }, + { + "time": 2.8860887367272294, + "pose": { + "rotation": { + "radians": 2.0989667111801324 + }, + "translation": { + "x": 3.2680135040000002, + "y": 4.017293445396137 + } + }, + "velocity": -2.446284282103891, + "acceleration": -0.3329955301518617, + "curvature": -0.50131119707638, + "holonomicRotation": 69.58774560304208, + "angularVelocity": 1.2270709076372577, + "holonomicAngularVelocity": -92.35775044436066 + }, + { + "time": 2.8912376259834023, + "pose": { + "rotation": { + "radians": 2.105284763393028 + }, + "translation": { + "x": 3.2744320000000005, + "y": 4.006450700163881 + } + }, + "velocity": -2.4480093305759216, + "acceleration": -0.33503312776881694, + "curvature": -0.5006049240997247, + "holonomicRotation": 69.11220577405483, + "angularVelocity": 1.2262018193366309, + "holonomicAngularVelocity": -93.20567103737582 + }, + { + "time": 2.8963805257711663, + "pose": { + "rotation": { + "radians": 2.1115909964694506 + }, + "translation": { + "x": 3.2809157760000005, + "y": 3.9956535905872963 + } + }, + "velocity": -2.449741633776713, + "acceleration": -0.33683394043815795, + "curvature": -0.49989718179259984, + "holonomicRotation": 68.63285834825828, + "angularVelocity": 1.2253301792953024, + "holonomicAngularVelocity": -94.04003299918955 + }, + { + "time": 2.9015174798181165, + "pose": { + "rotation": { + "radians": 2.1178854612928317 + }, + "translation": { + "x": 3.2874644480000006, + "y": 3.9849023285626646 + } + }, + "velocity": -2.4514799686116775, + "acceleration": -0.3383979726267414, + "curvature": -0.4991884828858999, + "holonomicRotation": 68.14977902016777, + "angularVelocity": 1.224456612402177, + "holonomicAngularVelocity": -94.86063272099182 + }, + { + "time": 2.9066485329494, + "pose": { + "rotation": { + "radians": 2.1241682132280184 + }, + "translation": { + "x": 3.2940776320000005, + "y": 3.9741971259862665 + } + }, + "velocity": -2.453223116749019, + "acceleration": -0.3397252167812531, + "curvature": -0.4984793339133297, + "holonomicRotation": 67.66304407360921, + "angularVelocity": 1.2235817376586304, + "holonomicAngularVelocity": -95.66726822646376 + }, + { + "time": 2.9117737310764693, + "pose": { + "rotation": { + "radians": 2.130439312058183 + }, + "translation": { + "x": 3.3007549440000004, + "y": 3.9635381947543835 + } + }, + "velocity": -2.4549698652585956, + "acceleration": -0.3408158019006307, + "curvature": -0.497770234969751, + "holonomicRotation": 67.17273036967309, + "angularVelocity": 1.2227061680084468, + "holonomicAngularVelocity": -96.4597392604555 + }, + { + "time": 2.916893121185565, + "pose": { + "rotation": { + "radians": 2.1366988219210157 + }, + "translation": { + "x": 3.3074960000000004, + "y": 3.9529257467632957 + } + }, + "velocity": -2.456719006680205, + "acceleration": -0.341669883391296, + "curvature": -0.497061679711388, + "holonomicRotation": 66.67891533457716, + "angularVelocity": 1.2218305102229903, + "holonomicAngularVelocity": -97.23784737105578 + }, + { + "time": 2.922006751326304, + "pose": { + "rotation": { + "radians": 2.1429468112449666 + }, + "translation": { + "x": 3.3143004160000005, + "y": 3.9423599939092844 + } + }, + "velocity": -2.458469339304636, + "acceleration": -0.3422876853150851, + "curvature": -0.4963541552778526, + "holonomicRotation": 66.18167694743994, + "angularVelocity": 1.2209553647377336, + "holonomicAngularVelocity": -98.00139599816646 + }, + { + "time": 2.9271146706000497, + "pose": { + "rotation": { + "radians": 2.1491833526848936 + }, + "translation": { + "x": 3.3211678080000007, + "y": 3.9318411480886293 + } + }, + "velocity": -2.4602196675683676, + "acceleration": -0.34266952352364594, + "curvature": -0.49564814217695435, + "holonomicRotation": 65.68109372796692, + "angularVelocity": 1.2200813256067014, + "holonomicAngularVelocity": -98.75019056144184 + }, + { + "time": 2.932216929148118, + "pose": { + "rotation": { + "radians": 2.155408523057809 + }, + "translation": { + "x": 3.3280977920000003, + "y": 3.921369421197612 + } + }, + "velocity": -2.461968802283485, + "acceleration": -0.3428157743553925, + "curvature": -0.49494411424464496, + "holonomicRotation": 65.17724472405142, + "angularVelocity": 1.2192089803800714, + "holonomicAngularVelocity": -99.48403854872984 + }, + { + "time": 2.9373135781398165, + "pose": { + "rotation": { + "radians": 2.161622403278333 + }, + "translation": { + "x": 3.3350899840000006, + "y": 3.910945025132512 + } + }, + "velocity": -2.463715561050444, + "acceleration": -0.342726911310549, + "curvature": -0.4942425385393566, + "holonomicRotation": 64.67020949929194, + "angularVelocity": 1.2183389099592048, + "holonomicAngularVelocity": -100.20274960216537 + }, + { + "time": 2.942404669760447, + "pose": { + "rotation": { + "radians": 2.167825078293914 + }, + "translation": { + "x": 3.3421440000000007, + "y": 3.9005681717896112 + } + }, + "velocity": -2.4654587683611564, + "acceleration": -0.3424034451960193, + "curvature": -0.49354387536872596, + "holonomicRotation": 64.16006812042824, + "angularVelocity": 1.217471688504721, + "holonomicAngularVelocity": -100.9061356007967 + }, + { + "time": 2.9474902571994575, + "pose": { + "rotation": { + "radians": 2.1740166370203244 + }, + "translation": { + "x": 3.3492594560000004, + "y": 3.8902390730651897 + } + }, + "velocity": -2.4671972558464152, + "acceleration": -0.34184595311906746, + "curvature": -0.49284857826519035, + "holonomicRotation": 63.64690114469775, + "angularVelocity": 1.2166078834262275, + "holonomicAngularVelocity": -101.59401075428647 + }, + { + "time": 2.9525703946381814, + "pose": { + "rotation": { + "radians": 2.1801971722771647 + }, + "translation": { + "x": 3.356435968000001, + "y": 3.8799579408555287 + } + }, + "velocity": -2.4689298629225123, + "acceleration": -0.3410551578565608, + "curvature": -0.4921570938094199, + "holonomicRotation": 63.13078960711478, + "angularVelocity": 1.2157480551464432, + "holonomicAngularVelocity": -102.26619168893342 + }, + { + "time": 2.9576451372375665, + "pose": { + "rotation": { + "radians": 2.186366780722736 + }, + "translation": { + "x": 3.3636731520000005, + "y": 3.869724987056909 + } + }, + "velocity": -2.470655436660188, + "acceleration": -0.3400317757761122, + "curvature": -0.4914698617718516, + "holonomicRotation": 62.611815007674075, + "angularVelocity": 1.2148927572524348, + "holonomicAngularVelocity": -102.9224975329877 + }, + { + "time": 2.9627145411259224, + "pose": { + "rotation": { + "radians": 2.192525562790287 + }, + "translation": { + "x": 3.3709706240000004, + "y": 3.85954042356561 + } + }, + "velocity": -2.4723728324069336, + "acceleration": -0.3387766657713812, + "curvature": -0.49078731495962646, + "holonomicRotation": 62.090059298481016, + "angularVelocity": 1.2140425361947913, + "holonomicAngularVelocity": -103.56275000564223 + }, + { + "time": 2.967778663386503, + "pose": { + "rotation": { + "radians": 2.198673622623123 + }, + "translation": { + "x": 3.3783280000000007, + "y": 3.8494044622779136 + } + }, + "velocity": -2.4740809138402975, + "acceleration": -0.33729071801042204, + "curvature": -0.4901098792969417, + "holonomicRotation": 61.565604870810475, + "angularVelocity": 1.2131979313363541, + "holonomicAngularVelocity": -104.18677350226001 + }, + { + "time": 2.9728375620451013, + "pose": { + "rotation": { + "radians": 2.2048110680105744 + }, + "translation": { + "x": 3.3857448960000003, + "y": 3.8393173150901005 + } + }, + "velocity": -2.4757785534211156, + "acceleration": -0.33557493347547346, + "curvature": -0.4894379737521331, + "holonomicRotation": 61.03853454209625, + "angularVelocity": 1.2123594749319873, + "holonomicAngularVelocity": -104.79439518315132 + }, + { + "time": 2.977891296057473, + "pose": { + "rotation": { + "radians": 2.2109380103242593 + }, + "translation": { + "x": 3.3932209280000003, + "y": 3.8292791938984516 + } + }, + "velocity": -2.4774646326332874, + "acceleration": -0.3336303826129742, + "curvature": -0.48877201035551443, + "holonomicRotation": 60.50893154285323, + "angularVelocity": 1.2115276919168534, + "holonomicAngularVelocity": -105.3854450568814 + }, + { + "time": 2.9829399252968494, + "pose": { + "rotation": { + "radians": 2.217054564453985 + }, + "translation": { + "x": 3.4007557120000005, + "y": 3.819290310599246 + } + }, + "velocity": -2.479138042187502, + "acceleration": -0.33145819882409144, + "curvature": -0.4881123942366022, + "holonomicRotation": 59.97687950353436, + "angularVelocity": 1.2107031000622246, + "holonomicAngularVelocity": -105.95975606700145 + }, + { + "time": 2.987983510541346, + "pose": { + "rotation": { + "radians": 2.223160848744925 + }, + "translation": { + "x": 3.4083488640000006, + "y": 3.8093508770887663 + } + }, + "velocity": -2.4807976824479416, + "acceleration": -0.32905962326121424, + "curvature": -0.4874595235784447, + "holonomicRotation": 59.44246244132438, + "angularVelocity": 1.2098862097183536, + "holonomicAngularVelocity": -106.51716417997883 + }, + { + "time": 2.9930221134612, + "pose": { + "rotation": { + "radians": 2.229256984933903 + }, + "translation": { + "x": 3.4160000000000004, + "y": 3.7994611052632923 + } + }, + "velocity": -2.4824424637147877, + "acceleration": -0.3264359769977284, + "curvature": -0.48681378963401156, + "holonomicRotation": 58.90576474687259, + "angularVelocity": 1.2090775239829443, + "holonomicAngularVelocity": -107.05750846728509 + }, + { + "time": 2.998055796606093, + "pose": { + "rotation": { + "radians": 2.2353430980872453 + }, + "translation": { + "x": 3.4237087360000005, + "y": 3.7896212070191044 + } + }, + "velocity": -2.4840713063948767, + "acceleration": -0.32358863941235766, + "curvature": -0.4861755767908796, + "holonomicRotation": 58.366871170966526, + "angularVelocity": 1.2082775384561817, + "holonomicAngularVelocity": -107.58063118750654 + }, + { + "time": 3.0030846233925312, + "pose": { + "rotation": { + "radians": 2.241419316538085 + }, + "translation": { + "x": 3.4314746880000007, + "y": 3.779831394252484 + } + }, + "velocity": -2.4856831413207248, + "acceleration": -0.32051907816648595, + "curvature": -0.4855452625816768, + "holonomicRotation": 57.825866811148884, + "angularVelocity": 1.2074867413515442, + "holonomicAngularVelocity": -108.08637787511516 + }, + { + "time": 3.008108658090934, + "pose": { + "rotation": { + "radians": 2.247485771824497 + }, + "translation": { + "x": 3.4392974720000007, + "y": 3.7700918788597115 + } + }, + "velocity": -2.4872769102582915, + "acceleration": -0.3172288873867211, + "curvature": -0.48492321762505763, + "holonomicRotation": 57.2828370982796, + "angularVelocity": 1.2067056134625382, + "holonomicAngularVelocity": -108.57459742055106 + }, + { + "time": 3.013127965812826, + "pose": { + "rotation": { + "radians": 2.2535425986282 + }, + "translation": { + "x": 3.4471767040000008, + "y": 3.7604028727370675 + } + }, + "velocity": -2.4888515658522445, + "acceleration": -0.3137196763380634, + "curvature": -0.4843098057902691, + "holonomicRotation": 56.73786778304532, + "angularVelocity": 1.2059346280378531, + "holonomicAngularVelocity": -109.04514215102253 + }, + { + "time": 3.0181426124980457, + "pose": { + "rotation": { + "radians": 2.259589934713281 + }, + "translation": { + "x": 3.4551120000000006, + "y": 3.750764587780833 + } + }, + "velocity": -2.490406072207704, + "acceleration": -0.30999319653791363, + "curvature": -0.4837053841163542, + "holonomicRotation": 56.19104492241842, + "angularVelocity": 1.2051742508556123, + "holonomicAngularVelocity": -109.49786791291324 + }, + { + "time": 3.023152664901871, + "pose": { + "rotation": { + "radians": 2.2656279208658088 + }, + "translation": { + "x": 3.463102976000001, + "y": 3.741177235887289 + } + }, + "velocity": -2.4919394049436834, + "acceleration": -0.30605123707062537, + "curvature": -0.4831103029406247, + "holonomicRotation": 55.64245486606757, + "angularVelocity": 1.2044249401110856, + "holonomicAngularVelocity": -109.93263414992425 + }, + { + "time": 3.0281581905822166, + "pose": { + "rotation": { + "radians": 2.2716567008335833 + }, + "translation": { + "x": 3.4711492480000006, + "y": 3.731641028952715 + } + }, + "velocity": -2.4934505516220318, + "acceleration": -0.30189569984268283, + "curvature": -0.48252490588364283, + "holonomicRotation": 55.092184242722105, + "angularVelocity": 1.2036871465900916, + "holonomicAngularVelocity": -110.3493039885737 + }, + { + "time": 3.033159257886518, + "pose": { + "rotation": { + "radians": 2.277676421267003 + }, + "translation": { + "x": 3.4792504320000006, + "y": 3.722156178873393 + } + }, + "velocity": -2.49493851217749, + "acceleration": -0.29752860038065254, + "curvature": -0.48194952983696343, + "holonomicRotation": 54.54031994649241, + "angularVelocity": 1.2029613133807362, + "holonomicAngularVelocity": -110.7477443083269 + }, + { + "time": 3.0381559359389714, + "pose": { + "rotation": { + "radians": 2.283687231659523 + }, + "translation": { + "x": 3.487406144000001, + "y": 3.7127228975456026 + } + }, + "velocity": -2.496402298692382, + "acceleration": -0.29295193717221096, + "curvature": -0.4813845052065131, + "holonomicRotation": 53.98694912314827, + "angularVelocity": 1.2022478761007076, + "holonomicAngularVelocity": -111.12782582146583 + }, + { + "time": 3.0431482946276227, + "pose": { + "rotation": { + "radians": 2.289689284289687 + }, + "translation": { + "x": 3.495616000000001, + "y": 3.7033413968656252 + } + }, + "velocity": -2.497840936318273, + "acceleration": -0.28816792133974267, + "curvature": -0.48083015571435544, + "holonomicRotation": 53.43215915635756, + "angularVelocity": 1.2015472627763575, + "holonomicAngularVelocity": -111.48942315254924 + }, + { + "time": 3.048136404591285, + "pose": { + "rotation": { + "radians": 2.295682734162953 + }, + "translation": { + "x": 3.5038796160000008, + "y": 3.694011888729742 + } + }, + "velocity": -2.4992534630817476, + "acceleration": -0.2831787538294935, + "curvature": -0.48028679863367535, + "holonomicRotation": 52.876037653887366, + "angularVelocity": 1.2008598938776565, + "holonomicAngularVelocity": -111.83241490896566 + }, + { + "time": 3.0531203372066305, + "pose": { + "rotation": { + "radians": 2.30166773895451 + }, + "translation": { + "x": 3.512196608000001, + "y": 3.684734585034233 + } + }, + "velocity": -2.5006389304550187, + "acceleration": -0.2779867787548527, + "curvature": -0.4797547447299139, + "holonomicRotation": 52.31867243376971, + "angularVelocity": 1.2001861822685285, + "holonomicAngularVelocity": -112.15668375425062 + }, + { + "time": 3.058100164575274, + "pose": { + "rotation": { + "radians": 2.3076444589524385 + }, + "translation": { + "x": 3.5205665920000007, + "y": 3.675509697675378 + } + }, + "velocity": -2.501996403341811, + "acceleration": -0.27259436649151636, + "curvature": -0.4792342984282738, + "holonomicRotation": 51.76015151043402, + "angularVelocity": 1.1995265333241345, + "holonomicAngularVelocity": -112.46211648169826 + }, + { + "time": 3.063075959510775, + "pose": { + "rotation": { + "radians": 2.3136130570019517 + }, + "translation": { + "x": 3.5289891840000007, + "y": 3.6663374385494594 + } + }, + "velocity": -2.5033249607201844, + "acceleration": -0.2670040457042024, + "curvature": -0.478725757729861, + "holonomicRotation": 51.20056308080867, + "angularVelocity": 1.1988813446963977, + "holonomicAngularVelocity": -112.74860408376729 + }, + { + "time": 3.0680477955256897, + "pose": { + "rotation": { + "radians": 2.3195736984491226 + }, + "translation": { + "x": 3.5374640000000004, + "y": 3.657218019552756 + } + }, + "velocity": -2.504623695499301, + "acceleration": -0.26121834574198977, + "curvature": -0.4782294144300909, + "holonomicRotation": 50.63999551039364, + "angularVelocity": 1.1982510067002008, + "holonomicAngularVelocity": -113.01604182264045 + }, + { + "time": 3.073015746818552, + "pose": { + "rotation": { + "radians": 2.325526551087033 + }, + "translation": { + "x": 3.5459906560000007, + "y": 3.648151652581551 + } + }, + "velocity": -2.505891715271616, + "acceleration": -0.25523997671568976, + "curvature": -0.47774555399467156, + "holonomicRotation": 50.07853731930663, + "angularVelocity": 1.1976359018500262, + "holonomicAngularVelocity": -113.26432929716299 + }, + { + "time": 3.0779798882608844, + "pose": { + "rotation": { + "radians": 2.3314717851002316 + }, + "translation": { + "x": 3.5545687680000007, + "y": 3.639138549532123 + } + }, + "velocity": -2.5071281420774696, + "acceleration": -0.24907163105990904, + "curvature": -0.4772744558135262, + "holonomicRotation": 49.51627716830462, + "angularVelocity": 1.1970364053482834, + "holonomicAngularVelocity": -113.4933705072513 + }, + { + "time": 3.08294029538427, + "pose": { + "rotation": { + "radians": 2.3374095730122733 + }, + "translation": { + "x": 3.563197952000001, + "y": 3.630178922300754 + } + }, + "velocity": -2.508332113108115, + "acceleration": -0.24271617242250404, + "curvature": -0.4768163930962272, + "holonomicRotation": 48.95330384478339, + "angularVelocity": 1.1964528846801932, + "holonomicAngularVelocity": -113.70307392083812 + }, + { + "time": 3.0878970443673177, + "pose": { + "rotation": { + "radians": 2.343340089631676 + }, + "translation": { + "x": 3.571877824000001, + "y": 3.621272982783724 + } + }, + "velocity": -2.5095027806524683, + "acceleration": -0.23617648348888906, + "curvature": -0.4763716330557826, + "holonomicRotation": 48.38970624875692, + "angularVelocity": 1.195885699914519, + "holonomicAngularVelocity": -113.89335253366002 + }, + { + "time": 3.0928502120227446, + "pose": { + "rotation": { + "radians": 2.34926351200008 + }, + "translation": { + "x": 3.5806080000000007, + "y": 3.612420942877314 + } + }, + "velocity": -2.510639312551345, + "acceleration": -0.22945556822238247, + "curvature": -0.4759404368985347, + "holonomicRotation": 47.825573378819044, + "angularVelocity": 1.1953352035476041, + "holonomicAngularVelocity": -114.06412393141328 + }, + { + "time": 3.0977998757844105, + "pose": { + "rotation": { + "radians": 2.355180019340123 + }, + "translation": { + "x": 3.5893880960000004, + "y": 3.603623014477804 + } + }, + "velocity": -2.5117408923267215, + "acceleration": -0.2225564863431604, + "curvature": -0.4755230599370365, + "holonomicRotation": 47.26099431808958, + "angularVelocity": 1.1948017406665197, + "holonomicAngularVelocity": -114.21531035103021 + }, + { + "time": 3.102746113694252, + "pose": { + "rotation": { + "radians": 2.3610897930045525 + }, + "translation": { + "x": 3.598217728000001, + "y": 3.5948794094814756 + } + }, + "velocity": -2.512806719663429, + "acceleration": -0.21548242444768187, + "curvature": -0.4751197515683634, + "holonomicRotation": 46.696058220147, + "angularVelocity": 1.1942856487011924, + "holonomicAngularVelocity": -114.34683873146564 + }, + { + "time": 3.1076890043895005, + "pose": { + "rotation": { + "radians": 2.3669930164249866 + }, + "translation": { + "x": 3.607096512000001, + "y": 3.586190339784609 + } + }, + "velocity": -2.5138360101605874, + "acceleration": -0.2082365483314603, + "curvature": -0.47473075552777316, + "holonomicRotation": 46.13085429495014, + "angularVelocity": 1.1937872578194393, + "holonomicAngularVelocity": -114.4586407752318 + }, + { + "time": 3.11262862708963, + "pose": { + "rotation": { + "radians": 2.372889875062837 + }, + "translation": { + "x": 3.616024064000001, + "y": 3.5775560172834857 + } + }, + "velocity": -2.5148279963615496, + "acceleration": -0.2008222613715301, + "curvature": -0.47435630965733216, + "holonomicRotation": 45.56547179475081, + "angularVelocity": 1.1933068905729998, + "holonomicAngularVelocity": -114.55065300129512 + }, + { + "time": 3.117565061583325, + "pose": { + "rotation": { + "radians": 2.3787805563590254 + }, + "translation": { + "x": 3.625000000000001, + "y": 3.5689766538743855 + } + }, + "velocity": -2.51578192720497, + "acceleration": -0.19324288504972006, + "curvature": -0.47399664627005966, + "holonomicRotation": 44.99999999999995, + "angularVelocity": 1.1928448621924224, + "holonomicAngularVelocity": -114.622816790235 + }, + { + "time": 3.1224983882157153, + "pose": { + "rotation": { + "radians": 2.3846652496859893 + }, + "translation": { + "x": 3.634023936000001, + "y": 3.560452461453589 + } + }, + "velocity": -2.5166970687976487, + "acceleration": -0.1855019261587106, + "curvature": -0.47365199201272495, + "holonomicRotation": 44.43452820524909, + "angularVelocity": 1.1924014804181657, + "holonomicAngularVelocity": -114.67507844083346 + }, + { + "time": 3.127428687875297, + "pose": { + "rotation": { + "radians": 2.3905441462989794 + }, + "translation": { + "x": 3.643095488000001, + "y": 3.5519836519173777 + } + }, + "velocity": -2.5175727044523204, + "acceleration": -0.17760292784030876, + "curvature": -0.4733225680044457, + "holonomicRotation": 43.86914570504977, + "angularVelocity": 1.191977045585318, + "holonomicAngularVelocity": -114.70738921137864 + }, + { + "time": 3.132356041981102, + "pose": { + "rotation": { + "radians": 2.3964174392885695 + }, + "translation": { + "x": 3.652214272000001, + "y": 3.543570437162032 + } + }, + "velocity": -2.518408134876489, + "acceleration": -0.16954949983895642, + "curvature": -0.47300858991591366, + "holonomicRotation": 43.303941779852906, + "angularVelocity": 1.1915718506935267, + "holonomicAngularVelocity": -114.71970536786596 + }, + { + "time": 3.137280532469733, + "pose": { + "rotation": { + "radians": 2.40228532353383 + }, + "translation": { + "x": 3.661379904000001, + "y": 3.535213029083832 + } + }, + "velocity": -2.5192026785969412, + "acceleration": -0.16134536604072128, + "curvature": -0.47271026795776055, + "holonomicRotation": 42.73900568191033, + "angularVelocity": 1.191186181363483, + "holonomicAngularVelocity": -114.71198822779128 + }, + { + "time": 3.142202241782349, + "pose": { + "rotation": { + "radians": 2.408147995655707 + }, + "translation": { + "x": 3.670592000000001, + "y": 3.5269116395790587 + } + }, + "velocity": -2.5199556720485856, + "acceleration": -0.15299429604956574, + "curvature": -0.47242780699268483, + "holonomicRotation": 42.17442662118084, + "angularVelocity": 1.1908203158165607, + "holonomicAngularVelocity": -114.68420419402902 + }, + { + "time": 3.147121252851942, + "pose": { + "rotation": { + "radians": 2.4140056539711043 + }, + "translation": { + "x": 3.679850176000001, + "y": 3.5186664805439936 + } + }, + "velocity": -2.5206664696512644, + "acceleration": -0.1445001022812573, + "curvature": -0.4721614066490972, + "holonomicRotation": 41.610293751242985, + "angularVelocity": 1.190474524961364, + "holonomicAngularVelocity": -114.63632479819923 + }, + { + "time": 3.1520376490903823, + "pose": { + "rotation": { + "radians": 2.4198584984475833 + }, + "translation": { + "x": 3.689154048000001, + "y": 3.5104777638749165 + } + }, + "velocity": -2.521334444410858, + "acceleration": -0.13586674612813227, + "curvature": -0.47191126123538196, + "holonomicRotation": 41.04669615521651, + "angularVelocity": 1.1901490724165622, + "holonomicAngularVelocity": -114.56832673867883 + }, + { + "time": 3.1569515143753777, + "pose": { + "rotation": { + "radians": 2.4257067306585007 + }, + "translation": { + "x": 3.698503232000001, + "y": 3.5023457014681085 + } + }, + "velocity": -2.5219589878529036, + "acceleration": -0.12709820188860255, + "curvature": -0.47167755990147925, + "holonomicRotation": 40.48372283169528, + "angularVelocity": 1.1898442144572068, + "holonomicAngularVelocity": -114.48019190561627 + }, + { + "time": 3.161862933037792, + "pose": { + "rotation": { + "radians": 2.4315505537387514 + }, + "translation": { + "x": 3.707897344000001, + "y": 3.49427050521985 + } + }, + "velocity": -2.5225395101493246, + "acceleration": -0.11819849544971883, + "curvature": -0.47146048672457774, + "holonomicRotation": 39.92146268069328, + "angularVelocity": 1.1895602000975292, + "holonomicAngularVelocity": -114.37190742014383 + }, + { + "time": 3.166771989848609, + "pose": { + "rotation": { + "radians": 2.4373901723409173 + }, + "translation": { + "x": 3.717336000000001, + "y": 3.4862523870264224 + } + }, + "velocity": -2.5230754407727187, + "acceleration": -0.10917181121496528, + "curvature": -0.471260220594255, + "holonomicRotation": 39.36000448960627, + "angularVelocity": 1.189297271060311, + "holonomicAngularVelocity": -114.24346565953405 + }, + { + "time": 3.171678770006046, + "pose": { + "rotation": { + "radians": 2.44322579259185 + }, + "translation": { + "x": 3.726818816000001, + "y": 3.4782915587841052 + } + }, + "velocity": -2.5235662281046483, + "acceleration": -0.10002227859865927, + "curvature": -0.4710769354852334, + "holonomicRotation": 38.79943691919124, + "angularVelocity": 1.189055661833772, + "holonomicAngularVelocity": -114.09486428153625 + }, + { + "time": 3.176583359122735, + "pose": { + "rotation": { + "radians": 2.4490576220500175 + }, + "translation": { + "x": 3.736345408000001, + "y": 3.4703882323891806 + } + }, + "velocity": -2.524011340151306, + "acceleration": -0.09075419695059489, + "curvature": -0.47091080031243926, + "holonomicRotation": 38.23984848956588, + "angularVelocity": 1.1888355996123872, + "holonomicAngularVelocity": -113.92610625049942 + }, + { + "time": 3.1814858432127964, + "pose": { + "rotation": { + "radians": 2.4548858696628155 + }, + "translation": { + "x": 3.745915392000001, + "y": 3.4625426197379277 + } + }, + "velocity": -2.5244102643344153, + "acceleration": -0.08137184655387633, + "curvature": -0.47076197912776857, + "holonomicRotation": 37.681327566230195, + "angularVelocity": 1.1886373044021066, + "holonomicAngularVelocity": -113.73719985418194 + }, + { + "time": 3.186386308679084, + "pose": { + "rotation": { + "radians": 2.4607107457249793 + }, + "translation": { + "x": 3.755528384000001, + "y": 3.4547549327266283 + } + }, + "velocity": -2.5247625078932936, + "acceleration": -0.07187961251875728, + "curvature": -0.4706306310845671, + "holonomicRotation": 37.12396234611252, + "angularVelocity": 1.1884609889574362, + "holonomicAngularVelocity": -113.52815873068948 + }, + { + "time": 3.1912848423000635, + "pose": { + "rotation": { + "radians": 2.46653246183661 + }, + "translation": { + "x": 3.765184000000001, + "y": 3.447025383251563 + } + }, + "velocity": -2.5250675982355864, + "acceleration": -0.062281973729059366, + "curvature": -0.4705169104173357, + "holonomicRotation": 36.567840843642344, + "angularVelocity": 1.1883068588401509, + "holonomicAngularVelocity": -113.29900187478664 + }, + { + "time": 3.1961815312170927, + "pose": { + "rotation": { + "radians": 2.472351230862322 + }, + "translation": { + "x": 3.7748818560000013, + "y": 3.4393541832090118 + } + }, + "velocity": -2.5253250825219324, + "acceleration": -0.052583345748317134, + "curvature": -0.47042096670266986, + "holonomicRotation": 36.01305087685163, + "angularVelocity": 1.1881751123985647, + "holonomicAngularVelocity": -113.04975365531308 + }, + { + "time": 3.2010764629215114, + "pose": { + "rotation": { + "radians": 2.478167266890403 + }, + "translation": { + "x": 3.7846215680000013, + "y": 3.4317415444952566 + } + }, + "velocity": -2.525534528618787, + "acceleration": -0.0427883593688127, + "curvature": -0.4703429446057929, + "holonomicRotation": 35.45968005350749, + "angularVelocity": 1.1880659407550722, + "holonomicAngularVelocity": -112.78044382583438 + }, + { + "time": 3.205969725241723, + "pose": { + "rotation": { + "radians": 2.4839807851922266 + }, + "translation": { + "x": 3.794402752000001, + "y": 3.424187679006577 + } + }, + "velocity": -2.525695524490209, + "acceleration": -0.03290154111643255, + "curvature": -0.47028298420432846, + "holonomicRotation": 34.907815757277795, + "angularVelocity": 1.1879795278928396, + "holonomicAngularVelocity": -112.4911075305061 + }, + { + "time": 3.210861406330348, + "pose": { + "rotation": { + "radians": 2.4897920021824937 + }, + "translation": { + "x": 3.8042250240000013, + "y": 3.416692798639254 + } + }, + "velocity": -2.525807679042665, + "acceleration": -0.022927609225605317, + "curvature": -0.47024122076600894, + "holonomicRotation": 34.357545133932334, + "angularVelocity": 1.1879160505732695, + "holonomicAngularVelocity": -112.18178531250864 + }, + { + "time": 3.2157515946512296, + "pose": { + "rotation": { + "radians": 2.4956011353791947 + }, + "translation": { + "x": 3.8140880000000013, + "y": 3.4092571152895688 + } + }, + "velocity": -2.5258706217414932, + "acceleration": -0.0128712218626321, + "curvature": -0.47021778497915745, + "holonomicRotation": 33.80895507758148, + "angularVelocity": 1.1878756783720692, + "holonomicAngularVelocity": -111.85252311199142 + }, + { + "time": 3.220640378966621, + "pose": { + "rotation": { + "radians": 2.5014084033642554 + }, + "translation": { + "x": 3.8239912960000013, + "y": 3.4018808408538015 + } + }, + "velocity": -2.5258840030950935, + "acceleration": -0.002737153602412999, + "curvature": -0.4702128028550573, + "holonomicRotation": 33.26213221695458, + "angularVelocity": 1.187858573687972, + "holonomicAngularVelocity": -111.50337226844077 + }, + { + "time": 3.2255278483242495, + "pose": { + "rotation": { + "radians": 2.507214025744352 + }, + "translation": { + "x": 3.8339345280000012, + "y": 3.3945641872282333 + } + }, + "velocity": -2.525847494579902, + "acceleration": 0.007469819761519579, + "curvature": -0.4702263958335384, + "holonomicRotation": 32.71716290172032, + "angularVelocity": 1.1878648917443635, + "holonomicAngularVelocity": -111.13438951908545 + }, + { + "time": 3.2304140920443007, + "pose": { + "rotation": { + "radians": 2.5130182231119065 + }, + "translation": { + "x": 3.843917312000001, + "y": 3.387307366309144 + } + }, + "velocity": -2.525760789056921, + "acceleration": 0.017744821574322937, + "curvature": -0.47025868070038246, + "holonomicRotation": 32.174133188851016, + "angularVelocity": 1.1878947806022002, + "holonomicAngularVelocity": -110.74563699043296 + }, + { + "time": 3.2352991997065046, + "pose": { + "rotation": { + "radians": 2.5188212170065185 + }, + "translation": { + "x": 3.853939264000001, + "y": 3.3801105899928157 + } + }, + "velocity": -2.5256236005006802, + "acceleration": 0.028083015918425037, + "curvature": -0.4703097697554681, + "holonomicRotation": 31.63312882903338, + "angularVelocity": 1.1879483810710896, + "holonomicAngularVelocity": -110.33718218871411 + }, + { + "time": 3.2401832611372594, + "pose": { + "rotation": { + "radians": 2.5246232298762354 + }, + "translation": { + "x": 3.864000000000001, + "y": 3.3729740701755277 + } + }, + "velocity": -2.525435664472835, + "acceleration": 0.03847945618823787, + "curvature": -0.47037977069829995, + "holonomicRotation": 31.094235253127316, + "angularVelocity": 1.1880258268210526, + "holonomicAngularVelocity": -109.90909799181578 + }, + { + "time": 3.2450663663965873, + "pose": { + "rotation": { + "radians": 2.5304244850394024 + }, + "translation": { + "x": 3.874099136000001, + "y": 3.365898018753562 + } + }, + "velocity": -2.5251967380340625, + "acceleration": 0.04892920100707005, + "curvature": -0.4704687867172178, + "holonomicRotation": 30.55753755867552, + "angularVelocity": 1.1881272442978712, + "holonomicAngularVelocity": -109.46146263436894 + }, + { + "time": 3.2499486057651135, + "pose": { + "rotation": { + "radians": 2.536225206646332 + }, + "translation": { + "x": 3.884236288000001, + "y": 3.358882647623198 + } + }, + "velocity": -2.524906600021658, + "acceleration": 0.059427240351045144, + "curvature": -0.47057691643683625, + "holonomicRotation": 30.02312049646555, + "angularVelocity": 1.1882527527596127, + "holonomicAngularVelocity": -108.99435968894919 + }, + { + "time": 3.2548300697311134, + "pose": { + "rotation": { + "radians": 2.5420256196414286 + }, + "translation": { + "x": 3.8944110720000014, + "y": 3.3519281686807174 + } + }, + "velocity": -2.5245650508903887, + "acceleration": 0.06996858599140866, + "curvature": -0.47070425402255034, + "holonomicRotation": 29.491068457146678, + "angularVelocity": 1.1884024641917774, + "holonomicAngularVelocity": -108.50787804778435 + }, + { + "time": 3.2597108489774813, + "pose": { + "rotation": { + "radians": 2.547825949724988 + }, + "translation": { + "x": 3.9046231040000015, + "y": 3.3450347938224 + } + }, + "velocity": -2.5241719131306364, + "acceleration": 0.08054815428190878, + "curvature": -0.4708508890641576, + "holonomicRotation": 28.96146545790366, + "angularVelocity": 1.1885764834315444, + "holonomicAngularVelocity": -108.0021119014011 + }, + { + "time": 3.264591034368628, + "pose": { + "rotation": { + "radians": 2.5536264233156913 + }, + "translation": { + "x": 3.9148720000000012, + "y": 3.338202734944528 + } + }, + "velocity": -2.523727031080917, + "acceleration": 0.09116089124942546, + "curvature": -0.47101690667937196, + "holonomicRotation": 28.434395129189433, + "angularVelocity": 1.188774907954385, + "holonomicAngularVelocity": -107.47716071321132 + }, + { + "time": 3.2694707169373736, + "pose": { + "rotation": { + "radians": 2.5594272675121985 + }, + "translation": { + "x": 3.9251573760000014, + "y": 3.33143220394338 + } + }, + "velocity": -2.523230271274464, + "acceleration": 0.10180166423829849, + "curvature": -0.47120238741225473, + "holonomicRotation": 27.909940701518906, + "angularVelocity": 1.1889978281035867, + "holonomicAngularVelocity": -106.93312919028769 + }, + { + "time": 3.2743499878718714, + "pose": { + "rotation": { + "radians": 2.5652287100560454 + }, + "translation": { + "x": 3.9354788480000007, + "y": 3.3247234127152385 + } + }, + "velocity": -2.5226815221802, + "acceleration": 0.11246538706927674, + "curvature": -0.4714074073516342, + "holonomicRotation": 27.388184992325836, + "angularVelocity": 1.1892453268004288, + "holonomicAngularVelocity": -106.37012725172265 + }, + { + "time": 3.2792289385025555, + "pose": { + "rotation": { + "radians": 2.571030979293276 + }, + "translation": { + "x": 3.945836032000001, + "y": 3.3180765731563833 + } + }, + "velocity": -2.5220806945623155, + "acceleration": 0.1231468943558796, + "curvature": -0.4716320380125646, + "holonomicRotation": 26.86921039288512, + "angularVelocity": 1.1895174797487822, + "holonomicAngularVelocity": -105.78827000146062 + }, + { + "time": 3.284107660288778, + "pose": { + "rotation": { + "radians": 2.5768343041368196 + }, + "translation": { + "x": 3.956228544000001, + "y": 3.311491897163096 + } + }, + "velocity": -2.5214277215293275, + "acceleration": 0.13384100623076972, + "curvature": -0.47187634632741926, + "holonomicRotation": 26.353098855302157, + "angularVelocity": 1.1898143552818996, + "holonomicAngularVelocity": -105.18767768515991 + }, + { + "time": 3.288986244805745, + "pose": { + "rotation": { + "radians": 2.5826389140285624 + }, + "translation": { + "x": 3.9666560000000013, + "y": 3.304969596631656 + } + }, + "velocity": -2.520722558272556, + "acceleration": 0.14454259310650955, + "curvature": -0.47214039474709035, + "holonomicRotation": 25.83993187957167, + "angularVelocity": 1.1901360143775113, + "holonomicAngularVelocity": -104.56847565338994 + }, + { + "time": 3.2938647837313253, + "pose": { + "rotation": { + "radians": 2.5884450389014386 + }, + "translation": { + "x": 3.977118016000001, + "y": 3.298509883458345 + } + }, + "velocity": -2.5199651825072515, + "acceleration": 0.15524643276555644, + "curvature": -0.47242424107305725, + "holonomicRotation": 25.32979050070796, + "angularVelocity": 1.189645268913223, + "holonomicAngularVelocity": -103.85770194645232 + }, + { + "time": 3.2987468022552946, + "pose": { + "rotation": { + "radians": 2.5942529091412254 + }, + "translation": { + "x": 3.9876142080000014, + "y": 3.292112969539443 + } + }, + "velocity": -2.515611684910395, + "acceleration": 0.891741310583367, + "curvature": -0.4727279384940904, + "holonomicRotation": 24.8227552759485, + "angularVelocity": 1.1859076290663977, + "holonomicAngularVelocity": -102.8458130887217 + }, + { + "time": 3.3036458738731236, + "pose": { + "rotation": { + "radians": 2.6000627555481515 + }, + "translation": { + "x": 3.9981441920000007, + "y": 3.285779066771231 + } + }, + "velocity": -2.5009144700569084, + "acceleration": 2.9999999999999094, + "curvature": -0.47305153562240315, + "holonomicRotation": 24.318906272032997, + "angularVelocity": 1.179747509794824, + "holonomicAngularVelocity": -101.60983224477155 + }, + { + "time": 3.3085723973050998, + "pose": { + "rotation": { + "radians": 2.605874809298971 + }, + "translation": { + "x": 4.0087075840000015, + "y": 3.27950838704999 + } + }, + "velocity": -2.4861348997609802, + "acceleration": 3.000000000000045, + "curvature": -0.4733950762761256, + "holonomicRotation": 23.818323052559983, + "angularVelocity": 1.1735879413475419, + "holonomicAngularVelocity": -100.36180530480989 + }, + { + "time": 3.3135268556832354, + "pose": { + "rotation": { + "radians": 2.611689301907459 + }, + "translation": { + "x": 4.019304000000001, + "y": 3.2733011422720004 + } + }, + "velocity": -2.471271524626574, + "acceleration": 2.9999999999999103, + "curvature": -0.47375859973557605, + "holonomicRotation": 23.321084665422756, + "angularVelocity": 1.1674273485551854, + "holonomicAngularVelocity": -99.10211376668313 + }, + { + "time": 3.318509746726897, + "pose": { + "rotation": { + "radians": 2.6175064651867004 + }, + "translation": { + "x": 4.029933056000002, + "y": 3.267157544333543 + } + }, + "velocity": -2.4563228514955893, + "acceleration": 3.0, + "curvature": -0.47414214031863405, + "holonomicRotation": 22.82726963032682, + "angularVelocity": 1.161264108636459, + "holonomicAngularVelocity": -97.83114215653715 + }, + { + "time": 3.3235215833785796, + "pose": { + "rotation": { + "radians": 2.6233265312086482 + }, + "translation": { + "x": 4.040594368000001, + "y": 3.2610778051308986 + } + }, + "velocity": -2.441287341540541, + "acceleration": 3.0, + "curvature": -0.4745457277939175, + "holonomicRotation": 22.336955926390708, + "angularVelocity": 1.155096550640754, + "holonomicAngularVelocity": -96.54927801758882 + }, + { + "time": 3.3285628944743486, + "pose": { + "rotation": { + "radians": 2.629149732266078 + }, + "translation": { + "x": 4.051287552000002, + "y": 3.2550621365603476 + } + }, + "velocity": -2.4261634082532337, + "acceleration": 3.000000000000088, + "curvature": -0.47496938687565216, + "holonomicRotation": 21.85022097983215, + "angularVelocity": 1.1489229537358603, + "holonomicAngularVelocity": -95.25691190089452 + }, + { + "time": 3.333634225451287, + "pose": { + "rotation": { + "radians": 2.6349763008314744 + }, + "translation": { + "x": 4.062012224000001, + "y": 3.2491107505181707 + } + }, + "velocity": -2.410949415322418, + "acceleration": 3.000000000000044, + "curvature": -0.4754131375406458, + "holonomicRotation": 21.367141651741637, + "angularVelocity": 1.1427415464961193, + "holonomicAngularVelocity": -93.95443735758198 + }, + { + "time": 3.3387361390945163, + "pose": { + "rotation": { + "radians": 2.6408064695182274 + }, + "translation": { + "x": 4.072768000000002, + "y": 3.2432238589006492 + } + }, + "velocity": -2.395643674392731, + "acceleration": 3.0, + "curvature": -0.47587699474317613, + "holonomicRotation": 20.887794225945097, + "angularVelocity": 1.1365505050778797, + "holonomicAngularVelocity": -92.64225093318588 + }, + { + "time": 3.3438692163265253, + "pose": { + "rotation": { + "radians": 2.6466404710388716 + }, + "translation": { + "x": 4.0835544960000005, + "y": 3.2374016736040634 + } + }, + "velocity": -2.3802444426967027, + "acceleration": 3.0, + "curvature": -0.4763609684774519, + "holonomicRotation": 20.41225439695785, + "angularVelocity": 1.1303479523230882, + "holonomicAngularVelocity": -91.32075216362355 + }, + { + "time": 3.349034057041824, + "pose": { + "rotation": { + "radians": 2.652478538165484 + }, + "translation": { + "x": 4.094371328000001, + "y": 3.2316444065246936 + } + }, + "velocity": -2.3647499205508073, + "acceleration": 3.0, + "curvature": -0.4768650635862502, + "holonomicRotation": 19.940597258031488, + "angularVelocity": 1.1241319557916827, + "holonomicAngularVelocity": -89.99034357339347 + }, + { + "time": 3.3542312809901262, + "pose": { + "rotation": { + "radians": 2.6583209036871764 + }, + "translation": { + "x": 4.105218112000001, + "y": 3.225952269558821 + } + }, + "velocity": -2.3491582487059004, + "acceleration": 3.0000000000000426, + "curvature": -0.4773892799171057, + "holonomicRotation": 19.4728972892959, + "angularVelocity": 1.117900526573738, + "holonomicAngularVelocity": -88.65143067557575 + }, + { + "time": 3.359461528711619, + "pose": { + "rotation": { + "radians": 2.6641678003691442 + }, + "translation": { + "x": 4.1160944640000015, + "y": 3.2203254746027263 + } + }, + "velocity": -2.3334675055414222, + "acceleration": 3.0, + "curvature": -0.47793361195538225, + "holonomicRotation": 19.0092283459979, + "angularVelocity": 1.111651617315528, + "holonomicAngularVelocity": -87.30442197418871 + }, + { + "time": 3.3647254625281113, + "pose": { + "rotation": { + "radians": 2.67001946090969 + }, + "translation": { + "x": 4.127000000000001, + "y": 3.21476423355269 + } + }, + "velocity": -2.317675704091945, + "acceleration": 3.0, + "curvature": -0.47849804904257176, + "holonomicRotation": 18.54966364683865, + "angularVelocity": 1.1053831206956037, + "holonomicAngularVelocity": -85.9497289685807 + }, + { + "time": 3.370023767594245, + "pose": { + "rotation": { + "radians": 2.67587611789809 + }, + "translation": { + "x": 4.137934336000002, + "y": 3.209268758304993 + } + }, + "velocity": -2.3017807888935438, + "acceleration": 3.0000000000000417, + "curvature": -0.4790825750718403, + "holonomicRotation": 18.0942757624116, + "angularVelocity": 1.099092867194516, + "holonomicAngularVelocity": -84.58776616038908 + }, + { + "time": 3.375357153013284, + "pose": { + "rotation": { + "radians": 2.681738003770155 + }, + "translation": { + "x": 4.148897088000001, + "y": 3.2038392607559154 + } + }, + "velocity": -2.2857806326364263, + "acceleration": 3.000000000000125, + "curvature": -0.4796871685309068, + "holonomicRotation": 17.643136603742704, + "angularVelocity": 1.0927786234901078, + "holonomicAngularVelocity": -83.2189510626718 + }, + { + "time": 3.3807263530224416, + "pose": { + "rotation": { + "radians": 2.6876053507654056 + }, + "translation": { + "x": 4.159887872000001, + "y": 3.1984759528017386 + } + }, + "velocity": -2.269673032608953, + "acceleration": 2.9999999999999587, + "curvature": -0.48031180230736537, + "holonomicRotation": 17.1963174109349, + "angularVelocity": 1.0864380898787445, + "holonomicAngularVelocity": -81.84370421196407 + }, + { + "time": 3.3861321282531263, + "pose": { + "rotation": { + "radians": 2.693478390881344 + }, + "translation": { + "x": 4.170906304000001, + "y": 3.1931790463387437 + } + }, + "velocity": -2.2534557069169003, + "acceleration": 3.0, + "curvature": -0.4809564438096599, + "holonomicRotation": 16.75388874191842, + "angularVelocity": 1.0800688983034952, + "holonomicAngularVelocity": -80.46244918269026 + }, + { + "time": 3.391575267072019, + "pose": { + "rotation": { + "radians": 2.699357355828779 + }, + "translation": { + "x": 4.181952000000002, + "y": 3.18794875326321 + } + }, + "velocity": -2.237126290460221, + "acceleration": 2.999999999999959, + "curvature": -0.4816210545661112, + "holonomicRotation": 16.315920461308902, + "angularVelocity": 1.0736686097512136, + "holonomicAngularVelocity": -79.07561260483114 + }, + { + "time": 3.3970565870094314, + "pose": { + "rotation": { + "radians": 2.705242476985582 + }, + "translation": { + "x": 4.193024576000001, + "y": 3.1827852854714194 + } + }, + "velocity": -2.220682330647984, + "acceleration": 3.000000000000081, + "curvature": -0.4823055904398, + "holonomicRotation": 15.882481729374959, + "angularVelocity": 1.0672347117267755, + "holonomicAngularVelocity": -77.6836241842693 + }, + { + "time": 3.402576936282025, + "pose": { + "rotation": { + "radians": 2.7111339853501493 + }, + "translation": { + "x": 4.204123648000001, + "y": 3.1776888548596522 + } + }, + "velocity": -2.2041212828302035, + "acceleration": 3.0000000000000404, + "curvature": -0.4830100011954003, + "holonomicRotation": 15.453640991116902, + "angularVelocity": 1.0607646153637207, + "holonomicAngularVelocity": -76.2869167266683 + }, + { + "time": 3.408137195417652, + "pose": { + "rotation": { + "radians": 2.7170321114934755 + }, + "translation": { + "x": 4.215248832000001, + "y": 3.1726596733241887 + } + }, + "velocity": -2.187440505423322, + "acceleration": 3.0, + "curvature": -0.48373423076088373, + "holonomicRotation": 15.029465965458614, + "angularVelocity": 1.0542556526712294, + "holonomicAngularVelocity": -74.88592616458293 + }, + { + "time": 3.4137382789908584, + "pose": { + "rotation": { + "radians": 2.722937085511612 + }, + "translation": { + "x": 4.226399744000002, + "y": 3.1676979527613107 + } + }, + "velocity": -2.1706372547037036, + "acceleration": 3.0, + "curvature": -0.4844782167624344, + "holonomicRotation": 14.610023634553844, + "angularVelocity": 1.047705073073782, + "holonomicAngularVelocity": -73.4810915883214 + }, + { + "time": 3.4193811374784255, + "pose": { + "rotation": { + "radians": 2.7288491369756738 + }, + "translation": { + "x": 4.237576000000001, + "y": 3.162803905067298 + } + }, + "velocity": -2.1537086792410016, + "acceleration": 2.9999999999999605, + "curvature": -0.48524189070637075, + "holonomicRotation": 14.195380233208967, + "angularVelocity": 1.0411100403867837, + "holonomicAngularVelocity": -72.07285528061695 + }, + { + "time": 3.4250667592453135, + "pose": { + "rotation": { + "radians": 2.7347684948830224 + }, + "translation": { + "x": 4.2487772160000015, + "y": 3.157977742138431 + } + }, + "velocity": -2.136651813940338, + "acceleration": 3.0, + "curvature": -0.4860251776092164, + "holonomicRotation": 13.785601238423729, + "angularVelocity": 1.0344676288016506, + "holonomicAngularVelocity": -70.66166275559415 + }, + { + "time": 3.4307961726723977, + "pose": { + "rotation": { + "radians": 2.7406953876053626 + }, + "translation": { + "x": 4.260003008000001, + "y": 3.153219675870991 + } + }, + "velocity": -2.119463573659085, + "acceleration": 3.0, + "curvature": -0.486827996068867, + "holonomicRotation": 13.38075135905173, + "angularVelocity": 1.0277748193668228, + "holonomicAngularVelocity": -69.24796280197698 + }, + { + "time": 3.4365704484386477, + "pose": { + "rotation": { + "radians": 2.746630042837994 + }, + "translation": { + "x": 4.271252992000002, + "y": 3.148529918161259 + } + }, + "velocity": -2.1021407463603357, + "acceleration": 3.0000000000000386, + "curvature": -0.4876502580522222, + "holonomicRotation": 12.980894525582109, + "angularVelocity": 1.0210284955354487, + "holonomicAngularVelocity": -67.83220753132842 + }, + { + "time": 3.4423907019716853, + "pose": { + "rotation": { + "radians": 2.7525726875464667 + }, + "translation": { + "x": 4.282526784000001, + "y": 3.1439086809055152 + } + }, + "velocity": -2.0846799857612224, + "acceleration": 2.999999999999962, + "curvature": -0.4884918687304187, + "holonomicRotation": 12.586093880044139, + "angularVelocity": 1.0142254389443273, + "holonomicAngularVelocity": -66.4148524311318 + }, + { + "time": 3.448258096082239, + "pose": { + "rotation": { + "radians": 2.7585235479137022 + }, + "translation": { + "x": 4.293824000000002, + "y": 3.1393561760000406 + } + }, + "velocity": -2.067077803429562, + "acceleration": 2.9999999999999623, + "curvature": -0.4893527263930312, + "holonomicRotation": 12.19641176603643, + "angularVelocity": 1.0073623243585152, + "holonomicAngularVelocity": -64.99635642368415 + }, + { + "time": 3.454173843799663, + "pose": { + "rotation": { + "radians": 2.7644828492846454 + }, + "translation": { + "x": 4.305144256000001, + "y": 3.134872615341115 + } + }, + "velocity": -2.0493305602772884, + "acceleration": 3.000000000000075, + "curvature": -0.49023272239377874, + "holonomicRotation": 11.811909718882124, + "angularVelocity": 1.0004357148136194, + "holonomicAngularVelocity": -63.577181930649736 + }, + { + "time": 3.4601392114276917, + "pose": { + "rotation": { + "radians": 2.770450816111718 + }, + "translation": { + "x": 4.316487168000002, + "y": 3.1304582108250205 + } + }, + "velocity": -2.031434457393203, + "acceleration": 3.0000000000000373, + "curvature": -0.4911317407982573, + "holonomicRotation": 11.43264845591175, + "angularVelocity": 0.9934420556728796, + "holonomicAngularVelocity": -62.15779494429541 + }, + { + "time": 3.466155521841721, + "pose": { + "rotation": { + "radians": 2.7764276718969976 + }, + "translation": { + "x": 4.327852352000001, + "y": 3.126113174348037 + } + }, + "velocity": -2.013385526151115, + "acceleration": 2.9999999999999263, + "curvature": -0.4920496584562309, + "holonomicRotation": 11.058687866875282, + "angularVelocity": 0.9863776690339577, + "holonomicAngularVelocity": -60.73866510544962 + }, + { + "time": 3.472224158051466, + "pose": { + "rotation": { + "radians": 2.7824136391357808 + }, + "translation": { + "x": 4.339239424000002, + "y": 3.121837717806445 + } + }, + "velocity": -1.9951796175218803, + "acceleration": 3.0000000000000364, + "curvature": -0.4929863447293872, + "holonomicRotation": 10.690087004484784, + "angularVelocity": 0.9792387468544239, + "holonomicAngularVelocity": -59.32026578919857 + }, + { + "time": 3.478346567055599, + "pose": { + "rotation": { + "radians": 2.788408939256718 + }, + "translation": { + "x": 4.350648000000001, + "y": 3.117632053096526 + } + }, + "velocity": -1.9768123905094812, + "acceleration": 3.0000000000000364, + "curvature": -0.4939416613608526, + "holonomicRotation": 10.326904075089434, + "angularVelocity": 0.9720213442853626, + "holonomicAngularVelocity": -57.90307419853841 + }, + { + "time": 3.484524264018268, + "pose": { + "rotation": { + "radians": 2.7944137925629597 + }, + "translation": { + "x": 4.362077696000002, + "y": 3.11349639211456 + } + }, + "velocity": -1.9582792996214728, + "acceleration": 3.0, + "curvature": -0.49491546234555484, + "holonomicRotation": 9.9691964294839, + "angularVelocity": 0.964721371740083, + "holonomicAngularVelocity": -56.487571467135446 + }, + { + "time": 3.490758836801003, + "pose": { + "rotation": { + "radians": 2.8004284181701333 + }, + "translation": { + "x": 4.373528128000001, + "y": 3.1094309467568277 + } + }, + "velocity": -1.9395755812732676, + "acceleration": 3.0, + "curvature": -0.4959075937861373, + "holonomicRotation": 9.617020553852093, + "angularVelocity": 0.9573345869699085, + "holonomicAngularVelocity": -55.074242771548406 + }, + { + "time": 3.4970519508877898, + "pose": { + "rotation": { + "radians": 2.8064530339451617 + }, + "translation": { + "x": 4.384998912000002, + "y": 3.1054359289196105 + } + }, + "velocity": -1.920696239012908, + "acceleration": 2.999999999999965, + "curvature": -0.4969178936404211, + "holonomicRotation": 9.270432060847359, + "angularVelocity": 0.949856585776932, + "holonomicAngularVelocity": -53.66357745423141 + }, + { + "time": 3.503405354745884, + "pose": { + "rotation": { + "radians": 2.812487856441873 + }, + "translation": { + "x": 4.3964896640000015, + "y": 3.1015115504991884 + } + }, + "velocity": -1.9016360274386255, + "acceleration": 3.000000000000035, + "curvature": -0.4979461917199805, + "holonomicRotation": 8.929485680810512, + "angularVelocity": 0.9422827925820624, + "holonomicAngularVelocity": -52.25606915784077 + }, + { + "time": 3.5098208856705417, + "pose": { + "rotation": { + "radians": 2.818533100837456 + }, + "translation": { + "x": 4.408000000000002, + "y": 3.0976580233918423 + } + }, + "velocity": -1.882389434664652, + "acceleration": 3.0, + "curvature": -0.4989923093779659, + "holonomicRotation": 8.594235253127325, + "angularVelocity": 0.9346084494762857, + "holonomicAngularVelocity": -50.85221597241104 + }, + { + "time": 3.516300476168219, + "pose": { + "rotation": { + "radians": 2.824588980865731 + }, + "translation": { + "x": 4.4195295360000015, + "y": 3.0938755594938527 + } + }, + "velocity": -1.8629506631716213, + "acceleration": 3.0, + "curvature": -0.5000560594170246, + "holonomicRotation": 8.264733717726678, + "angularVelocity": 0.92682860485997, + "holonomicAngularVelocity": -49.452520596195136 + }, + { + "time": 3.5228461609402677, + "pose": { + "rotation": { + "radians": 2.8306557087508626 + }, + "translation": { + "x": 4.431077888000002, + "y": 3.090164370701501 + } + }, + "velocity": -1.8433136088554738, + "acceleration": 3.0000000000000338, + "curvature": -0.5011372458585169, + "holonomicRotation": 7.941033106720719, + "angularVelocity": 0.9189381004802402, + "holonomicAngularVelocity": -48.05749051188394 + }, + { + "time": 3.5294600845377504, + "pose": { + "rotation": { + "radians": 2.8367334951382546 + }, + "translation": { + "x": 4.442644672000001, + "y": 3.0865246689110672 + } + }, + "velocity": -1.8234718380630266, + "acceleration": 2.9999999999999662, + "curvature": -0.5022356639002403, + "holonomicRotation": 7.62318453618838, + "angularVelocity": 0.910931557733977, + "holonomicAngularVelocity": -46.66763817947671 + }, + { + "time": 3.5361445097680377, + "pose": { + "rotation": { + "radians": 2.8428225490258363 + }, + "translation": { + "x": 4.454229504000002, + "y": 3.0829566660188323 + } + }, + "velocity": -1.803418562372165, + "acceleration": 3.0000000000000333, + "curvature": -0.5033510995965044, + "holonomicRotation": 7.311238198103576, + "angularVelocity": 0.9028033620501636, + "holonomicAngularVelocity": -45.28348124775536 + }, + { + "time": 3.5429018269455783, + "pose": { + "rotation": { + "radians": 2.8489230776921595 + }, + "translation": { + "x": 4.465832000000002, + "y": 3.079460573921077 + } + }, + "velocity": -1.7831466108395428, + "acceleration": 2.999999999999967, + "curvature": -0.504483329742147, + "holonomicRotation": 7.005243352409272, + "angularVelocity": 0.894547646292854, + "holonomicAngularVelocity": -43.905542786037614 + }, + { + "time": 3.549734564092968, + "pose": { + "rotation": { + "radians": 2.8550352866250943 + }, + "translation": { + "x": 4.477451776000002, + "y": 3.0760366045140817 + } + }, + "velocity": -1.7626483993973747, + "acceleration": 3.0000000000000324, + "curvature": -0.5056321217279383, + "holonomicRotation": 6.705248319238822, + "angularVelocity": 0.8861582718762545, + "holonomicAngularVelocity": -42.53435153875966 + }, + { + "time": 3.5566453982145445, + "pose": { + "rotation": { + "radians": 2.8611593794474945 + }, + "translation": { + "x": 4.489088448000001, + "y": 3.0726849696941274 + } + }, + "velocity": -1.7419158970326432, + "acceleration": 3.000000000000032, + "curvature": -0.506797233320977, + "holonomicRotation": 6.411300471285606, + "angularVelocity": 0.8776288083554918, + "holonomicAngularVelocity": -41.170442204949744 + }, + { + "time": 3.5636371677838463, + "pose": { + "rotation": { + "radians": 2.8672955578428967 + }, + "translation": { + "x": 4.500741632000002, + "y": 3.069405881357495 + } + }, + "velocity": -1.720940588324739, + "acceleration": 3.0, + "curvature": -0.507978412463492, + "holonomicRotation": 6.123446226322358, + "angularVelocity": 0.8689525103825774, + "holonomicAngularVelocity": -39.81435574581486 + }, + { + "time": 3.5707128866087237, + "pose": { + "rotation": { + "radians": 2.8734440214785355 + }, + "translation": { + "x": 4.512410944000001, + "y": 3.066199551400465 + } + }, + "velocity": -1.6997134318501057, + "acceleration": 3.0, + "curvature": -0.5091753972438993, + "holonomicRotation": 5.8417310398713145, + "angularVelocity": 0.8601222925409711, + "holonomicAngularVelocity": -38.46663972327497 + }, + { + "time": 3.5778757592648063, + "pose": { + "rotation": { + "radians": 2.879604967928664 + }, + "translation": { + "x": 4.524096000000002, + "y": 3.0630661917193183 + } + }, + "velocity": -1.6782248138818594, + "acceleration": 2.999999999999969, + "curvature": -0.5103879154242502, + "holonomicRotation": 5.566199398026104, + "angularVelocity": 0.8511307007328054, + "holonomicAngularVelocity": -37.127848673380825 + }, + { + "time": 3.585129198319898, + "pose": { + "rotation": { + "radians": 2.885778592594347 + }, + "translation": { + "x": 4.535796416000001, + "y": 3.0600060142103347 + } + }, + "velocity": -1.6564644967165831, + "acceleration": 3.0000000000000306, + "curvature": -0.5116156846177222, + "holonomicRotation": 5.296894810427057, + "angularVelocity": 0.8419698808848267, + "holonomicAngularVelocity": -35.79854451851486 + }, + { + "time": 3.5924768436103527, + "pose": { + "rotation": { + "radians": 2.8919650886243353 + }, + "translation": { + "x": 4.547511808000002, + "y": 3.0570192307697956 + } + }, + "velocity": -1.6344215608452184, + "acceleration": 3.00000000000003, + "curvature": -0.5128584118230285, + "holonomicRotation": 5.033859803390453, + "angularVelocity": 0.8326315431606574, + "holonomicAngularVelocity": -34.479297023430654 + }, + { + "time": 3.5999225838765447, + "pose": { + "rotation": { + "radians": 2.8981646468321483 + }, + "translation": { + "x": 4.559241792000002, + "y": 3.054106053293982 + } + }, + "velocity": -1.6120843400466425, + "acceleration": 2.9999999999999702, + "curvature": -0.5141157933934679, + "holonomicRotation": 4.7771359131931, + "angularVelocity": 0.8231069223561549, + "holonomicAngularVelocity": -33.170684300285295 + }, + { + "time": 3.607470581120536, + "pose": { + "rotation": { + "radians": 2.904377455613602 + }, + "translation": { + "x": 4.570985984000002, + "y": 3.051266693679174 + } + }, + "velocity": -1.5894403483146702, + "acceleration": 3.0000000000000293, + "curvature": -0.5153875148097261, + "holonomicRotation": 4.5267636795132615, + "angularVelocity": 0.8133867328283466, + "holonomicAngularVelocity": -31.873293369280947 + }, + { + "time": 3.6151252981169075, + "pose": { + "rotation": { + "radians": 2.9106037008620067 + }, + "translation": { + "x": 4.582744000000002, + "y": 3.0485013638216527 + } + }, + "velocity": -1.5664761973255548, + "acceleration": 2.999999999999971, + "curvature": -0.5166732504881834, + "holonomicRotation": 4.2827826390290795, + "angularVelocity": 0.8034611176815546, + "holonomicAngularVelocity": -30.5877207820835 + }, + { + "time": 3.622891529590848, + "pose": { + "rotation": { + "radians": 2.9168435658822327 + }, + "translation": { + "x": 4.594515456000002, + "y": 3.045810275617699 + } + }, + "velocity": -1.5431775029037327, + "acceleration": 3.0000000000000284, + "curvature": -0.5179726636388742, + "holonomicRotation": 4.045231319175155, + "angularVelocity": 0.7933195910243753, + "holonomicAngularVelocity": -29.31457331653535 + }, + { + "time": 3.630774437679643, + "pose": { + "rotation": { + "radians": 2.923097231303318 + }, + "translation": { + "x": 4.606299968000002, + "y": 3.043193640963593 + } + }, + "velocity": -1.5195287786373484, + "acceleration": 3.0, + "curvature": -0.5192854061280454, + "holonomicRotation": 3.814147232058671, + "angularVelocity": 0.7829509721905035, + "holonomicAngularVelocity": -28.054468752649058 + }, + { + "time": 3.6387795924199784, + "pose": { + "rotation": { + "radians": 2.9293648749897994 + }, + "translation": { + "x": 4.6180971520000025, + "y": 3.040651671755615 + } + }, + "velocity": -1.495513314416341, + "acceleration": 3.0000000000000275, + "curvature": -0.5206111181933657, + "holonomicRotation": 3.589566868535803, + "angularVelocity": 0.7723433104766161, + "holonomicAngularVelocity": -26.80803674146673 + }, + { + "time": 3.6469130181605207, + "pose": { + "rotation": { + "radians": 2.9356466719517655 + }, + "translation": { + "x": 4.629906624000001, + "y": 3.0381845798900473 + } + }, + "velocity": -1.4711130371947143, + "acceleration": 2.999999999999973, + "curvature": -0.5219494283315183, + "holonomicRotation": 3.371525692449353, + "angularVelocity": 0.7614837986078355, + "holonomicAngularVelocity": -25.575919780440216 + }, + { + "time": 3.6551812469959284, + "pose": { + "rotation": { + "radians": 2.9419427942531104 + }, + "translation": { + "x": 4.641728000000002, + "y": 3.035792577263169 + } + }, + "velocity": -1.4463083506884924, + "acceleration": 2.9999999999999463, + "curvature": -0.5232999531912867, + "holonomicRotation": 3.1600581350286494, + "angularVelocity": 0.7503586730135737, + "holonomicAngularVelocity": -24.35877431164802 + }, + { + "time": 3.663591380566494, + "pose": { + "rotation": { + "radians": 2.948253410918987 + }, + "translation": { + "x": 4.653560896000002, + "y": 3.0334758757712623 + } + }, + "velocity": -1.4210779499767952, + "acceleration": 3.0, + "curvature": -0.5246622973501797, + "holonomicRotation": 2.955197589452424, + "angularVelocity": 0.7389530980618538, + "holonomicAngularVelocity": -23.15727196183363 + }, + { + "time": 3.672151161882855, + "pose": { + "rotation": { + "radians": 2.954578687841444 + }, + "translation": { + "x": 4.665404928000002, + "y": 3.031234687310606 + } + }, + "velocity": -1.3953986060277122, + "acceleration": 3.0000000000000258, + "curvature": -0.5260360531124699, + "holonomicRotation": 2.7569764055756316, + "angularVelocity": 0.7272510313156108, + "holonomicAngularVelocity": -21.972100947492603 + }, + { + "time": 3.680869059238794, + "pose": { + "rotation": { + "radians": 2.960918787684454 + }, + "translation": { + "x": 4.6772597120000015, + "y": 3.029069223777483 + } + }, + "velocity": -1.3692449139598961, + "acceleration": 2.9999999999999747, + "curvature": -0.5274208004195751, + "holonomicRotation": 2.5654258848210665, + "angularVelocity": 0.7152350654277648, + "holonomicAngularVelocity": -20.8039676724005 + }, + { + "time": 3.689754364796628, + "pose": { + "rotation": { + "radians": 2.9672738697864576 + }, + "translation": { + "x": 4.689124864000002, + "y": 3.0269796970681724 + } + }, + "velocity": -1.3425889972863922, + "acceleration": 3.0, + "curvature": -0.5288161067204993, + "holonomicRotation": 2.3805762752364745, + "angularVelocity": 0.7028862421564607, + "holonomicAngularVelocity": -19.653598551045544 + }, + { + "time": 3.6988173111092735, + "pose": { + "rotation": { + "radians": 2.9736440900630186 + }, + "translation": { + "x": 4.701000000000001, + "y": 3.0249663190789553 + } + }, + "velocity": -1.3154001583484565, + "acceleration": 3.0, + "curvature": -0.530221526743801, + "holonomicRotation": 2.202456766718066, + "angularVelocity": 0.6901838315299829, + "holonomicAngularVelocity": -18.521742098502607 + }, + { + "time": 3.7080692097376904, + "pose": { + "rotation": { + "radians": 2.980029600907306 + }, + "translation": { + "x": 4.712884736000002, + "y": 3.0230293017061127 + } + }, + "velocity": -1.2876444624632064, + "acceleration": 3.0, + "curvature": -0.5316366023821089, + "holonomicRotation": 2.031095486401042, + "angularVelocity": 0.6771050683668322, + "holonomicAngularVelocity": -17.409171336522384 + }, + { + "time": 3.7175226173124507, + "pose": { + "rotation": { + "radians": 2.986430551089514 + }, + "translation": { + "x": 4.724778688000002, + "y": 3.021168856845925 + } + }, + "velocity": -1.2592842397389246, + "acceleration": 3.0000000000000235, + "curvature": -0.5330608626280348, + "holonomicRotation": 1.8665194942180574, + "angularVelocity": 0.6636248354538734, + "holonomicAngularVelocity": -16.3166865772123 + }, + { + "time": 3.727191535989376, + "pose": { + "rotation": { + "radians": 2.992847085655505 + }, + "translation": { + "x": 4.736681472000003, + "y": 3.0193851963946727 + } + }, + "velocity": -1.2302774837081494, + "acceleration": 3.000000000000023, + "curvature": -0.5344938233678657, + "holonomicRotation": 1.7087547786261181, + "angularVelocity": 0.6497152794409348, + "holonomicAngularVelocity": -15.245118660858344 + }, + { + "time": 3.7370916574302786, + "pose": { + "rotation": { + "radians": 2.9992793458239806 + }, + "translation": { + "x": 4.748592704000002, + "y": 3.0176785322486377 + } + }, + "velocity": -1.2005771193854406, + "acceleration": 3.0, + "curvature": -0.5359349872727417, + "holonomicRotation": 1.5578262525026454, + "angularVelocity": 0.6353453412347533, + "holonomicAngularVelocity": -14.195332743797312 + }, + { + "time": 3.7472406624512438, + "pose": { + "rotation": { + "radians": 3.0057274688822186 + }, + "translation": { + "x": 4.760512000000002, + "y": 3.016049076304099 + } + }, + "velocity": -1.1701301043225467, + "acceleration": 2.9999999999999782, + "curvature": -0.5373838437421952, + "holonomicRotation": 1.4137577492115816, + "angularVelocity": 0.62048017653661, + "holonomicAngularVelocity": -13.168232758378622 + }, + { + "time": 3.757658592699678, + "pose": { + "rotation": { + "radians": 3.0121915880819135 + }, + "translation": { + "x": 4.772438976000002, + "y": 3.0144970404573384 + } + }, + "velocity": -1.1388763135772426, + "acceleration": 3.0000000000000213, + "curvature": -0.5388398686776363, + "holonomicRotation": 1.2765720188396412, + "angularVelocity": 0.6050804328165802, + "holonomicAngularVelocity": -12.164766700902831 + }, + { + "time": 3.768368316728004, + "pose": { + "rotation": { + "radians": 3.018671832532319 + }, + "translation": { + "x": 4.784373248000002, + "y": 3.0130226366046355 + } + }, + "velocity": -1.106747141492265, + "acceleration": 3.000000000000021, + "curvature": -0.5403025245756908, + "holonomicRotation": 1.1462907246040044, + "angularVelocity": 0.589101337479254, + "holonomicAngularVelocity": -11.185932950216882 + }, + { + "time": 3.779396121536215, + "pose": { + "rotation": { + "radians": 3.0251683270942964 + }, + "translation": { + "x": 4.796314432000002, + "y": 3.011626076642273 + } + }, + "velocity": -1.073663727067631, + "acceleration": 3.0, + "curvature": -0.5417712602151914, + "holonomicRotation": 1.0229344394312734, + "angularVelocity": 0.57249153214415, + "holonomicAngularVelocity": -10.232787882509578 + }, + { + "time": 3.7907724735195667, + "pose": { + "rotation": { + "radians": 3.0316811922714564 + }, + "translation": { + "x": 4.808262144000002, + "y": 3.01030757246653 + } + }, + "velocity": -1.039534671117577, + "acceleration": 2.9999999999999805, + "curvature": -0.5432455108121239, + "holonomicRotation": 0.9065226427088713, + "angularVelocity": 0.5551915617904356, + "holonomicAngularVelocity": -9.306455136223637 + }, + { + "time": 3.8025330121884613, + "pose": { + "rotation": { + "radians": 3.0382105441025367 + }, + "translation": { + "x": 4.820216000000001, + "y": 3.009067335973687 + } + }, + "velocity": -1.0042530551108941, + "acceleration": 2.999999999999981, + "curvature": -0.5447246977401435, + "holonomicRotation": 0.7970737172089826, + "angularVelocity": 0.5371318836759915, + "holonomicAngularVelocity": -8.408137005072163 + }, + { + "time": 3.814719870104957, + "pose": { + "rotation": { + "radians": 3.044756494051316 + }, + "translation": { + "x": 4.8321756160000024, + "y": 3.0079055790600258 + } + }, + "velocity": -0.9676924813614058, + "acceleration": 3.0, + "curvature": -0.5462082286298287, + "holonomicRotation": 0.6946049461857351, + "angularVelocity": 0.5182301955923827, + "holonomicAngularVelocity": -7.539128616449812 + }, + { + "time": 3.827383460341566, + "pose": { + "rotation": { + "radians": 3.0513191488965354 + }, + "translation": { + "x": 4.844140608000002, + "y": 3.006822513621827 + } + }, + "velocity": -0.9297017106515791, + "acceleration": 3.000000000000026, + "curvature": -0.5476954972706566, + "holonomicRotation": 0.5991325106459233, + "angularVelocity": 0.4983877740925543, + "holonomicAngularVelocity": -6.700835815571002 + }, + { + "time": 3.8405849513625085, + "pose": { + "rotation": { + "radians": 3.057898610621166 + }, + "translation": { + "x": 4.856110592000002, + "y": 3.0058183515553702 + } + }, + "velocity": -0.8900972375887511, + "acceleration": 3.000000000000017, + "curvature": -0.549185883552854, + "holonomicRotation": 0.5106714867938522, + "angularVelocity": 0.4774843322945403, + "holonomicAngularVelocity": -5.8947980717647805 + }, + { + "time": 3.8543997830415164, + "pose": { + "rotation": { + "radians": 3.0644949763011784 + }, + "translation": { + "x": 4.868085184000002, + "y": 3.004893304756937 + } + }, + "velocity": -0.8486527425517276, + "acceleration": 2.999999999999992, + "curvature": -0.550678753507413, + "holonomicRotation": 0.42923584365068157, + "angularVelocity": 0.4553705897180785, + "holonomicAngularVelocity": -5.122718333648229 + }, + { + "time": 3.868922815142172, + "pose": { + "rotation": { + "radians": 3.0711083379933486 + }, + "translation": { + "x": 4.880064000000003, + "y": 3.0040475851228083 + } + }, + "velocity": -0.8050836462497605, + "acceleration": 2.9999999999999925, + "curvature": -0.5521734592537758, + "holonomicRotation": 0.3548384408484906, + "angularVelocity": 0.43185716592552986, + "holonomicAngularVelocity": -4.386502727126849 + }, + { + "time": 3.8842761429384574, + "pose": { + "rotation": { + "radians": 3.077738782622978 + }, + "translation": { + "x": 4.8920466560000015, + "y": 3.003281404549264 + } + }, + "velocity": -0.759023662860904, + "acceleration": 3.0000000000000218, + "curvature": -0.5536693390456592, + "holonomicRotation": 0.28749102659961223, + "angularVelocity": 0.4066972833724865, + "holonomicAngularVelocity": -3.688314566573384 + }, + { + "time": 3.900621492465988, + "pose": { + "rotation": { + "radians": 3.0843863918715986 + }, + "translation": { + "x": 4.904032768000002, + "y": 3.002594974932586 + } + }, + "velocity": -0.7099876142783116, + "acceleration": 3.0000000000000067, + "curvature": -0.555165717284197, + "holonomicRotation": 0.2272042358414872, + "angularVelocity": 0.3795584251366028, + "holonomicAngularVelocity": -3.030649789986334 + }, + { + "time": 3.9181809767257976, + "pose": { + "rotation": { + "radians": 3.091051242063463 + }, + "translation": { + "x": 4.916021952000001, + "y": 3.001988508169053 + } + }, + "velocity": -0.6573091614988833, + "acceleration": 2.999999999999994, + "curvature": -0.5566619045708889, + "holonomicRotation": 0.1739875885572273, + "angularVelocity": 0.34997279260682573, + "holonomicAngularVelocity": -2.416445429868007 + }, + { + "time": 3.9372743523570404, + "pose": { + "rotation": { + "radians": 3.09773340405342 + }, + "translation": { + "x": 4.928013824000002, + "y": 3.001462216154948 + } + }, + "velocity": -0.6000290346051556, + "acceleration": 3.0, + "curvature": -0.5581571976422951, + "holonomicRotation": 0.12784948827235798, + "angularVelocity": 0.3172429663973512, + "holonomicAngularVelocity": -1.8492402373960939 + }, + { + "time": 3.958392358960432, + "pose": { + "rotation": { + "radians": 3.1044329431126787 + }, + "translation": { + "x": 4.9400080000000015, + "y": 3.00101631078655 + } + }, + "velocity": -0.5366750147949809, + "acceleration": 2.9999999999999947, + "curvature": -0.5596508797624753, + "holonomicRotation": 0.08879722072776985, + "angularVelocity": 0.28023940774195016, + "holonomicAngularVelocity": -1.3334165508090225 + }, + { + "time": 3.982361063998006, + "pose": { + "rotation": { + "radians": 3.11114991881675 + }, + "translation": { + "x": 4.952004096000002, + "y": 3.00065100396014 + } + }, + "velocity": -0.4647688996822589, + "acceleration": 2.9999999999999907, + "curvature": -0.5611422204213573, + "holonomicRotation": 0.05683695272920897, + "angularVelocity": 0.2368783781248903, + "holonomicAngularVelocity": -0.8745399406582713 + }, + { + "time": 4.010791122363344, + "pose": { + "rotation": { + "radians": 3.117884384932327 + }, + "translation": { + "x": 4.964001728000001, + "y": 3.000366507572 + } + }, + "velocity": -0.379478724586247, + "acceleration": 3.0000000000000115, + "curvature": -0.5626304757071848, + "holonomicRotation": 0.031973731173475795, + "angularVelocity": 0.18224260470890688, + "holonomicAngularVelocity": -0.4794189000382439 + }, + { + "time": 4.047840660711865, + "pose": { + "rotation": { + "radians": 3.124636389304224 + }, + "translation": { + "x": 4.976000512000002, + "y": 3.0001630335184095 + } + }, + "velocity": -0.26833010954068137, + "acceleration": 3.0, + "curvature": -0.5641148883737164, + "holonomicRotation": 0.014211482251502705, + "angularVelocity": 0.07568570427505669, + "holonomicAngularVelocity": -0.1191644662033369 + }, + { + "time": 4.137284030558758, + "pose": { + "rotation": { + "radians": 3.1314059737438207 + }, + "translation": { + "x": 4.988000064000001, + "y": 3.000040793695649 + } + }, + "velocity": 0, + "acceleration": 3.0000000000000027, + "curvature": -0.5641148883737164, + "holonomicRotation": 0.0035530108282699757, + "angularVelocity": 0.0, + "holonomicAngularVelocity": 0.0 + } +] \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/pathplanner/navgrid.json b/examples/drivebase_only_2026/src/main/deploy/pathplanner/navgrid.json new file mode 100644 index 0000000..c1fc67b --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/pathplanner/navgrid.json @@ -0,0 +1,1656 @@ +{ + "field_size": { + "x": 17.548, + "y": 8.052 + }, + "nodeSizeMeters": 0.3, + "grid": [ + [ + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true + ], + [ + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true + ], + [ + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true + ], + [ + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true + ], + [ + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true + ], + [ + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true + ], + [ + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true + ], + [ + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true + ], + [ + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true + ] + ] +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/pathplanner/paths/New Path.path b/examples/drivebase_only_2026/src/main/deploy/pathplanner/paths/New Path.path new file mode 100644 index 0000000..679a12e --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/pathplanner/paths/New Path.path @@ -0,0 +1,70 @@ +{ + "version": "2025.0", + "waypoints": [ + { + "anchor": { + "x": 2.0, + "y": 7.0 + }, + "prevControl": null, + "nextControl": { + "x": 3.0, + "y": 6.5 + }, + "isLocked": false, + "linkedName": null + }, + { + "anchor": { + "x": 4.958476027397261, + "y": 6.012192024384049 + }, + "prevControl": { + "x": 3.9584760273972606, + "y": 7.012192024384048 + }, + "nextControl": { + "x": 5.958476027397261, + "y": 5.012192024384049 + }, + "isLocked": false, + "linkedName": null + }, + { + "anchor": { + "x": 7.225280307703473, + "y": 6.012192024384049 + }, + "prevControl": { + "x": 6.975280307703473, + "y": 7.512192024384059 + }, + "nextControl": null, + "isLocked": false, + "linkedName": null + } + ], + "rotationTargets": [], + "constraintZones": [], + "pointTowardsZones": [], + "eventMarkers": [], + "globalConstraints": { + "maxVelocity": 3.0, + "maxAcceleration": 3.0, + "maxAngularVelocity": 540.0, + "maxAngularAcceleration": 720.0, + "nominalVoltage": 12.0, + "unlimited": false + }, + "goalEndState": { + "velocity": 0, + "rotation": 0.0 + }, + "reversed": false, + "folder": null, + "idealStartingState": { + "velocity": 0, + "rotation": 0.0 + }, + "useDefaultConstraints": false +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/pathplanner/settings.json b/examples/drivebase_only_2026/src/main/deploy/pathplanner/settings.json new file mode 100644 index 0000000..2ca3c4c --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/pathplanner/settings.json @@ -0,0 +1,32 @@ +{ + "robotWidth": 0.9, + "robotLength": 0.9, + "holonomicMode": true, + "pathFolders": [], + "autoFolders": [], + "defaultMaxVel": 3.0, + "defaultMaxAccel": 3.0, + "defaultMaxAngVel": 540.0, + "defaultMaxAngAccel": 720.0, + "defaultNominalVoltage": 12.0, + "robotMass": 74.088, + "robotMOI": 6.883, + "robotTrackwidth": 0.546, + "driveWheelRadius": 0.048, + "driveGearing": 5.143, + "maxDriveSpeed": 5.45, + "driveMotorType": "NEO", + "driveCurrentLimit": 60.0, + "wheelCOF": 1.2, + "flModuleX": 0.273, + "flModuleY": 0.273, + "frModuleX": 0.273, + "frModuleY": -0.273, + "blModuleX": -0.273, + "blModuleY": 0.273, + "brModuleX": -0.273, + "brModuleY": -0.273, + "bumperOffsetX": 0.0, + "bumperOffsetY": 0.0, + "robotFeatures": [] +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/controllerproperties.json b/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/controllerproperties.json new file mode 100644 index 0000000..5c7d529 --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/controllerproperties.json @@ -0,0 +1,8 @@ +{ + "angleJoystickRadiusDeadband": 0.5, + "heading": { + "p": 0.118, + "i": 0, + "d": 0 + } +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/backleft.json b/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/backleft.json new file mode 100644 index 0000000..547032e --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/backleft.json @@ -0,0 +1,26 @@ +{ + "drive": { + "type": "talonfx", + "id": 4, + "canbus": null + }, + "angle": { + "type": "talonfx", + "id": 2, + "canbus": null + }, + "encoder": { + "type": "cancoder", + "id": 1, + "canbus": null + }, + "inverted": { + "drive": false, + "angle": false + }, + "absoluteEncoderOffset": -259.805, + "location": { + "front": -7, + "left": 7 + } +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/backright.json b/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/backright.json new file mode 100644 index 0000000..557c253 --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/backright.json @@ -0,0 +1,26 @@ +{ + "drive": { + "type": "talonfx", + "id": 3, + "canbus": null + }, + "angle": { + "type": "talonfx", + "id": 53, + "canbus": null + }, + "encoder": { + "type": "cancoder", + "id": 4, + "canbus": null + }, + "inverted": { + "drive": false, + "angle": false + }, + "absoluteEncoderOffset": -31.816, + "location": { + "front": -7, + "left": -7 + } +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/frontleft.json b/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/frontleft.json new file mode 100644 index 0000000..51c0ff2 --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/frontleft.json @@ -0,0 +1,26 @@ +{ + "drive": { + "type": "talonfx", + "id": 50, + "canbus": null + }, + "angle": { + "type": "talonfx", + "id": 8, + "canbus": null + }, + "encoder": { + "type": "cancoder", + "id": 3, + "canbus": null + }, + "inverted": { + "drive": false, + "angle": false + }, + "absoluteEncoderOffset": -139.043, + "location": { + "front": 7, + "left": 7 + } +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/frontright.json b/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/frontright.json new file mode 100644 index 0000000..1037f63 --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/frontright.json @@ -0,0 +1,26 @@ +{ + "drive": { + "type": "talonfx", + "id": 51, + "canbus": null + }, + "angle": { + "type": "talonfx", + "id": 52, + "canbus": null + }, + "encoder": { + "type": "cancoder", + "id": 2, + "canbus": null + }, + "inverted": { + "drive": false, + "angle": false + }, + "absoluteEncoderOffset": -118.564, + "location": { + "front": 7, + "left": -7 + } +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/physicalproperties.json b/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/physicalproperties.json new file mode 100644 index 0000000..efeb5d6 --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/physicalproperties.json @@ -0,0 +1,23 @@ +{ + "conversionFactors": { + "angle": { + "gearRatio": 21.4285714286, + "factor": 0 + }, + "drive": { + "gearRatio": 8.14, + "diameter": 4, + "factor": 0 + } + }, + "currentLimit": { + "drive": 40, + "angle": 20 + }, + "rampRate": { + "drive": 0.25, + "angle": 0.25 + }, + "wheelGripCoefficientOfFriction": 1.19, + "optimalVoltage": 12 +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/pidfproperties.json b/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/pidfproperties.json new file mode 100644 index 0000000..5aed412 --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/modules/pidfproperties.json @@ -0,0 +1,16 @@ +{ + "drive": { + "p": 1, + "i": 0, + "d": 0, + "f": 0, + "iz": 0 + }, + "angle": { + "p": 50, + "i": 0, + "d": 0.32, + "f": 0, + "iz": 0 + } +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/swervedrive.json b/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/swervedrive.json new file mode 100644 index 0000000..f4631eb --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/swervedrive.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://broncbotz3481.github.io/YAGSL-Example/schemas/swervedrive_schema.json", + "imu": { + "type": "navx", + "id": 13, + "canbus": "canivore" + }, + "invertedIMU": true, + "modules": [ + "frontleft.json", + "frontright.json", + "backleft.json", + "backright.json" + ] +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/controllerproperties.json b/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/controllerproperties.json new file mode 100644 index 0000000..669097e --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/controllerproperties.json @@ -0,0 +1,8 @@ +{ + "angleJoystickRadiusDeadband": 0.5, + "heading": { + "p": 0.4, + "i": 0, + "d": 0.01 + } +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/backleft.json b/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/backleft.json new file mode 100644 index 0000000..571d166 --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/backleft.json @@ -0,0 +1,27 @@ +{ + "drive": { + "type": "sparkmax_neo", + "id": 42, + "canbus": null + }, + "angle": { + "type": "sparkmax_neo550", + "id": 4, + "canbus": null + }, + "encoder": { + "type": "attached", + "id": 0, + "canbus": null + }, + "inverted": { + "drive": false, + "angle": false + }, + "absoluteEncoderInverted": true, + "absoluteEncoderOffset": 301.3301969, + "location": { + "front": -12, + "left": 12 + } +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/backright.json b/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/backright.json new file mode 100644 index 0000000..90e2a56 --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/backright.json @@ -0,0 +1,27 @@ +{ + "drive": { + "type": "sparkmax_neo", + "id": 22, + "canbus": null + }, + "angle": { + "type": "sparkmax_neo550", + "id": 21, + "canbus": null + }, + "encoder": { + "type": "attached", + "id": 0, + "canbus": null + }, + "inverted": { + "drive": false, + "angle": false + }, + "absoluteEncoderInverted": true, + "absoluteEncoderOffset": 7.6941204, + "location": { + "front": -12, + "left": -12 + } +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/frontleft.json b/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/frontleft.json new file mode 100644 index 0000000..c1ceeda --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/frontleft.json @@ -0,0 +1,27 @@ +{ + "drive": { + "type": "sparkmax_neo", + "id": 32, + "canbus": null + }, + "angle": { + "type": "sparkmax_neo550", + "id": 31, + "canbus": null + }, + "encoder": { + "type": "attached", + "id": 0, + "canbus": null + }, + "inverted": { + "drive": false, + "angle": false + }, + "absoluteEncoderInverted": true, + "absoluteEncoderOffset": 90, + "location": { + "front": 12, + "left": 12 + } +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/frontright.json b/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/frontright.json new file mode 100644 index 0000000..6541c7c --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/frontright.json @@ -0,0 +1,27 @@ +{ + "drive": { + "type": "sparkmax_neo", + "id": 12, + "canbus": null + }, + "angle": { + "type": "sparkmax_neo550", + "id": 11, + "canbus": null + }, + "encoder": { + "type": "attached", + "id": 0, + "canbus": null + }, + "inverted": { + "drive": false, + "angle": false + }, + "absoluteEncoderInverted": true, + "absoluteEncoderOffset": -90, + "location": { + "front": 12, + "left": -12 + } +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/physicalproperties.json b/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/physicalproperties.json new file mode 100644 index 0000000..e2013af --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/physicalproperties.json @@ -0,0 +1,23 @@ +{ + "conversionFactors": { + "angle": { + "gearRatio": 46.42, + "factor": 0 + }, + "drive": { + "gearRatio": 5.50, + "diameter": 3, + "factor": 0 + } + }, + "currentLimit": { + "drive": 40, + "angle": 20 + }, + "rampRate": { + "drive": 0.25, + "angle": 0.25 + }, + "optimalVoltage": 12, + "wheelGripCoefficientOfFriction": 1.19 +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/pidfproperties.json b/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/pidfproperties.json new file mode 100644 index 0000000..99664bb --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/modules/pidfproperties.json @@ -0,0 +1,16 @@ +{ + "drive": { + "p": 0.0020645, + "i": 0, + "d": 0, + "f": 0, + "iz": 0 + }, + "angle": { + "p": 0.01, + "i": 0, + "d": 0, + "f": 0, + "iz": 0 + } +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/swervedrive.json b/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/swervedrive.json new file mode 100644 index 0000000..b42e51e --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/maxSwerve/swervedrive.json @@ -0,0 +1,14 @@ +{ + "imu": { + "type": "navx_spi", + "id": 0, + "canbus": null + }, + "invertedIMU": false, + "modules": [ + "frontleft.json", + "frontright.json", + "backleft.json", + "backright.json" + ] +} diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/neo/controllerproperties.json b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/controllerproperties.json new file mode 100644 index 0000000..669097e --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/controllerproperties.json @@ -0,0 +1,8 @@ +{ + "angleJoystickRadiusDeadband": 0.5, + "heading": { + "p": 0.4, + "i": 0, + "d": 0.01 + } +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/backleft.json b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/backleft.json new file mode 100644 index 0000000..6c6c7d9 --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/backleft.json @@ -0,0 +1,26 @@ +{ + "drive": { + "type": "sparkmax_neo", + "id": 7, + "canbus": null + }, + "angle": { + "type": "sparkmax_neo", + "id": 8, + "canbus": null + }, + "encoder": { + "type": "cancoder", + "id": 12, + "canbus": null + }, + "inverted": { + "drive": false, + "angle": false + }, + "absoluteEncoderOffset": 6.504, + "location": { + "front": -12, + "left": 12 + } +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/backright.json b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/backright.json new file mode 100644 index 0000000..4f9f082 --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/backright.json @@ -0,0 +1,26 @@ +{ + "drive": { + "type": "sparkmax_neo", + "id": 5, + "canbus": null + }, + "angle": { + "type": "sparkmax_neo", + "id": 6, + "canbus": null + }, + "encoder": { + "type": "cancoder", + "id": 11, + "canbus": null + }, + "inverted": { + "drive": false, + "angle": false + }, + "absoluteEncoderOffset": -18.281, + "location": { + "front": -12, + "left": -12 + } +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/frontleft.json b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/frontleft.json new file mode 100644 index 0000000..a3ef16b --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/frontleft.json @@ -0,0 +1,26 @@ +{ + "drive": { + "type": "sparkmax_neo", + "id": 4, + "canbus": null + }, + "angle": { + "type": "sparkmax_neo", + "id": 3, + "canbus": null + }, + "encoder": { + "type": "cancoder", + "id": 9, + "canbus": null + }, + "inverted": { + "drive": false, + "angle": false + }, + "absoluteEncoderOffset": -114.609, + "location": { + "front": 12, + "left": 12 + } +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/frontright.json b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/frontright.json new file mode 100644 index 0000000..b60f22f --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/frontright.json @@ -0,0 +1,26 @@ +{ + "drive": { + "type": "sparkmax_neo", + "id": 2, + "canbus": null + }, + "angle": { + "type": "sparkmax_neo", + "id": 1, + "canbus": null + }, + "encoder": { + "type": "cancoder", + "id": 10, + "canbus": null + }, + "inverted": { + "drive": false, + "angle": false + }, + "absoluteEncoderOffset": -50.977, + "location": { + "front": 12, + "left": -12 + } +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/physicalproperties.json b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/physicalproperties.json new file mode 100644 index 0000000..d7ae5ab --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/physicalproperties.json @@ -0,0 +1,23 @@ +{ + "conversionFactors": { + "angle": { + "gearRatio": 12.8, + "factor": 0 + }, + "drive": { + "gearRatio": 8.14, + "diameter": 4, + "factor": 0 + } + }, + "currentLimit": { + "drive": 40, + "angle": 20 + }, + "rampRate": { + "drive": 0.25, + "angle": 0.25 + }, + "wheelGripCoefficientOfFriction": 1.19, + "optimalVoltage": 12 +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/pidfproperties.json b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/pidfproperties.json new file mode 100644 index 0000000..1f0b34b --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/pidfproperties.json @@ -0,0 +1,16 @@ +{ + "drive": { + "p": 0.00023, + "i": 0.0000002, + "d": 1, + "f": 0, + "iz": 0 + }, + "angle": { + "p": 0.01, + "i": 0, + "d": 0, + "f": 0, + "iz": 0 + } +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/neo/swervedrive.json b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/swervedrive.json new file mode 100644 index 0000000..89ae3b1 --- /dev/null +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/swervedrive.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://broncbotz3481.github.io/YAGSL-Example/schemas/swervedrive_schema.json", + "imu": { + "type": "pigeon2", + "id": 13, + "canbus": "canivore" + }, + "invertedIMU": true, + "modules": [ + "frontleft.json", + "frontright.json", + "backleft.json", + "backright.json" + ] +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/src/main/java/frc/robot/Constants.java b/examples/drivebase_only_2026/src/main/java/frc/robot/Constants.java new file mode 100644 index 0000000..b5b7e09 --- /dev/null +++ b/examples/drivebase_only_2026/src/main/java/frc/robot/Constants.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; + +import edu.wpi.first.math.geometry.Translation3d; +import edu.wpi.first.math.util.Units; +import swervelib.math.Matter; + +/** + * The Constants class provides a convenient place for teams to hold robot-wide numerical or boolean constants. This + * class should not be used for any other purpose. All constants should be declared globally (i.e. public static). Do + * not put anything functional in this class. + * + *

It is advised to statically import this class (or one of its inner classes) wherever the + * constants are needed, to reduce verbosity. + */ +public final class Constants +{ + + public static final double ROBOT_MASS = (148 - 20.3) * 0.453592; // 32lbs * kg per pound + public static final Matter CHASSIS = new Matter(new Translation3d(0, 0, Units.inchesToMeters(8)), ROBOT_MASS); + public static final double LOOP_TIME = 0.13; //s, 20ms + 110ms sprk max velocity lag + public static final double MAX_SPEED = Units.feetToMeters(14.5); + // Maximum speed of the robot in meters per second, used to limit acceleration. + +// public static final class AutonConstants +// { +// +// public static final PIDConstants TRANSLATION_PID = new PIDConstants(0.7, 0, 0); +// public static final PIDConstants ANGLE_PID = new PIDConstants(0.4, 0, 0.01); +// } + + public static final class DrivebaseConstants + { + + // Hold time on motor brakes when disabled + public static final double WHEEL_LOCK_TIME = 10; // seconds + } + + public static class OperatorConstants + { + + // Joystick Deadband + public static final double DEADBAND = 0.1; + public static final double LEFT_Y_DEADBAND = 0.1; + public static final double RIGHT_X_DEADBAND = 0.1; + public static final double TURN_CONSTANT = 6; + } +} diff --git a/examples/drivebase_only_2026/src/main/java/frc/robot/Main.java b/examples/drivebase_only_2026/src/main/java/frc/robot/Main.java new file mode 100644 index 0000000..4ca4b2f --- /dev/null +++ b/examples/drivebase_only_2026/src/main/java/frc/robot/Main.java @@ -0,0 +1,29 @@ +// 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; + +import edu.wpi.first.wpilibj.RobotBase; + +/** + * Do NOT add any static variables to this class, or any initialization at all. Unless you know what you are doing, do + * not modify this file except to change the parameter class to the startRobot call. + */ +public final class Main +{ + + private Main() + { + } + + /** + * Main initialization function. Do not perform any initialization here. + * + *

If you change your main robot class, change the parameter type. + */ + public static void main(String... args) + { + RobotBase.startRobot(Robot::new); + } +} diff --git a/examples/drivebase_only_2026/src/main/java/frc/robot/Robot.java b/examples/drivebase_only_2026/src/main/java/frc/robot/Robot.java new file mode 100644 index 0000000..e70ed5b --- /dev/null +++ b/examples/drivebase_only_2026/src/main/java/frc/robot/Robot.java @@ -0,0 +1,178 @@ +// 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; + +import edu.wpi.first.wpilibj.DriverStation; +import edu.wpi.first.wpilibj.TimedRobot; +import edu.wpi.first.wpilibj.Timer; +import edu.wpi.first.wpilibj2.command.Command; +import edu.wpi.first.wpilibj2.command.CommandScheduler; + +/** + * The VM is configured to automatically run this class, and to call the functions corresponding to each mode, as + * described in the TimedRobot documentation. If you change the name of this class or the package after creating this + * project, you must also update the build.gradle file in the project. + */ +public class Robot extends TimedRobot +{ + + private static Robot instance; + private Command m_autonomousCommand; + + private RobotContainer m_robotContainer; + + private Timer disabledTimer; + + public Robot() + { + instance = this; + } + + public static Robot getInstance() + { + return instance; + } + + /** + * This function is run when the robot is first started up and should be used for any initialization code. + */ + @Override + public void robotInit() + { + // Instantiate our RobotContainer. This will perform all our button bindings, and put our + // autonomous chooser on the dashboard. + m_robotContainer = new RobotContainer(); + + // Create a timer to disable motor brake a few seconds after disable. This will let the robot stop + // immediately when disabled, but then also let it be pushed more + disabledTimer = new Timer(); + + if (isSimulation()) + { + DriverStation.silenceJoystickConnectionWarning(true); + } + } + + /** + * This function is called every 20 ms, no matter the mode. Use this for items like diagnostics that you want ran + * during disabled, autonomous, teleoperated and test. + * + *

This runs after the mode specific periodic functions, but before LiveWindow and + * SmartDashboard integrated updating. + */ + @Override + public void robotPeriodic() + { + // Runs the Scheduler. This is responsible for polling buttons, adding newly-scheduled + // commands, running already-scheduled commands, removing finished or interrupted commands, + // and running subsystem periodic() methods. This must be called from the robot's periodic + // block in order for anything in the Command-based framework to work. + CommandScheduler.getInstance().run(); + } + + /** + * This function is called once each time the robot enters Disabled mode. + */ + @Override + public void disabledInit() + { + m_robotContainer.setMotorBrake(true); + disabledTimer.reset(); + disabledTimer.start(); + } + + @Override + public void disabledPeriodic() + { + if (disabledTimer.hasElapsed(Constants.DrivebaseConstants.WHEEL_LOCK_TIME)) + { + m_robotContainer.setMotorBrake(false); + disabledTimer.stop(); + disabledTimer.reset(); + } + } + + /** + * This autonomous runs the autonomous command selected by your {@link RobotContainer} class. + */ + @Override + public void autonomousInit() + { + m_robotContainer.setMotorBrake(true); + m_autonomousCommand = m_robotContainer.getAutonomousCommand(); + + //Print the selected autonomous command upon autonomous init + System.out.println("Auto selected: " + m_autonomousCommand); + + // schedule the autonomous command selected in the autoChooser + if (m_autonomousCommand != null) + { + m_autonomousCommand.schedule(); + } + } + + /** + * This function is called periodically during autonomous. + */ + @Override + public void autonomousPeriodic() + { + } + + @Override + public void teleopInit() + { + // This makes sure that the autonomous stops running when + // teleop starts running. If you want the autonomous to + // continue until interrupted by another command, remove + // this line or comment it out. + if (m_autonomousCommand != null) + { + m_autonomousCommand.cancel(); + } else + { + CommandScheduler.getInstance().cancelAll(); + } + } + + /** + * This function is called periodically during operator control. + */ + @Override + public void teleopPeriodic() + { + } + + @Override + public void testInit() + { + // Cancels all running commands at the start of test mode. + CommandScheduler.getInstance().cancelAll(); + } + + /** + * This function is called periodically during test mode. + */ + @Override + public void testPeriodic() + { + } + + /** + * This function is called once when the robot is first started up. + */ + @Override + public void simulationInit() + { + } + + /** + * This function is called periodically whilst in simulation. + */ + @Override + public void simulationPeriodic() + { + } +} diff --git a/examples/drivebase_only_2026/src/main/java/frc/robot/RobotContainer.java b/examples/drivebase_only_2026/src/main/java/frc/robot/RobotContainer.java new file mode 100644 index 0000000..28294a8 --- /dev/null +++ b/examples/drivebase_only_2026/src/main/java/frc/robot/RobotContainer.java @@ -0,0 +1,205 @@ +// 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; + +import edu.wpi.first.math.controller.ProfiledPIDController; +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.trajectory.TrapezoidProfile.Constraints; +import edu.wpi.first.math.util.Units; +import edu.wpi.first.wpilibj.DriverStation; +import edu.wpi.first.wpilibj.Filesystem; +import edu.wpi.first.wpilibj.RobotBase; +import edu.wpi.first.wpilibj.smartdashboard.SendableChooser; +import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; +import edu.wpi.first.wpilibj2.command.Command; +import edu.wpi.first.wpilibj2.command.Commands; +import edu.wpi.first.wpilibj2.command.button.CommandXboxController; +import edu.wpi.first.wpilibj2.command.button.RobotModeTriggers; +import edu.wpi.first.wpilibj2.command.button.Trigger; +import frc.robot.Constants.OperatorConstants; +import frc.robot.subsystems.swervedrive.SwerveSubsystem; +import java.io.File; +import swervelib.SwerveInputStream; + +/** + * This class is where the bulk of the robot should be declared. Since Command-based is a "declarative" paradigm, very + * little robot logic should actually be handled in the {@link Robot} periodic methods (other than the scheduler calls). + * Instead, the structure of the robot (including subsystems, commands, and trigger mappings) should be declared here. + */ +public class RobotContainer +{ + + // Replace with CommandPS4Controller or CommandJoystick if needed + final CommandXboxController driverXbox = new CommandXboxController(0); + // The robot's subsystems and commands are defined here... + private final SwerveSubsystem drivebase = new SwerveSubsystem(new File(Filesystem.getDeployDirectory(), + "swerve/neo")); + + // Establish a Sendable Chooser that will be able to be sent to the SmartDashboard, allowing selection of desired auto + private final SendableChooser autoChooser = new SendableChooser<>(); + + /** + * Converts driver input into a field-relative ChassisSpeeds that is controlled by angular velocity. + */ + SwerveInputStream driveAngularVelocity = SwerveInputStream.of(drivebase.getSwerveDrive(), + () -> driverXbox.getLeftY() * -1, + () -> driverXbox.getLeftX() * -1) + .withControllerRotationAxis(driverXbox::getRightX) + .deadband(OperatorConstants.DEADBAND) + .scaleTranslation(0.8) + .allianceRelativeControl(true); + + /** + * Clone's the angular velocity input stream and converts it to a fieldRelative input stream. + */ + SwerveInputStream driveDirectAngle = driveAngularVelocity.copy().withControllerHeadingAxis(driverXbox::getRightX, + driverXbox::getRightY) + .headingWhile(true); + + /** + * Clone's the angular velocity input stream and converts it to a robotRelative input stream. + */ + SwerveInputStream driveRobotOriented = driveAngularVelocity.copy().robotRelative(true) + .allianceRelativeControl(false); + + SwerveInputStream driveAngularVelocityKeyboard = SwerveInputStream.of(drivebase.getSwerveDrive(), + () -> -driverXbox.getLeftY(), + () -> -driverXbox.getLeftX()) + .withControllerRotationAxis(() -> driverXbox.getRawAxis( + 2)) + .deadband(OperatorConstants.DEADBAND) + .scaleTranslation(0.8) + .allianceRelativeControl(true); + // Derive the heading axis with math! + SwerveInputStream driveDirectAngleKeyboard = driveAngularVelocityKeyboard.copy() + .withControllerHeadingAxis(() -> + Math.sin( + driverXbox.getRawAxis( + 2) * + Math.PI) * + (Math.PI * + 2), + () -> + Math.cos( + driverXbox.getRawAxis( + 2) * + Math.PI) * + (Math.PI * + 2)) + .headingWhile(true) + .translationHeadingOffset(true) + .translationHeadingOffset(Rotation2d.fromDegrees( + 0)); + + /** + * The container for the robot. Contains subsystems, OI devices, and commands. + */ + public RobotContainer() + { + // Configure the trigger bindings + configureBindings(); + DriverStation.silenceJoystickConnectionWarning(true); + + //Set the default auto (do nothing) + autoChooser.setDefaultOption("Do Nothing", Commands.runOnce(drivebase::zeroGyroWithAlliance) + .andThen(Commands.none())); + + //Add a simple auto option to have the robot drive forward for 1 second then stop + autoChooser.addOption("Drive Forward", Commands.runOnce(drivebase::zeroGyroWithAlliance).withTimeout(.2) + .andThen(drivebase.driveForward().withTimeout(1))); + //Put the autoChooser on the SmartDashboard + SmartDashboard.putData("Auto Chooser", autoChooser); + + if (autoChooser.getSelected() == null ) { + RobotModeTriggers.autonomous().onTrue(Commands.runOnce(drivebase::zeroGyroWithAlliance)); + } + } + + /** + * Use this method to define your trigger->command mappings. Triggers can be created via the + * {@link Trigger#Trigger(java.util.function.BooleanSupplier)} constructor with an arbitrary predicate, or via the + * named factories in {@link edu.wpi.first.wpilibj2.command.button.CommandGenericHID}'s subclasses for + * {@link CommandXboxController Xbox}/{@link edu.wpi.first.wpilibj2.command.button.CommandPS4Controller PS4} + * controllers or {@link edu.wpi.first.wpilibj2.command.button.CommandJoystick Flight joysticks}. + */ + private void configureBindings() + { + Command driveFieldOrientedDirectAngle = drivebase.driveFieldOriented(driveDirectAngle); + Command driveFieldOrientedAnglularVelocity = drivebase.driveFieldOriented(driveAngularVelocity); + Command driveRobotOrientedAngularVelocity = drivebase.driveFieldOriented(driveRobotOriented); + Command driveFieldOrientedDirectAngleKeyboard = drivebase.driveFieldOriented(driveDirectAngleKeyboard); + Command driveFieldOrientedAnglularVelocityKeyboard = drivebase.driveFieldOriented(driveAngularVelocityKeyboard); + + + if (RobotBase.isSimulation()) + { + drivebase.setDefaultCommand(driveFieldOrientedDirectAngleKeyboard); + } else + { + drivebase.setDefaultCommand(driveFieldOrientedAnglularVelocity); + } + + if (Robot.isSimulation()) + { + Pose2d target = new Pose2d(new Translation2d(1, 4), + Rotation2d.fromDegrees(90)); + //drivebase.getSwerveDrive().field.getObject("targetPose").setPose(target); + driveDirectAngleKeyboard.driveToPose(() -> target, + new ProfiledPIDController(5, + 0, + 0, + new Constraints(5, 2)), + new ProfiledPIDController(5, + 0, + 0, + new Constraints(Units.degreesToRadians(360), + Units.degreesToRadians(180)) + )); + driverXbox.start().onTrue(Commands.runOnce(() -> drivebase.resetOdometry(new Pose2d(3, 3, new Rotation2d())))); + driverXbox.button(1).whileTrue(drivebase.sysIdDriveMotorCommand()); + driverXbox.button(2).whileTrue(Commands.runEnd(() -> driveDirectAngleKeyboard.driveToPoseEnabled(true), + () -> driveDirectAngleKeyboard.driveToPoseEnabled(false))); + + + + } + if (DriverStation.isTest()) + { + drivebase.setDefaultCommand(driveFieldOrientedAnglularVelocity); // Overrides drive command above! + + driverXbox.x().whileTrue(Commands.runOnce(drivebase::lock, drivebase).repeatedly()); + driverXbox.start().onTrue((Commands.runOnce(drivebase::zeroGyro))); + driverXbox.back().whileTrue(drivebase.centerModulesCommand()); + driverXbox.leftBumper().onTrue(Commands.none()); + driverXbox.rightBumper().onTrue(Commands.none()); + } else + { + driverXbox.a().onTrue((Commands.runOnce(drivebase::zeroGyro))); + driverXbox.start().whileTrue(Commands.none()); + driverXbox.back().whileTrue(Commands.none()); + driverXbox.leftBumper().whileTrue(Commands.runOnce(drivebase::lock, drivebase).repeatedly()); + driverXbox.rightBumper().onTrue(Commands.none()); + } + + } + + /** + * Use this to pass the autonomous command to the main {@link Robot} class. + * + * @return the command to run in autonomous + */ + public Command getAutonomousCommand() + { + // Pass in the selected auto from the SmartDashboard as our desired autnomous commmand + return autoChooser.getSelected(); + } + + public void setMotorBrake(boolean brake) + { + drivebase.setMotorBrake(brake); + } +} diff --git a/examples/drivebase_only_2026/src/main/java/frc/robot/commands/swervedrive/auto/AutoBalanceCommand.java b/examples/drivebase_only_2026/src/main/java/frc/robot/commands/swervedrive/auto/AutoBalanceCommand.java new file mode 100644 index 0000000..6919e45 --- /dev/null +++ b/examples/drivebase_only_2026/src/main/java/frc/robot/commands/swervedrive/auto/AutoBalanceCommand.java @@ -0,0 +1,86 @@ +package frc.robot.commands.swervedrive.auto; + +import edu.wpi.first.math.MathUtil; +import edu.wpi.first.math.controller.PIDController; +import edu.wpi.first.math.geometry.Translation2d; +import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; +import edu.wpi.first.wpilibj2.command.Command; +import frc.robot.subsystems.swervedrive.SwerveSubsystem; + + +/** + * Auto Balance command using a simple PID controller. Created by Team 3512 + * ... + */ +public class AutoBalanceCommand extends Command +{ + + private final SwerveSubsystem swerveSubsystem; + private final PIDController controller; + + public AutoBalanceCommand(SwerveSubsystem swerveSubsystem) + { + this.swerveSubsystem = swerveSubsystem; + controller = new PIDController(1.0, 0.0, 0.0); + controller.setTolerance(1); + controller.setSetpoint(0.0); + // each subsystem used by the command must be passed into the + // addRequirements() method (which takes a vararg of Subsystem) + addRequirements(this.swerveSubsystem); + } + + /** + * The initial subroutine of a command. Called once when the command is initially scheduled. + */ + @Override + public void initialize() + { + + } + + /** + * The main body of a command. Called repeatedly while the command is scheduled. (That is, it is called repeatedly + * until {@link #isFinished()}) returns true.) + */ + @Override + public void execute() + { + SmartDashboard.putBoolean("At Tolerance", controller.atSetpoint()); + + double translationVal = MathUtil.clamp(controller.calculate(swerveSubsystem.getPitch().getDegrees(), 0.0), -0.5, + 0.5); + swerveSubsystem.drive(new Translation2d(translationVal, 0.0), 0.0, true); + } + + /** + *

+ * Returns whether this command has finished. Once a command finishes -- indicated by this method returning true -- + * the scheduler will call its {@link #end(boolean)} method. + *

+ * Returning false will result in the command never ending automatically. It may still be cancelled manually or + * interrupted by another command. Hard coding this command to always return true will result in the command executing + * once and finishing immediately. It is recommended to use * + * {@link edu.wpi.first.wpilibj2.command.InstantCommand InstantCommand} for such an operation. + *

+ * + * @return whether this command has finished. + */ + @Override + public boolean isFinished() + { + return controller.atSetpoint(); + } + + /** + * The action to take when the command ends. Called when either the command finishes normally -- that is it is called + * when {@link #isFinished()} returns true -- or when it is interrupted/canceled. This is where you may want to wrap + * up loose ends, like shutting off a motor that was being used in the command. + * + * @param interrupted whether the command was interrupted/canceled + */ + @Override + public void end(boolean interrupted) + { + swerveSubsystem.lock(); + } +} diff --git a/examples/drivebase_only_2026/src/main/java/frc/robot/commands/swervedrive/drivebase/AbsoluteDrive.java b/examples/drivebase_only_2026/src/main/java/frc/robot/commands/swervedrive/drivebase/AbsoluteDrive.java new file mode 100644 index 0000000..9ab90b7 --- /dev/null +++ b/examples/drivebase_only_2026/src/main/java/frc/robot/commands/swervedrive/drivebase/AbsoluteDrive.java @@ -0,0 +1,120 @@ +// 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.commands.swervedrive.drivebase; + +import edu.wpi.first.math.geometry.Rotation2d; +import edu.wpi.first.math.geometry.Translation2d; +import edu.wpi.first.math.kinematics.ChassisSpeeds; +import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; +import edu.wpi.first.wpilibj2.command.Command; +import frc.robot.Constants; +import frc.robot.subsystems.swervedrive.SwerveSubsystem; +import java.util.List; +import java.util.function.DoubleSupplier; +import swervelib.SwerveController; +import swervelib.math.SwerveMath; + +/** + * An example command that uses an example subsystem. + */ +public class AbsoluteDrive extends Command +{ + + private final SwerveSubsystem swerve; + private final DoubleSupplier vX, vY; + private final DoubleSupplier headingHorizontal, headingVertical; + private boolean initRotation = false; + + /** + * Used to drive a swerve robot in full field-centric mode. vX and vY supply translation inputs, where x is + * torwards/away from alliance wall and y is left/right. headingHorzontal and headingVertical are the Cartesian + * coordinates from which the robot's angle will be derived— they will be converted to a polar angle, which the robot + * will rotate to. + * + * @param swerve The swerve drivebase subsystem. + * @param vX DoubleSupplier that supplies the x-translation joystick input. Should be in the range -1 + * to 1 with deadband already accounted for. Positive X is away from the alliance wall. + * @param vY DoubleSupplier that supplies the y-translation joystick input. Should be in the range -1 + * to 1 with deadband already accounted for. Positive Y is towards the left wall when + * looking through the driver station glass. + * @param headingHorizontal DoubleSupplier that supplies the horizontal component of the robot's heading angle. In the + * robot coordinate system, this is along the same axis as vY. Should range from -1 to 1 with + * no deadband. Positive is towards the left wall when looking through the driver station + * glass. + * @param headingVertical DoubleSupplier that supplies the vertical component of the robot's heading angle. In the + * robot coordinate system, this is along the same axis as vX. Should range from -1 to 1 + * with no deadband. Positive is away from the alliance wall. + */ + public AbsoluteDrive(SwerveSubsystem swerve, DoubleSupplier vX, DoubleSupplier vY, DoubleSupplier headingHorizontal, + DoubleSupplier headingVertical) + { + this.swerve = swerve; + this.vX = vX; + this.vY = vY; + this.headingHorizontal = headingHorizontal; + this.headingVertical = headingVertical; + + addRequirements(swerve); + } + + @Override + public void initialize() + { + initRotation = true; + } + + // Called every time the scheduler runs while the command is scheduled. + @Override + public void execute() + { + + // Get the desired chassis speeds based on a 2 joystick module. + ChassisSpeeds desiredSpeeds = swerve.getTargetSpeeds(vX.getAsDouble(), vY.getAsDouble(), + headingHorizontal.getAsDouble(), + headingVertical.getAsDouble()); + + // Prevent Movement After Auto + if (initRotation) + { + if (headingHorizontal.getAsDouble() == 0 && headingVertical.getAsDouble() == 0) + { + // Get the curretHeading + Rotation2d firstLoopHeading = swerve.getHeading(); + + // Set the Current Heading to the desired Heading + desiredSpeeds = swerve.getTargetSpeeds(0, 0, firstLoopHeading.getSin(), firstLoopHeading.getCos()); + } + //Dont Init Rotation Again + initRotation = false; + } + + // Limit velocity to prevent tippy + Translation2d translation = SwerveController.getTranslation2d(desiredSpeeds); + translation = SwerveMath.limitVelocity(translation, swerve.getFieldVelocity(), swerve.getPose(), + Constants.LOOP_TIME, Constants.ROBOT_MASS, List.of(Constants.CHASSIS), + swerve.getSwerveDriveConfiguration()); + SmartDashboard.putNumber("LimitedTranslation", translation.getX()); + SmartDashboard.putString("Translation", translation.toString()); + + // Make the robot move + swerve.drive(translation, desiredSpeeds.omegaRadiansPerSecond, true); + + } + + // Called once the command ends or is interrupted. + @Override + public void end(boolean interrupted) + { + } + + // Returns true when the command should end. + @Override + public boolean isFinished() + { + return false; + } + + +} diff --git a/examples/drivebase_only_2026/src/main/java/frc/robot/commands/swervedrive/drivebase/AbsoluteDriveAdv.java b/examples/drivebase_only_2026/src/main/java/frc/robot/commands/swervedrive/drivebase/AbsoluteDriveAdv.java new file mode 100644 index 0000000..a92904f --- /dev/null +++ b/examples/drivebase_only_2026/src/main/java/frc/robot/commands/swervedrive/drivebase/AbsoluteDriveAdv.java @@ -0,0 +1,154 @@ +// 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.commands.swervedrive.drivebase; + +import edu.wpi.first.math.geometry.Rotation2d; +import edu.wpi.first.math.geometry.Translation2d; +import edu.wpi.first.math.kinematics.ChassisSpeeds; +import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; +import edu.wpi.first.wpilibj2.command.Command; +import frc.robot.Constants; +import frc.robot.subsystems.swervedrive.SwerveSubsystem; +import java.util.List; +import java.util.function.BooleanSupplier; +import java.util.function.DoubleSupplier; +import swervelib.SwerveController; +import swervelib.math.SwerveMath; + +/** + * A more advanced Swerve Control System that has 4 buttons for which direction to face + */ +public class AbsoluteDriveAdv extends Command +{ + + private final SwerveSubsystem swerve; + private final DoubleSupplier vX, vY; + private final DoubleSupplier headingAdjust; + private final BooleanSupplier lookAway, lookTowards, lookLeft, lookRight; + private boolean resetHeading = false; + + /** + * Used to drive a swerve robot in full field-centric mode. vX and vY supply translation inputs, where x is + * torwards/away from alliance wall and y is left/right. Heading Adjust changes the current heading after being + * multipied by a constant. The look booleans are shortcuts to get the robot to face a certian direction. Based off of + * ideas in https://www.chiefdelphi.com/t/experiments-with-a-swerve-steering-knob/446172 + * + * @param swerve The swerve drivebase subsystem. + * @param vX DoubleSupplier that supplies the x-translation joystick input. Should be in the range -1 to 1 + * with deadband already accounted for. Positive X is away from the alliance wall. + * @param vY DoubleSupplier that supplies the y-translation joystick input. Should be in the range -1 to 1 + * with deadband already accounted for. Positive Y is towards the left wall when looking through + * the driver station glass. + * @param headingAdjust DoubleSupplier that supplies the component of the robot's heading angle that should be + * adjusted. Should range from -1 to 1 with deadband already accounted for. + * @param lookAway Face the robot towards the opposing alliance's wall in the same direction the driver is + * facing + * @param lookTowards Face the robot towards the driver + * @param lookLeft Face the robot left + * @param lookRight Face the robot right + */ + public AbsoluteDriveAdv(SwerveSubsystem swerve, DoubleSupplier vX, DoubleSupplier vY, DoubleSupplier headingAdjust, + BooleanSupplier lookAway, BooleanSupplier lookTowards, BooleanSupplier lookLeft, + BooleanSupplier lookRight) + { + this.swerve = swerve; + this.vX = vX; + this.vY = vY; + this.headingAdjust = headingAdjust; + this.lookAway = lookAway; + this.lookTowards = lookTowards; + this.lookLeft = lookLeft; + this.lookRight = lookRight; + + addRequirements(swerve); + } + + @Override + public void initialize() + { + resetHeading = true; + } + + // Called every time the scheduler runs while the command is scheduled. + @Override + public void execute() + { + double headingX = 0; + double headingY = 0; + + // These are written to allow combinations for 45 angles + // Face Away from Drivers + if (lookAway.getAsBoolean()) + { + headingY = -1; + } + // Face Right + if (lookRight.getAsBoolean()) + { + headingX = 1; + } + // Face Left + if (lookLeft.getAsBoolean()) + { + headingX = -1; + } + // Face Towards the Drivers + if (lookTowards.getAsBoolean()) + { + headingY = 1; + } + + // Prevent Movement After Auto + if (resetHeading) + { + if (headingX == 0 && headingY == 0 && Math.abs(headingAdjust.getAsDouble()) == 0) + { + // Get the curret Heading + Rotation2d currentHeading = swerve.getHeading(); + + // Set the Current Heading to the desired Heading + headingX = currentHeading.getSin(); + headingY = currentHeading.getCos(); + } + //Dont reset Heading Again + resetHeading = false; + } + + ChassisSpeeds desiredSpeeds = swerve.getTargetSpeeds(vX.getAsDouble(), vY.getAsDouble(), headingX, headingY); + + // Limit velocity to prevent tippy + Translation2d translation = SwerveController.getTranslation2d(desiredSpeeds); + translation = SwerveMath.limitVelocity(translation, swerve.getFieldVelocity(), swerve.getPose(), + Constants.LOOP_TIME, Constants.ROBOT_MASS, List.of(Constants.CHASSIS), + swerve.getSwerveDriveConfiguration()); + SmartDashboard.putNumber("LimitedTranslation", translation.getX()); + SmartDashboard.putString("Translation", translation.toString()); + + // Make the robot move + if (headingX == 0 && headingY == 0 && Math.abs(headingAdjust.getAsDouble()) > 0) + { + resetHeading = true; + swerve.drive(translation, (Constants.OperatorConstants.TURN_CONSTANT * -headingAdjust.getAsDouble()), true); + } else + { + swerve.drive(translation, desiredSpeeds.omegaRadiansPerSecond, true); + } + } + + // Called once the command ends or is interrupted. + @Override + public void end(boolean interrupted) + { + } + + // Returns true when the command should end. + @Override + public boolean isFinished() + { + return false; + } + + +} diff --git a/examples/drivebase_only_2026/src/main/java/frc/robot/commands/swervedrive/drivebase/AbsoluteFieldDrive.java b/examples/drivebase_only_2026/src/main/java/frc/robot/commands/swervedrive/drivebase/AbsoluteFieldDrive.java new file mode 100644 index 0000000..b91489f --- /dev/null +++ b/examples/drivebase_only_2026/src/main/java/frc/robot/commands/swervedrive/drivebase/AbsoluteFieldDrive.java @@ -0,0 +1,95 @@ +// 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.commands.swervedrive.drivebase; + +import edu.wpi.first.math.geometry.Rotation2d; +import edu.wpi.first.math.geometry.Translation2d; +import edu.wpi.first.math.kinematics.ChassisSpeeds; +import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; +import edu.wpi.first.wpilibj2.command.Command; +import frc.robot.Constants; +import frc.robot.subsystems.swervedrive.SwerveSubsystem; +import java.util.List; +import java.util.function.DoubleSupplier; +import swervelib.SwerveController; +import swervelib.math.SwerveMath; + +/** + * An example command that uses an example subsystem. + */ +public class AbsoluteFieldDrive extends Command +{ + + private final SwerveSubsystem swerve; + private final DoubleSupplier vX, vY, heading; + + /** + * Used to drive a swerve robot in full field-centric mode. vX and vY supply translation inputs, where x is + * torwards/away from alliance wall and y is left/right. headingHorzontal and headingVertical are the Cartesian + * coordinates from which the robot's angle will be derived— they will be converted to a polar angle, which the robot + * will rotate to. + * + * @param swerve The swerve drivebase subsystem. + * @param vX DoubleSupplier that supplies the x-translation joystick input. Should be in the range -1 to 1 with + * deadband already accounted for. Positive X is away from the alliance wall. + * @param vY DoubleSupplier that supplies the y-translation joystick input. Should be in the range -1 to 1 with + * deadband already accounted for. Positive Y is towards the left wall when looking through the driver + * station glass. + * @param heading DoubleSupplier that supplies the robot's heading angle. + */ + public AbsoluteFieldDrive(SwerveSubsystem swerve, DoubleSupplier vX, DoubleSupplier vY, + DoubleSupplier heading) + { + this.swerve = swerve; + this.vX = vX; + this.vY = vY; + this.heading = heading; + + addRequirements(swerve); + } + + @Override + public void initialize() + { + } + + // Called every time the scheduler runs while the command is scheduled. + @Override + public void execute() + { + + // Get the desired chassis speeds based on a 2 joystick module. + + ChassisSpeeds desiredSpeeds = swerve.getTargetSpeeds(vX.getAsDouble(), vY.getAsDouble(), + new Rotation2d(heading.getAsDouble() * Math.PI)); + + // Limit velocity to prevent tippy + Translation2d translation = SwerveController.getTranslation2d(desiredSpeeds); + translation = SwerveMath.limitVelocity(translation, swerve.getFieldVelocity(), swerve.getPose(), + Constants.LOOP_TIME, Constants.ROBOT_MASS, List.of(Constants.CHASSIS), + swerve.getSwerveDriveConfiguration()); + SmartDashboard.putNumber("LimitedTranslation", translation.getX()); + SmartDashboard.putString("Translation", translation.toString()); + + // Make the robot move + swerve.drive(translation, desiredSpeeds.omegaRadiansPerSecond, true); + + } + + // Called once the command ends or is interrupted. + @Override + public void end(boolean interrupted) + { + } + + // Returns true when the command should end. + @Override + public boolean isFinished() + { + return false; + } + + +} diff --git a/examples/drivebase_only_2026/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java b/examples/drivebase_only_2026/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java new file mode 100644 index 0000000..1d70326 --- /dev/null +++ b/examples/drivebase_only_2026/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java @@ -0,0 +1,486 @@ +// 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.swervedrive; + +import static edu.wpi.first.units.Units.Meter; + +import edu.wpi.first.math.controller.SimpleMotorFeedforward; +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.kinematics.ChassisSpeeds; +import edu.wpi.first.math.kinematics.SwerveDriveKinematics; +import edu.wpi.first.math.trajectory.Trajectory; +import edu.wpi.first.wpilibj.DriverStation; +import edu.wpi.first.wpilibj2.command.Command; +import edu.wpi.first.wpilibj2.command.SubsystemBase; +import edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine.Config; +import frc.robot.Constants; +import java.io.File; +import java.util.Arrays; +import java.util.function.DoubleSupplier; +import java.util.function.Supplier; +import swervelib.SwerveController; +import swervelib.SwerveDrive; +import swervelib.SwerveDriveTest; +import swervelib.math.SwerveMath; +import swervelib.parser.SwerveControllerConfiguration; +import swervelib.parser.SwerveDriveConfiguration; +import swervelib.parser.SwerveParser; +import swervelib.telemetry.SwerveDriveTelemetry; +import swervelib.telemetry.SwerveDriveTelemetry.TelemetryVerbosity; + +public class SwerveSubsystem extends SubsystemBase +{ + /** + * Swerve drive object. + */ + private final SwerveDrive swerveDrive; + + /** + * Initialize {@link SwerveDrive} with the directory provided. + * + * @param directory Directory of swerve drive config files. + */ + public SwerveSubsystem(File directory) + { + boolean blueAlliance = false; + Pose2d startingPose = blueAlliance ? new Pose2d(new Translation2d(Meter.of(1), + Meter.of(4)), + Rotation2d.fromDegrees(0)) + : new Pose2d(new Translation2d(Meter.of(16), + Meter.of(4)), + Rotation2d.fromDegrees(180)); + // Configure the Telemetry before creating the SwerveDrive to avoid unnecessary objects being created. + SwerveDriveTelemetry.verbosity = TelemetryVerbosity.HIGH; + try + { + swerveDrive = new SwerveParser(directory).createSwerveDrive(Constants.MAX_SPEED, startingPose); + // Alternative method if you don't want to supply the conversion factor via JSON files. + // swerveDrive = new SwerveParser(directory).createSwerveDrive(maximumSpeed, angleConversionFactor, driveConversionFactor); + } catch (Exception e) + { + throw new RuntimeException(e); + } + swerveDrive.setHeadingCorrection(false); // Heading correction should only be used while controlling the robot via angle. + swerveDrive.setCosineCompensator(false);//!SwerveDriveTelemetry.isSimulation); // Disables cosine compensation for simulations since it causes discrepancies not seen in real life. + swerveDrive.setAngularVelocityCompensation(true, + true, + 0.1); //Correct for skew that gets worse as angular velocity increases. Start with a coefficient of 0.1. + swerveDrive.setModuleEncoderAutoSynchronize(false, + 1); // Enable if you want to resynchronize your absolute encoders and motor encoders periodically when they are not moving. + // swerveDrive.pushOffsetsToEncoders(); // Set the absolute encoder to be used over the internal encoder and push the offsets onto it. Throws warning if not possible + } + + /** + * Construct the swerve drive. + * + * @param driveCfg SwerveDriveConfiguration for the swerve. + * @param controllerCfg Swerve Controller. + */ + public SwerveSubsystem(SwerveDriveConfiguration driveCfg, SwerveControllerConfiguration controllerCfg) + { + swerveDrive = new SwerveDrive(driveCfg, + controllerCfg, + Constants.MAX_SPEED, + new Pose2d(new Translation2d(Meter.of(2), Meter.of(0)), + Rotation2d.fromDegrees(0))); + } + + @Override + public void periodic() + { + } + + @Override + public void simulationPeriodic() + { + } + + /** + * Command to characterize the robot drive motors using SysId + * + * @return SysId Drive Command + */ + public Command sysIdDriveMotorCommand() + { + return SwerveDriveTest.generateSysIdCommand( + SwerveDriveTest.setDriveSysIdRoutine( + new Config(), + this, swerveDrive, 12, true), + 3.0, 5.0, 3.0); + } + + /** + * Command to characterize the robot angle motors using SysId + * + * @return SysId Angle Command + */ + public Command sysIdAngleMotorCommand() + { + return SwerveDriveTest.generateSysIdCommand( + SwerveDriveTest.setAngleSysIdRoutine( + new Config(), + this, swerveDrive), + 3.0, 5.0, 3.0); + } + + /** + * Returns a Command that centers the modules of the SwerveDrive subsystem. + * + * @return a Command that centers the modules of the SwerveDrive subsystem + */ + public Command centerModulesCommand() + { + return run(() -> Arrays.asList(swerveDrive.getModules()) + .forEach(it -> it.setAngle(0.0))); + } + + /** + * Returns a Command that tells the robot to drive forward until the command ends. + * + * @return a Command that tells the robot to drive forward until the command ends + */ + public Command driveForward() + { + return run(() -> { + swerveDrive.drive(new Translation2d(1, 0), 0, false, false); + }).finallyDo(() -> swerveDrive.drive(new Translation2d(0, 0), 0, false, false)); + } + + + /** + * Replaces the swerve module feedforward with a new SimpleMotorFeedforward object. + * + * @param kS the static gain of the feedforward + * @param kV the velocity gain of the feedforward + * @param kA the acceleration gain of the feedforward + */ + public void replaceSwerveModuleFeedforward(double kS, double kV, double kA) + { + swerveDrive.replaceSwerveModuleFeedforward(new SimpleMotorFeedforward(kS, kV, kA)); + } + + /** + * Command to drive the robot using translative values and heading as angular velocity. + * + * @param translationX Translation in the X direction. Cubed for smoother controls. + * @param translationY Translation in the Y direction. Cubed for smoother controls. + * @param angularRotationX Angular velocity of the robot to set. Cubed for smoother controls. + * @return Drive command. + */ + public Command driveCommand(DoubleSupplier translationX, DoubleSupplier translationY, DoubleSupplier angularRotationX) + { + return run(() -> { + // Make the robot move + swerveDrive.drive(SwerveMath.scaleTranslation(new Translation2d( + translationX.getAsDouble() * swerveDrive.getMaximumChassisVelocity(), + translationY.getAsDouble() * swerveDrive.getMaximumChassisVelocity()), 0.8), + Math.pow(angularRotationX.getAsDouble(), 3) * swerveDrive.getMaximumChassisAngularVelocity(), + true, + false); + }); + } + + /** + * Command to drive the robot using translative values and heading as a setpoint. + * + * @param translationX Translation in the X direction. Cubed for smoother controls. + * @param translationY Translation in the Y direction. Cubed for smoother controls. + * @param headingX Heading X to calculate angle of the joystick. + * @param headingY Heading Y to calculate angle of the joystick. + * @return Drive command. + */ + public Command driveCommand(DoubleSupplier translationX, DoubleSupplier translationY, DoubleSupplier headingX, + DoubleSupplier headingY) + { + // swerveDrive.setHeadingCorrection(true); // Normally you would want heading correction for this kind of control. + return run(() -> { + + Translation2d scaledInputs = SwerveMath.scaleTranslation(new Translation2d(translationX.getAsDouble(), + translationY.getAsDouble()), 0.8); + + // Make the robot move + driveFieldOriented(swerveDrive.swerveController.getTargetSpeeds(scaledInputs.getX(), scaledInputs.getY(), + headingX.getAsDouble(), + headingY.getAsDouble(), + swerveDrive.getOdometryHeading().getRadians(), + swerveDrive.getMaximumChassisVelocity())); + }); + } + + /** + * The primary method for controlling the drivebase. Takes a {@link Translation2d} and a rotation rate, and + * calculates and commands module states accordingly. Can use either open-loop or closed-loop velocity control for + * the wheel velocities. Also has field- and robot-relative modes, which affect how the translation vector is used. + * + * @param translation {@link Translation2d} that is the commanded linear velocity of the robot, in meters per + * second. In robot-relative mode, positive x is torwards the bow (front) and positive y is + * torwards port (left). In field-relative mode, positive x is away from the alliance wall + * (field North) and positive y is torwards the left wall when looking through the driver station + * glass (field West). + * @param rotation Robot angular rate, in radians per second. CCW positive. Unaffected by field/robot + * relativity. + * @param fieldRelative Drive mode. True for field-relative, false for robot-relative. + */ + public void drive(Translation2d translation, double rotation, boolean fieldRelative) + { + swerveDrive.drive(translation, + rotation, + fieldRelative, + false); // Open loop is disabled since it shouldn't be used most of the time. + } + + /** + * Drive the robot given a chassis field oriented velocity. + * + * @param velocity Velocity according to the field. + */ + public void driveFieldOriented(ChassisSpeeds velocity) + { + swerveDrive.driveFieldOriented(velocity); + } + + /** + * Drive the robot given a chassis field oriented velocity. + * + * @param velocity Velocity according to the field. + */ + public Command driveFieldOriented(Supplier velocity) + { + return run(() -> { + swerveDrive.driveFieldOriented(velocity.get()); + }); + } + + /** + * Drive according to the chassis robot oriented velocity. + * + * @param velocity Robot oriented {@link ChassisSpeeds} + */ + public void drive(ChassisSpeeds velocity) + { + swerveDrive.drive(velocity); + } + + /** + * Get the swerve drive kinematics object. + * + * @return {@link SwerveDriveKinematics} of the swerve drive. + */ + public SwerveDriveKinematics getKinematics() + { + return swerveDrive.kinematics; + } + + /** + * Resets odometry to the given pose. Gyro angle and module positions do not need to be reset when calling this + * method. However, if either gyro angle or module position is reset, this must be called in order for odometry to + * keep working. + * + * @param initialHolonomicPose The pose to set the odometry to + */ + public void resetOdometry(Pose2d initialHolonomicPose) + { + swerveDrive.resetOdometry(initialHolonomicPose); + } + + /** + * Gets the current pose (position and rotation) of the robot, as reported by odometry. + * + * @return The robot's pose + */ + public Pose2d getPose() + { + return swerveDrive.getPose(); + } + + /** + * Set chassis speeds with closed-loop velocity control. + * + * @param chassisSpeeds Chassis Speeds to set. + */ + public void setChassisSpeeds(ChassisSpeeds chassisSpeeds) + { + swerveDrive.setChassisSpeeds(chassisSpeeds); + } + + /** + * Post the trajectory to the field. + * + * @param trajectory The trajectory to post. + */ + public void postTrajectory(Trajectory trajectory) + { + swerveDrive.postTrajectory(trajectory); + } + + /** + * Resets the gyro angle to zero and resets odometry to the same position, but facing toward 0. + */ + public void zeroGyro() + { + swerveDrive.zeroGyro(); + } + + /** + * Checks if the alliance is red, defaults to false if alliance isn't available. + * + * @return true if the red alliance, false if blue. Defaults to false if none is available. + */ + private boolean isRedAlliance() + { + var alliance = DriverStation.getAlliance(); + return alliance.isPresent() ? alliance.get() == DriverStation.Alliance.Red : false; + } + + /** + * This will zero (calibrate) the robot to assume the current position is facing forward + *

+ * If red alliance rotate the robot 180 after the drviebase zero command + */ + public void zeroGyroWithAlliance() + { + if (isRedAlliance()) + { + zeroGyro(); + //Set the pose 180 degrees + resetOdometry(new Pose2d(getPose().getTranslation(), Rotation2d.fromDegrees(180))); + } else + { + zeroGyro(); + } + } + + /** + * Sets the drive motors to brake/coast mode. + * + * @param brake True to set motors to brake mode, false for coast. + */ + public void setMotorBrake(boolean brake) + { + swerveDrive.setMotorIdleMode(brake); + } + + /** + * Gets the current yaw angle of the robot, as reported by the swerve pose estimator in the underlying drivebase. + * Note, this is not the raw gyro reading, this may be corrected from calls to resetOdometry(). + * + * @return The yaw angle + */ + public Rotation2d getHeading() + { + return getPose().getRotation(); + } + + /** + * Get the chassis speeds based on controller input of 2 joysticks. One for speeds in which direction. The other for + * the angle of the robot. + * + * @param xInput X joystick input for the robot to move in the X direction. + * @param yInput Y joystick input for the robot to move in the Y direction. + * @param headingX X joystick which controls the angle of the robot. + * @param headingY Y joystick which controls the angle of the robot. + * @return {@link ChassisSpeeds} which can be sent to the Swerve Drive. + */ + public ChassisSpeeds getTargetSpeeds(double xInput, double yInput, double headingX, double headingY) + { + Translation2d scaledInputs = SwerveMath.cubeTranslation(new Translation2d(xInput, yInput)); + return swerveDrive.swerveController.getTargetSpeeds(scaledInputs.getX(), + scaledInputs.getY(), + headingX, + headingY, + getHeading().getRadians(), + Constants.MAX_SPEED); + } + + /** + * Get the chassis speeds based on controller input of 1 joystick and one angle. Control the robot at an offset of + * 90deg. + * + * @param xInput X joystick input for the robot to move in the X direction. + * @param yInput Y joystick input for the robot to move in the Y direction. + * @param angle The angle in as a {@link Rotation2d}. + * @return {@link ChassisSpeeds} which can be sent to the Swerve Drive. + */ + public ChassisSpeeds getTargetSpeeds(double xInput, double yInput, Rotation2d angle) + { + Translation2d scaledInputs = SwerveMath.cubeTranslation(new Translation2d(xInput, yInput)); + + return swerveDrive.swerveController.getTargetSpeeds(scaledInputs.getX(), + scaledInputs.getY(), + angle.getRadians(), + getHeading().getRadians(), + Constants.MAX_SPEED); + } + + /** + * Gets the current field-relative velocity (x, y and omega) of the robot + * + * @return A ChassisSpeeds object of the current field-relative velocity + */ + public ChassisSpeeds getFieldVelocity() + { + return swerveDrive.getFieldVelocity(); + } + + /** + * Gets the current velocity (x, y and omega) of the robot + * + * @return A {@link ChassisSpeeds} object of the current velocity + */ + public ChassisSpeeds getRobotVelocity() + { + return swerveDrive.getRobotVelocity(); + } + + /** + * Get the {@link SwerveController} in the swerve drive. + * + * @return {@link SwerveController} from the {@link SwerveDrive}. + */ + public SwerveController getSwerveController() + { + return swerveDrive.swerveController; + } + + /** + * Get the {@link SwerveDriveConfiguration} object. + * + * @return The {@link SwerveDriveConfiguration} fpr the current drive. + */ + public SwerveDriveConfiguration getSwerveDriveConfiguration() + { + return swerveDrive.swerveDriveConfiguration; + } + + /** + * Lock the swerve drive to prevent it from moving. + */ + public void lock() + { + swerveDrive.lockPose(); + } + + /** + * Gets the current pitch angle of the robot, as reported by the imu. + * + * @return The heading as a {@link Rotation2d} angle + */ + public Rotation2d getPitch() + { + return swerveDrive.getPitch(); + } + + /** + * Gets the swerve drive object. + * + * @return {@link SwerveDrive} + */ + public SwerveDrive getSwerveDrive() + { + return swerveDrive; + } +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/vendordeps/Phoenix5-replay-5.36.0-beta-1.json b/examples/drivebase_only_2026/vendordeps/Phoenix5-replay-5.36.0-beta-1.json new file mode 100644 index 0000000..4a78551 --- /dev/null +++ b/examples/drivebase_only_2026/vendordeps/Phoenix5-replay-5.36.0-beta-1.json @@ -0,0 +1,221 @@ +{ + "fileName": "Phoenix5-replay-5.36.0-beta-1.json", + "name": "CTRE-Phoenix (v5)", + "version": "5.36.0-beta-1", + "frcYear": "2026beta", + "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", + "mavenUrls": [ + "https://maven.ctr-electronics.com/release/" + ], + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-beta-latest.json", + "requires": [ + { + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", + "offlineFileName": "Phoenix6-replay-frc2026-beta-latest.json", + "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json" + } + ], + "conflictsWith": [ + { + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "errorMessage": "Users must use the regular Phoenix 5 vendordep when using the regular Phoenix 6 vendordep.", + "offlineFileName": "Phoenix6-frc2026-beta-latest.json" + }, + { + "uuid": "ab676553-b602-441f-a38d-f1296eff6537", + "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", + "offlineFileName": "Phoenix5-frc2026-beta-latest.json" + } + ], + "javaDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-java", + "version": "5.36.0-beta-1" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-java", + "version": "5.36.0-beta-1" + } + ], + "jniDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "cci-replay", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ], + "cppDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-cpp", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-cpp", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "wpiapi-cpp-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "api-cpp-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "cci-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "wpiapi-cpp-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "api-cpp-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixSim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ] +} \ No newline at end of file diff --git a/examples/drivebase_with_PathPlanner/vendordeps/Phoenix6-frc2025-latest.json b/examples/drivebase_only_2026/vendordeps/Phoenix6-replay-26.0.0-beta-1.json similarity index 81% rename from examples/drivebase_with_PathPlanner/vendordeps/Phoenix6-frc2025-latest.json rename to examples/drivebase_only_2026/vendordeps/Phoenix6-replay-26.0.0-beta-1.json index 6f40c84..5312c86 100644 --- a/examples/drivebase_with_PathPlanner/vendordeps/Phoenix6-frc2025-latest.json +++ b/examples/drivebase_only_2026/vendordeps/Phoenix6-replay-26.0.0-beta-1.json @@ -1,38 +1,35 @@ { - "fileName": "Phoenix6-frc2025-latest.json", - "name": "CTRE-Phoenix (v6)", - "version": "25.4.0", - "frcYear": "2025", - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "fileName": "Phoenix6-replay-26.0.0-beta-1.json", + "name": "CTRE-Phoenix (v6) Replay", + "version": "26.0.0-beta-1", + "frcYear": "2026beta", + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", "mavenUrls": [ "https://maven.ctr-electronics.com/release/" ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json", + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json", "conflictsWith": [ { - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", "errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.", - "offlineFileName": "Phoenix6-replay-frc2025-latest.json" + "offlineFileName": "Phoenix6-frc2026-beta-latest.json" } ], "javaDependencies": [ { "groupId": "com.ctre.phoenix6", "artifactId": "wpiapi-java", - "version": "25.4.0" + "version": "26.0.0-beta-1" } ], "jniDependencies": [ { "groupId": "com.ctre.phoenix6", "artifactId": "api-cpp", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", "linuxathena" ], "simMode": "hwsim" @@ -40,21 +37,18 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "tools", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", "linuxathena" ], "simMode": "hwsim" }, { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "api-cpp-sim", - "version": "25.4.0", + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "api-cpp-replay", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -63,12 +57,12 @@ "linuxarm64", "osxuniversal" ], - "simMode": "swsim" + "simMode": "hwsim" }, { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "tools-sim", - "version": "25.4.0", + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "tools-replay", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -77,12 +71,12 @@ "linuxarm64", "osxuniversal" ], - "simMode": "swsim" + "simMode": "hwsim" }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simTalonSRX", - "version": "25.4.0", + "artifactId": "api-cpp-sim", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -95,8 +89,8 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simVictorSPX", - "version": "25.4.0", + "artifactId": "tools-sim", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -109,8 +103,8 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simPigeonIMU", - "version": "25.4.0", + "artifactId": "simTalonSRX", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -123,8 +117,8 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simCANCoder", - "version": "25.4.0", + "artifactId": "simVictorSPX", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -138,21 +132,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProTalonFX", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFXS", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -166,7 +146,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANcoder", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -180,7 +160,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProPigeon2", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -194,7 +174,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANrange", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -208,7 +188,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdi", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -222,7 +202,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdle", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -238,15 +218,12 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "wpiapi-cpp", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_Phoenix6_WPI", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", "linuxathena" ], "simMode": "hwsim" @@ -254,24 +231,21 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "tools", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_PhoenixTools", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", "linuxathena" ], "simMode": "hwsim" }, { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "wpiapi-cpp-sim", - "version": "25.4.0", - "libName": "CTRE_Phoenix6_WPISim", + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "wpiapi-cpp-replay", + "version": "26.0.0-beta-1", + "libName": "CTRE_Phoenix6_WPIReplay", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -281,13 +255,13 @@ "linuxarm64", "osxuniversal" ], - "simMode": "swsim" + "simMode": "hwsim" }, { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "tools-sim", - "version": "25.4.0", - "libName": "CTRE_PhoenixTools_Sim", + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "tools-replay", + "version": "26.0.0-beta-1", + "libName": "CTRE_PhoenixTools_Replay", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -297,13 +271,13 @@ "linuxarm64", "osxuniversal" ], - "simMode": "swsim" + "simMode": "hwsim" }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simTalonSRX", - "version": "25.4.0", - "libName": "CTRE_SimTalonSRX", + "artifactId": "wpiapi-cpp-sim", + "version": "26.0.0-beta-1", + "libName": "CTRE_Phoenix6_WPISim", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -317,9 +291,9 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simVictorSPX", - "version": "25.4.0", - "libName": "CTRE_SimVictorSPX", + "artifactId": "tools-sim", + "version": "26.0.0-beta-1", + "libName": "CTRE_PhoenixTools_Sim", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -333,9 +307,9 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simPigeonIMU", - "version": "25.4.0", - "libName": "CTRE_SimPigeonIMU", + "artifactId": "simTalonSRX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimTalonSRX", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -349,9 +323,9 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simCANCoder", - "version": "25.4.0", - "libName": "CTRE_SimCANCoder", + "artifactId": "simVictorSPX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimVictorSPX", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -365,9 +339,9 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFX", - "version": "25.4.0", - "libName": "CTRE_SimProTalonFX", + "artifactId": "simPigeonIMU", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimPigeonIMU", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -381,9 +355,9 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFXS", - "version": "25.4.0", - "libName": "CTRE_SimProTalonFXS", + "artifactId": "simProTalonFX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProTalonFX", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -398,7 +372,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANcoder", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_SimProCANcoder", "headerClassifier": "headers", "sharedLibrary": true, @@ -414,7 +388,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProPigeon2", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_SimProPigeon2", "headerClassifier": "headers", "sharedLibrary": true, @@ -430,7 +404,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANrange", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_SimProCANrange", "headerClassifier": "headers", "sharedLibrary": true, @@ -446,7 +420,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdi", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_SimProCANdi", "headerClassifier": "headers", "sharedLibrary": true, @@ -462,7 +436,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdle", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_SimProCANdle", "headerClassifier": "headers", "sharedLibrary": true, diff --git a/examples/drivebase_only_2026/vendordeps/REVLib.json b/examples/drivebase_only_2026/vendordeps/REVLib.json new file mode 100644 index 0000000..0f666c9 --- /dev/null +++ b/examples/drivebase_only_2026/vendordeps/REVLib.json @@ -0,0 +1,133 @@ +{ + "fileName": "REVLib.json", + "name": "REVLib", + "version": "2026.0.0-beta-1", + "frcYear": "2026beta", + "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", + "mavenUrls": [ + "https://maven.revrobotics.com/" + ], + "jsonUrl": "https://software-metadata.revrobotics.com/REVLib-2026.json", + "javaDependencies": [ + { + "groupId": "com.revrobotics.frc", + "artifactId": "REVLib-java", + "version": "2026.0.0-beta-1" + } + ], + "jniDependencies": [ + { + "groupId": "com.revrobotics.frc", + "artifactId": "REVLib-driver", + "version": "2026.0.0-beta-1", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibBackendDriver", + "version": "2026.0.0-beta-1", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibWpiBackendDriver", + "version": "2026.0.0-beta-1", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.revrobotics.frc", + "artifactId": "REVLib-cpp", + "version": "2026.0.0-beta-1", + "libName": "REVLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "REVLib-driver", + "version": "2026.0.0-beta-1", + "libName": "REVLibDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibBackendDriver", + "version": "2026.0.0-beta-1", + "libName": "BackendDriver", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibWpiBackendDriver", + "version": "2026.0.0-beta-1", + "libName": "REVLibWpi", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/vendordeps/Studica-2026.0.0-beta.json b/examples/drivebase_only_2026/vendordeps/Studica-2026.0.0-beta.json new file mode 100644 index 0000000..c5d48c7 --- /dev/null +++ b/examples/drivebase_only_2026/vendordeps/Studica-2026.0.0-beta.json @@ -0,0 +1,71 @@ +{ + "fileName": "Studica-2026.0.0-beta.json", + "name": "Studica", + "version": "2026.0.0-beta", + "frcYear": "2026beta", + "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0-beta.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-java", + "version": "2026.0.0-beta" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0-beta", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-cpp", + "version": "2026.0.0-beta", + "libName": "Studica", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0-beta", + "libName": "StudicaDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/vendordeps/StudicaLib.json b/examples/drivebase_only_2026/vendordeps/StudicaLib.json new file mode 100644 index 0000000..b6ed33e --- /dev/null +++ b/examples/drivebase_only_2026/vendordeps/StudicaLib.json @@ -0,0 +1,71 @@ +{ + "fileName": "StudicaLib.json", + "name": "StudicaLib", + "version": "2026.0.1-beta", + "frcYear": "2026beta", + "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.1-beta.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-java", + "version": "2026.0.1-beta" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.1-beta", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-cpp", + "version": "2026.0.1-beta", + "libName": "StudicaLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.1-beta", + "libName": "StudicaLibDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/vendordeps/ThriftyLib.json b/examples/drivebase_only_2026/vendordeps/ThriftyLib.json new file mode 100644 index 0000000..1e59797 --- /dev/null +++ b/examples/drivebase_only_2026/vendordeps/ThriftyLib.json @@ -0,0 +1,20 @@ +{ + "fileName": "ThriftyLib.json", + "name": "ThriftyLib", + "version": "2026.0.0", + "frcYear": "2026beta", + "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", + "mavenUrls": [ + "https://docs.home.thethriftybot.com" + ], + "jsonUrl": "https://docs.home.thethriftybot.com/ThriftyLib.json", + "javaDependencies": [ + { + "groupId": "com.thethriftybot.frc", + "artifactId": "ThriftyLib-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [], + "cppDependencies": [] +} diff --git a/examples/drivebase_only_2026/vendordeps/WPILibNewCommands.json b/examples/drivebase_only_2026/vendordeps/WPILibNewCommands.json new file mode 100644 index 0000000..7ebc954 --- /dev/null +++ b/examples/drivebase_only_2026/vendordeps/WPILibNewCommands.json @@ -0,0 +1,39 @@ +{ + "fileName": "WPILibNewCommands.json", + "name": "WPILib-New-Commands", + "version": "1.0.0", + "uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266", + "frcYear": "2026beta", + "mavenUrls": [], + "jsonUrl": "", + "javaDependencies": [ + { + "groupId": "edu.wpi.first.wpilibNewCommands", + "artifactId": "wpilibNewCommands-java", + "version": "wpilib" + } + ], + "jniDependencies": [], + "cppDependencies": [ + { + "groupId": "edu.wpi.first.wpilibNewCommands", + "artifactId": "wpilibNewCommands-cpp", + "version": "wpilib", + "libName": "wpilibNewCommands", + "headerClassifier": "headers", + "sourcesClassifier": "sources", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxsystemcore", + "linuxathena", + "linuxarm32", + "linuxarm64", + "windowsx86-64", + "windowsx86", + "linuxx86-64", + "osxuniversal" + ] + } + ] +} diff --git a/examples/drivebase_with_PathPlanner/.wpilib/wpilib_preferences.json b/examples/drivebase_with_PathPlanner/.wpilib/wpilib_preferences.json index 83517dd..f727ea3 100644 --- a/examples/drivebase_with_PathPlanner/.wpilib/wpilib_preferences.json +++ b/examples/drivebase_with_PathPlanner/.wpilib/wpilib_preferences.json @@ -1,6 +1,6 @@ { "enableCppIntellisense": false, "currentLanguage": "java", - "projectYear": "2025", + "projectYear": "2026beta", "teamNumber": 3481 } \ No newline at end of file diff --git a/examples/drivebase_with_PathPlanner/build.gradle b/examples/drivebase_with_PathPlanner/build.gradle index fdf6d52..4233229 100644 --- a/examples/drivebase_with_PathPlanner/build.gradle +++ b/examples/drivebase_with_PathPlanner/build.gradle @@ -1,6 +1,6 @@ plugins { id "java" - id "edu.wpi.first.GradleRIO" version "2025.3.1" + id "edu.wpi.first.GradleRIO" version "2026.1.1-beta-1" } java { @@ -8,6 +8,14 @@ java { targetCompatibility = JavaVersion.VERSION_17 } +sourceSets { + main { + java { + srcDir '../../yagsl/java/' + } + } +} + def ROBOT_MAIN_CLASS = "frc.robot.Main" // Define my targets (RoboRIO) and artifacts (deployable files) @@ -34,7 +42,7 @@ deploy { files = project.fileTree('src/main/deploy') directory = '/home/lvuser/deploy' deleteOldFiles = false // Change to true to delete files on roboRIO that no - // longer exist in deploy directory of this project + // longer exist in deploy directory of this project } } } @@ -43,7 +51,8 @@ deploy { def deployArtifact = deploy.targets.roborio.artifacts.frcJava -// Set to true to use debug for JNI. +// Set to true to use debug for all targets including JNI, which will drastically impact +// performance. wpi.java.debugJni = false // Set this to true to enable desktop support. @@ -69,6 +78,7 @@ dependencies { nativeRelease wpi.java.deps.wpilibJniRelease(wpi.platforms.desktop) nativeRelease wpi.java.vendor.jniRelease(wpi.platforms.desktop) simulationRelease wpi.sim.enableRelease() + implementation 'org.dyn4j:dyn4j:5.0.2' testImplementation 'org.junit.jupiter:junit-jupiter:5.10.1' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' diff --git a/examples/drivebase_with_PathPlanner/settings.gradle b/examples/drivebase_with_PathPlanner/settings.gradle index 969c7b0..25f6f6e 100644 --- a/examples/drivebase_with_PathPlanner/settings.gradle +++ b/examples/drivebase_with_PathPlanner/settings.gradle @@ -4,7 +4,7 @@ pluginManagement { repositories { mavenLocal() gradlePluginPortal() - String frcYear = '2025' + String frcYear = '2026' File frcHome if (OperatingSystem.current().isWindows()) { String publicFolder = System.getenv('PUBLIC') @@ -20,8 +20,8 @@ pluginManagement { } def frcHomeMaven = new File(frcHome, 'maven') maven { - name 'frcHome' - url frcHomeMaven + name = 'frcHome' + url = frcHomeMaven } } } diff --git a/examples/drivebase_with_PathPlanner/vendordeps/PathplannerLib.json b/examples/drivebase_with_PathPlanner/vendordeps/PathplannerLib.json deleted file mode 100644 index c496379..0000000 --- a/examples/drivebase_with_PathPlanner/vendordeps/PathplannerLib.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "fileName": "PathplannerLib.json", - "name": "PathplannerLib", - "version": "2025.2.7", - "uuid": "1b42324f-17c6-4875-8e77-1c312bc8c786", - "frcYear": "2025", - "mavenUrls": [ - "https://3015rangerrobotics.github.io/pathplannerlib/repo" - ], - "jsonUrl": "https://3015rangerrobotics.github.io/pathplannerlib/PathplannerLib.json", - "javaDependencies": [ - { - "groupId": "com.pathplanner.lib", - "artifactId": "PathplannerLib-java", - "version": "2025.2.7" - } - ], - "jniDependencies": [], - "cppDependencies": [ - { - "groupId": "com.pathplanner.lib", - "artifactId": "PathplannerLib-cpp", - "version": "2025.2.7", - "libName": "PathplannerLib", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "osxuniversal", - "linuxathena", - "linuxarm32", - "linuxarm64" - ] - } - ] -} \ No newline at end of file diff --git a/examples/drivebase_with_PathPlanner/vendordeps/Phoenix5-frc2025-latest.json b/examples/drivebase_with_PathPlanner/vendordeps/Phoenix5-frc2025-latest.json deleted file mode 100644 index 3cbc8f6..0000000 --- a/examples/drivebase_with_PathPlanner/vendordeps/Phoenix5-frc2025-latest.json +++ /dev/null @@ -1,171 +0,0 @@ -{ - "fileName": "Phoenix5-frc2025-latest.json", - "name": "CTRE-Phoenix (v5)", - "version": "5.35.1", - "frcYear": "2025", - "uuid": "ab676553-b602-441f-a38d-f1296eff6537", - "mavenUrls": [ - "https://maven.ctr-electronics.com/release/" - ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-frc2025-latest.json", - "requires": [ - { - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", - "offlineFileName": "Phoenix6-frc2025-latest.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json" - } - ], - "conflictsWith": [ - { - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", - "errorMessage": "Users must use the Phoenix 5 replay vendordep when using the Phoenix 6 replay vendordep.", - "offlineFileName": "Phoenix6-replay-frc2025-latest.json" - }, - { - "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", - "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", - "offlineFileName": "Phoenix5-replay-frc2025-latest.json" - } - ], - "javaDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "api-java", - "version": "5.35.1" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "wpiapi-java", - "version": "5.35.1" - } - ], - "jniDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "cci", - "version": "5.35.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "cci-sim", - "version": "5.35.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ], - "cppDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "wpiapi-cpp", - "version": "5.35.1", - "libName": "CTRE_Phoenix_WPI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "api-cpp", - "version": "5.35.1", - "libName": "CTRE_Phoenix", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "cci", - "version": "5.35.1", - "libName": "CTRE_PhoenixCCI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "wpiapi-cpp-sim", - "version": "5.35.1", - "libName": "CTRE_Phoenix_WPISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "api-cpp-sim", - "version": "5.35.1", - "libName": "CTRE_PhoenixSim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "cci-sim", - "version": "5.35.1", - "libName": "CTRE_PhoenixCCISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ] -} \ No newline at end of file diff --git a/examples/drivebase_with_PathPlanner/vendordeps/Phoenix5-replay-5.36.0-beta-1.json b/examples/drivebase_with_PathPlanner/vendordeps/Phoenix5-replay-5.36.0-beta-1.json new file mode 100644 index 0000000..4a78551 --- /dev/null +++ b/examples/drivebase_with_PathPlanner/vendordeps/Phoenix5-replay-5.36.0-beta-1.json @@ -0,0 +1,221 @@ +{ + "fileName": "Phoenix5-replay-5.36.0-beta-1.json", + "name": "CTRE-Phoenix (v5)", + "version": "5.36.0-beta-1", + "frcYear": "2026beta", + "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", + "mavenUrls": [ + "https://maven.ctr-electronics.com/release/" + ], + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-beta-latest.json", + "requires": [ + { + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", + "offlineFileName": "Phoenix6-replay-frc2026-beta-latest.json", + "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json" + } + ], + "conflictsWith": [ + { + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "errorMessage": "Users must use the regular Phoenix 5 vendordep when using the regular Phoenix 6 vendordep.", + "offlineFileName": "Phoenix6-frc2026-beta-latest.json" + }, + { + "uuid": "ab676553-b602-441f-a38d-f1296eff6537", + "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", + "offlineFileName": "Phoenix5-frc2026-beta-latest.json" + } + ], + "javaDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-java", + "version": "5.36.0-beta-1" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-java", + "version": "5.36.0-beta-1" + } + ], + "jniDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "cci-replay", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ], + "cppDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-cpp", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-cpp", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "wpiapi-cpp-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "api-cpp-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "cci-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "wpiapi-cpp-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "api-cpp-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixSim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ] +} \ No newline at end of file diff --git a/examples/drivebase_with_PhotonVision/vendordeps/Phoenix6-frc2025-latest.json b/examples/drivebase_with_PathPlanner/vendordeps/Phoenix6-replay-26.0.0-beta-1.json similarity index 81% rename from examples/drivebase_with_PhotonVision/vendordeps/Phoenix6-frc2025-latest.json rename to examples/drivebase_with_PathPlanner/vendordeps/Phoenix6-replay-26.0.0-beta-1.json index 6f40c84..5312c86 100644 --- a/examples/drivebase_with_PhotonVision/vendordeps/Phoenix6-frc2025-latest.json +++ b/examples/drivebase_with_PathPlanner/vendordeps/Phoenix6-replay-26.0.0-beta-1.json @@ -1,38 +1,35 @@ { - "fileName": "Phoenix6-frc2025-latest.json", - "name": "CTRE-Phoenix (v6)", - "version": "25.4.0", - "frcYear": "2025", - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "fileName": "Phoenix6-replay-26.0.0-beta-1.json", + "name": "CTRE-Phoenix (v6) Replay", + "version": "26.0.0-beta-1", + "frcYear": "2026beta", + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", "mavenUrls": [ "https://maven.ctr-electronics.com/release/" ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json", + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json", "conflictsWith": [ { - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", "errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.", - "offlineFileName": "Phoenix6-replay-frc2025-latest.json" + "offlineFileName": "Phoenix6-frc2026-beta-latest.json" } ], "javaDependencies": [ { "groupId": "com.ctre.phoenix6", "artifactId": "wpiapi-java", - "version": "25.4.0" + "version": "26.0.0-beta-1" } ], "jniDependencies": [ { "groupId": "com.ctre.phoenix6", "artifactId": "api-cpp", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", "linuxathena" ], "simMode": "hwsim" @@ -40,21 +37,18 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "tools", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", "linuxathena" ], "simMode": "hwsim" }, { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "api-cpp-sim", - "version": "25.4.0", + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "api-cpp-replay", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -63,12 +57,12 @@ "linuxarm64", "osxuniversal" ], - "simMode": "swsim" + "simMode": "hwsim" }, { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "tools-sim", - "version": "25.4.0", + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "tools-replay", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -77,12 +71,12 @@ "linuxarm64", "osxuniversal" ], - "simMode": "swsim" + "simMode": "hwsim" }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simTalonSRX", - "version": "25.4.0", + "artifactId": "api-cpp-sim", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -95,8 +89,8 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simVictorSPX", - "version": "25.4.0", + "artifactId": "tools-sim", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -109,8 +103,8 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simPigeonIMU", - "version": "25.4.0", + "artifactId": "simTalonSRX", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -123,8 +117,8 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simCANCoder", - "version": "25.4.0", + "artifactId": "simVictorSPX", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -138,21 +132,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProTalonFX", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFXS", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -166,7 +146,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANcoder", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -180,7 +160,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProPigeon2", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -194,7 +174,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANrange", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -208,7 +188,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdi", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -222,7 +202,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdle", - "version": "25.4.0", + "version": "26.0.0-beta-1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -238,15 +218,12 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "wpiapi-cpp", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_Phoenix6_WPI", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", "linuxathena" ], "simMode": "hwsim" @@ -254,24 +231,21 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "tools", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_PhoenixTools", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", "linuxathena" ], "simMode": "hwsim" }, { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "wpiapi-cpp-sim", - "version": "25.4.0", - "libName": "CTRE_Phoenix6_WPISim", + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "wpiapi-cpp-replay", + "version": "26.0.0-beta-1", + "libName": "CTRE_Phoenix6_WPIReplay", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -281,13 +255,13 @@ "linuxarm64", "osxuniversal" ], - "simMode": "swsim" + "simMode": "hwsim" }, { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "tools-sim", - "version": "25.4.0", - "libName": "CTRE_PhoenixTools_Sim", + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "tools-replay", + "version": "26.0.0-beta-1", + "libName": "CTRE_PhoenixTools_Replay", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -297,13 +271,13 @@ "linuxarm64", "osxuniversal" ], - "simMode": "swsim" + "simMode": "hwsim" }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simTalonSRX", - "version": "25.4.0", - "libName": "CTRE_SimTalonSRX", + "artifactId": "wpiapi-cpp-sim", + "version": "26.0.0-beta-1", + "libName": "CTRE_Phoenix6_WPISim", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -317,9 +291,9 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simVictorSPX", - "version": "25.4.0", - "libName": "CTRE_SimVictorSPX", + "artifactId": "tools-sim", + "version": "26.0.0-beta-1", + "libName": "CTRE_PhoenixTools_Sim", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -333,9 +307,9 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simPigeonIMU", - "version": "25.4.0", - "libName": "CTRE_SimPigeonIMU", + "artifactId": "simTalonSRX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimTalonSRX", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -349,9 +323,9 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simCANCoder", - "version": "25.4.0", - "libName": "CTRE_SimCANCoder", + "artifactId": "simVictorSPX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimVictorSPX", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -365,9 +339,9 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFX", - "version": "25.4.0", - "libName": "CTRE_SimProTalonFX", + "artifactId": "simPigeonIMU", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimPigeonIMU", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -381,9 +355,9 @@ }, { "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFXS", - "version": "25.4.0", - "libName": "CTRE_SimProTalonFXS", + "artifactId": "simProTalonFX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProTalonFX", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -398,7 +372,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANcoder", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_SimProCANcoder", "headerClassifier": "headers", "sharedLibrary": true, @@ -414,7 +388,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProPigeon2", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_SimProPigeon2", "headerClassifier": "headers", "sharedLibrary": true, @@ -430,7 +404,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANrange", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_SimProCANrange", "headerClassifier": "headers", "sharedLibrary": true, @@ -446,7 +420,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdi", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_SimProCANdi", "headerClassifier": "headers", "sharedLibrary": true, @@ -462,7 +436,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdle", - "version": "25.4.0", + "version": "26.0.0-beta-1", "libName": "CTRE_SimProCANdle", "headerClassifier": "headers", "sharedLibrary": true, diff --git a/examples/drivebase_with_PathPlanner/vendordeps/REVLib.json b/examples/drivebase_with_PathPlanner/vendordeps/REVLib.json index 5546ea8..0f666c9 100644 --- a/examples/drivebase_with_PathPlanner/vendordeps/REVLib.json +++ b/examples/drivebase_with_PathPlanner/vendordeps/REVLib.json @@ -1,25 +1,55 @@ { "fileName": "REVLib.json", "name": "REVLib", - "version": "2025.0.3", - "frcYear": "2025", + "version": "2026.0.0-beta-1", + "frcYear": "2026beta", "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", "mavenUrls": [ "https://maven.revrobotics.com/" ], - "jsonUrl": "https://software-metadata.revrobotics.com/REVLib-2025.json", + "jsonUrl": "https://software-metadata.revrobotics.com/REVLib-2026.json", "javaDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-java", - "version": "2025.0.3" + "version": "2026.0.0-beta-1" } ], "jniDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibBackendDriver", + "version": "2026.0.0-beta-1", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibWpiBackendDriver", + "version": "2026.0.0-beta-1", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -36,7 +66,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-cpp", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", "libName": "REVLib", "headerClassifier": "headers", "sharedLibrary": false, @@ -53,7 +83,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", "libName": "REVLibDriver", "headerClassifier": "headers", "sharedLibrary": false, @@ -66,6 +96,38 @@ "linuxarm32", "osxuniversal" ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibBackendDriver", + "version": "2026.0.0-beta-1", + "libName": "BackendDriver", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibWpiBackendDriver", + "version": "2026.0.0-beta-1", + "libName": "REVLibWpi", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] } ] } \ No newline at end of file diff --git a/examples/drivebase_with_PathPlanner/vendordeps/ReduxLib-2025.0.1.json b/examples/drivebase_with_PathPlanner/vendordeps/ReduxLib-2025.0.1.json deleted file mode 100644 index 007f97f..0000000 --- a/examples/drivebase_with_PathPlanner/vendordeps/ReduxLib-2025.0.1.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "fileName": "ReduxLib-2025.0.1.json", - "name": "ReduxLib", - "version": "2025.0.1", - "frcYear": "2025", - "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", - "mavenUrls": [ - "https://maven.reduxrobotics.com/" - ], - "jsonUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2025.json", - "javaDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-java", - "version": "2025.0.1" - } - ], - "jniDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-driver", - "version": "2025.0.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - } - ], - "cppDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-cpp", - "version": "2025.0.1", - "libName": "ReduxLib", - "headerClassifier": "headers", - "sourcesClassifier": "sources", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - }, - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-driver", - "version": "2025.0.1", - "libName": "ReduxCore", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - } - ] -} \ No newline at end of file diff --git a/examples/drivebase_with_PathPlanner/vendordeps/Studica-2025.0.1.json b/examples/drivebase_with_PathPlanner/vendordeps/Studica-2025.0.1.json deleted file mode 100644 index e0b50d7..0000000 --- a/examples/drivebase_with_PathPlanner/vendordeps/Studica-2025.0.1.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "Studica-2025.0.1.json", - "name": "Studica", - "version": "2025.0.1", - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", - "frcYear": "2025", - "mavenUrls": [ - "https://dev.studica.com/maven/release/2025/" - ], - "jsonUrl": "https://dev.studica.com/releases/2025/Studica-2025.0.1.json", - "cppDependencies": [ - { - "artifactId": "Studica-cpp", - "binaryPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "groupId": "com.studica.frc", - "headerClassifier": "headers", - "libName": "Studica", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "version": "2025.0.1" - }, - { - "artifactId": "Studica-driver", - "binaryPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "groupId": "com.studica.frc", - "headerClassifier": "headers", - "libName": "StudicaDriver", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "version": "2025.0.1" - } - ], - "javaDependencies": [ - { - "artifactId": "Studica-java", - "groupId": "com.studica.frc", - "version": "2025.0.1" - } - ], - "jniDependencies": [ - { - "artifactId": "Studica-driver", - "groupId": "com.studica.frc", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "version": "2025.0.1" - } - ] -} \ No newline at end of file diff --git a/examples/drivebase_with_PathPlanner/vendordeps/Studica-2026.0.0-beta.json b/examples/drivebase_with_PathPlanner/vendordeps/Studica-2026.0.0-beta.json new file mode 100644 index 0000000..c5d48c7 --- /dev/null +++ b/examples/drivebase_with_PathPlanner/vendordeps/Studica-2026.0.0-beta.json @@ -0,0 +1,71 @@ +{ + "fileName": "Studica-2026.0.0-beta.json", + "name": "Studica", + "version": "2026.0.0-beta", + "frcYear": "2026beta", + "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0-beta.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-java", + "version": "2026.0.0-beta" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0-beta", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-cpp", + "version": "2026.0.0-beta", + "libName": "Studica", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0-beta", + "libName": "StudicaDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/examples/drivebase_with_PathPlanner/vendordeps/StudicaLib.json b/examples/drivebase_with_PathPlanner/vendordeps/StudicaLib.json new file mode 100644 index 0000000..b6ed33e --- /dev/null +++ b/examples/drivebase_with_PathPlanner/vendordeps/StudicaLib.json @@ -0,0 +1,71 @@ +{ + "fileName": "StudicaLib.json", + "name": "StudicaLib", + "version": "2026.0.1-beta", + "frcYear": "2026beta", + "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.1-beta.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-java", + "version": "2026.0.1-beta" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.1-beta", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-cpp", + "version": "2026.0.1-beta", + "libName": "StudicaLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.1-beta", + "libName": "StudicaLibDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/examples/drivebase_with_PathPlanner/vendordeps/ThriftyLib.json b/examples/drivebase_with_PathPlanner/vendordeps/ThriftyLib.json index 887721f..1e59797 100644 --- a/examples/drivebase_with_PathPlanner/vendordeps/ThriftyLib.json +++ b/examples/drivebase_with_PathPlanner/vendordeps/ThriftyLib.json @@ -1,8 +1,8 @@ { "fileName": "ThriftyLib.json", "name": "ThriftyLib", - "version": "2025.1.1", - "frcYear": "2025", + "version": "2026.0.0", + "frcYear": "2026beta", "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", "mavenUrls": [ "https://docs.home.thethriftybot.com" @@ -12,9 +12,9 @@ { "groupId": "com.thethriftybot.frc", "artifactId": "ThriftyLib-java", - "version": "2025.1.1" + "version": "2026.0.0" } ], "jniDependencies": [], "cppDependencies": [] -} \ No newline at end of file +} diff --git a/examples/drivebase_with_PathPlanner/vendordeps/WPILibNewCommands.json b/examples/drivebase_with_PathPlanner/vendordeps/WPILibNewCommands.json index 3718e0a..7ebc954 100644 --- a/examples/drivebase_with_PathPlanner/vendordeps/WPILibNewCommands.json +++ b/examples/drivebase_with_PathPlanner/vendordeps/WPILibNewCommands.json @@ -3,7 +3,7 @@ "name": "WPILib-New-Commands", "version": "1.0.0", "uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266", - "frcYear": "2025", + "frcYear": "2026beta", "mavenUrls": [], "jsonUrl": "", "javaDependencies": [ @@ -25,6 +25,7 @@ "sharedLibrary": true, "skipInvalidPlatforms": true, "binaryPlatforms": [ + "linuxsystemcore", "linuxathena", "linuxarm32", "linuxarm64", diff --git a/examples/drivebase_with_PathPlanner/vendordeps/maple-sim.json b/examples/drivebase_with_PathPlanner/vendordeps/maple-sim.json deleted file mode 100644 index 73c812f..0000000 --- a/examples/drivebase_with_PathPlanner/vendordeps/maple-sim.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "fileName": "maple-sim.json", - "name": "maplesim", - "version": "0.3.14", - "frcYear": "2025", - "uuid": "c39481e8-4a63-4a4c-9df6-48d91e4da37b", - "mavenUrls": [ - "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/repos/releases", - "https://repo1.maven.org/maven2" - ], - "jsonUrl": "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/maple-sim.json", - "javaDependencies": [ - { - "groupId": "org.ironmaple", - "artifactId": "maplesim-java", - "version": "0.3.14" - }, - { - "groupId": "org.dyn4j", - "artifactId": "dyn4j", - "version": "5.0.2" - } - ], - "jniDependencies": [], - "cppDependencies": [] -} \ No newline at end of file diff --git a/examples/drivebase_with_PathPlanner/vendordeps/photonlib.json b/examples/drivebase_with_PathPlanner/vendordeps/photonlib.json deleted file mode 100644 index 5c6484d..0000000 --- a/examples/drivebase_with_PathPlanner/vendordeps/photonlib.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "photonlib.json", - "name": "photonlib", - "version": "v2025.3.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.3.1", - "skipInvalidPlatforms": true, - "isJar": false, - "validPlatforms": [ - "windowsx86-64", - "linuxathena", - "linuxx86-64", - "osxuniversal" - ] - } - ], - "cppDependencies": [ - { - "groupId": "org.photonvision", - "artifactId": "photonlib-cpp", - "version": "v2025.3.1", - "libName": "photonlib", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxathena", - "linuxx86-64", - "osxuniversal" - ] - }, - { - "groupId": "org.photonvision", - "artifactId": "photontargeting-cpp", - "version": "v2025.3.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.3.1" - }, - { - "groupId": "org.photonvision", - "artifactId": "photontargeting-java", - "version": "v2025.3.1" - } - ] -} \ No newline at end of file diff --git a/examples/drivebase_with_PathPlanner/vendordeps/yagsl-2025.7.2.json b/examples/drivebase_with_PathPlanner/vendordeps/yagsl-2025.7.2.json deleted file mode 100644 index 9fb6a48..0000000 --- a/examples/drivebase_with_PathPlanner/vendordeps/yagsl-2025.7.2.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "fileName": "yagsl-2025.7.2.json", - "name": "YAGSL", - "version": "2025.7.2", - "frcYear": "2025", - "uuid": "1ccce5a4-acd2-4d18-bca3-4b8047188400", - "mavenUrls": [ - "https://broncbotz3481.github.io/YAGSL-Lib/yagsl/repos" - ], - "jsonUrl": "https://broncbotz3481.github.io/YAGSL-Lib/yagsl/yagsl.json", - "javaDependencies": [ - { - "groupId": "swervelib", - "artifactId": "YAGSL-java", - "version": "2025.7.2" - } - ], - "requires": [ - { - "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", - "errorMessage": "REVLib is required!", - "offlineFileName": "REVLib-2025.0.0.json", - "onlineUrl": "https://software-metadata.revrobotics.com/REVLib-2025.json" - }, - { - "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", - "errorMessage": "ReduxLib is required!", - "offlineFileName": "ReduxLib-2025.0.0.json", - "onlineUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2025.json" - }, - { - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "errorMessage": "Phoenix6 is required!", - "offlineFileName": "Phoenix6-25.1.0.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json" - }, - { - "uuid": "ab676553-b602-441f-a38d-f1296eff6537", - "errorMessage": "Phoenix5 is required!", - "offlineFileName": "Phoenix5-5.35.0.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-frc2025-latest.json" - }, - { - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", - "errorMessage": "Studica is required!", - "offlineFileName": "Studica-2025.0.0.json", - "onlineUrl": "https://dev.studica.com/releases/2025/Studica-2025.0.0.json" - }, - { - "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", - "errorMessage": "ThriftyLib is required!", - "offlineFileName": "ThriftyLib.json", - "onlineUrl": "https://docs.home.thethriftybot.com/ThriftyLib.json" - }, - { - "uuid": "c39481e8-4a63-4a4c-9df6-48d91e4da37b", - "errorMessage": "maple-sim is required for simulation", - "offlineFileName": "maple-sim.json", - "onlineUrl": "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/maple-sim.json" - } - ], - "jniDependencies": [], - "cppDependencies": [] -} \ No newline at end of file diff --git a/examples/drivebase_with_PhotonVision/.wpilib/wpilib_preferences.json b/examples/drivebase_with_PhotonVision/.wpilib/wpilib_preferences.json index 04917b5..f727ea3 100644 --- a/examples/drivebase_with_PhotonVision/.wpilib/wpilib_preferences.json +++ b/examples/drivebase_with_PhotonVision/.wpilib/wpilib_preferences.json @@ -1,6 +1,6 @@ { "enableCppIntellisense": false, "currentLanguage": "java", - "projectYear": "2025", - "teamNumber": 2181 + "projectYear": "2026beta", + "teamNumber": 3481 } \ No newline at end of file diff --git a/examples/drivebase_with_PhotonVision/build.gradle b/examples/drivebase_with_PhotonVision/build.gradle index fdf6d52..4233229 100644 --- a/examples/drivebase_with_PhotonVision/build.gradle +++ b/examples/drivebase_with_PhotonVision/build.gradle @@ -1,6 +1,6 @@ plugins { id "java" - id "edu.wpi.first.GradleRIO" version "2025.3.1" + id "edu.wpi.first.GradleRIO" version "2026.1.1-beta-1" } java { @@ -8,6 +8,14 @@ java { targetCompatibility = JavaVersion.VERSION_17 } +sourceSets { + main { + java { + srcDir '../../yagsl/java/' + } + } +} + def ROBOT_MAIN_CLASS = "frc.robot.Main" // Define my targets (RoboRIO) and artifacts (deployable files) @@ -34,7 +42,7 @@ deploy { files = project.fileTree('src/main/deploy') directory = '/home/lvuser/deploy' deleteOldFiles = false // Change to true to delete files on roboRIO that no - // longer exist in deploy directory of this project + // longer exist in deploy directory of this project } } } @@ -43,7 +51,8 @@ deploy { def deployArtifact = deploy.targets.roborio.artifacts.frcJava -// Set to true to use debug for JNI. +// Set to true to use debug for all targets including JNI, which will drastically impact +// performance. wpi.java.debugJni = false // Set this to true to enable desktop support. @@ -69,6 +78,7 @@ dependencies { nativeRelease wpi.java.deps.wpilibJniRelease(wpi.platforms.desktop) nativeRelease wpi.java.vendor.jniRelease(wpi.platforms.desktop) simulationRelease wpi.sim.enableRelease() + implementation 'org.dyn4j:dyn4j:5.0.2' testImplementation 'org.junit.jupiter:junit-jupiter:5.10.1' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' diff --git a/examples/drivebase_with_PhotonVision/settings.gradle b/examples/drivebase_with_PhotonVision/settings.gradle index 969c7b0..25f6f6e 100644 --- a/examples/drivebase_with_PhotonVision/settings.gradle +++ b/examples/drivebase_with_PhotonVision/settings.gradle @@ -4,7 +4,7 @@ pluginManagement { repositories { mavenLocal() gradlePluginPortal() - String frcYear = '2025' + String frcYear = '2026' File frcHome if (OperatingSystem.current().isWindows()) { String publicFolder = System.getenv('PUBLIC') @@ -20,8 +20,8 @@ pluginManagement { } def frcHomeMaven = new File(frcHome, 'maven') maven { - name 'frcHome' - url frcHomeMaven + name = 'frcHome' + url = frcHomeMaven } } } diff --git a/examples/drivebase_with_PhotonVision/vendordeps/PathplannerLib.json b/examples/drivebase_with_PhotonVision/vendordeps/PathplannerLib.json deleted file mode 100644 index c496379..0000000 --- a/examples/drivebase_with_PhotonVision/vendordeps/PathplannerLib.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "fileName": "PathplannerLib.json", - "name": "PathplannerLib", - "version": "2025.2.7", - "uuid": "1b42324f-17c6-4875-8e77-1c312bc8c786", - "frcYear": "2025", - "mavenUrls": [ - "https://3015rangerrobotics.github.io/pathplannerlib/repo" - ], - "jsonUrl": "https://3015rangerrobotics.github.io/pathplannerlib/PathplannerLib.json", - "javaDependencies": [ - { - "groupId": "com.pathplanner.lib", - "artifactId": "PathplannerLib-java", - "version": "2025.2.7" - } - ], - "jniDependencies": [], - "cppDependencies": [ - { - "groupId": "com.pathplanner.lib", - "artifactId": "PathplannerLib-cpp", - "version": "2025.2.7", - "libName": "PathplannerLib", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "osxuniversal", - "linuxathena", - "linuxarm32", - "linuxarm64" - ] - } - ] -} \ No newline at end of file diff --git a/examples/drivebase_with_PhotonVision/vendordeps/Phoenix5-frc2025-latest.json b/examples/drivebase_with_PhotonVision/vendordeps/Phoenix5-frc2025-latest.json deleted file mode 100644 index 3cbc8f6..0000000 --- a/examples/drivebase_with_PhotonVision/vendordeps/Phoenix5-frc2025-latest.json +++ /dev/null @@ -1,171 +0,0 @@ -{ - "fileName": "Phoenix5-frc2025-latest.json", - "name": "CTRE-Phoenix (v5)", - "version": "5.35.1", - "frcYear": "2025", - "uuid": "ab676553-b602-441f-a38d-f1296eff6537", - "mavenUrls": [ - "https://maven.ctr-electronics.com/release/" - ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-frc2025-latest.json", - "requires": [ - { - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", - "offlineFileName": "Phoenix6-frc2025-latest.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json" - } - ], - "conflictsWith": [ - { - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", - "errorMessage": "Users must use the Phoenix 5 replay vendordep when using the Phoenix 6 replay vendordep.", - "offlineFileName": "Phoenix6-replay-frc2025-latest.json" - }, - { - "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", - "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", - "offlineFileName": "Phoenix5-replay-frc2025-latest.json" - } - ], - "javaDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "api-java", - "version": "5.35.1" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "wpiapi-java", - "version": "5.35.1" - } - ], - "jniDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "cci", - "version": "5.35.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "cci-sim", - "version": "5.35.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ], - "cppDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "wpiapi-cpp", - "version": "5.35.1", - "libName": "CTRE_Phoenix_WPI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "api-cpp", - "version": "5.35.1", - "libName": "CTRE_Phoenix", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "cci", - "version": "5.35.1", - "libName": "CTRE_PhoenixCCI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "wpiapi-cpp-sim", - "version": "5.35.1", - "libName": "CTRE_Phoenix_WPISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "api-cpp-sim", - "version": "5.35.1", - "libName": "CTRE_PhoenixSim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "cci-sim", - "version": "5.35.1", - "libName": "CTRE_PhoenixCCISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ] -} \ No newline at end of file diff --git a/examples/drivebase_with_PhotonVision/vendordeps/Phoenix5-replay-5.36.0-beta-1.json b/examples/drivebase_with_PhotonVision/vendordeps/Phoenix5-replay-5.36.0-beta-1.json new file mode 100644 index 0000000..4a78551 --- /dev/null +++ b/examples/drivebase_with_PhotonVision/vendordeps/Phoenix5-replay-5.36.0-beta-1.json @@ -0,0 +1,221 @@ +{ + "fileName": "Phoenix5-replay-5.36.0-beta-1.json", + "name": "CTRE-Phoenix (v5)", + "version": "5.36.0-beta-1", + "frcYear": "2026beta", + "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", + "mavenUrls": [ + "https://maven.ctr-electronics.com/release/" + ], + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-beta-latest.json", + "requires": [ + { + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", + "offlineFileName": "Phoenix6-replay-frc2026-beta-latest.json", + "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json" + } + ], + "conflictsWith": [ + { + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "errorMessage": "Users must use the regular Phoenix 5 vendordep when using the regular Phoenix 6 vendordep.", + "offlineFileName": "Phoenix6-frc2026-beta-latest.json" + }, + { + "uuid": "ab676553-b602-441f-a38d-f1296eff6537", + "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", + "offlineFileName": "Phoenix5-frc2026-beta-latest.json" + } + ], + "javaDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-java", + "version": "5.36.0-beta-1" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-java", + "version": "5.36.0-beta-1" + } + ], + "jniDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "cci-replay", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ], + "cppDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-cpp", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-cpp", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "wpiapi-cpp-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "api-cpp-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "cci-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "wpiapi-cpp-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "api-cpp-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixSim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ] +} \ No newline at end of file diff --git a/examples/drivebase_with_PhotonVision/vendordeps/Phoenix6-replay-26.0.0-beta-1.json b/examples/drivebase_with_PhotonVision/vendordeps/Phoenix6-replay-26.0.0-beta-1.json new file mode 100644 index 0000000..5312c86 --- /dev/null +++ b/examples/drivebase_with_PhotonVision/vendordeps/Phoenix6-replay-26.0.0-beta-1.json @@ -0,0 +1,453 @@ +{ + "fileName": "Phoenix6-replay-26.0.0-beta-1.json", + "name": "CTRE-Phoenix (v6) Replay", + "version": "26.0.0-beta-1", + "frcYear": "2026beta", + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "mavenUrls": [ + "https://maven.ctr-electronics.com/release/" + ], + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json", + "conflictsWith": [ + { + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.", + "offlineFileName": "Phoenix6-frc2026-beta-latest.json" + } + ], + "javaDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "wpiapi-java", + "version": "26.0.0-beta-1" + } + ], + "jniDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "api-cpp", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6", + "artifactId": "tools", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "api-cpp-replay", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "tools-replay", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "api-cpp-sim", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "tools-sim", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simTalonSRX", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simVictorSPX", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFX", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANcoder", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProPigeon2", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANrange", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdi", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdle", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ], + "cppDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "wpiapi-cpp", + "version": "26.0.0-beta-1", + "libName": "CTRE_Phoenix6_WPI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6", + "artifactId": "tools", + "version": "26.0.0-beta-1", + "libName": "CTRE_PhoenixTools", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "wpiapi-cpp-replay", + "version": "26.0.0-beta-1", + "libName": "CTRE_Phoenix6_WPIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "tools-replay", + "version": "26.0.0-beta-1", + "libName": "CTRE_PhoenixTools_Replay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "wpiapi-cpp-sim", + "version": "26.0.0-beta-1", + "libName": "CTRE_Phoenix6_WPISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "tools-sim", + "version": "26.0.0-beta-1", + "libName": "CTRE_PhoenixTools_Sim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simTalonSRX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimTalonSRX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simVictorSPX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimVictorSPX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simPigeonIMU", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimPigeonIMU", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProTalonFX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANcoder", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProCANcoder", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProPigeon2", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProPigeon2", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANrange", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProCANrange", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdi", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProCANdi", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdle", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProCANdle", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ] +} \ No newline at end of file diff --git a/examples/drivebase_with_PhotonVision/vendordeps/REVLib.json b/examples/drivebase_with_PhotonVision/vendordeps/REVLib.json index 5546ea8..0f666c9 100644 --- a/examples/drivebase_with_PhotonVision/vendordeps/REVLib.json +++ b/examples/drivebase_with_PhotonVision/vendordeps/REVLib.json @@ -1,25 +1,55 @@ { "fileName": "REVLib.json", "name": "REVLib", - "version": "2025.0.3", - "frcYear": "2025", + "version": "2026.0.0-beta-1", + "frcYear": "2026beta", "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", "mavenUrls": [ "https://maven.revrobotics.com/" ], - "jsonUrl": "https://software-metadata.revrobotics.com/REVLib-2025.json", + "jsonUrl": "https://software-metadata.revrobotics.com/REVLib-2026.json", "javaDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-java", - "version": "2025.0.3" + "version": "2026.0.0-beta-1" } ], "jniDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibBackendDriver", + "version": "2026.0.0-beta-1", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibWpiBackendDriver", + "version": "2026.0.0-beta-1", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -36,7 +66,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-cpp", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", "libName": "REVLib", "headerClassifier": "headers", "sharedLibrary": false, @@ -53,7 +83,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", "libName": "REVLibDriver", "headerClassifier": "headers", "sharedLibrary": false, @@ -66,6 +96,38 @@ "linuxarm32", "osxuniversal" ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibBackendDriver", + "version": "2026.0.0-beta-1", + "libName": "BackendDriver", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibWpiBackendDriver", + "version": "2026.0.0-beta-1", + "libName": "REVLibWpi", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] } ] } \ No newline at end of file diff --git a/examples/drivebase_with_PhotonVision/vendordeps/ReduxLib-2025.0.1.json b/examples/drivebase_with_PhotonVision/vendordeps/ReduxLib-2025.0.1.json deleted file mode 100644 index 007f97f..0000000 --- a/examples/drivebase_with_PhotonVision/vendordeps/ReduxLib-2025.0.1.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "fileName": "ReduxLib-2025.0.1.json", - "name": "ReduxLib", - "version": "2025.0.1", - "frcYear": "2025", - "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", - "mavenUrls": [ - "https://maven.reduxrobotics.com/" - ], - "jsonUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2025.json", - "javaDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-java", - "version": "2025.0.1" - } - ], - "jniDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-driver", - "version": "2025.0.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - } - ], - "cppDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-cpp", - "version": "2025.0.1", - "libName": "ReduxLib", - "headerClassifier": "headers", - "sourcesClassifier": "sources", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - }, - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-driver", - "version": "2025.0.1", - "libName": "ReduxCore", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - } - ] -} \ No newline at end of file diff --git a/examples/drivebase_with_PhotonVision/vendordeps/Studica-2025.0.1.json b/examples/drivebase_with_PhotonVision/vendordeps/Studica-2025.0.1.json deleted file mode 100644 index e0b50d7..0000000 --- a/examples/drivebase_with_PhotonVision/vendordeps/Studica-2025.0.1.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "Studica-2025.0.1.json", - "name": "Studica", - "version": "2025.0.1", - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", - "frcYear": "2025", - "mavenUrls": [ - "https://dev.studica.com/maven/release/2025/" - ], - "jsonUrl": "https://dev.studica.com/releases/2025/Studica-2025.0.1.json", - "cppDependencies": [ - { - "artifactId": "Studica-cpp", - "binaryPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "groupId": "com.studica.frc", - "headerClassifier": "headers", - "libName": "Studica", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "version": "2025.0.1" - }, - { - "artifactId": "Studica-driver", - "binaryPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "groupId": "com.studica.frc", - "headerClassifier": "headers", - "libName": "StudicaDriver", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "version": "2025.0.1" - } - ], - "javaDependencies": [ - { - "artifactId": "Studica-java", - "groupId": "com.studica.frc", - "version": "2025.0.1" - } - ], - "jniDependencies": [ - { - "artifactId": "Studica-driver", - "groupId": "com.studica.frc", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "version": "2025.0.1" - } - ] -} \ No newline at end of file diff --git a/examples/drivebase_with_PhotonVision/vendordeps/Studica-2026.0.0-beta.json b/examples/drivebase_with_PhotonVision/vendordeps/Studica-2026.0.0-beta.json new file mode 100644 index 0000000..c5d48c7 --- /dev/null +++ b/examples/drivebase_with_PhotonVision/vendordeps/Studica-2026.0.0-beta.json @@ -0,0 +1,71 @@ +{ + "fileName": "Studica-2026.0.0-beta.json", + "name": "Studica", + "version": "2026.0.0-beta", + "frcYear": "2026beta", + "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0-beta.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-java", + "version": "2026.0.0-beta" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0-beta", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-cpp", + "version": "2026.0.0-beta", + "libName": "Studica", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0-beta", + "libName": "StudicaDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/examples/drivebase_with_PhotonVision/vendordeps/StudicaLib.json b/examples/drivebase_with_PhotonVision/vendordeps/StudicaLib.json new file mode 100644 index 0000000..b6ed33e --- /dev/null +++ b/examples/drivebase_with_PhotonVision/vendordeps/StudicaLib.json @@ -0,0 +1,71 @@ +{ + "fileName": "StudicaLib.json", + "name": "StudicaLib", + "version": "2026.0.1-beta", + "frcYear": "2026beta", + "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.1-beta.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-java", + "version": "2026.0.1-beta" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.1-beta", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-cpp", + "version": "2026.0.1-beta", + "libName": "StudicaLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.1-beta", + "libName": "StudicaLibDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/examples/drivebase_with_PhotonVision/vendordeps/ThriftyLib.json b/examples/drivebase_with_PhotonVision/vendordeps/ThriftyLib.json index 887721f..1e59797 100644 --- a/examples/drivebase_with_PhotonVision/vendordeps/ThriftyLib.json +++ b/examples/drivebase_with_PhotonVision/vendordeps/ThriftyLib.json @@ -1,8 +1,8 @@ { "fileName": "ThriftyLib.json", "name": "ThriftyLib", - "version": "2025.1.1", - "frcYear": "2025", + "version": "2026.0.0", + "frcYear": "2026beta", "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", "mavenUrls": [ "https://docs.home.thethriftybot.com" @@ -12,9 +12,9 @@ { "groupId": "com.thethriftybot.frc", "artifactId": "ThriftyLib-java", - "version": "2025.1.1" + "version": "2026.0.0" } ], "jniDependencies": [], "cppDependencies": [] -} \ No newline at end of file +} diff --git a/examples/drivebase_with_PhotonVision/vendordeps/WPILibNewCommands.json b/examples/drivebase_with_PhotonVision/vendordeps/WPILibNewCommands.json index 3718e0a..7ebc954 100644 --- a/examples/drivebase_with_PhotonVision/vendordeps/WPILibNewCommands.json +++ b/examples/drivebase_with_PhotonVision/vendordeps/WPILibNewCommands.json @@ -3,7 +3,7 @@ "name": "WPILib-New-Commands", "version": "1.0.0", "uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266", - "frcYear": "2025", + "frcYear": "2026beta", "mavenUrls": [], "jsonUrl": "", "javaDependencies": [ @@ -25,6 +25,7 @@ "sharedLibrary": true, "skipInvalidPlatforms": true, "binaryPlatforms": [ + "linuxsystemcore", "linuxathena", "linuxarm32", "linuxarm64", diff --git a/examples/drivebase_with_PhotonVision/vendordeps/maple-sim.json b/examples/drivebase_with_PhotonVision/vendordeps/maple-sim.json deleted file mode 100644 index 73c812f..0000000 --- a/examples/drivebase_with_PhotonVision/vendordeps/maple-sim.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "fileName": "maple-sim.json", - "name": "maplesim", - "version": "0.3.14", - "frcYear": "2025", - "uuid": "c39481e8-4a63-4a4c-9df6-48d91e4da37b", - "mavenUrls": [ - "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/repos/releases", - "https://repo1.maven.org/maven2" - ], - "jsonUrl": "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/maple-sim.json", - "javaDependencies": [ - { - "groupId": "org.ironmaple", - "artifactId": "maplesim-java", - "version": "0.3.14" - }, - { - "groupId": "org.dyn4j", - "artifactId": "dyn4j", - "version": "5.0.2" - } - ], - "jniDependencies": [], - "cppDependencies": [] -} \ No newline at end of file diff --git a/examples/drivebase_with_PhotonVision/vendordeps/photonlib.json b/examples/drivebase_with_PhotonVision/vendordeps/photonlib.json deleted file mode 100644 index 5c6484d..0000000 --- a/examples/drivebase_with_PhotonVision/vendordeps/photonlib.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "photonlib.json", - "name": "photonlib", - "version": "v2025.3.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.3.1", - "skipInvalidPlatforms": true, - "isJar": false, - "validPlatforms": [ - "windowsx86-64", - "linuxathena", - "linuxx86-64", - "osxuniversal" - ] - } - ], - "cppDependencies": [ - { - "groupId": "org.photonvision", - "artifactId": "photonlib-cpp", - "version": "v2025.3.1", - "libName": "photonlib", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxathena", - "linuxx86-64", - "osxuniversal" - ] - }, - { - "groupId": "org.photonvision", - "artifactId": "photontargeting-cpp", - "version": "v2025.3.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.3.1" - }, - { - "groupId": "org.photonvision", - "artifactId": "photontargeting-java", - "version": "v2025.3.1" - } - ] -} \ No newline at end of file diff --git a/examples/drivebase_with_PhotonVision/vendordeps/yagsl-2025.7.2.json b/examples/drivebase_with_PhotonVision/vendordeps/yagsl-2025.7.2.json deleted file mode 100644 index 9fb6a48..0000000 --- a/examples/drivebase_with_PhotonVision/vendordeps/yagsl-2025.7.2.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "fileName": "yagsl-2025.7.2.json", - "name": "YAGSL", - "version": "2025.7.2", - "frcYear": "2025", - "uuid": "1ccce5a4-acd2-4d18-bca3-4b8047188400", - "mavenUrls": [ - "https://broncbotz3481.github.io/YAGSL-Lib/yagsl/repos" - ], - "jsonUrl": "https://broncbotz3481.github.io/YAGSL-Lib/yagsl/yagsl.json", - "javaDependencies": [ - { - "groupId": "swervelib", - "artifactId": "YAGSL-java", - "version": "2025.7.2" - } - ], - "requires": [ - { - "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", - "errorMessage": "REVLib is required!", - "offlineFileName": "REVLib-2025.0.0.json", - "onlineUrl": "https://software-metadata.revrobotics.com/REVLib-2025.json" - }, - { - "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", - "errorMessage": "ReduxLib is required!", - "offlineFileName": "ReduxLib-2025.0.0.json", - "onlineUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2025.json" - }, - { - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "errorMessage": "Phoenix6 is required!", - "offlineFileName": "Phoenix6-25.1.0.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json" - }, - { - "uuid": "ab676553-b602-441f-a38d-f1296eff6537", - "errorMessage": "Phoenix5 is required!", - "offlineFileName": "Phoenix5-5.35.0.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-frc2025-latest.json" - }, - { - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", - "errorMessage": "Studica is required!", - "offlineFileName": "Studica-2025.0.0.json", - "onlineUrl": "https://dev.studica.com/releases/2025/Studica-2025.0.0.json" - }, - { - "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", - "errorMessage": "ThriftyLib is required!", - "offlineFileName": "ThriftyLib.json", - "onlineUrl": "https://docs.home.thethriftybot.com/ThriftyLib.json" - }, - { - "uuid": "c39481e8-4a63-4a4c-9df6-48d91e4da37b", - "errorMessage": "maple-sim is required for simulation", - "offlineFileName": "maple-sim.json", - "onlineUrl": "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/maple-sim.json" - } - ], - "jniDependencies": [], - "cppDependencies": [] -} \ No newline at end of file diff --git a/examples/field_oriented_drivebase/.wpilib/wpilib_preferences.json b/examples/field_oriented_drivebase/.wpilib/wpilib_preferences.json index 83517dd..f727ea3 100644 --- a/examples/field_oriented_drivebase/.wpilib/wpilib_preferences.json +++ b/examples/field_oriented_drivebase/.wpilib/wpilib_preferences.json @@ -1,6 +1,6 @@ { "enableCppIntellisense": false, "currentLanguage": "java", - "projectYear": "2025", + "projectYear": "2026beta", "teamNumber": 3481 } \ No newline at end of file diff --git a/examples/field_oriented_drivebase/build.gradle b/examples/field_oriented_drivebase/build.gradle index fdf6d52..4233229 100644 --- a/examples/field_oriented_drivebase/build.gradle +++ b/examples/field_oriented_drivebase/build.gradle @@ -1,6 +1,6 @@ plugins { id "java" - id "edu.wpi.first.GradleRIO" version "2025.3.1" + id "edu.wpi.first.GradleRIO" version "2026.1.1-beta-1" } java { @@ -8,6 +8,14 @@ java { targetCompatibility = JavaVersion.VERSION_17 } +sourceSets { + main { + java { + srcDir '../../yagsl/java/' + } + } +} + def ROBOT_MAIN_CLASS = "frc.robot.Main" // Define my targets (RoboRIO) and artifacts (deployable files) @@ -34,7 +42,7 @@ deploy { files = project.fileTree('src/main/deploy') directory = '/home/lvuser/deploy' deleteOldFiles = false // Change to true to delete files on roboRIO that no - // longer exist in deploy directory of this project + // longer exist in deploy directory of this project } } } @@ -43,7 +51,8 @@ deploy { def deployArtifact = deploy.targets.roborio.artifacts.frcJava -// Set to true to use debug for JNI. +// Set to true to use debug for all targets including JNI, which will drastically impact +// performance. wpi.java.debugJni = false // Set this to true to enable desktop support. @@ -69,6 +78,7 @@ dependencies { nativeRelease wpi.java.deps.wpilibJniRelease(wpi.platforms.desktop) nativeRelease wpi.java.vendor.jniRelease(wpi.platforms.desktop) simulationRelease wpi.sim.enableRelease() + implementation 'org.dyn4j:dyn4j:5.0.2' testImplementation 'org.junit.jupiter:junit-jupiter:5.10.1' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' diff --git a/examples/field_oriented_drivebase/settings.gradle b/examples/field_oriented_drivebase/settings.gradle index 969c7b0..25f6f6e 100644 --- a/examples/field_oriented_drivebase/settings.gradle +++ b/examples/field_oriented_drivebase/settings.gradle @@ -4,7 +4,7 @@ pluginManagement { repositories { mavenLocal() gradlePluginPortal() - String frcYear = '2025' + String frcYear = '2026' File frcHome if (OperatingSystem.current().isWindows()) { String publicFolder = System.getenv('PUBLIC') @@ -20,8 +20,8 @@ pluginManagement { } def frcHomeMaven = new File(frcHome, 'maven') maven { - name 'frcHome' - url frcHomeMaven + name = 'frcHome' + url = frcHomeMaven } } } diff --git a/examples/field_oriented_drivebase/vendordeps/Phoenix5-frc2025-latest.json b/examples/field_oriented_drivebase/vendordeps/Phoenix5-frc2025-latest.json deleted file mode 100644 index 3cbc8f6..0000000 --- a/examples/field_oriented_drivebase/vendordeps/Phoenix5-frc2025-latest.json +++ /dev/null @@ -1,171 +0,0 @@ -{ - "fileName": "Phoenix5-frc2025-latest.json", - "name": "CTRE-Phoenix (v5)", - "version": "5.35.1", - "frcYear": "2025", - "uuid": "ab676553-b602-441f-a38d-f1296eff6537", - "mavenUrls": [ - "https://maven.ctr-electronics.com/release/" - ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-frc2025-latest.json", - "requires": [ - { - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", - "offlineFileName": "Phoenix6-frc2025-latest.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json" - } - ], - "conflictsWith": [ - { - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", - "errorMessage": "Users must use the Phoenix 5 replay vendordep when using the Phoenix 6 replay vendordep.", - "offlineFileName": "Phoenix6-replay-frc2025-latest.json" - }, - { - "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", - "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", - "offlineFileName": "Phoenix5-replay-frc2025-latest.json" - } - ], - "javaDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "api-java", - "version": "5.35.1" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "wpiapi-java", - "version": "5.35.1" - } - ], - "jniDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "cci", - "version": "5.35.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "cci-sim", - "version": "5.35.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ], - "cppDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "wpiapi-cpp", - "version": "5.35.1", - "libName": "CTRE_Phoenix_WPI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "api-cpp", - "version": "5.35.1", - "libName": "CTRE_Phoenix", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "cci", - "version": "5.35.1", - "libName": "CTRE_PhoenixCCI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "wpiapi-cpp-sim", - "version": "5.35.1", - "libName": "CTRE_Phoenix_WPISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "api-cpp-sim", - "version": "5.35.1", - "libName": "CTRE_PhoenixSim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "cci-sim", - "version": "5.35.1", - "libName": "CTRE_PhoenixCCISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ] -} \ No newline at end of file diff --git a/examples/field_oriented_drivebase/vendordeps/Phoenix5-replay-5.36.0-beta-1.json b/examples/field_oriented_drivebase/vendordeps/Phoenix5-replay-5.36.0-beta-1.json new file mode 100644 index 0000000..4a78551 --- /dev/null +++ b/examples/field_oriented_drivebase/vendordeps/Phoenix5-replay-5.36.0-beta-1.json @@ -0,0 +1,221 @@ +{ + "fileName": "Phoenix5-replay-5.36.0-beta-1.json", + "name": "CTRE-Phoenix (v5)", + "version": "5.36.0-beta-1", + "frcYear": "2026beta", + "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", + "mavenUrls": [ + "https://maven.ctr-electronics.com/release/" + ], + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-beta-latest.json", + "requires": [ + { + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", + "offlineFileName": "Phoenix6-replay-frc2026-beta-latest.json", + "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json" + } + ], + "conflictsWith": [ + { + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "errorMessage": "Users must use the regular Phoenix 5 vendordep when using the regular Phoenix 6 vendordep.", + "offlineFileName": "Phoenix6-frc2026-beta-latest.json" + }, + { + "uuid": "ab676553-b602-441f-a38d-f1296eff6537", + "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", + "offlineFileName": "Phoenix5-frc2026-beta-latest.json" + } + ], + "javaDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-java", + "version": "5.36.0-beta-1" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-java", + "version": "5.36.0-beta-1" + } + ], + "jniDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "cci-replay", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ], + "cppDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-cpp", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-cpp", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "wpiapi-cpp-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "api-cpp-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "cci-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "wpiapi-cpp-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "api-cpp-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixSim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ] +} \ No newline at end of file diff --git a/examples/field_oriented_drivebase/vendordeps/Phoenix6-frc2025-latest.json b/examples/field_oriented_drivebase/vendordeps/Phoenix6-frc2025-latest.json deleted file mode 100644 index 6f40c84..0000000 --- a/examples/field_oriented_drivebase/vendordeps/Phoenix6-frc2025-latest.json +++ /dev/null @@ -1,479 +0,0 @@ -{ - "fileName": "Phoenix6-frc2025-latest.json", - "name": "CTRE-Phoenix (v6)", - "version": "25.4.0", - "frcYear": "2025", - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "mavenUrls": [ - "https://maven.ctr-electronics.com/release/" - ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json", - "conflictsWith": [ - { - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", - "errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.", - "offlineFileName": "Phoenix6-replay-frc2025-latest.json" - } - ], - "javaDependencies": [ - { - "groupId": "com.ctre.phoenix6", - "artifactId": "wpiapi-java", - "version": "25.4.0" - } - ], - "jniDependencies": [ - { - "groupId": "com.ctre.phoenix6", - "artifactId": "api-cpp", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6", - "artifactId": "tools", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "api-cpp-sim", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "tools-sim", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simTalonSRX", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simVictorSPX", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simPigeonIMU", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simCANCoder", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFX", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFXS", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANcoder", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProPigeon2", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANrange", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANdi", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANdle", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ], - "cppDependencies": [ - { - "groupId": "com.ctre.phoenix6", - "artifactId": "wpiapi-cpp", - "version": "25.4.0", - "libName": "CTRE_Phoenix6_WPI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6", - "artifactId": "tools", - "version": "25.4.0", - "libName": "CTRE_PhoenixTools", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "wpiapi-cpp-sim", - "version": "25.4.0", - "libName": "CTRE_Phoenix6_WPISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "tools-sim", - "version": "25.4.0", - "libName": "CTRE_PhoenixTools_Sim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simTalonSRX", - "version": "25.4.0", - "libName": "CTRE_SimTalonSRX", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simVictorSPX", - "version": "25.4.0", - "libName": "CTRE_SimVictorSPX", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simPigeonIMU", - "version": "25.4.0", - "libName": "CTRE_SimPigeonIMU", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simCANCoder", - "version": "25.4.0", - "libName": "CTRE_SimCANCoder", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFX", - "version": "25.4.0", - "libName": "CTRE_SimProTalonFX", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFXS", - "version": "25.4.0", - "libName": "CTRE_SimProTalonFXS", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANcoder", - "version": "25.4.0", - "libName": "CTRE_SimProCANcoder", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProPigeon2", - "version": "25.4.0", - "libName": "CTRE_SimProPigeon2", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANrange", - "version": "25.4.0", - "libName": "CTRE_SimProCANrange", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANdi", - "version": "25.4.0", - "libName": "CTRE_SimProCANdi", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANdle", - "version": "25.4.0", - "libName": "CTRE_SimProCANdle", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ] -} \ No newline at end of file diff --git a/examples/field_oriented_drivebase/vendordeps/Phoenix6-replay-26.0.0-beta-1.json b/examples/field_oriented_drivebase/vendordeps/Phoenix6-replay-26.0.0-beta-1.json new file mode 100644 index 0000000..5312c86 --- /dev/null +++ b/examples/field_oriented_drivebase/vendordeps/Phoenix6-replay-26.0.0-beta-1.json @@ -0,0 +1,453 @@ +{ + "fileName": "Phoenix6-replay-26.0.0-beta-1.json", + "name": "CTRE-Phoenix (v6) Replay", + "version": "26.0.0-beta-1", + "frcYear": "2026beta", + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "mavenUrls": [ + "https://maven.ctr-electronics.com/release/" + ], + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json", + "conflictsWith": [ + { + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.", + "offlineFileName": "Phoenix6-frc2026-beta-latest.json" + } + ], + "javaDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "wpiapi-java", + "version": "26.0.0-beta-1" + } + ], + "jniDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "api-cpp", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6", + "artifactId": "tools", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "api-cpp-replay", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "tools-replay", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "api-cpp-sim", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "tools-sim", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simTalonSRX", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simVictorSPX", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFX", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANcoder", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProPigeon2", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANrange", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdi", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdle", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ], + "cppDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "wpiapi-cpp", + "version": "26.0.0-beta-1", + "libName": "CTRE_Phoenix6_WPI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6", + "artifactId": "tools", + "version": "26.0.0-beta-1", + "libName": "CTRE_PhoenixTools", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "wpiapi-cpp-replay", + "version": "26.0.0-beta-1", + "libName": "CTRE_Phoenix6_WPIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "tools-replay", + "version": "26.0.0-beta-1", + "libName": "CTRE_PhoenixTools_Replay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "wpiapi-cpp-sim", + "version": "26.0.0-beta-1", + "libName": "CTRE_Phoenix6_WPISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "tools-sim", + "version": "26.0.0-beta-1", + "libName": "CTRE_PhoenixTools_Sim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simTalonSRX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimTalonSRX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simVictorSPX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimVictorSPX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simPigeonIMU", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimPigeonIMU", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProTalonFX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANcoder", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProCANcoder", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProPigeon2", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProPigeon2", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANrange", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProCANrange", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdi", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProCANdi", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdle", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProCANdle", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ] +} \ No newline at end of file diff --git a/examples/field_oriented_drivebase/vendordeps/REVLib.json b/examples/field_oriented_drivebase/vendordeps/REVLib.json index 5546ea8..0f666c9 100644 --- a/examples/field_oriented_drivebase/vendordeps/REVLib.json +++ b/examples/field_oriented_drivebase/vendordeps/REVLib.json @@ -1,25 +1,55 @@ { "fileName": "REVLib.json", "name": "REVLib", - "version": "2025.0.3", - "frcYear": "2025", + "version": "2026.0.0-beta-1", + "frcYear": "2026beta", "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", "mavenUrls": [ "https://maven.revrobotics.com/" ], - "jsonUrl": "https://software-metadata.revrobotics.com/REVLib-2025.json", + "jsonUrl": "https://software-metadata.revrobotics.com/REVLib-2026.json", "javaDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-java", - "version": "2025.0.3" + "version": "2026.0.0-beta-1" } ], "jniDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibBackendDriver", + "version": "2026.0.0-beta-1", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibWpiBackendDriver", + "version": "2026.0.0-beta-1", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -36,7 +66,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-cpp", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", "libName": "REVLib", "headerClassifier": "headers", "sharedLibrary": false, @@ -53,7 +83,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", "libName": "REVLibDriver", "headerClassifier": "headers", "sharedLibrary": false, @@ -66,6 +96,38 @@ "linuxarm32", "osxuniversal" ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibBackendDriver", + "version": "2026.0.0-beta-1", + "libName": "BackendDriver", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibWpiBackendDriver", + "version": "2026.0.0-beta-1", + "libName": "REVLibWpi", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] } ] } \ No newline at end of file diff --git a/examples/field_oriented_drivebase/vendordeps/ReduxLib-2025.0.1.json b/examples/field_oriented_drivebase/vendordeps/ReduxLib-2025.0.1.json deleted file mode 100644 index 007f97f..0000000 --- a/examples/field_oriented_drivebase/vendordeps/ReduxLib-2025.0.1.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "fileName": "ReduxLib-2025.0.1.json", - "name": "ReduxLib", - "version": "2025.0.1", - "frcYear": "2025", - "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", - "mavenUrls": [ - "https://maven.reduxrobotics.com/" - ], - "jsonUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2025.json", - "javaDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-java", - "version": "2025.0.1" - } - ], - "jniDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-driver", - "version": "2025.0.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - } - ], - "cppDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-cpp", - "version": "2025.0.1", - "libName": "ReduxLib", - "headerClassifier": "headers", - "sourcesClassifier": "sources", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - }, - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-driver", - "version": "2025.0.1", - "libName": "ReduxCore", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - } - ] -} \ No newline at end of file diff --git a/examples/field_oriented_drivebase/vendordeps/Studica-2025.0.1.json b/examples/field_oriented_drivebase/vendordeps/Studica-2025.0.1.json deleted file mode 100644 index e0b50d7..0000000 --- a/examples/field_oriented_drivebase/vendordeps/Studica-2025.0.1.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "Studica-2025.0.1.json", - "name": "Studica", - "version": "2025.0.1", - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", - "frcYear": "2025", - "mavenUrls": [ - "https://dev.studica.com/maven/release/2025/" - ], - "jsonUrl": "https://dev.studica.com/releases/2025/Studica-2025.0.1.json", - "cppDependencies": [ - { - "artifactId": "Studica-cpp", - "binaryPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "groupId": "com.studica.frc", - "headerClassifier": "headers", - "libName": "Studica", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "version": "2025.0.1" - }, - { - "artifactId": "Studica-driver", - "binaryPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "groupId": "com.studica.frc", - "headerClassifier": "headers", - "libName": "StudicaDriver", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "version": "2025.0.1" - } - ], - "javaDependencies": [ - { - "artifactId": "Studica-java", - "groupId": "com.studica.frc", - "version": "2025.0.1" - } - ], - "jniDependencies": [ - { - "artifactId": "Studica-driver", - "groupId": "com.studica.frc", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "version": "2025.0.1" - } - ] -} \ No newline at end of file diff --git a/examples/field_oriented_drivebase/vendordeps/Studica-2026.0.0-beta.json b/examples/field_oriented_drivebase/vendordeps/Studica-2026.0.0-beta.json new file mode 100644 index 0000000..c5d48c7 --- /dev/null +++ b/examples/field_oriented_drivebase/vendordeps/Studica-2026.0.0-beta.json @@ -0,0 +1,71 @@ +{ + "fileName": "Studica-2026.0.0-beta.json", + "name": "Studica", + "version": "2026.0.0-beta", + "frcYear": "2026beta", + "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0-beta.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-java", + "version": "2026.0.0-beta" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0-beta", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-cpp", + "version": "2026.0.0-beta", + "libName": "Studica", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0-beta", + "libName": "StudicaDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/examples/field_oriented_drivebase/vendordeps/StudicaLib.json b/examples/field_oriented_drivebase/vendordeps/StudicaLib.json new file mode 100644 index 0000000..b6ed33e --- /dev/null +++ b/examples/field_oriented_drivebase/vendordeps/StudicaLib.json @@ -0,0 +1,71 @@ +{ + "fileName": "StudicaLib.json", + "name": "StudicaLib", + "version": "2026.0.1-beta", + "frcYear": "2026beta", + "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.1-beta.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-java", + "version": "2026.0.1-beta" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.1-beta", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-cpp", + "version": "2026.0.1-beta", + "libName": "StudicaLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.1-beta", + "libName": "StudicaLibDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/examples/field_oriented_drivebase/vendordeps/ThriftyLib.json b/examples/field_oriented_drivebase/vendordeps/ThriftyLib.json index 887721f..1e59797 100644 --- a/examples/field_oriented_drivebase/vendordeps/ThriftyLib.json +++ b/examples/field_oriented_drivebase/vendordeps/ThriftyLib.json @@ -1,8 +1,8 @@ { "fileName": "ThriftyLib.json", "name": "ThriftyLib", - "version": "2025.1.1", - "frcYear": "2025", + "version": "2026.0.0", + "frcYear": "2026beta", "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", "mavenUrls": [ "https://docs.home.thethriftybot.com" @@ -12,9 +12,9 @@ { "groupId": "com.thethriftybot.frc", "artifactId": "ThriftyLib-java", - "version": "2025.1.1" + "version": "2026.0.0" } ], "jniDependencies": [], "cppDependencies": [] -} \ No newline at end of file +} diff --git a/examples/field_oriented_drivebase/vendordeps/WPILibNewCommands.json b/examples/field_oriented_drivebase/vendordeps/WPILibNewCommands.json index 3718e0a..7ebc954 100644 --- a/examples/field_oriented_drivebase/vendordeps/WPILibNewCommands.json +++ b/examples/field_oriented_drivebase/vendordeps/WPILibNewCommands.json @@ -3,7 +3,7 @@ "name": "WPILib-New-Commands", "version": "1.0.0", "uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266", - "frcYear": "2025", + "frcYear": "2026beta", "mavenUrls": [], "jsonUrl": "", "javaDependencies": [ @@ -25,6 +25,7 @@ "sharedLibrary": true, "skipInvalidPlatforms": true, "binaryPlatforms": [ + "linuxsystemcore", "linuxathena", "linuxarm32", "linuxarm64", diff --git a/examples/field_oriented_drivebase/vendordeps/maple-sim.json b/examples/field_oriented_drivebase/vendordeps/maple-sim.json deleted file mode 100644 index 73c812f..0000000 --- a/examples/field_oriented_drivebase/vendordeps/maple-sim.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "fileName": "maple-sim.json", - "name": "maplesim", - "version": "0.3.14", - "frcYear": "2025", - "uuid": "c39481e8-4a63-4a4c-9df6-48d91e4da37b", - "mavenUrls": [ - "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/repos/releases", - "https://repo1.maven.org/maven2" - ], - "jsonUrl": "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/maple-sim.json", - "javaDependencies": [ - { - "groupId": "org.ironmaple", - "artifactId": "maplesim-java", - "version": "0.3.14" - }, - { - "groupId": "org.dyn4j", - "artifactId": "dyn4j", - "version": "5.0.2" - } - ], - "jniDependencies": [], - "cppDependencies": [] -} \ No newline at end of file diff --git a/examples/field_oriented_drivebase/vendordeps/photonlib.json b/examples/field_oriented_drivebase/vendordeps/photonlib.json deleted file mode 100644 index 5c6484d..0000000 --- a/examples/field_oriented_drivebase/vendordeps/photonlib.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "photonlib.json", - "name": "photonlib", - "version": "v2025.3.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.3.1", - "skipInvalidPlatforms": true, - "isJar": false, - "validPlatforms": [ - "windowsx86-64", - "linuxathena", - "linuxx86-64", - "osxuniversal" - ] - } - ], - "cppDependencies": [ - { - "groupId": "org.photonvision", - "artifactId": "photonlib-cpp", - "version": "v2025.3.1", - "libName": "photonlib", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxathena", - "linuxx86-64", - "osxuniversal" - ] - }, - { - "groupId": "org.photonvision", - "artifactId": "photontargeting-cpp", - "version": "v2025.3.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.3.1" - }, - { - "groupId": "org.photonvision", - "artifactId": "photontargeting-java", - "version": "v2025.3.1" - } - ] -} \ No newline at end of file diff --git a/examples/field_oriented_drivebase/vendordeps/yagsl-2025.7.2.json b/examples/field_oriented_drivebase/vendordeps/yagsl-2025.7.2.json deleted file mode 100644 index 9fb6a48..0000000 --- a/examples/field_oriented_drivebase/vendordeps/yagsl-2025.7.2.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "fileName": "yagsl-2025.7.2.json", - "name": "YAGSL", - "version": "2025.7.2", - "frcYear": "2025", - "uuid": "1ccce5a4-acd2-4d18-bca3-4b8047188400", - "mavenUrls": [ - "https://broncbotz3481.github.io/YAGSL-Lib/yagsl/repos" - ], - "jsonUrl": "https://broncbotz3481.github.io/YAGSL-Lib/yagsl/yagsl.json", - "javaDependencies": [ - { - "groupId": "swervelib", - "artifactId": "YAGSL-java", - "version": "2025.7.2" - } - ], - "requires": [ - { - "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", - "errorMessage": "REVLib is required!", - "offlineFileName": "REVLib-2025.0.0.json", - "onlineUrl": "https://software-metadata.revrobotics.com/REVLib-2025.json" - }, - { - "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", - "errorMessage": "ReduxLib is required!", - "offlineFileName": "ReduxLib-2025.0.0.json", - "onlineUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2025.json" - }, - { - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "errorMessage": "Phoenix6 is required!", - "offlineFileName": "Phoenix6-25.1.0.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json" - }, - { - "uuid": "ab676553-b602-441f-a38d-f1296eff6537", - "errorMessage": "Phoenix5 is required!", - "offlineFileName": "Phoenix5-5.35.0.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-frc2025-latest.json" - }, - { - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", - "errorMessage": "Studica is required!", - "offlineFileName": "Studica-2025.0.0.json", - "onlineUrl": "https://dev.studica.com/releases/2025/Studica-2025.0.0.json" - }, - { - "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", - "errorMessage": "ThriftyLib is required!", - "offlineFileName": "ThriftyLib.json", - "onlineUrl": "https://docs.home.thethriftybot.com/ThriftyLib.json" - }, - { - "uuid": "c39481e8-4a63-4a4c-9df6-48d91e4da37b", - "errorMessage": "maple-sim is required for simulation", - "offlineFileName": "maple-sim.json", - "onlineUrl": "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/maple-sim.json" - } - ], - "jniDependencies": [], - "cppDependencies": [] -} \ No newline at end of file diff --git a/examples/full_example/.wpilib/wpilib_preferences.json b/examples/full_example/.wpilib/wpilib_preferences.json index 83517dd..f727ea3 100644 --- a/examples/full_example/.wpilib/wpilib_preferences.json +++ b/examples/full_example/.wpilib/wpilib_preferences.json @@ -1,6 +1,6 @@ { "enableCppIntellisense": false, "currentLanguage": "java", - "projectYear": "2025", + "projectYear": "2026beta", "teamNumber": 3481 } \ No newline at end of file diff --git a/examples/full_example/build.gradle b/examples/full_example/build.gradle index fdf6d52..4233229 100644 --- a/examples/full_example/build.gradle +++ b/examples/full_example/build.gradle @@ -1,6 +1,6 @@ plugins { id "java" - id "edu.wpi.first.GradleRIO" version "2025.3.1" + id "edu.wpi.first.GradleRIO" version "2026.1.1-beta-1" } java { @@ -8,6 +8,14 @@ java { targetCompatibility = JavaVersion.VERSION_17 } +sourceSets { + main { + java { + srcDir '../../yagsl/java/' + } + } +} + def ROBOT_MAIN_CLASS = "frc.robot.Main" // Define my targets (RoboRIO) and artifacts (deployable files) @@ -34,7 +42,7 @@ deploy { files = project.fileTree('src/main/deploy') directory = '/home/lvuser/deploy' deleteOldFiles = false // Change to true to delete files on roboRIO that no - // longer exist in deploy directory of this project + // longer exist in deploy directory of this project } } } @@ -43,7 +51,8 @@ deploy { def deployArtifact = deploy.targets.roborio.artifacts.frcJava -// Set to true to use debug for JNI. +// Set to true to use debug for all targets including JNI, which will drastically impact +// performance. wpi.java.debugJni = false // Set this to true to enable desktop support. @@ -69,6 +78,7 @@ dependencies { nativeRelease wpi.java.deps.wpilibJniRelease(wpi.platforms.desktop) nativeRelease wpi.java.vendor.jniRelease(wpi.platforms.desktop) simulationRelease wpi.sim.enableRelease() + implementation 'org.dyn4j:dyn4j:5.0.2' testImplementation 'org.junit.jupiter:junit-jupiter:5.10.1' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' diff --git a/examples/full_example/settings.gradle b/examples/full_example/settings.gradle index 969c7b0..25f6f6e 100644 --- a/examples/full_example/settings.gradle +++ b/examples/full_example/settings.gradle @@ -4,7 +4,7 @@ pluginManagement { repositories { mavenLocal() gradlePluginPortal() - String frcYear = '2025' + String frcYear = '2026' File frcHome if (OperatingSystem.current().isWindows()) { String publicFolder = System.getenv('PUBLIC') @@ -20,8 +20,8 @@ pluginManagement { } def frcHomeMaven = new File(frcHome, 'maven') maven { - name 'frcHome' - url frcHomeMaven + name = 'frcHome' + url = frcHomeMaven } } } diff --git a/examples/full_example/vendordeps/PathplannerLib.json b/examples/full_example/vendordeps/PathplannerLib.json deleted file mode 100644 index c496379..0000000 --- a/examples/full_example/vendordeps/PathplannerLib.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "fileName": "PathplannerLib.json", - "name": "PathplannerLib", - "version": "2025.2.7", - "uuid": "1b42324f-17c6-4875-8e77-1c312bc8c786", - "frcYear": "2025", - "mavenUrls": [ - "https://3015rangerrobotics.github.io/pathplannerlib/repo" - ], - "jsonUrl": "https://3015rangerrobotics.github.io/pathplannerlib/PathplannerLib.json", - "javaDependencies": [ - { - "groupId": "com.pathplanner.lib", - "artifactId": "PathplannerLib-java", - "version": "2025.2.7" - } - ], - "jniDependencies": [], - "cppDependencies": [ - { - "groupId": "com.pathplanner.lib", - "artifactId": "PathplannerLib-cpp", - "version": "2025.2.7", - "libName": "PathplannerLib", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "osxuniversal", - "linuxathena", - "linuxarm32", - "linuxarm64" - ] - } - ] -} \ No newline at end of file diff --git a/examples/full_example/vendordeps/Phoenix5-frc2025-latest.json b/examples/full_example/vendordeps/Phoenix5-frc2025-latest.json deleted file mode 100644 index 3cbc8f6..0000000 --- a/examples/full_example/vendordeps/Phoenix5-frc2025-latest.json +++ /dev/null @@ -1,171 +0,0 @@ -{ - "fileName": "Phoenix5-frc2025-latest.json", - "name": "CTRE-Phoenix (v5)", - "version": "5.35.1", - "frcYear": "2025", - "uuid": "ab676553-b602-441f-a38d-f1296eff6537", - "mavenUrls": [ - "https://maven.ctr-electronics.com/release/" - ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-frc2025-latest.json", - "requires": [ - { - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", - "offlineFileName": "Phoenix6-frc2025-latest.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json" - } - ], - "conflictsWith": [ - { - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", - "errorMessage": "Users must use the Phoenix 5 replay vendordep when using the Phoenix 6 replay vendordep.", - "offlineFileName": "Phoenix6-replay-frc2025-latest.json" - }, - { - "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", - "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", - "offlineFileName": "Phoenix5-replay-frc2025-latest.json" - } - ], - "javaDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "api-java", - "version": "5.35.1" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "wpiapi-java", - "version": "5.35.1" - } - ], - "jniDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "cci", - "version": "5.35.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "cci-sim", - "version": "5.35.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ], - "cppDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "wpiapi-cpp", - "version": "5.35.1", - "libName": "CTRE_Phoenix_WPI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "api-cpp", - "version": "5.35.1", - "libName": "CTRE_Phoenix", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "cci", - "version": "5.35.1", - "libName": "CTRE_PhoenixCCI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "wpiapi-cpp-sim", - "version": "5.35.1", - "libName": "CTRE_Phoenix_WPISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "api-cpp-sim", - "version": "5.35.1", - "libName": "CTRE_PhoenixSim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "cci-sim", - "version": "5.35.1", - "libName": "CTRE_PhoenixCCISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ] -} \ No newline at end of file diff --git a/examples/full_example/vendordeps/Phoenix5-replay-5.36.0-beta-1.json b/examples/full_example/vendordeps/Phoenix5-replay-5.36.0-beta-1.json new file mode 100644 index 0000000..4a78551 --- /dev/null +++ b/examples/full_example/vendordeps/Phoenix5-replay-5.36.0-beta-1.json @@ -0,0 +1,221 @@ +{ + "fileName": "Phoenix5-replay-5.36.0-beta-1.json", + "name": "CTRE-Phoenix (v5)", + "version": "5.36.0-beta-1", + "frcYear": "2026beta", + "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", + "mavenUrls": [ + "https://maven.ctr-electronics.com/release/" + ], + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-beta-latest.json", + "requires": [ + { + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", + "offlineFileName": "Phoenix6-replay-frc2026-beta-latest.json", + "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json" + } + ], + "conflictsWith": [ + { + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "errorMessage": "Users must use the regular Phoenix 5 vendordep when using the regular Phoenix 6 vendordep.", + "offlineFileName": "Phoenix6-frc2026-beta-latest.json" + }, + { + "uuid": "ab676553-b602-441f-a38d-f1296eff6537", + "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", + "offlineFileName": "Phoenix5-frc2026-beta-latest.json" + } + ], + "javaDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-java", + "version": "5.36.0-beta-1" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-java", + "version": "5.36.0-beta-1" + } + ], + "jniDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "cci-replay", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ], + "cppDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-cpp", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-cpp", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "wpiapi-cpp-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "api-cpp-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "cci-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "wpiapi-cpp-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "api-cpp-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixSim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ] +} \ No newline at end of file diff --git a/examples/full_example/vendordeps/Phoenix6-frc2025-latest.json b/examples/full_example/vendordeps/Phoenix6-frc2025-latest.json deleted file mode 100644 index 6f40c84..0000000 --- a/examples/full_example/vendordeps/Phoenix6-frc2025-latest.json +++ /dev/null @@ -1,479 +0,0 @@ -{ - "fileName": "Phoenix6-frc2025-latest.json", - "name": "CTRE-Phoenix (v6)", - "version": "25.4.0", - "frcYear": "2025", - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "mavenUrls": [ - "https://maven.ctr-electronics.com/release/" - ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json", - "conflictsWith": [ - { - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", - "errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.", - "offlineFileName": "Phoenix6-replay-frc2025-latest.json" - } - ], - "javaDependencies": [ - { - "groupId": "com.ctre.phoenix6", - "artifactId": "wpiapi-java", - "version": "25.4.0" - } - ], - "jniDependencies": [ - { - "groupId": "com.ctre.phoenix6", - "artifactId": "api-cpp", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6", - "artifactId": "tools", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "api-cpp-sim", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "tools-sim", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simTalonSRX", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simVictorSPX", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simPigeonIMU", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simCANCoder", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFX", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFXS", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANcoder", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProPigeon2", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANrange", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANdi", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANdle", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ], - "cppDependencies": [ - { - "groupId": "com.ctre.phoenix6", - "artifactId": "wpiapi-cpp", - "version": "25.4.0", - "libName": "CTRE_Phoenix6_WPI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6", - "artifactId": "tools", - "version": "25.4.0", - "libName": "CTRE_PhoenixTools", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "wpiapi-cpp-sim", - "version": "25.4.0", - "libName": "CTRE_Phoenix6_WPISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "tools-sim", - "version": "25.4.0", - "libName": "CTRE_PhoenixTools_Sim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simTalonSRX", - "version": "25.4.0", - "libName": "CTRE_SimTalonSRX", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simVictorSPX", - "version": "25.4.0", - "libName": "CTRE_SimVictorSPX", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simPigeonIMU", - "version": "25.4.0", - "libName": "CTRE_SimPigeonIMU", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simCANCoder", - "version": "25.4.0", - "libName": "CTRE_SimCANCoder", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFX", - "version": "25.4.0", - "libName": "CTRE_SimProTalonFX", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFXS", - "version": "25.4.0", - "libName": "CTRE_SimProTalonFXS", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANcoder", - "version": "25.4.0", - "libName": "CTRE_SimProCANcoder", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProPigeon2", - "version": "25.4.0", - "libName": "CTRE_SimProPigeon2", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANrange", - "version": "25.4.0", - "libName": "CTRE_SimProCANrange", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANdi", - "version": "25.4.0", - "libName": "CTRE_SimProCANdi", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANdle", - "version": "25.4.0", - "libName": "CTRE_SimProCANdle", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ] -} \ No newline at end of file diff --git a/examples/full_example/vendordeps/Phoenix6-replay-26.0.0-beta-1.json b/examples/full_example/vendordeps/Phoenix6-replay-26.0.0-beta-1.json new file mode 100644 index 0000000..5312c86 --- /dev/null +++ b/examples/full_example/vendordeps/Phoenix6-replay-26.0.0-beta-1.json @@ -0,0 +1,453 @@ +{ + "fileName": "Phoenix6-replay-26.0.0-beta-1.json", + "name": "CTRE-Phoenix (v6) Replay", + "version": "26.0.0-beta-1", + "frcYear": "2026beta", + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "mavenUrls": [ + "https://maven.ctr-electronics.com/release/" + ], + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json", + "conflictsWith": [ + { + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.", + "offlineFileName": "Phoenix6-frc2026-beta-latest.json" + } + ], + "javaDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "wpiapi-java", + "version": "26.0.0-beta-1" + } + ], + "jniDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "api-cpp", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6", + "artifactId": "tools", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "api-cpp-replay", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "tools-replay", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "api-cpp-sim", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "tools-sim", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simTalonSRX", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simVictorSPX", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFX", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANcoder", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProPigeon2", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANrange", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdi", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdle", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ], + "cppDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "wpiapi-cpp", + "version": "26.0.0-beta-1", + "libName": "CTRE_Phoenix6_WPI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6", + "artifactId": "tools", + "version": "26.0.0-beta-1", + "libName": "CTRE_PhoenixTools", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "wpiapi-cpp-replay", + "version": "26.0.0-beta-1", + "libName": "CTRE_Phoenix6_WPIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "tools-replay", + "version": "26.0.0-beta-1", + "libName": "CTRE_PhoenixTools_Replay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "wpiapi-cpp-sim", + "version": "26.0.0-beta-1", + "libName": "CTRE_Phoenix6_WPISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "tools-sim", + "version": "26.0.0-beta-1", + "libName": "CTRE_PhoenixTools_Sim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simTalonSRX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimTalonSRX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simVictorSPX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimVictorSPX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simPigeonIMU", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimPigeonIMU", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProTalonFX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANcoder", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProCANcoder", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProPigeon2", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProPigeon2", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANrange", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProCANrange", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdi", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProCANdi", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdle", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProCANdle", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ] +} \ No newline at end of file diff --git a/examples/full_example/vendordeps/REVLib.json b/examples/full_example/vendordeps/REVLib.json index 5546ea8..0f666c9 100644 --- a/examples/full_example/vendordeps/REVLib.json +++ b/examples/full_example/vendordeps/REVLib.json @@ -1,25 +1,55 @@ { "fileName": "REVLib.json", "name": "REVLib", - "version": "2025.0.3", - "frcYear": "2025", + "version": "2026.0.0-beta-1", + "frcYear": "2026beta", "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", "mavenUrls": [ "https://maven.revrobotics.com/" ], - "jsonUrl": "https://software-metadata.revrobotics.com/REVLib-2025.json", + "jsonUrl": "https://software-metadata.revrobotics.com/REVLib-2026.json", "javaDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-java", - "version": "2025.0.3" + "version": "2026.0.0-beta-1" } ], "jniDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibBackendDriver", + "version": "2026.0.0-beta-1", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibWpiBackendDriver", + "version": "2026.0.0-beta-1", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -36,7 +66,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-cpp", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", "libName": "REVLib", "headerClassifier": "headers", "sharedLibrary": false, @@ -53,7 +83,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", "libName": "REVLibDriver", "headerClassifier": "headers", "sharedLibrary": false, @@ -66,6 +96,38 @@ "linuxarm32", "osxuniversal" ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibBackendDriver", + "version": "2026.0.0-beta-1", + "libName": "BackendDriver", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibWpiBackendDriver", + "version": "2026.0.0-beta-1", + "libName": "REVLibWpi", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] } ] } \ No newline at end of file diff --git a/examples/full_example/vendordeps/ReduxLib-2025.0.1.json b/examples/full_example/vendordeps/ReduxLib-2025.0.1.json deleted file mode 100644 index 007f97f..0000000 --- a/examples/full_example/vendordeps/ReduxLib-2025.0.1.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "fileName": "ReduxLib-2025.0.1.json", - "name": "ReduxLib", - "version": "2025.0.1", - "frcYear": "2025", - "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", - "mavenUrls": [ - "https://maven.reduxrobotics.com/" - ], - "jsonUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2025.json", - "javaDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-java", - "version": "2025.0.1" - } - ], - "jniDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-driver", - "version": "2025.0.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - } - ], - "cppDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-cpp", - "version": "2025.0.1", - "libName": "ReduxLib", - "headerClassifier": "headers", - "sourcesClassifier": "sources", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - }, - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-driver", - "version": "2025.0.1", - "libName": "ReduxCore", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - } - ] -} \ No newline at end of file diff --git a/examples/full_example/vendordeps/Studica-2025.0.1.json b/examples/full_example/vendordeps/Studica-2025.0.1.json deleted file mode 100644 index e0b50d7..0000000 --- a/examples/full_example/vendordeps/Studica-2025.0.1.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "Studica-2025.0.1.json", - "name": "Studica", - "version": "2025.0.1", - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", - "frcYear": "2025", - "mavenUrls": [ - "https://dev.studica.com/maven/release/2025/" - ], - "jsonUrl": "https://dev.studica.com/releases/2025/Studica-2025.0.1.json", - "cppDependencies": [ - { - "artifactId": "Studica-cpp", - "binaryPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "groupId": "com.studica.frc", - "headerClassifier": "headers", - "libName": "Studica", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "version": "2025.0.1" - }, - { - "artifactId": "Studica-driver", - "binaryPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "groupId": "com.studica.frc", - "headerClassifier": "headers", - "libName": "StudicaDriver", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "version": "2025.0.1" - } - ], - "javaDependencies": [ - { - "artifactId": "Studica-java", - "groupId": "com.studica.frc", - "version": "2025.0.1" - } - ], - "jniDependencies": [ - { - "artifactId": "Studica-driver", - "groupId": "com.studica.frc", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "version": "2025.0.1" - } - ] -} \ No newline at end of file diff --git a/examples/full_example/vendordeps/Studica-2026.0.0-beta.json b/examples/full_example/vendordeps/Studica-2026.0.0-beta.json new file mode 100644 index 0000000..c5d48c7 --- /dev/null +++ b/examples/full_example/vendordeps/Studica-2026.0.0-beta.json @@ -0,0 +1,71 @@ +{ + "fileName": "Studica-2026.0.0-beta.json", + "name": "Studica", + "version": "2026.0.0-beta", + "frcYear": "2026beta", + "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0-beta.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-java", + "version": "2026.0.0-beta" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0-beta", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-cpp", + "version": "2026.0.0-beta", + "libName": "Studica", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0-beta", + "libName": "StudicaDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/examples/full_example/vendordeps/StudicaLib.json b/examples/full_example/vendordeps/StudicaLib.json new file mode 100644 index 0000000..b6ed33e --- /dev/null +++ b/examples/full_example/vendordeps/StudicaLib.json @@ -0,0 +1,71 @@ +{ + "fileName": "StudicaLib.json", + "name": "StudicaLib", + "version": "2026.0.1-beta", + "frcYear": "2026beta", + "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.1-beta.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-java", + "version": "2026.0.1-beta" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.1-beta", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-cpp", + "version": "2026.0.1-beta", + "libName": "StudicaLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.1-beta", + "libName": "StudicaLibDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/examples/full_example/vendordeps/ThriftyLib.json b/examples/full_example/vendordeps/ThriftyLib.json index 887721f..1e59797 100644 --- a/examples/full_example/vendordeps/ThriftyLib.json +++ b/examples/full_example/vendordeps/ThriftyLib.json @@ -1,8 +1,8 @@ { "fileName": "ThriftyLib.json", "name": "ThriftyLib", - "version": "2025.1.1", - "frcYear": "2025", + "version": "2026.0.0", + "frcYear": "2026beta", "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", "mavenUrls": [ "https://docs.home.thethriftybot.com" @@ -12,9 +12,9 @@ { "groupId": "com.thethriftybot.frc", "artifactId": "ThriftyLib-java", - "version": "2025.1.1" + "version": "2026.0.0" } ], "jniDependencies": [], "cppDependencies": [] -} \ No newline at end of file +} diff --git a/examples/full_example/vendordeps/WPILibNewCommands.json b/examples/full_example/vendordeps/WPILibNewCommands.json index 3718e0a..7ebc954 100644 --- a/examples/full_example/vendordeps/WPILibNewCommands.json +++ b/examples/full_example/vendordeps/WPILibNewCommands.json @@ -3,7 +3,7 @@ "name": "WPILib-New-Commands", "version": "1.0.0", "uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266", - "frcYear": "2025", + "frcYear": "2026beta", "mavenUrls": [], "jsonUrl": "", "javaDependencies": [ @@ -25,6 +25,7 @@ "sharedLibrary": true, "skipInvalidPlatforms": true, "binaryPlatforms": [ + "linuxsystemcore", "linuxathena", "linuxarm32", "linuxarm64", diff --git a/examples/full_example/vendordeps/maple-sim.json b/examples/full_example/vendordeps/maple-sim.json deleted file mode 100644 index 73c812f..0000000 --- a/examples/full_example/vendordeps/maple-sim.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "fileName": "maple-sim.json", - "name": "maplesim", - "version": "0.3.14", - "frcYear": "2025", - "uuid": "c39481e8-4a63-4a4c-9df6-48d91e4da37b", - "mavenUrls": [ - "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/repos/releases", - "https://repo1.maven.org/maven2" - ], - "jsonUrl": "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/maple-sim.json", - "javaDependencies": [ - { - "groupId": "org.ironmaple", - "artifactId": "maplesim-java", - "version": "0.3.14" - }, - { - "groupId": "org.dyn4j", - "artifactId": "dyn4j", - "version": "5.0.2" - } - ], - "jniDependencies": [], - "cppDependencies": [] -} \ No newline at end of file diff --git a/examples/full_example/vendordeps/photonlib.json b/examples/full_example/vendordeps/photonlib.json deleted file mode 100644 index 5c6484d..0000000 --- a/examples/full_example/vendordeps/photonlib.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "photonlib.json", - "name": "photonlib", - "version": "v2025.3.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.3.1", - "skipInvalidPlatforms": true, - "isJar": false, - "validPlatforms": [ - "windowsx86-64", - "linuxathena", - "linuxx86-64", - "osxuniversal" - ] - } - ], - "cppDependencies": [ - { - "groupId": "org.photonvision", - "artifactId": "photonlib-cpp", - "version": "v2025.3.1", - "libName": "photonlib", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxathena", - "linuxx86-64", - "osxuniversal" - ] - }, - { - "groupId": "org.photonvision", - "artifactId": "photontargeting-cpp", - "version": "v2025.3.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.3.1" - }, - { - "groupId": "org.photonvision", - "artifactId": "photontargeting-java", - "version": "v2025.3.1" - } - ] -} \ No newline at end of file diff --git a/examples/full_example/vendordeps/yagsl-2025.7.2.json b/examples/full_example/vendordeps/yagsl-2025.7.2.json deleted file mode 100644 index 9fb6a48..0000000 --- a/examples/full_example/vendordeps/yagsl-2025.7.2.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "fileName": "yagsl-2025.7.2.json", - "name": "YAGSL", - "version": "2025.7.2", - "frcYear": "2025", - "uuid": "1ccce5a4-acd2-4d18-bca3-4b8047188400", - "mavenUrls": [ - "https://broncbotz3481.github.io/YAGSL-Lib/yagsl/repos" - ], - "jsonUrl": "https://broncbotz3481.github.io/YAGSL-Lib/yagsl/yagsl.json", - "javaDependencies": [ - { - "groupId": "swervelib", - "artifactId": "YAGSL-java", - "version": "2025.7.2" - } - ], - "requires": [ - { - "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", - "errorMessage": "REVLib is required!", - "offlineFileName": "REVLib-2025.0.0.json", - "onlineUrl": "https://software-metadata.revrobotics.com/REVLib-2025.json" - }, - { - "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", - "errorMessage": "ReduxLib is required!", - "offlineFileName": "ReduxLib-2025.0.0.json", - "onlineUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2025.json" - }, - { - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "errorMessage": "Phoenix6 is required!", - "offlineFileName": "Phoenix6-25.1.0.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json" - }, - { - "uuid": "ab676553-b602-441f-a38d-f1296eff6537", - "errorMessage": "Phoenix5 is required!", - "offlineFileName": "Phoenix5-5.35.0.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-frc2025-latest.json" - }, - { - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", - "errorMessage": "Studica is required!", - "offlineFileName": "Studica-2025.0.0.json", - "onlineUrl": "https://dev.studica.com/releases/2025/Studica-2025.0.0.json" - }, - { - "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", - "errorMessage": "ThriftyLib is required!", - "offlineFileName": "ThriftyLib.json", - "onlineUrl": "https://docs.home.thethriftybot.com/ThriftyLib.json" - }, - { - "uuid": "c39481e8-4a63-4a4c-9df6-48d91e4da37b", - "errorMessage": "maple-sim is required for simulation", - "offlineFileName": "maple-sim.json", - "onlineUrl": "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/maple-sim.json" - } - ], - "jniDependencies": [], - "cppDependencies": [] -} \ No newline at end of file diff --git a/examples/robot_relative_drivebase/.wpilib/wpilib_preferences.json b/examples/robot_relative_drivebase/.wpilib/wpilib_preferences.json index 83517dd..f727ea3 100644 --- a/examples/robot_relative_drivebase/.wpilib/wpilib_preferences.json +++ b/examples/robot_relative_drivebase/.wpilib/wpilib_preferences.json @@ -1,6 +1,6 @@ { "enableCppIntellisense": false, "currentLanguage": "java", - "projectYear": "2025", + "projectYear": "2026beta", "teamNumber": 3481 } \ No newline at end of file diff --git a/examples/robot_relative_drivebase/build.gradle b/examples/robot_relative_drivebase/build.gradle index fdf6d52..4233229 100644 --- a/examples/robot_relative_drivebase/build.gradle +++ b/examples/robot_relative_drivebase/build.gradle @@ -1,6 +1,6 @@ plugins { id "java" - id "edu.wpi.first.GradleRIO" version "2025.3.1" + id "edu.wpi.first.GradleRIO" version "2026.1.1-beta-1" } java { @@ -8,6 +8,14 @@ java { targetCompatibility = JavaVersion.VERSION_17 } +sourceSets { + main { + java { + srcDir '../../yagsl/java/' + } + } +} + def ROBOT_MAIN_CLASS = "frc.robot.Main" // Define my targets (RoboRIO) and artifacts (deployable files) @@ -34,7 +42,7 @@ deploy { files = project.fileTree('src/main/deploy') directory = '/home/lvuser/deploy' deleteOldFiles = false // Change to true to delete files on roboRIO that no - // longer exist in deploy directory of this project + // longer exist in deploy directory of this project } } } @@ -43,7 +51,8 @@ deploy { def deployArtifact = deploy.targets.roborio.artifacts.frcJava -// Set to true to use debug for JNI. +// Set to true to use debug for all targets including JNI, which will drastically impact +// performance. wpi.java.debugJni = false // Set this to true to enable desktop support. @@ -69,6 +78,7 @@ dependencies { nativeRelease wpi.java.deps.wpilibJniRelease(wpi.platforms.desktop) nativeRelease wpi.java.vendor.jniRelease(wpi.platforms.desktop) simulationRelease wpi.sim.enableRelease() + implementation 'org.dyn4j:dyn4j:5.0.2' testImplementation 'org.junit.jupiter:junit-jupiter:5.10.1' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' diff --git a/examples/robot_relative_drivebase/settings.gradle b/examples/robot_relative_drivebase/settings.gradle index 969c7b0..25f6f6e 100644 --- a/examples/robot_relative_drivebase/settings.gradle +++ b/examples/robot_relative_drivebase/settings.gradle @@ -4,7 +4,7 @@ pluginManagement { repositories { mavenLocal() gradlePluginPortal() - String frcYear = '2025' + String frcYear = '2026' File frcHome if (OperatingSystem.current().isWindows()) { String publicFolder = System.getenv('PUBLIC') @@ -20,8 +20,8 @@ pluginManagement { } def frcHomeMaven = new File(frcHome, 'maven') maven { - name 'frcHome' - url frcHomeMaven + name = 'frcHome' + url = frcHomeMaven } } } diff --git a/examples/robot_relative_drivebase/vendordeps/Phoenix5-frc2025-latest.json b/examples/robot_relative_drivebase/vendordeps/Phoenix5-frc2025-latest.json deleted file mode 100644 index 3cbc8f6..0000000 --- a/examples/robot_relative_drivebase/vendordeps/Phoenix5-frc2025-latest.json +++ /dev/null @@ -1,171 +0,0 @@ -{ - "fileName": "Phoenix5-frc2025-latest.json", - "name": "CTRE-Phoenix (v5)", - "version": "5.35.1", - "frcYear": "2025", - "uuid": "ab676553-b602-441f-a38d-f1296eff6537", - "mavenUrls": [ - "https://maven.ctr-electronics.com/release/" - ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-frc2025-latest.json", - "requires": [ - { - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", - "offlineFileName": "Phoenix6-frc2025-latest.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json" - } - ], - "conflictsWith": [ - { - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", - "errorMessage": "Users must use the Phoenix 5 replay vendordep when using the Phoenix 6 replay vendordep.", - "offlineFileName": "Phoenix6-replay-frc2025-latest.json" - }, - { - "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", - "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", - "offlineFileName": "Phoenix5-replay-frc2025-latest.json" - } - ], - "javaDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "api-java", - "version": "5.35.1" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "wpiapi-java", - "version": "5.35.1" - } - ], - "jniDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "cci", - "version": "5.35.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "cci-sim", - "version": "5.35.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ], - "cppDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "wpiapi-cpp", - "version": "5.35.1", - "libName": "CTRE_Phoenix_WPI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "api-cpp", - "version": "5.35.1", - "libName": "CTRE_Phoenix", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "cci", - "version": "5.35.1", - "libName": "CTRE_PhoenixCCI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "wpiapi-cpp-sim", - "version": "5.35.1", - "libName": "CTRE_Phoenix_WPISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "api-cpp-sim", - "version": "5.35.1", - "libName": "CTRE_PhoenixSim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "cci-sim", - "version": "5.35.1", - "libName": "CTRE_PhoenixCCISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ] -} \ No newline at end of file diff --git a/examples/robot_relative_drivebase/vendordeps/Phoenix5-replay-5.36.0-beta-1.json b/examples/robot_relative_drivebase/vendordeps/Phoenix5-replay-5.36.0-beta-1.json new file mode 100644 index 0000000..4a78551 --- /dev/null +++ b/examples/robot_relative_drivebase/vendordeps/Phoenix5-replay-5.36.0-beta-1.json @@ -0,0 +1,221 @@ +{ + "fileName": "Phoenix5-replay-5.36.0-beta-1.json", + "name": "CTRE-Phoenix (v5)", + "version": "5.36.0-beta-1", + "frcYear": "2026beta", + "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", + "mavenUrls": [ + "https://maven.ctr-electronics.com/release/" + ], + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-beta-latest.json", + "requires": [ + { + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", + "offlineFileName": "Phoenix6-replay-frc2026-beta-latest.json", + "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json" + } + ], + "conflictsWith": [ + { + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "errorMessage": "Users must use the regular Phoenix 5 vendordep when using the regular Phoenix 6 vendordep.", + "offlineFileName": "Phoenix6-frc2026-beta-latest.json" + }, + { + "uuid": "ab676553-b602-441f-a38d-f1296eff6537", + "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", + "offlineFileName": "Phoenix5-frc2026-beta-latest.json" + } + ], + "javaDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-java", + "version": "5.36.0-beta-1" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-java", + "version": "5.36.0-beta-1" + } + ], + "jniDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "cci-replay", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ], + "cppDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-cpp", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-cpp", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "wpiapi-cpp-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "api-cpp-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "cci-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "wpiapi-cpp-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "api-cpp-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixSim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ] +} \ No newline at end of file diff --git a/examples/robot_relative_drivebase/vendordeps/Phoenix6-frc2025-latest.json b/examples/robot_relative_drivebase/vendordeps/Phoenix6-frc2025-latest.json deleted file mode 100644 index 6f40c84..0000000 --- a/examples/robot_relative_drivebase/vendordeps/Phoenix6-frc2025-latest.json +++ /dev/null @@ -1,479 +0,0 @@ -{ - "fileName": "Phoenix6-frc2025-latest.json", - "name": "CTRE-Phoenix (v6)", - "version": "25.4.0", - "frcYear": "2025", - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "mavenUrls": [ - "https://maven.ctr-electronics.com/release/" - ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json", - "conflictsWith": [ - { - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", - "errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.", - "offlineFileName": "Phoenix6-replay-frc2025-latest.json" - } - ], - "javaDependencies": [ - { - "groupId": "com.ctre.phoenix6", - "artifactId": "wpiapi-java", - "version": "25.4.0" - } - ], - "jniDependencies": [ - { - "groupId": "com.ctre.phoenix6", - "artifactId": "api-cpp", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6", - "artifactId": "tools", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "api-cpp-sim", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "tools-sim", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simTalonSRX", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simVictorSPX", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simPigeonIMU", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simCANCoder", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFX", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFXS", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANcoder", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProPigeon2", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANrange", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANdi", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANdle", - "version": "25.4.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ], - "cppDependencies": [ - { - "groupId": "com.ctre.phoenix6", - "artifactId": "wpiapi-cpp", - "version": "25.4.0", - "libName": "CTRE_Phoenix6_WPI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6", - "artifactId": "tools", - "version": "25.4.0", - "libName": "CTRE_PhoenixTools", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "wpiapi-cpp-sim", - "version": "25.4.0", - "libName": "CTRE_Phoenix6_WPISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "tools-sim", - "version": "25.4.0", - "libName": "CTRE_PhoenixTools_Sim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simTalonSRX", - "version": "25.4.0", - "libName": "CTRE_SimTalonSRX", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simVictorSPX", - "version": "25.4.0", - "libName": "CTRE_SimVictorSPX", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simPigeonIMU", - "version": "25.4.0", - "libName": "CTRE_SimPigeonIMU", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simCANCoder", - "version": "25.4.0", - "libName": "CTRE_SimCANCoder", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFX", - "version": "25.4.0", - "libName": "CTRE_SimProTalonFX", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFXS", - "version": "25.4.0", - "libName": "CTRE_SimProTalonFXS", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANcoder", - "version": "25.4.0", - "libName": "CTRE_SimProCANcoder", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProPigeon2", - "version": "25.4.0", - "libName": "CTRE_SimProPigeon2", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANrange", - "version": "25.4.0", - "libName": "CTRE_SimProCANrange", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANdi", - "version": "25.4.0", - "libName": "CTRE_SimProCANdi", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANdle", - "version": "25.4.0", - "libName": "CTRE_SimProCANdle", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ] -} \ No newline at end of file diff --git a/examples/robot_relative_drivebase/vendordeps/Phoenix6-replay-26.0.0-beta-1.json b/examples/robot_relative_drivebase/vendordeps/Phoenix6-replay-26.0.0-beta-1.json new file mode 100644 index 0000000..5312c86 --- /dev/null +++ b/examples/robot_relative_drivebase/vendordeps/Phoenix6-replay-26.0.0-beta-1.json @@ -0,0 +1,453 @@ +{ + "fileName": "Phoenix6-replay-26.0.0-beta-1.json", + "name": "CTRE-Phoenix (v6) Replay", + "version": "26.0.0-beta-1", + "frcYear": "2026beta", + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "mavenUrls": [ + "https://maven.ctr-electronics.com/release/" + ], + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json", + "conflictsWith": [ + { + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.", + "offlineFileName": "Phoenix6-frc2026-beta-latest.json" + } + ], + "javaDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "wpiapi-java", + "version": "26.0.0-beta-1" + } + ], + "jniDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "api-cpp", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6", + "artifactId": "tools", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "api-cpp-replay", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "tools-replay", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "api-cpp-sim", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "tools-sim", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simTalonSRX", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simVictorSPX", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFX", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANcoder", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProPigeon2", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANrange", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdi", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdle", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ], + "cppDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "wpiapi-cpp", + "version": "26.0.0-beta-1", + "libName": "CTRE_Phoenix6_WPI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6", + "artifactId": "tools", + "version": "26.0.0-beta-1", + "libName": "CTRE_PhoenixTools", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "wpiapi-cpp-replay", + "version": "26.0.0-beta-1", + "libName": "CTRE_Phoenix6_WPIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "tools-replay", + "version": "26.0.0-beta-1", + "libName": "CTRE_PhoenixTools_Replay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "wpiapi-cpp-sim", + "version": "26.0.0-beta-1", + "libName": "CTRE_Phoenix6_WPISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "tools-sim", + "version": "26.0.0-beta-1", + "libName": "CTRE_PhoenixTools_Sim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simTalonSRX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimTalonSRX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simVictorSPX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimVictorSPX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simPigeonIMU", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimPigeonIMU", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProTalonFX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANcoder", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProCANcoder", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProPigeon2", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProPigeon2", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANrange", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProCANrange", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdi", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProCANdi", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdle", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProCANdle", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ] +} \ No newline at end of file diff --git a/examples/robot_relative_drivebase/vendordeps/REVLib.json b/examples/robot_relative_drivebase/vendordeps/REVLib.json index 5546ea8..0f666c9 100644 --- a/examples/robot_relative_drivebase/vendordeps/REVLib.json +++ b/examples/robot_relative_drivebase/vendordeps/REVLib.json @@ -1,25 +1,55 @@ { "fileName": "REVLib.json", "name": "REVLib", - "version": "2025.0.3", - "frcYear": "2025", + "version": "2026.0.0-beta-1", + "frcYear": "2026beta", "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", "mavenUrls": [ "https://maven.revrobotics.com/" ], - "jsonUrl": "https://software-metadata.revrobotics.com/REVLib-2025.json", + "jsonUrl": "https://software-metadata.revrobotics.com/REVLib-2026.json", "javaDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-java", - "version": "2025.0.3" + "version": "2026.0.0-beta-1" } ], "jniDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibBackendDriver", + "version": "2026.0.0-beta-1", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibWpiBackendDriver", + "version": "2026.0.0-beta-1", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -36,7 +66,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-cpp", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", "libName": "REVLib", "headerClassifier": "headers", "sharedLibrary": false, @@ -53,7 +83,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", "libName": "REVLibDriver", "headerClassifier": "headers", "sharedLibrary": false, @@ -66,6 +96,38 @@ "linuxarm32", "osxuniversal" ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibBackendDriver", + "version": "2026.0.0-beta-1", + "libName": "BackendDriver", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibWpiBackendDriver", + "version": "2026.0.0-beta-1", + "libName": "REVLibWpi", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] } ] } \ No newline at end of file diff --git a/examples/robot_relative_drivebase/vendordeps/ReduxLib-2025.0.1.json b/examples/robot_relative_drivebase/vendordeps/ReduxLib-2025.0.1.json deleted file mode 100644 index 007f97f..0000000 --- a/examples/robot_relative_drivebase/vendordeps/ReduxLib-2025.0.1.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "fileName": "ReduxLib-2025.0.1.json", - "name": "ReduxLib", - "version": "2025.0.1", - "frcYear": "2025", - "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", - "mavenUrls": [ - "https://maven.reduxrobotics.com/" - ], - "jsonUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2025.json", - "javaDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-java", - "version": "2025.0.1" - } - ], - "jniDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-driver", - "version": "2025.0.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - } - ], - "cppDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-cpp", - "version": "2025.0.1", - "libName": "ReduxLib", - "headerClassifier": "headers", - "sourcesClassifier": "sources", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - }, - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-driver", - "version": "2025.0.1", - "libName": "ReduxCore", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - } - ] -} \ No newline at end of file diff --git a/examples/robot_relative_drivebase/vendordeps/Studica-2025.0.1.json b/examples/robot_relative_drivebase/vendordeps/Studica-2025.0.1.json deleted file mode 100644 index e0b50d7..0000000 --- a/examples/robot_relative_drivebase/vendordeps/Studica-2025.0.1.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "Studica-2025.0.1.json", - "name": "Studica", - "version": "2025.0.1", - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", - "frcYear": "2025", - "mavenUrls": [ - "https://dev.studica.com/maven/release/2025/" - ], - "jsonUrl": "https://dev.studica.com/releases/2025/Studica-2025.0.1.json", - "cppDependencies": [ - { - "artifactId": "Studica-cpp", - "binaryPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "groupId": "com.studica.frc", - "headerClassifier": "headers", - "libName": "Studica", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "version": "2025.0.1" - }, - { - "artifactId": "Studica-driver", - "binaryPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "groupId": "com.studica.frc", - "headerClassifier": "headers", - "libName": "StudicaDriver", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "version": "2025.0.1" - } - ], - "javaDependencies": [ - { - "artifactId": "Studica-java", - "groupId": "com.studica.frc", - "version": "2025.0.1" - } - ], - "jniDependencies": [ - { - "artifactId": "Studica-driver", - "groupId": "com.studica.frc", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "version": "2025.0.1" - } - ] -} \ No newline at end of file diff --git a/examples/robot_relative_drivebase/vendordeps/Studica-2026.0.0-beta.json b/examples/robot_relative_drivebase/vendordeps/Studica-2026.0.0-beta.json new file mode 100644 index 0000000..c5d48c7 --- /dev/null +++ b/examples/robot_relative_drivebase/vendordeps/Studica-2026.0.0-beta.json @@ -0,0 +1,71 @@ +{ + "fileName": "Studica-2026.0.0-beta.json", + "name": "Studica", + "version": "2026.0.0-beta", + "frcYear": "2026beta", + "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0-beta.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-java", + "version": "2026.0.0-beta" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0-beta", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-cpp", + "version": "2026.0.0-beta", + "libName": "Studica", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0-beta", + "libName": "StudicaDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/examples/robot_relative_drivebase/vendordeps/StudicaLib.json b/examples/robot_relative_drivebase/vendordeps/StudicaLib.json new file mode 100644 index 0000000..b6ed33e --- /dev/null +++ b/examples/robot_relative_drivebase/vendordeps/StudicaLib.json @@ -0,0 +1,71 @@ +{ + "fileName": "StudicaLib.json", + "name": "StudicaLib", + "version": "2026.0.1-beta", + "frcYear": "2026beta", + "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.1-beta.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-java", + "version": "2026.0.1-beta" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.1-beta", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-cpp", + "version": "2026.0.1-beta", + "libName": "StudicaLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.1-beta", + "libName": "StudicaLibDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/examples/robot_relative_drivebase/vendordeps/ThriftyLib.json b/examples/robot_relative_drivebase/vendordeps/ThriftyLib.json index 887721f..1e59797 100644 --- a/examples/robot_relative_drivebase/vendordeps/ThriftyLib.json +++ b/examples/robot_relative_drivebase/vendordeps/ThriftyLib.json @@ -1,8 +1,8 @@ { "fileName": "ThriftyLib.json", "name": "ThriftyLib", - "version": "2025.1.1", - "frcYear": "2025", + "version": "2026.0.0", + "frcYear": "2026beta", "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", "mavenUrls": [ "https://docs.home.thethriftybot.com" @@ -12,9 +12,9 @@ { "groupId": "com.thethriftybot.frc", "artifactId": "ThriftyLib-java", - "version": "2025.1.1" + "version": "2026.0.0" } ], "jniDependencies": [], "cppDependencies": [] -} \ No newline at end of file +} diff --git a/examples/robot_relative_drivebase/vendordeps/WPILibNewCommands.json b/examples/robot_relative_drivebase/vendordeps/WPILibNewCommands.json index 3718e0a..7ebc954 100644 --- a/examples/robot_relative_drivebase/vendordeps/WPILibNewCommands.json +++ b/examples/robot_relative_drivebase/vendordeps/WPILibNewCommands.json @@ -3,7 +3,7 @@ "name": "WPILib-New-Commands", "version": "1.0.0", "uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266", - "frcYear": "2025", + "frcYear": "2026beta", "mavenUrls": [], "jsonUrl": "", "javaDependencies": [ @@ -25,6 +25,7 @@ "sharedLibrary": true, "skipInvalidPlatforms": true, "binaryPlatforms": [ + "linuxsystemcore", "linuxathena", "linuxarm32", "linuxarm64", diff --git a/examples/robot_relative_drivebase/vendordeps/maple-sim.json b/examples/robot_relative_drivebase/vendordeps/maple-sim.json deleted file mode 100644 index 73c812f..0000000 --- a/examples/robot_relative_drivebase/vendordeps/maple-sim.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "fileName": "maple-sim.json", - "name": "maplesim", - "version": "0.3.14", - "frcYear": "2025", - "uuid": "c39481e8-4a63-4a4c-9df6-48d91e4da37b", - "mavenUrls": [ - "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/repos/releases", - "https://repo1.maven.org/maven2" - ], - "jsonUrl": "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/maple-sim.json", - "javaDependencies": [ - { - "groupId": "org.ironmaple", - "artifactId": "maplesim-java", - "version": "0.3.14" - }, - { - "groupId": "org.dyn4j", - "artifactId": "dyn4j", - "version": "5.0.2" - } - ], - "jniDependencies": [], - "cppDependencies": [] -} \ No newline at end of file diff --git a/examples/robot_relative_drivebase/vendordeps/photonlib.json b/examples/robot_relative_drivebase/vendordeps/photonlib.json deleted file mode 100644 index 5c6484d..0000000 --- a/examples/robot_relative_drivebase/vendordeps/photonlib.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "photonlib.json", - "name": "photonlib", - "version": "v2025.3.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.3.1", - "skipInvalidPlatforms": true, - "isJar": false, - "validPlatforms": [ - "windowsx86-64", - "linuxathena", - "linuxx86-64", - "osxuniversal" - ] - } - ], - "cppDependencies": [ - { - "groupId": "org.photonvision", - "artifactId": "photonlib-cpp", - "version": "v2025.3.1", - "libName": "photonlib", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxathena", - "linuxx86-64", - "osxuniversal" - ] - }, - { - "groupId": "org.photonvision", - "artifactId": "photontargeting-cpp", - "version": "v2025.3.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.3.1" - }, - { - "groupId": "org.photonvision", - "artifactId": "photontargeting-java", - "version": "v2025.3.1" - } - ] -} \ No newline at end of file diff --git a/examples/robot_relative_drivebase/vendordeps/yagsl-2025.7.2.json b/examples/robot_relative_drivebase/vendordeps/yagsl-2025.7.2.json deleted file mode 100644 index 9fb6a48..0000000 --- a/examples/robot_relative_drivebase/vendordeps/yagsl-2025.7.2.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "fileName": "yagsl-2025.7.2.json", - "name": "YAGSL", - "version": "2025.7.2", - "frcYear": "2025", - "uuid": "1ccce5a4-acd2-4d18-bca3-4b8047188400", - "mavenUrls": [ - "https://broncbotz3481.github.io/YAGSL-Lib/yagsl/repos" - ], - "jsonUrl": "https://broncbotz3481.github.io/YAGSL-Lib/yagsl/yagsl.json", - "javaDependencies": [ - { - "groupId": "swervelib", - "artifactId": "YAGSL-java", - "version": "2025.7.2" - } - ], - "requires": [ - { - "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", - "errorMessage": "REVLib is required!", - "offlineFileName": "REVLib-2025.0.0.json", - "onlineUrl": "https://software-metadata.revrobotics.com/REVLib-2025.json" - }, - { - "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", - "errorMessage": "ReduxLib is required!", - "offlineFileName": "ReduxLib-2025.0.0.json", - "onlineUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2025.json" - }, - { - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "errorMessage": "Phoenix6 is required!", - "offlineFileName": "Phoenix6-25.1.0.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json" - }, - { - "uuid": "ab676553-b602-441f-a38d-f1296eff6537", - "errorMessage": "Phoenix5 is required!", - "offlineFileName": "Phoenix5-5.35.0.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-frc2025-latest.json" - }, - { - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", - "errorMessage": "Studica is required!", - "offlineFileName": "Studica-2025.0.0.json", - "onlineUrl": "https://dev.studica.com/releases/2025/Studica-2025.0.0.json" - }, - { - "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", - "errorMessage": "ThriftyLib is required!", - "offlineFileName": "ThriftyLib.json", - "onlineUrl": "https://docs.home.thethriftybot.com/ThriftyLib.json" - }, - { - "uuid": "c39481e8-4a63-4a4c-9df6-48d91e4da37b", - "errorMessage": "maple-sim is required for simulation", - "offlineFileName": "maple-sim.json", - "onlineUrl": "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/maple-sim.json" - } - ], - "jniDependencies": [], - "cppDependencies": [] -} \ No newline at end of file diff --git a/vendordep/build.gradle b/vendordep/build.gradle index 28fdf2c..ad96031 100644 --- a/vendordep/build.gradle +++ b/vendordep/build.gradle @@ -3,14 +3,14 @@ plugins { id 'java' id 'google-test' id 'edu.wpi.first.wpilib.repositories.WPILibRepositoriesPlugin' version '2025.0' - id 'edu.wpi.first.NativeUtils' version '2025.9.0' + id 'edu.wpi.first.NativeUtils' version '2026.0.1' + id "edu.wpi.first.GradleRIO" version "2026.1.1-beta-1" // Version supplied here id 'edu.wpi.first.GradleJni' version '1.1.0' id 'edu.wpi.first.GradleVsCode' version '2.1.0' - id "edu.wpi.first.GradleRIO" version "2025.3.1" // Version should be defined here. id "com.diffplug.spotless" version "6.11.0" } -ext.wpilibVersion = "2025.3.1" // and again here, thanks gradle.... +ext.wpilibVersion = "2026.1.1-beta-1" // and again here, thanks gradle.... ext.releasePath = "$buildDir/maven" ext.pubVersion = System.getenv("releaseVersion") ?: System.getenv("releaseName") ?: "test" @@ -34,11 +34,11 @@ sourceSets { srcDir "$rootDir/../yagsl/java/" } } -// test { -// java { -// srcDir "src/test/java" -// } -// } + // test { + // java { + // srcDir "src/test/java" + // } + // } } var javaVersion = "17" @@ -51,6 +51,7 @@ dependencies { // implementation wpi.java.deps.wpilib() implementation wpi.java.vendor.java() + implementation 'org.dyn4j:dyn4j:5.0.2' implementation "edu.wpi.first.cscore:cscore-java:$wpilibVersion" implementation "edu.wpi.first.cameraserver:cameraserver-java:$wpilibVersion" implementation "edu.wpi.first.ntcore:ntcore-java:$wpilibVersion" @@ -59,10 +60,10 @@ dependencies { implementation "edu.wpi.first.wpimath:wpimath-java:$wpilibVersion" implementation "edu.wpi.first.wpiunits:wpiunits-java:$wpilibVersion" implementation "edu.wpi.first.hal:hal-java:$wpilibVersion" - implementation "org.ejml:ejml-simple:0.43.1" - implementation "com.fasterxml.jackson.core:jackson-annotations:2.15.2" - implementation "com.fasterxml.jackson.core:jackson-core:2.15.2" - implementation "com.fasterxml.jackson.core:jackson-databind:2.15.2" + implementation "org.ejml:ejml-simple:0.44.0" + implementation "com.fasterxml.jackson.core:jackson-annotations:2.19.2" + implementation "com.fasterxml.jackson.core:jackson-core:2.19.2" + implementation "com.fasterxml.jackson.core:jackson-databind:2.19.2" implementation 'edu.wpi.first.thirdparty.frc2025.opencv:opencv-java:4.10.0-2' } @@ -76,6 +77,7 @@ nativeUtils { } javadoc { + failOnError false title = "Yet Another Generic Swerve Library API" destinationDir = file("$releasePath/javadocs") options { @@ -84,8 +86,11 @@ javadoc { 'https://codedocs.revrobotics.com/java/', 'https://api.ctr-electronics.com/phoenix6/release/java/', 'https://api.ctr-electronics.com/phoenix/release/java/', - "https://shenzhen-robotics-alliance.github.io/maple-sim/javadocs/", "https://www.kauailabs.com/public_files/navx-mxp/apidocs/java/" + tags 'todo:X"', + 'apiNote:a:"API Note:"', + 'implSpec:a:"Implementation Requirements:"', + 'implNote:a:"Implementation Note:"' } } @@ -144,5 +149,5 @@ build.dependsOn spotlessApply apply from: 'publish.gradle' wrapper { - gradleVersion '8.11' + gradleVersion = '8.14.3' } diff --git a/vendordep/publish.gradle b/vendordep/publish.gradle index 875cabe..ed205b6 100644 --- a/vendordep/publish.gradle +++ b/vendordep/publish.gradle @@ -124,8 +124,8 @@ task vendordepJson() { from templateVendorFile into "$releasePath/" expand(version: pubVersion, - groupId: artifactGroupId, - artifactId: baseArtifactId) + groupId: artifactGroupId, + artifactId: baseArtifactId) } } diff --git a/vendordep/vendordeps/Phoenix5-frc2025-latest.json b/vendordep/vendordeps/Phoenix5-frc2025-latest.json deleted file mode 100644 index 3cbc8f6..0000000 --- a/vendordep/vendordeps/Phoenix5-frc2025-latest.json +++ /dev/null @@ -1,171 +0,0 @@ -{ - "fileName": "Phoenix5-frc2025-latest.json", - "name": "CTRE-Phoenix (v5)", - "version": "5.35.1", - "frcYear": "2025", - "uuid": "ab676553-b602-441f-a38d-f1296eff6537", - "mavenUrls": [ - "https://maven.ctr-electronics.com/release/" - ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-frc2025-latest.json", - "requires": [ - { - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", - "offlineFileName": "Phoenix6-frc2025-latest.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json" - } - ], - "conflictsWith": [ - { - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", - "errorMessage": "Users must use the Phoenix 5 replay vendordep when using the Phoenix 6 replay vendordep.", - "offlineFileName": "Phoenix6-replay-frc2025-latest.json" - }, - { - "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", - "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", - "offlineFileName": "Phoenix5-replay-frc2025-latest.json" - } - ], - "javaDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "api-java", - "version": "5.35.1" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "wpiapi-java", - "version": "5.35.1" - } - ], - "jniDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "cci", - "version": "5.35.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "cci-sim", - "version": "5.35.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ], - "cppDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "wpiapi-cpp", - "version": "5.35.1", - "libName": "CTRE_Phoenix_WPI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "api-cpp", - "version": "5.35.1", - "libName": "CTRE_Phoenix", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "cci", - "version": "5.35.1", - "libName": "CTRE_PhoenixCCI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "wpiapi-cpp-sim", - "version": "5.35.1", - "libName": "CTRE_Phoenix_WPISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "api-cpp-sim", - "version": "5.35.1", - "libName": "CTRE_PhoenixSim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "cci-sim", - "version": "5.35.1", - "libName": "CTRE_PhoenixCCISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ] -} \ No newline at end of file diff --git a/vendordep/vendordeps/Phoenix5-replay-5.36.0-beta-1.json b/vendordep/vendordeps/Phoenix5-replay-5.36.0-beta-1.json new file mode 100644 index 0000000..4a78551 --- /dev/null +++ b/vendordep/vendordeps/Phoenix5-replay-5.36.0-beta-1.json @@ -0,0 +1,221 @@ +{ + "fileName": "Phoenix5-replay-5.36.0-beta-1.json", + "name": "CTRE-Phoenix (v5)", + "version": "5.36.0-beta-1", + "frcYear": "2026beta", + "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", + "mavenUrls": [ + "https://maven.ctr-electronics.com/release/" + ], + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-beta-latest.json", + "requires": [ + { + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", + "offlineFileName": "Phoenix6-replay-frc2026-beta-latest.json", + "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json" + } + ], + "conflictsWith": [ + { + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "errorMessage": "Users must use the regular Phoenix 5 vendordep when using the regular Phoenix 6 vendordep.", + "offlineFileName": "Phoenix6-frc2026-beta-latest.json" + }, + { + "uuid": "ab676553-b602-441f-a38d-f1296eff6537", + "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", + "offlineFileName": "Phoenix5-frc2026-beta-latest.json" + } + ], + "javaDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-java", + "version": "5.36.0-beta-1" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-java", + "version": "5.36.0-beta-1" + } + ], + "jniDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "cci-replay", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ], + "cppDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-cpp", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-cpp", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "wpiapi-cpp-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "api-cpp-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "cci-replay", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "wpiapi-cpp-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_Phoenix_WPISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "api-cpp-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixSim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0-beta-1", + "libName": "CTRE_PhoenixCCISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ] +} \ No newline at end of file diff --git a/vendordep/vendordeps/Phoenix6-frc2025-latest.json b/vendordep/vendordeps/Phoenix6-frc2025-latest.json deleted file mode 100644 index 765fef4..0000000 --- a/vendordep/vendordeps/Phoenix6-frc2025-latest.json +++ /dev/null @@ -1,449 +0,0 @@ -{ - "fileName": "Phoenix6-frc2025-latest.json", - "name": "CTRE-Phoenix (v6)", - "version": "25.3.2", - "frcYear": "2025", - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "mavenUrls": [ - "https://maven.ctr-electronics.com/release/" - ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json", - "conflictsWith": [ - { - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", - "errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.", - "offlineFileName": "Phoenix6-replay-frc2025-latest.json" - } - ], - "javaDependencies": [ - { - "groupId": "com.ctre.phoenix6", - "artifactId": "wpiapi-java", - "version": "25.3.2" - } - ], - "jniDependencies": [ - { - "groupId": "com.ctre.phoenix6", - "artifactId": "api-cpp", - "version": "25.3.2", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6", - "artifactId": "tools", - "version": "25.3.2", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "api-cpp-sim", - "version": "25.3.2", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "tools-sim", - "version": "25.3.2", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simTalonSRX", - "version": "25.3.2", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simVictorSPX", - "version": "25.3.2", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simPigeonIMU", - "version": "25.3.2", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simCANCoder", - "version": "25.3.2", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFX", - "version": "25.3.2", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFXS", - "version": "25.3.2", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANcoder", - "version": "25.3.2", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProPigeon2", - "version": "25.3.2", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANrange", - "version": "25.3.2", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANdi", - "version": "25.3.2", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ], - "cppDependencies": [ - { - "groupId": "com.ctre.phoenix6", - "artifactId": "wpiapi-cpp", - "version": "25.3.2", - "libName": "CTRE_Phoenix6_WPI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6", - "artifactId": "tools", - "version": "25.3.2", - "libName": "CTRE_PhoenixTools", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "wpiapi-cpp-sim", - "version": "25.3.2", - "libName": "CTRE_Phoenix6_WPISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "tools-sim", - "version": "25.3.2", - "libName": "CTRE_PhoenixTools_Sim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simTalonSRX", - "version": "25.3.2", - "libName": "CTRE_SimTalonSRX", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simVictorSPX", - "version": "25.3.2", - "libName": "CTRE_SimVictorSPX", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simPigeonIMU", - "version": "25.3.2", - "libName": "CTRE_SimPigeonIMU", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simCANCoder", - "version": "25.3.2", - "libName": "CTRE_SimCANCoder", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFX", - "version": "25.3.2", - "libName": "CTRE_SimProTalonFX", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFXS", - "version": "25.3.2", - "libName": "CTRE_SimProTalonFXS", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANcoder", - "version": "25.3.2", - "libName": "CTRE_SimProCANcoder", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProPigeon2", - "version": "25.3.2", - "libName": "CTRE_SimProPigeon2", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANrange", - "version": "25.3.2", - "libName": "CTRE_SimProCANrange", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANdi", - "version": "25.3.2", - "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/vendordep/vendordeps/Phoenix6-replay-26.0.0-beta-1.json b/vendordep/vendordeps/Phoenix6-replay-26.0.0-beta-1.json new file mode 100644 index 0000000..5312c86 --- /dev/null +++ b/vendordep/vendordeps/Phoenix6-replay-26.0.0-beta-1.json @@ -0,0 +1,453 @@ +{ + "fileName": "Phoenix6-replay-26.0.0-beta-1.json", + "name": "CTRE-Phoenix (v6) Replay", + "version": "26.0.0-beta-1", + "frcYear": "2026beta", + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "mavenUrls": [ + "https://maven.ctr-electronics.com/release/" + ], + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json", + "conflictsWith": [ + { + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.", + "offlineFileName": "Phoenix6-frc2026-beta-latest.json" + } + ], + "javaDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "wpiapi-java", + "version": "26.0.0-beta-1" + } + ], + "jniDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "api-cpp", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6", + "artifactId": "tools", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "api-cpp-replay", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "tools-replay", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "api-cpp-sim", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "tools-sim", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simTalonSRX", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simVictorSPX", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFX", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANcoder", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProPigeon2", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANrange", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdi", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdle", + "version": "26.0.0-beta-1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ], + "cppDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "wpiapi-cpp", + "version": "26.0.0-beta-1", + "libName": "CTRE_Phoenix6_WPI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6", + "artifactId": "tools", + "version": "26.0.0-beta-1", + "libName": "CTRE_PhoenixTools", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "wpiapi-cpp-replay", + "version": "26.0.0-beta-1", + "libName": "CTRE_Phoenix6_WPIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "tools-replay", + "version": "26.0.0-beta-1", + "libName": "CTRE_PhoenixTools_Replay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "wpiapi-cpp-sim", + "version": "26.0.0-beta-1", + "libName": "CTRE_Phoenix6_WPISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "tools-sim", + "version": "26.0.0-beta-1", + "libName": "CTRE_PhoenixTools_Sim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simTalonSRX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimTalonSRX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simVictorSPX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimVictorSPX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simPigeonIMU", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimPigeonIMU", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFX", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProTalonFX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANcoder", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProCANcoder", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProPigeon2", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProPigeon2", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANrange", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProCANrange", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdi", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProCANdi", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdle", + "version": "26.0.0-beta-1", + "libName": "CTRE_SimProCANdle", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ] +} \ No newline at end of file diff --git a/vendordep/vendordeps/REVLib.json b/vendordep/vendordeps/REVLib.json index 5546ea8..0f666c9 100644 --- a/vendordep/vendordeps/REVLib.json +++ b/vendordep/vendordeps/REVLib.json @@ -1,25 +1,55 @@ { "fileName": "REVLib.json", "name": "REVLib", - "version": "2025.0.3", - "frcYear": "2025", + "version": "2026.0.0-beta-1", + "frcYear": "2026beta", "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", "mavenUrls": [ "https://maven.revrobotics.com/" ], - "jsonUrl": "https://software-metadata.revrobotics.com/REVLib-2025.json", + "jsonUrl": "https://software-metadata.revrobotics.com/REVLib-2026.json", "javaDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-java", - "version": "2025.0.3" + "version": "2026.0.0-beta-1" } ], "jniDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibBackendDriver", + "version": "2026.0.0-beta-1", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibWpiBackendDriver", + "version": "2026.0.0-beta-1", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -36,7 +66,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-cpp", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", "libName": "REVLib", "headerClassifier": "headers", "sharedLibrary": false, @@ -53,7 +83,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2025.0.3", + "version": "2026.0.0-beta-1", "libName": "REVLibDriver", "headerClassifier": "headers", "sharedLibrary": false, @@ -66,6 +96,38 @@ "linuxarm32", "osxuniversal" ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibBackendDriver", + "version": "2026.0.0-beta-1", + "libName": "BackendDriver", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.revrobotics.frc", + "artifactId": "RevLibWpiBackendDriver", + "version": "2026.0.0-beta-1", + "libName": "REVLibWpi", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] } ] } \ No newline at end of file diff --git a/vendordep/vendordeps/ReduxLib-2025.0.1.json b/vendordep/vendordeps/ReduxLib-2025.0.1.json deleted file mode 100644 index 007f97f..0000000 --- a/vendordep/vendordeps/ReduxLib-2025.0.1.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "fileName": "ReduxLib-2025.0.1.json", - "name": "ReduxLib", - "version": "2025.0.1", - "frcYear": "2025", - "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", - "mavenUrls": [ - "https://maven.reduxrobotics.com/" - ], - "jsonUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2025.json", - "javaDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-java", - "version": "2025.0.1" - } - ], - "jniDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-driver", - "version": "2025.0.1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - } - ], - "cppDependencies": [ - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-cpp", - "version": "2025.0.1", - "libName": "ReduxLib", - "headerClassifier": "headers", - "sourcesClassifier": "sources", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - }, - { - "groupId": "com.reduxrobotics.frc", - "artifactId": "ReduxLib-driver", - "version": "2025.0.1", - "libName": "ReduxCore", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena", - "linuxx86-64", - "linuxarm32", - "linuxarm64", - "osxuniversal", - "windowsx86-64" - ] - } - ] -} \ No newline at end of file diff --git a/vendordep/vendordeps/Studica-2025.0.1.json b/vendordep/vendordeps/Studica-2025.0.1.json deleted file mode 100644 index e0b50d7..0000000 --- a/vendordep/vendordeps/Studica-2025.0.1.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "Studica-2025.0.1.json", - "name": "Studica", - "version": "2025.0.1", - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", - "frcYear": "2025", - "mavenUrls": [ - "https://dev.studica.com/maven/release/2025/" - ], - "jsonUrl": "https://dev.studica.com/releases/2025/Studica-2025.0.1.json", - "cppDependencies": [ - { - "artifactId": "Studica-cpp", - "binaryPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "groupId": "com.studica.frc", - "headerClassifier": "headers", - "libName": "Studica", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "version": "2025.0.1" - }, - { - "artifactId": "Studica-driver", - "binaryPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "groupId": "com.studica.frc", - "headerClassifier": "headers", - "libName": "StudicaDriver", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "version": "2025.0.1" - } - ], - "javaDependencies": [ - { - "artifactId": "Studica-java", - "groupId": "com.studica.frc", - "version": "2025.0.1" - } - ], - "jniDependencies": [ - { - "artifactId": "Studica-driver", - "groupId": "com.studica.frc", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena", - "linuxarm32", - "linuxarm64", - "linuxx86-64", - "osxuniversal", - "windowsx86-64" - ], - "version": "2025.0.1" - } - ] -} \ No newline at end of file diff --git a/vendordep/vendordeps/Studica-2026.0.0-beta.json b/vendordep/vendordeps/Studica-2026.0.0-beta.json new file mode 100644 index 0000000..c5d48c7 --- /dev/null +++ b/vendordep/vendordeps/Studica-2026.0.0-beta.json @@ -0,0 +1,71 @@ +{ + "fileName": "Studica-2026.0.0-beta.json", + "name": "Studica", + "version": "2026.0.0-beta", + "frcYear": "2026beta", + "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0-beta.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-java", + "version": "2026.0.0-beta" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0-beta", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-cpp", + "version": "2026.0.0-beta", + "libName": "Studica", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0-beta", + "libName": "StudicaDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/vendordep/vendordeps/StudicaLib.json b/vendordep/vendordeps/StudicaLib.json new file mode 100644 index 0000000..b6ed33e --- /dev/null +++ b/vendordep/vendordeps/StudicaLib.json @@ -0,0 +1,71 @@ +{ + "fileName": "StudicaLib.json", + "name": "StudicaLib", + "version": "2026.0.1-beta", + "frcYear": "2026beta", + "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.1-beta.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-java", + "version": "2026.0.1-beta" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.1-beta", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-cpp", + "version": "2026.0.1-beta", + "libName": "StudicaLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.1-beta", + "libName": "StudicaLibDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/vendordep/vendordeps/ThriftyLib.json b/vendordep/vendordeps/ThriftyLib.json index 887721f..1e59797 100644 --- a/vendordep/vendordeps/ThriftyLib.json +++ b/vendordep/vendordeps/ThriftyLib.json @@ -1,8 +1,8 @@ { "fileName": "ThriftyLib.json", "name": "ThriftyLib", - "version": "2025.1.1", - "frcYear": "2025", + "version": "2026.0.0", + "frcYear": "2026beta", "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", "mavenUrls": [ "https://docs.home.thethriftybot.com" @@ -12,9 +12,9 @@ { "groupId": "com.thethriftybot.frc", "artifactId": "ThriftyLib-java", - "version": "2025.1.1" + "version": "2026.0.0" } ], "jniDependencies": [], "cppDependencies": [] -} \ No newline at end of file +} diff --git a/vendordep/vendordeps/WPILibNewCommands.json b/vendordep/vendordeps/WPILibNewCommands.json index 3718e0a..7ebc954 100644 --- a/vendordep/vendordeps/WPILibNewCommands.json +++ b/vendordep/vendordeps/WPILibNewCommands.json @@ -3,7 +3,7 @@ "name": "WPILib-New-Commands", "version": "1.0.0", "uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266", - "frcYear": "2025", + "frcYear": "2026beta", "mavenUrls": [], "jsonUrl": "", "javaDependencies": [ @@ -25,6 +25,7 @@ "sharedLibrary": true, "skipInvalidPlatforms": true, "binaryPlatforms": [ + "linuxsystemcore", "linuxathena", "linuxarm32", "linuxarm64", diff --git a/vendordep/vendordeps/maple-sim.json b/vendordep/vendordeps/maple-sim.json deleted file mode 100644 index db80edc..0000000 --- a/vendordep/vendordeps/maple-sim.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "fileName": "maple-sim.json", - "name": "maplesim", - "version": "0.3.11prev", - "frcYear": "2025", - "uuid": "c39481e8-4a63-4a4c-9df6-48d91e4da37b", - "mavenUrls": [ - "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/repos/releases", - "https://repo1.maven.org/maven2" - ], - "jsonUrl": "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/maple-sim.json", - "javaDependencies": [ - { - "groupId": "org.ironmaple", - "artifactId": "maplesim-java", - "version": "0.3.11prev" - }, - { - "groupId": "org.dyn4j", - "artifactId": "dyn4j", - "version": "5.0.2" - } - ], - "jniDependencies": [], - "cppDependencies": [] -} \ No newline at end of file diff --git a/vendordep/vendordeps/photonlib.json b/vendordep/vendordeps/photonlib.json deleted file mode 100644 index 5c6484d..0000000 --- a/vendordep/vendordeps/photonlib.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "photonlib.json", - "name": "photonlib", - "version": "v2025.3.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.3.1", - "skipInvalidPlatforms": true, - "isJar": false, - "validPlatforms": [ - "windowsx86-64", - "linuxathena", - "linuxx86-64", - "osxuniversal" - ] - } - ], - "cppDependencies": [ - { - "groupId": "org.photonvision", - "artifactId": "photonlib-cpp", - "version": "v2025.3.1", - "libName": "photonlib", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxathena", - "linuxx86-64", - "osxuniversal" - ] - }, - { - "groupId": "org.photonvision", - "artifactId": "photontargeting-cpp", - "version": "v2025.3.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.3.1" - }, - { - "groupId": "org.photonvision", - "artifactId": "photontargeting-java", - "version": "v2025.3.1" - } - ] -} \ No newline at end of file diff --git a/vendordep/yagsl.json b/vendordep/yagsl.json index b321d39..9433483 100644 --- a/vendordep/yagsl.json +++ b/vendordep/yagsl.json @@ -2,10 +2,11 @@ "fileName": "yagsl-${version}.json", "name": "YAGSL", "version": "${version}", - "frcYear": "2025", + "frcYear": "2026beta", "uuid": "1ccce5a4-acd2-4d18-bca3-4b8047188400", "mavenUrls": [ - "https://yet-another-software-suite.github.io/YAGSL/releases/" + "https://yet-another-software-suite.github.io/YAGSL/releases/", + "https://repo1.maven.org/maven2" ], "jsonUrl": "https://yet-another-software-suite.github.io/YAGSL/yagsl.json", "javaDependencies": [ @@ -13,50 +14,43 @@ "groupId": "swervelib", "artifactId": "YAGSL-java", "version": "${version}" - } + }, + { + "groupId": "org.dyn4j", + "artifactId": "dyn4j", + "version": "5.0.2" + } ], "requires": [ { "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", "errorMessage": "REVLib is required!", - "offlineFileName": "REVLib-2025.0.0.json", - "onlineUrl": "https://software-metadata.revrobotics.com/REVLib-2025.json" - }, - { - "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", - "errorMessage": "ReduxLib is required!", - "offlineFileName": "ReduxLib-2025.0.0.json", - "onlineUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2025.json" + "offlineFileName": "REVLib.json", + "onlineUrl": "https://software-metadata.revrobotics.com/REVLib-2026.json" }, { "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", "errorMessage": "Phoenix6 is required!", - "offlineFileName": "Phoenix6-25.1.0.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json" + "offlineFileName": "Phoenix6-replay-26.0.0-beta-1", + "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json" }, { "uuid": "ab676553-b602-441f-a38d-f1296eff6537", "errorMessage": "Phoenix5 is required!", - "offlineFileName": "Phoenix5-5.35.0.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-frc2025-latest.json" + "offlineFileName": "Phoenix5-replay-5.36.0-beta-1.json", + "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-beta-latest.json" }, { "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", "errorMessage": "Studica is required!", - "offlineFileName": "Studica-2025.0.0.json", - "onlineUrl": "https://dev.studica.com/releases/2025/Studica-2025.0.0.json" + "offlineFileName": "StudicaLib.json", + "onlineUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.1-beta.json" }, { "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", "errorMessage": "ThriftyLib is required!", "offlineFileName": "ThriftyLib.json", "onlineUrl": "https://docs.home.thethriftybot.com/ThriftyLib.json" - }, - { - "uuid": "c39481e8-4a63-4a4c-9df6-48d91e4da37b", - "errorMessage": "maple-sim is required for simulation", - "offlineFileName": "maple-sim.json", - "onlineUrl": "https://shenzhen-robotics-alliance.github.io/maple-sim/vendordep/maple-sim.json" } ], "jniDependencies": [], diff --git a/yagsl/java/swervelib/SwerveDrive.java b/yagsl/java/swervelib/SwerveDrive.java index ddccf84..9ccb6a5 100644 --- a/yagsl/java/swervelib/SwerveDrive.java +++ b/yagsl/java/swervelib/SwerveDrive.java @@ -51,11 +51,11 @@ import java.util.Optional; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; -import org.ironmaple.simulation.SimulatedArena; -import org.ironmaple.simulation.drivesims.AbstractDriveTrainSimulation; -import org.ironmaple.simulation.drivesims.SwerveDriveSimulation; -import org.ironmaple.simulation.drivesims.configs.DriveTrainSimulationConfig; -import org.ironmaple.simulation.drivesims.configs.SwerveModuleSimulationConfig; +import swervelib.simulation.ironmaple.simulation.SimulatedArena; +import swervelib.simulation.ironmaple.simulation.drivesims.AbstractDriveTrainSimulation; +import swervelib.simulation.ironmaple.simulation.drivesims.SwerveDriveSimulation; +import swervelib.simulation.ironmaple.simulation.drivesims.configs.DriveTrainSimulationConfig; +import swervelib.simulation.ironmaple.simulation.drivesims.configs.SwerveModuleSimulationConfig; import swervelib.encoders.CANCoderSwerve; import swervelib.imu.Pigeon2Swerve; import swervelib.imu.SwerveIMU; diff --git a/yagsl/java/swervelib/SwerveModule.java b/yagsl/java/swervelib/SwerveModule.java index 0eb060e..b639280 100644 --- a/yagsl/java/swervelib/SwerveModule.java +++ b/yagsl/java/swervelib/SwerveModule.java @@ -1001,14 +1001,14 @@ public SwerveModuleSimulation getSimModule() /** * Configure the {@link SwerveModule#simModule} with the MapleSim - * {@link org.ironmaple.simulation.drivesims.SwerveModuleSimulation} + * {@link swervelib.simulation.ironmaple.simulation.drivesims.SwerveModuleSimulation} * - * @param swerveModuleSimulation MapleSim {@link org.ironmaple.simulation.drivesims.SwerveModuleSimulation} to + * @param swerveModuleSimulation MapleSim {@link swervelib.simulation.ironmaple.simulation.drivesims.SwerveModuleSimulation} to * configure with. * @param physicalCharacteristics {@link SwerveModulePhysicalCharacteristics} that represent the swerve drive. */ public void configureModuleSimulation( - org.ironmaple.simulation.drivesims.SwerveModuleSimulation swerveModuleSimulation, + swervelib.simulation.ironmaple.simulation.drivesims.SwerveModuleSimulation swerveModuleSimulation, SwerveModulePhysicalCharacteristics physicalCharacteristics) { this.simModule.configureSimModule(swerveModuleSimulation, physicalCharacteristics); diff --git a/yagsl/java/swervelib/encoders/CanAndMagSwerve.java b/yagsl/java/swervelib/encoders/CanAndMagSwerve.java index 5ed9e90..2a25f1c 100644 --- a/yagsl/java/swervelib/encoders/CanAndMagSwerve.java +++ b/yagsl/java/swervelib/encoders/CanAndMagSwerve.java @@ -1,115 +1,115 @@ package swervelib.encoders; -import com.reduxrobotics.sensors.canandmag.Canandmag; -import com.reduxrobotics.sensors.canandmag.CanandmagSettings; - -/** - * HELIUM {@link Canandmag} from ReduxRobotics absolute encoder, attached through the CAN bus. - */ -public class CanAndMagSwerve extends SwerveAbsoluteEncoder -{ - - /** - * The {@link Canandmag} representing the CANandMag on the CAN bus. - */ - public Canandmag encoder; - /** - * The {@link Canandmag} settings object to use. - */ - public CanandmagSettings settings; - - /** - * Create the {@link Canandmag} - * - * @param canid The CAN ID whenever the CANandMag is operating on the CANBus. - */ - public CanAndMagSwerve(int canid) - { - encoder = new Canandmag(canid); - settings = new CanandmagSettings(); - } - - @Override - public void close() - { - encoder.close(); - } - - /** - * Reset the encoder to factory defaults. - *

- * This will not clear the stored zero offset. - */ - @Override - public void factoryDefault() - { - encoder.resetFactoryDefaults(false); - } - - /** - * Clear sticky faults on the encoder. - */ - @Override - public void clearStickyFaults() - { - encoder.clearStickyFaults(); - } - - /** - * Configure the CANandMag to read from [0, 360) per second. - * - * @param inverted Whether the encoder is inverted. - */ - @Override - public void configure(boolean inverted) - { - settings.setInvertDirection(inverted); - encoder.setSettings(settings); - } - - /** - * Get the absolute position of the encoder. - * - * @return Absolute position in degrees from [0, 360). - */ - @Override - public double getAbsolutePosition() - { - return encoder.getAbsPosition() * 360; - } - - /** - * Get the instantiated absolute encoder Object. - * - * @return Absolute encoder object. - */ - @Override - public Object getAbsoluteEncoder() - { - return encoder; - } - - /** - * Cannot set the offset of the CANandMag. - * - * @param offset the offset the Absolute Encoder uses as the zero point. - * @return true if setting the zero point succeeded, false otherwise - */ - @Override - public boolean setAbsoluteEncoderOffset(double offset) - { - settings.setZeroOffset(offset); - return encoder.setSettings(settings); - } - - /** - * Get the velocity in degrees/sec. - * - * @return velocity in degrees/sec. - */ - @Override - public double getVelocity() - { - return encoder.getVelocity() * 360; - } -} +//import com.reduxrobotics.sensors.canandmag.Canandmag; +//import com.reduxrobotics.sensors.canandmag.CanandmagSettings; +// +///** +// * HELIUM {@link Canandmag} from ReduxRobotics absolute encoder, attached through the CAN bus. +// */ +//public class CanAndMagSwerve extends SwerveAbsoluteEncoder +//{ +// +// /** +// * The {@link Canandmag} representing the CANandMag on the CAN bus. +// */ +// public Canandmag encoder; +// /** +// * The {@link Canandmag} settings object to use. +// */ +// public CanandmagSettings settings; +// +// /** +// * Create the {@link Canandmag} +// * +// * @param canid The CAN ID whenever the CANandMag is operating on the CANBus. +// */ +// public CanAndMagSwerve(int canid) +// { +// encoder = new Canandmag(canid); +// settings = new CanandmagSettings(); +// } +// +// @Override +// public void close() +// { +// encoder.close(); +// } +// +// /** +// * Reset the encoder to factory defaults. +// *

+// * This will not clear the stored zero offset. +// */ +// @Override +// public void factoryDefault() +// { +// encoder.resetFactoryDefaults(false); +// } +// +// /** +// * Clear sticky faults on the encoder. +// */ +// @Override +// public void clearStickyFaults() +// { +// encoder.clearStickyFaults(); +// } +// +// /** +// * Configure the CANandMag to read from [0, 360) per second. +// * +// * @param inverted Whether the encoder is inverted. +// */ +// @Override +// public void configure(boolean inverted) +// { +// settings.setInvertDirection(inverted); +// encoder.setSettings(settings); +// } +// +// /** +// * Get the absolute position of the encoder. +// * +// * @return Absolute position in degrees from [0, 360). +// */ +// @Override +// public double getAbsolutePosition() +// { +// return encoder.getAbsPosition() * 360; +// } +// +// /** +// * Get the instantiated absolute encoder Object. +// * +// * @return Absolute encoder object. +// */ +// @Override +// public Object getAbsoluteEncoder() +// { +// return encoder; +// } +// +// /** +// * Cannot set the offset of the CANandMag. +// * +// * @param offset the offset the Absolute Encoder uses as the zero point. +// * @return true if setting the zero point succeeded, false otherwise +// */ +// @Override +// public boolean setAbsoluteEncoderOffset(double offset) +// { +// settings.setZeroOffset(offset); +// return encoder.setSettings(settings); +// } +// +// /** +// * Get the velocity in degrees/sec. +// * +// * @return velocity in degrees/sec. +// */ +// @Override +// public double getVelocity() +// { +// return encoder.getVelocity() * 360; +// } +//} diff --git a/yagsl/java/swervelib/encoders/SparkMaxAnalogEncoderSwerve.java b/yagsl/java/swervelib/encoders/SparkMaxAnalogEncoderSwerve.java index bda6303..f43c66a 100644 --- a/yagsl/java/swervelib/encoders/SparkMaxAnalogEncoderSwerve.java +++ b/yagsl/java/swervelib/encoders/SparkMaxAnalogEncoderSwerve.java @@ -1,9 +1,9 @@ package swervelib.encoders; import com.revrobotics.REVLibError; +import com.revrobotics.spark.FeedbackSensor; import com.revrobotics.spark.SparkAnalogSensor; import com.revrobotics.spark.SparkMax; -import com.revrobotics.spark.config.ClosedLoopConfig.FeedbackSensor; import com.revrobotics.spark.config.SparkMaxConfig; import edu.wpi.first.wpilibj.Alert; import edu.wpi.first.wpilibj.Alert.AlertType; diff --git a/yagsl/java/swervelib/encoders/SparkMaxEncoderSwerve.java b/yagsl/java/swervelib/encoders/SparkMaxEncoderSwerve.java index 784a067..e23a256 100644 --- a/yagsl/java/swervelib/encoders/SparkMaxEncoderSwerve.java +++ b/yagsl/java/swervelib/encoders/SparkMaxEncoderSwerve.java @@ -4,7 +4,6 @@ import com.revrobotics.REVLibError; import com.revrobotics.spark.SparkAbsoluteEncoder; import com.revrobotics.spark.SparkMax; -import com.revrobotics.spark.config.ClosedLoopConfig.FeedbackSensor; import com.revrobotics.spark.config.SparkMaxConfig; import edu.wpi.first.wpilibj.Alert; import edu.wpi.first.wpilibj.Alert.AlertType; diff --git a/yagsl/java/swervelib/encoders/ThriftyNovaEncoderSwerve.java b/yagsl/java/swervelib/encoders/ThriftyNovaEncoderSwerve.java index 5883ae3..deb0922 100644 --- a/yagsl/java/swervelib/encoders/ThriftyNovaEncoderSwerve.java +++ b/yagsl/java/swervelib/encoders/ThriftyNovaEncoderSwerve.java @@ -1,12 +1,12 @@ package swervelib.encoders; -import com.thethriftybot.Conversion; -import com.thethriftybot.Conversion.PositionUnit; -import com.thethriftybot.Conversion.VelocityUnit; -import com.thethriftybot.ThriftyNova; -import com.thethriftybot.ThriftyNova.EncoderType; -import com.thethriftybot.ThriftyNova.ExternalEncoder; +import com.thethriftybot.devices.ThriftyNova; +import com.thethriftybot.devices.ThriftyNova.EncoderType; +import com.thethriftybot.devices.ThriftyNova.ExternalEncoder; +import com.thethriftybot.util.Conversion; +import com.thethriftybot.util.Conversion.PositionUnit; +import com.thethriftybot.util.Conversion.VelocityUnit; import swervelib.motors.SwerveMotor; import swervelib.motors.ThriftyNovaSwerve; @@ -23,19 +23,19 @@ public class ThriftyNovaEncoderSwerve extends SwerveAbsoluteEncoder /** * Inversion state of the attached encoder. */ - protected boolean inverted = false; + protected boolean inverted = false; /** * Offset of the absolute encoder. */ - protected double offset = 0.0; + protected double offset = 0.0; /** * Position conversion object for the motor encoder */ - private Conversion positionConversion; + private Conversion positionConversion; /** * Velocity conversion object for the motor encoder */ - private Conversion velocityConversion; + private Conversion velocityConversion; /** * Create the {@link ThriftyNovaEncoderSwerve} object as an absolute encoder from the {@link ThriftyNovaSwerve} diff --git a/yagsl/java/swervelib/imu/CanandgyroSwerve.java b/yagsl/java/swervelib/imu/CanandgyroSwerve.java index 9991418..fc5b331 100644 --- a/yagsl/java/swervelib/imu/CanandgyroSwerve.java +++ b/yagsl/java/swervelib/imu/CanandgyroSwerve.java @@ -1,144 +1,144 @@ package swervelib.imu; import static edu.wpi.first.units.Units.RotationsPerSecond; - -import com.reduxrobotics.sensors.canandgyro.Canandgyro; -import edu.wpi.first.math.geometry.Rotation3d; -import edu.wpi.first.math.geometry.Translation3d; -import edu.wpi.first.units.measure.MutAngularVelocity; -import java.util.Optional; - -/** - * SwerveIMU interface for the Boron {@link Canandgyro} by Redux Robotics - */ -public class CanandgyroSwerve extends SwerveIMU -{ - - /** - * Wait time for status frames to show up. - */ - public static double STATUS_TIMEOUT_SECONDS = 0.04; - /** - * Boron {@link Canandgyro} by Redux Robotics. - */ - private final Canandgyro imu; - /** - * Mutable {@link MutAngularVelocity} for readings. - */ - private final MutAngularVelocity yawVel = new MutAngularVelocity(0, 0, RotationsPerSecond); - /** - * Offset for the Boron {@link Canandgyro}. - */ - private Rotation3d offset = new Rotation3d(); - /** - * Inversion for the gyro - */ - private boolean invertedIMU = false; - - /** - * Generate the SwerveIMU for {@link Canandgyro}. - * - * @param canid CAN ID for the Boron {@link Canandgyro} - */ - public CanandgyroSwerve(int canid) - { - imu = new Canandgyro(canid); - } - - @Override - public void close() - { - imu.close(); - } - - /** - * Reset {@link Canandgyro} to factory default. - */ - @Override - public void factoryDefault() - { - imu.resetFactoryDefaults(STATUS_TIMEOUT_SECONDS); - } - - /** - * Clear sticky faults on {@link Canandgyro}. - */ - @Override - public void clearStickyFaults() - { - imu.clearStickyFaults(); - } - - /** - * Set the gyro offset. - * - * @param offset gyro offset as a {@link Rotation3d}. - */ - public void setOffset(Rotation3d offset) - { - this.offset = offset; - } - - /** - * Set the gyro to invert its default direction - * - * @param invertIMU invert gyro direction - */ - public void setInverted(boolean invertIMU) - { - invertedIMU = invertIMU; - } - - /** - * Fetch the {@link Rotation3d} from the IMU without any zeroing. Robot relative. - * - * @return {@link Rotation3d} from the IMU. - */ - @Override - public Rotation3d getRawRotation3d() - { - Rotation3d reading = imu.getRotation3d(); - return invertedIMU ? reading.unaryMinus() : reading; - } - - /** - * Fetch the {@link Rotation3d} from the IMU. Robot relative. - * - * @return {@link Rotation3d} from the IMU. - */ - @Override - public Rotation3d getRotation3d() - { - return getRawRotation3d().rotateBy(offset.unaryMinus()); - } - - /** - * Fetch the acceleration [x, y, z] from the IMU in meters per second squared. If acceleration isn't supported returns - * empty. - * - * @return {@link Translation3d} of the acceleration as an {@link Optional}. - */ - @Override - public Optional getAccel() - { - - return Optional.of(new Translation3d(imu.getAccelerationFrame().getValue()).times(9.81 / 16384.0)); - } - - @Override - public MutAngularVelocity getYawAngularVelocity() - { - return yawVel.mut_setMagnitude(imu.getAngularVelocityYaw()); - } - - /** - * Get the instantiated {@link Canandgyro} IMU object. - * - * @return IMU object. - */ - @Override - public Object getIMU() - { - return imu; - } -} +// +//import com.reduxrobotics.sensors.canandgyro.Canandgyro; +//import edu.wpi.first.math.geometry.Rotation3d; +//import edu.wpi.first.math.geometry.Translation3d; +//import edu.wpi.first.units.measure.MutAngularVelocity; +//import java.util.Optional; +// +///** +// * SwerveIMU interface for the Boron {@link Canandgyro} by Redux Robotics +// */ +//public class CanandgyroSwerve extends SwerveIMU +//{ +// +// /** +// * Wait time for status frames to show up. +// */ +// public static double STATUS_TIMEOUT_SECONDS = 0.04; +// /** +// * Boron {@link Canandgyro} by Redux Robotics. +// */ +// private final Canandgyro imu; +// /** +// * Mutable {@link MutAngularVelocity} for readings. +// */ +// private final MutAngularVelocity yawVel = new MutAngularVelocity(0, 0, RotationsPerSecond); +// /** +// * Offset for the Boron {@link Canandgyro}. +// */ +// private Rotation3d offset = new Rotation3d(); +// /** +// * Inversion for the gyro +// */ +// private boolean invertedIMU = false; +// +// /** +// * Generate the SwerveIMU for {@link Canandgyro}. +// * +// * @param canid CAN ID for the Boron {@link Canandgyro} +// */ +// public CanandgyroSwerve(int canid) +// { +// imu = new Canandgyro(canid); +// } +// +// @Override +// public void close() +// { +// imu.close(); +// } +// +// /** +// * Reset {@link Canandgyro} to factory default. +// */ +// @Override +// public void factoryDefault() +// { +// imu.resetFactoryDefaults(STATUS_TIMEOUT_SECONDS); +// } +// +// /** +// * Clear sticky faults on {@link Canandgyro}. +// */ +// @Override +// public void clearStickyFaults() +// { +// imu.clearStickyFaults(); +// } +// +// /** +// * Set the gyro offset. +// * +// * @param offset gyro offset as a {@link Rotation3d}. +// */ +// public void setOffset(Rotation3d offset) +// { +// this.offset = offset; +// } +// +// /** +// * Set the gyro to invert its default direction +// * +// * @param invertIMU invert gyro direction +// */ +// public void setInverted(boolean invertIMU) +// { +// invertedIMU = invertIMU; +// } +// +// /** +// * Fetch the {@link Rotation3d} from the IMU without any zeroing. Robot relative. +// * +// * @return {@link Rotation3d} from the IMU. +// */ +// @Override +// public Rotation3d getRawRotation3d() +// { +// Rotation3d reading = imu.getRotation3d(); +// return invertedIMU ? reading.unaryMinus() : reading; +// } +// +// /** +// * Fetch the {@link Rotation3d} from the IMU. Robot relative. +// * +// * @return {@link Rotation3d} from the IMU. +// */ +// @Override +// public Rotation3d getRotation3d() +// { +// return getRawRotation3d().rotateBy(offset.unaryMinus()); +// } +// +// /** +// * Fetch the acceleration [x, y, z] from the IMU in meters per second squared. If acceleration isn't supported returns +// * empty. +// * +// * @return {@link Translation3d} of the acceleration as an {@link Optional}. +// */ +// @Override +// public Optional getAccel() +// { +// +// return Optional.of(new Translation3d(imu.getAccelerationFrame().getValue()).times(9.81 / 16384.0)); +// } +// +// @Override +// public MutAngularVelocity getYawAngularVelocity() +// { +// return yawVel.mut_setMagnitude(imu.getAngularVelocityYaw()); +// } +// +// /** +// * Get the instantiated {@link Canandgyro} IMU object. +// * +// * @return IMU object. +// */ +// @Override +// public Object getIMU() +// { +// return imu; +// } +//} diff --git a/yagsl/java/swervelib/motors/SparkFlexSwerve.java b/yagsl/java/swervelib/motors/SparkFlexSwerve.java index 21e0bd5..d401da2 100644 --- a/yagsl/java/swervelib/motors/SparkFlexSwerve.java +++ b/yagsl/java/swervelib/motors/SparkFlexSwerve.java @@ -7,13 +7,13 @@ import com.revrobotics.REVLibError; import com.revrobotics.RelativeEncoder; import com.revrobotics.spark.ClosedLoopSlot; +import com.revrobotics.spark.FeedbackSensor; import com.revrobotics.spark.SparkBase.ControlType; import com.revrobotics.spark.SparkBase.PersistMode; import com.revrobotics.spark.SparkBase.ResetMode; import com.revrobotics.spark.SparkClosedLoopController; import com.revrobotics.spark.SparkFlex; import com.revrobotics.spark.SparkLowLevel.MotorType; -import com.revrobotics.spark.config.ClosedLoopConfig.FeedbackSensor; import com.revrobotics.spark.config.SparkBaseConfig.IdleMode; import com.revrobotics.spark.config.SparkFlexConfig; import edu.wpi.first.math.system.plant.DCMotor; diff --git a/yagsl/java/swervelib/motors/SparkMaxBrushedMotorSwerve.java b/yagsl/java/swervelib/motors/SparkMaxBrushedMotorSwerve.java index 7306cf4..0fdc2e3 100644 --- a/yagsl/java/swervelib/motors/SparkMaxBrushedMotorSwerve.java +++ b/yagsl/java/swervelib/motors/SparkMaxBrushedMotorSwerve.java @@ -6,13 +6,13 @@ import com.revrobotics.REVLibError; import com.revrobotics.RelativeEncoder; import com.revrobotics.spark.ClosedLoopSlot; +import com.revrobotics.spark.FeedbackSensor; import com.revrobotics.spark.SparkBase.ControlType; import com.revrobotics.spark.SparkBase.PersistMode; import com.revrobotics.spark.SparkBase.ResetMode; import com.revrobotics.spark.SparkClosedLoopController; import com.revrobotics.spark.SparkLowLevel.MotorType; import com.revrobotics.spark.SparkMax; -import com.revrobotics.spark.config.ClosedLoopConfig.FeedbackSensor; import com.revrobotics.spark.config.SparkBaseConfig.IdleMode; import com.revrobotics.spark.config.SparkMaxConfig; import edu.wpi.first.math.system.plant.DCMotor; @@ -400,7 +400,7 @@ public void configureIntegratedEncoder(double positionConversionFactor) @Override public void configurePIDF(PIDFConfig config) { - cfg.closedLoop.pidf(config.p, config.i, config.d, config.f) + cfg.closedLoop.pid(config.p, config.i, config.d) .iZone(config.iz) .outputRange(config.output.min, config.output.max); } @@ -491,7 +491,7 @@ public void setReference(double setpoint, double feedforward) if (isDriveMotor) { configureSparkMax(() -> - pid.setReference( + pid.setSetpoint( setpoint, ControlType.kVelocity, ClosedLoopSlot.kSlot0, @@ -499,7 +499,7 @@ public void setReference(double setpoint, double feedforward) } else { configureSparkMax(() -> - pid.setReference( + pid.setSetpoint( setpoint, ControlType.kPosition, ClosedLoopSlot.kSlot0, diff --git a/yagsl/java/swervelib/motors/SparkMaxSwerve.java b/yagsl/java/swervelib/motors/SparkMaxSwerve.java index 4acd4c9..c9cee45 100644 --- a/yagsl/java/swervelib/motors/SparkMaxSwerve.java +++ b/yagsl/java/swervelib/motors/SparkMaxSwerve.java @@ -6,13 +6,13 @@ import com.revrobotics.REVLibError; import com.revrobotics.RelativeEncoder; import com.revrobotics.spark.ClosedLoopSlot; +import com.revrobotics.spark.FeedbackSensor; import com.revrobotics.spark.SparkBase.ControlType; import com.revrobotics.spark.SparkBase.PersistMode; import com.revrobotics.spark.SparkBase.ResetMode; import com.revrobotics.spark.SparkClosedLoopController; import com.revrobotics.spark.SparkLowLevel.MotorType; import com.revrobotics.spark.SparkMax; -import com.revrobotics.spark.config.ClosedLoopConfig.FeedbackSensor; import com.revrobotics.spark.config.SparkBaseConfig.IdleMode; import com.revrobotics.spark.config.SparkMaxConfig; import edu.wpi.first.math.system.plant.DCMotor; diff --git a/yagsl/java/swervelib/motors/TalonFXSSwerve.java b/yagsl/java/swervelib/motors/TalonFXSSwerve.java index 7a002be..1838af4 100644 --- a/yagsl/java/swervelib/motors/TalonFXSSwerve.java +++ b/yagsl/java/swervelib/motors/TalonFXSSwerve.java @@ -9,8 +9,10 @@ import com.ctre.phoenix6.controls.MotionMagicVoltage; import com.ctre.phoenix6.controls.VelocityVoltage; import com.ctre.phoenix6.hardware.TalonFXS; +import com.ctre.phoenix6.signals.AdvancedHallSupportValue; import com.ctre.phoenix6.signals.FeedbackSensorSourceValue; import com.ctre.phoenix6.signals.InvertedValue; +import com.ctre.phoenix6.signals.MotorArrangementValue; import com.ctre.phoenix6.signals.NeutralModeValue; import edu.wpi.first.math.system.plant.DCMotor; import swervelib.encoders.SwerveAbsoluteEncoder; @@ -124,9 +126,32 @@ public void factoryDefaults() // motor.setSensorPhase(true); // motor.configSelectedFeedbackSensor(TalonFXSFeedbackDevice.IntegratedSensor, 0, 30); // motor.configNeutralDeadband(0.001); + if(isMotor(simMotor, DCMotor.getMinion(1))) + { + configuration.Commutation.withAdvancedHallSupport(AdvancedHallSupportValue.Enabled); + configuration.Commutation.withMotorArrangement(MotorArrangementValue.Minion_JST); + } } } + + /** + * Compare {@link DCMotor}s to identify the given motor. + * + * @param a {@link DCMotor} a + * @param b {@link DCMotor} b + * @return True if same DC motor. + */ + private boolean isMotor(DCMotor a, DCMotor b) + { + return a.stallTorqueNewtonMeters == b.stallTorqueNewtonMeters && + a.stallCurrentAmps == b.stallCurrentAmps && + a.freeCurrentAmps == b.freeCurrentAmps && + a.freeSpeedRadPerSec == b.freeSpeedRadPerSec && + a.KtNMPerAmp == b.KtNMPerAmp && + a.KvRadPerSecPerVolt == b.KvRadPerSecPerVolt && + a.nominalVoltageVolts == b.nominalVoltageVolts; + } /** * Clear the sticky faults on the motor controller. */ diff --git a/yagsl/java/swervelib/motors/ThriftyNovaSwerve.java b/yagsl/java/swervelib/motors/ThriftyNovaSwerve.java index bbed6c5..6f07e78 100644 --- a/yagsl/java/swervelib/motors/ThriftyNovaSwerve.java +++ b/yagsl/java/swervelib/motors/ThriftyNovaSwerve.java @@ -4,17 +4,17 @@ package swervelib.motors; +import com.thethriftybot.devices.ThriftyNova; +import com.thethriftybot.devices.ThriftyNova.CurrentType; +import com.thethriftybot.devices.ThriftyNova.EncoderType; +import com.thethriftybot.devices.ThriftyNova.PIDSlot; +import com.thethriftybot.util.Conversion; +import com.thethriftybot.util.Conversion.PositionUnit; +import com.thethriftybot.util.Conversion.VelocityUnit; import java.util.List; import java.util.Optional; import java.util.function.Supplier; -import com.thethriftybot.Conversion; -import com.thethriftybot.Conversion.PositionUnit; -import com.thethriftybot.Conversion.VelocityUnit; -import com.thethriftybot.ThriftyNova; -import com.thethriftybot.ThriftyNova.CurrentType; -import com.thethriftybot.ThriftyNova.EncoderType; -import com.thethriftybot.ThriftyNova.PIDSlot; import edu.wpi.first.math.controller.PIDController; import edu.wpi.first.math.system.plant.DCMotor; @@ -39,23 +39,23 @@ public class ThriftyNovaSwerve extends SwerveMotor /** * Closed-loop PID controller. */ - public PIDController pid; + public PIDController pid; /** * ThriftyNova Instance. */ - private ThriftyNova motor; + private ThriftyNova motor; /** * Factory default already occurred. */ - private boolean factoryDefaultOccurred = false; + private boolean factoryDefaultOccurred = false; /** * Position conversion object for the motor encoder */ - private Conversion positionConversion; + private Conversion positionConversion; /** * Velocity conversion object for the motor encoder */ - private Conversion velocityConversion; + private Conversion velocityConversion; /** * The position conversion factor for the encoder */ diff --git a/yagsl/java/swervelib/parser/SwerveDriveConfiguration.java b/yagsl/java/swervelib/parser/SwerveDriveConfiguration.java index 573d574..4b783d8 100644 --- a/yagsl/java/swervelib/parser/SwerveDriveConfiguration.java +++ b/yagsl/java/swervelib/parser/SwerveDriveConfiguration.java @@ -3,8 +3,8 @@ import edu.wpi.first.math.geometry.Translation2d; import edu.wpi.first.math.system.plant.DCMotor; import java.util.function.Supplier; -import org.ironmaple.simulation.drivesims.COTS; -import org.ironmaple.simulation.drivesims.GyroSimulation; +import swervelib.simulation.ironmaple.simulation.drivesims.COTS; +import swervelib.simulation.ironmaple.simulation.drivesims.GyroSimulation; import swervelib.SwerveModule; import swervelib.imu.NavXSwerve; import swervelib.imu.Pigeon2Swerve; diff --git a/yagsl/java/swervelib/parser/json/DeviceJson.java b/yagsl/java/swervelib/parser/json/DeviceJson.java index ff519ad..3dadc69 100644 --- a/yagsl/java/swervelib/parser/json/DeviceJson.java +++ b/yagsl/java/swervelib/parser/json/DeviceJson.java @@ -11,7 +11,7 @@ import edu.wpi.first.wpilibj.DriverStation; import swervelib.encoders.AnalogAbsoluteEncoderSwerve; import swervelib.encoders.CANCoderSwerve; -import swervelib.encoders.CanAndMagSwerve; +//import swervelib.encoders.CanAndMagSwerve; import swervelib.encoders.DIODutyCycleEncoderSwerve; import swervelib.encoders.SparkFlexEncoderSwerve; import swervelib.encoders.SparkMaxAnalogEncoderSwerve; @@ -22,7 +22,7 @@ import swervelib.imu.ADIS16470Swerve; import swervelib.imu.ADXRS450Swerve; import swervelib.imu.AnalogGyroSwerve; -import swervelib.imu.CanandgyroSwerve; +//import swervelib.imu.CanandgyroSwerve; import swervelib.imu.NavXSwerve; import swervelib.imu.Pigeon2Swerve; import swervelib.imu.PigeonSwerve; @@ -36,6 +36,7 @@ import swervelib.motors.TalonFXSSwerve; import swervelib.motors.TalonFXSwerve; import swervelib.motors.TalonSRXSwerve; +import swervelib.motors.ThriftyNovaSwerve; import swervelib.parser.deserializer.ReflectionsManager; import swervelib.parser.deserializer.ReflectionsManager.VENDOR; @@ -90,8 +91,8 @@ public SwerveAbsoluteEncoder createEncoder(SwerveMotor motor) case "sparkflex_canandcoder": return new SparkFlexEncoderSwerve(motor, 360); case "canandcoder_can": - case "canandmag_can": - return new CanAndMagSwerve(id); +// case "canandmag_can": +// return new CanAndMagSwerve(id); case "ctre_mag": case "rev_hex": case "throughbore": @@ -152,8 +153,8 @@ public SwerveIMU createIMU() return new ADXRS450Swerve(); case "analog": return new AnalogGyroSwerve(id); - case "canandgyro": - return new CanandgyroSwerve(id); +// case "canandgyro": +// return new CanandgyroSwerve(id); case "navx": case "navx_spi": return new NavXSwerve(NavXComType.kMXP_SPI); @@ -205,7 +206,9 @@ public SwerveMotor createMotor(boolean isDriveMotor) case "talonfxs_vortex": return new TalonFXSSwerve(id, canbus != null ? canbus : "", isDriveMotor, DCMotor.getNeoVortex(1)); case "talonfxs_minion": - throw new UnsupportedOperationException("Cannot create minion combination yet"); //new TalonFXSSwerve(id, canbus != null ? canbus : "", isDriveMotor, DCMotor.getNeoVortex(1)); + return new TalonFXSSwerve(id, canbus != null ? canbus : "", isDriveMotor, DCMotor.getMinion(1)); + case "talonfxs_pulsar": + throw new UnsupportedOperationException("Cannot create pulsar combination"); case "sparkmax_neo": case "neo": case "sparkmax": @@ -213,12 +216,13 @@ public SwerveMotor createMotor(boolean isDriveMotor) case "sparkmax_vortex": return new SparkMaxSwerve(id, isDriveMotor, DCMotor.getNeoVortex(1)); case "sparkmax_minion": - throw new UnsupportedOperationException("Cannot create minion combination yet"); + return new SparkMaxSwerve(id, isDriveMotor, DCMotor.getMinion(1)); case "sparkmax_neo550": case "neo550": return new SparkMaxSwerve(id, isDriveMotor, DCMotor.getNeo550(1)); + case "sparkmax_pulsar": + throw new UnsupportedOperationException("Cannot create pulsar combination"); case "sparkflex_vortex": - case "vortex": case "sparkflex": return new SparkFlexSwerve(id, isDriveMotor, DCMotor.getNeoVortex(1)); case "sparkflex_neo": @@ -226,12 +230,16 @@ public SwerveMotor createMotor(boolean isDriveMotor) case "sparkflex_neo550": return new SparkFlexSwerve(id, isDriveMotor, DCMotor.getNeo550(1)); case "sparkflex_minion": - throw new UnsupportedOperationException("Cannot create minion combination yet"); + return new SparkFlexSwerve(id, isDriveMotor, DCMotor.getMinion(1)); + case "sparkflex_pulsar": + throw new UnsupportedOperationException("Cannot create pulsar combination"); case "falcon500": case "falcon": return new TalonFXSwerve(id, canbus != null ? canbus : "", isDriveMotor, DCMotor.getFalcon500(1)); case "falcon500foc": return new TalonFXSwerve(id, canbus != null ? canbus : "", isDriveMotor, DCMotor.getFalcon500Foc(1)); + case "krakenx44": + return new TalonFXSwerve(id, canbus != null ? canbus : "", isDriveMotor, DCMotor.getKrakenX44(1)); case "krakenx60": case "talonfx": return new TalonFXSwerve(id, canbus != null ? canbus : "", isDriveMotor, DCMotor.getKrakenX60(1)); @@ -288,7 +296,9 @@ public SwerveMotor createMotor(boolean isDriveMotor) new Object[]{id, isDriveMotor, DCMotor.getNeoVortex(1)}); case "nova_minion": - throw new UnsupportedOperationException("Cannot create minion combination");//return new ThriftyNovaSwerve(id, isDriveMotor, DCMotor.getMinion(1)); + return new ThriftyNovaSwerve(id, isDriveMotor, DCMotor.getMinion(1)); + case "nova_pulsar": + throw new UnsupportedOperationException("Cannot create pulsar combination"); default: throw new RuntimeException(type + " is not a recognized motor type."); } diff --git a/yagsl/java/swervelib/simulation/SwerveIMUSimulation.java b/yagsl/java/swervelib/simulation/SwerveIMUSimulation.java index aa92c7e..2857be7 100644 --- a/yagsl/java/swervelib/simulation/SwerveIMUSimulation.java +++ b/yagsl/java/swervelib/simulation/SwerveIMUSimulation.java @@ -8,7 +8,7 @@ import edu.wpi.first.math.kinematics.SwerveModuleState; import edu.wpi.first.wpilibj.smartdashboard.Field2d; import java.util.Optional; -import org.ironmaple.simulation.drivesims.GyroSimulation; +import swervelib.simulation.ironmaple.simulation.drivesims.GyroSimulation; /** * Simulation for {@link swervelib.SwerveDrive} IMU. diff --git a/yagsl/java/swervelib/simulation/SwerveModuleSimulation.java b/yagsl/java/swervelib/simulation/SwerveModuleSimulation.java index 41bc138..593d1ba 100644 --- a/yagsl/java/swervelib/simulation/SwerveModuleSimulation.java +++ b/yagsl/java/swervelib/simulation/SwerveModuleSimulation.java @@ -5,12 +5,12 @@ import edu.wpi.first.math.geometry.Rotation2d; import edu.wpi.first.math.kinematics.SwerveModulePosition; import edu.wpi.first.math.kinematics.SwerveModuleState; -import org.ironmaple.simulation.drivesims.SelfControlledSwerveDriveSimulation; +import swervelib.simulation.ironmaple.simulation.drivesims.SelfControlledSwerveDriveSimulation; import swervelib.SwerveDrive; import swervelib.parser.SwerveModulePhysicalCharacteristics; /** - * Class that wraps around {@link org.ironmaple.simulation.drivesims.SwerveModuleSimulation} + * Class that wraps around {@link swervelib.simulation.ironmaple.simulation.drivesims.SwerveModuleSimulation} */ public class SwerveModuleSimulation { @@ -23,11 +23,11 @@ public class SwerveModuleSimulation /** * Configure the maple sim module * - * @param simModule the {@link org.ironmaple.simulation.drivesims.SwerveModuleSimulation} object for + * @param simModule the {@link swervelib.simulation.ironmaple.simulation.drivesims.SwerveModuleSimulation} object for * simulation * @param physicalCharacteristics Physical characteristics of the swerve drive from the JSON or built. */ - public void configureSimModule(org.ironmaple.simulation.drivesims.SwerveModuleSimulation simModule, + public void configureSimModule(swervelib.simulation.ironmaple.simulation.drivesims.SwerveModuleSimulation simModule, SwerveModulePhysicalCharacteristics physicalCharacteristics) { this.mapleSimModule = new SelfControlledSwerveDriveSimulation.SelfControlledModuleSimulation(simModule); diff --git a/yagsl/java/swervelib/simulation/ironmaple/LICENSE-Dyn4j.md b/yagsl/java/swervelib/simulation/ironmaple/LICENSE-Dyn4j.md new file mode 100644 index 0000000..bf61eac --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/LICENSE-Dyn4j.md @@ -0,0 +1,27 @@ +Copyright (c) 2010-2024, William Bittle +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java new file mode 100644 index 0000000..feb37f2 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java @@ -0,0 +1,297 @@ +package swervelib.simulation.ironmaple.simulation; + +import static edu.wpi.first.units.Units.Degrees; + +import edu.wpi.first.math.geometry.Pose3d; +import edu.wpi.first.math.geometry.Rotation3d; +import edu.wpi.first.math.geometry.Translation3d; +import edu.wpi.first.units.Units; +import edu.wpi.first.units.measure.Angle; +import edu.wpi.first.units.measure.Distance; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.dyn4j.geometry.Rectangle; +import org.dyn4j.geometry.Vector2; +import swervelib.simulation.ironmaple.simulation.gamepieces.GamePiece; + +/** + * + * + *

A abstract class to handle scoring elements in simulation.

+ */ +public abstract class Goal implements SimulatedArena.Simulatable { + + protected Rectangle xyBox; + protected final Distance height; + protected final Distance elevation; + + protected final String gamePieceType; + + protected final Translation3d position; + protected final SimulatedArena arena; + protected final int max; + public final boolean isBlue; + protected int gamePieceCount = 0; + protected Rotation3d pieceAngle = null; + protected Angle pieceAngleTolerance = Angle.ofBaseUnits(15, Units.Degrees); + + /** + * + * + *

Reverses a rotation so that the returned rotation points directly "behind" the original rotation.

+ * + * @param toFlip The rotation to be flipped. + * @return The flipped rotation. + */ + public static Rotation3d flipRotation(Rotation3d toFlip) { + return new Rotation3d(0, -toFlip.getY(), toFlip.getZ() + Math.PI); + } + + /** + * + * + *

Creates a goal object

+ * + * @param arena The host arena of this goal + * @param xDimension The x dimension of the default box collider. + * @param yDimension The y dimension of the default box collider. + * @param height The height or z dimension of the default box collider. + * @param gamePieceType the string game piece type to be handled by this goal. + * @param position The position of this goal. + * @param isBlue Wether this is a blue goal or a red one. + * @param max How many pieces can be scored in this goal. + */ + public Goal( + SimulatedArena arena, + Distance xDimension, + Distance yDimension, + Distance height, + String gamePieceType, + Translation3d position, + boolean isBlue, + int max) { + + xyBox = new Rectangle(xDimension.in(Units.Meters), yDimension.in(Units.Meters)); + this.height = height; + this.gamePieceType = gamePieceType; + this.position = position; + this.arena = arena; + this.max = max; + this.elevation = position.getMeasureZ(); + this.isBlue = isBlue; + + xyBox.translate(new Vector2(position.getX(), position.getY())); + } + + /** + * + * + *

Creates a goal object with no scoring max.

+ * + * @param arena The host arena of this goal. + * @param xDimension The x dimension of the default box collider. + * @param yDimension The y dimension of the default box collider. + * @param height The height or z dimension of the default box collider. + * @param gamePieceType the string game piece type to be handled by this goal. + * @param position The position of this goal. + * @param isBlue Wether this is a blue goal or a red one. + */ + public Goal( + SimulatedArena arena, + Distance xDimension, + Distance yDimension, + Distance height, + String gamePieceType, + Translation3d position, + boolean isBlue) { + this(arena, xDimension, yDimension, height, gamePieceType, position, isBlue, 99999); + } + + /** + * + * + *

Handles the update triggers for the goal object.

+ */ + @Override + public void simulationSubTick(int subTickNum) { + + Set gamePieces = new HashSet(arena.getGamePiecesByType(gamePieceType)); + Set toRemove = new HashSet<>(); + + for (GamePiece gamePiece : gamePieces) { + if (gamePieceCount != max && !toRemove.contains(gamePiece) && this.checkValidity(gamePiece)) { + gamePieceCount++; + this.addPoints(); + toRemove.add(gamePiece); + } + } + + for (GamePiece gamePiece : toRemove) { + this.arena.removePiece(gamePiece); + } + } + + /** + * + * + *

Sets the angle to be used when checking game piece rotation. + * + * @param angle The angle that pieces should have when interacting with this goal + * @param angleTolerance The tolerance to be used in checking said angle. + */ + public void setNeededAngle(Rotation3d angle, Angle angleTolerance) { + pieceAngle = angle; + pieceAngleTolerance = angleTolerance; + } + + /** + * + * + *

Sets the angle to be used when checking game piece rotation. + * + * @param angle The angle that pieces should have when interacting with this goal + */ + public void setNeededAngle(Rotation3d angle) { + setNeededAngle(angle, pieceAngleTolerance); + } + + /** + * A high level call to check wether or not the provided piece is within this goals hit box and meets all + * requirements to be scored. For more information on how this function calculates see the functions: + * + *

{@link org.dyn4j.geometry.AbstractShape#contains(Vector2 point)} + * + *

{@link Goal#checkHeight(GamePiece)} + * + *

{@link Goal#checkRotation(GamePiece)} + * + *

{@link Goal#checkVel(GamePiece)} + * + *

Be aware that due to the nature of the goal class the above functions may or may not have the same + * implementation for children of the goal class. + * + * @param gamePiece The game piece to be checked. + * @return Wether or not the game piece is within this goal. + */ + protected boolean checkValidity(GamePiece gamePiece) { + return checkCollision(gamePiece) && checkRotation(gamePiece) && checkVel(gamePiece); + } + + /** + * + * + *

Checks wether or not the submitted game piece has a rotation able to be scored in this goal

+ * + * By default the rotation needed and tolerance may be set using the {@link Goal#setNeededAngle(Rotation3d, Angle)} + * function. However rotation checks may be handled differently by some children making this not apply. Additionally + * be aware that this function only supports pitch and yaw, not role. If support for roll is needed a custom + * implementation will have to be created. + * + * @param gamePiece The game piece to have its rotation checked. + * @return Wether or not the pieces rotation is consistent with rotation that are able to be scored in this goal. + */ + protected boolean checkRotation(GamePiece gamePiece) { + if (pieceAngle == null) { + System.out.println("test"); + return true; + } + + Rotation3d normalDiff = gamePiece.getPose3d().getRotation().minus(pieceAngle); + Rotation3d flippedDiff = + flipRotation(gamePiece.getPose3d().getRotation()).minus(pieceAngle); + + + + return new Rotation3d(Degrees.of(0), normalDiff.getMeasureZ(), normalDiff.getMeasureZ()) + .getMeasureAngle() + .in(Units.Degrees) + < pieceAngleTolerance.in(Units.Degrees) + || new Rotation3d(Degrees.of(0), flippedDiff.getMeasureZ(), flippedDiff.getMeasureZ()) + .getMeasureAngle() + .in(Units.Degrees) + < pieceAngleTolerance.in(Units.Degrees); + } + + /** + * + * + *

Returns wether or not the submitted game piece is within the goal.

+ * + * @param gamePiece The game piece to be checked. + * @return Wether or not the game piece is within the goal. + */ + protected boolean checkCollision(GamePiece gamePiece) { + return xyBox.contains(new Vector2( + gamePiece.getPose3d().getX(), gamePiece.getPose3d().getY())) + && gamePiece.getPose3d().getZ() >= elevation.in(Units.Meters) + && gamePiece.getPose3d().getZ() <= elevation.in(Units.Meters) + height.in(Units.Meters); + } + + /** + * + * + *

Function to check wether the velocity of potential game pieces is acceptable.

+ * + * The default implementation of this function always returns true so any velocity checks will need to be + * implemented by children classes. + * + * @param gamePiece The game piece to have its velocity checked. + * @return Wether or not the pieces velocity is consistent with velocities that are able to be scored in this goal. + */ + protected boolean checkVel(GamePiece gamePiece) { + + return true; + } + + /** + * + * + *

Removes all game pieces from this goal

+ */ + public void clear() { + this.gamePieceCount = 0; + } + + /** + * + * + *

Returns wether or not this goal is full.

+ * + * @return wether or not the goal is full. + */ + public boolean isFull() { + return this.gamePieceCount == this.max; + } + + /** + * + * + *

Adds points when a piece has been successfully scored in this goal

+ * + * Since this function is the only trigger called when a piece is scored it may handle other small things outside of + * adding points. + */ + protected abstract void addPoints(); + + /** + * + * + *

Displays game pieces to advantage scope if applicable.

+ * + * @param drawList a list of {@link Pose3d} objects used to visualize the positions of the game pieces on + * AdvantageScope + */ + public abstract void draw(List drawList); + + /** + * + * + *

Returns the number of game pieces currently scored in this goal.

+ * + * @return This goals game piece count. + */ + public int getGamePieceCount() { + return gamePieceCount; + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/IntakeSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/IntakeSimulation.java new file mode 100644 index 0000000..29f8334 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/IntakeSimulation.java @@ -0,0 +1,406 @@ +package swervelib.simulation.ironmaple.simulation; + +import static edu.wpi.first.units.Units.Meters; + +import edu.wpi.first.math.MathUtil; +import edu.wpi.first.units.measure.Distance; +import java.util.ArrayDeque; +import java.util.Objects; +import java.util.Queue; +import java.util.function.Predicate; +import org.dyn4j.collision.CollisionBody; +import org.dyn4j.collision.Fixture; +import org.dyn4j.dynamics.Body; +import org.dyn4j.dynamics.BodyFixture; +import org.dyn4j.dynamics.contact.Contact; +import org.dyn4j.dynamics.contact.SolvedContact; +import org.dyn4j.geometry.Convex; +import org.dyn4j.geometry.Rectangle; +import org.dyn4j.geometry.Vector2; +import org.dyn4j.world.ContactCollisionData; +import org.dyn4j.world.listener.ContactListener; +import swervelib.simulation.ironmaple.simulation.drivesims.AbstractDriveTrainSimulation; +import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation; +import swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025.ReefscapeCoralAlgaeStack; + +/** + * + * + *

Simulates an Intake Mechanism on the Robot.

+ * + *

CheckOnline Documentation + * + *

The intake is a 2D component attached to one side of the robot's chassis. It is rectangular in shape and extends + * from the robot when activated. + * + *

The intake can be turned on through {@link #startIntake()}, which causes it to extend, expanding the collision + * space of the robot's chassis. When turned off via {@link #stopIntake()}, the intake retracts. + * + *

The intake can "collect" {@link GamePieceOnFieldSimulation} instances from the field, removing them and + * incrementing the {@link #gamePiecesInIntakeCount}. + * + *

A game piece is collected if the following conditions are met: + * + *

    + *
  • 1. The type of the game piece ({@link GamePieceOnFieldSimulation#type}) + * matches {@link #targetedGamePieceType}. + *
  • 2. The {@link GamePieceOnFieldSimulation} is in contact with the intake + * (and not other parts of the robot). + *
  • 3. The intake is turned on via {@link #startIntake()}. + *
  • 4. The number of game pieces in the intake ({@link #gamePiecesInIntakeCount}) is less than {@link #capacity}. + *
+ * + *

Note: This class simulates an idealized "touch it, get it" intake and does not model the actual + * functioning of an intake mechanism. + */ +public class IntakeSimulation extends BodyFixture { + private final int capacity; + private int gamePiecesInIntakeCount; + private boolean intakeRunning; + + private final Queue gamePiecesToRemove; + private final AbstractDriveTrainSimulation driveTrainSimulation; + private final String targetedGamePieceType; + private Predicate customIntakeCondition = gp -> true; + + public enum IntakeSide { + FRONT, + LEFT, + RIGHT, + BACK + } + + /** + * + * + *

Creates an Intake Simulation that Tightly Attaches to One Side of the Chassis.

+ * + *

This typically represents an In-The-Frame (ITF) Intake. + * + * @param targetedGamePieceType the type of game pieces that this intake can collect + * @param driveTrainSimulation the chassis to which this intake is attached + * @param width the width of the intake + * @param side the side of the chassis where the intake is attached + * @param capacity the maximum number of game pieces that the intake can hold + */ + public static IntakeSimulation InTheFrameIntake( + String targetedGamePieceType, + AbstractDriveTrainSimulation driveTrainSimulation, + Distance width, + IntakeSide side, + int capacity) { + return OverTheBumperIntake(targetedGamePieceType, driveTrainSimulation, width, Meters.of(0.02), side, capacity); + } + + /** + * + * + *

Creates an Intake Simulation that Extends Out of the Chassis Frame.

+ * + *

This typically represents an Over-The-Bumper (OTB) Intake. + * + * @param targetedGamePieceType the type of game pieces that this intake can collect + * @param driveTrainSimulation the chassis to which this intake is attached + * @param width the valid width of the intake + * @param lengthExtended the length the intake extends out from the chassis when activated + * @param side the side of the chassis where the intake is attached + * @param capacity the maximum number of game pieces that the intake can hold + * @return a new instance of {@link IntakeSimulation} that extends over the bumper + */ + public static IntakeSimulation OverTheBumperIntake( + String targetedGamePieceType, + AbstractDriveTrainSimulation driveTrainSimulation, + Distance width, + Distance lengthExtended, + IntakeSide side, + int capacity) { + return new IntakeSimulation( + targetedGamePieceType, + driveTrainSimulation, + getIntakeRectangle(driveTrainSimulation, width.in(Meters), lengthExtended.in(Meters), side), + capacity); + } + + private static Rectangle getIntakeRectangle( + AbstractDriveTrainSimulation driveTrainSimulation, double width, double lengthExtended, IntakeSide side) { + final Rectangle intakeRectangle = new Rectangle(width, lengthExtended); + intakeRectangle.rotate( + switch (side) { + case LEFT, RIGHT -> 0; + case FRONT, BACK -> Math.toRadians(90); + }); + final double distanceTransformed = lengthExtended / 2 - 0.01; + intakeRectangle.translate( + switch (side) { + case LEFT -> new Vector2( + 0, driveTrainSimulation.config.bumperWidthY.in(Meters) / 2 + distanceTransformed); + case RIGHT -> new Vector2( + 0, -driveTrainSimulation.config.bumperWidthY.in(Meters) / 2 - distanceTransformed); + case FRONT -> new Vector2( + driveTrainSimulation.config.bumperLengthX.in(Meters) / 2 + distanceTransformed, 0); + case BACK -> new Vector2( + -driveTrainSimulation.config.bumperLengthX.in(Meters) / 2 - distanceTransformed / 2, 0); + }); + + return intakeRectangle; + } + + /** + * + * + *

Creates an Intake Simulation with a Specific Shape.

+ * + *

This constructor initializes an intake with a custom shape that is used when the intake is fully extended. + * + * @param targetedGamePieceType the type of game pieces that this intake can collect + * @param driveTrainSimulation the chassis to which this intake is attached + * @param shape the shape of the intake when fully extended, represented as a {@link Convex} object + * @param capacity the maximum number of game pieces that the intake can hold + */ + public IntakeSimulation( + String targetedGamePieceType, + AbstractDriveTrainSimulation driveTrainSimulation, + Convex shape, + int capacity) { + super(shape); + super.setDensity(0); + + this.targetedGamePieceType = targetedGamePieceType; + this.gamePiecesInIntakeCount = 0; + + if (capacity > 100) throw new IllegalArgumentException("capacity too large, max is 100"); + this.capacity = capacity; + + this.gamePiecesToRemove = new ArrayDeque<>(capacity); + + this.intakeRunning = false; + this.driveTrainSimulation = driveTrainSimulation; + + register(); + } + + /** + * + * + *

Turns the Intake On.

+ * + *

Extends the intake out from the chassis, making it part of the chassis's collision space. + * + *

Once activated, the intake is considered running and will listen for contact with + * {@link GamePieceOnFieldSimulation} instances, allowing it to collect game pieces. + */ + public void startIntake() { + if (intakeRunning) return; + + driveTrainSimulation.addFixture(this); + this.intakeRunning = true; + } + + /** + * + * + *

Turns the Intake Off.

+ * + *

Retracts the intake into the chassis, removing it from the chassis's collision space. + * + *

Once turned off, the intake will no longer listen for or respond to contacts with + * {@link GamePieceOnFieldSimulation} instances. + */ + public void stopIntake() { + if (!intakeRunning) return; + + driveTrainSimulation.removeFixture(this); + this.intakeRunning = false; + } + + /** + * + * + *

Get the amount of game pieces in the intake.

+ * + * @return the amount of game pieces stored in the intake + */ + public int getGamePiecesAmount() { + return gamePiecesInIntakeCount; + } + + /** + * + * + *

Removes 1 game piece from the intake.

+ * + *

Deducts the {@link #getGamePiecesAmount()}} by 1, if there is any remaining. + * + *

This is used to obtain a game piece from the intake and move it a feeder/shooter. + * + * @return if there is game piece(s) remaining, and therefore retrieved + */ + public boolean obtainGamePieceFromIntake() { + if (gamePiecesInIntakeCount < 1) return false; + gamePiecesInIntakeCount--; + return true; + } + + /** + * + * + *

Adds 1 game piece from the intake.

+ * + *

Increases the {@link #getGamePiecesAmount()}} by 1, if there is still space. + * + * @return if there is still space in the intake to perform this action + */ + public boolean addGamePieceToIntake() { + boolean toReturn = gamePiecesInIntakeCount < capacity; + if (toReturn) gamePiecesInIntakeCount++; + + return toReturn; + } + + /** + * + * + *

Sets the amount of game pieces in the intake.

+ * + *

Sets the {@link #getGamePiecesAmount()}} to a given amount. + * + *

Will make sure that the amount is non-negative and does not exceed the capacity + * + * @return the actual (clamped) game piece count after performing this action + */ + public int setGamePiecesCount(int gamePiecesInIntakeCount) { + return this.gamePiecesInIntakeCount = MathUtil.clamp(gamePiecesInIntakeCount, 0, capacity); + } + + /** + * + * + *

The {@link ContactListener} for the Intake Simulation.

+ * + *

This class can be added to the simulation world to detect and manage contacts between the intake and + * {@link GamePieceOnFieldSimulation} instances of the type {@link #targetedGamePieceType}. + * + *

If contact is detected and the intake is running, the {@link GamePieceOnFieldSimulation} will be marked for + * removal from the field. + */ + public final class GamePieceContactListener implements ContactListener { + @Override + public void begin(ContactCollisionData collision, Contact contact) { + if (!intakeRunning) return; + if (gamePiecesInIntakeCount >= capacity) return; + + final CollisionBody collisionBody1 = collision.getBody1(), collisionBody2 = collision.getBody2(); + final Fixture fixture1 = collision.getFixture1(), fixture2 = collision.getFixture2(); + + if (collisionBody1 instanceof GamePieceOnFieldSimulation gamePiece + && Objects.equals(gamePiece.type, targetedGamePieceType) + && fixture2 == IntakeSimulation.this) flagGamePieceForRemoval(gamePiece); + else if (collisionBody2 instanceof GamePieceOnFieldSimulation gamePiece + && Objects.equals(gamePiece.type, targetedGamePieceType) + && fixture1 == IntakeSimulation.this) flagGamePieceForRemoval(gamePiece); + + boolean coralOrAlgaeIntake = "Coral".equals(IntakeSimulation.this.targetedGamePieceType) + || "Algae".equals(IntakeSimulation.this.targetedGamePieceType); + if (collisionBody1 instanceof ReefscapeCoralAlgaeStack stack + && coralOrAlgaeIntake + && fixture2 == IntakeSimulation.this) flagGamePieceForRemoval(stack); + else if (collisionBody2 instanceof ReefscapeCoralAlgaeStack stack + && coralOrAlgaeIntake + && fixture1 == IntakeSimulation.this) flagGamePieceForRemoval(stack); + } + + private void flagGamePieceForRemoval(GamePieceOnFieldSimulation gamePiece) { + if (!customIntakeCondition.test(gamePiece)) return; + gamePiecesToRemove.add(gamePiece); + gamePiecesInIntakeCount++; + } + + /* functions not used */ + @Override + public void persist(ContactCollisionData collision, Contact oldContact, Contact newContact) {} + + @Override + public void end(ContactCollisionData collision, Contact contact) {} + + @Override + public void destroyed(ContactCollisionData collision, Contact contact) {} + + @Override + public void collision(ContactCollisionData collision) {} + + @Override + public void preSolve(ContactCollisionData collision, Contact contact) {} + + @Override + public void postSolve(ContactCollisionData collision, SolvedContact contact) {} + } + + /** + * + * + *

Obtains a New Instance of the {@link GamePieceContactListener} for This Intake.

+ * + * @return a new {@link GamePieceContactListener} for this intake + */ + public GamePieceContactListener getGamePieceContactListener() { + return new GamePieceContactListener(); + } + + /** + * + * + *

Clears the game pieces that have been obtained by the intake.

+ * + *

This method is called from {@link SimulatedArena#simulationPeriodic()} to remove the + * {@link GamePieceOnFieldSimulation} instances that have been obtained by the intake from the field. + * + *

Game pieces are marked for removal if they have come into contact with the intake during the last + * {@link SimulatedArena#getSimulationSubTicksIn1Period()} sub-ticks. These game pieces should be removed from the + * field to reflect their interaction with the intake. + */ + public void removeObtainedGamePieces(SimulatedArena arena) { + while (!gamePiecesToRemove.isEmpty()) { + GamePieceOnFieldSimulation gamePiece = gamePiecesToRemove.poll(); + gamePiece.onIntake(this.targetedGamePieceType); + arena.removeGamePiece(gamePiece); + } + } + + public void register() { + register(SimulatedArena.getInstance()); + } + + public void register(SimulatedArena arena) { + arena.addIntakeSimulation(this); + } + + /** + * + * + *

Returns wether or not this intake is currently running

+ */ + public boolean isRunning() { + return intakeRunning; + } + + /** + * + * + *

Sets a Custom Intake Condition.

+ * + *

This method allows the user to define a custom condition for determining whether a game piece on the field can + * be collected by the intake. The condition is specified as a {@link Predicate} that takes a + * {@link GamePieceOnFieldSimulation} object as input and returns a boolean value. + * + *

The condition is used to determine whether a game piece should be collected by the intake. If the predicate + * returns true, the game piece will be collected by the intake. If the predicate returns false, the game piece will + * not be collected by the intake. Note how this predicate is only called if the game piece is in contact with the + * intake, and the intake is turned on, and it is the target game piece. + * + * @param customIntakeCondition a {@link Predicate} representing the custom condition for intake eligibility of game + * pieces on the field + */ + public void setCustomIntakeCondition(Predicate customIntakeCondition) { + this.customIntakeCondition = customIntakeCondition; + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java new file mode 100644 index 0000000..17e7b1c --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java @@ -0,0 +1,760 @@ +package swervelib.simulation.ironmaple.simulation; + +import static edu.wpi.first.units.Units.Seconds; + +import edu.wpi.first.math.geometry.Pose2d; +import edu.wpi.first.math.geometry.Pose3d; +import edu.wpi.first.math.geometry.Translation2d; +import edu.wpi.first.networktables.BooleanPublisher; +import edu.wpi.first.networktables.BooleanSubscriber; +import edu.wpi.first.networktables.DoublePublisher; +import edu.wpi.first.networktables.NetworkTable; +import edu.wpi.first.networktables.NetworkTableInstance; +import edu.wpi.first.units.Units; +import edu.wpi.first.units.measure.Time; +import edu.wpi.first.wpilibj.DriverStation; +import edu.wpi.first.wpilibj.DriverStation.Alliance; +import edu.wpi.first.wpilibj.RobotBase; +import edu.wpi.first.wpilibj.TimedRobot; +import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; +import java.util.*; +import org.dyn4j.dynamics.Body; +import org.dyn4j.dynamics.BodyFixture; +import org.dyn4j.geometry.Convex; +import org.dyn4j.geometry.Geometry; +import org.dyn4j.geometry.MassType; +import org.dyn4j.world.PhysicsWorld; +import org.dyn4j.world.World; +import swervelib.simulation.ironmaple.simulation.drivesims.AbstractDriveTrainSimulation; +import swervelib.simulation.ironmaple.simulation.gamepieces.GamePiece; +import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation; +import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceProjectile; +import swervelib.simulation.ironmaple.simulation.motorsims.SimulatedBattery; +import swervelib.simulation.ironmaple.simulation.seasonspecific.crescendo2024.CrescendoNoteOnField; +import swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025.Arena2025Reefscape; +import swervelib.simulation.ironmaple.utils.mathutils.GeometryConvertor; + +/** + * + * + *

Abstract Simulation World

+ * + *

Check Online + * Documentation + * + *

The heart of the simulator.

+ * + *

This class cannot be instantiated directly; it must be created as a specific season's arena. + * + *

The default instance can be obtained using the {@link #getInstance()} method. + * + *

Simulates all interactions within the arena field. + * + *

The following objects can be added to the simulation world and will interact with each other:

+ * + *
    + *
  • {@link AbstractDriveTrainSimulation}: Represents abstract drivetrain simulations with collision detection. + *
  • {@link GamePieceOnFieldSimulation}: Represents abstract game pieces with collision detection. + *
  • {@link IntakeSimulation}: Represents an intake simulation that responds to contact with + * {@link GamePieceOnFieldSimulation}. + *
+ */ +public abstract class SimulatedArena { + /** Whether to allow the simulation to run a real robot This feature is HIGHLY RECOMMENDED to be turned OFF */ + public static boolean ALLOW_CREATION_ON_REAL_ROBOT = false; + + protected int redScore = 0; + protected int blueScore = 0; + protected double matchClock = 0; + + public Map redScoringBreakdown = new Hashtable(); + public Map blueScoringBreakdown = new Hashtable(); + protected Map redPublishers = new Hashtable(); + protected Map bluePublishers = new Hashtable(); + + public NetworkTable redTable = + NetworkTableInstance.getDefault().getTable("SmartDashboard/MapleSim/MatchData/Breakdown/Red Alliance"); + public NetworkTable blueTable = + NetworkTableInstance.getDefault().getTable("SmartDashboard/MapleSim/MatchData/Breakdown/blue Alliance"); + public NetworkTable genericInfoTable = + NetworkTableInstance.getDefault().getTable("SmartDashboard/MapleSim/MatchData/Breakdown"); + + public DoublePublisher matchClockPublisher = + genericInfoTable.getDoubleTopic("Match Clock").publish(); + + public static BooleanPublisher resetFieldPublisher = NetworkTableInstance.getDefault() + .getTable("SmartDashboard/MapleSim/MatchData") + .getBooleanTopic("Reset Field") + .publish(); + + public static BooleanSubscriber resetFieldSubscriber = + resetFieldPublisher.getTopic().subscribe(false); + + Boolean shouldPublishMatchBreakdown = true; + + private static SimulatedArena instance = null; + /** + * + * + *

Gets/Creates the Default Simulation World

+ * + *

Multiple instances of {@link SimulatedArena} can exist elsewhere. + * + * @return the main simulation arena instance + * @throws IllegalStateException if the method is call when running on a real robot + */ + public static SimulatedArena getInstance() { + if (RobotBase.isReal() && (!ALLOW_CREATION_ON_REAL_ROBOT)) + throw new IllegalStateException( + "MapleSim is running on a real robot! (If you would actually want that, set SimulatedArena.ALLOW_CREATION_ON_REAL_ROBOT to true)."); + + if (instance == null) instance = new Arena2025Reefscape(); + + return instance; + } + + /** + * + * + *

Overrides the Default Simulation World

+ * + *

Overrides the return value of {@link #getInstance()} + * + *

This method allows simulating an arena from a different year or a custom field. + * + *

Currently, only the 2024 arena is supported, so avoid calling this method for now. + * + * @param newInstance the new simulation arena instance to override the current one + */ + public static void overrideInstance(SimulatedArena newInstance) { + instance = newInstance; + } + + /** The number of sub-ticks the simulator will run in each robot period. */ + private static int SIMULATION_SUB_TICKS_IN_1_PERIOD = 5; + + public static int getSimulationSubTicksIn1Period() { + return SIMULATION_SUB_TICKS_IN_1_PERIOD; + } + /** The period length of each sub-tick, in seconds. */ + private static Time SIMULATION_DT = Seconds.of(TimedRobot.kDefaultPeriod / SIMULATION_SUB_TICKS_IN_1_PERIOD); + + public static Time getSimulationDt() { + return SIMULATION_DT; + } + + /** + * + * + *

Returns the score of the specified team.

+ * + * @param isBlue The team to return the score of as a bool. + * @return The score of the specified team. + */ + public int getScore(boolean isBlue) { + return isBlue ? blueScore : redScore; + } + + /** + * + * + *

Returns the score of the specified team.

+ * + * @param allianceColor The team to return the score of as a Alliance enum. + * @return The score of the specified team. + */ + public int getScore(Alliance allianceColor) { + return getScore(allianceColor == Alliance.Blue); + } + + /** + * + * + *

Adds to the score of the specified team

+ * + * @param isBlue Wether to add to the blue or red team score. + * @param toAdd How many points to add. + */ + public void addToScore(boolean isBlue, int toAdd) { + if (isBlue) blueScore += toAdd; + else redScore += toAdd; + addValueToMatchBreakdown(isBlue, DriverStation.isAutonomous() ? "Auto/AutoScore" : "TeleopScore", toAdd); + } + + /** + * + * + *

Overrides the Timing Configurations of the Simulations.

+ * + *

If Using Advantage-Kit: DO NOT CHANGE THE + * DEFAULT TIMINGS

+ * + *

Changes apply to every instance of {@link SimulatedArena}. + * + *

The new configuration will take effect the next time {@link SimulatedArena#simulationPeriodic()} is called on + * an instance. + * + *

It is recommended to call this method before the first call to {@link SimulatedArena#simulationPeriodic()} of + * any instance. + * + *

It is also recommended to keep the simulation frequency above 200 Hz for accurate simulation results. + * + * @param robotPeriod the time between two calls of {@link #simulationPeriodic()}, usually obtained from + * {@link TimedRobot#getPeriod()} + * @param simulationSubTicksPerPeriod the number of Iterations, or {@link #simulationSubTick(int)} that the + * simulation runs per each call to {@link #simulationPeriodic()} + */ + public static synchronized void overrideSimulationTimings(Time robotPeriod, int simulationSubTicksPerPeriod) { + SIMULATION_SUB_TICKS_IN_1_PERIOD = simulationSubTicksPerPeriod; + SIMULATION_DT = robotPeriod.div(SIMULATION_SUB_TICKS_IN_1_PERIOD); + } + + protected final World physicsWorld; + protected final Set driveTrainSimulations; + + protected final Set gamePieces; + protected final List customSimulations; + + private final List intakeSimulations; + + /** + * + * + *

Constructs a new simulation arena with the specified field map of obstacles.

+ * + *

This constructor initializes a physics world with zero gravity and adds the provided obstacles to the world. + * + *

It also sets up the collections for drivetrain simulations, game pieces, projectiles, and intake simulations. + * + * @param obstaclesMap the season-specific field map containing the layout of obstacles for the simulation + */ + protected SimulatedArena(FieldMap obstaclesMap) { + this.physicsWorld = new World<>(); + this.physicsWorld.setGravity(PhysicsWorld.ZERO_GRAVITY); + for (Body obstacle : obstaclesMap.obstacles) this.physicsWorld.addBody(obstacle); + this.driveTrainSimulations = new HashSet<>(); + customSimulations = new ArrayList<>(); + this.gamePieces = new HashSet<>(); + this.intakeSimulations = new ArrayList<>(); + setupValueForMatchBreakdown("TotalScore"); + setupValueForMatchBreakdown("TeleopScore"); + setupValueForMatchBreakdown("Auto/AutoScore"); + resetFieldPublisher.set(false); + } + + /** + * + * + *

Represents a custom simulation to be updated during each simulation sub-tick.

+ * + *

This allows you to register custom actions that will be executed at a high frequency during each simulation + * sub-tick. This is useful for tasks that need to be updated multiple times per simulation cycle. + * + *

Examples of how this method is used: + * + *

    + *
  • Pulling encoder values for high-frequency odometry updates. + *
  • Adding custom simulation objects or handling events in the simulated arena. + *
+ */ + public interface Simulatable { + /** + * Called in {@link #simulationSubTick(int)}. + * + * @param subTickNum the number of this sub-tick (counting from 0 in each robot period) + */ + void simulationSubTick(int subTickNum); + } + + /** + * + * + *

Registers a custom simulation.

+ * + * @param simulatable the custom simulation to register + */ + public synchronized void addCustomSimulation(Simulatable simulatable) { + this.customSimulations.add(simulatable); + } + + /** + * + * + *

Registers an {@link IntakeSimulation}.

+ * + *

NOTE: This method is automatically called in the constructor of {@link IntakeSimulation}, so + * you don't need to call it manually. + * + *

The intake simulation should be bound to an {@link AbstractDriveTrainSimulation} and becomes part of its + * collision space. + * + *

This method immediately starts the {@link IntakeSimulation.GamePieceContactListener}, + * which listens for contact between the intake and any game piece. + * + * @param intakeSimulation the intake simulation to be registered + */ + protected synchronized void addIntakeSimulation(IntakeSimulation intakeSimulation) { + this.intakeSimulations.add(intakeSimulation); + this.physicsWorld.addContactListener(intakeSimulation.getGamePieceContactListener()); + } + + /** + * + * + *

Registers an {@link AbstractDriveTrainSimulation}.

+ * + *

The collision space of the drive train is immediately added to the simulation world. + * + *

Starting from the next call to {@link #simulationPeriodic()}, the + * {@link AbstractDriveTrainSimulation#simulationSubTick()} method will be called during each sub-tick of the + * simulator. + * + * @param driveTrainSimulation the drivetrain simulation to be registered + */ + public synchronized void addDriveTrainSimulation(AbstractDriveTrainSimulation driveTrainSimulation) { + this.physicsWorld.addBody(driveTrainSimulation); + + this.driveTrainSimulations.add(driveTrainSimulation); + } + + /** + * + * + *

Registers a {@link GamePieceOnFieldSimulation} to the Simulation.

+ * + *

The collision space of the game piece is immediately added to the simulation world. + * + *

{@link IntakeSimulation}s will be able to interact with this game piece during the next call to + * {@link SimulatedArena#simulationPeriodic()}. + * + * @param gamePiece the game piece to be registered in the simulation + */ + public synchronized void addGamePiece(GamePieceOnFieldSimulation gamePiece) { + this.physicsWorld.addBody(gamePiece); + this.gamePieces.add(gamePiece); + } + + /** + * + * + *

Tells the arena to start publishing the match breakdown data to network tables

+ */ + public void enableBreakdownPublishing() { + shouldPublishMatchBreakdown = true; + } + + /** + * + * + *

Tells the arena to stop publishing the match breakdown data to network tables

+ */ + public void disableBreakdownPublishing() { + shouldPublishMatchBreakdown = false; + } + + /** + * + * + *

Publishes the match breakdown data to network tables

+ */ + protected void publishBreakdown() { + + for (String key : redScoringBreakdown.keySet()) { + if (!redPublishers.containsKey(key)) + redPublishers.put(key, redTable.getDoubleTopic(key).publish()); + + redPublishers.get(key).set(redScoringBreakdown.get(key)); + } + for (String key : blueScoringBreakdown.keySet()) { + if (!bluePublishers.containsKey(key)) + bluePublishers.put(key, blueTable.getDoubleTopic(key).publish()); + + bluePublishers.get(key).set(blueScoringBreakdown.get(key)); + } + + // genericInfoTable.getDoubleTopic("currentMatchTime").publish().set(blueScore); + } + + /** + * + * + *

replaces or adds a value to the match scoring breakdown published to network tables

+ * + * @param isBlueTeam Wether to add to the blue teams match breakdown or the red teams match breakdown + * @param valueKey The name of the value to be added + * @param value The value to be added + */ + public void replaceValueInMatchBreakDown(boolean isBlueTeam, String valueKey, Double value) { + if (isBlueTeam) blueScoringBreakdown.put(valueKey, value); + else redScoringBreakdown.put(valueKey, value); + } + + /** + * + * + *

Defaults a value to 0 and creates it in the match breakdown. This is useful on startup to make sure all match + * breakdown values display before they are first updated

+ * + * @param valueKey The key to add to match breakdown + */ + public void setupValueForMatchBreakdown(String valueKey) { + replaceValueInMatchBreakDown(true, valueKey, 0); + replaceValueInMatchBreakDown(false, valueKey, 0); + } + + /** + * + * + *

replaces or adds a value to the match scoring breakdown published to network tables

+ * + * @param isBlueTeam Wether to add to the blue teams match breakdown or the red teams match breakdown + * @param valueKey The name of the value to be added + * @param value The value to be added + */ + public void replaceValueInMatchBreakDown(boolean isBlueTeam, String valueKey, Integer value) { + replaceValueInMatchBreakDown(isBlueTeam, valueKey, (double) value); + } + + /** + * + * + *

Adds too a value in the scoring breakdown. If value does not already exist in the scoring breakdown it will + * be defaulted to 0 and then added too + * + * @param isBlueTeam Wether to add to the blue teams match breakdown or the red teams match breakdown + * @param ValueKey The name of the value to be added too + * @param toAdd how much to be added to specified value + */ + public void addValueToMatchBreakdown(boolean isBlueTeam, String ValueKey, Double toAdd) { + if (isBlueTeam) { + if (blueScoringBreakdown.get(ValueKey) == null) blueScoringBreakdown.put(ValueKey, toAdd); + else blueScoringBreakdown.put(ValueKey, blueScoringBreakdown.get(ValueKey) + toAdd); + } else { + if (redScoringBreakdown.get(ValueKey) == null) redScoringBreakdown.put(ValueKey, toAdd); + else redScoringBreakdown.put(ValueKey, redScoringBreakdown.get(ValueKey) + toAdd); + } + } + + /** + * + * + *

Adds too a value in the scoring breakdown. If value does not already exist in the scoring breakdown it will + * be defaulted to 0 and then added too + * + * @param isBlueTeam Wether to add to the blue teams match breakdown or the red teams match breakdown + * @param ValueKey The name of the value to be added too + * @param toAdd how much to be added to specified value + */ + public void addValueToMatchBreakdown(boolean isBlueTeam, String valueKey, int toAdd) { + addValueToMatchBreakdown(isBlueTeam, valueKey, (double) toAdd); + } + + /** + * + * + *

Registers a {@link GamePieceProjectile} to the Simulation and Launches It.

+ * + *

Calls to {@link GamePieceProjectile#launch()}, which will launch the game piece immediately. + * + * @param gamePieceProjectile the projectile to be registered and launched in the simulation + */ + public synchronized void addGamePieceProjectile(GamePieceProjectile gamePieceProjectile) { + this.gamePieces.add(gamePieceProjectile); + gamePieceProjectile.launch(); + } + + /** + * + * + *

Removes a {@link GamePieceOnFieldSimulation} from the Simulation.

+ * + *

Removes the game piece from the physics world and the simulation's game piece collection. + * + * @param gamePiece the game piece to be removed from the simulation + * @return true if this set contained the specified element + */ + public synchronized boolean removeGamePiece(GamePieceOnFieldSimulation gamePiece) { + this.physicsWorld.removeBody(gamePiece); + return this.gamePieces.remove(gamePiece); + } + + public synchronized boolean removePiece(GamePiece toRemove) { + if (toRemove.isGrounded()) { + return removeGamePiece((GamePieceOnFieldSimulation) toRemove); + } + return removeProjectile((GamePieceProjectile) toRemove); + } + + /** + * + * + *

Removes a {@link GamePieceProjectile} from the Simulation.

+ * + *

Removes the game piece projectile from the simulation. + * + * @param gamePieceLaunched the game piece projectile to be removed from the simulation + * @return true if this set contained the specified element + */ + public synchronized boolean removeProjectile(GamePieceProjectile gamePieceLaunched) { + return this.gamePieces.remove(gamePieceLaunched); + } + + /** + * + * + *

Removes All {@link GamePieceOnFieldSimulation} Objects from the Simulation.

+ * + *

This method clears all game pieces from the physics world and the simulation's game piece collection. + */ + public synchronized void clearGamePieces() { + for (GamePieceOnFieldSimulation gamePiece : this.gamePiecesOnField()) this.physicsWorld.removeBody(gamePiece); + + this.gamePieces.clear(); + this.blueScore = 0; + this.redScore = 0; + } + + /** + * + * + *

Shuts down the current SimulatedArena and stops all simulation so that simulatable objects may be added to a + * new arena

+ */ + public synchronized void shutDown() { + this.physicsWorld.removeAllBodies(); + } + + /** + * + * + *

Update the simulation world.

+ * + *

This method should be called ONCE in {@link TimedRobot#simulationPeriodic()} (or + * LoggedRobot.simulationPeriodic() if using Advantage-Kit) + * + *

If not configured through {@link SimulatedArena#overrideSimulationTimings(Time, int)} , the simulator will + * iterate through 5 Sub-ticks by default. + * + *

The amount of CPU Time that the Dyn4j engine uses in displayed in + * SmartDashboard/MapleArenaSimulation/Dyn4jEngineCPUTimeMS, usually performance is not a concern + */ + public synchronized void simulationPeriodic() { + /* obtain lock to the simulated arena class to block any calls to overrideTimings() */ + synchronized (SimulatedArena.class) { + final long t0 = System.nanoTime(); + // move through a few sub-periods in each update + for (int i = 0; i < SIMULATION_SUB_TICKS_IN_1_PERIOD; i++) simulationSubTick(i); + + matchClock += getSimulationDt().in(Units.Seconds); + + SmartDashboard.putNumber("MapleArenaSimulation/Dyn4jEngineCPUTimeMS", (System.nanoTime() - t0) / 1000000.0); + + if (resetFieldSubscriber.get()) { + SimulatedArena.getInstance().resetFieldForAuto(); + resetFieldPublisher.set(false); + matchClock = 0; + } + } + } + + /** + * + * + *

Processes a Single Simulation Sub-Tick.

+ * + *

This method performs the actions for each sub-tick of the simulation, including: + * + *

    + *
  • Updating all registered {@link AbstractDriveTrainSimulation} objects. + *
  • Updating all {@link GamePieceProjectile} objects in the simulation. + *
  • Stepping the physics world with the specified sub-tick duration. + *
  • Removing any game pieces as detected by the {@link IntakeSimulation} objects. + *
  • Executing any additional sub-tick actions registered via + * {@link SimulatedArena#addCustomSimulation(Simulatable)} . + *
+ */ + protected void simulationSubTick(int subTickNum) { + SimulatedBattery.simulationSubTick(); + for (AbstractDriveTrainSimulation driveTrainSimulation : driveTrainSimulations) + driveTrainSimulation.simulationSubTick(); + + GamePieceProjectile.updateGamePieceProjectiles(this, this.gamePieceLaunched()); + + this.physicsWorld.step(1, SIMULATION_DT.in(Seconds)); + + for (IntakeSimulation intakeSimulation : intakeSimulations) intakeSimulation.removeObtainedGamePieces(this); + + for (Simulatable customSimulation : customSimulations) customSimulation.simulationSubTick(subTickNum); + + replaceValueInMatchBreakDown(true, "TotalScore", blueScore); + replaceValueInMatchBreakDown(false, "TotalScore", redScore); + + if (shouldPublishMatchBreakdown) { + publishBreakdown(); + matchClockPublisher.set(matchClock); + } + } + + /** + * + * + *

Returns a list of all grounded pieces on the field

+ * + * @return all grounded (aka not projectile) pieces on the field as a set of GamePieceOnFieldSimulation objects + */ + public synchronized Set gamePiecesOnField() { + Set returnList = new HashSet(); + for (GamePiece gamePiece : this.gamePieces) { + if (gamePiece.isGrounded()) { + returnList.add((GamePieceOnFieldSimulation) gamePiece); + } + } + + return returnList; + } + + /** + * + * + *

Returns a list of all projectile pieces on the field

+ * + * @return all projectile pieces on the field as a set of GamePieceProjectile objects + */ + public synchronized Set gamePieceLaunched() { + Set returnList = new HashSet(); + for (GamePiece gamePiece : this.gamePieces) { + if (!gamePiece.isGrounded()) { + returnList.add((GamePieceProjectile) gamePiece); + } + } + + return returnList; + } + + /** + * + * + *

Obtains the 3D Poses of a Specific Type of Game Piece.

+ * + *

This method is used to visualize the positions of game pieces + * + *

Also, if you have a game-piece detection vision system (wow!), this is the how you can + * simulate it. + * + *

Both {@link GamePieceOnFieldSimulation} and {@link GamePieceProjectile} of the specified type will be + * included. + * + *

    + *
  • The type is determined in the constructor of {@link GamePieceOnFieldSimulation}. + *
  • For example, {@link CrescendoNoteOnField} has the + * type "Note". + *
+ * + * @param type the type of game piece, as determined by the constructor of {@link GamePieceOnFieldSimulation} + * @return a {@link List} of {@link Pose3d} objects representing the 3D positions of the game pieces + */ + public synchronized List getGamePiecesPosesByType(String type) { + final List gamePiecesPoses = new ArrayList<>(); + for (GamePiece gamePiece : gamePieces) + if (Objects.equals(gamePiece.getType(), type)) gamePiecesPoses.add(gamePiece.getPose3d()); + + return gamePiecesPoses; + } + + /** + * + * + *

Obtains the 3D Poses of a Specific Type of Game Piece as an array.

+ * + * @see #getGamePiecesPosesByType(String) + */ + public synchronized Pose3d[] getGamePiecesArrayByType(String type) { + return getGamePiecesPosesByType(type).toArray(Pose3d[]::new); + } + + /** + * + * + *

Returns all game pieces on the field of the specified type as a list + * + * @param type The string type to be selected. + * @return The game pieces as a list of {@link GamePiece} + */ + public synchronized List getGamePiecesByType(String type) { + final List gamePiecesPoses = new ArrayList<>(); + for (GamePiece gamePiece : gamePieces) + if (Objects.equals(gamePiece.getType(), type)) gamePiecesPoses.add(gamePiece); + + return gamePiecesPoses; + } + + /** + * + * + *

Resets the Field for Autonomous Mode.

+ * + *

This method clears all current game pieces from the field and places new game pieces in their starting + * positions for the autonomous mode. + */ + public synchronized void resetFieldForAuto() { + clearGamePieces(); + matchClock = 0; + placeGamePiecesOnField(); + } + + /** + * + * + *

Places Game Pieces on the Field for Autonomous Mode.

+ * + *

This method sets up the game pieces on the field, typically in their starting positions for autonomous mode. + * + *

It should be implemented differently for each season-specific subclass of {@link SimulatedArena} to reflect + * the unique game piece placements for that season's game. + */ + public abstract void placeGamePiecesOnField(); + + /** + * + * + *

Represents an Abstract Field Map

+ * + *

Stores the layout of obstacles and game pieces. + * + *

For each season-specific subclass of {@link SimulatedArena}, there should be a corresponding subclass of this + * class to store the field map for that specific season's game. + */ + public abstract static class FieldMap { + private final List obstacles = new ArrayList<>(); + + protected void addBorderLine(Translation2d startingPoint, Translation2d endingPoint) { + addCustomObstacle( + Geometry.createSegment( + GeometryConvertor.toDyn4jVector2(startingPoint), + GeometryConvertor.toDyn4jVector2(endingPoint)), + new Pose2d()); + } + + protected void addRectangularObstacle(double width, double height, Pose2d absolutePositionOnField) { + addCustomObstacle(Geometry.createRectangle(width, height), absolutePositionOnField); + } + + protected void addCustomObstacle(Convex shape, Pose2d absolutePositionOnField) { + final Body obstacle = createObstacle(shape); + + obstacle.getTransform().set(GeometryConvertor.toDyn4jTransform(absolutePositionOnField)); + + obstacles.add(obstacle); + } + + private static Body createObstacle(Convex shape) { + final Body obstacle = new Body(); + obstacle.setMass(MassType.INFINITE); + final BodyFixture fixture = obstacle.addFixture(shape); + fixture.setFriction(0.6); + fixture.setRestitution(0.3); + return obstacle; + } + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/AbstractDriveTrainSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/AbstractDriveTrainSimulation.java new file mode 100644 index 0000000..a2278cb --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/AbstractDriveTrainSimulation.java @@ -0,0 +1,170 @@ +package swervelib.simulation.ironmaple.simulation.drivesims; + +import static edu.wpi.first.units.Units.Meters; + +import edu.wpi.first.math.geometry.Pose2d; +import edu.wpi.first.math.kinematics.ChassisSpeeds; +import edu.wpi.first.math.kinematics.SwerveModuleState; +import org.dyn4j.dynamics.Body; +import org.dyn4j.geometry.Geometry; +import org.dyn4j.geometry.MassType; +import swervelib.simulation.ironmaple.simulation.SimulatedArena; +import swervelib.simulation.ironmaple.simulation.drivesims.configs.DriveTrainSimulationConfig; +import swervelib.simulation.ironmaple.utils.mathutils.GeometryConvertor; + +/** + * + * + *

Represents an Abstract Drivetrain Simulation.

+ * + *

Simulates the Mass, Collision Space, and Friction of the Drivetrain.

+ * + *

This class models the physical properties of a drivetrain, including mass and collision space. + * + *

It also provides APIs to obtain the status (position, velocity etc.) in WPILib geometry classes. + * + *

The propelling forces generated by motors are simulated in its subclass, or {@link SwerveDriveSimulation}. + */ +public abstract class AbstractDriveTrainSimulation extends Body { + public static final double + BUMPER_COEFFICIENT_OF_FRICTION = 0.65, // https://en.wikipedia.org/wiki/Friction#Coefficient_of_friction + BUMPER_COEFFICIENT_OF_RESTITUTION = 0.08; // https://simple.wikipedia.org/wiki/Coefficient_of_restitution + + public final DriveTrainSimulationConfig config; + + /** + * + * + *

Creates a Simulation of a Drivetrain.

+ * + *

Sets Up the Collision Space and Mass of the Chassis.

+ * + *

Since this is an abstract class, the constructor must be called from a subclass. + * + *

Note that the chassis does not appear on the simulation field upon creation. Refer to + * {@link SimulatedArena} for instructions on how to add it to the simulation world. + * + * @param config a {@link DriveTrainSimulationConfig} instance containing the configurations of this drivetrain + * @param initialPoseOnField the initial pose of the drivetrain in the simulation world + */ + protected AbstractDriveTrainSimulation(DriveTrainSimulationConfig config, Pose2d initialPoseOnField) { + + this.config = config; + /* width and height in world reference is flipped */ + final double WIDTH_IN_WORLD_REFERENCE = config.bumperLengthX.in(Meters), + HEIGHT_IN_WORLD_REFERENCE = config.bumperWidthY.in(Meters); + + super.addFixture( + Geometry.createRectangle(WIDTH_IN_WORLD_REFERENCE, HEIGHT_IN_WORLD_REFERENCE), + config.getDensityKgPerSquaredMeters(), + BUMPER_COEFFICIENT_OF_FRICTION, + BUMPER_COEFFICIENT_OF_RESTITUTION); + + super.setMass(MassType.NORMAL); + super.setLinearDamping(0.1); + super.setAngularDamping(0.1); + setSimulationWorldPose(initialPoseOnField); + } + + /** + * + * + *

Sets the Robot's Current Pose in the Simulation World.

+ * + *

This method instantly teleports the robot to the specified pose in the simulation world. The robot does not + * drive to the new pose; it is moved directly. + * + * @param robotPose the desired robot pose, represented as a {@link Pose2d} + */ + public void setSimulationWorldPose(Pose2d robotPose) { + super.transform.set(GeometryConvertor.toDyn4jTransform(robotPose)); + super.linearVelocity.set(0, 0); + } + + /** + * + * + *

Sets the Robot's Speeds to the Given Chassis Speeds.

+ * + *

This method sets the robot's current velocity to the specified chassis speeds. + * + *

The robot does not accelerate smoothly to these speeds; instead, it jumps to the velocity + * Instantaneously. + * + * @param givenSpeeds the desired chassis speeds, represented as a {@link ChassisSpeeds} object + */ + public void setRobotSpeeds(ChassisSpeeds givenSpeeds) { + super.setLinearVelocity(GeometryConvertor.toDyn4jLinearVelocity(givenSpeeds)); + super.setAngularVelocity(givenSpeeds.omegaRadiansPerSecond); + } + + /** + * + * + *

Abstract Simulation Sub-Tick Method.

+ * + *

This method is called every time the simulation world is updated. + * + *

It is implemented in the sub-classes of {@link AbstractDriveTrainSimulation}. + * + *

It is responsible for applying the propelling forces to the robot during each sub-tick of the simulation. + */ + public abstract void simulationSubTick(); + + /** + * + * + *

Gets the Actual Pose of the Drivetrain in the Simulation World.

+ * + *

This method is used to display the robot on AdvantageScope Field3d or to update + * vision simulations. + * + *

Note: Do not use this method to simulate odometry! For a more realistic odometry simulation, + * use a {@link SwerveDriveSimulation} together with a + * {@link edu.wpi.first.math.estimator.SwerveDrivePoseEstimator}. + * + * @return a {@link Pose2d} object yielding the current world pose of the robot in the simulation + */ + public Pose2d getSimulatedDriveTrainPose() { + return GeometryConvertor.toWpilibPose2d(getTransform()); + } + + /** + * + * + *

Gets the Actual Robot-Relative Chassis Speeds from the Simulation.

+ * + *

This method returns the actual chassis speeds of the drivetrain in the simulation, relative to the robot. + * + *

To simulate the chassis speeds calculated by encoders, use a {@link SwerveDriveSimulation} together with + * {@link edu.wpi.first.math.kinematics.SwerveDriveKinematics#toChassisSpeeds(SwerveModuleState...)} for a more + * realistic simulation. + * + * @return the actual chassis speeds in the simulation world, Robot-Relative + */ + public ChassisSpeeds getDriveTrainSimulatedChassisSpeedsRobotRelative() { + ChassisSpeeds speeds = getDriveTrainSimulatedChassisSpeedsFieldRelative(); + speeds = ChassisSpeeds.fromFieldRelativeSpeeds( + speeds, getSimulatedDriveTrainPose().getRotation()); + return speeds; + } + + /** + * + * + *

Gets the Actual Field-Relative Chassis Speeds from the Simulation.

+ * + *

This method returns the actual chassis speeds of the drivetrain in the simulation, relative to the robot. + * + *

To simulate the chassis speeds calculated by encoders, use a {@link SwerveDriveSimulation} together with + * {@link edu.wpi.first.math.kinematics.SwerveDriveKinematics#toChassisSpeeds(SwerveModuleState...)} for a more + * realistic simulation. + * + * @return the actual chassis speeds in the simulation world, Field-Relative + */ + public ChassisSpeeds getDriveTrainSimulatedChassisSpeedsFieldRelative() { + return GeometryConvertor.toWpilibChassisSpeeds(getLinearVelocity(), getAngularVelocity()); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/COTS.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/COTS.java new file mode 100644 index 0000000..ef945ee --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/COTS.java @@ -0,0 +1,404 @@ +package swervelib.simulation.ironmaple.simulation.drivesims; + +import static edu.wpi.first.units.Units.*; +import static edu.wpi.first.units.Units.KilogramSquareMeters; + +import edu.wpi.first.math.system.plant.DCMotor; +import java.util.function.Supplier; +import swervelib.simulation.ironmaple.simulation.drivesims.configs.SwerveModuleSimulationConfig; + +public class COTS { + /** + * + * + *

Stores the coefficient of friction of some common used wheels.

+ * + *

Data comes from Spectrum + * 3847's Build Blog. + */ + public enum WHEELS { + /** Colsons Wheels. */ + COLSONS(0.899), + /** + * Default Neoprene Treads for Mark4 Modules + */ + DEFAULT_NEOPRENE_TREAD(1.426), + /** + * Blue Nitrile + * Tread from AndyMark. + */ + BLUE_NITRILE_TREAD(1.542), + /** Vex Grip V2 Wheel. */ + VEX_GRIP_V2(1.916), + /** + * Team 88's TPU90A Grippy Tire + */ + SLS_PRINTED_WHEELS(2.106); + + public final double cof; + + WHEELS(double cof) { + this.cof = cof; + } + } + + /** + * creates a SDS Mark4 + * Swerve Module for simulation + */ + public static SwerveModuleSimulationConfig ofMark4( + DCMotor driveMotor, DCMotor steerMotor, double wheelCOF, int gearRatioLevel) { + return new SwerveModuleSimulationConfig( + driveMotor, + steerMotor, + switch (gearRatioLevel) { + case 1 -> 8.14; + case 2 -> 6.75; + case 3 -> 6.12; + case 4 -> 5.14; + default -> throw new IllegalStateException("Unknown gearing level: " + gearRatioLevel); + }, + 12.8, + Volts.of(0.1), + Volts.of(0.2), + Inches.of(2), + KilogramSquareMeters.of(0.03), + wheelCOF); + } + + /** + * creates a SDS + * Mark4-i Swerve Module for simulation + */ + public static SwerveModuleSimulationConfig ofMark4i( + DCMotor driveMotor, DCMotor steerMotor, double wheelCOF, int gearRatioLevel) { + return new SwerveModuleSimulationConfig( + driveMotor, + steerMotor, + switch (gearRatioLevel) { + case 1 -> 8.14; + case 2 -> 6.75; + case 3 -> 6.12; + case 4 -> 5.15; + default -> throw new IllegalStateException("Unknown gearing level: " + gearRatioLevel); + }, + 150.0 / 7.0, + Volts.of(0.1), + Volts.of(0.2), + Inches.of(2), + KilogramSquareMeters.of(0.03), + wheelCOF); + } + + /** + * creates a SDS Mark4-n Swerve + * Module for simulation + */ + public static SwerveModuleSimulationConfig ofMark4n( + DCMotor driveMotor, DCMotor steerMotor, double wheelCOF, int gearRatioLevel) { + return new SwerveModuleSimulationConfig( + driveMotor, + steerMotor, + switch (gearRatioLevel) { + case 1 -> 7.13; + case 2 -> 5.9; + case 3 -> 5.36; + default -> throw new IllegalStateException("Unknown gearing level: " + gearRatioLevel); + }, + 18.75, + Volts.of(0.1), + Volts.of(0.2), + Inches.of(2), + KilogramSquareMeters.of(0.03), + wheelCOF); + } + + /** + * creates a WCP SwerveX Swerve Module + * for simulation + */ + public static SwerveModuleSimulationConfig ofSwerveX( + DCMotor driveMotor, DCMotor steerMotor, double wheelCOF, int gearRatioLevel, double firstStageRatio) { + double secondStageRatio = + switch (gearRatioLevel) { + case 1 -> 26.0 / 20.0; + case 2, 3 -> 28.0 / 18.0; + default -> throw new IllegalStateException("Unknown gearing level: " + gearRatioLevel); + }; + return new SwerveModuleSimulationConfig( + driveMotor, + steerMotor, + firstStageRatio * secondStageRatio, + 11.3142, + Volts.of(0.1), + Volts.of(0.2), + Inches.of(2), + KilogramSquareMeters.of(0.03), + wheelCOF); + } + + /** + * creates a WCP SwerveX Flipped + * Swerve Module for simulation + * + *

X1 Ratios are gearRatioLevel 1-3
+ * X2 Ratios are gearRatioLevel 4-6
+ * X3 Ratios are gearRatioLevel 7-9 + */ + public static SwerveModuleSimulationConfig ofSwerveXFlipped( + DCMotor driveMotor, DCMotor steerMotor, double wheelCOF, int gearRatioLevel, int pinionSize) { + var unknownPinionErr = new IllegalStateException("Unknown pinion size: " + pinionSize); + var unknownLevelErr = new IllegalStateException("Unknown gearing level: " + gearRatioLevel); + return new SwerveModuleSimulationConfig( + driveMotor, + steerMotor, + switch (gearRatioLevel) { + case 1 -> switch (pinionSize) { + case 10 -> 8.1; + case 11 -> 7.36; + case 12 -> 6.75; + default -> throw unknownPinionErr; + }; + case 2 -> switch (pinionSize) { + case 10 -> 6.72; + case 11 -> 6.11; + case 12 -> 5.6; + default -> throw unknownPinionErr; + }; + case 3 -> switch (pinionSize) { + case 10 -> 5.51; + case 11 -> 5.01; + case 12 -> 4.59; + default -> throw unknownPinionErr; + }; + default -> throw unknownLevelErr; + }, + 13.3714, + Volts.of(0.1), + Volts.of(0.2), + Inches.of(2), + KilogramSquareMeters.of(0.03), + wheelCOF); + } + + /** + * creates a WCP SwerveXS Swerve + * Module for simulation + */ + public static SwerveModuleSimulationConfig ofSwerveXS( + DCMotor driveMotor, DCMotor steerMotor, double wheelCOF, int gearRatioLevel, int pinionSize) { + var unknownPinionErr = new IllegalStateException("Unknown pinion size: " + pinionSize); + var unknownLevelErr = new IllegalStateException("Unknown gearing level: " + gearRatioLevel); + return new SwerveModuleSimulationConfig( + driveMotor, + steerMotor, + switch (gearRatioLevel) { + case 1 -> switch (pinionSize) { + case 12 -> 6; + case 13 -> 5.54; + case 14 -> 5.14; + default -> throw unknownPinionErr; + }; + case 2 -> switch (pinionSize) { + case 12 -> 4.71; + case 13 -> 4.4; + case 14 -> 4.13; + default -> throw unknownPinionErr; + }; + default -> throw unknownLevelErr; + }, + 41.25, + Volts.of(0.1), + Volts.of(0.2), + Inches.of(2), + KilogramSquareMeters.of(0.03), + wheelCOF); + } + + /** + * creates a WCP SwerveX2 Swerve + * Module for simulation + * + *

X1 Ratios are gearRatioLevel 1-3
+ * X2 Ratios are gearRatioLevel 4-6
+ * X3 Ratios are gearRatioLevel 7-9
+ * X4 Ratios are gearRatioLevel 10-12 + */ + public static SwerveModuleSimulationConfig ofSwerveX2( + DCMotor driveMotor, DCMotor steerMotor, double wheelCOF, int gearRatioLevel, int pinionSize) { + var unknownPinionErr = new IllegalStateException("Unknown pinion size: " + pinionSize); + var unknownLevelErr = new IllegalStateException("Unknown gearing level: " + gearRatioLevel); + return new SwerveModuleSimulationConfig( + driveMotor, + steerMotor, + switch (gearRatioLevel) { + case 1 -> switch (pinionSize) { + case 10 -> 7.67; + case 11 -> 6.98; + case 12 -> 6.39; + default -> throw unknownPinionErr; + }; + case 2 -> switch (pinionSize) { + case 10 -> 6.82; + case 11 -> 6.2; + case 12 -> 5.68; + default -> throw unknownPinionErr; + }; + case 3 -> switch (pinionSize) { + case 10 -> 6.48; + case 11 -> 5.89; + case 12 -> 5.4; + default -> throw unknownPinionErr; + }; + case 4 -> switch (pinionSize) { + case 10 -> 5.67; + case 11 -> 5.15; + case 12 -> 4.73; + default -> throw unknownPinionErr; + }; + default -> throw unknownLevelErr; + }, + 12.1, + Volts.of(0.1), + Volts.of(0.2), + Inches.of(2), + KilogramSquareMeters.of(0.03), + wheelCOF); + } + + /** + * creates a WCP SwerveX2S Swerve + * Module for simulation + */ + public static SwerveModuleSimulationConfig ofSwerveX2S( + DCMotor driveMotor, DCMotor steerMotor, double wheelCOF, int gearRatioLevel, int pinionSize) { + var unknownPinionErr = new IllegalStateException("Unknown pinion size: " + pinionSize); + var unknownLevelErr = new IllegalStateException("Unknown gearing level: " + gearRatioLevel); + return new SwerveModuleSimulationConfig( + driveMotor, + steerMotor, + switch (gearRatioLevel) { + case 1 -> switch (pinionSize) { + case 15 -> 6.0; + case 16 -> 5.63; + case 17 -> 5.29; + default -> throw unknownPinionErr; + }; + case 2 -> switch (pinionSize) { + case 17 -> 4.94; + case 18 -> 4.67; + case 19 -> 4.42; + default -> throw unknownPinionErr; + }; + case 3 -> switch (pinionSize) { + case 19 -> 4.11; + case 20 -> 3.9; + case 21 -> 3.71; + default -> throw unknownPinionErr; + }; + default -> throw unknownLevelErr; + }, + 25.9, + Volts.of(0.1), + Volts.of(0.2), + Inches.of(2), + KilogramSquareMeters.of(0.03), + wheelCOF); + } + + /** + * Creates a REV MAXSwerve swerve module for simulation + * + *

Base Kit ratios are gearRatioLevel 1-3
+ * Gear Ratio Upgrade Kit ratios are gearRatioLevel 4-8 + */ + public static SwerveModuleSimulationConfig ofMAXSwerve( + DCMotor driveMotor, DCMotor steerMotor, double wheelCOF, int gearRatioLevel) { + return new SwerveModuleSimulationConfig( + driveMotor, + steerMotor, + switch (gearRatioLevel) { + case 1 -> 5.5; + case 2 -> 5.08; + case 3 -> 4.71; + case 4 -> 4.50; + case 5 -> 4.29; + case 6 -> 4; + case 7 -> 3.75; + case 8 -> 3.56; + default -> throw new IllegalStateException("Unknown gearing level: " + gearRatioLevel); + }, + 9424.0 / 203.0, + Volts.of(0.1), + Volts.of(0.1), + Inches.of(1.5), + KilogramSquareMeters.of(0.02), + wheelCOF); + } + + /** + * Creates a TTB Thrifty Swerve swerve module + * for simulation + */ + public static SwerveModuleSimulationConfig ofThriftySwerve( + DCMotor driveMotor, DCMotor steerMotor, double wheelCOF, int gearRatioLevel) { + return new SwerveModuleSimulationConfig( + driveMotor, + steerMotor, + switch (gearRatioLevel) { + case 1 -> 6.75; + case 2 -> 6.23; + case 3 -> 5.79; + case 4 -> 6; + case 5 -> 5.54; + case 6 -> 5.14; + default -> throw new IllegalStateException("Unknown gearing level: " + gearRatioLevel); + }, + 25, + Volts.of(0.1), + Volts.of(0.2), + Inches.of(2), + KilogramSquareMeters.of(0.03), + wheelCOF); + } + + /** + * + * + *

Creates the Simulation for a CTRE Pigeon 2 IMU. + *

+ * + * @return a gyro simulation factory configured for the Pigeon 2 IMU + */ + public static Supplier ofPigeon2() { + /* + * user manual of pigeon 2: + * https://store.ctr-electronics.com/content/user-manual/Pigeon2%20User's%20Guide.pdf + * */ + return () -> new GyroSimulation(0.5, 0.02); + } + + /** + * + * + *

Creates the Simulation for a navX2-MXP IMU.

+ * + * @return a gyro simulation factory configured for the navX2-MXP IMU + */ + public static Supplier ofNav2X() { + return () -> new GyroSimulation(2, 0.04); + } + + /** + * + * + *

Creates the Simulation for a Generic, Low-Accuracy IMU.

+ * + * @return a gyro simulation factory configured for a generic low-accuracy IMU + */ + public static Supplier ofGenericGyro() { + return () -> new GyroSimulation(5, 0.06); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/GyroSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/GyroSimulation.java new file mode 100644 index 0000000..d7c06a8 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/GyroSimulation.java @@ -0,0 +1,212 @@ +package swervelib.simulation.ironmaple.simulation.drivesims; + +import static edu.wpi.first.units.Units.RadiansPerSecond; +import static edu.wpi.first.units.Units.Seconds; + +import edu.wpi.first.math.geometry.Rotation2d; +import edu.wpi.first.units.measure.AngularVelocity; +import edu.wpi.first.units.measure.Time; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import swervelib.simulation.ironmaple.simulation.SimulatedArena; +import swervelib.simulation.ironmaple.utils.mathutils.MapleCommonMath; + +/** + * Simulation for a IMU module used as gyro. + * + *

The Simulation is basically an indefinite integral of the angular velocity during each simulation sub ticks. Above + * that, it also musicales the measurement inaccuracy of the gyro, drifting in no-motion and drifting due to impacts. + */ +public class GyroSimulation { + private static final double + /* The threshold of instantaneous angular acceleration at which the chassis is considered to experience an "impact." */ + ANGULAR_ACCELERATION_THRESHOLD_START_DRIFTING = 500, + /* The amount of drift, in radians, that the gyro experiences as a result of each multiple of the angular acceleration threshold. */ + DRIFT_DUE_TO_IMPACT_COEFFICIENT = Math.toRadians(1); + private final double AVERAGE_DRIFTING_IN_30_SECS_MOTIONLESS_DEG, VELOCITY_MEASUREMENT_STANDARD_DEVIATION_PERCENT; + + private Rotation2d gyroReading; + private double measuredAngularVelocityRadPerSec, previousAngularVelocityRadPerSec; + private final Queue cachedRotations; + + /** + * + * + *

Creates a Gyro Simulation.

+ * + * @param AVERAGE_DRIFTING_IN_30_SECS_MOTIONLESS_DEG the average amount of drift, in degrees, the gyro experiences + * if it remains motionless for 30 seconds on a vibrating platform. This value can often be found in the user + * manual. + * @param VELOCITY_MEASUREMENT_STANDARD_DEVIATION_PERCENT the standard deviation of the velocity measurement, + * typically around 0.05 + */ + public GyroSimulation( + double AVERAGE_DRIFTING_IN_30_SECS_MOTIONLESS_DEG, double VELOCITY_MEASUREMENT_STANDARD_DEVIATION_PERCENT) { + this.AVERAGE_DRIFTING_IN_30_SECS_MOTIONLESS_DEG = AVERAGE_DRIFTING_IN_30_SECS_MOTIONLESS_DEG; + this.VELOCITY_MEASUREMENT_STANDARD_DEVIATION_PERCENT = VELOCITY_MEASUREMENT_STANDARD_DEVIATION_PERCENT; + + gyroReading = new Rotation2d(); + this.previousAngularVelocityRadPerSec = this.measuredAngularVelocityRadPerSec = 0; + this.cachedRotations = new ConcurrentLinkedQueue<>(); + for (int i = 0; i < SimulatedArena.getSimulationSubTicksIn1Period(); i++) cachedRotations.offer(gyroReading); + } + + /** + * + * + *

Calibrates the Gyro to a Given Rotation.

+ * + *

This method sets the current rotation of the gyro, similar to Pigeon2().setYaw() + * . + * + *

After setting the rotation, the gyro will continue to estimate the rotation by integrating the angular + * velocity, adding it to the specified rotation. + * + * @param currentRotation the current rotation of the robot, represented as a {@link Rotation2d} + */ + public void setRotation(Rotation2d currentRotation) { + this.gyroReading = currentRotation; + } + + /** + * + * + *

Obtains the Estimated Rotation of the Gyro.

+ * + *

This method returns the estimated rotation of the gyro, which includes measurement errors due to drifting and + * other factors. + * + * @return the current reading of the gyro, represented as a {@link Rotation2d} + */ + public Rotation2d getGyroReading() { + return gyroReading; + } + + /** + * + * + *

Gets the Measured Angular Velocity of the Gyro.

+ * + *

This method returns the angular velocity measured by the gyro, in radians per second. + * + *

The measurement includes random errors based on the configured settings of the gyro. + * + * @return the measured angular velocity + */ + public AngularVelocity getMeasuredAngularVelocity() { + return RadiansPerSecond.of(measuredAngularVelocityRadPerSec); + } + + /** + * gyro readings for high-frequency + * odometers. + * + * @return the readings of the gyro during the last 5 simulation sub ticks + */ + public Rotation2d[] getCachedGyroReadings() { + return cachedRotations.toArray(Rotation2d[]::new); + } + + /** + * + * + *

Updates the Gyro Simulation for Each Sub-Tick.

+ * + *

This method updates the gyro simulation and should be called during every sub-tick of the simulation. + * + *

If you are using this class outside of {@link SimulatedArena}: make sure to call it 5 + * times in each robot period (if using default timings), or refer to + * {@link SimulatedArena#overrideSimulationTimings(Time, int)}. + * + * @param actualAngularVelocityRadPerSec the actual angular velocity in radians per second, usually obtained from + * {@link AbstractDriveTrainSimulation#getAngularVelocity()} + */ + public void updateSimulationSubTick(double actualAngularVelocityRadPerSec) { + final Rotation2d driftingDueToImpact = getDriftingDueToImpact(actualAngularVelocityRadPerSec); + gyroReading = gyroReading.plus(driftingDueToImpact); + + final Rotation2d dTheta = getGyroDTheta(actualAngularVelocityRadPerSec); + gyroReading = gyroReading.plus(dTheta); + + final Rotation2d noMotionDrifting = getNoMotionDrifting(); + gyroReading = gyroReading.plus(noMotionDrifting); + + cachedRotations.poll(); + cachedRotations.offer(gyroReading); + } + + /** + * + * + *

Simulates IMU Drifting Due to Robot Impacts.

+ * + *

This method generates a random amount of drifting for the IMU if the instantaneous angular acceleration + * exceeds a threshold, simulating the effects of impacts on the robot. + * + * @param actualAngularVelocityRadPerSec the actual angular velocity in radians per second, used to determine if an + * impact is detected + * @return the amount of drifting the IMU will experience if an impact is detected, or + * Rotation2d.fromRadians(0) if no impact is detected + */ + private Rotation2d getDriftingDueToImpact(double actualAngularVelocityRadPerSec) { + final double + angularAccelerationRadPerSecSq = + (actualAngularVelocityRadPerSec - previousAngularVelocityRadPerSec) + / SimulatedArena.getSimulationDt().in(Seconds), + driftingDueToImpactDegAbsVal = + Math.abs(angularAccelerationRadPerSecSq) > ANGULAR_ACCELERATION_THRESHOLD_START_DRIFTING + ? Math.abs(angularAccelerationRadPerSecSq) + / ANGULAR_ACCELERATION_THRESHOLD_START_DRIFTING + * DRIFT_DUE_TO_IMPACT_COEFFICIENT + : 0, + driftingDueToImpactDeg = Math.copySign(driftingDueToImpactDegAbsVal, -angularAccelerationRadPerSecSq); + + previousAngularVelocityRadPerSec = actualAngularVelocityRadPerSec; + + return Rotation2d.fromRadians(driftingDueToImpactDeg); + } + + /** + * + * + *

Gets the Measured ΔTheta of the Gyro.

+ * + *

This method simulates the change in the robot's angle (ΔTheta) since the last sub-tick, as measured by the + * gyro. + * + *

The measurement includes random errors based on the configuration of the gyro. + * + * @param actualAngularVelocityRadPerSec the actual angular velocity in radians per second, used to calculate the + * ΔTheta + * @return the measured ΔTheta, including any measurement errors + */ + private Rotation2d getGyroDTheta(double actualAngularVelocityRadPerSec) { + this.measuredAngularVelocityRadPerSec = MapleCommonMath.generateRandomNormal( + actualAngularVelocityRadPerSec, + VELOCITY_MEASUREMENT_STANDARD_DEVIATION_PERCENT * Math.abs(actualAngularVelocityRadPerSec)); + return Rotation2d.fromRadians(measuredAngularVelocityRadPerSec + * SimulatedArena.getSimulationDt().in(Seconds)); + } + + /** + * + * + *

Generates the No-Motion Gyro Drifting.

+ * + *

This method simulates the minor drifting of the gyro that occurs regardless of whether the robot is moving or + * not. + * + * @return the amount of drifting generated while the robot is not moving + */ + private Rotation2d getNoMotionDrifting() { + final double + AVERAGE_DRIFTING_1_PERIOD = + this.AVERAGE_DRIFTING_IN_30_SECS_MOTIONLESS_DEG + / 30 + * SimulatedArena.getSimulationDt().in(Seconds), + driftingInThisPeriod = MapleCommonMath.generateRandomNormal(0, AVERAGE_DRIFTING_1_PERIOD); + + return Rotation2d.fromDegrees(driftingInThisPeriod); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SelfControlledSwerveDriveSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SelfControlledSwerveDriveSimulation.java new file mode 100644 index 0000000..906c96d --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SelfControlledSwerveDriveSimulation.java @@ -0,0 +1,580 @@ +package swervelib.simulation.ironmaple.simulation.drivesims; + +import static edu.wpi.first.units.Units.*; + +import edu.wpi.first.math.Matrix; +import edu.wpi.first.math.VecBuilder; +import edu.wpi.first.math.controller.PIDController; +import edu.wpi.first.math.estimator.SwerveDrivePoseEstimator; +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.kinematics.*; +import edu.wpi.first.math.numbers.N1; +import edu.wpi.first.math.numbers.N3; +import edu.wpi.first.units.measure.*; +import edu.wpi.first.wpilibj.Timer; +import java.util.Arrays; +import swervelib.simulation.ironmaple.simulation.SimulatedArena; +import swervelib.simulation.ironmaple.simulation.drivesims.configs.DriveTrainSimulationConfig; +import swervelib.simulation.ironmaple.simulation.motorsims.SimulatedMotorController; +import swervelib.simulation.ironmaple.utils.mathutils.SwerveStateProjection; + +/** + * + * + *

An easier way to simulate swerve drive.

+ * + *

Check Online Documentation + * + *

This class owns and controls a {@link SwerveDriveSimulation}, running closed loops/open loops on the simulated + * motors. + * + *

It works identically to how the real swerve simulation code. + * + *

Note: The order for swerve modules is: front-left, front-right, back-left, back-right. + */ +public class SelfControlledSwerveDriveSimulation { + private final SwerveDriveSimulation swerveDriveSimulation; + private final SelfControlledModuleSimulation[] moduleSimulations; + private final SwerveDriveKinematics kinematics; + private final SwerveDrivePoseEstimator poseEstimator; + private final SwerveModuleState[] setPointsOptimized; + + /** + * + * + *

Default Constructor.

+ * + *

Constructs a simplified swerve simulation with default standard deviations for odometry & vision pose + * estimates. + * + *

Odometry is simulated as high-frequency odometry, assuming a robot period of 0.02 seconds and an odometry + * frequency of 250 Hz. + * + * @param swerveDriveSimulation the {@link SwerveDriveSimulation} to control. + */ + public SelfControlledSwerveDriveSimulation(SwerveDriveSimulation swerveDriveSimulation) { + this(swerveDriveSimulation, VecBuilder.fill(0.1, 0.1, 0.1), VecBuilder.fill(0.9, 0.9, 0.9)); + } + + /** + * + * + *

Constructs an instance with given odometry standard deviations.

+ * + *

Constructs a simplified swerve simulation with specified standard deviations for odometry & vision pose + * estimates. + * + * @param swerveDriveSimulation the {@link SwerveDriveSimulation} to control. + * @param stateStdDevs the standard deviations for odometry encoders. + * @param visionMeasurementStdDevs the standard deviations for vision pose estimates. + */ + public SelfControlledSwerveDriveSimulation( + SwerveDriveSimulation swerveDriveSimulation, + Matrix stateStdDevs, + Matrix visionMeasurementStdDevs) { + this.swerveDriveSimulation = swerveDriveSimulation; + this.moduleSimulations = Arrays.stream(swerveDriveSimulation.getModules()) + .map(SelfControlledModuleSimulation::new) + .toArray(SelfControlledModuleSimulation[]::new); + + this.kinematics = swerveDriveSimulation.kinematics; + + this.poseEstimator = new SwerveDrivePoseEstimator( + kinematics, + getRawGyroAngle(), + getLatestModulePositions(), + getActualPoseInSimulationWorld(), + stateStdDevs, + visionMeasurementStdDevs); + + this.setPointsOptimized = new SwerveModuleState[moduleSimulations.length]; + Arrays.fill(setPointsOptimized, new SwerveModuleState()); + } + + /** + * + * + *

Periodic Method for Simplified Swerve Sim.

+ * + *

Call this method in the {@link edu.wpi.first.wpilibj2.command.Subsystem#periodic()} of your swerve subsystem. + * + *

Updates the odometry by fetching cached inputs. + */ + public void periodic() { + final SwerveModulePosition[][] cachedModulePositions = getCachedModulePositions(); + for (int i = 0; i < SimulatedArena.getSimulationSubTicksIn1Period(); i++) + poseEstimator.updateWithTime( + Timer.getFPGATimestamp() + - SimulatedArena.getSimulationDt().in(Seconds) + * (SimulatedArena.getSimulationDt().in(Seconds) - i), + swerveDriveSimulation.gyroSimulation.getCachedGyroReadings()[i], + cachedModulePositions[i]); + } + + /** + * + * + *

Obtains the LATEST module positions measured by the encoders.

+ * + *

The order for swerve modules is: front-left, front-right, back-left, back-right. + * + * @return the module positions + */ + public SwerveModulePosition[] getLatestModulePositions() { + return Arrays.stream(moduleSimulations) + .map(SelfControlledModuleSimulation::getModulePosition) + .toArray(SwerveModulePosition[]::new); + } + + /** + * + * + *

Obtains the CACHED module positions measured by the encoders.

+ * + *

This simulates high-frequency odometry. + * + *

The module positions, or the value of {@link #getLatestModulePositions()} are cached in every simulation + * sub-tick. + * + *

The array is ordered in a [timeStampIndex][moduleIndex] format. + * + *

The order for swerve modules is: front-left, front-right, back-left, back-right. + * + * @return the cached module positions + */ + public SwerveModulePosition[][] getCachedModulePositions() { + final SwerveModulePosition[][] cachedModulePositions = + new SwerveModulePosition[SimulatedArena.getSimulationSubTicksIn1Period()][moduleSimulations.length]; + + for (int moduleIndex = 0; moduleIndex < moduleSimulations.length; moduleIndex++) { + final Angle[] wheelPosition = moduleSimulations[moduleIndex].instance.getCachedDriveWheelFinalPositions(); + final Rotation2d[] swerveModuleFacings = + moduleSimulations[moduleIndex].instance.getCachedSteerAbsolutePositions(); + for (int timeStamp = 0; timeStamp < SimulatedArena.getSimulationSubTicksIn1Period(); timeStamp++) + cachedModulePositions[timeStamp][moduleIndex] = new SwerveModulePosition( + wheelPosition[timeStamp].in(Radians) + * moduleSimulations[0].instance.config.WHEEL_RADIUS.in(Meters), + swerveModuleFacings[timeStamp]); + } + + return cachedModulePositions; + } + + /** + * + * + *

Obtains the raw angle of the gyro.

+ * + *

Note that the simulated gyro also drifts/skids like real gyros, especially if the robot collides. + * + *

To obtain the facing of the robot retrieved from the odometry, use {@link #getOdometryEstimatedPose()}; to + * obtain the actual facing of the robot, use {@link #getActualPoseInSimulationWorld()}. + * + * @deprecated This rotation is NOT the actual facing of the robot; it is uncalibrated and is only + * used for features like rotation lock. + * @return the raw (uncalibrated) angle of the simulated gyro. + */ + @Deprecated + public Rotation2d getRawGyroAngle() { + return swerveDriveSimulation.gyroSimulation.getGyroReading(); + } + + /** + * + * + *

Obtains the robot pose measured by the odometry.

+ * + *

Retrieves the pose estimated by the odometry system (and vision, if applicable). + * + *

This method wraps around {@link SwerveDrivePoseEstimator#getEstimatedPosition()}. + * + *

This represents the estimated position of the robot. + * + *

Note that this estimation includes realistic simulations of measurement errors due to skidding and odometry + * drift. + * + *

To obtain the ACTUAL pose of the robot, with no measurement errors, use + * {@link #getActualPoseInSimulationWorld()}. + */ + public Pose2d getOdometryEstimatedPose() { + return poseEstimator.getEstimatedPosition(); + } + + /** + * + * + *

Resets the odometry to a specified position.

+ * + *

This method wraps around {@link SwerveDrivePoseEstimator#resetPosition(Rotation2d, SwerveModulePosition[], + * Pose2d)}. + * + *

It resets the position of the pose estimator to the given pose. + * + * @param pose The position on the field where the robot is located. + */ + public void resetOdometry(Pose2d pose) { + this.poseEstimator.resetPosition(getRawGyroAngle(), getLatestModulePositions(), pose); + } + + /** + * + * + *

Adds a vision estimation to the pose estimator.

+ * + *

This method wraps around {@link SwerveDrivePoseEstimator#addVisionMeasurement(Pose2d, double)}. + * + *

Adds a vision measurement to the Kalman Filter, correcting the odometry pose estimate while accounting for + * measurement noise. + * + * @param robotPoseMeters The pose of the robot as measured by the vision camera. + * @param timeStampSeconds The timestamp of the vision measurement, in seconds. + */ + public void addVisionEstimation(Pose2d robotPoseMeters, double timeStampSeconds) { + this.poseEstimator.addVisionMeasurement(robotPoseMeters, timeStampSeconds); + } + + /** + * + * + *

Adds a vision estimation to the pose estimator.

+ * + *

This method wraps around {@link SwerveDrivePoseEstimator#addVisionMeasurement(Pose2d, double, Matrix)}. + * + *

Adds a vision measurement to the Kalman Filter, correcting the odometry pose estimate while accounting for + * measurement noise. + * + * @param robotPoseMeters The pose of the robot as measured by the vision camera. + * @param timeStampSeconds The timestamp of the vision measurement, in seconds. + * @param measurementStdDevs Standard deviations of the vision pose measurement (x position in meters, y position in + * meters, and heading in radians). Increase these values to reduce the trust in the vision pose measurement. + */ + public void addVisionEstimation( + Pose2d robotPoseMeters, double timeStampSeconds, Matrix measurementStdDevs) { + this.poseEstimator.addVisionMeasurement(robotPoseMeters, timeStampSeconds, measurementStdDevs); + } + + /** + * + * + *

Runs chassis speeds on the simulated swerve drive.

+ * + *

Runs the specified chassis speeds, either robot-centric or field-centric. + * + * @param chassisSpeeds The speeds to run, in either robot-centric or field-centric coordinates. + * @param centerOfRotationMeters The center of rotation. For example, if you set the center of rotation at one + * corner of the robot and provide a chassis speed that has only a dtheta component, the robot will rotate + * around that corner. + * @param fieldCentricDrive Whether to execute field-centric drive with the provided speed. + * @param discretizeSpeeds Whether to apply {@link ChassisSpeeds#discretize(ChassisSpeeds, double)} to the provided + * speed. + */ + public void runChassisSpeeds( + ChassisSpeeds chassisSpeeds, + Translation2d centerOfRotationMeters, + boolean fieldCentricDrive, + boolean discretizeSpeeds) { + if (fieldCentricDrive) { + chassisSpeeds = ChassisSpeeds.fromFieldRelativeSpeeds( + chassisSpeeds, getOdometryEstimatedPose().getRotation()); + } + if (discretizeSpeeds) { + chassisSpeeds = ChassisSpeeds.discretize( + chassisSpeeds, + SimulatedArena.getSimulationDt().in(Seconds) * SimulatedArena.getSimulationSubTicksIn1Period()); + } + final SwerveModuleState[] setPoints = kinematics.toSwerveModuleStates(chassisSpeeds, centerOfRotationMeters); + runSwerveStates(setPoints); + } + + /** + * + * + *

Runs a raw module states on the chassis.

+ * + *

Runs the specified module states on the modules. + * + * @param setPoints an array of {@link SwerveModuleState} yielding the requested states + */ + public void runSwerveStates(SwerveModuleState[] setPoints) { + for (int i = 0; i < moduleSimulations.length; i++) + setPointsOptimized[i] = moduleSimulations[i].optimizeAndRunModuleState(setPoints[i]); + } + + /** + * + * + *

Obtain the MEASURED swerve states.

+ * + *

The order of the swerve modules is: front-left, front-right, back-left, back-right. + * + * @return The actual measured swerve states of the simulated swerve. + */ + public SwerveModuleState[] getMeasuredStates() { + return Arrays.stream(moduleSimulations) + .map(SelfControlledModuleSimulation::getMeasuredState) + .toArray(SwerveModuleState[]::new); + } + + /** + * + * + *

Obtain the optimized SETPOINTS of the swerve.

+ * + *

The setpoints are calculated using {@link SwerveDriveKinematics#toSwerveModuleStates(ChassisSpeeds)} in the + * most recent call to {@link #runChassisSpeeds(ChassisSpeeds, Translation2d, boolean, boolean)}. + * + *

The setpoints are optimized using {@link SwerveModuleState#optimize(SwerveModuleState, Rotation2d)}. + * + *

The order of the swerve modules is: front-left, front-right, back-left, back-right. + * + * @return The optimized setpoints of the swerve, calculated during the last chassis speed run. + */ + public SwerveModuleState[] getSetPointsOptimized() { + return setPointsOptimized; + } + + /** + * + * + *

Obtain the field-relative chassis speeds measured from the encoders.

+ * + *

The speeds are measured from the simulated swerve modules. + * + * @param useGyroForAngularVelocity Whether to use the gyro for a more accurate angular velocity measurement. + * @return The measured chassis speeds, field-relative. + */ + public ChassisSpeeds getMeasuredSpeedsFieldRelative(boolean useGyroForAngularVelocity) { + ChassisSpeeds speeds = getMeasuredSpeedsRobotRelative(useGyroForAngularVelocity); + speeds = ChassisSpeeds.fromRobotRelativeSpeeds( + speeds, getOdometryEstimatedPose().getRotation()); + return speeds; + } + + /** + * + * + *

Obtain the robot-relative chassis speeds measured from the encoders.

+ * + *

The speeds are measured from the simulated swerve modules. + * + * @param useGyroForAngularVelocity Whether to use the gyro for a more accurate angular velocity measurement. + * @return The measured chassis speeds, robot-relative. + */ + public ChassisSpeeds getMeasuredSpeedsRobotRelative(boolean useGyroForAngularVelocity) { + final ChassisSpeeds swerveSpeeds = kinematics.toChassisSpeeds(getMeasuredStates()); + return new ChassisSpeeds( + swerveSpeeds.vxMetersPerSecond, + swerveSpeeds.vyMetersPerSecond, + useGyroForAngularVelocity + ? swerveDriveSimulation + .gyroSimulation + .getMeasuredAngularVelocity() + .in(RadiansPerSecond) + : swerveSpeeds.omegaRadiansPerSecond); + } + + /** + * + * + *

Obtain the {@link SwerveDriveSimulation} object controlled by this simplified swerve simulation.

+ * + * @return The swerve drive simulation. + */ + public SwerveDriveSimulation getDriveTrainSimulation() { + return this.swerveDriveSimulation; + } + + /** + * + * + *

Obtain the ACTUAL robot pose.

+ * + *

Obtains the ACTUAL robot pose with zero measurement error. + * + *

To obtain the pose calculated by odometry (where the robot thinks it is), use + * {@link #getOdometryEstimatedPose()}. + */ + public Pose2d getActualPoseInSimulationWorld() { + return swerveDriveSimulation.getSimulatedDriveTrainPose(); + } + + /** + * + * + *

Get the ACTUAL field-relative chassis speeds of the robot.

+ * + *

Wraps around {@link SwerveDriveSimulation#getDriveTrainSimulatedChassisSpeedsFieldRelative()}. + * + * @return the actual chassis speeds in the simulation world, field-relative + */ + public ChassisSpeeds getActualSpeedsFieldRelative() { + return this.swerveDriveSimulation.getDriveTrainSimulatedChassisSpeedsFieldRelative(); + } + + /** + * + * + *

Get the ACTUAL robot-relative chassis speeds of the robot.

+ * + *

Wraps around {@link SwerveDriveSimulation#getDriveTrainSimulatedChassisSpeedsRobotRelative()}. + * + * @return the actual chassis speeds in the simulation world, robot-relative + */ + public ChassisSpeeds getActualSpeedsRobotRelative() { + return this.swerveDriveSimulation.getDriveTrainSimulatedChassisSpeedsRobotRelative(); + } + + /** + * + * + *

Teleport the robot to a specified location on the simulated field.

+ * + *

This method moves the drivetrain instantly to the specified location on the field, bypassing any obstacles in + * its path. + * + *

Wraps around {@link SwerveDriveSimulation#setSimulationWorldPose(Pose2d)}. + * + * @param robotPose the pose of the robot to teleport to + */ + public void setSimulationWorldPose(Pose2d robotPose) { + this.swerveDriveSimulation.setSimulationWorldPose(robotPose); + } + + public SelfControlledSwerveDriveSimulation withSteerPID(PIDController steerController) { + for (SelfControlledModuleSimulation moduleSimulation : moduleSimulations) + moduleSimulation.withSteerPID( + new PIDController(steerController.getP(), steerController.getI(), steerController.getD())); + return this; + } + + public SelfControlledSwerveDriveSimulation withCurrentLimits(Current driveCurrentLimit, Current steerCurrentLimit) { + for (SelfControlledModuleSimulation moduleSimulation : moduleSimulations) + moduleSimulation.withCurrentLimits(driveCurrentLimit, steerCurrentLimit); + + return this; + } + + public static class SelfControlledModuleSimulation { + public final SwerveModuleSimulation instance; + private Current driveCurrentLimit; + + private PIDController steerController; + + private final SimulatedMotorController.GenericMotorController driveMotor; + private final SimulatedMotorController.GenericMotorController steerMotor; + + public SelfControlledModuleSimulation(SwerveModuleSimulation moduleSimulation) { + this.instance = moduleSimulation; + steerController = new PIDController(5.0, 0, 0); + + this.driveMotor = this.instance.useGenericMotorControllerForDrive(); + this.driveMotor.withCurrentLimit(this.driveCurrentLimit = Amps.of(60)); + this.steerMotor = this.instance.useGenericControllerForSteer(); + } + + public SelfControlledModuleSimulation withSteerPID(PIDController steerController) { + this.steerController = steerController; + steerController.enableContinuousInput(-Math.PI, Math.PI); + return this; + } + + public SelfControlledModuleSimulation withCurrentLimits(Current driveCurrentLimit, Current steerCurrentLimit) { + this.driveMotor.withCurrentLimit(this.driveCurrentLimit = driveCurrentLimit); + this.steerMotor.withCurrentLimit(steerCurrentLimit); + steerController.enableContinuousInput(-Math.PI, Math.PI); + return this; + } + + /** + * + * + *

Runs the control loops for swerve states on a simulated module.

+ * + *

Optimizes the set-point using {@link SwerveModuleState#optimize(SwerveModuleState, Rotation2d)}. + * + *

Executes a closed-loop control on the swerve module. + * + * @param setPoint the desired state to optimize and apply + * @return the optimized swerve module state after control execution + */ + public SwerveModuleState optimizeAndRunModuleState(SwerveModuleState setPoint) { + setPoint.optimize(instance.getSteerAbsoluteFacing()); + runModuleState(setPoint); + return setPoint; + } + + public void runModuleState(SwerveModuleState setPoint) { + final double + cosProjectedSpeedMPS = SwerveStateProjection.project(setPoint, instance.getSteerAbsoluteFacing()), + driveWheelVelocitySetPointRadPerSec = + cosProjectedSpeedMPS / instance.config.WHEEL_RADIUS.in(Meters); + + driveMotor.requestVoltage(instance.config.driveMotorConfigs.calculateVoltage( + Amps.of(0), RadiansPerSecond.of(driveWheelVelocitySetPointRadPerSec))); + + steerMotor.requestVoltage(Volts.of(steerController.calculate( + instance.getSteerAbsoluteFacing().getRadians(), setPoint.angle.getRadians()))); + } + + public void runDriveMotorCharacterization(Rotation2d desiredModuleFacing, double volts) { + driveMotor.requestVoltage(Volts.of(volts)); + + steerMotor.requestVoltage(Volts.of(steerController.calculate( + instance.getSteerAbsoluteFacing().getRadians(), desiredModuleFacing.getRadians()))); + } + + public void runSteerMotorCharacterization(double volts) { + driveMotor.requestVoltage(Volts.zero()); + + steerMotor.requestVoltage(Volts.of(volts)); + } + + public SwerveModuleState getMeasuredState() { + return instance.getCurrentState(); + } + + public SwerveModulePosition getModulePosition() { + return new SwerveModulePosition( + instance.getDriveWheelFinalPosition().in(Radians) * instance.config.WHEEL_RADIUS.in(Meters), + instance.getSteerAbsoluteFacing()); + } + } + + /** @see SwerveDriveSimulation#maxLinearVelocity() */ + public LinearVelocity maxLinearVelocity() { + return swerveDriveSimulation.maxLinearVelocity(); + } + + /** @see SwerveDriveSimulation#maxLinearAcceleration(Current) */ + public LinearAcceleration maxLinearAcceleration() { + return swerveDriveSimulation.maxLinearAcceleration(moduleSimulations[0].driveCurrentLimit); + } + + /** @see DriveTrainSimulationConfig#trackWidthY() */ + public Distance trackWidthY() { + return swerveDriveSimulation.config.trackWidthY(); + } + + /** @see DriveTrainSimulationConfig#trackLengthX() */ + public Distance trackLengthX() { + return swerveDriveSimulation.config.trackLengthX(); + } + + /** @see SwerveDriveSimulation#driveBaseRadius() */ + public Distance driveBaseRadius() { + return swerveDriveSimulation.config.driveBaseRadius(); + } + + /** @see SwerveDriveSimulation#maxAngularVelocity() */ + public AngularVelocity maxAngularVelocity() { + return RadiansPerSecond.of( + maxLinearVelocity().in(MetersPerSecond) / driveBaseRadius().in(Meters)); + } + + /** @see SwerveDriveSimulation#maxAngularAcceleration(Current) */ + public AngularAcceleration maxAngularAcceleration() { + return swerveDriveSimulation.maxAngularAcceleration(moduleSimulations[0].driveCurrentLimit); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SwerveDriveSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SwerveDriveSimulation.java new file mode 100644 index 0000000..6af5bc6 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SwerveDriveSimulation.java @@ -0,0 +1,368 @@ +package swervelib.simulation.ironmaple.simulation.drivesims; + +import static edu.wpi.first.units.Units.*; + +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.kinematics.ChassisSpeeds; +import edu.wpi.first.math.kinematics.SwerveDriveKinematics; +import edu.wpi.first.math.kinematics.SwerveModuleState; +import edu.wpi.first.units.measure.*; +import java.util.Arrays; +import java.util.function.Supplier; +import org.dyn4j.geometry.Vector2; +import swervelib.simulation.ironmaple.simulation.SimulatedArena; +import swervelib.simulation.ironmaple.simulation.drivesims.configs.DriveTrainSimulationConfig; +import swervelib.simulation.ironmaple.utils.mathutils.GeometryConvertor; +import swervelib.simulation.ironmaple.utils.mathutils.MapleCommonMath; +import swervelib.simulation.ironmaple.simulation.drivesims.configs.SwerveModuleSimulationConfig; + +/** + * + * + *

Simulates a Swerve Drivetrain.

+ * + *

Check Online + * Documentation + * + *

1. Purpose

+ * + *

This class simulates a swerve drivetrain composed of more than two {@link SwerveModuleSimulation} modules. + * + *

It provides a realistic modeling of drivetrain physics, replicating wheel grip and motor propulsion for an actual + * swerve drive. + * + *

2. Simulation Dynamics

+ * + *
    + *
  • 1. Propelling forces generated by the drive motors, computed by + * {@link SwerveModuleSimulation#updateSimulationSubTickGetModuleForce(Vector2, Rotation2d, double)}. + *
  • 2. Friction forces generated by the wheels that "pull" the robot from its current ground velocity to the module + * velocities, both translational and rotational. + *
  • 3. Centripetal forces generated by the steering when the drivetrain makes a turn. + *
+ * + *

3. Odometry Simulation

+ * + *

To simulate odometry, follow these steps: + * + *

    + *
  • Obtain the {@link SwerveModuleSimulation} instances through {@link #getModules()}. + *
  • Create an IO + * Implementation that wraps around {@link SwerveModuleSimulation} to retrieve encoder readings. + *
  • Update a {@link edu.wpi.first.math.estimator.SwerveDrivePoseEstimator} using the encoder readings, similar to + * how you would on a real robot. + *
+ * + *

Refer to the ModuleIOSim.java + * example project for more details. + * + *

Vision Simulation

+ * + *

You can obtain the real robot pose from {@link #getSimulatedDriveTrainPose()} and feed it to the PhotonVision + * simulation to simulate vision. + */ +public class SwerveDriveSimulation extends AbstractDriveTrainSimulation { + private final SwerveModuleSimulation[] moduleSimulations; + protected final GyroSimulation gyroSimulation; + protected final Translation2d[] moduleTranslations; + protected final SwerveDriveKinematics kinematics; + private final double gravityForceOnEachModule; + + /** + * + * + *

Creates a Swerve Drive Simulation.

+ * + *

This constructor initializes a swerve drive simulation with the given robot mass, bumper dimensions, module + * simulations, module translations, gyro simulation, and initial pose on the field. + * + * @param config a {@link DriveTrainSimulationConfig} instance containing the configurations of * this drivetrain + * @param initialPoseOnField the initial pose of the drivetrain in the simulation world, represented as a + * {@link Pose2d} + */ + public SwerveDriveSimulation(DriveTrainSimulationConfig config, Pose2d initialPoseOnField) { + super(config, initialPoseOnField); + this.moduleTranslations = config.moduleTranslations; + this.moduleSimulations = Arrays.stream(config.swerveModuleSimulationFactories) + .map(Supplier::get) + .toArray(SwerveModuleSimulation[]::new); + this.gyroSimulation = config.gyroSimulationFactory.get(); + + super.setLinearDamping(1.4); + super.setAngularDamping(1.4); + this.kinematics = new SwerveDriveKinematics(moduleTranslations); + + this.gravityForceOnEachModule = config.robotMass.in(Kilograms) * 9.8 / moduleSimulations.length; + } + + /** + * + * + *

Updates the Swerve Drive Simulation.

+ * + *

This method performs the following actions during each sub-tick of the simulation: + * + *

    + *
  • Applies the translational friction force to the physics engine. + *
  • Applies the rotational friction torque to the physics engine. + *
  • Updates the simulation of each swerve module. + *
  • Applies the propelling forces of the modules to the physics engine. + *
  • Updates the gyro simulation of the drivetrain. + *
+ */ + @Override + public void simulationSubTick() { + simulateChassisFrictionForce(); + + simulateChassisFrictionTorque(); + + simulateModulePropellingForces(); + + gyroSimulation.updateSimulationSubTick(super.getAngularVelocity()); + } + + private Translation2d previousModuleSpeedsFieldRelative = new Translation2d(); + + /** + * + * + *

Simulates the Translational Friction Force and Applies It to the Physics Engine.

+ * + *

This method simulates the translational friction forces acting on the robot and applies them to the physics + * engine. There are two components of the friction forces: + * + *

    + *
  • A portion of the friction force pushes the robot from its current ground speeds + * ({@link #getDriveTrainSimulatedChassisSpeedsRobotRelative()}) toward its current module speeds + * ({@link #getModuleSpeeds()}). + *
  • Another portion of the friction force is the centripetal force, which occurs when the chassis changes its + * direction of movement. + *
+ * + *

The total friction force should not exceed the tire's grip limit. + */ + private void simulateChassisFrictionForce() { + final ChassisSpeeds moduleSpeeds = getModuleSpeeds(); + + /* The friction force that tries to bring the chassis from floor speeds to module speeds */ + final ChassisSpeeds differenceBetweenFloorSpeedAndModuleSpeedsRobotRelative = + moduleSpeeds.minus(getDriveTrainSimulatedChassisSpeedsRobotRelative()); + final Translation2d floorAndModuleSpeedsDiffFieldRelative = new Translation2d( + differenceBetweenFloorSpeedAndModuleSpeedsRobotRelative.vxMetersPerSecond, + differenceBetweenFloorSpeedAndModuleSpeedsRobotRelative.vyMetersPerSecond) + .rotateBy(getSimulatedDriveTrainPose().getRotation()); + final double FRICTION_FORCE_GAIN = 3.0, + totalGrippingForce = + moduleSimulations[0].config.getGrippingForceNewtons(gravityForceOnEachModule) + * moduleSimulations.length; + final Vector2 speedsDifferenceFrictionForce = Vector2.create( + Math.min( + FRICTION_FORCE_GAIN * totalGrippingForce * floorAndModuleSpeedsDiffFieldRelative.getNorm(), + totalGrippingForce), + MapleCommonMath.getAngle(floorAndModuleSpeedsDiffFieldRelative).getRadians()); + + /* the centripetal friction force during turning */ + final ChassisSpeeds moduleSpeedsFieldRelative = ChassisSpeeds.fromRobotRelativeSpeeds( + moduleSpeeds, getSimulatedDriveTrainPose().getRotation()); + final Rotation2d dTheta = MapleCommonMath.getAngle( + GeometryConvertor.getChassisSpeedsTranslationalComponent(moduleSpeedsFieldRelative)) + .minus(MapleCommonMath.getAngle(previousModuleSpeedsFieldRelative)); + + final double orbitalAngularVelocity = + dTheta.getRadians() / SimulatedArena.getSimulationDt().in(Seconds); + final Rotation2d centripetalForceDirection = + MapleCommonMath.getAngle(previousModuleSpeedsFieldRelative).plus(Rotation2d.fromDegrees(90)); + final Vector2 centripetalFrictionForce = Vector2.create( + previousModuleSpeedsFieldRelative.getNorm() * orbitalAngularVelocity * config.robotMass.in(Kilograms), + centripetalForceDirection.getRadians()); + previousModuleSpeedsFieldRelative = + GeometryConvertor.getChassisSpeedsTranslationalComponent(moduleSpeedsFieldRelative); + + /* apply force to physics engine */ + final Vector2 + totalFrictionForceUnlimited = centripetalFrictionForce.copy().add(speedsDifferenceFrictionForce), + totalFrictionForce = + Vector2.create( + Math.min(totalGrippingForce, totalFrictionForceUnlimited.getMagnitude()), + totalFrictionForceUnlimited.getDirection()); + super.applyForce(totalFrictionForce); + } + + /** + * + * + *

Simulates the Rotational Friction Torque and Applies It to the Physics Engine.

+ * + *

This method simulates the rotational friction torque acting on the robot and applies them to the physics + * engine. + * + *

The friction torque pushes the robot from its current ground angular velocity + * ({@link #getDriveTrainSimulatedChassisSpeedsRobotRelative()}) toward its current modules' angular velocity + * ({@link #getModuleSpeeds()}). + */ + private void simulateChassisFrictionTorque() { + final double + desiredRotationalMotionPercent = + Math.abs(getDesiredSpeed().omegaRadiansPerSecond + / maxAngularVelocity().in(RadiansPerSecond)), + actualRotationalMotionPercent = + Math.abs(getAngularVelocity() / maxAngularVelocity().in(RadiansPerSecond)), + differenceBetweenFloorSpeedAndModuleSpeed = + getModuleSpeeds().omegaRadiansPerSecond - getAngularVelocity(), + grippingTorqueMagnitude = + moduleSimulations[0].config.getGrippingForceNewtons(gravityForceOnEachModule) + * moduleTranslations[0].getNorm() + * moduleSimulations.length, + FRICTION_TORQUE_GAIN = 1; + + if (actualRotationalMotionPercent < 0.01 && desiredRotationalMotionPercent < 0.02) super.setAngularVelocity(0); + else + super.applyTorque(Math.copySign( + Math.min( + FRICTION_TORQUE_GAIN + * grippingTorqueMagnitude + * Math.abs(differenceBetweenFloorSpeedAndModuleSpeed), + grippingTorqueMagnitude), + differenceBetweenFloorSpeedAndModuleSpeed)); + } + + /** + * + * + *

Simulates the Translational Friction Force and Applies It to the Physics Engine.

+ * + *

This method simulates the translational friction forces acting on the robot and applies them to the physics + * engine. There are two components of the friction forces: + * + *

    + *
  • A portion of the friction force pushes the robot from its current ground speeds + * ({@link #getDriveTrainSimulatedChassisSpeedsRobotRelative()}) toward its current module speeds + * ({@link #getModuleSpeeds()}). + *
  • Another portion of the friction force is the centripetal force, which occurs when the chassis changes its + * direction of movement. + *
+ * + *

The total friction force should not exceed the tire's grip limit. + */ + private void simulateModulePropellingForces() { + for (int i = 0; i < moduleSimulations.length; i++) { + final Vector2 moduleWorldPosition = getWorldPoint(GeometryConvertor.toDyn4jVector2(moduleTranslations[i])); + final Vector2 moduleForce = moduleSimulations[i].updateSimulationSubTickGetModuleForce( + super.getLinearVelocity(moduleWorldPosition), + getSimulatedDriveTrainPose().getRotation(), + gravityForceOnEachModule); + super.applyForce(moduleForce, moduleWorldPosition); + } + } + + /** + * + * + *

Obtains the Chassis Speeds the Modules Are Attempting to Achieve.

+ * + *

This method returns the desired chassis speeds that the modules are trying to reach. If the robot maintains + * the current driving voltage and steering position for a long enough period, it will achieve these speeds. + * + * @return the desired chassis speeds, robot-relative + */ + private ChassisSpeeds getDesiredSpeed() { + return kinematics.toChassisSpeeds(Arrays.stream(moduleSimulations) + .map((SwerveModuleSimulation::getFreeSpinState)) + .toArray(SwerveModuleState[]::new)); + } + + /** + * + * + *

Obtains the Current Chassis Speeds of the Modules.

+ * + *

This method estimates the chassis speeds of the robot based on the swerve states of the modules. + * + *

Note: These speeds might not represent the actual floor speeds due to potential skidding. + * + * @return the module speeds, robot-relative + */ + private ChassisSpeeds getModuleSpeeds() { + return kinematics.toChassisSpeeds(Arrays.stream(moduleSimulations) + .map((SwerveModuleSimulation::getCurrentState)) + .toArray(SwerveModuleState[]::new)); + } + + /** + * + * + *

Obtains the maximum achievable linear velocity of the chassis.

+ * + * @return the maximum linear velocity + * @see SwerveModuleSimulationConfig#maximumGroundSpeed() + */ + public LinearVelocity maxLinearVelocity() { + return moduleSimulations[0].config.maximumGroundSpeed(); + } + + /** + * + * + *

Obtains the maximum achievable linear acceleration of the chassis.

+ * + * @return the maximum linear acceleration + * @see SwerveModuleSimulationConfig#maxAcceleration(Mass, int, Current) + */ + public LinearAcceleration maxLinearAcceleration(Current statorCurrentLimit) { + return moduleSimulations[0].config.maxAcceleration( + config.robotMass, moduleSimulations.length, statorCurrentLimit); + } + + /** + * + * + *

Obtains the drive base radius of the swerve drive.

+ * + * @return the drive base radius. + */ + public Distance driveBaseRadius() { + return config.driveBaseRadius(); + } + + /** + * + * + *

Obtains the maximum achievable angular velocity of the chassis.

+ * + * @return the maximum angular velocity + */ + public AngularVelocity maxAngularVelocity() { + return RadiansPerSecond.of(maxLinearVelocity().in(MetersPerSecond) + / config.driveBaseRadius().in(Meters)); + } + + /** + * + * + *

Obtains the maximum achievable angular acceleration of the chassis.

+ * + * @return the maximum angular acceleration + */ + public AngularAcceleration maxAngularAcceleration(Current statorCurrentLimit) { + return RadiansPerSecondPerSecond.of(moduleSimulations[0] + .config + .getTheoreticalPropellingForcePerModule( + config.robotMass, moduleSimulations.length, statorCurrentLimit) + .in(Newtons) + * moduleTranslations[0].getNorm() + * moduleSimulations.length + / super.getMass().getInertia()); + } + + public SwerveModuleSimulation[] getModules() { + return moduleSimulations; + } + + public GyroSimulation getGyroSimulation() { + return this.gyroSimulation; + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SwerveModuleSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SwerveModuleSimulation.java new file mode 100644 index 0000000..a8d1d46 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SwerveModuleSimulation.java @@ -0,0 +1,541 @@ +package swervelib.simulation.ironmaple.simulation.drivesims; + +import static edu.wpi.first.units.Units.*; + +import edu.wpi.first.math.MathUtil; +import edu.wpi.first.math.geometry.Rotation2d; +import edu.wpi.first.math.kinematics.SwerveDriveOdometry; +import edu.wpi.first.math.kinematics.SwerveModuleState; +import edu.wpi.first.units.measure.*; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import org.dyn4j.geometry.Vector2; +import swervelib.simulation.ironmaple.simulation.SimulatedArena; +import swervelib.simulation.ironmaple.simulation.drivesims.configs.SwerveModuleSimulationConfig; +import swervelib.simulation.ironmaple.simulation.motorsims.MapleMotorSim; +import swervelib.simulation.ironmaple.simulation.motorsims.SimMotorConfigs; +import swervelib.simulation.ironmaple.simulation.motorsims.SimulatedBattery; +import swervelib.simulation.ironmaple.simulation.motorsims.SimulatedMotorController; + +/** + * + * + *

Simulation for a Single Swerve Module.

+ * + *

Check Online + * Documentation + * + *

This class provides a simulation for a single swerve module in the {@link SwerveDriveSimulation}. + * + *

1. Purpose

+ * + *

This class serves as the bridge between your code and the physics engine. + * + *

You will apply voltage outputs to the drive/steer motor of the module and obtain their encoder readings in your + * code, just as how you deal with your physical motors. + * + *

2. Perspectives

+ * + *
    + *
  • Simulates the steering mechanism using a custom brushless motor simulator. + *
  • Simulates the propelling force generated by the driving motor, with a current limit. + *
  • Simulates encoder readings, which can be used to simulate a {@link SwerveDriveOdometry}. + *
+ * + *

3. Simulating Odometry

+ * + *
    + *
  • Retrieve the encoder readings from {@link #getDriveEncoderUnGearedPosition()}} and + * {@link #getSteerAbsoluteFacing()}. + *
  • Use {@link SwerveDriveOdometry} to estimate the pose of your robot. + *
  • 250Hz + * Odometry is supported. You can retrive cached encoder readings from every sub-tick through + * {@link #getCachedDriveEncoderUnGearedPositions()} and {@link #getCachedSteerAbsolutePositions()}. + *
+ * + *

An example of how to simulate odometry using this class is the ModuleIOSim.java + * from the Advanced Swerve Drive with maple-sim example. + */ +public class SwerveModuleSimulation { + public final SwerveModuleSimulationConfig config; + + private final MapleMotorSim steerMotorSim; + + private Voltage driveMotorAppliedVoltage = Volts.zero(); + private Current driveMotorStatorCurrent = Amps.zero(); + private Angle driveWheelFinalPosition = Radians.zero(); + private AngularVelocity driveWheelFinalSpeed = RadiansPerSecond.zero(); + + private SimulatedMotorController driveMotorController; + + private final Angle steerRelativeEncoderOffSet = Radians.of((Math.random() - 0.5) * 30); + private final Queue driveWheelFinalPositionCache; + private final Queue steerAbsolutePositionCache; + + /** + * + * + *

Constructs a Swerve Module Simulation.

+ * + *

If you are using {@link SimulatedArena#overrideSimulationTimings(Time, int)} to use custom timings, you must + * call the method before constructing any swerve module simulations using this constructor. + * + * @param config the configuration + */ + public SwerveModuleSimulation(SwerveModuleSimulationConfig config) { + this.config = config; + + SimulatedBattery.addElectricalAppliances(this::getDriveMotorSupplyCurrent); + this.steerMotorSim = new MapleMotorSim(config.steerMotorConfigs); + + this.driveWheelFinalPositionCache = new ConcurrentLinkedQueue<>(); + for (int i = 0; i < SimulatedArena.getSimulationSubTicksIn1Period(); i++) + driveWheelFinalPositionCache.offer(driveWheelFinalPosition); + this.steerAbsolutePositionCache = new ConcurrentLinkedQueue<>(); + for (int i = 0; i < SimulatedArena.getSimulationSubTicksIn1Period(); i++) + steerAbsolutePositionCache.offer(getSteerAbsoluteFacing()); + + this.driveMotorController = new SimulatedMotorController.GenericMotorController(config.driveMotorConfigs.motor); + this.steerMotorSim.useSimpleDCMotorController(); + } + + public SimMotorConfigs getDriveMotorConfigs() { + return config.driveMotorConfigs; + } + + public SimMotorConfigs getSteerMotorConfigs() { + return steerMotorSim.getConfigs(); + } + + /** + * + * + *

Sets the motor controller for the drive motor.

+ * + *

The configured controller runs control loop on the motor. + * + * @param driveMotorController the motor controller to control the drive motor + */ + public T useDriveMotorController(T driveMotorController) { + this.driveMotorController = driveMotorController; + return driveMotorController; + } + + public SimulatedMotorController.GenericMotorController useGenericMotorControllerForDrive() { + return useDriveMotorController( + new SimulatedMotorController.GenericMotorController(config.driveMotorConfigs.motor)); + } + + /** + * + * + *

Requests the Steering Motor to Run at a Specified Output.

+ * + *

Think of it as the requestOutput() of your physical steering motor. + * + * @param steerMotorController the motor controller to control the steer motor + */ + public T useSteerMotorController(T steerMotorController) { + return this.steerMotorSim.useMotorController(steerMotorController); + } + + public SimulatedMotorController.GenericMotorController useGenericControllerForSteer() { + return this.steerMotorSim.useSimpleDCMotorController(); + } + + /** + * + * + *

Updates the Simulation for This Module.

+ * + *

Note: Friction forces are not simulated in this method. + * + * @param moduleCurrentGroundVelocityWorldRelative the current ground velocity of the module, relative to the world + * @param robotFacing the absolute facing of the robot, relative to the world + * @param gravityForceOnModuleNewtons the gravitational force acting on this module, in newtons + * @return the propelling force generated by the module, as a {@link Vector2} object + */ + public Vector2 updateSimulationSubTickGetModuleForce( + Vector2 moduleCurrentGroundVelocityWorldRelative, + Rotation2d robotFacing, + double gravityForceOnModuleNewtons) { + /* Step1: Update the steer mechanism simulation */ + steerMotorSim.update(SimulatedArena.getSimulationDt()); + + /* Step2: Simulate the amount of propelling force generated by the module. */ + final double grippingForceNewtons = config.getGrippingForceNewtons(gravityForceOnModuleNewtons); + final Rotation2d moduleWorldFacing = this.getSteerAbsoluteFacing().plus(robotFacing); + final Vector2 propellingForce = + getPropellingForce(grippingForceNewtons, moduleWorldFacing, moduleCurrentGroundVelocityWorldRelative); + + /* Step3: Updates and caches the encoder readings for odometry simulation. */ + updateEncoderCaches(); + + return propellingForce; + } + + /** + * + * + *

Calculates the amount of propelling force that the module generates.

+ * + *

For most of the time, that propelling force is directly applied to the drivetrain. And the drive wheel runs as + * fast as the ground velocity + * + *

However, if the propelling force exceeds the gripping, only the max gripping force is applied. The rest of the + * propelling force will cause the wheel to start skidding and make the odometry inaccurate. + * + * @param grippingForceNewtons the amount of gripping force that wheel can generate, in newtons + * @param moduleWorldFacing the current world facing of the module + * @param moduleCurrentGroundVelocity the current ground velocity of the module, world-reference + * @return a vector representing the propelling force that the module generates, world-reference + */ + private Vector2 getPropellingForce( + double grippingForceNewtons, Rotation2d moduleWorldFacing, Vector2 moduleCurrentGroundVelocity) { + final double driveWheelTorque = getDriveWheelTorque(); + double propellingForceNewtons = driveWheelTorque / config.WHEEL_RADIUS.in(Meters); + final boolean skidding = Math.abs(propellingForceNewtons) > grippingForceNewtons; + if (skidding) propellingForceNewtons = Math.copySign(grippingForceNewtons, propellingForceNewtons); + + final double floorVelocityProjectionOnWheelDirectionMPS = moduleCurrentGroundVelocity.getMagnitude() + * Math.cos(moduleCurrentGroundVelocity.getAngleBetween(new Vector2(moduleWorldFacing.getRadians()))); + + // if the chassis is tightly gripped on floor, the floor velocity is projected to the wheel + this.driveWheelFinalSpeed = + RadiansPerSecond.of(floorVelocityProjectionOnWheelDirectionMPS / config.WHEEL_RADIUS.in(Meters)); + + // if the module is skidding + if (skidding) { + final AngularVelocity skiddingEquilibriumWheelSpeed = config.driveMotorConfigs.calculateMechanismVelocity( + config.driveMotorConfigs.calculateCurrent( + NewtonMeters.of(propellingForceNewtons * config.WHEEL_RADIUS.in(Meters))), + driveMotorAppliedVoltage); + this.driveWheelFinalSpeed = driveWheelFinalSpeed.times(0.5).plus(skiddingEquilibriumWheelSpeed.times(0.5)); + } + + return Vector2.create(propellingForceNewtons, moduleWorldFacing.getRadians()); + } + + /** + * + * + *

Calculates the amount of torque that the drive motor can generate on the wheel.

+ * + * @return the amount of torque on the wheel by the drive motor, in Newton * Meters + */ + private double getDriveWheelTorque() { + driveMotorAppliedVoltage = driveMotorController.updateControlSignal( + driveWheelFinalPosition, + driveWheelFinalSpeed, + getDriveEncoderUnGearedPosition(), + getDriveEncoderUnGearedSpeed()); + + driveMotorAppliedVoltage = SimulatedBattery.clamp(driveMotorAppliedVoltage); + + /* calculate the stator current */ + driveMotorStatorCurrent = + config.driveMotorConfigs.calculateCurrent(driveWheelFinalSpeed, driveMotorAppliedVoltage); + + /* calculate the torque generated */ + Torque driveWheelTorque = config.driveMotorConfigs.calculateTorque(driveMotorStatorCurrent); + + /* calculates the torque if you included losses from friction */ + Torque driveWheelTorqueWithFriction = NewtonMeters.of(MathUtil.applyDeadband( + driveWheelTorque.in(NewtonMeters), + config.driveMotorConfigs.friction.in(NewtonMeters), + Double.POSITIVE_INFINITY)); + return driveWheelTorqueWithFriction.in(NewtonMeters); + } + + /** @return the current module state of this simulation module */ + public SwerveModuleState getCurrentState() { + return new SwerveModuleState( + MetersPerSecond.of(getDriveWheelFinalSpeed().in(RadiansPerSecond) * config.WHEEL_RADIUS.in(Meters)), + getSteerAbsoluteFacing()); + } + + /** + * + * + *

Obtains the "free spin" state of the module

+ * + *

The "free spin" state of a simulated module refers to its state after spinning freely for a long time under + * the current input voltage + * + * @return the free spinning module state + */ + protected SwerveModuleState getFreeSpinState() { + return new SwerveModuleState( + config.driveMotorConfigs + .calculateMechanismVelocity( + config.driveMotorConfigs.calculateCurrent(config.driveMotorConfigs.friction), + driveMotorAppliedVoltage) + .in(RadiansPerSecond) + * config.WHEEL_RADIUS.in(Meters), + getSteerAbsoluteFacing()); + } + + /** + * + * + *

Cache the encoder values for high-frequency odometry.

+ * + *

An internal method to cache the encoder values to their queues. + */ + private void updateEncoderCaches() { + /* Increment of drive wheel position */ + this.driveWheelFinalPosition = + this.driveWheelFinalPosition.plus(this.driveWheelFinalSpeed.times(SimulatedArena.getSimulationDt())); + + /* cache sensor readings to queue for high-frequency odometry */ + this.steerAbsolutePositionCache.poll(); + this.steerAbsolutePositionCache.offer(getSteerAbsoluteFacing()); + + this.driveWheelFinalPositionCache.poll(); + this.driveWheelFinalPositionCache.offer(driveWheelFinalPosition); + } + + /** + * + * + *

Obtains the Actual Output Voltage of the Drive Motor.

+ * + * @return the actual output voltage of the drive motor + */ + public Voltage getDriveMotorAppliedVoltage() { + return driveMotorAppliedVoltage; + } + + /** + * + * + *

Obtains the Actual Output Voltage of the Steering Motor.

+ * + * @return the actual output voltage of the steering motor + * @see MapleMotorSim#getAppliedVoltage() + */ + public Voltage getSteerMotorAppliedVoltage() { + return steerMotorSim.getAppliedVoltage(); + } + + /** + * + * + *

Obtains the Amount of Current Supplied to the Drive Motor.

+ * + * @return the current supplied to the drive motor + */ + public Current getDriveMotorSupplyCurrent() { + return getDriveMotorStatorCurrent().times(driveMotorAppliedVoltage.div(SimulatedBattery.getBatteryVoltage())); + } + + /** + * + * + *

Obtains the Stator current the Drive Motor.

+ * + * @return the stator current of the drive motor + */ + public Current getDriveMotorStatorCurrent() { + return driveMotorStatorCurrent; + } + + /** + * + * + *

Obtains the Amount of Current Supplied to the Steer Motor.

+ * + * @return the current supplied to the steer motor + * @see MapleMotorSim#getSupplyCurrent() + */ + public Current getSteerMotorSupplyCurrent() { + return steerMotorSim.getSupplyCurrent(); + } + + /** + * + * + *

Obtains the Stator current the Steer Motor.

+ * + * @return the stator current of the drive motor + * @see MapleMotorSim#getSupplyCurrent() + */ + public Current getSteerMotorStatorCurrent() { + return steerMotorSim.getStatorCurrent(); + } + + /** + * + * + *

Obtains the Position of the Drive Encoder.

+ * + *

This value represents the un-geared position of the encoder, i.e., the amount of radians the drive motor's + * encoder has rotated. + * + * @return the position of the drive motor's encoder (un-geared) + */ + public Angle getDriveEncoderUnGearedPosition() { + return getDriveWheelFinalPosition().times(config.DRIVE_GEAR_RATIO); + } + + /** + * + * + *

Obtains the Final Position of the Wheel.

+ * + *

This method provides the final position of the drive encoder in terms of wheel angle. + * + * @return the final position of the drive encoder (wheel rotations) + */ + public Angle getDriveWheelFinalPosition() { + return driveWheelFinalPosition; + } + + /** + * + * + *

Obtains the Speed of the Drive Encoder.

+ * + * @return the un-geared speed of the drive encoder + */ + public AngularVelocity getDriveEncoderUnGearedSpeed() { + return getDriveWheelFinalSpeed().times(config.DRIVE_GEAR_RATIO); + } + + /** + * + * + *

Obtains the Final Speed of the Wheel.

+ * + * @return the final speed of the drive wheel + */ + public AngularVelocity getDriveWheelFinalSpeed() { + return driveWheelFinalSpeed; + } + + /** + * + * + *

Obtains the Relative Position of the Steer Encoder.

+ * + * @return the relative encoder position of the steer motor + * @see MapleMotorSim#getEncoderPosition() + */ + public Angle getSteerRelativeEncoderPosition() { + return getSteerAbsoluteFacing() + .getMeasure() + .times(config.STEER_GEAR_RATIO) + .plus(steerRelativeEncoderOffSet); + } + + /** + * + * + *

Obtains the Speed of the Steer Relative Encoder (Geared).

+ * + * @return the speed of the steer relative encoder + * @see MapleMotorSim#getEncoderVelocity() + */ + public AngularVelocity getSteerRelativeEncoderVelocity() { + return getSteerAbsoluteEncoderSpeed().times(config.STEER_GEAR_RATIO); + } + + /** + * + * + *

Obtains the Absolute Facing of the Steer Mechanism.

+ * + * @return the absolute facing of the steer mechanism, as a {@link Rotation2d} + */ + public Rotation2d getSteerAbsoluteFacing() { + return new Rotation2d(getSteerAbsoluteAngle()); + } + + /** + * + * + *

Obtains the Absolute Angle of the Steer Mechanism.

+ * + * @return the (continuous) final angle of the steer mechanism, as a {@link Angle} + * @see MapleMotorSim#getAngularPosition() + */ + public Angle getSteerAbsoluteAngle() { + return steerMotorSim.getAngularPosition(); + } + + /** + * + * + *

Obtains the Absolute Rotational Velocity of the Steer Mechanism.

+ * + * @return the absolute angular velocity of the steer mechanism + */ + public AngularVelocity getSteerAbsoluteEncoderSpeed() { + return steerMotorSim.getVelocity(); + } + + /** + * + * + *

Obtains the Cached Readings of the Drive Encoder's Un-Geared Position.

+ * + *

The values of {@link #getDriveEncoderUnGearedPosition()} are cached at each sub-tick and can be retrieved + * using this method. + * + * @return an array of cached drive encoder un-geared positions + */ + public Angle[] getCachedDriveEncoderUnGearedPositions() { + return driveWheelFinalPositionCache.stream() + .map(value -> value.times(config.DRIVE_GEAR_RATIO)) + .toArray(Angle[]::new); + } + + /** + * + * + *

Obtains the Cached Readings of the Drive Encoder's Final Position (Wheel Rotations).

+ * + *

The values of {@link #getDriveWheelFinalPosition()} are cached at each sub-tick and are divided by the gear + * ratio to obtain the final wheel rotations. + * + * @return an array of cached drive encoder final positions (wheel rotations) + */ + public Angle[] getCachedDriveWheelFinalPositions() { + return driveWheelFinalPositionCache.toArray(Angle[]::new); + } + + /** + * + * + *

Obtains the Cached Readings of the Steer Relative Encoder's Position.

+ * + *

The values of {@link #getSteerRelativeEncoderPosition()} are cached at each sub-tick and can be retrieved + * using this method. + * + * @return an array of cached steer relative encoder positions + */ + public Angle[] getCachedSteerRelativeEncoderPositions() { + return steerAbsolutePositionCache.stream() + .map(absoluteFacing -> absoluteFacing + .getMeasure() + .times(config.STEER_GEAR_RATIO) + .plus(steerRelativeEncoderOffSet)) + .toArray(Angle[]::new); + } + + /** + * + * + *

Obtains the Cached Readings of the Steer Absolute Positions.

+ * + *

The values of {@link #getSteerAbsoluteFacing()} are cached at each sub-tick and can be retrieved using this + * method. + * + * @return an array of cached absolute steer positions, as {@link Rotation2d} objects + */ + public Rotation2d[] getCachedSteerAbsolutePositions() { + return steerAbsolutePositionCache.toArray(Rotation2d[]::new); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/configs/BoundingCheck.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/configs/BoundingCheck.java new file mode 100644 index 0000000..fe0b13b --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/configs/BoundingCheck.java @@ -0,0 +1,12 @@ +package swervelib.simulation.ironmaple.simulation.drivesims.configs; + +import edu.wpi.first.wpilibj.DriverStation; + +public class BoundingCheck { + public static void check(double value, double lowerBound, double upperBound, String variableName, String unit) { + if (lowerBound <= value && value <= upperBound) return; + final String errorMessage = "The provided \"" + variableName + "\" is " + value + unit + + ", which seems abnormal, please check its correctness"; + DriverStation.reportError(errorMessage, true); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/configs/DriveTrainSimulationConfig.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/configs/DriveTrainSimulationConfig.java new file mode 100644 index 0000000..5bf369c --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/configs/DriveTrainSimulationConfig.java @@ -0,0 +1,323 @@ +package swervelib.simulation.ironmaple.simulation.drivesims.configs; + +import static edu.wpi.first.units.Units.Kilograms; +import static edu.wpi.first.units.Units.Meters; + +import edu.wpi.first.math.geometry.Translation2d; +import edu.wpi.first.math.system.plant.DCMotor; +import edu.wpi.first.units.measure.Distance; +import edu.wpi.first.units.measure.Mass; +import java.util.Arrays; +import java.util.OptionalDouble; +import java.util.function.Supplier; +import swervelib.simulation.ironmaple.simulation.drivesims.COTS; +import swervelib.simulation.ironmaple.simulation.drivesims.GyroSimulation; +import swervelib.simulation.ironmaple.simulation.drivesims.SwerveModuleSimulation; + +/** + * + * + *

Stores the configurations for a swerve drive simulation.

+ * + *

This class is used to hold all the parameters necessary for simulating a swerve drivetrain, allowing for realistic + * performance testing and evaluation. + */ +public class DriveTrainSimulationConfig { + public Mass robotMass; + public Distance bumperLengthX, bumperWidthY; + public Supplier[] swerveModuleSimulationFactories; + public Supplier gyroSimulationFactory; + public Translation2d[] moduleTranslations; + + /** + * + * + *

Ordinary Constructor

+ * + *

Creates an instance of {@link DriveTrainSimulationConfig} with specified parameters. + * + * @param robotMass the mass of the robot, including bumpers. + * @param bumperLengthX the length of the bumper (distance from front to back). + * @param bumperWidthY the width of the bumper (distance from left to right). + * @param trackLengthX the distance between the front and rear wheels. + * @param trackWidthY the distance between the left and right wheels. + * @param swerveModuleSimulationFactory the factory that creates appropriate swerve module simulation for the + * drivetrain. You can specify one factory to apply the same configuration over all modules or specify four + * factories in the order (FL, FR, BL, BR). + * @param gyroSimulationFactory the factory that creates appropriate gyro simulation for the drivetrain. + */ + public DriveTrainSimulationConfig( + Mass robotMass, + Distance bumperLengthX, + Distance bumperWidthY, + Distance trackLengthX, + Distance trackWidthY, + Supplier gyroSimulationFactory, + Supplier... swerveModuleSimulationFactory) { + this.robotMass = robotMass; + this.bumperLengthX = bumperLengthX; + this.bumperWidthY = bumperWidthY; + this.withTrackLengthTrackWidth(trackLengthX, trackWidthY); + + if (swerveModuleSimulationFactory.length == 1) this.withSwerveModule(swerveModuleSimulationFactory[0]); + else if (swerveModuleSimulationFactory.length == 4) this.withSwerveModules(swerveModuleSimulationFactory); + else + throw new IllegalArgumentException("Module simulation factories length must be 1 or 4, provided " + + swerveModuleSimulationFactory.length); + this.gyroSimulationFactory = gyroSimulationFactory; + + checkRobotMass(); + checkBumperSize(); + } + + /** + * + * + *

Default Constructor.

+ * + *

Creates a {@link DriveTrainSimulationConfig} with all the data set to default values. + * + *

Though the config starts with default values, any configuration can be modified after creation. + * + *

The default configurations are: + * + *

    + *
  • Robot Mass of 45 kilograms. + *
  • Bumper Length of 0.76 meters. + *
  • Bumper Width of 0.76 meters. + *
  • Track Length of 0.52 meters. + *
  • Track Width of 0.52 meters. + *
  • Default swerve module simulations based on Falcon 500 motors. + *
  • Default gyro simulation using the Pigeon2 gyro. + *
+ * + * @return a new instance of {@link DriveTrainSimulationConfig} with all configs set to default values. + */ + public static DriveTrainSimulationConfig Default() { + return new DriveTrainSimulationConfig( + Kilograms.of(45), + Meters.of(0.76), + Meters.of(.76), + Meters.of(0.52), + Meters.of(0.52), + COTS.ofPigeon2(), + COTS.ofMark4(DCMotor.getFalcon500(1), DCMotor.getFalcon500(1), COTS.WHEELS.COLSONS.cof, 2)); + } + + /** + * + * + *

Sets the robot mass.

+ * + *

Updates the mass of the robot in kilograms. + * + * @param robotMass the new mass of the robot. + * @return the current instance of {@link DriveTrainSimulationConfig} for method chaining. + */ + public DriveTrainSimulationConfig withRobotMass(Mass robotMass) { + this.robotMass = robotMass; + checkRobotMass(); + return this; + } + + /** + * + * + *

Sets the bumper size.

+ * + *

Updates the dimensions of the bumper. + * + * @param bumperLengthX the length of the bumper. + * @param bumperWidthY the width of the bumper. + * @return the current instance of {@link DriveTrainSimulationConfig} for method chaining. + */ + public DriveTrainSimulationConfig withBumperSize(Distance bumperLengthX, Distance bumperWidthY) { + this.bumperLengthX = bumperLengthX; + this.bumperWidthY = bumperWidthY; + + checkBumperSize(); + return this; + } + + /** + * + * + *

Sets the track length and width.

+ * + *

Updates the translations for the swerve modules based on the specified track length and track width. + * + *

For non-rectangular chassis configuration, use {@link #withCustomModuleTranslations(Translation2d[])} instead. + * + * @param trackLengthX the distance between the front and rear wheels. + * @param trackWidthY the distance between the left and right wheels. + * @return the current instance of {@link DriveTrainSimulationConfig} for method chaining. + */ + public DriveTrainSimulationConfig withTrackLengthTrackWidth(Distance trackLengthX, Distance trackWidthY) { + BoundingCheck.check(trackLengthX.in(Meters), 0.5, 1.5, "track length", "meters"); + BoundingCheck.check(trackWidthY.in(Meters), 0.5, 1.5, "track width", "meters"); + + this.moduleTranslations = new Translation2d[] { + new Translation2d(trackLengthX.in(Meters) / 2, trackWidthY.in(Meters) / 2), + new Translation2d(trackLengthX.in(Meters) / 2, -trackWidthY.in(Meters) / 2), + new Translation2d(-trackLengthX.in(Meters) / 2, trackWidthY.in(Meters) / 2), + new Translation2d(-trackLengthX.in(Meters) / 2, -trackWidthY.in(Meters) / 2) + }; + return this; + } + + /** + * + * + *

Sets custom module translations.

+ * + *

Updates the translations of the swerve modules with user-defined values. + * + *

For ordinary rectangular modules configuration, use {@link #withTrackLengthTrackWidth(Distance, Distance)} + * instead. + * + * @param moduleTranslations the custom translations for the swerve modules. + * @return the current instance of {@link DriveTrainSimulationConfig} for method chaining. + */ + public DriveTrainSimulationConfig withCustomModuleTranslations(Translation2d[] moduleTranslations) { + checkModuleTranslations(); + this.moduleTranslations = moduleTranslations; + return this; + } + + /** + * + * + *

Sets the swerve module simulation factory.

+ * + *

Updates the factory used to create swerve module simulations. + * + * @param swerveModuleSimulationFactory the new factory (or factories) for swerve module simulations. You can + * specify one factory to apply the same configuration over all modules, or specify four factories in the order + * (FL, FR, BL, BR) + * @return the current instance of {@link DriveTrainSimulationConfig} for method chaining. + */ + public DriveTrainSimulationConfig withSwerveModules( + Supplier... swerveModuleSimulationFactory) { + if (swerveModuleSimulationFactory.length == 1) return withSwerveModule(swerveModuleSimulationFactory[0]); + + if (swerveModuleSimulationFactory.length != moduleTranslations.length) + throw new IllegalArgumentException("Module simulation factories length must be 1 or 4, provided " + + swerveModuleSimulationFactory.length); + + this.swerveModuleSimulationFactories = swerveModuleSimulationFactory; + return this; + } + + /** + * + * + *

Sets the swerve module simulation factory.

+ * + *

Updates the factory used to create swerve module simulations. + * + *

Uses the same configuration over all the modules + * + * @param swerveModuleSimulationFactory the new factory for swerve module simulations. + * @return the current instance of {@link DriveTrainSimulationConfig} for method chaining. + */ + public DriveTrainSimulationConfig withSwerveModule(Supplier swerveModuleSimulationFactory) { + this.swerveModuleSimulationFactories = new Supplier[moduleTranslations.length]; + Arrays.fill(this.swerveModuleSimulationFactories, swerveModuleSimulationFactory); + return this; + } + + /** + * + * + *

Sets the gyro simulation factory.

+ * + *

Updates the factory used to create gyro simulations. + * + * @param gyroSimulationFactory the new factory for gyro simulations. + * @return the current instance of {@link DriveTrainSimulationConfig} for method chaining. + */ + public DriveTrainSimulationConfig withGyro(Supplier gyroSimulationFactory) { + this.gyroSimulationFactory = gyroSimulationFactory; + return this; + } + + /** + * + * + *

Calculates the density of the robot.

+ * + *

Returns the density of the robot based on its mass and bumper dimensions. + * + * @return the density in kilograms per square meter. + */ + public double getDensityKgPerSquaredMeters() { + return robotMass.in(Kilograms) / (bumperLengthX.in(Meters) * bumperWidthY.in(Meters)); + } + + /** + * + * + *

Calculates the track length in the X direction.

+ * + *

Returns the total distance between the frontmost and rearmost module translations in the X direction. + * + * @return the track length. + * @throws IllegalStateException if the module translations are empty. + */ + public Distance trackLengthX() { + final OptionalDouble maxModuleX = Arrays.stream(moduleTranslations) + .mapToDouble(Translation2d::getX) + .max(); + final OptionalDouble minModuleX = Arrays.stream(moduleTranslations) + .mapToDouble(Translation2d::getX) + .min(); + if (maxModuleX.isEmpty() || minModuleX.isEmpty()) + throw new IllegalStateException("Modules translations are empty"); + return Meters.of(maxModuleX.getAsDouble() - minModuleX.getAsDouble()); + } + + /** + * + * + *

Calculates the track width in the Y direction.

+ * + *

Returns the total distance between the leftmost and rightmost module translations in the Y direction. + * + * @return the track width. + * @throws IllegalStateException if the module translations are empty. + */ + public Distance trackWidthY() { + final OptionalDouble maxModuleY = Arrays.stream(moduleTranslations) + .mapToDouble(Translation2d::getY) + .max(); + final OptionalDouble minModuleY = Arrays.stream(moduleTranslations) + .mapToDouble(Translation2d::getY) + .min(); + if (maxModuleY.isEmpty() || minModuleY.isEmpty()) + throw new IllegalStateException("Modules translations are empty"); + return Meters.of(maxModuleY.getAsDouble() - minModuleY.getAsDouble()); + } + + public Distance driveBaseRadius() { + return Meters.of(Math.hypot(trackLengthX().in(Meters), trackWidthY().in(Meters))); + } + + private void checkRobotMass() { + BoundingCheck.check(robotMass.in(Kilograms), 10, 80, "robot mass", "kg"); + } + + private void checkBumperSize() { + BoundingCheck.check(bumperLengthX.in(Meters), 0.5, 1.5, "bumper length", "meters"); + BoundingCheck.check(bumperWidthY.in(Meters), 0.5, 1.5, "bumper width", "meters"); + } + + private void checkModuleTranslations() { + for (int i = 0; i < moduleTranslations.length; i++) + BoundingCheck.check( + moduleTranslations[i].getNorm(), + 0.2, + 1.2, + "module number " + i + " translation magnitude", + "meters"); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/configs/SwerveModuleSimulationConfig.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/configs/SwerveModuleSimulationConfig.java new file mode 100644 index 0000000..bd898a6 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/configs/SwerveModuleSimulationConfig.java @@ -0,0 +1,128 @@ +package swervelib.simulation.ironmaple.simulation.drivesims.configs; + +import static edu.wpi.first.units.Units.*; + +import edu.wpi.first.math.system.plant.DCMotor; +import edu.wpi.first.math.util.Units; +import edu.wpi.first.units.measure.*; +import java.util.function.Supplier; +import swervelib.simulation.ironmaple.simulation.SimulatedArena; +import swervelib.simulation.ironmaple.simulation.drivesims.SwerveModuleSimulation; +import swervelib.simulation.ironmaple.simulation.motorsims.SimMotorConfigs; + +public class SwerveModuleSimulationConfig implements Supplier { + public final SimMotorConfigs driveMotorConfigs, steerMotorConfigs; + public final double DRIVE_GEAR_RATIO, STEER_GEAR_RATIO, WHEELS_COEFFICIENT_OF_FRICTION; + public final Voltage DRIVE_FRICTION_VOLTAGE; + public final Distance WHEEL_RADIUS; + + /** + * + * + *

Constructs a Configuration for Swerve Module Simulation.

+ * + *

If you are using {@link SimulatedArena#overrideSimulationTimings(Time, int)} to use custom timings, you must + * call the method before constructing any swerve module simulations using this constructor. + * + * @param driveMotorModel the model of the driving motor + * @param steerMotorModel; the model of the steering motor + * @param driveGearRatio the gear ratio for the driving motor, >1 is reduction + * @param steerGearRatio the gear ratio for the steering motor, >1 is reduction + * @param driveFrictionVoltage the measured minimum amount of voltage that can turn the driving rotter + * @param steerFrictionVoltage the measured minimum amount of voltage that can turn the steering rotter + * @param wheelRadius the radius of the wheels. + * @param steerRotationalInertia the rotational inertia of the entire steering mechanism + * @param wheelsCoefficientOfFriction the coefficient + * of friction of the tires, normally around 1.2 {@link Units#inchesToMeters(double)}. + */ + public SwerveModuleSimulationConfig( + DCMotor driveMotorModel, + DCMotor steerMotorModel, + double driveGearRatio, + double steerGearRatio, + Voltage driveFrictionVoltage, + Voltage steerFrictionVoltage, + Distance wheelRadius, + MomentOfInertia steerRotationalInertia, + double wheelsCoefficientOfFriction) { + BoundingCheck.check(driveGearRatio, 4, 24, "drive gear ratio", "times reduction"); + BoundingCheck.check(steerGearRatio, 6, 50, "steer gear ratio", "times reduction"); + BoundingCheck.check(driveFrictionVoltage.in(Volts), 0.01, 0.35, "drive friction voltage", "volts"); + BoundingCheck.check(steerFrictionVoltage.in(Volts), 0.01, 0.6, "steer friction voltage", "volts"); + BoundingCheck.check(wheelRadius.in(Inches), 1, 3.2, "drive wheel radius", "inches"); + BoundingCheck.check( + steerRotationalInertia.in(KilogramSquareMeters), 0.005, 0.06, "steer rotation inertia", "kg * m^2"); + BoundingCheck.check(wheelsCoefficientOfFriction, 0.6, 1.9, "tire coefficient of friction", ""); + + this.driveMotorConfigs = + new SimMotorConfigs(driveMotorModel, driveGearRatio, KilogramSquareMeters.zero(), driveFrictionVoltage); + this.steerMotorConfigs = + new SimMotorConfigs(steerMotorModel, steerGearRatio, steerRotationalInertia, steerFrictionVoltage); + DRIVE_GEAR_RATIO = driveGearRatio; + STEER_GEAR_RATIO = steerGearRatio; + WHEELS_COEFFICIENT_OF_FRICTION = wheelsCoefficientOfFriction; + DRIVE_FRICTION_VOLTAGE = driveFrictionVoltage; + WHEEL_RADIUS = wheelRadius; + } + + @Override + public SwerveModuleSimulation get() { + return new SwerveModuleSimulation(this); + } + + public double getGrippingForceNewtons(double gravityForceOnModuleNewtons) { + return gravityForceOnModuleNewtons * WHEELS_COEFFICIENT_OF_FRICTION; + } + + /** + * + * + *

Obtains the theoretical speed that the module can achieve.

+ * + * @return the theoretical maximum ground speed that the module can achieve, in m/s + */ + public LinearVelocity maximumGroundSpeed() { + return MetersPerSecond.of( + driveMotorConfigs.freeSpinMechanismVelocity().in(RadiansPerSecond) * WHEEL_RADIUS.in(Meters)); + } + + /** + * + * + *

Obtains the theoretical maximum propelling force of ONE module.

+ * + *

Calculates the maximum propelling force with respect to the gripping force and the drive motor's torque under + * its current limit. + * + * @param robotMass the mass of the robot + * @param modulesCount the amount of modules on the robot, assumed to be sharing the gravity force equally + * @return the maximum propelling force of EACH module + */ + public Force getTheoreticalPropellingForcePerModule(Mass robotMass, int modulesCount, Current statorCurrentLimit) { + final double + maxThrustNewtons = + driveMotorConfigs.calculateTorque(statorCurrentLimit).in(NewtonMeters) + / WHEEL_RADIUS.in(Meters), + maxGrippingNewtons = 9.8 * robotMass.in(Kilograms) / modulesCount * WHEELS_COEFFICIENT_OF_FRICTION; + + return Newtons.of(Math.min(maxThrustNewtons, maxGrippingNewtons)); + } + + /** + * + * + *

Obtains the theatrical linear acceleration that the robot can achieve.

+ * + *

Calculates the maximum linear acceleration of a robot, with respect to its mass and + * {@link #getTheoreticalPropellingForcePerModule(Mass, int, Current)}. + * + * @param robotMass the mass of the robot + * @param modulesCount the amount of modules on the robot, assumed to be sharing the gravity force equally + */ + public LinearAcceleration maxAcceleration(Mass robotMass, int modulesCount, Current statorCurrentLimit) { + return getTheoreticalPropellingForcePerModule(robotMass, modulesCount, statorCurrentLimit) + .times(modulesCount) + .div(robotMass); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePiece.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePiece.java new file mode 100644 index 0000000..ea9e69c --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePiece.java @@ -0,0 +1,56 @@ +package swervelib.simulation.ironmaple.simulation.gamepieces; + +import edu.wpi.first.math.geometry.Pose3d; +import edu.wpi.first.math.geometry.Translation3d; + +/** + * + * + *

Interface for all Game pieces.

+ * + *

This class contains basic functions all game pieces will have so that game pieces of different types can be used + * interchangeably in collision detection. + */ +public interface GamePiece { + + /** + * + * + *

Gives the pose3d of a game piece.

+ * + * @return The pose of this piece as a Pose3d. + */ + Pose3d getPose3d(); + + /** + * + * + *

Gives the string type of the current game piece.

+ * + * @return The game piece string type (ex "Coral", "Algae", "Note"). + */ + String getType(); + + /** + * + * + *

Gives the velocity of the game piece.

+ * + * For grounded game pieces the z access velocity does not exist and so will be set to 0 automatically. + * + * @return The velocity of the game piece as a Translation3d. + */ + Translation3d getVelocity3dMPS(); + + /** + * + * + *

Gives wether or not the piece is "grounded".

+ * + * A grounded piece is likely a child of {@link GamePieceOnFieldSimulation} while a non grounded piece is likely a + * child of{@link GamePieceProjectile}. + * + * @return wether or not the piece is grounded. + */ + boolean isGrounded(); +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceOnFieldSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceOnFieldSimulation.java new file mode 100644 index 0000000..58f0104 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceOnFieldSimulation.java @@ -0,0 +1,183 @@ +package swervelib.simulation.ironmaple.simulation.gamepieces; + +import static edu.wpi.first.units.Units.Kilogram; +import static edu.wpi.first.units.Units.Meters; + +import edu.wpi.first.math.geometry.Pose2d; +import edu.wpi.first.math.geometry.Pose3d; +import edu.wpi.first.math.geometry.Rotation3d; +import edu.wpi.first.math.geometry.Translation2d; +import edu.wpi.first.math.geometry.Translation3d; +import edu.wpi.first.math.kinematics.ChassisSpeeds; +import edu.wpi.first.units.measure.Distance; +import edu.wpi.first.units.measure.Mass; +import java.util.function.DoubleSupplier; +import org.dyn4j.dynamics.Body; +import org.dyn4j.dynamics.BodyFixture; +import org.dyn4j.geometry.Convex; +import org.dyn4j.geometry.MassType; +import swervelib.simulation.ironmaple.simulation.IntakeSimulation; +import swervelib.simulation.ironmaple.simulation.SimulatedArena; +import swervelib.simulation.ironmaple.utils.mathutils.GeometryConvertor; + +/** + * + * + *

Simulates a Game Piece on the Field.

+ * + *

This class simulates a game piece on the field, which has a collision space and interacts with other objects. + * + *

Game pieces can be "grabbed" by an {@link IntakeSimulation}. + * + *

For the simulation to actually run, every instance must be added to a + * {@link SimulatedArena} through + * {@link SimulatedArena#addGamePiece(GamePieceOnFieldSimulation)}. + */ +public class GamePieceOnFieldSimulation extends Body implements GamePiece { + public static final double COEFFICIENT_OF_FRICTION = 0.8, MINIMUM_BOUNCING_VELOCITY = 0.2; + + /** + * + * + *

Supplier of the Current Z-Pose (Height) of the Game Piece.

+ * + *

Normally, the height is fixed at half the thickness of the game piece to simulate it being "on the ground." + * + *

If the game piece is flying at a low height, the height is calculated using the law of free-fall. + */ + private final DoubleSupplier zPositionSupplier; + /** + * + * + *

The Type of the Game Piece.

+ * + *

Affects the result of {@link SimulatedArena#getGamePiecesPosesByType(String)}. + */ + public final String type; + + /** + * + * + *

Creates a Game Piece on the Field with Fixed Height.

+ * + * @param info info about the game piece type + * @param initialPose the initial position of the game piece on the field + */ + public GamePieceOnFieldSimulation(GamePieceInfo info, Pose2d initialPose) { + this(info, () -> info.gamePieceHeight.in(Meters) / 2, initialPose, new Translation2d()); + } + + /** + * + * + *

Creates a Game Piece on the Field with Custom Height Supplier and Initial Velocity.

+ * + * @param info info about the game piece type + * @param zPositionSupplier a supplier that provides the current Z-height of the game piece + * @param initialPose the initial position of the game piece on the field + * @param initialVelocityMPS the initial velocity of the game piece, in meters per second + */ + public GamePieceOnFieldSimulation( + GamePieceInfo info, + DoubleSupplier zPositionSupplier, + Pose2d initialPose, + Translation2d initialVelocityMPS) { + super(); + this.type = info.type; + this.zPositionSupplier = zPositionSupplier; + + BodyFixture bodyFixture = super.addFixture(info.shape); + + bodyFixture.setFriction(COEFFICIENT_OF_FRICTION); + bodyFixture.setRestitution(info.coefficientOfRestitution); + bodyFixture.setRestitutionVelocity(MINIMUM_BOUNCING_VELOCITY); + + bodyFixture.setDensity(info.gamePieceMass.in(Kilogram) / info.shape.getArea()); + super.setMass(MassType.NORMAL); + + super.setLinearDamping(info.linearDamping); + super.setAngularDamping(info.angularDamping); + super.setBullet(true); + + super.setTransform(GeometryConvertor.toDyn4jTransform(initialPose)); + super.setLinearVelocity(GeometryConvertor.toDyn4jVector2(initialVelocityMPS)); + } + + /** + * + * + *

Sets the world velocity of this game piece.

+ * + * @param chassisSpeedsWorldFrame the speeds of the game piece + */ + public void setVelocity(ChassisSpeeds chassisSpeedsWorldFrame) { + super.setLinearVelocity(GeometryConvertor.toDyn4jLinearVelocity(chassisSpeedsWorldFrame)); + super.setAngularVelocity(chassisSpeedsWorldFrame.omegaRadiansPerSecond); + } + + /** + * + * + *

Obtains the 2d position of the game piece

+ * + * @return the 2d position of the game piece + */ + public Pose2d getPoseOnField() { + return GeometryConvertor.toWpilibPose2d(super.getTransform()); + } + + /** + * + * + *

Obtains a 3d pose of the game piece.

+ * + *

The 3d position is calculated from both the {@link #getPoseOnField()} and {@link #zPositionSupplier} + * + * @return the 3d position of the game piece + */ + @Override + public Pose3d getPose3d() { + final Pose2d pose2d = getPoseOnField(); + return new Pose3d( + pose2d.getX(), + pose2d.getY(), + zPositionSupplier.getAsDouble(), + new Rotation3d(0, 0, pose2d.getRotation().getRadians())); + } + + /** + * + * + *

Stores the info of a type of game piece

+ * + * @param type the type of the game piece, affecting categorization within the arena + * @param shape the shape of the collision space for the game piece + * @param gamePieceHeight the height (thickness) of the game piece, in meters + * @param gamePieceMass the mass of the game piece, in kilograms + */ + public record GamePieceInfo( + String type, + Convex shape, + Distance gamePieceHeight, + Mass gamePieceMass, + double linearDamping, + double angularDamping, + double coefficientOfRestitution) {} + + public void onIntake(String intakeTargetGamePieceType) {} + + @Override + public String getType() { + return this.type; + } + + @Override + public Translation3d getVelocity3dMPS() { + return new Translation3d(GeometryConvertor.toWpilibTranslation2d(this.getLinearVelocity())); + } + + @Override + public boolean isGrounded() { + return true; + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceProjectile.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceProjectile.java new file mode 100644 index 0000000..a7aa182 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceProjectile.java @@ -0,0 +1,639 @@ +package swervelib.simulation.ironmaple.simulation.gamepieces; + +import static edu.wpi.first.units.Units.*; + +import edu.wpi.first.math.geometry.*; +import edu.wpi.first.math.kinematics.ChassisSpeeds; +import edu.wpi.first.units.measure.Angle; +import edu.wpi.first.units.measure.Distance; +import edu.wpi.first.units.measure.LinearVelocity; +import edu.wpi.first.wpilibj.Timer; +import java.util.ArrayList; +import java.util.List; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.function.Consumer; +import java.util.function.Supplier; +import swervelib.simulation.ironmaple.simulation.SimulatedArena; +import swervelib.simulation.ironmaple.utils.LegacyFieldMirroringUtils2024; + +/** + * + * + *

Simulates a Game Piece Launched into the Air

+ * + *

CheckOnline + * Documentation + * + *

The movement is modeled by simple projectile motion. + * + *

If the projectile flies off the field, touches the ground, or hits its target, it will be automatically removed. + * + *

Additional Features:

+ * + *
    + *
  • Optionally, it can be configured to become a {@link GamePieceOnFieldSimulation} upon touching the ground. + *
  • Optionally, it can be configured to have a "desired target." Upon hitting the target, it can be configured to + * run a callback. + *
+ * + *

Limitations:

+ * + *
    + *
  • Air drag is ignored. + *
  • DOES NOT have collision space when flying. + *
+ */ +public class GamePieceProjectile implements GamePiece { + /** + * This value may seem unusual compared to the standard 9.8 m/s² for gravity. However, through experimentation, it + * appears more realistic in our simulation, possibly due to the ignoring of air drag. + */ + public static final double GRAVITY = 11; + + // Properties of the game piece projectile: + protected final GamePieceOnFieldSimulation.GamePieceInfo info; + public final String gamePieceType; + protected final Translation2d initialPosition; + protected final Translation2d initialLaunchingVelocityMPS; + protected final double initialHeight, initialVerticalSpeedMPS; + protected final Rotation3d gamePieceRotation; + protected final Timer launchedTimer; + + /** + * + * + *

Visualizes the Projectile Flight Trajectory.

+ * + *

Optionally, this callback will be used to visualize the projectile flight trajectory in a telemetry system, + * such as Advantage Scope. + */ + private Consumer> projectileTrajectoryDisplayCallBackHitTarget = projectileTrajectory -> {}; + + private Consumer> projectileTrajectoryDisplayCallBackMiss = projectileTrajectory -> {}; + + // Optional properties of the game piece, used if we want it to become a + // GamePieceOnFieldSimulation upon touching ground: + protected boolean becomesGamePieceOnGroundAfterTouchGround = false; + + // Optional properties of the game piece, used if we want it to have a target: + private Translation3d tolerance = new Translation3d(0.2, 0.2, 0.2); + private Supplier targetPositionSupplier = () -> new Translation3d(0, 0, -100); + private Runnable hitTargetCallBack = () -> {}; + private double heightAsTouchGround = 0.5; + + /** + * + * + *

Time to Hit the Desired Target.

+ * + *

This value represents the amount of time it takes for the projectile to hit the desired target, calculated + * when the {@link #launch()} method is called. + * + *

Determines the results of {@link #hasHitTarget()} and {@link #willHitTarget()} + * + *

If the projectile never hits the target, or if there is no target, this value remains + * -1. + */ + private double calculatedHitTargetTime = -1; + + private boolean hitTargetCallBackCalled = false; + + /** + * + * + *

Creates a Game Piece Projectile Ejected from a Shooter.

+ * + * @param info the info of the game piece + * @param robotPosition the position of the robot (not the shooter) at the time of launching the game piece + * @param shooterPositionOnRobot the translation from the shooter's position to the robot's center, in the robot's + * frame of reference + * @param chassisSpeedsFieldRelative the field-relative velocity of the robot chassis when launching the game piece, + * influencing the initial velocity of the game piece + * @param shooterFacing the direction in which the shooter is facing at launch + * @param initialHeight the initial height of the game piece when launched, i.e., the height of the shooter from the + * ground + * @param launchingSpeed the speed at which the game piece is launch + * @param shooterAngle the pitch angle of the shooter when launching + */ + public GamePieceProjectile( + GamePieceOnFieldSimulation.GamePieceInfo info, + Translation2d robotPosition, + Translation2d shooterPositionOnRobot, + ChassisSpeeds chassisSpeedsFieldRelative, + Rotation2d shooterFacing, + Distance initialHeight, + LinearVelocity launchingSpeed, + Angle shooterAngle) { + this( + info, + robotPosition.plus(shooterPositionOnRobot.rotateBy(shooterFacing)), + calculateInitialProjectileVelocityMPS( + shooterPositionOnRobot, + chassisSpeedsFieldRelative, + shooterFacing, + launchingSpeed.in(MetersPerSecond) * Math.cos(shooterAngle.in(Radians))), + initialHeight.in(Meters), + launchingSpeed.in(MetersPerSecond) * Math.sin(shooterAngle.in(Radians)), + new Rotation3d(0, -shooterAngle.in(Radians), shooterFacing.getRadians())); + } + + /** + * + * + *

Calculates the Initial Velocity of the Game Piece Projectile in the X-Y Plane.

+ * + *

This method calculates the initial velocity of the game piece projectile, accounting for the chassis's + * translational and rotational motion as well as the shooter's ground speed. + * + * @param shooterPositionOnRobot the translation of the shooter on the robot, in the robot's frame of reference + * @param chassisSpeeds the speeds of the chassis when the game piece is launched, including translational and + * rotational velocities + * @param chassisFacing the direction the chassis is facing at the time of the launch + * @param groundSpeedMPS the ground component of the projectile's initial velocity, provided as a scalar in meters + * per second (m/s) + * @return the calculated initial velocity of the projectile as a {@link Translation2d} in meters per second + */ + private static Translation2d calculateInitialProjectileVelocityMPS( + Translation2d shooterPositionOnRobot, + ChassisSpeeds chassisSpeeds, + Rotation2d chassisFacing, + double groundSpeedMPS) { + final Translation2d + chassisTranslationalVelocity = + new Translation2d(chassisSpeeds.vxMetersPerSecond, chassisSpeeds.vyMetersPerSecond), + shooterGroundVelocityDueToChassisRotation = + shooterPositionOnRobot + .rotateBy(chassisFacing) + .rotateBy(Rotation2d.fromDegrees(90)) + .times(chassisSpeeds.omegaRadiansPerSecond), + shooterGroundVelocity = chassisTranslationalVelocity.plus(shooterGroundVelocityDueToChassisRotation); + + return shooterGroundVelocity.plus(new Translation2d(groundSpeedMPS, chassisFacing)); + } + + /** + * + * + *

Creates a Game Piece Projectile Ejected from a Shooter.

+ * + * @param info the info of the game piece + * @param initialPosition the position of the game piece at the moment it is launched into the air + * @param initialLaunchingVelocityMPS the horizontal component of the initial velocity in the X-Y plane, in meters + * per second (m/s) + * @param initialHeight the initial height of the game piece when launched (the height of the shooter from the + * ground) + * @param initialVerticalSpeedMPS the vertical component of the initial velocity, in meters per second (m/s) + * @param gamePieceRotation the 3D rotation of the game piece during flight (only affects visualization of the game + * piece) + */ + public GamePieceProjectile( + GamePieceOnFieldSimulation.GamePieceInfo info, + Translation2d initialPosition, + Translation2d initialLaunchingVelocityMPS, + double initialHeight, + double initialVerticalSpeedMPS, + Rotation3d gamePieceRotation) { + this.info = info; + this.gamePieceType = info.type(); + this.initialPosition = initialPosition; + this.initialLaunchingVelocityMPS = initialLaunchingVelocityMPS; + this.initialHeight = initialHeight; + this.initialVerticalSpeedMPS = initialVerticalSpeedMPS; + this.gamePieceRotation = gamePieceRotation; + this.launchedTimer = new Timer(); + } + + /** + * + * + *

Starts the Game Piece Projectile Simulation.

+ * + *

This method initiates the projectile motion of the game piece with the following actions: + * + *

    + *
  • Initiates the projectile motion of the game piece. The current pose can be obtained with + * {@link #getPose3d()}. + *
  • Calculates whether the projectile will hit the target during its flight. The result can be obtained using + * {@link #willHitTarget()}. + *
  • Calculates a preview trajectory by simulating the projectile's motion for up to 100 steps, with each step + * lasting 0.02 seconds. + *
  • If specified, displays the trajectory using + * {@link GamePieceProjectile#projectileTrajectoryDisplayCallBackHitTarget}, which can be set via + * {@link GamePieceProjectile#withProjectileTrajectoryDisplayCallBack(Consumer)}. + *
  • Starts the {@link #launchedTimer}, which stores the amount of time elapsed after the game piece is launched + *
+ */ + public void launch() { + final int maxIterations = 100; + final double stepSeconds = 0.02; + List trajectoryPoints = new ArrayList<>(); + + for (int i = 0; i < maxIterations; i++) { + final double t = i * stepSeconds; + final Translation3d currentPosition = getPositionAtTime(t); + trajectoryPoints.add(new Pose3d(currentPosition, gamePieceRotation)); + + if (currentPosition.getZ() < heightAsTouchGround && t * GRAVITY > initialVerticalSpeedMPS) break; + if (isOutOfField(t)) break; + final Translation3d displacementToTarget = + targetPositionSupplier.get().minus(currentPosition); + if (Math.abs(displacementToTarget.getX()) < tolerance.getX() + && Math.abs(displacementToTarget.getY()) < tolerance.getY() + && Math.abs(displacementToTarget.getZ()) < tolerance.getZ()) { + this.calculatedHitTargetTime = t; + break; + } + } + if (willHitTarget()) projectileTrajectoryDisplayCallBackHitTarget.accept(trajectoryPoints); + else projectileTrajectoryDisplayCallBackMiss.accept(trajectoryPoints); + this.hitTargetCallBackCalled = false; + + launchedTimer.start(); + } + + /** + * + * + *

Checks if the Game Piece Has Touched the Ground.

+ * + *

This method determines whether the game piece has touched the ground at the current time. + * + *

    + *
  • The result is calculated during the {@link #launch()} method. + *
  • Before calling {@link #launch()}, this method will always return false. + *
+ * + * @return true if the game piece has touched the ground, otherwise false + * + */ + public boolean hasHitGround() { + return getPositionAtTime(launchedTimer.get()).getZ() <= heightAsTouchGround + && launchedTimer.get() * GRAVITY > initialVerticalSpeedMPS; + } + + /** + * + * + *

Checks if the Game Piece Has Flown Out of the Field's Boundaries.

+ * + *

This method determines whether the game piece has flown out of the field's boundaries (outside the fence). + * + *

    + *
  • The result is calculated during the {@link #launch()} method. + *
  • Before calling {@link #launch()}, this method will always return false. + *
+ * + * @return true if the game piece has flown out of the field's boundaries, otherwise false + */ + public boolean hasGoneOutOfField() { + return isOutOfField(launchedTimer.get()); + } + + private boolean isOutOfField(double time) { + final Translation3d position = getPositionAtTime(time); + final double EDGE_TOLERANCE = 2; + return position.getX() < -EDGE_TOLERANCE + || position.getX() > LegacyFieldMirroringUtils2024.FIELD_WIDTH + EDGE_TOLERANCE + || position.getY() < -EDGE_TOLERANCE + || position.getY() > LegacyFieldMirroringUtils2024.FIELD_HEIGHT + EDGE_TOLERANCE; + } + + /** + * + * + *

Checks if the projectile will hit the target AT SOME MOMENT during its flight

+ * + *
    + *
  • The result is calculated during the {@link #launch()} method. + *
  • Before calling {@link #launch()}, this method will always return false. + *
+ * + *

This is different from {@link #hasHitTarget()} + */ + public boolean willHitTarget() { + return calculatedHitTargetTime != -1; + } + + /** + * + * + *

Checks if the Projectile Has Already Hit the Target At the Moment.

+ * + *

This method checks whether the projectile has hit the target at the current time. + * + *

    + *
  • Before calling {@link #launch()}, this method will always return false. + *
  • This is different from {@link #willHitTarget()}, which predicts whether the projectile will eventually hit + * the target. + *
+ * + * @return true if the projectile has hit the target at the current time, otherwise false + */ + public boolean hasHitTarget() { + return willHitTarget() && launchedTimer.get() >= calculatedHitTargetTime; + } + + /** + * + * + *

Clean up the trajectory through {@link #projectileTrajectoryDisplayCallBackHitTarget}

+ * + * @return this instance + */ + public GamePieceProjectile cleanUp() { + this.projectileTrajectoryDisplayCallBackHitTarget.accept(new ArrayList<>()); + this.projectileTrajectoryDisplayCallBackMiss.accept(new ArrayList<>()); + return this; + } + + /** + * + * + *

Calculates the Projectile's Position at a Given Time.

+ * + *

This method calculates the position of the projectile using the physics formula for projectile motion. + * + * @param t the time elapsed after the launch of the projectile, in seconds + * @return the calculated position of the projectile at time t as a {@link Translation3d} object + */ + protected Translation3d getPositionAtTime(double t) { + final double height = initialHeight + initialVerticalSpeedMPS * t - 1.0 / 2.0 * GRAVITY * t * t; + + final Translation2d current2dPosition = initialPosition.plus(initialLaunchingVelocityMPS.times(t)); + return new Translation3d(current2dPosition.getX(), current2dPosition.getY(), height); + } + + /** + * + * + *

Calculates the Projectile's Velocity at a Given Time.

+ * + *

This method calculates the 3d velocity of the projectile using the physics formula for projectile motion. + * + * @param t the time elapsed after the launch of the projectile, in seconds + * @return a {@link Translation3d} object representing the calculated 3d velocity of the projectile at time t + * , in meters per second + */ + private Translation3d getVelocityMPSAtTime(double t) { + final double verticalVelocityMPS = initialVerticalSpeedMPS - GRAVITY * t; + + return new Translation3d( + initialLaunchingVelocityMPS.getX(), initialLaunchingVelocityMPS.getY(), verticalVelocityMPS); + } + + /** + * + * + *

Calculates the Projectile's Current Position.

+ * + *

The position is calculated using {@link #getPositionAtTime(double)} while the rotation is pre-stored. + * + * @return a {@link Pose3d} object representing the current pose of the game piece + */ + @Override + public Pose3d getPose3d() { + return new Pose3d(getPositionAtTime(launchedTimer.get()), gamePieceRotation); + } + + /** + * + * + *

Calculates the Projectile's Velocity at a Given Time.

+ * + * @see #getVelocityMPSAtTime(double) + * @return a {@link Translation3d} object representing the calculated 3d velocity of the projectile at time t + * , in meters per second + */ + @Override + public Translation3d getVelocity3dMPS() { + return getVelocityMPSAtTime(launchedTimer.get()); + } + + /** + * + * + *

Adds a {@link GamePieceOnFieldSimulation} to a {@link SimulatedArena} to Simulate the Game Piece After + * Touch-Ground.

+ * + *

The added {@link GamePieceOnFieldSimulation} will have the initial velocity of the game piece projectile. + * + *

The game piece will start falling from mid-air until it touches the ground. + * + *

The added {@link GamePieceOnFieldSimulation} will always have collision space on the field, even before + * touching the ground. + * + * @param simulatedArena the arena simulation to which the game piece will be added, usually obtained from + * {@link SimulatedArena#getInstance()} + */ + public void addGamePieceAfterTouchGround(SimulatedArena simulatedArena) { + if (!becomesGamePieceOnGroundAfterTouchGround) return; + simulatedArena.addGamePiece(new GamePieceOnFieldSimulation( + info, + () -> Math.max( + info.gamePieceHeight().in(Meters) / 2, + getPositionAtTime(launchedTimer.get()).getZ()), + new Pose2d(getPositionAtTime(launchedTimer.get()).toTranslation2d(), new Rotation2d()), + initialLaunchingVelocityMPS)); + } + + /** + * + * + *

Check every {@link GamePieceProjectile} instance for available actions.

+ * + *

1. If a game piece {@link #hasHitTarget()}, remove it and run {@link #hitTargetCallBack} specified by + * {@link #withHitTargetCallBack(Runnable)} + * + *

2. If a game piece {@link #hasHitGround()}, remove it and create a corresponding + * {@link GamePieceOnFieldSimulation} using {@link #addGamePieceAfterTouchGround(SimulatedArena)} + * + *

3. If a game piece {@link #hasGoneOutOfField()}, remove it. + */ + public static void updateGamePieceProjectiles( + SimulatedArena simulatedArena, Set gamePieceProjectiles) { + final Queue toRemoves = new ArrayBlockingQueue<>(5); + for (GamePieceProjectile gamePieceProjectile : gamePieceProjectiles) { + if (gamePieceProjectile.hasHitTarget() + || gamePieceProjectile.hasHitGround() + || gamePieceProjectile.hasGoneOutOfField()) toRemoves.offer(gamePieceProjectile); + if (gamePieceProjectile.hasHitTarget() && !gamePieceProjectile.hitTargetCallBackCalled) { + gamePieceProjectile.hitTargetCallBack.run(); + gamePieceProjectile.hitTargetCallBackCalled = true; + } + if (gamePieceProjectile.hasHitGround()) gamePieceProjectile.addGamePieceAfterTouchGround(simulatedArena); + } + + while (!toRemoves.isEmpty()) simulatedArena.removePiece(toRemoves.poll().cleanUp()); + } + + // The rest are methods to configure a game piece projectile simulation + /** + * + * + *

Configures the Game Piece Projectile to Automatically Become a {@link GamePieceOnFieldSimulation} Upon + * Touching Ground.

+ * + *

This method configures the game piece projectile to transform into a {@link GamePieceOnFieldSimulation} when + * it touches the ground. + * + * @return the current instance of {@link GamePieceProjectile} to allow method chaining + */ + public GamePieceProjectile enableBecomesGamePieceOnFieldAfterTouchGround() { + this.becomesGamePieceOnGroundAfterTouchGround = true; + return this; + } + + /** + * + * + *

Configures the Game Piece Projectile to Disappear Upon Touching Ground.

+ * + *

Reverts the effect of {@link #enableBecomesGamePieceOnFieldAfterTouchGround()}. + */ + public GamePieceProjectile disableBecomesGamePieceOnFieldAfterTouchGround() { + this.becomesGamePieceOnGroundAfterTouchGround = false; + return this; + } + + /** + * + * + *

Sets a Target for the Game Projectile.

+ * + *

Configures the {@link #targetPositionSupplier} of this game piece projectile. + * + *

The method {@link #launch()} will estimate whether or not the game piece will hit the target. + * + *

After calling {@link #launch()}, {@link #hasHitTarget()} will indicate whether the game piece has already hit + * the target. + * + *

Before calling this method, the target position is 0, 0, -100 (x,y,z), which the projectile will + * never hit. + * + * @param targetPositionSupplier the position of the target, represented as a {@link Translation3d} + * @return the current instance of {@link GamePieceProjectile} to allow method chaining + */ + public GamePieceProjectile withTargetPosition(Supplier targetPositionSupplier) { + this.targetPositionSupplier = targetPositionSupplier; + return this; + } + + /** + * + * + *

Sets the Target Tolerance for the Game Projectile.

+ * + *

Configures the {@link #tolerance} for determining whether the game piece has hit the target. The tolerance + * defines how close the projectile needs to be to the target for it to be considered a hit. + * + *

If this method is not called, the default tolerance is 0.2, 0.2, 0.2 (x,y,z) + * + * @param tolerance the tolerance for the target, represented as a {@link Translation3d} + * @return the current instance of {@link GamePieceProjectile} to allow method chaining + */ + public GamePieceProjectile withTargetTolerance(Translation3d tolerance) { + this.tolerance = tolerance; + return this; + } + + /** + * + * + *

Configures a callback to be executed when the game piece hits the target.

+ * + *

Sets the {@link #hitTargetCallBack} to Execute When the Game Piece Hits the Target. + * + *

The callback will be triggered when {@link #hasHitTarget()} becomes true. + * + * @param hitTargetCallBack the callback to run when the game piece hits the target + * @return the current instance of {@link GamePieceProjectile} to allow method chaining + */ + public GamePieceProjectile withHitTargetCallBack(Runnable hitTargetCallBack) { + this.hitTargetCallBack = hitTargetCallBack; + return this; + } + + /** + * + * + *

Configures a Callback to Display the Trajectory of the Projectile When Launched.

+ * + *

Sets the {@link #projectileTrajectoryDisplayCallBackHitTarget} to be fed with data during the + * {@link #launch()} method. + * + *

A {@link List} containing up to 50 {@link Pose3d} objects will be passed to the callback, representing the + * future trajectory of the projectile. + * + *

This is usually for visualizing the trajectory of the projectile on a telemetry, like Advantage Scope + * + * @param projectileTrajectoryDisplayCallBack the callback that will receive the list of {@link Pose3d} objects + * representing the projectile's trajectory + * @return the current instance of {@link GamePieceProjectile} to allow method chaining + */ + public GamePieceProjectile withProjectileTrajectoryDisplayCallBack( + Consumer> projectileTrajectoryDisplayCallBack) { + this.projectileTrajectoryDisplayCallBackMiss = + this.projectileTrajectoryDisplayCallBackHitTarget = projectileTrajectoryDisplayCallBack; + return this; + } + + /** + * + * + *

Configures a Callback to Display the Trajectory of the Projectile When Launched.

+ * + *

Sets the {@link #projectileTrajectoryDisplayCallBackHitTarget} to be fed with data during the + * {@link #launch()} method. + * + *

A {@link List} containing up to 50 {@link Pose3d} objects will be passed to the callback, representing the + * future trajectory of the projectile. + * + *

This is usually for visualizing the trajectory of the projectile on a telemetry, like Advantage Scope + * + * @param projectileTrajectoryDisplayCallBackHitTarget the callback that will receive the list of {@link Pose3d} + * objects representing the projectile's trajectory, called if the projectile will hit the target on its path + * @param projectileTrajectoryDisplayCallBackHitTargetMiss the callback that will receive the list of {@link Pose3d} + * objects representing the projectile's trajectory, called if the projectile will be off the target + * @return the current instance of {@link GamePieceProjectile} to allow method chaining + */ + public GamePieceProjectile withProjectileTrajectoryDisplayCallBack( + Consumer> projectileTrajectoryDisplayCallBackHitTarget, + Consumer> projectileTrajectoryDisplayCallBackHitTargetMiss) { + this.projectileTrajectoryDisplayCallBackHitTarget = projectileTrajectoryDisplayCallBackHitTarget; + this.projectileTrajectoryDisplayCallBackMiss = projectileTrajectoryDisplayCallBackHitTargetMiss; + return this; + } + + /** + * + * + *

Configures the Height at Which the Projectile Is Considered to Be Touching Ground.

+ * + *

Sets the {@link #heightAsTouchGround}, defining the height at which the projectile is considered to have + * landed. + * + *

When the game piece is below this height, it will either be deleted or, if configured, transformed into a + * {@link GamePieceOnFieldSimulation} using {@link #enableBecomesGamePieceOnFieldAfterTouchGround()}. + * + * @param heightAsTouchGround the height (in meters) at which the projectile is considered to touch the ground + * @return the current instance of {@link GamePieceProjectile} to allow method chaining + */ + public GamePieceProjectile withTouchGroundHeight(double heightAsTouchGround) { + this.heightAsTouchGround = heightAsTouchGround; + return this; + } + + @Override + public String getType() { + return this.gamePieceType; + } + + @Override + public boolean isGrounded() { + return false; + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/MapleMotorSim.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/MapleMotorSim.java new file mode 100644 index 0000000..d8da554 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/MapleMotorSim.java @@ -0,0 +1,194 @@ +package swervelib.simulation.ironmaple.simulation.motorsims; + +import static edu.wpi.first.units.Units.*; + +import edu.wpi.first.units.measure.*; +import edu.wpi.first.wpilibj.simulation.DCMotorSim; + +/** + * + * + *

{@link edu.wpi.first.wpilibj.simulation.DCMotorSim} with a bit of extra spice.

+ * + *

This class extends the functionality of the original {@link edu.wpi.first.wpilibj.simulation.DCMotorSim} and + * models the following aspects in addition: + * + *

    + *
  • Motor Controller Closed Loops. + *
  • Smart current limiting. + *
  • Friction force on the rotor. + *
+ */ +public class MapleMotorSim { + private final SimMotorConfigs configs; + + private SimMotorState state; + private SimulatedMotorController controller; + private Voltage appliedVoltage; + private Current statorCurrent; + + /** + * + * + *

Constructs a Brushless Motor Simulation Instance.

+ * + * @param configs the configuration for this motor + */ + public MapleMotorSim(SimMotorConfigs configs) { + this.configs = configs; + this.state = new SimMotorState(Radians.zero(), RadiansPerSecond.zero()); + this.controller = (mechanismAngle, mechanismVelocity, encoderAngle, encoderVelocity) -> Volts.of(0); + this.appliedVoltage = Volts.zero(); + this.statorCurrent = Amps.zero(); + + SimulatedBattery.addMotor(this); + } + + /** + * + * + *

Updates the simulation.

+ * + *

This is equivalent to{@link edu.wpi.first.wpilibj.simulation.DCMotorSim#update(double)}. + */ + public void update(Time dt) { + this.appliedVoltage = controller.updateControlSignal( + state.mechanismAngularPosition, + state.mechanismAngularVelocity, + state.mechanismAngularPosition.times(configs.gearing), + state.mechanismAngularVelocity.times(configs.gearing)); + this.appliedVoltage = SimulatedBattery.clamp(appliedVoltage); + this.statorCurrent = configs.calculateCurrent(state.mechanismAngularVelocity, appliedVoltage); + this.state.step(configs.calculateTorque(statorCurrent), configs.friction, configs.loadMOI, dt); + + if (state.mechanismAngularPosition.lte(configs.reverseHardwareLimit)) + state = new SimMotorState(configs.reverseHardwareLimit, RadiansPerSecond.zero()); + else if (state.mechanismAngularPosition.gte(configs.forwardHardwareLimit)) + state = new SimMotorState(configs.forwardHardwareLimit, RadiansPerSecond.zero()); + } + + public T useMotorController(T motorController) { + this.controller = motorController; + return motorController; + } + + public SimulatedMotorController.GenericMotorController useSimpleDCMotorController() { + return useMotorController(new SimulatedMotorController.GenericMotorController(configs.motor)); + } + + /** + * + * + *

Obtains the final position of the mechanism.

+ * + *

This is equivalent to {@link edu.wpi.first.wpilibj.simulation.DCMotorSim#getAngularPosition()}. + * + * @return the angular position of the mechanism, continuous + */ + public Angle getAngularPosition() { + return state.mechanismAngularPosition; + } + + /** + * + * + *

Obtains the angular position measured by the relative encoder of the motor.

+ * + * @return the angular position measured by the encoder, continuous + */ + public Angle getEncoderPosition() { + return getAngularPosition().times(configs.gearing); + } + + /** + * + * + *

Obtains the final velocity of the mechanism.

+ * + *

This is equivalent to {@link edu.wpi.first.wpilibj.simulation.DCMotorSim#getAngularVelocity()}. + * + * @return the final angular velocity of the mechanism + */ + public AngularVelocity getVelocity() { + return state.mechanismAngularVelocity; + } + + /** + * + * + *

Obtains the angular velocity measured by the relative encoder of the motor.

+ * + * @return the angular velocity measured by the encoder + */ + public AngularVelocity getEncoderVelocity() { + return getVelocity().times(configs.gearing); + } + + /** + * + * + *

Obtains the applied voltage by the motor controller.

+ * + *

The applied voltage is calculated by the motor controller in the previous call to {@link #update(Time)} + * + *

The motor controller specified by {@link #useMotorController(SimulatedMotorController)} is used to calculate + * the applied voltage. + * + *

The applied voltage is also restricted for current limit and battery voltage. + * + * @return the applied voltage + */ + public Voltage getAppliedVoltage() { + return appliedVoltage; + } + + /** + * + * + *

Obtains the stator current.

+ * + *

This is equivalent to {@link DCMotorSim#getCurrentDrawAmps()} + * + * @return the stator current of the motor + */ + public Current getStatorCurrent() { + return statorCurrent; + } + + /** + * + * + *

Obtains the supply current.

+ * + *

The supply current is different from the stator current, as described here. + * + * @return the supply current of the motor + */ + public Current getSupplyCurrent() { + // Supply Power = Stator Power (Conservation of Energy) + // Hence, + // Battery Voltage x Supply Current = Applied Voltage x Stator Current + // Supply Current = Stator Current * Applied Voltage / Battery Voltage + return getStatorCurrent().times(appliedVoltage.div(SimulatedBattery.getBatteryVoltage())); + } + + /** + * + * + *

Obtains the configuration of the motor.

+ * + *

You can modify the configuration of this motor by: + * + *


+     *     mapleMotorSim.getConfigs()
+     *          .with...(...)
+     *          .with...(...);
+     * 
+ * + * @return the configuration of the motor + */ + public SimMotorConfigs getConfigs() { + return this.configs; + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimMotorConfigs.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimMotorConfigs.java new file mode 100644 index 0000000..b9cfb65 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimMotorConfigs.java @@ -0,0 +1,203 @@ +package swervelib.simulation.ironmaple.simulation.motorsims; + +import static edu.wpi.first.units.Units.*; +import static edu.wpi.first.units.Units.Volts; + +import edu.wpi.first.math.system.plant.DCMotor; +import edu.wpi.first.units.measure.*; + +/** + * + * + *

Stores the configurations of the motor.

+ * + *

This class encapsulates the various configuration parameters required to simulate and control a motor in a system. + * The configurations include: + * + *

    + *
  • motor: The motor model used in the simulation (e.g., Falcon 500, NEO). + *
  • gearing: The gear ratio between the motor and the load, affecting the output torque and speed. + *
  • loadMOI: The moment of inertia (MOI) of the load connected to the motor, which determines the + * resistance to changes in rotational speed. + *
  • friction: The torque friction characteristics applied to the motor's simulation, representing + * real-world losses. + *
  • positionVoltageController: PID controller for controlling the motor's position via voltage. + *
  • velocityVoltageController: PID controller for controlling the motor's velocity via voltage. + *
  • positionCurrentController: PID controller for controlling the motor's position via current. + *
  • velocityCurrentController: PID controller for controlling the motor's velocity via current. + *
  • feedforward: A feedforward controller used to compensate for the desired motor behavior based + * on input speeds. + *
  • forwardHardwareLimit: The forward limit for motor rotation, specified in angle units. + *
  • reverseHardwareLimit: The reverse limit for motor rotation, specified in angle units. + *
  • currentLimit: The current limit applied to the motor to protect it from overcurrent + * conditions. + *
+ */ +public final class SimMotorConfigs { + public final DCMotor motor; + public final double gearing; + public final MomentOfInertia loadMOI; + public final Torque friction; + + protected Angle forwardHardwareLimit, reverseHardwareLimit; + + /** + * + * + *

Constructs a simulated motor configuration.

+ * + *

This constructor initializes a {@link SimMotorConfigs} object with the necessary parameters for motor + * simulation, including the motor model, gearing ratio, load moment of inertia, and friction characteristics. + * + * @param motor the motor model to be used in the simulation (e.g., Falcon 500, NEO). + * @param gearing the gear ratio between the motor and the load, affecting torque and speed output. + * @param loadMOI the moment of inertia of the load connected to the motor, representing rotational resistance. + * @param frictionVoltage the voltage applied to simulate frictional torque losses in the motor. + */ + public SimMotorConfigs(DCMotor motor, double gearing, MomentOfInertia loadMOI, Voltage frictionVoltage) { + this.motor = motor; + this.gearing = gearing; + this.loadMOI = loadMOI; + this.friction = NewtonMeters.of(motor.getTorque(motor.getCurrent(0, frictionVoltage.in(Volts)))); + + forwardHardwareLimit = Radians.of(Double.POSITIVE_INFINITY); + reverseHardwareLimit = Radians.of(-Double.POSITIVE_INFINITY); + } + + /** + * + * + *

Calculates the voltage of the motor.

+ * + *

This method uses the {@link DCMotor} model to find the voltage for a given current and angular velocity. + * + * @see DCMotor#getVoltage(double, double) for the underlying implementation. + * @param current the current flowing through the motor + * @param mechanismVelocity the final angular velocity of the mechanism + * @return the voltage required for the motor to achieve the specified current and angular velocity + */ + public Voltage calculateVoltage(Current current, AngularVelocity mechanismVelocity) { + return Volts.of(motor.getVoltage(current.in(Amps), mechanismVelocity.in(RadiansPerSecond) * gearing)); + } + + /** + * + * + *

Calculates the velocity of the motor.

+ * + *

This method uses the {@link DCMotor} model to find the angular velocity for a given current and voltage. + * + * @see DCMotor#getSpeed(double, double) for the underlying implementation. + * @param current the current flowing through the motor. + * @param voltage the voltage applied to the motor. + * @return the final angular velocity of the mechanism. + */ + public AngularVelocity calculateMechanismVelocity(Current current, Voltage voltage) { + return RadiansPerSecond.of(motor.getSpeed(motor.getTorque(current.in(Amps)), voltage.in(Volts))) + .div(gearing); + } + + /** + * + * + *

Calculates the current of the motor.

+ * + *

This method uses the {@link DCMotor} model to find the current for a given angular velocity and voltage. + * + * @see DCMotor#getCurrent(double, double) for the underlying implementation. + * @param mechanismVelocity the final angular velocity of the mechanism. + * @param voltage the voltage applied to the moto. + * @return the current drawn by the motor. + */ + public Current calculateCurrent(AngularVelocity mechanismVelocity, Voltage voltage) { + return Amps.of(motor.getCurrent(mechanismVelocity.in(RadiansPerSecond) * gearing, voltage.in(Volts))); + } + + /** + * + * + *

Calculates the current based on the motor's torque.

+ * + *

This method uses the {@link DCMotor} model to find the current required for a given torque. + * + * @see DCMotor#getCurrent(double) for the underlying implementation. + * @param torque the final torque generated by the motor on the mechanism. + * @return the current required to produce the specified torque. + */ + public Current calculateCurrent(Torque torque) { + return Amps.of(motor.getCurrent(torque.in(NewtonMeters) / gearing)); + } + + /** + * + * + *

Calculates the torque based on the motor's current.

+ * + *

This method uses the {@link DCMotor} model to find the torque generated by a given current. + * + * @see DCMotor#getTorque(double) for the underlying implementation. + * @param current the current flowing through the motor. + * @return the torque generated by the motor. + */ + public Torque calculateTorque(Current current) { + return NewtonMeters.of(motor.getTorque(current.in(Amps)) * gearing); + } + + /** + * + * + *

Configures the hard limits for the motor.

+ * + *

This method sets the hardware limits for the motor's movement. When either the forward or reverse limit is + * reached, the motor will be physically restricted from moving beyond that point, based on the motor's hardware + * constraints. + * + * @param forwardLimit the forward hardware limit angle, beyond which the motor cannot move + * @param reverseLimit the reverse hardware limit angle, beyond which the motor cannot move + * @return this instance for method chaining + */ + public SimMotorConfigs withHardLimits(Angle forwardLimit, Angle reverseLimit) { + this.forwardHardwareLimit = forwardLimit; + this.reverseHardwareLimit = reverseLimit; + return this; + } + + public AngularVelocity freeSpinMechanismVelocity() { + return RadiansPerSecond.of(motor.freeSpeedRadPerSec / gearing); + } + + public Current freeSpinCurrent() { + return Amps.of(motor.freeCurrentAmps); + } + + public Current stallCurrent() { + return Amps.of(motor.stallCurrentAmps); + } + + public Torque stallTorque() { + return NewtonMeters.of(motor.stallTorqueNewtonMeters); + } + + public Voltage nominalVoltage() { + return Volts.of(motor.nominalVoltageVolts); + } + + @Override + protected SimMotorConfigs clone() { + SimMotorConfigs cfg = new SimMotorConfigs( + motor, gearing, loadMOI, Volts.of(motor.getVoltage(friction.in(NewtonMeter), 0.0))) + .withHardLimits(forwardHardwareLimit, reverseHardwareLimit); + + return cfg; + } + + @Override + public String toString() { + return "SimMotorConfigs {" + + "\n motor = " + motor // Relies on DCMotor.toString() for details + + "\n gearing = " + gearing + + "\n loadMOI (kg·m^2) = " + loadMOI.in(KilogramSquareMeters) + + "\n friction (N·m) = " + friction.in(NewtonMeters) + + "\n}"; + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimMotorState.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimMotorState.java new file mode 100644 index 0000000..86fc9a4 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimMotorState.java @@ -0,0 +1,95 @@ +package swervelib.simulation.ironmaple.simulation.motorsims; + +import static edu.wpi.first.units.Units.*; + +import edu.wpi.first.units.measure.*; + +/** + * + * + *

Represents the state of a simulated motor at a given point in time.

+ * + *

This record holds the final angular position and velocity of the motor. It is used to track the motor's state + * during each simulation step. + */ +public class SimMotorState { + public Angle mechanismAngularPosition; + public AngularVelocity mechanismAngularVelocity; + + /** + * + * + *

Constructs a new sim motor state with initial angle and velocity

+ * + * @param mechanismAngularPosition the final angular position of the motor, in radians + * @param mechanismAngularVelocity the final angular velocity of the motor, in radians per second + */ + public SimMotorState(Angle mechanismAngularPosition, AngularVelocity mechanismAngularVelocity) { + this.mechanismAngularPosition = mechanismAngularPosition; + this.mechanismAngularVelocity = mechanismAngularVelocity; + } + + /** + * + * + *

Simulates a step in the motor's motion based on the applied forces.

+ * + *

This method calculates the new angular position and velocity of the motor after applying electric and + * frictional torques over a time step. + * + *

The method follows these steps: + * + *

    + *
  • Convert all units to SI units for calculation. + *
  • Apply the electric torque to the current angular velocity. + *
  • Compute the change in angular velocity due to friction. + *
  • If friction reverses the direction of angular velocity, the velocity is set to zero. + *
  • Integrate the angular velocity to find the new position. + *
+ * + * @param finalElectricTorque the final applied electric torque, in Newton-meters + * @param finalFrictionTorque the final frictional torque, in Newton-meters + * @param loadMOI the moment of inertia of the load, in kilogram square meters + * @param dt the time step for the simulation, in seconds + */ + public void step(Torque finalElectricTorque, Torque finalFrictionTorque, MomentOfInertia loadMOI, Time dt) { + // Step 0: Convert all units to SI units (radians, radians per second, Newton-meters, seconds, kg*m²) + double currentAngularPositionRadians = mechanismAngularPosition.in(Radians); + double currentAngularVelocityRadiansPerSecond = mechanismAngularVelocity.in(RadiansPerSecond); + final double electricTorqueNewtonsMeters = finalElectricTorque.in(NewtonMeters); + final double frictionTorqueNewtonsMeters = finalFrictionTorque.in(NewtonMeters); + final double loadMOIKgMetersSquared = loadMOI.in(KilogramSquareMeters); + final double dtSeconds = dt.in(Seconds); + + // Step 1: Apply electric torque to the angular velocity. + // The torque causes a change in the angular velocity, according to the moment of inertia. + currentAngularVelocityRadiansPerSecond += electricTorqueNewtonsMeters / loadMOIKgMetersSquared * dtSeconds; + + // Step 2: Calculate the change in angular velocity due to friction. + // Friction opposes the motion and reduces the angular velocity over time. + final double deltaAngularVelocityDueToFrictionRadPerSec = + Math.copySign(frictionTorqueNewtonsMeters, -currentAngularVelocityRadiansPerSecond) + / loadMOIKgMetersSquared + * dtSeconds; + + // Step 3: Check if the angular velocity changes direction due to friction, or if it reaches zero. + // If friction causes the motor to reverse direction, or if the velocity reaches zero, set the angular velocity + // to zero. + if ((currentAngularVelocityRadiansPerSecond + deltaAngularVelocityDueToFrictionRadPerSec) + * currentAngularVelocityRadiansPerSecond + <= 0) + // The velocity has reversed direction or reached zero, so stop the motor + currentAngularVelocityRadiansPerSecond = 0; + else + // Otherwise, apply the change due to friction + currentAngularVelocityRadiansPerSecond += deltaAngularVelocityDueToFrictionRadPerSec; + + // Step 4: Integrate angular velocity to find the new position. + // The new angular position is the current position plus the change in position over the time step. + currentAngularPositionRadians += currentAngularVelocityRadiansPerSecond * dtSeconds; + + // Return a new instance with the updated angular position and velocity + this.mechanismAngularPosition = Radians.of(currentAngularPositionRadians); + this.mechanismAngularVelocity = RadiansPerSecond.of(currentAngularVelocityRadiansPerSecond); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimulatedBattery.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimulatedBattery.java new file mode 100644 index 0000000..08cdfb6 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimulatedBattery.java @@ -0,0 +1,138 @@ +package swervelib.simulation.ironmaple.simulation.motorsims; + +import static edu.wpi.first.units.Units.Amps; +import static edu.wpi.first.units.Units.Volts; + +import edu.wpi.first.math.MathUtil; +import edu.wpi.first.math.filter.LinearFilter; +import edu.wpi.first.units.measure.Current; +import edu.wpi.first.units.measure.Voltage; +import edu.wpi.first.wpilibj.DriverStation; +import edu.wpi.first.wpilibj.simulation.BatterySim; +import edu.wpi.first.wpilibj.simulation.RoboRioSim; +import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +/** + * + * + *

Simulates the main battery of the robot.

+ * + *

This class simulates the behavior of a robot's battery. Electrical appliances can be added to the battery to draw + * current. The battery voltage is affected by the current drawn from various appliances. + */ +public class SimulatedBattery { + // Nominal voltage for a fully charged battery (13.5 volts). + private static final double BATTERY_NOMINAL_VOLTAGE = 13.5; + + // Filter to smooth the current readings. + private static final LinearFilter currentFilter = LinearFilter.movingAverage(50); + + private static final List> electricalAppliances = new ArrayList<>(); + + // The current battery voltage in volts. + private static double batteryVoltageVolts = BATTERY_NOMINAL_VOLTAGE; + + /** + * + * + *

Adds a custom electrical appliance.

+ * + *

Connects the electrical appliance to the battery, allowing it to draw current from the battery. + * + * @param customElectricalAppliances The supplier for the current drawn by the appliance. + */ + public static void addElectricalAppliances(Supplier customElectricalAppliances) { + electricalAppliances.add(customElectricalAppliances); + } + + /** + * + * + *

Adds a motor to the list of electrical appliances.

+ * + *

The motor will draw current from the battery. + * + * @param mapleMotorSim The motor simulation object. + */ + public static void addMotor(MapleMotorSim mapleMotorSim) { + electricalAppliances.add(mapleMotorSim::getSupplyCurrent); + } + + /** + * + * + *

Updates the battery simulation.

+ * + *

Calculates the battery voltage based on the current drawn by all appliances. + * + *

The battery voltage is clamped to avoid going below the brownout voltage. + */ + public static void simulationSubTick() { + double totalCurrentAmps = getTotalCurrentDrawn().in(Amps); + totalCurrentAmps = currentFilter.calculate(totalCurrentAmps); + + batteryVoltageVolts = BatterySim.calculateLoadedBatteryVoltage(BATTERY_NOMINAL_VOLTAGE, 0.02, totalCurrentAmps); + + if (Double.isNaN(batteryVoltageVolts)) { + batteryVoltageVolts = 12.0; + DriverStation.reportError( + "[MapleSim] Internal Library Error: Calculated battery voltage is invalid" + + ", reverting to normal operation voltage...", + false); + } + if (batteryVoltageVolts < RoboRioSim.getBrownoutVoltage()) { + batteryVoltageVolts = RoboRioSim.getBrownoutVoltage(); + DriverStation.reportError("[MapleSim] BrownOut Detected, protecting battery voltage...", false); + } + + RoboRioSim.setVInVoltage(batteryVoltageVolts); + + SmartDashboard.putNumber("BatterySim/TotalCurrent (Amps)", totalCurrentAmps); + SmartDashboard.putNumber("BatterySim/BatteryVoltage (Volts)", batteryVoltageVolts); + } + + /** + * + * + *

Obtains the voltage of the battery.

+ * + * @return The battery voltage as a {@link Voltage} object. + */ + public static Voltage getBatteryVoltage() { + return Volts.of(batteryVoltageVolts); + } + + /** + * + * + *

Obtains the total current drawn from the battery.

+ * + *

Iterates through all the appliances to obtain the total current used. + * + * @return The total current as a {@link Current} object. + */ + public static Current getTotalCurrentDrawn() { + double totalCurrentAmps = electricalAppliances.stream() + .mapToDouble(currentSupplier -> currentSupplier.get().in(Amps)) + .sum(); + return Amps.of(totalCurrentAmps); + } + + /** + * + * + *

Clamps the voltage according to the supplied voltage and the battery's capabilities.

+ * + *

If the supplied voltage exceeds the battery's maximum voltage, it will be reduced to match the battery's + * voltage. + * + * @param voltage The voltage to be clamped. + * @return The clamped voltage as a {@link Voltage} object. + */ + public static Voltage clamp(Voltage voltage) { + return Volts.of(MathUtil.clamp(voltage.in(Volts), -batteryVoltageVolts, batteryVoltageVolts)); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimulatedMotorController.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimulatedMotorController.java new file mode 100644 index 0000000..4eeddd1 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimulatedMotorController.java @@ -0,0 +1,108 @@ +package swervelib.simulation.ironmaple.simulation.motorsims; + +import static edu.wpi.first.units.Units.*; + +import edu.wpi.first.math.system.plant.DCMotor; +import edu.wpi.first.units.measure.Angle; +import edu.wpi.first.units.measure.AngularVelocity; +import edu.wpi.first.units.measure.Current; +import edu.wpi.first.units.measure.Voltage; + +public interface SimulatedMotorController { + Voltage updateControlSignal( + Angle mechanismAngle, + AngularVelocity mechanismVelocity, + Angle encoderAngle, + AngularVelocity encoderVelocity); + + final class GenericMotorController implements SimulatedMotorController { + private final DCMotor model; + private Current currentLimit = Amps.of(150); + private Angle forwardSoftwareLimit = Radians.of(Double.POSITIVE_INFINITY), + reverseSoftwareLimit = Radians.of(-Double.POSITIVE_INFINITY); + + private Voltage requestedVoltage = Volts.zero(); + private Voltage appliedVoltage = Volts.zero(); + + public GenericMotorController(DCMotor model) { + this.model = model; + } + + public GenericMotorController withCurrentLimit(Current currentLimit) { + this.currentLimit = currentLimit; + return this; + } + + public GenericMotorController withSoftwareLimits(Angle forwardSoftwareLimit, Angle reverseSoftwareLimit) { + this.forwardSoftwareLimit = forwardSoftwareLimit; + this.reverseSoftwareLimit = reverseSoftwareLimit; + return this; + } + + public void requestVoltage(Voltage voltage) { + this.requestedVoltage = voltage; + } + + /** + * + * + *

(Utility Function) Constrains the Output Voltage of a Motor.

+ * + *

Constrains the output voltage of a motor such that the stator current does not exceed the + * current limit + * + *

Prevents motor from exceeding software limits + * + * @param encoderAngle the angle of the encoder + * @param encoderVelocity the velocity of the encoder + * @param requestedVoltage the requested voltage + * @return the constrained voltage that satisfied the limits + */ + public Voltage constrainOutputVoltage( + Angle encoderAngle, AngularVelocity encoderVelocity, Voltage requestedVoltage) { + final double kCurrentThreshold = 1.2; + + // don't use WpiLib Units for calculations + final double motorCurrentVelocityRadPerSec = encoderVelocity.in(RadiansPerSecond); + final double currentLimitAmps = currentLimit.in(Amps); + final double requestedOutputVoltageVolts = requestedVoltage.in(Volts); + final double currentAtRequestedVoltageAmps = + model.getCurrent(motorCurrentVelocityRadPerSec, requestedOutputVoltageVolts); + + // Resource for current limiting: + // https://file.tavsys.net/control/controls-engineering-in-frc.pdf (sec 12.1.3) + double limitedVoltage = requestedOutputVoltageVolts; + final boolean currentTooHigh = + Math.abs(currentAtRequestedVoltageAmps) > (kCurrentThreshold * currentLimitAmps); + if (currentTooHigh) { + final double limitedCurrent = Math.copySign(currentLimitAmps, currentAtRequestedVoltageAmps); + limitedVoltage = model.getVoltage(model.getTorque(limitedCurrent), motorCurrentVelocityRadPerSec); + } + + // ensure the current limit doesn't cause an increase to output voltage + if (Math.abs(limitedVoltage) > Math.abs(requestedOutputVoltageVolts)) + limitedVoltage = requestedOutputVoltageVolts; + + // apply software limits + if (encoderAngle.gte(forwardSoftwareLimit) && limitedVoltage > 0) limitedVoltage = 0; + if (encoderAngle.lte(reverseSoftwareLimit) && limitedVoltage < 0) limitedVoltage = 0; + + // constrain the output voltage to the battery voltage + return Volts.of(limitedVoltage); + } + + @Override + public Voltage updateControlSignal( + Angle mechanismAngle, + AngularVelocity mechanismVelocity, + Angle encoderAngle, + AngularVelocity encoderVelocity) { + appliedVoltage = constrainOutputVoltage(encoderAngle, encoderVelocity, requestedVoltage); + return appliedVoltage; + } + + public Voltage getAppliedVoltage() { + return appliedVoltage; + } + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/Arena2024Crescendo.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/Arena2024Crescendo.java new file mode 100644 index 0000000..e8ce671 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/Arena2024Crescendo.java @@ -0,0 +1,210 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.crescendo2024; + +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.networktables.BooleanPublisher; +import edu.wpi.first.units.Units; +import edu.wpi.first.wpilibj.DriverStation; +import swervelib.simulation.ironmaple.simulation.SimulatedArena; + +public class Arena2024Crescendo extends SimulatedArena { + + protected double blueAmpClock = 0; + protected int blueAmpCount = 0; + + protected double redAmpClock = 0; + protected int redAmpCount = 0; + + BooleanPublisher redAmpPublisher = redTable.getBooleanTopic("redIsAmped").publish(); + BooleanPublisher blueAmpPublisher = blueTable.getBooleanTopic("blueIsAmped").publish(); + + protected final CrescendoSpeaker redSpeaker; + protected final CrescendoSpeaker blueSpeaker; + + protected final CrescendoAmp redAmp; + protected final CrescendoAmp blueAmp; + + /** the obstacles on the 2024 competition field */ + public static final class CrescendoFieldObstaclesMap extends FieldMap { + private static final double FIELD_WIDTH = 16.54; + + public CrescendoFieldObstaclesMap() { + super(); + + // left wall + super.addBorderLine(new Translation2d(0, 1), new Translation2d(0, 4.51)); + super.addBorderLine(new Translation2d(0, 4.51), new Translation2d(0.9, 5)); + + super.addBorderLine(new Translation2d(0.9, 5), new Translation2d(0.9, 6.05)); + + super.addBorderLine(new Translation2d(0.9, 6.05), new Translation2d(0, 6.5)); + super.addBorderLine(new Translation2d(0, 6.5), new Translation2d(0, 8.2)); + + // upper wall + super.addBorderLine(new Translation2d(0, 8.12), new Translation2d(FIELD_WIDTH, 8.12)); + + // righter wall + super.addBorderLine(new Translation2d(FIELD_WIDTH, 1), new Translation2d(FIELD_WIDTH, 4.51)); + super.addBorderLine(new Translation2d(FIELD_WIDTH, 4.51), new Translation2d(FIELD_WIDTH - 0.9, 5)); + super.addBorderLine(new Translation2d(FIELD_WIDTH - 0.9, 5), new Translation2d(FIELD_WIDTH - 0.9, 6.05)); + super.addBorderLine(new Translation2d(FIELD_WIDTH - 0.9, 6.05), new Translation2d(FIELD_WIDTH, 6.5)); + super.addBorderLine(new Translation2d(FIELD_WIDTH, 6.5), new Translation2d(FIELD_WIDTH, 8.2)); + + // lower wall + super.addBorderLine(new Translation2d(1.92, 0), new Translation2d(FIELD_WIDTH - 1.92, 0)); + + // red source wall + super.addBorderLine(new Translation2d(1.92, 0), new Translation2d(0, 1)); + + // blue source wall + super.addBorderLine(new Translation2d(FIELD_WIDTH - 1.92, 0), new Translation2d(FIELD_WIDTH, 1)); + + // blue state + super.addRectangularObstacle(0.35, 0.35, new Pose2d(3.4, 4.1, new Rotation2d())); + super.addRectangularObstacle(0.35, 0.35, new Pose2d(5.62, 4.1 - 1.28, Rotation2d.fromDegrees(30))); + super.addRectangularObstacle(0.35, 0.35, new Pose2d(5.62, 4.1 + 1.28, Rotation2d.fromDegrees(60))); + + // red stage + super.addRectangularObstacle(0.35, 0.35, new Pose2d(FIELD_WIDTH - 3.4, 4.1, new Rotation2d())); + super.addRectangularObstacle( + 0.35, 0.35, new Pose2d(FIELD_WIDTH - 5.62, 4.1 - 1.28, Rotation2d.fromDegrees(60))); + super.addRectangularObstacle( + 0.35, 0.35, new Pose2d(FIELD_WIDTH - 5.62, 4.1 + 1.28, Rotation2d.fromDegrees(30))); + } + } + + private static final Translation2d[] NOTE_INITIAL_POSITIONS = new Translation2d[] { + new Translation2d(2.9, 4.1), + new Translation2d(2.9, 5.55), + new Translation2d(2.9, 7), + new Translation2d(8.27, 0.75), + new Translation2d(8.27, 2.43), + new Translation2d(8.27, 4.1), + new Translation2d(8.27, 5.78), + new Translation2d(8.27, 7.46), + new Translation2d(13.64, 4.1), + new Translation2d(13.64, 5.55), + new Translation2d(13.64, 7), + }; + + public Arena2024Crescendo() { + super(new CrescendoFieldObstaclesMap()); + + redSpeaker = new CrescendoSpeaker(this, false); + super.addCustomSimulation(redSpeaker); + + blueSpeaker = new CrescendoSpeaker(this, true); + super.addCustomSimulation(blueSpeaker); + + blueAmp = new CrescendoAmp(this, true); + super.addCustomSimulation(blueAmp); + + redAmp = new CrescendoAmp(this, false); + super.addCustomSimulation(redAmp); + } + + @Override + public void placeGamePiecesOnField() { + for (Translation2d notePosition : NOTE_INITIAL_POSITIONS) + super.addGamePiece(new CrescendoNoteOnField(notePosition)); + + super.addCustomSimulation(new CrescendoHumanPlayerSimulation(this)); + setupValueForMatchBreakdown("TotalNotesInAmp"); + setupValueForMatchBreakdown("TotalNotesInSpeaker"); + setupValueForMatchBreakdown("TotalAmplifiedScore"); + setupValueForMatchBreakdown("TotalTimeAmped"); + setupValueForMatchBreakdown("AmpClock"); + setupValueForMatchBreakdown("AmpCharge"); + } + + @Override + public void simulationSubTick(int tickNum) { + addValueToMatchBreakdown( + false, "totalTimeAmped", redAmpClock > 0 ? getSimulationDt().in(Units.Seconds) : 0); + addValueToMatchBreakdown( + true, "totalTimeAmped", blueAmpClock > 0 ? getSimulationDt().in(Units.Seconds) : 0); + + redAmpClock -= getSimulationDt().in(Units.Seconds); + blueAmpClock -= getSimulationDt().in(Units.Seconds); + + super.simulationSubTick(tickNum); + + replaceValueInMatchBreakDown(true, "AmpCharge", blueAmpCount); + replaceValueInMatchBreakDown(false, "AmpCharge", redAmpCount); + replaceValueInMatchBreakDown(true, "AmpClock", blueAmpClock > 0 ? blueAmpClock : 0); + replaceValueInMatchBreakDown(false, "AmpClock", redAmpClock > 0 ? redAmpClock : 0); + // SmartDashboard.putNumber("blue Amp Charge", blueAmpCount); + // SmartDashboard.putNumber("red Amp Charge", redAmpCount); + // SmartDashboard.putNumber("blue Amp Clock", blueAmpClock); + // SmartDashboard.putNumber("red Amp Clock", redAmpClock); + } + + /** + * + * + *

Returns wether the specified team currently has an amped speaker

+ * + * This function returns true during autonomous since the autonomous mode behaves exactly like amplified game play. + * + * @param isBlue Wether to check the blue or red alliance. + * @return Wether the specified alliance is currently amplified. + */ + public boolean isAmped(boolean isBlue) { + if (isBlue) { + return blueAmpClock > 0 || DriverStation.isAutonomous(); + } else { + return redAmpClock > 0 || DriverStation.isAutonomous(); + } + } + + /** + * + * + *

Adds a charge to the amp of the specified team. One charge is equal to one note in the amp so two charges are + * needed to use the amp.

+ * + * @param isBlue Wether the charge is added to the blue or red alliance. + */ + public void addAmpCharge(boolean isBlue) { + if (isBlue) { + blueAmpCount = Math.min(blueAmpCount + 1, 2); + } else { + redAmpCount = Math.min(redAmpCount + 1, 2); + } + } + + /** + * + * + *

Activates the amp for the specified team.

+ * + * @param isBlue Wether to amplify for the blue or red team. + * @return Returns true if the amplification was successful and false if it was not. + */ + public boolean activateAmp(boolean isBlue) { + + if (DriverStation.isAutonomous()) { + System.out.println("Amplification is not allowed during auto."); + return false; + } + + if (isBlue && blueAmpCount == 2) { + blueAmpCount = 0; + blueAmpClock = 5; + System.out.println("blue amped it up"); + return true; + } + if (!isBlue && redAmpCount == 2) { + redAmpCount = 0; + redAmpClock = 5; + System.out.println("red amped it up"); + return true; + } + System.out.println( + isBlue + ? "Blue " + : "Red " + "Only has " + (isBlue ? blueAmpCount : redAmpCount) + "of needed 2 to use amp"); + return false; + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoAmp.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoAmp.java new file mode 100644 index 0000000..03e5b30 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoAmp.java @@ -0,0 +1,68 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.crescendo2024; + +import static edu.wpi.first.units.Units.Centimeters; + +import edu.wpi.first.math.geometry.*; +import edu.wpi.first.networktables.NetworkTableInstance; +import edu.wpi.first.networktables.StructPublisher; +import java.util.*; +import swervelib.simulation.ironmaple.simulation.Goal; + +/** + * + * + *

Simulates a AMPS on the field.

+ * + *

This class simulates the AMP on the field where NOTESs can be scored. + */ +public class CrescendoAmp extends Goal { + + protected static final Translation3d blueAmpPose = new Translation3d(1.81, 8.3, 0.66); + protected static final Translation3d redAmpPose = new Translation3d(14.7, 8.3, 0.66); + + protected final Arena2024Crescendo crescendoArena; + + StructPublisher posePublisher; + + /** + * + * + *

Creates an Amp of the specified color.

+ * + * @param arena The host arena of this amp. + * @param isBlue Wether this is the blue amp or the red one. + */ + public CrescendoAmp(Arena2024Crescendo arena, boolean isBlue) { + super( + arena, + Centimeters.of(61), + Centimeters.of(30), + Centimeters.of(46), + "Note", + isBlue ? blueAmpPose : redAmpPose, + isBlue); + + crescendoArena = arena; + + setNeededAngle(new Rotation3d(0, Math.PI / 2, Math.PI / 2)); + + StructPublisher ampPublisher = NetworkTableInstance.getDefault() + .getStructTopic(isBlue ? "BlueAmp" : "RedAmp", Pose3d.struct) + .publish(); + ampPublisher.set(new Pose3d(position, this.pieceAngle)); + } + + @Override + protected void addPoints() { + crescendoArena.addValueToMatchBreakdown(isBlue, "TotalNotesInAmp", 1.0); + arena.addValueToMatchBreakdown(isBlue, "AmplifiedScore", crescendoArena.isAmped(isBlue) ? 2 : 0); + + crescendoArena.addAmpCharge(isBlue); + arena.addToScore(isBlue, crescendoArena.isAmped(isBlue) ? 2 : 1); + } + + @Override + public void draw(List drawList) { + return; + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoHumanPlayerSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoHumanPlayerSimulation.java new file mode 100644 index 0000000..be80ee6 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoHumanPlayerSimulation.java @@ -0,0 +1,36 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.crescendo2024; + +import static swervelib.simulation.ironmaple.utils.LegacyFieldMirroringUtils2024.toCurrentAllianceTranslation; + +import edu.wpi.first.math.geometry.Translation2d; +import edu.wpi.first.wpilibj.DriverStation; +import edu.wpi.first.wpilibj.Timer; +import swervelib.simulation.ironmaple.simulation.SimulatedArena; +import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation; + +public class CrescendoHumanPlayerSimulation implements SimulatedArena.Simulatable { + private static final Translation2d BLUE_SOURCE_POSITION = new Translation2d(15.6, 0.8); + private double previousThrowTimeSeconds = 0; + private final Arena2024Crescendo arena; + + public CrescendoHumanPlayerSimulation(Arena2024Crescendo arena) { + this.arena = arena; + } + + @Override + public void simulationSubTick(int subTickNum) { + if (!DriverStation.isTeleopEnabled()) return; + + if (Timer.getFPGATimestamp() - previousThrowTimeSeconds < 1) return; + + final Translation2d sourcePosition = toCurrentAllianceTranslation(BLUE_SOURCE_POSITION); + /* if there is any game-piece 0.5 meters within the human player station, we don't throw a new note */ + for (GamePieceOnFieldSimulation gamePiece : arena.gamePiecesOnField()) + if (gamePiece instanceof CrescendoNoteOnField + && gamePiece.getPoseOnField().getTranslation().getDistance(sourcePosition) < 1) return; + + /* otherwise, place a note */ + arena.addGamePiece(new CrescendoNoteOnField(sourcePosition)); + previousThrowTimeSeconds = Timer.getFPGATimestamp(); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoNoteOnField.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoNoteOnField.java new file mode 100644 index 0000000..7658c52 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoNoteOnField.java @@ -0,0 +1,21 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.crescendo2024; + +import static edu.wpi.first.units.Units.Inches; +import static edu.wpi.first.units.Units.Kilograms; + +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 org.dyn4j.geometry.Geometry; +import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation; + +public class CrescendoNoteOnField extends GamePieceOnFieldSimulation { + /* https://www.andymark.com/products/frc-2024-am-4999 */ + public static final GamePieceInfo CRESCENDO_NOTE_INFO = new GamePieceInfo( + "Note", Geometry.createCircle(Units.inchesToMeters(14) / 2), Inches.of(2), Kilograms.of(0.2), 3.5, 5, 0.3); + + public CrescendoNoteOnField(Translation2d initialPosition) { + super(CRESCENDO_NOTE_INFO, new Pose2d(initialPosition, new Rotation2d())); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoSpeaker.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoSpeaker.java new file mode 100644 index 0000000..acde813 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoSpeaker.java @@ -0,0 +1,68 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.crescendo2024; + +import static edu.wpi.first.units.Units.Centimeters; + +import edu.wpi.first.math.geometry.*; +import edu.wpi.first.networktables.NetworkTableInstance; +import edu.wpi.first.networktables.StructPublisher; +import java.util.*; +import swervelib.simulation.ironmaple.simulation.Goal; +import swervelib.simulation.ironmaple.simulation.gamepieces.GamePiece; + +/** + * + * + *

Simulates a SPEAKERs on the field.

+ * + *

This class simulates the SPEAKERs on the field where NOTESs can be scored. It + * may be amplified by using the {@link Arena2024Crescendo#activateAmp(boolean)} function on the host arena. + */ +public class CrescendoSpeaker extends Goal { + + protected static final Translation3d redSpeakerPose = new Translation3d(16.52, 5.5825, 2.1); + protected static final Translation3d blueSpeakerPose = new Translation3d(0, 5.5825, 2.1); + StructPublisher posePublisher; + protected final Arena2024Crescendo crescendoArena; + + /** + * + * + *

Creates an Speaker of the specified color.

+ * + * @param arena The host arena of this speaker. + * @param isBlue Wether this is the blue speaker or the red one. + */ + public CrescendoSpeaker(Arena2024Crescendo arena, boolean isBlue) { + super( + arena, + Centimeters.of(90), + Centimeters.of(116.5), + Centimeters.of(100), + "Note", + isBlue ? blueSpeakerPose : redSpeakerPose, + isBlue); + + crescendoArena = arena; + StructPublisher speakerPosePublisher = NetworkTableInstance.getDefault() + .getStructTopic(isBlue ? "BlueSpeaker" : "RedSpeaker", Pose3d.struct) + .publish(); + speakerPosePublisher.set(new Pose3d(position, new Rotation3d())); + } + + @Override + protected boolean checkVel(GamePiece gamePiece) { + return gamePiece.getVelocity3dMPS().getZ() > 0; + } + + @Override + protected void addPoints() { + arena.addValueToMatchBreakdown(isBlue, "TotalNotesInSpeaker", 1); + arena.addValueToMatchBreakdown(isBlue, "AmplifiedScore", crescendoArena.isAmped(isBlue) ? 5 : 0); + arena.addToScore(isBlue, crescendoArena.isAmped(isBlue) ? 5 : 2); + } + + @Override + public void draw(List drawList) { + return; + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/NoteOnFly.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/NoteOnFly.java new file mode 100644 index 0000000..b393f0e --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/NoteOnFly.java @@ -0,0 +1,57 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.crescendo2024; + +import static swervelib.simulation.ironmaple.simulation.seasonspecific.crescendo2024.CrescendoNoteOnField.*; + +import edu.wpi.first.math.geometry.Rotation2d; +import edu.wpi.first.math.geometry.Translation2d; +import edu.wpi.first.math.geometry.Translation3d; +import edu.wpi.first.math.kinematics.ChassisSpeeds; +import edu.wpi.first.units.measure.Angle; +import edu.wpi.first.units.measure.Distance; +import edu.wpi.first.units.measure.LinearVelocity; +import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceProjectile; +import swervelib.simulation.ironmaple.utils.LegacyFieldMirroringUtils2024; + +public class NoteOnFly extends GamePieceProjectile { + public NoteOnFly( + Translation2d robotPosition, + Translation2d shooterPositionOnRobot, + ChassisSpeeds chassisSpeeds, + Rotation2d shooterFacing, + Distance initialHeight, + LinearVelocity launchingSpeed, + Angle shooterAngle) { + super( + CRESCENDO_NOTE_INFO, + robotPosition, + shooterPositionOnRobot, + chassisSpeeds, + shooterFacing, + initialHeight, + launchingSpeed, + shooterAngle); + super.withTouchGroundHeight(0.6); + } + + public NoteOnFly asSpeakerShotNote(Runnable hitTargetCallBack) { + return (NoteOnFly) super.withTargetPosition(() -> + LegacyFieldMirroringUtils2024.toCurrentAllianceTranslation(new Translation3d(0.25, 5.56, 2.3))) + .withTargetTolerance(new Translation3d(0.5, 1.2, 0.3)) + .withHitTargetCallBack(hitTargetCallBack); + } + + public NoteOnFly asAmpShotNote(Runnable hitTargetCallBack) { + return (NoteOnFly) super.withTargetPosition(() -> + LegacyFieldMirroringUtils2024.toCurrentAllianceTranslation(new Translation3d(1.83, 8.12, 0.95))) + .withTargetTolerance(new Translation3d(0.1, 0.6, 0.45)) + .withHitTargetCallBack(hitTargetCallBack); + } + + public NoteOnFly enableBecomeNoteOnFieldAfterTouchGround() { + return (NoteOnFly) super.enableBecomesGamePieceOnFieldAfterTouchGround(); + } + + public NoteOnFly disableBecomeNoteOnFieldAfterTouchGround() { + return (NoteOnFly) super.disableBecomesGamePieceOnFieldAfterTouchGround(); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/evergreen/ArenaEvergreen.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/evergreen/ArenaEvergreen.java new file mode 100644 index 0000000..b3391df --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/evergreen/ArenaEvergreen.java @@ -0,0 +1,70 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.evergreen; + +import edu.wpi.first.math.geometry.Translation2d; +import edu.wpi.first.wpilibj.DriverStation; +import swervelib.simulation.ironmaple.simulation.SimulatedArena; + +/** + *

A field with no obstacles

+ * + *

This class represents the playing field for the simulated Evergreen Field + * + *

It extends {@link SimulatedArena}. + */ +public class ArenaEvergreen extends SimulatedArena { + public static final class EvergreenFieldObstacleMap extends FieldMap { + public EvergreenFieldObstacleMap() { + super(); + } + + /** + * Used for adding walls when desired. + * + * @return this, for chaining. + */ + public EvergreenFieldObstacleMap withWalls() { + // blue wall + super.addBorderLine(new Translation2d(0, 1.270), new Translation2d(0, 6.782)); + + // red wall + super.addBorderLine(new Translation2d(17.548, 1.270), new Translation2d(17.548, 6.782)); + + // upper walls + super.addBorderLine(new Translation2d(1.672, 8.052), new Translation2d(11, 8.052)); + super.addBorderLine(new Translation2d(12, 8.052), new Translation2d(17.548 - 1.672, 8.052)); + + // lower walls + super.addBorderLine(new Translation2d(1.672, 0), new Translation2d(5.8, 0)); + super.addBorderLine(new Translation2d(6.3, 0), new Translation2d(17.548 - 1.672, 0)); + return this; + } + } + + /** + *

A field with no obstacles

+ * + *

This class represents the playing field for the simulated Evergreen Field + * + *

It extends {@link SimulatedArena}. + * + * @param withWalls used to add wall obstacles when desired. + */ + public ArenaEvergreen(boolean withWalls) { + super(withWalls ? new EvergreenFieldObstacleMap() : new EvergreenFieldObstacleMap().withWalls()); + } + + /** + *

Evergreen does not have game pieces, this method does nothing.

+ * + *

Places Game Pieces on the Field for Autonomous Mode. + * + *

This method sets up the game pieces on the field, typically in their starting positions for autonomous mode. + * + *

It should be implemented differently for each season-specific subclass of {@link SimulatedArena} to reflect + * the unique game piece placements for that season's game. + */ + @Override + public void placeGamePiecesOnField() { + DriverStation.reportError("Evergreen doesn't have game pieces.", false); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/Arena2025Reefscape.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/Arena2025Reefscape.java new file mode 100644 index 0000000..203244d --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/Arena2025Reefscape.java @@ -0,0 +1,173 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025; + +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.geometry.Translation2d; +import edu.wpi.first.wpilibj.DriverStation; +import java.util.Arrays; +import java.util.List; +import swervelib.simulation.ironmaple.simulation.SimulatedArena; +import swervelib.simulation.ironmaple.utils.FieldMirroringUtils; + +/** + * + * + *

The playing field for the 2025 FRC Game: Reefscape

+ * + *

This class represents the playing field for the 2025 FRC game, Reefscape. + * + *

It extends {@link SimulatedArena} and includes specific details of the Reefscape game environment. + */ +public class Arena2025Reefscape extends SimulatedArena { + public static final class ReefscapeFieldObstacleMap extends FieldMap { + public ReefscapeFieldObstacleMap() { + super(); + + // blue wall + super.addBorderLine(new Translation2d(0, 1.270), new Translation2d(0, 6.782)); + + // blue coral stations + super.addBorderLine(new Translation2d(0, 1.270), new Translation2d(1.672, 0)); + super.addBorderLine(new Translation2d(0, 6.782), new Translation2d(1.672, 8.052)); + + // red wall + super.addBorderLine(new Translation2d(17.548, 1.270), new Translation2d(17.548, 6.782)); + + // red coral stations + super.addBorderLine(new Translation2d(17.548, 1.270), new Translation2d(17.548 - 1.672, 0)); + super.addBorderLine(new Translation2d(17.548, 6.782), new Translation2d(17.548 - 1.672, 8.052)); + + // upper walls + super.addBorderLine(new Translation2d(1.672, 8.052), new Translation2d(11, 8.052)); + super.addBorderLine(new Translation2d(12, 8.052), new Translation2d(17.548 - 1.672, 8.052)); + + // lower walls + super.addBorderLine(new Translation2d(1.672, 0), new Translation2d(5.8, 0)); + super.addBorderLine(new Translation2d(6.3, 0), new Translation2d(17.548 - 1.672, 0)); + + // blue reef + Translation2d[] reefVorticesBlue = new Translation2d[] { + new Translation2d(3.658, 3.546), + new Translation2d(3.658, 4.506), + new Translation2d(4.489, 4.987), + new Translation2d(5.3213, 4.506), + new Translation2d(5.3213, 3.546), + new Translation2d(4.489, 3.065) + }; + for (int i = 0; i < 6; i++) super.addBorderLine(reefVorticesBlue[i], reefVorticesBlue[(i + 1) % 6]); + + // red reef + Translation2d[] reefVorticesRed = Arrays.stream(reefVorticesBlue) + .map(pointAtBlue -> + new Translation2d(FieldMirroringUtils.FIELD_WIDTH - pointAtBlue.getX(), pointAtBlue.getY())) + .toArray(Translation2d[]::new); + for (int i = 0; i < 6; i++) super.addBorderLine(reefVorticesRed[i], reefVorticesRed[(i + 1) % 6]); + + // the pillar in the middle of the field + super.addRectangularObstacle(0.305, 0.305, new Pose2d(8.774, 4.026, new Rotation2d())); + } + } + + public final ReefscapeReefSimulation redReefSimulation; + public final ReefscapeReefSimulation blueReefSimulation; + public final ReefscapeBargeSimulation redBarge; + public final ReefscapeBargeSimulation blueBarge; + public final ReefscapeProcessorSimulation redProcessor; + public final ReefscapeProcessorSimulation blueProcessor; + + public Arena2025Reefscape() { + super(new ReefscapeFieldObstacleMap()); + + redReefSimulation = new ReefscapeReefSimulation(this, false); + super.addCustomSimulation(redReefSimulation); + + blueReefSimulation = new ReefscapeReefSimulation(this, true); + super.addCustomSimulation(blueReefSimulation); + + blueBarge = new ReefscapeBargeSimulation(this, true); + super.addCustomSimulation(blueBarge); + + redBarge = new ReefscapeBargeSimulation(this, false); + super.addCustomSimulation(redBarge); + + blueProcessor = new ReefscapeProcessorSimulation(this, true); + super.addCustomSimulation(blueProcessor); + + redProcessor = new ReefscapeProcessorSimulation(this, false); + super.addCustomSimulation(redProcessor); + } + + @Override + public void placeGamePiecesOnField() { + Translation2d[] bluePositions = new Translation2d[] { + new Translation2d(1.219, 5.855), new Translation2d(1.219, 4.026), new Translation2d(1.219, 2.197), + }; + for (Translation2d position : bluePositions) super.addGamePiece(new ReefscapeCoralAlgaeStack(position)); + + Translation2d[] redPositions = Arrays.stream(bluePositions) + .map(bluePosition -> + new Translation2d(FieldMirroringUtils.FIELD_WIDTH - bluePosition.getX(), bluePosition.getY())) + .toArray(Translation2d[]::new); + for (Translation2d position : redPositions) super.addGamePiece(new ReefscapeCoralAlgaeStack(position)); + + setupValueForMatchBreakdown("AlgaeInProcessor"); + setupValueForMatchBreakdown("AlgaeInNet"); + setupValueForMatchBreakdown("Auto/CoralScoredInAuto"); + setupValueForMatchBreakdown("CoralScoredOnLevel 1"); + setupValueForMatchBreakdown("CoralScoredOnLevel 2"); + setupValueForMatchBreakdown("CoralScoredOnLevel 3"); + setupValueForMatchBreakdown("CoralScoredOnLevel 4"); + setupValueForMatchBreakdown("Auto/AlgaeScoredInAuto"); + } + + @Override + public synchronized List getGamePiecesPosesByType(String type) { + List poses = super.getGamePiecesPosesByType(type); + + // add algae and coral stack + if (type.equals("Algae")) { + poses.addAll(ReefscapeCoralAlgaeStack.getStackedAlgaePoses()); + redBarge.draw(poses); + blueBarge.draw(poses); + + } else if (type.equals("Coral")) { + poses.addAll(ReefscapeCoralAlgaeStack.getStackedCoralPoses()); + redReefSimulation.draw(poses); + blueReefSimulation.draw(poses); + } + + return poses; + } + + @Override + public synchronized void clearGamePieces() { + super.clearGamePieces(); + redReefSimulation.clearReef(); + blueReefSimulation.clearReef(); + } + + /** + * Obtains the amount of CORAL held on the BRANCHES. + * + *

This method returns a 2D array of size 12 x 4, where each entry represents the number of + * CORALs held on a particular branch. + * + *

The BRANCHES are tracked in FMS as A, B, C, D, E, F, G, H, I, J, K, L (as per the game + * manual), and are mapped to indices 0, 1, 2, ... in the array. + * + *

The [i][j] entry in the array represents the number of CORAL(s) held on the Lj-1 + * branch in the ith section. + * + *

For example, getBranches()[2][3] returns the number of CORALs held on L4 of Branch C. + * + *

Note that L2, L3, and L4 can only hold one CORAL, while L1 can hold up to two + * CORALs. + * + * @param side the alliance side (Red or Blue) to check for CORAL counts + * @return a 2D array where each entry represents the number of CORAL held on each branch + */ + public int[][] getBranches(DriverStation.Alliance side) { + return side == DriverStation.Alliance.Red ? redReefSimulation.getBranches() : blueReefSimulation.getBranches(); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeAlgaeOnField.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeAlgaeOnField.java new file mode 100644 index 0000000..dd9b4a1 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeAlgaeOnField.java @@ -0,0 +1,26 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025; + +import static edu.wpi.first.units.Units.*; + +import edu.wpi.first.math.geometry.Pose2d; +import edu.wpi.first.math.geometry.Rotation2d; +import edu.wpi.first.math.geometry.Translation2d; +import org.dyn4j.geometry.Circle; +import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation; + +/** + * + * + *

Represents an ALGAE in the 2025 Reefscape game.

+ * + *

The Algae (am-5602) is a 16-inch (41 cm) + * rubber playground ball with a ±½ inch (~12 mm) diameter, featured as a game piece in the 2025 Reefscape game. + */ +public class ReefscapeAlgaeOnField extends GamePieceOnFieldSimulation { + public static final GamePieceInfo REEFSCAPE_ALGAE_INFO = + new GamePieceInfo("Algae", new Circle(0.176), Inches.of(16), Kilograms.of(0.4), 1.8, 5, 0.8); + + public ReefscapeAlgaeOnField(Translation2d initialPosition) { + super(REEFSCAPE_ALGAE_INFO, new Pose2d(initialPosition, new Rotation2d())); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeAlgaeOnFly.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeAlgaeOnFly.java new file mode 100644 index 0000000..89d7875 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeAlgaeOnFly.java @@ -0,0 +1,58 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025; + +import edu.wpi.first.math.geometry.Rotation2d; +import edu.wpi.first.math.geometry.Translation2d; +import edu.wpi.first.math.kinematics.ChassisSpeeds; +import edu.wpi.first.units.measure.Angle; +import edu.wpi.first.units.measure.Distance; +import edu.wpi.first.units.measure.LinearVelocity; +import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceProjectile; + +/** + * + * + *

Represents an ALGAE launched into the air.

+ * + *

This class models a {@link ReefscapeAlgaeOnField} launched into the air. + * + *

The simulation will determine if the ALGAE hits its target—the NET. + * + *

The user can specify a callback using {@link #setHitNetCallBack(Runnable)}, which will be triggered when the ALGAE + * hits the NET. + */ +public class ReefscapeAlgaeOnFly extends GamePieceProjectile { + private static Runnable hitNetCallBack = () -> System.out.println("hit target!"); + + /** + * + * + *

Specifies a callback for when any ALGAE launched into the air hits the NET.

+ * + * @param callBack a {@link Runnable} to be invoked when an ALGAE hits the NET + */ + public static void setHitNetCallBack(Runnable callBack) { + hitNetCallBack = callBack; + } + + public ReefscapeAlgaeOnFly( + Translation2d robotPosition, + Translation2d shooterPositionOnRobot, + ChassisSpeeds chassisSpeeds, + Rotation2d shooterFacing, + Distance initialHeight, + LinearVelocity launchingSpeed, + Angle shooterAngle) { + super( + ReefscapeAlgaeOnField.REEFSCAPE_ALGAE_INFO, + robotPosition, + shooterPositionOnRobot, + chassisSpeeds, + shooterFacing, + initialHeight, + launchingSpeed, + shooterAngle); + + super.withTouchGroundHeight(0.8); + super.enableBecomesGamePieceOnFieldAfterTouchGround(); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeBargeSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeBargeSimulation.java new file mode 100644 index 0000000..b824f36 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeBargeSimulation.java @@ -0,0 +1,75 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025; + +import static edu.wpi.first.units.Units.Centimeters; + +import edu.wpi.first.math.geometry.*; +import edu.wpi.first.networktables.NetworkTableInstance; +import edu.wpi.first.networktables.StructPublisher; +import edu.wpi.first.units.Units; +import edu.wpi.first.wpilibj.DriverStation; +import java.util.*; +import swervelib.simulation.ironmaple.simulation.Goal; +import swervelib.simulation.ironmaple.simulation.gamepieces.GamePiece; + +/** + * + * + *

Simulates a BARGEs on the field.

+ * + *

This class simulates a BARGEs on the field where ALGAE can be scored. + */ +public class ReefscapeBargeSimulation extends Goal { + + protected static final Translation3d redBargePose = new Translation3d(8.805, 2.1, 1.57); + protected static final Translation3d blueBargePose = new Translation3d(8.805, 6.18, 1.57); + StructPublisher posePublisher; + + /** + * + * + *

Creates an barge of the specified color.

+ * + * @param arena The host arena of this barge. + * @param isBlue Wether this is the blue barge or the red one. + */ + public ReefscapeBargeSimulation(Arena2025Reefscape arena, boolean isBlue) { + super( + arena, + Centimeters.of(112), + Centimeters.of(343), + Centimeters.of(100), + "Algae", + isBlue ? blueBargePose : redBargePose, + isBlue); + + StructPublisher heldAlgaePublisher = NetworkTableInstance.getDefault() + .getStructTopic(isBlue ? "BlueBarge" : "RedBarge", Pose3d.struct) + .publish(); + heldAlgaePublisher.set(new Pose3d(position, new Rotation3d())); + } + + @Override + public void draw(List algaePosesToDisplay) { + for (int i = 0; i < gamePieceCount; i++) { + algaePosesToDisplay.add(new Pose3d( + xyBox.getCenter().x, + xyBox.getCenter().y - xyBox.getHeight() / 2, + elevation.in(Units.Meters) + height.in(Units.Meters) / 2, + new Rotation3d()) + .plus(new Transform3d(0, i * 0.35, 0, new Rotation3d()))); + } + } + + @Override + protected boolean checkVel(GamePiece gamePiece) { + return gamePiece.getVelocity3dMPS().getZ() < 0; + } + + @Override + protected void addPoints() { + arena.addValueToMatchBreakdown(isBlue, "AlgaeInNet", 1); + arena.addValueToMatchBreakdown(isBlue, "Auto/AlgaeScoredInAuto", DriverStation.isAutonomous() ? 1 : 0); + + arena.addToScore(isBlue, 4); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralAlgaeStack.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralAlgaeStack.java new file mode 100644 index 0000000..8a8b3a7 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralAlgaeStack.java @@ -0,0 +1,146 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025; + +import static edu.wpi.first.units.Units.*; + +import edu.wpi.first.math.geometry.*; +import edu.wpi.first.math.kinematics.ChassisSpeeds; +import java.util.List; +import org.dyn4j.geometry.Circle; +import swervelib.simulation.ironmaple.simulation.SimulatedArena; +import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation; +import swervelib.simulation.ironmaple.utils.mathutils.GeometryConvertor; + +/** + * + * + *

A CORAL-ALGAE stack on the field.

+ * + *

This class represents a CORAL-ALGAE stack, which consists of a standing CORAL with an ALGAE placed on top of it. + * + *

Three such stacks are staged on each side of the field before the match begins. + * + *

The stacks will collapse if hit, separating into a {@link ReefscapeCoralOnField} and a + * {@link ReefscapeAlgaeOnField}. + * + *

Intakes can also grab a Coral and/or an Algae from the stack. + * + *

To visualize these stacks, use {@link #getStackedAlgaePoses()} and {@link #getStackedCoralPoses()} to retrieve the + * positions of the coral and algae in the stacks, and display them through AScope. + */ +public class ReefscapeCoralAlgaeStack extends GamePieceOnFieldSimulation { + public static final GamePieceInfo REEFSCAPE_STACK_INFO = + new GamePieceInfo("CoralAlgaeStack", new Circle(0.15), Meters.zero(), Kilograms.of(0.7), 1.8, 4, 0.3); + + private final SimulatedArena arena; + private final Translation2d initialPosition; + private boolean collapsed = false; + + public ReefscapeCoralAlgaeStack(Translation2d initialPosition) { + this(initialPosition, SimulatedArena.getInstance()); + } + + public ReefscapeCoralAlgaeStack(Translation2d initialPosition, SimulatedArena arena) { + super(REEFSCAPE_STACK_INFO, new Pose2d(initialPosition, new Rotation2d())); + this.arena = arena; + this.initialPosition = initialPosition; + arena.addCustomSimulation(this::simulationSubTick); + } + + private void simulationSubTick(int subTickCount) { + // if already collapsed, skip + if (collapsed) return; + // make the stack collapse if its moved + if (getPoseOnField().getTranslation().minus(initialPosition).getNorm() > 0.2 + && getLinearVelocity().getMagnitude() > 0.3) collapse(); + } + + private Translation2d velocityMPS() { + return GeometryConvertor.toWpilibTranslation2d(getLinearVelocity()); + } + + private Rotation2d velocityDirection() { + return velocityMPS().getAngle(); + } + + private Translation2d stackPosition() { + return getPoseOnField().getTranslation(); + } + + private void collapse() { + // remove the stack + arena.removeGamePiece(this); + + throwCoralToGround(); + throwAlgaeToGround(); + + // mark as collapsed + collapsed = true; + } + + private void throwCoralToGround() { + ReefscapeCoralOnField coral = new ReefscapeCoralOnField(new Pose2d( + stackPosition().plus(new Translation2d(0.15, 0).rotateBy(velocityDirection())), velocityDirection())); + System.out.println("coral position: " + coral.getPoseOnField()); + coral.setLinearVelocity(getLinearVelocity()); + arena.addGamePiece(coral); + } + + private void throwAlgaeToGround() { + arena.addGamePieceProjectile(new ReefscapeAlgaeOnFly( + stackPosition(), + new Translation2d(), + new ChassisSpeeds(), + velocityDirection(), + Meters.of(0.3).plus(Inches.of(8)), + MetersPerSecond.of(velocityMPS().getNorm() * 0.6), + Degrees.zero())); + } + + /** + * + * + *

Retrieves the positions of the Coral pieces in all stacks.

+ * + * @return list of {@link Pose3d} representing the positions of the Coral pieces in all stacks in the arena + */ + public static List getStackedCoralPoses() { + return getStackedCoralPoses(SimulatedArena.getInstance()); + } + + /** @see #getStackedCoralPoses() */ + private static final Transform3d STACK_TO_CORAL = + new Transform3d(new Translation3d(0, 0, 0.15), new Rotation3d(0, Math.toRadians(90), 0)); + + public static List getStackedCoralPoses(SimulatedArena arena) { + return arena.getGamePiecesPosesByType(REEFSCAPE_STACK_INFO.type()).stream() + .map(stackPose -> stackPose.plus(STACK_TO_CORAL)) + .toList(); + } + + /** + * + * + *

Retrieves the positions of the Algae pieces in all stacks.

+ * + * @return a list of {@link Pose3d} representing the positions of the Algae pieces in all stacks in the arena + */ + public static List getStackedAlgaePoses() { + return getStackedAlgaePoses(SimulatedArena.getInstance()); + } + + private static final Transform3d STACK_TO_ALGAE = new Transform3d( + new Translation3d(0, 0, 0.3 + edu.wpi.first.math.util.Units.inchesToMeters(8)), new Rotation3d()); + + /** @see #getStackedAlgaePoses() */ + public static List getStackedAlgaePoses(SimulatedArena arena) { + return arena.getGamePiecesPosesByType(REEFSCAPE_STACK_INFO.type()).stream() + .map(stackPose -> stackPose.plus(STACK_TO_ALGAE)) + .toList(); + } + + @Override + public void onIntake(String intakeTargetGamePieceType) { + if ("Coral".equals(intakeTargetGamePieceType)) throwAlgaeToGround(); + else if ("Algae".equals(intakeTargetGamePieceType)) throwCoralToGround(); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralOnField.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralOnField.java new file mode 100644 index 0000000..31a2a4c --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralOnField.java @@ -0,0 +1,27 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025; + +import static edu.wpi.first.units.Units.*; + +import edu.wpi.first.math.geometry.Pose2d; +import org.dyn4j.geometry.Rectangle; +import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation; + +/** + * + * + *

Represents a CORAL in the 2025 Reefscape game.

+ * + *

The Coral (am-5601) is an 11 ⅞-inch (~30 cm) + * long piece of 4-inch diameter Schedule 40 Cellular (Foam) Core PVC pipe, featured as a game piece in the 2025 + * Reefscape game. + * + *

The Coral has a 4-inch (~102 mm) inside diameter and a 4½-inch (~11 cm) outside diameter. + */ +public class ReefscapeCoralOnField extends GamePieceOnFieldSimulation { + public static final GamePieceInfo REEFSCAPE_CORAL_INFO = + new GamePieceInfo("Coral", new Rectangle(0.3, 0.11), Meters.of(0.11), Kilograms.of(0.3), 2.8, 4, 0.3); + + public ReefscapeCoralOnField(Pose2d initialPose) { + super(REEFSCAPE_CORAL_INFO, initialPose); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralOnFly.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralOnFly.java new file mode 100644 index 0000000..1703492 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralOnFly.java @@ -0,0 +1,98 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025; + +import static edu.wpi.first.units.Units.*; + +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.kinematics.ChassisSpeeds; +import edu.wpi.first.units.measure.Angle; +import edu.wpi.first.units.measure.Distance; +import edu.wpi.first.units.measure.LinearVelocity; +import edu.wpi.first.wpilibj.DriverStation; +import swervelib.simulation.ironmaple.simulation.SimulatedArena; +import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation; +import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceProjectile; +import swervelib.simulation.ironmaple.utils.FieldMirroringUtils; + +public class ReefscapeCoralOnFly extends GamePieceProjectile { + public ReefscapeCoralOnFly( + Translation2d robotPosition, + Translation2d shooterPositionOnRobot, + ChassisSpeeds chassisSpeeds, + Rotation2d shooterFacing, + Distance initialHeight, + LinearVelocity launchingSpeed, + Angle shooterAngle) { + super( + ReefscapeCoralOnField.REEFSCAPE_CORAL_INFO, + robotPosition, + shooterPositionOnRobot, + chassisSpeeds, + shooterFacing, + initialHeight, + launchingSpeed, + shooterAngle); + super.enableBecomesGamePieceOnFieldAfterTouchGround(); + super.withTouchGroundHeight(0.2); + } + + public enum CoralStationsSide { + LEFT_STATION(new Pose2d(0.89, 7.32, Rotation2d.fromDegrees(-54))), + RIGHT_STATION(new Pose2d(0.89, 0.6, Rotation2d.fromDegrees(54))); + + private final Pose2d startingPose; + + CoralStationsSide(Pose2d startingPose) { + this.startingPose = startingPose; + } + } + + public static ReefscapeCoralOnFly DropFromCoralStation( + CoralStationsSide station, DriverStation.Alliance alliance, boolean isHorizontal) { + Rotation2d rot = alliance == DriverStation.Alliance.Red + ? FieldMirroringUtils.flip(station.startingPose.getRotation()) + : station.startingPose.getRotation(); + Translation2d pos = alliance == DriverStation.Alliance.Red + ? FieldMirroringUtils.flip(station.startingPose.getTranslation()) + : station.startingPose.getTranslation(); + return isHorizontal + ? new ReefscapeCoralOnFly( + pos, + new Translation2d(), + ChassisSpeeds.fromRobotRelativeSpeeds(new ChassisSpeeds(3.0, 0, 0), rot), + rot.rotateBy(Rotation2d.kCCW_90deg), + Centimeters.of(98), + MetersPerSecond.of(0), + Degrees.of(0)) + : new ReefscapeCoralOnFly( + alliance == DriverStation.Alliance.Red + ? FieldMirroringUtils.flip(station.startingPose.getTranslation()) + : station.startingPose.getTranslation(), + new Translation2d(), + new ChassisSpeeds(), + alliance == DriverStation.Alliance.Red + ? FieldMirroringUtils.flip(station.startingPose.getRotation()) + : station.startingPose.getRotation(), + Centimeters.of(98), + MetersPerSecond.of(3), + Degrees.of(-50)); + } + + @Override + public void addGamePieceAfterTouchGround(SimulatedArena simulatedArena) { + if (!super.becomesGamePieceOnGroundAfterTouchGround) return; + simulatedArena.addGamePiece(new GamePieceOnFieldSimulation( + ReefscapeCoralOnField.REEFSCAPE_CORAL_INFO, + () -> Math.max( + ReefscapeCoralOnField.REEFSCAPE_CORAL_INFO + .gamePieceHeight() + .in(Meters) + / 2, + getPositionAtTime(super.launchedTimer.get()).getZ()), + new Pose2d( + getPositionAtTime(launchedTimer.get()).toTranslation2d(), + initialLaunchingVelocityMPS.getAngle()), + super.initialLaunchingVelocityMPS)); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeProcessorSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeProcessorSimulation.java new file mode 100644 index 0000000..8df4d14 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeProcessorSimulation.java @@ -0,0 +1,87 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025; + +import static edu.wpi.first.units.Units.Centimeters; +import static edu.wpi.first.units.Units.Degrees; +import static edu.wpi.first.units.Units.Meters; +import static edu.wpi.first.units.Units.MetersPerSecond; + +import edu.wpi.first.math.geometry.*; +import edu.wpi.first.math.kinematics.ChassisSpeeds; +import edu.wpi.first.networktables.NetworkTableInstance; +import edu.wpi.first.networktables.StructPublisher; +import java.util.*; +import swervelib.simulation.ironmaple.simulation.Goal; + +/** + * + * + *

Simulates a PROCESSORs on the field.

+ * + *

This class simulates a PROCESSORs on the field where ALGAEs can be scored. It + * will automatically launch the algae scored into the apposing barge and always hit. + */ +public class ReefscapeProcessorSimulation extends Goal { + + protected static final Translation3d blueProcessorPose = new Translation3d(6.34, -0.5, 0); + protected static final Translation3d redProcessorPose = new Translation3d(11.5, 8.5, 0); + protected static final Translation3d blueProcessorLaunchPose = new Translation3d(6.34, 0, 0); + protected static final Translation3d redProcessorLaunchPose = new Translation3d(11.5, 8, 0); + + StructPublisher posePublisher; + + /** + * + * + *

Creates an processor of the specified color.

+ * + * @param arena The host arena of this processor. + * @param isBlue Wether this is the blue processor or the red one. + */ + public ReefscapeProcessorSimulation(Arena2025Reefscape arena, boolean isBlue) { + super( + arena, + Centimeters.of(100), + Centimeters.of(100), + Centimeters.of(100), + "Algae", + isBlue ? blueProcessorPose : redProcessorPose, + isBlue); + + StructPublisher heldAlgaePublisher = NetworkTableInstance.getDefault() + .getStructTopic(isBlue ? "BlueProcessor" : "RedProcessor", Pose3d.struct) + .publish(); + heldAlgaePublisher.set(new Pose3d(position, new Rotation3d())); + } + + @Override + protected void addPoints() { + arena.addValueToMatchBreakdown(isBlue, "AlgaeInProcessor", 1); + + if (isBlue) { + arena.addToScore(isBlue, 6); + this.arena.addGamePieceProjectile(new ReefscapeAlgaeOnFly( + blueProcessorLaunchPose.toTranslation2d(), + new Translation2d(), + new ChassisSpeeds(), + Rotation2d.fromDegrees(45), + Meters.of(1.7), + MetersPerSecond.of(7), + Degrees.of(45))); + } else { + arena.addToScore(isBlue, 6); + this.arena.addGamePieceProjectile(new ReefscapeAlgaeOnFly( + redProcessorLaunchPose.toTranslation2d(), + new Translation2d(), + new ChassisSpeeds(), + Rotation2d.fromDegrees(-135), + Meters.of(1.7), + MetersPerSecond.of(7), + Degrees.of(45))); + } + } + + @Override + public void draw(List drawList) { + return; + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefBranch.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefBranch.java new file mode 100644 index 0000000..89c0c0a --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefBranch.java @@ -0,0 +1,220 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025; + +import static edu.wpi.first.units.Units.Centimeters; +import static edu.wpi.first.units.Units.Degrees; + +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.geometry.Transform3d; +import edu.wpi.first.math.geometry.Translation2d; +import edu.wpi.first.math.geometry.Translation3d; +import edu.wpi.first.units.Units; +import edu.wpi.first.wpilibj.DriverStation; +import java.util.Arrays; +import java.util.List; +import swervelib.simulation.ironmaple.simulation.Goal; +import swervelib.simulation.ironmaple.simulation.gamepieces.GamePiece; +import swervelib.simulation.ironmaple.utils.FieldMirroringUtils; + +/** + * + * + *

Simulates a Reefscape branch on the field.

+ * + *

This class simulates a Reefscape branch where corals can be scored. This class should not be used directly and + * instead should be used via a {@link ReefscapeReefSimulation} which will handle an entire reef. + */ +public class ReefscapeReefBranch extends Goal { + + public final int level; + public final int column; + + public static final Translation2d origin = + new Translation2d(FieldMirroringUtils.FIELD_WIDTH / 2, FieldMirroringUtils.FIELD_HEIGHT / 2); + public static final Translation2d[] branchesCenterPositionBlue = new Translation2d[] { + new Translation2d(-4.810, 0.164).plus(origin), // A + new Translation2d(-4.810, -0.164).plus(origin), // B + new Translation2d(-4.690, -0.373).plus(origin), // C + new Translation2d(-4.406, -0.538).plus(origin), // D + new Translation2d(-4.164, -0.537).plus(origin), // E + new Translation2d(-3.879, -0.374).plus(origin), // F + new Translation2d(-3.759, -0.164).plus(origin), // G + new Translation2d(-3.759, 0.164).plus(origin), // H + new Translation2d(-3.880, 0.373).plus(origin), // I + new Translation2d(-4.164, 0.538).plus(origin), // J + new Translation2d(-4.405, 0.538).plus(origin), // K + new Translation2d(-4.690, 0.374).plus(origin) // L + }; + + public static final Translation3d[] heights = new Translation3d[] { + new Translation3d(0, 0, 0.45), + new Translation3d(0, 0, 0.79), + new Translation3d(0, 0, 1.19), + new Translation3d(0, 0, 1.78) + }; + + public static final Rotation3d flip90 = new Rotation3d(0, 0, Math.PI / 2); + + public static final Translation2d[] branchesCenterPositionRed = Arrays.stream(branchesCenterPositionBlue) + .map(FieldMirroringUtils::flip) + .toArray(Translation2d[]::new); + + public static final Rotation2d[] branchesFacingOutwardsBlue = new Rotation2d[] { + Rotation2d.fromDegrees(180), Rotation2d.fromDegrees(180), // A and B + Rotation2d.fromDegrees(240), Rotation2d.fromDegrees(240), // C and D + Rotation2d.fromDegrees(300), Rotation2d.fromDegrees(300), // E and F + Rotation2d.fromDegrees(0), Rotation2d.fromDegrees(0), // G and H + Rotation2d.fromDegrees(60), Rotation2d.fromDegrees(60), // I and J + Rotation2d.fromDegrees(120), Rotation2d.fromDegrees(120), // K and L + }; + + /** + * + * + *

Returns the required pose of a reef branch at the designated position.

+ * + * @param isBlue Wether the position is on the blue reef or the red reef. + * @param level The level of the reef (0 indexed). Range of 0-3. + * @param col The pole or Colum of the reef (0 indexed). Range of 0-11. + * @return The pose of a reef branch with the specified stats. + */ + public static Translation3d getPoseOfBranchAt(boolean isBlue, int level, int col) { + if (isBlue) { + return new Translation3d(branchesCenterPositionBlue[col]) + .plus(heights[level]) + .plus(new Translation3d(0.255, 0, 0).rotateBy(new Rotation3d(branchesFacingOutwardsBlue[col]))); + } else { + return new Translation3d(branchesCenterPositionRed[col]) + .plus(heights[level]) + .plus(new Translation3d(0.255, 0, 0).rotateBy(new Rotation3d(branchesFacingOutwardsRed[col]))); + } + } + + public static final Rotation2d[] branchesFacingOutwardsRed = Arrays.stream(branchesFacingOutwardsBlue) + .map(FieldMirroringUtils::flip) + .toArray(Rotation2d[]::new); + + /** + * + * + *

Creates a singular reef branch at the specified location

+ * + * @param arena The host arena of this reef. + * @param isBlue Wether the position is on the blue reef or the red reef. + * @param level The level of the reef (0 indexed). Range of 0-3. + * @param column The pole or Colum of the reef (0 indexed). Range of 0-11. + */ + public ReefscapeReefBranch(Arena2025Reefscape arena, boolean isBlue, int level, int column) { + super( + arena, + level == 0 ? Centimeters.of(30) : Centimeters.of(10), + level == 0 ? Centimeters.of(100) : Centimeters.of(10), + Centimeters.of(30), + "Coral", + getPoseOfBranchAt(isBlue, level, column), + isBlue, + level == 0 ? 2 : 1); + + if (level == 1 || level == 2) { + if (isBlue) { + setNeededAngle( + new Rotation3d(0, -35 * Math.PI / 180, branchesFacingOutwardsBlue[column].getRadians()), + Degrees.of(10)); + } else { + setNeededAngle( + new Rotation3d(0, -35 * Math.PI / 180, branchesFacingOutwardsRed[column].getRadians()), + Degrees.of(10)); + } + } else if (level == 3) { + setNeededAngle( + new Rotation3d(0, -Math.PI / 2, branchesFacingOutwardsRed[column].getRadians()), Degrees.of(10)); + } + this.level = level; + this.column = column; + } + + /** + * + * + *

Gives the pose of the reef branch.

+ * + * @return This position of this branch as a pose3d. + */ + public Pose3d getPose() { + return new Pose3d( + position, + pieceAngle != null + ? pieceAngle + : new Rotation3d(0, 0, branchesFacingOutwardsBlue[column].getRadians()).plus(flip90)); + } + + @Override + public boolean checkRotation(GamePiece gamePiece) { + if (level == 3) { + Rotation3d rotation = gamePiece.getPose3d().getRotation(); + System.out.println(Math.abs(rotation.getY() + Math.PI / 2)); + System.out.println(Math.abs(rotation.getY() - Math.PI / 2)); + + return Math.abs(rotation.getY() + Math.PI / 2) < Degrees.of(10).in(Units.Radians) + || Math.abs(rotation.getY() - Math.PI / 2) < Degrees.of(10).in(Units.Radians); + } else { + return super.checkRotation(gamePiece); + } + } + + @Override + protected void addPoints() { + System.out.println("Coral scored on level: " + (level + 1) + " on the " + (isBlue ? "Blue " : "Red") + "reef"); + arena.addValueToMatchBreakdown(isBlue, "Auto/CoralScoredInAuto", DriverStation.isAutonomous() ? 1 : 0); + arena.addValueToMatchBreakdown(isBlue, "CoralScoredOnLevel " + String.valueOf(level + 1), 1); + + if (DriverStation.isAutonomous()) { + switch (level) { + case 3: + arena.addToScore(isBlue, 7); + break; + case 2: + arena.addToScore(isBlue, 6); + break; + case 1: + arena.addToScore(isBlue, 4); + break; + case 0: + arena.addToScore(isBlue, 3); + break; + default: + throw new Error("Something has gone horribly wrong in the maplesim internal reef, level was: " + + level + " out of a supported range 0-3"); + } + } else { + switch (level) { + case 3: + arena.addToScore(isBlue, 5); + break; + case 2: + arena.addToScore(isBlue, 4); + break; + case 1: + arena.addToScore(isBlue, 3); + break; + case 0: + arena.addToScore(isBlue, 2); + break; + default: + throw new Error("Something has gone horribly wrong in the maplesim internal reef, level was: " + + level + " out of a supported range 0-3"); + } + } + } + + @Override + public void draw(List drawList) { + if (this.gamePieceCount > 0) { + drawList.add(getPose()); + } + if (this.gamePieceCount > 1) { + drawList.add(getPose().transformBy(new Transform3d(0, isBlue ? 0.12 : -0.12, 0, new Rotation3d()))); + } + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefSimulation.java new file mode 100644 index 0000000..0113e0e --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefSimulation.java @@ -0,0 +1,105 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025; + +import edu.wpi.first.math.geometry.Pose3d; +import edu.wpi.first.networktables.NetworkTableInstance; +import edu.wpi.first.networktables.StructArrayPublisher; +import java.util.ArrayList; +import java.util.List; +import swervelib.simulation.ironmaple.simulation.Goal; +import swervelib.simulation.ironmaple.simulation.SimulatedArena; + +/** + * + * + *

Simulates a REEFs on the field.

+ * + *

This class simulates a REEFs on the field where CORALs can be scored. This class + * does not directly handle scoring uses an array of {@link ReefscapeReefBranch} objects. However for all other purposes + * this class behaves and can be used like a normal goal. + */ +public class ReefscapeReefSimulation implements SimulatedArena.Simulatable { + protected final List branches; + public ReefscapeAlgaeOnField algae; + private StructArrayPublisher reefPub; + Pose3d[] branchPoses; + + /** + * + * + *

Creates an reef of the specified color.

+ * + * @param arena The host arena of this reef. + * @param isBlue Wether this is the blue reef or the red one. + */ + ReefscapeReefSimulation(Arena2025Reefscape arena, boolean isBlue) { + branches = new ArrayList(48); + branchPoses = new Pose3d[96]; + for (int tower = 0; tower < 12; tower++) { + for (int level = 0; level < 4; level++) { + branches.add(new ReefscapeReefBranch(arena, isBlue, level, tower)); + Pose3d tempPose = branches.get(branches.size() - 1).getPose(); + + branchPoses[2 * (tower * 4 + level)] = tempPose; + + branchPoses[2 * (tower * 4 + level) + 1] = + new Pose3d(tempPose.getTranslation(), Goal.flipRotation(tempPose.getRotation())); + } + } + reefPub = NetworkTableInstance.getDefault() + .getStructArrayTopic(isBlue ? "BlueReef" : "RedReef", Pose3d.struct) + .publish(); + + reefPub.set(branchPoses); + } + + public void draw(List coralPosesToDisplay) { + for (ReefscapeReefBranch branch : branches) { + branch.draw(coralPosesToDisplay); + } + } + + @Override + public void simulationSubTick(int subTickNum) { + for (ReefscapeReefBranch branch : branches) { + branch.simulationSubTick(subTickNum); + } + } + + /** + * + * + *

Resets the reef to its original state.

+ */ + public void clearReef() { + for (ReefscapeReefBranch branch : branches) { + branch.clear(); + } + } + + /** + * Obtains the amount of CORAL held on the BRANCHES. + * + *

This method returns a 2D array of size 12 x 4, where each entry represents the number of + * CORALs held on a particular branch. + * + *

The BRANCHES are tracked in FMS as A, B, C, D, E, F, G, H, I, J, K, L (as per the game + * manual), and are mapped to indices 0, 1, 2, ... in the array. + * + *

The [i][j] entry in the array represents the number of CORAL(s) held on the Lj-1 + * branch in the ith section. + * + *

For example, getBranches()[2][3] returns the number of CORALs held on L4 of Branch C. + * + *

Note that L2, L3, and L4 can only hold one CORAL, while L1 can hold up to two + * CORALs. + * + * @return a 2D array where each entry represents the number of CORAL held on each branch + */ + public int[][] getBranches() { + int[][] toReturn = new int[12][4]; + for (ReefscapeReefBranch branch : branches) { + toReturn[branch.column][branch.level] = branch.getGamePieceCount(); + } + return toReturn; + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/utils/FieldMirroringUtils.java b/yagsl/java/swervelib/simulation/ironmaple/utils/FieldMirroringUtils.java new file mode 100644 index 0000000..aeb3218 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/utils/FieldMirroringUtils.java @@ -0,0 +1,55 @@ +package swervelib.simulation.ironmaple.utils; + +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.geometry.Translation3d; +import edu.wpi.first.wpilibj.DriverStation; +import java.util.Optional; + +public class FieldMirroringUtils { + public static final double FIELD_WIDTH = 17.548; + public static final double FIELD_HEIGHT = 8.052; + + public static Rotation2d toCurrentAllianceRotation(Rotation2d rotationAtBlueSide) { + return isSidePresentedAsRed() ? flip(rotationAtBlueSide) : rotationAtBlueSide; + } + + public static Rotation2d flip(Rotation2d rotation) { + return rotation.plus(Rotation2d.k180deg); + } + + public static Translation2d toCurrentAllianceTranslation(Translation2d translationAtBlueSide) { + return isSidePresentedAsRed() ? flip(translationAtBlueSide) : translationAtBlueSide; + } + + public static Translation2d flip(Translation2d translation) { + return new Translation2d(FIELD_WIDTH - translation.getX(), FIELD_HEIGHT - translation.getY()); + } + + public static Translation3d toCurrentAllianceTranslation(Translation3d translation3dAtBlueSide) { + final Translation2d translation3dAtCurrentAlliance = + toCurrentAllianceTranslation(translation3dAtBlueSide.toTranslation2d()); + if (isSidePresentedAsRed()) + return new Translation3d( + translation3dAtCurrentAlliance.getX(), + translation3dAtCurrentAlliance.getY(), + translation3dAtBlueSide.getZ()); + return translation3dAtBlueSide; + } + + public static Pose2d toCurrentAlliancePose(Pose2d poseAtBlueSide) { + return new Pose2d( + toCurrentAllianceTranslation(poseAtBlueSide.getTranslation()), + toCurrentAllianceRotation(poseAtBlueSide.getRotation())); + } + + public static boolean isSidePresentedAsRed() { + final Optional alliance = DriverStation.getAlliance(); + return alliance.isPresent() && alliance.get().equals(DriverStation.Alliance.Red); + } + + public static Rotation2d getCurrentAllianceDriverStationFacing() { + return toCurrentAllianceRotation(Rotation2d.kZero); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/utils/LegacyFieldMirroringUtils2024.java b/yagsl/java/swervelib/simulation/ironmaple/utils/LegacyFieldMirroringUtils2024.java new file mode 100644 index 0000000..9618877 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/utils/LegacyFieldMirroringUtils2024.java @@ -0,0 +1,61 @@ +package swervelib.simulation.ironmaple.utils; + +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.geometry.Translation3d; +import edu.wpi.first.wpilibj.DriverStation; +import java.util.Optional; +import java.util.function.Supplier; + +public class LegacyFieldMirroringUtils2024 { + public static final double FIELD_WIDTH = 16.54; + public static final double FIELD_HEIGHT = 8.21; + + public static final Translation3d SPEAKER_POSE_BLUE = new Translation3d(0.1, 5.55, 2.2); + + public static final Supplier SPEAKER_POSITION_SUPPLIER = + () -> toCurrentAllianceTranslation(SPEAKER_POSE_BLUE.toTranslation2d()); + + public static Rotation2d toCurrentAllianceRotation(Rotation2d rotationAtBlueSide) { + final Rotation2d yAxis = Rotation2d.fromDegrees(90), + differenceFromYAxisAtBlueSide = rotationAtBlueSide.minus(yAxis), + differenceFromYAxisNew = differenceFromYAxisAtBlueSide.times(isSidePresentedAsRed() ? -1 : 1); + return yAxis.rotateBy(differenceFromYAxisNew); + } + + public static Translation2d toCurrentAllianceTranslation(Translation2d translationAtBlueSide) { + if (isSidePresentedAsRed()) + return new Translation2d(FIELD_WIDTH - translationAtBlueSide.getX(), translationAtBlueSide.getY()); + return translationAtBlueSide; + } + + public static Translation3d toCurrentAllianceTranslation(Translation3d translation3dAtBlueSide) { + final Translation2d translation3dAtCurrentAlliance = + toCurrentAllianceTranslation(translation3dAtBlueSide.toTranslation2d()); + if (isSidePresentedAsRed()) + return new Translation3d( + translation3dAtCurrentAlliance.getX(), + translation3dAtCurrentAlliance.getY(), + translation3dAtBlueSide.getZ()); + return translation3dAtBlueSide; + } + + public static Pose2d toCurrentAlliancePose(Pose2d poseAtBlueSide) { + return new Pose2d( + toCurrentAllianceTranslation(poseAtBlueSide.getTranslation()), + toCurrentAllianceRotation(poseAtBlueSide.getRotation())); + } + + public static boolean isSidePresentedAsRed() { + final Optional alliance = DriverStation.getAlliance(); + return alliance.isPresent() && alliance.get().equals(DriverStation.Alliance.Red); + } + + public static Rotation2d getCurrentAllianceDriverStationFacing() { + return switch (DriverStation.getAlliance().orElse(DriverStation.Alliance.Red)) { + case Red -> new Rotation2d(Math.PI); + case Blue -> new Rotation2d(0); + }; + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/GeometryConvertor.java b/yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/GeometryConvertor.java new file mode 100644 index 0000000..52ffbf9 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/GeometryConvertor.java @@ -0,0 +1,53 @@ +package swervelib.simulation.ironmaple.utils.mathutils; + +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.kinematics.ChassisSpeeds; +import org.dyn4j.geometry.Rotation; +import org.dyn4j.geometry.Transform; +import org.dyn4j.geometry.Vector2; + +/** utils to convert between WPILIB and dyn4j geometry classes */ +public class GeometryConvertor { + public static Vector2 toDyn4jVector2(Translation2d wpilibTranslation2d) { + return new Vector2(wpilibTranslation2d.getX(), wpilibTranslation2d.getY()); + } + + public static Translation2d toWpilibTranslation2d(Vector2 dyn4jVector2) { + return new Translation2d(dyn4jVector2.x, dyn4jVector2.y); + } + + public static Rotation toDyn4jRotation(Rotation2d wpilibRotation2d) { + return new Rotation(wpilibRotation2d.getRadians()); + } + + public static Rotation2d toWpilibRotation2d(Rotation dyn4jRotation) { + return new Rotation2d(dyn4jRotation.toRadians()); + } + + public static Transform toDyn4jTransform(Pose2d wpilibPose2d) { + final Transform transform = new Transform(); + transform.setTranslation(toDyn4jVector2(wpilibPose2d.getTranslation())); + transform.setRotation(toDyn4jRotation(wpilibPose2d.getRotation())); + return transform; + } + + public static Pose2d toWpilibPose2d(Transform dyn4jTransform) { + return new Pose2d( + toWpilibTranslation2d(dyn4jTransform.getTranslation()), + toWpilibRotation2d(dyn4jTransform.getRotation())); + } + + public static Vector2 toDyn4jLinearVelocity(ChassisSpeeds wpilibChassisSpeeds) { + return new Vector2(wpilibChassisSpeeds.vxMetersPerSecond, wpilibChassisSpeeds.vyMetersPerSecond); + } + + public static ChassisSpeeds toWpilibChassisSpeeds(Vector2 dyn4jLinearVelocity, double angularVelocityRadPerSec) { + return new ChassisSpeeds(dyn4jLinearVelocity.x, dyn4jLinearVelocity.y, angularVelocityRadPerSec); + } + + public static Translation2d getChassisSpeedsTranslationalComponent(ChassisSpeeds chassisSpeeds) { + return new Translation2d(chassisSpeeds.vxMetersPerSecond, chassisSpeeds.vyMetersPerSecond); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/MapleCommonMath.java b/yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/MapleCommonMath.java new file mode 100644 index 0000000..9ade923 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/MapleCommonMath.java @@ -0,0 +1,61 @@ +package swervelib.simulation.ironmaple.utils.mathutils; + +import edu.wpi.first.math.geometry.Rotation2d; +import edu.wpi.first.math.geometry.Translation2d; +import java.util.Random; + +public class MapleCommonMath { + private static final Random random = new Random(); + + /** + * using the random number generator of a fixed seed, generate the next random normal variable + * + * @param mean the center of the distribution + * @param stdDev the standard deviation of the distribution + * @return the next random variable x from the distribution + */ + public static double generateRandomNormal(double mean, double stdDev) { + double u1 = random.nextDouble(); + double u2 = random.nextDouble(); + // Box–Muller transform https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform + double z0 = Math.sqrt(-2.0 * Math.log(u1)) * Math.cos(2.0 * Math.PI * u2); + return z0 * stdDev + mean; + } + + /** + * + * + *

Constrains the magnitude of a value.

+ * + * @param value the value to constrain + * @param maxMagnitude the maximum allowed magnitude + * @return the constrained value + */ + public static double constrainMagnitude(double value, double maxMagnitude) { + return Math.copySign(Math.min(Math.abs(value), Math.abs(maxMagnitude)), value); + } + + public static double linearInterpretationWithBounding(double x1, double y1, double x2, double y2, double x) { + final double minX = Math.min(x1, x2), maxX = Math.max(x1, x2); + return linearInterpretation(x1, y1, x2, y2, Math.min(maxX, Math.max(minX, x))); + } + + public static double linearInterpretation(double x1, double y1, double x2, double y2, double x) { + return y1 + (x - x1) * (y2 - y1) / (x2 - x1); + } + + /** + * + * + *

Obtains the angle of a translation, ignores zero translation.

+ * + *

This prevents the driver-station from throwing a bunch of "x and y components of Rotation2d are zero" warning. + * + * @param translation2d the translation + * @return the angle of the translation, or zero if the translation is zero + */ + public static Rotation2d getAngle(Translation2d translation2d) { + final double tooSmall = 1e-6; + return translation2d.getNorm() < tooSmall ? Rotation2d.fromDegrees(0) : translation2d.getAngle(); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/SwerveStateProjection.java b/yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/SwerveStateProjection.java new file mode 100644 index 0000000..0a31e76 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/SwerveStateProjection.java @@ -0,0 +1,26 @@ +// Created by Team 5516 https://github.com/Shenzhen-Robotics-Alliance/ using ChatGPT4o +package swervelib.simulation.ironmaple.utils.mathutils; + +import edu.wpi.first.math.geometry.Rotation2d; +import edu.wpi.first.math.kinematics.SwerveModuleState; + +public class SwerveStateProjection { + /** + * Projects the swerve module speed onto the direction of the current swerve facing. + * + * @param swerveSpeed The current speed and direction of the swerve module. + * @param currentSwerveFacing The desired direction to project onto. + * @return The projected speed in the direction of currentSwerveFacing. + */ + public static double project(SwerveModuleState swerveSpeed, Rotation2d currentSwerveFacing) { + // Get the angle of the swerve module's current direction + Rotation2d swerveModuleAngle = swerveSpeed.angle; + + // Calculate the cosine of the angle difference between swerve module direction and the desired + // direction + double cosTheta = Math.cos(swerveModuleAngle.minus(currentSwerveFacing).getRadians()); + + // Scale the speed by the cosine value to get the projection + return swerveSpeed.speedMetersPerSecond * cosTheta; + } +} From 8bbdcd40f4aeaf16c4ba636d2bd876052932ca00 Mon Sep 17 00:00:00 2001 From: thenetworkgrinch Date: Mon, 5 Jan 2026 15:17:56 -0600 Subject: [PATCH 02/62] Added navx3 support. --- yagsl/java/swervelib/imu/NavX3Swerve.java | 174 ++++++++++++++++++ .../swervelib/parser/json/DeviceJson.java | 3 + 2 files changed, 177 insertions(+) create mode 100644 yagsl/java/swervelib/imu/NavX3Swerve.java diff --git a/yagsl/java/swervelib/imu/NavX3Swerve.java b/yagsl/java/swervelib/imu/NavX3Swerve.java new file mode 100644 index 0000000..c748f05 --- /dev/null +++ b/yagsl/java/swervelib/imu/NavX3Swerve.java @@ -0,0 +1,174 @@ +package swervelib.imu; + +import static edu.wpi.first.units.Units.Degree; +import static edu.wpi.first.units.Units.DegreesPerSecond; +import static edu.wpi.first.units.Units.Milliseconds; + +import com.studica.frc.AHRS; +import com.studica.frc.AHRS.NavXComType; +import com.studica.frc.Navx; +import edu.wpi.first.math.geometry.Rotation3d; +import edu.wpi.first.math.geometry.Translation3d; +import edu.wpi.first.units.measure.MutAngularVelocity; +import edu.wpi.first.wpilibj.Alert; +import edu.wpi.first.wpilibj.Alert.AlertType; +import edu.wpi.first.wpilibj.Timer; +import java.util.Optional; + +/** + * Communicates with the NavX({@link AHRS}) as the IMU. + */ +public class NavX3Swerve extends SwerveIMU +{ + + /** + * Mutable {@link MutAngularVelocity} for readings. + */ + private final MutAngularVelocity yawVel = new MutAngularVelocity(0, 0, DegreesPerSecond); + /** + * NavX IMU. + */ + private Navx imu; + /** + * Offset for the NavX. + */ + private Rotation3d offset = new Rotation3d(); + /** + * An {@link Alert} for if there is an error instantiating the NavX. + */ + private Alert navXError; + /** + * Inversion state of the {@link AHRS}. + */ + private boolean inverted = false; + + /** + * Constructor for the NavX({@link com.studica.frc.Navx}) swerve. + * + * @param canid CAN ID of the NavX3. + */ + public NavX3Swerve(int canid) + { + navXError = new Alert("IMU", "Error instantiating NavX.", AlertType.kError); + try + { + imu = new Navx(canid); + for(int i = 0; i < 4; i++) + { + if (imu.start() == 0) + break; + Timer.delay(Milliseconds.of(5)); + } + + } catch (RuntimeException ex) + { + navXError.setText("Error instantiating NavX: " + ex.getMessage()); + navXError.set(true); + } + } + + @Override + public void close() + { +// imu.close(); + } + + /** + * Reset offset to current gyro reading. Does not call NavX({@link AHRS#reset()}) because it has been reported to be + * too slow. + */ + @Override + public void factoryDefault() + { + // gyro.reset(); // Reported to be slow + offset = new Rotation3d(Degree.of(imu.getRoll()), Degree.of(imu.getPitch()), Degree.of(imu.getYaw())); + } + + /** + * Clear sticky faults on IMU. + */ + @Override + public void clearStickyFaults() + { + } + + /** + * Set the gyro offset. + * + * @param offset gyro offset as a {@link Rotation3d}. + */ + public void setOffset(Rotation3d offset) + { + this.offset = offset; + } + + /** + * Set the gyro to invert its default direction + * + * @param invertIMU invert gyro direction + */ + public void setInverted(boolean invertIMU) + { + inverted = invertIMU; +// setOffset(getRawRotation3d()); + } + + private Rotation3d negate(Rotation3d rot) { + return new Rotation3d(-rot.getX(), -rot.getY(), -rot.getZ()); + } + + /** + * Fetch the {@link Rotation3d} from the IMU without any zeroing. Robot relative. + * + * @return {@link Rotation3d} from the IMU. + */ + @Override + public Rotation3d getRawRotation3d() + { + Rotation3d rotation = new Rotation3d(Degree.of(imu.getRoll()), Degree.of(imu.getPitch()), Degree.of(imu.getYaw())); + return inverted ? negate(rotation) : rotation; + } + + /** + * Fetch the {@link Rotation3d} from the IMU. Robot relative. + * + * @return {@link Rotation3d} from the IMU. + */ + @Override + public Rotation3d getRotation3d() + { + return getRawRotation3d().rotateBy(offset.unaryMinus()); + } + + /** + * Fetch the acceleration [x, y, z] from the IMU in meters per second squared. If acceleration isn't supported returns + * empty. + * + * @return {@link Translation3d} of the acceleration as an {@link Optional}. + */ + @Override + public Optional getAccel() + { + return Optional.empty(); + } + + @Override + public MutAngularVelocity getYawAngularVelocity() + { + // x, y, z + float[] angularVelocity = {0,0,0}; + imu.getAngularVel(angularVelocity); + return yawVel.mut_setMagnitude(angularVelocity[2]); + } + + /** + * Get the instantiated NavX({@link AHRS}) IMU object. + * + * @return IMU object. + */ + @Override + public Object getIMU() + { + return imu; + } +} diff --git a/yagsl/java/swervelib/parser/json/DeviceJson.java b/yagsl/java/swervelib/parser/json/DeviceJson.java index 3dadc69..be047e4 100644 --- a/yagsl/java/swervelib/parser/json/DeviceJson.java +++ b/yagsl/java/swervelib/parser/json/DeviceJson.java @@ -23,6 +23,7 @@ import swervelib.imu.ADXRS450Swerve; import swervelib.imu.AnalogGyroSwerve; //import swervelib.imu.CanandgyroSwerve; +import swervelib.imu.NavX3Swerve; import swervelib.imu.NavXSwerve; import swervelib.imu.Pigeon2Swerve; import swervelib.imu.PigeonSwerve; @@ -158,6 +159,8 @@ public SwerveIMU createIMU() case "navx": case "navx_spi": return new NavXSwerve(NavXComType.kMXP_SPI); + case "navx3": + return new NavX3Swerve(id); case "navx_i2c": DriverStation.reportWarning( "WARNING: There exists an I2C lockup issue on the roboRIO that could occur, more information here: " + From 824d2a86fa2b337b1a880611cdc6fc05650c1354 Mon Sep 17 00:00:00 2001 From: twisterjafla <122408604+twisterjafla@users.noreply.github.com> Date: Thu, 8 Jan 2026 15:17:02 -0700 Subject: [PATCH 03/62] Update README.md Fixed the vendor dep link --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 611b5a0..e488ec6 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ used in both TimedRobot and Command-Based Robot templates. Vendor URL: ``` -https://yet-another-software-suite.github.io/YAGSL/yagsl/yagsl.json +https://yet-another-software-suite.github.io/YAGSL/yagsl.json ``` [Javadocs here](https://yet-another-software-suite.github.io/YAGSL/javadocs/) @@ -73,4 +73,4 @@ SwerveDrive swerveDrive=new SwerveParser(new File(Filesystem.getDeployDirectory( # Special Thanks to Team 7900! Trial N' Terror Without the debugging and aid of Team 7900 the project could never be as stable or active as it is. -Falcon Support would not have been possible without support from Team 1466 Webb Robotics! \ No newline at end of file +Falcon Support would not have been possible without support from Team 1466 Webb Robotics! From 5a4852da0b67764876846a282478177151749645 Mon Sep 17 00:00:00 2001 From: twisterjafla <122408604+twisterjafla@users.noreply.github.com> Date: Thu, 8 Jan 2026 15:24:14 -0700 Subject: [PATCH 04/62] Update README.md (#7) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 611b5a0..e488ec6 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ used in both TimedRobot and Command-Based Robot templates. Vendor URL: ``` -https://yet-another-software-suite.github.io/YAGSL/yagsl/yagsl.json +https://yet-another-software-suite.github.io/YAGSL/yagsl.json ``` [Javadocs here](https://yet-another-software-suite.github.io/YAGSL/javadocs/) @@ -73,4 +73,4 @@ SwerveDrive swerveDrive=new SwerveParser(new File(Filesystem.getDeployDirectory( # Special Thanks to Team 7900! Trial N' Terror Without the debugging and aid of Team 7900 the project could never be as stable or active as it is. -Falcon Support would not have been possible without support from Team 1466 Webb Robotics! \ No newline at end of file +Falcon Support would not have been possible without support from Team 1466 Webb Robotics! From fa368c4c56c85c37d5e74d3bbfb413bd5b386111 Mon Sep 17 00:00:00 2001 From: thenetworkgrinch Date: Sun, 11 Jan 2026 17:03:58 -0600 Subject: [PATCH 05/62] 2026 official build. --- examples/drivebase_only/.gitignore | 182 - .../drivebase_only/.pathplanner/settings.json | 15 - ...Build & Deploy Robot for Debugging.run.xml | 48 - .../.run/Build & Deploy Robot.run.xml | 48 - .../drivebase_only/.run/Build Robot.run.xml | 48 - ...Build & Deploy Robot for Debugging.run.xml | 50 - .../.run/Clean Build & Deploy Robot.run.xml | 50 - .../.run/Clean Build Robot.run.xml | 50 - examples/drivebase_only/.run/Clean.run.xml | 46 - .../.run/Debug Robot via IP.run.xml | 16 - .../.run/Debug Robot via USB.run.xml | 12 - .../drivebase_only/.styles/BroncBotzStyle.xml | 601 -- examples/drivebase_only/.vscode/launch.json | 21 - examples/drivebase_only/.vscode/settings.json | 29 - .../.wpilib/wpilib_preferences.json | 6 - examples/drivebase_only/LICENSE.txt | 201 - examples/drivebase_only/README.md | 115 - examples/drivebase_only/build.gradle | 114 - .../gradle/wrapper/gradle-wrapper.jar | Bin 43583 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 7 - examples/drivebase_only/gradlew | 252 - examples/drivebase_only/gradlew.bat | 94 - examples/drivebase_only/networktables.json | 1 - examples/drivebase_only/settings.gradle | 30 - examples/drivebase_only/simgui.json | 142 - .../src/main/deploy/example.txt | 3 - .../main/deploy/pathplanner/SamplePath.path | 76 - .../deploy/pathplanner/autos/New Auto.auto | 19 - .../generatedJSON/New Path.wpilib.json | 9002 ----------------- .../generatedJSON/SamplePath.wpilib.json | 9002 ----------------- .../src/main/deploy/pathplanner/navgrid.json | 1656 --- .../deploy/pathplanner/paths/New Path.path | 70 - .../src/main/deploy/pathplanner/settings.json | 32 - .../swerve/falcon/controllerproperties.json | 8 - .../swerve/falcon/modules/backleft.json | 26 - .../swerve/falcon/modules/backright.json | 26 - .../swerve/falcon/modules/frontleft.json | 26 - .../swerve/falcon/modules/frontright.json | 26 - .../falcon/modules/physicalproperties.json | 23 - .../swerve/falcon/modules/pidfproperties.json | 16 - .../deploy/swerve/falcon/swervedrive.json | 15 - .../maxSwerve/controllerproperties.json | 8 - .../swerve/maxSwerve/modules/backleft.json | 27 - .../swerve/maxSwerve/modules/backright.json | 27 - .../swerve/maxSwerve/modules/frontleft.json | 27 - .../swerve/maxSwerve/modules/frontright.json | 27 - .../maxSwerve/modules/physicalproperties.json | 23 - .../maxSwerve/modules/pidfproperties.json | 16 - .../deploy/swerve/maxSwerve/swervedrive.json | 14 - .../swerve/neo/controllerproperties.json | 8 - .../deploy/swerve/neo/modules/backleft.json | 26 - .../deploy/swerve/neo/modules/backright.json | 26 - .../deploy/swerve/neo/modules/frontleft.json | 26 - .../deploy/swerve/neo/modules/frontright.json | 26 - .../neo/modules/physicalproperties.json | 23 - .../swerve/neo/modules/pidfproperties.json | 16 - .../main/deploy/swerve/neo/swervedrive.json | 15 - .../src/main/java/frc/robot/Constants.java | 51 - .../src/main/java/frc/robot/Main.java | 29 - .../src/main/java/frc/robot/Robot.java | 178 - .../main/java/frc/robot/RobotContainer.java | 199 - .../swervedrive/auto/AutoBalanceCommand.java | 86 - .../swervedrive/drivebase/AbsoluteDrive.java | 120 - .../drivebase/AbsoluteDriveAdv.java | 154 - .../drivebase/AbsoluteFieldDrive.java | 95 - .../swervedrive/SwerveSubsystem.java | 486 - .../drivebase_only/vendordeps/REVLib.json | 133 - .../vendordeps/Studica-2026.0.0-beta.json | 71 - .../drivebase_only/vendordeps/StudicaLib.json | 71 - .../drivebase_only/vendordeps/ThriftyLib.json | 20 - .../vendordeps/WPILibNewCommands.json | 39 - examples/drivebase_only_2026/build.gradle | 2 +- .../src/main/java/frc/robot/Robot.java | 2 +- .../vendordeps/PathplannerLib-2026.1.2.json | 38 + ...eta-1.json => Phoenix5-replay-5.36.0.json} | 44 +- .../Phoenix6-replay-26.0.0-beta-1.json | 453 - .../vendordeps/Phoenix6-replay-26.1.0.json} | 114 +- .../vendordeps/REVLib.json | 20 +- .../vendordeps/Studica-2026.0.0-beta.json | 71 - .../vendordeps/StudicaLib.json | 71 - .../vendordeps/ThriftyLib.json | 20 - .../vendordeps/WPILibNewCommands.json | 76 +- .../drivebase_with_PathPlanner/build.gradle | 2 +- .../drivebase_with_PhotonVision/build.gradle | 2 +- .../vendordeps/PathplannerLib-2026.1.2.json | 38 + .../Phoenix5-replay-5.36.0-beta-1.json | 221 - .../vendordeps/Phoenix5-replay-5.36.0.json} | 44 +- .../vendordeps/Phoenix6-replay-26.1.0.json} | 114 +- .../vendordeps/REVLib.json | 20 +- .../vendordeps/Studica-2026.0.0-beta.json | 71 - .../vendordeps/StudicaLib.json | 71 - .../vendordeps/ThriftyLib.json | 20 - .../vendordeps/WPILibNewCommands.json | 76 +- examples/full_example/build.gradle | 2 +- .../encoders/ThriftyNovaEncoderSwerve.java | 282 +- yagsl/java/swervelib/imu/NavX3Swerve.java | 348 +- yagsl/java/swervelib/imu/NavXSwerve.java | 336 +- .../swervelib/motors/SparkFlexSwerve.java | 10 +- .../java/swervelib/motors/SparkMaxSwerve.java | 10 +- .../java/swervelib/motors/TalonFXSSwerve.java | 3 +- .../java/swervelib/motors/TalonFXSwerve.java | 3 +- .../swervelib/motors/ThriftyNovaSwerve.java | 1078 +- .../parser/SwerveDriveConfiguration.java | 9 +- .../swervelib/parser/json/DeviceJson.java | 54 +- .../swervelib/parser/json/ModuleJson.java | 11 +- 105 files changed, 1453 insertions(+), 26554 deletions(-) delete mode 100644 examples/drivebase_only/.gitignore delete mode 100644 examples/drivebase_only/.pathplanner/settings.json delete mode 100644 examples/drivebase_only/.run/Build & Deploy Robot for Debugging.run.xml delete mode 100644 examples/drivebase_only/.run/Build & Deploy Robot.run.xml delete mode 100644 examples/drivebase_only/.run/Build Robot.run.xml delete mode 100644 examples/drivebase_only/.run/Clean Build & Deploy Robot for Debugging.run.xml delete mode 100644 examples/drivebase_only/.run/Clean Build & Deploy Robot.run.xml delete mode 100644 examples/drivebase_only/.run/Clean Build Robot.run.xml delete mode 100644 examples/drivebase_only/.run/Clean.run.xml delete mode 100644 examples/drivebase_only/.run/Debug Robot via IP.run.xml delete mode 100644 examples/drivebase_only/.run/Debug Robot via USB.run.xml delete mode 100644 examples/drivebase_only/.styles/BroncBotzStyle.xml delete mode 100644 examples/drivebase_only/.vscode/launch.json delete mode 100644 examples/drivebase_only/.vscode/settings.json delete mode 100644 examples/drivebase_only/.wpilib/wpilib_preferences.json delete mode 100644 examples/drivebase_only/LICENSE.txt delete mode 100644 examples/drivebase_only/README.md delete mode 100644 examples/drivebase_only/build.gradle delete mode 100644 examples/drivebase_only/gradle/wrapper/gradle-wrapper.jar delete mode 100644 examples/drivebase_only/gradle/wrapper/gradle-wrapper.properties delete mode 100644 examples/drivebase_only/gradlew delete mode 100644 examples/drivebase_only/gradlew.bat delete mode 100644 examples/drivebase_only/networktables.json delete mode 100644 examples/drivebase_only/settings.gradle delete mode 100644 examples/drivebase_only/simgui.json delete mode 100644 examples/drivebase_only/src/main/deploy/example.txt delete mode 100644 examples/drivebase_only/src/main/deploy/pathplanner/SamplePath.path delete mode 100644 examples/drivebase_only/src/main/deploy/pathplanner/autos/New Auto.auto delete mode 100644 examples/drivebase_only/src/main/deploy/pathplanner/generatedJSON/New Path.wpilib.json delete mode 100644 examples/drivebase_only/src/main/deploy/pathplanner/generatedJSON/SamplePath.wpilib.json delete mode 100644 examples/drivebase_only/src/main/deploy/pathplanner/navgrid.json delete mode 100644 examples/drivebase_only/src/main/deploy/pathplanner/paths/New Path.path delete mode 100644 examples/drivebase_only/src/main/deploy/pathplanner/settings.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/falcon/controllerproperties.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/falcon/modules/backleft.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/falcon/modules/backright.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/falcon/modules/frontleft.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/falcon/modules/frontright.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/falcon/modules/physicalproperties.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/falcon/modules/pidfproperties.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/falcon/swervedrive.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/maxSwerve/controllerproperties.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/maxSwerve/modules/backleft.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/maxSwerve/modules/backright.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/maxSwerve/modules/frontleft.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/maxSwerve/modules/frontright.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/maxSwerve/modules/physicalproperties.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/maxSwerve/modules/pidfproperties.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/maxSwerve/swervedrive.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/neo/controllerproperties.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/neo/modules/backleft.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/neo/modules/backright.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/neo/modules/frontleft.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/neo/modules/frontright.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/neo/modules/physicalproperties.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/neo/modules/pidfproperties.json delete mode 100644 examples/drivebase_only/src/main/deploy/swerve/neo/swervedrive.json delete mode 100644 examples/drivebase_only/src/main/java/frc/robot/Constants.java delete mode 100644 examples/drivebase_only/src/main/java/frc/robot/Main.java delete mode 100644 examples/drivebase_only/src/main/java/frc/robot/Robot.java delete mode 100644 examples/drivebase_only/src/main/java/frc/robot/RobotContainer.java delete mode 100644 examples/drivebase_only/src/main/java/frc/robot/commands/swervedrive/auto/AutoBalanceCommand.java delete mode 100644 examples/drivebase_only/src/main/java/frc/robot/commands/swervedrive/drivebase/AbsoluteDrive.java delete mode 100644 examples/drivebase_only/src/main/java/frc/robot/commands/swervedrive/drivebase/AbsoluteDriveAdv.java delete mode 100644 examples/drivebase_only/src/main/java/frc/robot/commands/swervedrive/drivebase/AbsoluteFieldDrive.java delete mode 100644 examples/drivebase_only/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java delete mode 100644 examples/drivebase_only/vendordeps/REVLib.json delete mode 100644 examples/drivebase_only/vendordeps/Studica-2026.0.0-beta.json delete mode 100644 examples/drivebase_only/vendordeps/StudicaLib.json delete mode 100644 examples/drivebase_only/vendordeps/ThriftyLib.json delete mode 100644 examples/drivebase_only/vendordeps/WPILibNewCommands.json create mode 100644 examples/drivebase_only_2026/vendordeps/PathplannerLib-2026.1.2.json rename examples/drivebase_only_2026/vendordeps/{Phoenix5-replay-5.36.0-beta-1.json => Phoenix5-replay-5.36.0.json} (86%) delete mode 100644 examples/drivebase_only_2026/vendordeps/Phoenix6-replay-26.0.0-beta-1.json rename examples/{field_oriented_drivebase/vendordeps/Phoenix6-replay-26.0.0-beta-1.json => drivebase_only_2026/vendordeps/Phoenix6-replay-26.1.0.json} (83%) delete mode 100644 examples/drivebase_only_2026/vendordeps/Studica-2026.0.0-beta.json delete mode 100644 examples/drivebase_only_2026/vendordeps/StudicaLib.json delete mode 100644 examples/drivebase_only_2026/vendordeps/ThriftyLib.json create mode 100644 examples/field_oriented_drivebase/vendordeps/PathplannerLib-2026.1.2.json delete mode 100644 examples/field_oriented_drivebase/vendordeps/Phoenix5-replay-5.36.0-beta-1.json rename examples/{drivebase_only/vendordeps/Phoenix5-replay-5.36.0-beta-1.json => field_oriented_drivebase/vendordeps/Phoenix5-replay-5.36.0.json} (86%) rename examples/{drivebase_only/vendordeps/Phoenix6-replay-26.0.0-beta-1.json => field_oriented_drivebase/vendordeps/Phoenix6-replay-26.1.0.json} (83%) delete mode 100644 examples/field_oriented_drivebase/vendordeps/Studica-2026.0.0-beta.json delete mode 100644 examples/field_oriented_drivebase/vendordeps/StudicaLib.json delete mode 100644 examples/field_oriented_drivebase/vendordeps/ThriftyLib.json diff --git a/examples/drivebase_only/.gitignore b/examples/drivebase_only/.gitignore deleted file mode 100644 index 8300c07..0000000 --- a/examples/drivebase_only/.gitignore +++ /dev/null @@ -1,182 +0,0 @@ -# This gitignore has been specially created by the WPILib team. -# If you remove items from this file, intellisense might break. - -### C++ ### -# Prerequisites -*.d - -# Compiled Object files -*.slo -*.lo -*.o -*.obj - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod -*.smod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app - -### Java ### -# Compiled class file -*.class - -# Log file -*.log - -# BlueJ files -*.ctxt - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.nar -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* - -### Linux ### -*~ - -# temporary files which can be created if a process still has a handle open of a deleted file -.fuse_hidden* - -# KDE directory preferences -.directory - -# Linux trash folder which might appear on any partition or disk -.Trash-* - -# .nfs files are created when an open file is removed but is still being accessed -.nfs* - -### macOS ### -# General -.DS_Store -.AppleDouble -.LSOverride - -# Icon must end with two \r -Icon - -# Thumbnails -._* - -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns -.com.apple.timemachine.donotpresent - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk - -### VisualStudioCode ### -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json - -### Windows ### -# Windows thumbnail cache files -Thumbs.db -ehthumbs.db -ehthumbs_vista.db - -# Dump file -*.stackdump - -# Folder config file -[Dd]esktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msix -*.msm -*.msp - -# Windows shortcuts -*.lnk - -### Gradle ### -.gradle -/build/ - -# Ignore Gradle GUI config -gradle-app.setting - -# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) -!gradle-wrapper.jar - -# Cache of project -.gradletasknamecache - -# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 -# gradle/wrapper/gradle-wrapper.properties - -# # VS Code Specific Java Settings -# DO NOT REMOVE .classpath and .project -.classpath -.project -.settings/ -bin/ - -# IntelliJ -*.iml -*.ipr -*.iws -.idea/ -out/ - -# Fleet -.fleet - -# Simulation data log directory -logs/ - -simgui-window.json -simgui-ds.json - -# Folder that has CTRE Phoenix Sim device config storage -ctre_sim/ - -# clangd -/.cache -compile_commands.json diff --git a/examples/drivebase_only/.pathplanner/settings.json b/examples/drivebase_only/.pathplanner/settings.json deleted file mode 100644 index ca9c059..0000000 --- a/examples/drivebase_only/.pathplanner/settings.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "robotWidth": 0.9, - "robotLength": 0.9, - "holonomicMode": true, - "pathFolders": [ - "New Folder" - ], - "autoFolders": [], - "defaultMaxVel": 3.0, - "defaultMaxAccel": 3.0, - "defaultMaxAngVel": 540.0, - "defaultMaxAngAccel": 720.0, - "maxModuleSpeed": 4.5, - "choreoProjectPath": null -} \ No newline at end of file diff --git a/examples/drivebase_only/.run/Build & Deploy Robot for Debugging.run.xml b/examples/drivebase_only/.run/Build & Deploy Robot for Debugging.run.xml deleted file mode 100644 index f40df3e..0000000 --- a/examples/drivebase_only/.run/Build & Deploy Robot for Debugging.run.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - false - true - true - - - - - false - - - - false - true - true - - - - - false - - - \ No newline at end of file diff --git a/examples/drivebase_only/.run/Build & Deploy Robot.run.xml b/examples/drivebase_only/.run/Build & Deploy Robot.run.xml deleted file mode 100644 index 0464963..0000000 --- a/examples/drivebase_only/.run/Build & Deploy Robot.run.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - false - true - true - - - - - false - - - - false - true - true - - - - - false - - - \ No newline at end of file diff --git a/examples/drivebase_only/.run/Build Robot.run.xml b/examples/drivebase_only/.run/Build Robot.run.xml deleted file mode 100644 index 50099e3..0000000 --- a/examples/drivebase_only/.run/Build Robot.run.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - false - true - true - - - - - false - - - - false - true - true - - - - - false - - - \ No newline at end of file diff --git a/examples/drivebase_only/.run/Clean Build & Deploy Robot for Debugging.run.xml b/examples/drivebase_only/.run/Clean Build & Deploy Robot for Debugging.run.xml deleted file mode 100644 index 4b8585a..0000000 --- a/examples/drivebase_only/.run/Clean Build & Deploy Robot for Debugging.run.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - false - true - true - - - - - false - - - - false - true - true - - - - - false - - - \ No newline at end of file diff --git a/examples/drivebase_only/.run/Clean Build & Deploy Robot.run.xml b/examples/drivebase_only/.run/Clean Build & Deploy Robot.run.xml deleted file mode 100644 index 618aefd..0000000 --- a/examples/drivebase_only/.run/Clean Build & Deploy Robot.run.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - false - true - true - - - - - false - - - - false - true - true - - - - - false - - - \ No newline at end of file diff --git a/examples/drivebase_only/.run/Clean Build Robot.run.xml b/examples/drivebase_only/.run/Clean Build Robot.run.xml deleted file mode 100644 index f0dac4e..0000000 --- a/examples/drivebase_only/.run/Clean Build Robot.run.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - false - true - true - - - - - false - - - - false - true - true - - - - - false - - - \ No newline at end of file diff --git a/examples/drivebase_only/.run/Clean.run.xml b/examples/drivebase_only/.run/Clean.run.xml deleted file mode 100644 index b992246..0000000 --- a/examples/drivebase_only/.run/Clean.run.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - false - true - true - - - - - false - - - - false - true - true - - - - - false - - - \ No newline at end of file diff --git a/examples/drivebase_only/.run/Debug Robot via IP.run.xml b/examples/drivebase_only/.run/Debug Robot via IP.run.xml deleted file mode 100644 index c553ddb..0000000 --- a/examples/drivebase_only/.run/Debug Robot via IP.run.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - \ No newline at end of file diff --git a/examples/drivebase_only/.run/Debug Robot via USB.run.xml b/examples/drivebase_only/.run/Debug Robot via USB.run.xml deleted file mode 100644 index e6ff4b0..0000000 --- a/examples/drivebase_only/.run/Debug Robot via USB.run.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/examples/drivebase_only/.styles/BroncBotzStyle.xml b/examples/drivebase_only/.styles/BroncBotzStyle.xml deleted file mode 100644 index dab66c9..0000000 --- a/examples/drivebase_only/.styles/BroncBotzStyle.xml +++ /dev/null @@ -1,601 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- - - - xmlns:android - - ^$ - - - -
-
- - - - xmlns:.* - - ^$ - - - BY_NAME - -
-
- - - - .*:id - - http://schemas.android.com/apk/res/android - - - -
-
- - - - style - - ^$ - - - -
-
- - - - .* - - ^$ - - - BY_NAME - -
-
- - - - .*:.*Style - - http://schemas.android.com/apk/res/android - - - BY_NAME - -
-
- - - - .*:layout_width - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:layout_height - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:layout_weight - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:layout_margin - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:layout_marginTop - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:layout_marginBottom - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:layout_marginStart - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:layout_marginEnd - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:layout_marginLeft - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:layout_marginRight - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:layout_.* - - http://schemas.android.com/apk/res/android - - - BY_NAME - -
-
- - - - .*:padding - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:paddingTop - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:paddingBottom - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:paddingStart - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:paddingEnd - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:paddingLeft - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:paddingRight - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .* - http://schemas.android.com/apk/res/android - - - BY_NAME - -
-
- - - - .* - http://schemas.android.com/apk/res-auto - - - BY_NAME - -
-
- - - - .* - http://schemas.android.com/tools - - - BY_NAME - -
-
- - - - .* - .* - - - BY_NAME - -
- - - - - - -

* - * @param AVERAGE_DRIFTING_IN_30_SECS_MOTIONLESS_DEG the average amount of drift, in degrees, the gyro experiences - * if it remains motionless for 30 seconds on a vibrating platform. This value can often be found in the user - * manual. + * @param AVERAGE_DRIFTING_IN_30_SECS_MOTIONLESS_DEG the average amount of drift, in degrees, the gyro experiences + * if it remains motionless for 30 seconds on a vibrating platform. This value can often be found in the user + * manual. * @param VELOCITY_MEASUREMENT_STANDARD_DEVIATION_PERCENT the standard deviation of the velocity measurement, - * typically around 0.05 + * typically around 0.05 */ public GyroSimulation( double AVERAGE_DRIFTING_IN_30_SECS_MOTIONLESS_DEG, double VELOCITY_MEASUREMENT_STANDARD_DEVIATION_PERCENT) { @@ -115,12 +116,12 @@ public Rotation2d[] getCachedGyroReadings() { * *

This method updates the gyro simulation and should be called during every sub-tick of the simulation. * - *

If you are using this class outside of {@link SimulatedArena}: make sure to call it 5 + *

If you are using this class outside of {@link swervelib.simulation.ironmaple.simulation.SimulatedArena}: make sure to call it 5 * times in each robot period (if using default timings), or refer to - * {@link SimulatedArena#overrideSimulationTimings(Time, int)}. + * {@link swervelib.simulation.ironmaple.simulation.SimulatedArena#overrideSimulationTimings(Time, int)}. * * @param actualAngularVelocityRadPerSec the actual angular velocity in radians per second, usually obtained from - * {@link AbstractDriveTrainSimulation#getAngularVelocity()} + * {@link AbstractDriveTrainSimulation#getAngularVelocity()} */ public void updateSimulationSubTick(double actualAngularVelocityRadPerSec) { final Rotation2d driftingDueToImpact = getDriftingDueToImpact(actualAngularVelocityRadPerSec); @@ -145,20 +146,20 @@ public void updateSimulationSubTick(double actualAngularVelocityRadPerSec) { * exceeds a threshold, simulating the effects of impacts on the robot. * * @param actualAngularVelocityRadPerSec the actual angular velocity in radians per second, used to determine if an - * impact is detected + * impact is detected * @return the amount of drifting the IMU will experience if an impact is detected, or - * Rotation2d.fromRadians(0) if no impact is detected + * Rotation2d.fromRadians(0) if no impact is detected */ private Rotation2d getDriftingDueToImpact(double actualAngularVelocityRadPerSec) { final double angularAccelerationRadPerSecSq = - (actualAngularVelocityRadPerSec - previousAngularVelocityRadPerSec) - / SimulatedArena.getSimulationDt().in(Seconds), + (actualAngularVelocityRadPerSec - previousAngularVelocityRadPerSec) + / SimulatedArena.getSimulationDt().in(Seconds), driftingDueToImpactDegAbsVal = Math.abs(angularAccelerationRadPerSecSq) > ANGULAR_ACCELERATION_THRESHOLD_START_DRIFTING ? Math.abs(angularAccelerationRadPerSecSq) - / ANGULAR_ACCELERATION_THRESHOLD_START_DRIFTING - * DRIFT_DUE_TO_IMPACT_COEFFICIENT + / ANGULAR_ACCELERATION_THRESHOLD_START_DRIFTING + * DRIFT_DUE_TO_IMPACT_COEFFICIENT : 0, driftingDueToImpactDeg = Math.copySign(driftingDueToImpactDegAbsVal, -angularAccelerationRadPerSecSq); @@ -178,7 +179,7 @@ private Rotation2d getDriftingDueToImpact(double actualAngularVelocityRadPerSec) *

The measurement includes random errors based on the configuration of the gyro. * * @param actualAngularVelocityRadPerSec the actual angular velocity in radians per second, used to calculate the - * ΔTheta + * ΔTheta * @return the measured ΔTheta, including any measurement errors */ private Rotation2d getGyroDTheta(double actualAngularVelocityRadPerSec) { @@ -202,9 +203,9 @@ private Rotation2d getGyroDTheta(double actualAngularVelocityRadPerSec) { private Rotation2d getNoMotionDrifting() { final double AVERAGE_DRIFTING_1_PERIOD = - this.AVERAGE_DRIFTING_IN_30_SECS_MOTIONLESS_DEG - / 30 - * SimulatedArena.getSimulationDt().in(Seconds), + this.AVERAGE_DRIFTING_IN_30_SECS_MOTIONLESS_DEG + / 30 + * SimulatedArena.getSimulationDt().in(Seconds), driftingInThisPeriod = MapleCommonMath.generateRandomNormal(0, AVERAGE_DRIFTING_1_PERIOD); return Rotation2d.fromDegrees(driftingInThisPeriod); diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SelfControlledSwerveDriveSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SelfControlledSwerveDriveSimulation.java index 906c96d..d0d4344 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SelfControlledSwerveDriveSimulation.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SelfControlledSwerveDriveSimulation.java @@ -1,7 +1,5 @@ package swervelib.simulation.ironmaple.simulation.drivesims; -import static edu.wpi.first.units.Units.*; - import edu.wpi.first.math.Matrix; import edu.wpi.first.math.VecBuilder; import edu.wpi.first.math.controller.PIDController; @@ -9,17 +7,23 @@ 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.kinematics.*; +import edu.wpi.first.math.kinematics.ChassisSpeeds; +import edu.wpi.first.math.kinematics.SwerveDriveKinematics; +import edu.wpi.first.math.kinematics.SwerveModulePosition; +import edu.wpi.first.math.kinematics.SwerveModuleState; import edu.wpi.first.math.numbers.N1; import edu.wpi.first.math.numbers.N3; import edu.wpi.first.units.measure.*; import edu.wpi.first.wpilibj.Timer; -import java.util.Arrays; import swervelib.simulation.ironmaple.simulation.SimulatedArena; import swervelib.simulation.ironmaple.simulation.drivesims.configs.DriveTrainSimulationConfig; import swervelib.simulation.ironmaple.simulation.motorsims.SimulatedMotorController; import swervelib.simulation.ironmaple.utils.mathutils.SwerveStateProjection; +import java.util.Arrays; + +import static edu.wpi.first.units.Units.*; + /** * * @@ -66,8 +70,8 @@ public SelfControlledSwerveDriveSimulation(SwerveDriveSimulation swerveDriveSimu *

Constructs a simplified swerve simulation with specified standard deviations for odometry & vision pose * estimates. * - * @param swerveDriveSimulation the {@link SwerveDriveSimulation} to control. - * @param stateStdDevs the standard deviations for odometry encoders. + * @param swerveDriveSimulation the {@link SwerveDriveSimulation} to control. + * @param stateStdDevs the standard deviations for odometry encoders. * @param visionMeasurementStdDevs the standard deviations for vision pose estimates. */ public SelfControlledSwerveDriveSimulation( @@ -108,7 +112,7 @@ public void periodic() { poseEstimator.updateWithTime( Timer.getFPGATimestamp() - SimulatedArena.getSimulationDt().in(Seconds) - * (SimulatedArena.getSimulationDt().in(Seconds) - i), + * (SimulatedArena.getSimulationDt().in(Seconds) - i), swerveDriveSimulation.gyroSimulation.getCachedGyroReadings()[i], cachedModulePositions[i]); } @@ -172,9 +176,9 @@ public SwerveModulePosition[][] getCachedModulePositions() { *

To obtain the facing of the robot retrieved from the odometry, use {@link #getOdometryEstimatedPose()}; to * obtain the actual facing of the robot, use {@link #getActualPoseInSimulationWorld()}. * - * @deprecated This rotation is NOT the actual facing of the robot; it is uncalibrated and is only - * used for features like rotation lock. * @return the raw (uncalibrated) angle of the simulated gyro. + * @deprecated This rotation is NOT the actual facing of the robot; it is uncalibrated and is only + * used for features like rotation lock. */ @Deprecated public Rotation2d getRawGyroAngle() { @@ -228,7 +232,7 @@ public void resetOdometry(Pose2d pose) { *

Adds a vision measurement to the Kalman Filter, correcting the odometry pose estimate while accounting for * measurement noise. * - * @param robotPoseMeters The pose of the robot as measured by the vision camera. + * @param robotPoseMeters The pose of the robot as measured by the vision camera. * @param timeStampSeconds The timestamp of the vision measurement, in seconds. */ public void addVisionEstimation(Pose2d robotPoseMeters, double timeStampSeconds) { @@ -245,10 +249,10 @@ public void addVisionEstimation(Pose2d robotPoseMeters, double timeStampSeconds) *

Adds a vision measurement to the Kalman Filter, correcting the odometry pose estimate while accounting for * measurement noise. * - * @param robotPoseMeters The pose of the robot as measured by the vision camera. - * @param timeStampSeconds The timestamp of the vision measurement, in seconds. + * @param robotPoseMeters The pose of the robot as measured by the vision camera. + * @param timeStampSeconds The timestamp of the vision measurement, in seconds. * @param measurementStdDevs Standard deviations of the vision pose measurement (x position in meters, y position in - * meters, and heading in radians). Increase these values to reduce the trust in the vision pose measurement. + * meters, and heading in radians). Increase these values to reduce the trust in the vision pose measurement. */ public void addVisionEstimation( Pose2d robotPoseMeters, double timeStampSeconds, Matrix measurementStdDevs) { @@ -262,13 +266,13 @@ public void addVisionEstimation( * *

Runs the specified chassis speeds, either robot-centric or field-centric. * - * @param chassisSpeeds The speeds to run, in either robot-centric or field-centric coordinates. + * @param chassisSpeeds The speeds to run, in either robot-centric or field-centric coordinates. * @param centerOfRotationMeters The center of rotation. For example, if you set the center of rotation at one - * corner of the robot and provide a chassis speed that has only a dtheta component, the robot will rotate - * around that corner. - * @param fieldCentricDrive Whether to execute field-centric drive with the provided speed. - * @param discretizeSpeeds Whether to apply {@link ChassisSpeeds#discretize(ChassisSpeeds, double)} to the provided - * speed. + * corner of the robot and provide a chassis speed that has only a dtheta component, the robot will rotate + * around that corner. + * @param fieldCentricDrive Whether to execute field-centric drive with the provided speed. + * @param discretizeSpeeds Whether to apply {@link ChassisSpeeds#discretize(ChassisSpeeds, double)} to the provided + * speed. */ public void runChassisSpeeds( ChassisSpeeds chassisSpeeds, @@ -369,9 +373,9 @@ public ChassisSpeeds getMeasuredSpeedsRobotRelative(boolean useGyroForAngularVel swerveSpeeds.vyMetersPerSecond, useGyroForAngularVelocity ? swerveDriveSimulation - .gyroSimulation - .getMeasuredAngularVelocity() - .in(RadiansPerSecond) + .gyroSimulation + .getMeasuredAngularVelocity() + .in(RadiansPerSecond) : swerveSpeeds.omegaRadiansPerSecond); } @@ -542,38 +546,52 @@ public SwerveModulePosition getModulePosition() { } } - /** @see SwerveDriveSimulation#maxLinearVelocity() */ + /** + * @see SwerveDriveSimulation#maxLinearVelocity() + */ public LinearVelocity maxLinearVelocity() { return swerveDriveSimulation.maxLinearVelocity(); } - /** @see SwerveDriveSimulation#maxLinearAcceleration(Current) */ + /** + * @see SwerveDriveSimulation#maxLinearAcceleration(Current) + */ public LinearAcceleration maxLinearAcceleration() { return swerveDriveSimulation.maxLinearAcceleration(moduleSimulations[0].driveCurrentLimit); } - /** @see DriveTrainSimulationConfig#trackWidthY() */ + /** + * @see DriveTrainSimulationConfig#trackWidthY() + */ public Distance trackWidthY() { return swerveDriveSimulation.config.trackWidthY(); } - /** @see DriveTrainSimulationConfig#trackLengthX() */ + /** + * @see DriveTrainSimulationConfig#trackLengthX() + */ public Distance trackLengthX() { return swerveDriveSimulation.config.trackLengthX(); } - /** @see SwerveDriveSimulation#driveBaseRadius() */ + /** + * @see SwerveDriveSimulation#driveBaseRadius() + */ public Distance driveBaseRadius() { return swerveDriveSimulation.config.driveBaseRadius(); } - /** @see SwerveDriveSimulation#maxAngularVelocity() */ + /** + * @see SwerveDriveSimulation#maxAngularVelocity() + */ public AngularVelocity maxAngularVelocity() { return RadiansPerSecond.of( maxLinearVelocity().in(MetersPerSecond) / driveBaseRadius().in(Meters)); } - /** @see SwerveDriveSimulation#maxAngularAcceleration(Current) */ + /** + * @see SwerveDriveSimulation#maxAngularAcceleration(Current) + */ public AngularAcceleration maxAngularAcceleration() { return swerveDriveSimulation.maxAngularAcceleration(moduleSimulations[0].driveCurrentLimit); } diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SwerveDriveSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SwerveDriveSimulation.java index 6af5bc6..2ee420a 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SwerveDriveSimulation.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SwerveDriveSimulation.java @@ -1,7 +1,5 @@ package swervelib.simulation.ironmaple.simulation.drivesims; -import static edu.wpi.first.units.Units.*; - import edu.wpi.first.math.geometry.Pose2d; import edu.wpi.first.math.geometry.Rotation2d; import edu.wpi.first.math.geometry.Translation2d; @@ -9,14 +7,16 @@ import edu.wpi.first.math.kinematics.SwerveDriveKinematics; import edu.wpi.first.math.kinematics.SwerveModuleState; import edu.wpi.first.units.measure.*; -import java.util.Arrays; -import java.util.function.Supplier; import org.dyn4j.geometry.Vector2; import swervelib.simulation.ironmaple.simulation.SimulatedArena; import swervelib.simulation.ironmaple.simulation.drivesims.configs.DriveTrainSimulationConfig; import swervelib.simulation.ironmaple.utils.mathutils.GeometryConvertor; import swervelib.simulation.ironmaple.utils.mathutils.MapleCommonMath; -import swervelib.simulation.ironmaple.simulation.drivesims.configs.SwerveModuleSimulationConfig; + +import java.util.Arrays; +import java.util.function.Supplier; + +import static edu.wpi.first.units.Units.*; /** * @@ -80,9 +80,9 @@ public class SwerveDriveSimulation extends AbstractDriveTrainSimulation { *

This constructor initializes a swerve drive simulation with the given robot mass, bumper dimensions, module * simulations, module translations, gyro simulation, and initial pose on the field. * - * @param config a {@link DriveTrainSimulationConfig} instance containing the configurations of * this drivetrain + * @param config a {@link DriveTrainSimulationConfig} instance containing the configurations of * this drivetrain * @param initialPoseOnField the initial pose of the drivetrain in the simulation world, represented as a - * {@link Pose2d} + * {@link Pose2d} */ public SwerveDriveSimulation(DriveTrainSimulationConfig config, Pose2d initialPoseOnField) { super(config, initialPoseOnField); @@ -152,8 +152,8 @@ private void simulateChassisFrictionForce() { final ChassisSpeeds differenceBetweenFloorSpeedAndModuleSpeedsRobotRelative = moduleSpeeds.minus(getDriveTrainSimulatedChassisSpeedsRobotRelative()); final Translation2d floorAndModuleSpeedsDiffFieldRelative = new Translation2d( - differenceBetweenFloorSpeedAndModuleSpeedsRobotRelative.vxMetersPerSecond, - differenceBetweenFloorSpeedAndModuleSpeedsRobotRelative.vyMetersPerSecond) + differenceBetweenFloorSpeedAndModuleSpeedsRobotRelative.vxMetersPerSecond, + differenceBetweenFloorSpeedAndModuleSpeedsRobotRelative.vyMetersPerSecond) .rotateBy(getSimulatedDriveTrainPose().getRotation()); final double FRICTION_FORCE_GAIN = 3.0, totalGrippingForce = @@ -207,8 +207,8 @@ private void simulateChassisFrictionForce() { private void simulateChassisFrictionTorque() { final double desiredRotationalMotionPercent = - Math.abs(getDesiredSpeed().omegaRadiansPerSecond - / maxAngularVelocity().in(RadiansPerSecond)), + Math.abs(getDesiredSpeed().omegaRadiansPerSecond + / maxAngularVelocity().in(RadiansPerSecond)), actualRotationalMotionPercent = Math.abs(getAngularVelocity() / maxAngularVelocity().in(RadiansPerSecond)), differenceBetweenFloorSpeedAndModuleSpeed = @@ -249,12 +249,12 @@ private void simulateChassisFrictionTorque() { *

The total friction force should not exceed the tire's grip limit. */ private void simulateModulePropellingForces() { - for (int i = 0; i < moduleSimulations.length; i++) { + final int arrayLength = moduleSimulations.length; // Call it once + final Rotation2d driveRotation = getSimulatedDriveTrainPose().getRotation(); // Call it once per 4 modules. + for (int i = 0; i < arrayLength; i++) { final Vector2 moduleWorldPosition = getWorldPoint(GeometryConvertor.toDyn4jVector2(moduleTranslations[i])); final Vector2 moduleForce = moduleSimulations[i].updateSimulationSubTickGetModuleForce( - super.getLinearVelocity(moduleWorldPosition), - getSimulatedDriveTrainPose().getRotation(), - gravityForceOnEachModule); + super.getLinearVelocity(moduleWorldPosition), driveRotation, gravityForceOnEachModule); super.applyForce(moduleForce, moduleWorldPosition); } } @@ -298,7 +298,7 @@ private ChassisSpeeds getModuleSpeeds() { *

Obtains the maximum achievable linear velocity of the chassis.

* * @return the maximum linear velocity - * @see SwerveModuleSimulationConfig#maximumGroundSpeed() + * @see swervelib.simulation.ironmaple.simulation.drivesims.configs.SwerveModuleSimulationConfig#maximumGroundSpeed() */ public LinearVelocity maxLinearVelocity() { return moduleSimulations[0].config.maximumGroundSpeed(); @@ -310,7 +310,7 @@ public LinearVelocity maxLinearVelocity() { *

Obtains the maximum achievable linear acceleration of the chassis.

* * @return the maximum linear acceleration - * @see SwerveModuleSimulationConfig#maxAcceleration(Mass, int, Current) + * @see swervelib.simulation.ironmaple.simulation.drivesims.configs.SwerveModuleSimulationConfig#maxAcceleration(Mass, int, Current) */ public LinearAcceleration maxLinearAcceleration(Current statorCurrentLimit) { return moduleSimulations[0].config.maxAcceleration( @@ -349,10 +349,10 @@ public AngularVelocity maxAngularVelocity() { */ public AngularAcceleration maxAngularAcceleration(Current statorCurrentLimit) { return RadiansPerSecondPerSecond.of(moduleSimulations[0] - .config - .getTheoreticalPropellingForcePerModule( - config.robotMass, moduleSimulations.length, statorCurrentLimit) - .in(Newtons) + .config + .getTheoreticalPropellingForcePerModule( + config.robotMass, moduleSimulations.length, statorCurrentLimit) + .in(Newtons) * moduleTranslations[0].getNorm() * moduleSimulations.length / super.getMass().getInertia()); diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SwerveModuleSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SwerveModuleSimulation.java index a8d1d46..2c8201d 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SwerveModuleSimulation.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/SwerveModuleSimulation.java @@ -1,14 +1,10 @@ package swervelib.simulation.ironmaple.simulation.drivesims; -import static edu.wpi.first.units.Units.*; - import edu.wpi.first.math.MathUtil; import edu.wpi.first.math.geometry.Rotation2d; import edu.wpi.first.math.kinematics.SwerveDriveOdometry; import edu.wpi.first.math.kinematics.SwerveModuleState; import edu.wpi.first.units.measure.*; -import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; import org.dyn4j.geometry.Vector2; import swervelib.simulation.ironmaple.simulation.SimulatedArena; import swervelib.simulation.ironmaple.simulation.drivesims.configs.SwerveModuleSimulationConfig; @@ -17,6 +13,11 @@ import swervelib.simulation.ironmaple.simulation.motorsims.SimulatedBattery; import swervelib.simulation.ironmaple.simulation.motorsims.SimulatedMotorController; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; + +import static edu.wpi.first.units.Units.*; + /** * * @@ -153,8 +154,8 @@ public SimulatedMotorController.GenericMotorController useGenericControllerForSt *

Note: Friction forces are not simulated in this method. * * @param moduleCurrentGroundVelocityWorldRelative the current ground velocity of the module, relative to the world - * @param robotFacing the absolute facing of the robot, relative to the world - * @param gravityForceOnModuleNewtons the gravitational force acting on this module, in newtons + * @param robotFacing the absolute facing of the robot, relative to the world + * @param gravityForceOnModuleNewtons the gravitational force acting on this module, in newtons * @return the propelling force generated by the module, as a {@link Vector2} object */ public Vector2 updateSimulationSubTickGetModuleForce( @@ -187,35 +188,35 @@ public Vector2 updateSimulationSubTickGetModuleForce( *

However, if the propelling force exceeds the gripping, only the max gripping force is applied. The rest of the * propelling force will cause the wheel to start skidding and make the odometry inaccurate. * - * @param grippingForceNewtons the amount of gripping force that wheel can generate, in newtons - * @param moduleWorldFacing the current world facing of the module + * @param grippingForceNewtons the amount of gripping force that wheel can generate, in newtons + * @param moduleWorldFacing the current world facing of the module * @param moduleCurrentGroundVelocity the current ground velocity of the module, world-reference * @return a vector representing the propelling force that the module generates, world-reference */ private Vector2 getPropellingForce( double grippingForceNewtons, Rotation2d moduleWorldFacing, Vector2 moduleCurrentGroundVelocity) { final double driveWheelTorque = getDriveWheelTorque(); - double propellingForceNewtons = driveWheelTorque / config.WHEEL_RADIUS.in(Meters); + final double wheelRadius = config.WHEEL_RADIUS.in(Meters); // Call it once + double propellingForceNewtons = driveWheelTorque / wheelRadius; final boolean skidding = Math.abs(propellingForceNewtons) > grippingForceNewtons; if (skidding) propellingForceNewtons = Math.copySign(grippingForceNewtons, propellingForceNewtons); + final double moduleAngleRadians = moduleWorldFacing.getRadians(); // Call it once final double floorVelocityProjectionOnWheelDirectionMPS = moduleCurrentGroundVelocity.getMagnitude() - * Math.cos(moduleCurrentGroundVelocity.getAngleBetween(new Vector2(moduleWorldFacing.getRadians()))); + * Math.cos(moduleCurrentGroundVelocity.getAngleBetween(moduleAngleRadians)); // if the chassis is tightly gripped on floor, the floor velocity is projected to the wheel - this.driveWheelFinalSpeed = - RadiansPerSecond.of(floorVelocityProjectionOnWheelDirectionMPS / config.WHEEL_RADIUS.in(Meters)); + this.driveWheelFinalSpeed = RadiansPerSecond.of(floorVelocityProjectionOnWheelDirectionMPS / wheelRadius); // if the module is skidding if (skidding) { final AngularVelocity skiddingEquilibriumWheelSpeed = config.driveMotorConfigs.calculateMechanismVelocity( - config.driveMotorConfigs.calculateCurrent( - NewtonMeters.of(propellingForceNewtons * config.WHEEL_RADIUS.in(Meters))), + config.driveMotorConfigs.calculateCurrent(NewtonMeters.of(propellingForceNewtons * wheelRadius)), driveMotorAppliedVoltage); this.driveWheelFinalSpeed = driveWheelFinalSpeed.times(0.5).plus(skiddingEquilibriumWheelSpeed.times(0.5)); } - return Vector2.create(propellingForceNewtons, moduleWorldFacing.getRadians()); + return Vector2.create(propellingForceNewtons, moduleAngleRadians); } /** @@ -249,7 +250,9 @@ private double getDriveWheelTorque() { return driveWheelTorqueWithFriction.in(NewtonMeters); } - /** @return the current module state of this simulation module */ + /** + * @return the current module state of this simulation module + */ public SwerveModuleState getCurrentState() { return new SwerveModuleState( MetersPerSecond.of(getDriveWheelFinalSpeed().in(RadiansPerSecond) * config.WHEEL_RADIUS.in(Meters)), @@ -269,10 +272,10 @@ public SwerveModuleState getCurrentState() { protected SwerveModuleState getFreeSpinState() { return new SwerveModuleState( config.driveMotorConfigs - .calculateMechanismVelocity( - config.driveMotorConfigs.calculateCurrent(config.driveMotorConfigs.friction), - driveMotorAppliedVoltage) - .in(RadiansPerSecond) + .calculateMechanismVelocity( + config.driveMotorConfigs.calculateCurrent(config.driveMotorConfigs.friction), + driveMotorAppliedVoltage) + .in(RadiansPerSecond) * config.WHEEL_RADIUS.in(Meters), getSteerAbsoluteFacing()); } diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/configs/DriveTrainSimulationConfig.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/configs/DriveTrainSimulationConfig.java index 5bf369c..0ba1274 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/configs/DriveTrainSimulationConfig.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/configs/DriveTrainSimulationConfig.java @@ -1,19 +1,20 @@ package swervelib.simulation.ironmaple.simulation.drivesims.configs; -import static edu.wpi.first.units.Units.Kilograms; -import static edu.wpi.first.units.Units.Meters; - import edu.wpi.first.math.geometry.Translation2d; import edu.wpi.first.math.system.plant.DCMotor; import edu.wpi.first.units.measure.Distance; import edu.wpi.first.units.measure.Mass; -import java.util.Arrays; -import java.util.OptionalDouble; -import java.util.function.Supplier; import swervelib.simulation.ironmaple.simulation.drivesims.COTS; import swervelib.simulation.ironmaple.simulation.drivesims.GyroSimulation; import swervelib.simulation.ironmaple.simulation.drivesims.SwerveModuleSimulation; +import java.util.Arrays; +import java.util.OptionalDouble; +import java.util.function.Supplier; + +import static edu.wpi.first.units.Units.Kilograms; +import static edu.wpi.first.units.Units.Meters; + /** * * @@ -36,15 +37,15 @@ public class DriveTrainSimulationConfig { * *

Creates an instance of {@link DriveTrainSimulationConfig} with specified parameters. * - * @param robotMass the mass of the robot, including bumpers. - * @param bumperLengthX the length of the bumper (distance from front to back). - * @param bumperWidthY the width of the bumper (distance from left to right). - * @param trackLengthX the distance between the front and rear wheels. - * @param trackWidthY the distance between the left and right wheels. + * @param robotMass the mass of the robot, including bumpers. + * @param bumperLengthX the length of the bumper (distance from front to back). + * @param bumperWidthY the width of the bumper (distance from left to right). + * @param trackLengthX the distance between the front and rear wheels. + * @param trackWidthY the distance between the left and right wheels. * @param swerveModuleSimulationFactory the factory that creates appropriate swerve module simulation for the - * drivetrain. You can specify one factory to apply the same configuration over all modules or specify four - * factories in the order (FL, FR, BL, BR). - * @param gyroSimulationFactory the factory that creates appropriate gyro simulation for the drivetrain. + * drivetrain. You can specify one factory to apply the same configuration over all modules or specify four + * factories in the order (FL, FR, BL, BR). + * @param gyroSimulationFactory the factory that creates appropriate gyro simulation for the drivetrain. */ public DriveTrainSimulationConfig( Mass robotMass, @@ -128,7 +129,7 @@ public DriveTrainSimulationConfig withRobotMass(Mass robotMass) { *

Updates the dimensions of the bumper. * * @param bumperLengthX the length of the bumper. - * @param bumperWidthY the width of the bumper. + * @param bumperWidthY the width of the bumper. * @return the current instance of {@link DriveTrainSimulationConfig} for method chaining. */ public DriveTrainSimulationConfig withBumperSize(Distance bumperLengthX, Distance bumperWidthY) { @@ -149,18 +150,18 @@ public DriveTrainSimulationConfig withBumperSize(Distance bumperLengthX, Distanc *

For non-rectangular chassis configuration, use {@link #withCustomModuleTranslations(Translation2d[])} instead. * * @param trackLengthX the distance between the front and rear wheels. - * @param trackWidthY the distance between the left and right wheels. + * @param trackWidthY the distance between the left and right wheels. * @return the current instance of {@link DriveTrainSimulationConfig} for method chaining. */ public DriveTrainSimulationConfig withTrackLengthTrackWidth(Distance trackLengthX, Distance trackWidthY) { BoundingCheck.check(trackLengthX.in(Meters), 0.5, 1.5, "track length", "meters"); BoundingCheck.check(trackWidthY.in(Meters), 0.5, 1.5, "track width", "meters"); - this.moduleTranslations = new Translation2d[] { - new Translation2d(trackLengthX.in(Meters) / 2, trackWidthY.in(Meters) / 2), - new Translation2d(trackLengthX.in(Meters) / 2, -trackWidthY.in(Meters) / 2), - new Translation2d(-trackLengthX.in(Meters) / 2, trackWidthY.in(Meters) / 2), - new Translation2d(-trackLengthX.in(Meters) / 2, -trackWidthY.in(Meters) / 2) + this.moduleTranslations = new Translation2d[]{ + new Translation2d(trackLengthX.in(Meters) / 2, trackWidthY.in(Meters) / 2), + new Translation2d(trackLengthX.in(Meters) / 2, -trackWidthY.in(Meters) / 2), + new Translation2d(-trackLengthX.in(Meters) / 2, trackWidthY.in(Meters) / 2), + new Translation2d(-trackLengthX.in(Meters) / 2, -trackWidthY.in(Meters) / 2) }; return this; } @@ -192,8 +193,8 @@ public DriveTrainSimulationConfig withCustomModuleTranslations(Translation2d[] m *

Updates the factory used to create swerve module simulations. * * @param swerveModuleSimulationFactory the new factory (or factories) for swerve module simulations. You can - * specify one factory to apply the same configuration over all modules, or specify four factories in the order - * (FL, FR, BL, BR) + * specify one factory to apply the same configuration over all modules, or specify four factories in the order + * (FL, FR, BL, BR) * @return the current instance of {@link DriveTrainSimulationConfig} for method chaining. */ public DriveTrainSimulationConfig withSwerveModules( diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/configs/SwerveModuleSimulationConfig.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/configs/SwerveModuleSimulationConfig.java index bd898a6..4fb958c 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/configs/SwerveModuleSimulationConfig.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/drivesims/configs/SwerveModuleSimulationConfig.java @@ -1,15 +1,16 @@ package swervelib.simulation.ironmaple.simulation.drivesims.configs; -import static edu.wpi.first.units.Units.*; - import edu.wpi.first.math.system.plant.DCMotor; import edu.wpi.first.math.util.Units; import edu.wpi.first.units.measure.*; -import java.util.function.Supplier; import swervelib.simulation.ironmaple.simulation.SimulatedArena; import swervelib.simulation.ironmaple.simulation.drivesims.SwerveModuleSimulation; import swervelib.simulation.ironmaple.simulation.motorsims.SimMotorConfigs; +import java.util.function.Supplier; + +import static edu.wpi.first.units.Units.*; + public class SwerveModuleSimulationConfig implements Supplier { public final SimMotorConfigs driveMotorConfigs, steerMotorConfigs; public final double DRIVE_GEAR_RATIO, STEER_GEAR_RATIO, WHEELS_COEFFICIENT_OF_FRICTION; @@ -24,17 +25,17 @@ public class SwerveModuleSimulationConfig implements SupplierIf you are using {@link SimulatedArena#overrideSimulationTimings(Time, int)} to use custom timings, you must * call the method before constructing any swerve module simulations using this constructor. * - * @param driveMotorModel the model of the driving motor - * @param steerMotorModel; the model of the steering motor - * @param driveGearRatio the gear ratio for the driving motor, >1 is reduction - * @param steerGearRatio the gear ratio for the steering motor, >1 is reduction - * @param driveFrictionVoltage the measured minimum amount of voltage that can turn the driving rotter - * @param steerFrictionVoltage the measured minimum amount of voltage that can turn the steering rotter - * @param wheelRadius the radius of the wheels. - * @param steerRotationalInertia the rotational inertia of the entire steering mechanism + * @param driveMotorModel the model of the driving motor + * @param steerMotorModel; the model of the steering motor + * @param driveGearRatio the gear ratio for the driving motor, >1 is reduction + * @param steerGearRatio the gear ratio for the steering motor, >1 is reduction + * @param driveFrictionVoltage the measured minimum amount of voltage that can turn the driving rotter + * @param steerFrictionVoltage the measured minimum amount of voltage that can turn the steering rotter + * @param wheelRadius the radius of the wheels. + * @param steerRotationalInertia the rotational inertia of the entire steering mechanism * @param wheelsCoefficientOfFriction the coefficient - * of friction of the tires, normally around 1.2 {@link Units#inchesToMeters(double)}. + * href='https://simple.wikipedia.org/wiki/Coefficient_of_friction#:~:text=A%20coefficient%20of%20friction%20is%20a%20value%20that%20shows%20the'>coefficient + * of friction of the tires, normally around 1.2 {@link Units#inchesToMeters(double)}. */ public SwerveModuleSimulationConfig( DCMotor driveMotorModel, @@ -95,15 +96,15 @@ public LinearVelocity maximumGroundSpeed() { *

Calculates the maximum propelling force with respect to the gripping force and the drive motor's torque under * its current limit. * - * @param robotMass the mass of the robot + * @param robotMass the mass of the robot * @param modulesCount the amount of modules on the robot, assumed to be sharing the gravity force equally * @return the maximum propelling force of EACH module */ public Force getTheoreticalPropellingForcePerModule(Mass robotMass, int modulesCount, Current statorCurrentLimit) { final double maxThrustNewtons = - driveMotorConfigs.calculateTorque(statorCurrentLimit).in(NewtonMeters) - / WHEEL_RADIUS.in(Meters), + driveMotorConfigs.calculateTorque(statorCurrentLimit).in(NewtonMeters) + / WHEEL_RADIUS.in(Meters), maxGrippingNewtons = 9.8 * robotMass.in(Kilograms) / modulesCount * WHEELS_COEFFICIENT_OF_FRICTION; return Newtons.of(Math.min(maxThrustNewtons, maxGrippingNewtons)); @@ -117,7 +118,7 @@ public Force getTheoreticalPropellingForcePerModule(Mass robotMass, int modulesC *

Calculates the maximum linear acceleration of a robot, with respect to its mass and * {@link #getTheoreticalPropellingForcePerModule(Mass, int, Current)}. * - * @param robotMass the mass of the robot + * @param robotMass the mass of the robot * @param modulesCount the amount of modules on the robot, assumed to be sharing the gravity force equally */ public LinearAcceleration maxAcceleration(Mass robotMass, int modulesCount, Current statorCurrentLimit) { diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePiece.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePiece.java index ea9e69c..68cb93d 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePiece.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePiece.java @@ -35,7 +35,7 @@ public interface GamePiece { * * *

Gives the velocity of the game piece.

- * + *

* For grounded game pieces the z access velocity does not exist and so will be set to 0 automatically. * * @return The velocity of the game piece as a Translation3d. @@ -46,7 +46,7 @@ public interface GamePiece { * * *

Gives wether or not the piece is "grounded".

- * + *

* A grounded piece is likely a child of {@link GamePieceOnFieldSimulation} while a non grounded piece is likely a * child of{@link GamePieceProjectile}. * diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceOnFieldSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceOnFieldSimulation.java index 58f0104..9c94425 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceOnFieldSimulation.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceOnFieldSimulation.java @@ -1,17 +1,9 @@ package swervelib.simulation.ironmaple.simulation.gamepieces; -import static edu.wpi.first.units.Units.Kilogram; -import static edu.wpi.first.units.Units.Meters; - -import edu.wpi.first.math.geometry.Pose2d; -import edu.wpi.first.math.geometry.Pose3d; -import edu.wpi.first.math.geometry.Rotation3d; -import edu.wpi.first.math.geometry.Translation2d; -import edu.wpi.first.math.geometry.Translation3d; +import edu.wpi.first.math.geometry.*; import edu.wpi.first.math.kinematics.ChassisSpeeds; import edu.wpi.first.units.measure.Distance; import edu.wpi.first.units.measure.Mass; -import java.util.function.DoubleSupplier; import org.dyn4j.dynamics.Body; import org.dyn4j.dynamics.BodyFixture; import org.dyn4j.geometry.Convex; @@ -20,6 +12,11 @@ import swervelib.simulation.ironmaple.simulation.SimulatedArena; import swervelib.simulation.ironmaple.utils.mathutils.GeometryConvertor; +import java.util.function.DoubleSupplier; + +import static edu.wpi.first.units.Units.Kilogram; +import static edu.wpi.first.units.Units.Meters; + /** * * @@ -30,7 +27,7 @@ *

Game pieces can be "grabbed" by an {@link IntakeSimulation}. * *

For the simulation to actually run, every instance must be added to a - * {@link SimulatedArena} through + * {@link swervelib.simulation.ironmaple.simulation.SimulatedArena} through * {@link SimulatedArena#addGamePiece(GamePieceOnFieldSimulation)}. */ public class GamePieceOnFieldSimulation extends Body implements GamePiece { @@ -60,7 +57,7 @@ public class GamePieceOnFieldSimulation extends Body implements GamePiece { * *

Creates a Game Piece on the Field with Fixed Height.

* - * @param info info about the game piece type + * @param info info about the game piece type * @param initialPose the initial position of the game piece on the field */ public GamePieceOnFieldSimulation(GamePieceInfo info, Pose2d initialPose) { @@ -72,9 +69,9 @@ public GamePieceOnFieldSimulation(GamePieceInfo info, Pose2d initialPose) { * *

Creates a Game Piece on the Field with Custom Height Supplier and Initial Velocity.

* - * @param info info about the game piece type - * @param zPositionSupplier a supplier that provides the current Z-height of the game piece - * @param initialPose the initial position of the game piece on the field + * @param info info about the game piece type + * @param zPositionSupplier a supplier that provides the current Z-height of the game piece + * @param initialPose the initial position of the game piece on the field * @param initialVelocityMPS the initial velocity of the game piece, in meters per second */ public GamePieceOnFieldSimulation( @@ -150,10 +147,10 @@ public Pose3d getPose3d() { * *

Stores the info of a type of game piece

* - * @param type the type of the game piece, affecting categorization within the arena - * @param shape the shape of the collision space for the game piece + * @param type the type of the game piece, affecting categorization within the arena + * @param shape the shape of the collision space for the game piece * @param gamePieceHeight the height (thickness) of the game piece, in meters - * @param gamePieceMass the mass of the game piece, in kilograms + * @param gamePieceMass the mass of the game piece, in kilograms */ public record GamePieceInfo( String type, @@ -162,9 +159,11 @@ public record GamePieceInfo( Mass gamePieceMass, double linearDamping, double angularDamping, - double coefficientOfRestitution) {} + double coefficientOfRestitution) { + } - public void onIntake(String intakeTargetGamePieceType) {} + public void onIntake(String intakeTargetGamePieceType) { + } @Override public String getType() { diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceProjectile.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceProjectile.java index a7aa182..d4c589b 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceProjectile.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceProjectile.java @@ -1,13 +1,14 @@ package swervelib.simulation.ironmaple.simulation.gamepieces; -import static edu.wpi.first.units.Units.*; - import edu.wpi.first.math.geometry.*; import edu.wpi.first.math.kinematics.ChassisSpeeds; import edu.wpi.first.units.measure.Angle; import edu.wpi.first.units.measure.Distance; import edu.wpi.first.units.measure.LinearVelocity; import edu.wpi.first.wpilibj.Timer; +import swervelib.simulation.ironmaple.simulation.SimulatedArena; +import swervelib.simulation.ironmaple.utils.LegacyFieldMirroringUtils2024; + import java.util.ArrayList; import java.util.List; import java.util.Queue; @@ -15,8 +16,8 @@ import java.util.concurrent.ArrayBlockingQueue; import java.util.function.Consumer; import java.util.function.Supplier; -import swervelib.simulation.ironmaple.simulation.SimulatedArena; -import swervelib.simulation.ironmaple.utils.LegacyFieldMirroringUtils2024; + +import static edu.wpi.first.units.Units.*; /** * @@ -55,7 +56,7 @@ public class GamePieceProjectile implements GamePiece { // Properties of the game piece projectile: protected final GamePieceOnFieldSimulation.GamePieceInfo info; public final String gamePieceType; - protected final Translation2d initialPosition; + protected Translation2d initialPosition; protected final Translation2d initialLaunchingVelocityMPS; protected final double initialHeight, initialVerticalSpeedMPS; protected final Rotation3d gamePieceRotation; @@ -69,9 +70,11 @@ public class GamePieceProjectile implements GamePiece { *

Optionally, this callback will be used to visualize the projectile flight trajectory in a telemetry system, * such as Advantage Scope. */ - private Consumer> projectileTrajectoryDisplayCallBackHitTarget = projectileTrajectory -> {}; + private Consumer> projectileTrajectoryDisplayCallBackHitTarget = projectileTrajectory -> { + }; - private Consumer> projectileTrajectoryDisplayCallBackMiss = projectileTrajectory -> {}; + private Consumer> projectileTrajectoryDisplayCallBackMiss = projectileTrajectory -> { + }; // Optional properties of the game piece, used if we want it to become a // GamePieceOnFieldSimulation upon touching ground: @@ -80,7 +83,8 @@ public class GamePieceProjectile implements GamePiece { // Optional properties of the game piece, used if we want it to have a target: private Translation3d tolerance = new Translation3d(0.2, 0.2, 0.2); private Supplier targetPositionSupplier = () -> new Translation3d(0, 0, -100); - private Runnable hitTargetCallBack = () -> {}; + private Runnable hitTargetCallBack = () -> { + }; private double heightAsTouchGround = 0.5; /** @@ -105,17 +109,17 @@ public class GamePieceProjectile implements GamePiece { * *

Creates a Game Piece Projectile Ejected from a Shooter.

* - * @param info the info of the game piece - * @param robotPosition the position of the robot (not the shooter) at the time of launching the game piece - * @param shooterPositionOnRobot the translation from the shooter's position to the robot's center, in the robot's - * frame of reference + * @param info the info of the game piece + * @param robotPosition the position of the robot (not the shooter) at the time of launching the game piece + * @param shooterPositionOnRobot the translation from the shooter's position to the robot's center, in the robot's + * frame of reference * @param chassisSpeedsFieldRelative the field-relative velocity of the robot chassis when launching the game piece, - * influencing the initial velocity of the game piece - * @param shooterFacing the direction in which the shooter is facing at launch - * @param initialHeight the initial height of the game piece when launched, i.e., the height of the shooter from the - * ground - * @param launchingSpeed the speed at which the game piece is launch - * @param shooterAngle the pitch angle of the shooter when launching + * influencing the initial velocity of the game piece + * @param shooterFacing the direction in which the shooter is facing at launch + * @param initialHeight the initial height of the game piece when launched, i.e., the height of the shooter from the + * ground + * @param launchingSpeed the speed at which the game piece is launch + * @param shooterAngle the pitch angle of the shooter when launching */ public GamePieceProjectile( GamePieceOnFieldSimulation.GamePieceInfo info, @@ -148,11 +152,11 @@ public GamePieceProjectile( * translational and rotational motion as well as the shooter's ground speed. * * @param shooterPositionOnRobot the translation of the shooter on the robot, in the robot's frame of reference - * @param chassisSpeeds the speeds of the chassis when the game piece is launched, including translational and - * rotational velocities - * @param chassisFacing the direction the chassis is facing at the time of the launch - * @param groundSpeedMPS the ground component of the projectile's initial velocity, provided as a scalar in meters - * per second (m/s) + * @param chassisSpeeds the speeds of the chassis when the game piece is launched, including translational and + * rotational velocities + * @param chassisFacing the direction the chassis is facing at the time of the launch + * @param groundSpeedMPS the ground component of the projectile's initial velocity, provided as a scalar in meters + * per second (m/s) * @return the calculated initial velocity of the projectile as a {@link Translation2d} in meters per second */ private static Translation2d calculateInitialProjectileVelocityMPS( @@ -162,7 +166,7 @@ private static Translation2d calculateInitialProjectileVelocityMPS( double groundSpeedMPS) { final Translation2d chassisTranslationalVelocity = - new Translation2d(chassisSpeeds.vxMetersPerSecond, chassisSpeeds.vyMetersPerSecond), + new Translation2d(chassisSpeeds.vxMetersPerSecond, chassisSpeeds.vyMetersPerSecond), shooterGroundVelocityDueToChassisRotation = shooterPositionOnRobot .rotateBy(chassisFacing) @@ -178,15 +182,15 @@ private static Translation2d calculateInitialProjectileVelocityMPS( * *

Creates a Game Piece Projectile Ejected from a Shooter.

* - * @param info the info of the game piece - * @param initialPosition the position of the game piece at the moment it is launched into the air + * @param info the info of the game piece + * @param initialPosition the position of the game piece at the moment it is launched into the air * @param initialLaunchingVelocityMPS the horizontal component of the initial velocity in the X-Y plane, in meters - * per second (m/s) - * @param initialHeight the initial height of the game piece when launched (the height of the shooter from the - * ground) - * @param initialVerticalSpeedMPS the vertical component of the initial velocity, in meters per second (m/s) - * @param gamePieceRotation the 3D rotation of the game piece during flight (only affects visualization of the game - * piece) + * per second (m/s) + * @param initialHeight the initial height of the game piece when launched (the height of the shooter from the + * ground) + * @param initialVerticalSpeedMPS the vertical component of the initial velocity, in meters per second (m/s) + * @param gamePieceRotation the 3D rotation of the game piece during flight (only affects visualization of the game + * piece) */ public GamePieceProjectile( GamePieceOnFieldSimulation.GamePieceInfo info, @@ -266,7 +270,7 @@ public void launch() { * * * @return true if the game piece has touched the ground, otherwise false - * + * */ public boolean hasHitGround() { return getPositionAtTime(launchedTimer.get()).getZ() <= heightAsTouchGround @@ -374,7 +378,7 @@ protected Translation3d getPositionAtTime(double t) { * * @param t the time elapsed after the launch of the projectile, in seconds * @return a {@link Translation3d} object representing the calculated 3d velocity of the projectile at time t - * , in meters per second + * , in meters per second */ private Translation3d getVelocityMPSAtTime(double t) { final double verticalVelocityMPS = initialVerticalSpeedMPS - GRAVITY * t; @@ -402,9 +406,9 @@ public Pose3d getPose3d() { * *

Calculates the Projectile's Velocity at a Given Time.

* - * @see #getVelocityMPSAtTime(double) * @return a {@link Translation3d} object representing the calculated 3d velocity of the projectile at time t - * , in meters per second + * , in meters per second + * @see #getVelocityMPSAtTime(double) */ @Override public Translation3d getVelocity3dMPS() { @@ -425,7 +429,7 @@ public Translation3d getVelocity3dMPS() { * touching the ground. * * @param simulatedArena the arena simulation to which the game piece will be added, usually obtained from - * {@link SimulatedArena#getInstance()} + * {@link SimulatedArena#getInstance()} */ public void addGamePieceAfterTouchGround(SimulatedArena simulatedArena) { if (!becomesGamePieceOnGroundAfterTouchGround) return; @@ -469,6 +473,7 @@ public static void updateGamePieceProjectiles( } // The rest are methods to configure a game piece projectile simulation + /** * * @@ -570,7 +575,7 @@ public GamePieceProjectile withHitTargetCallBack(Runnable hitTargetCallBack) { * href='https://github.com/Mechanical-Advantage/AdvantageScope'>Advantage Scope * * @param projectileTrajectoryDisplayCallBack the callback that will receive the list of {@link Pose3d} objects - * representing the projectile's trajectory + * representing the projectile's trajectory * @return the current instance of {@link GamePieceProjectile} to allow method chaining */ public GamePieceProjectile withProjectileTrajectoryDisplayCallBack( @@ -594,10 +599,10 @@ public GamePieceProjectile withProjectileTrajectoryDisplayCallBack( *

This is usually for visualizing the trajectory of the projectile on a telemetry, like Advantage Scope * - * @param projectileTrajectoryDisplayCallBackHitTarget the callback that will receive the list of {@link Pose3d} - * objects representing the projectile's trajectory, called if the projectile will hit the target on its path + * @param projectileTrajectoryDisplayCallBackHitTarget the callback that will receive the list of {@link Pose3d} + * objects representing the projectile's trajectory, called if the projectile will hit the target on its path * @param projectileTrajectoryDisplayCallBackHitTargetMiss the callback that will receive the list of {@link Pose3d} - * objects representing the projectile's trajectory, called if the projectile will be off the target + * objects representing the projectile's trajectory, called if the projectile will be off the target * @return the current instance of {@link GamePieceProjectile} to allow method chaining */ public GamePieceProjectile withProjectileTrajectoryDisplayCallBack( @@ -627,6 +632,19 @@ public GamePieceProjectile withTouchGroundHeight(double heightAsTouchGround) { return this; } + /** + * + * + *

Configures the position of the robot (not the shooter) at the time of launching the game piece.

+ * + * @param initialPosition the position of the robot (not the shooter) at the time of launching the game piece + * @return the current instance of {@link GamePieceProjectile} to allow method chaining + */ + public GamePieceProjectile replaceRobotPosition(Translation2d initialPosition) { + this.initialPosition = initialPosition; + return this; + } + @Override public String getType() { return this.gamePieceType; diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/MapleMotorSim.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/MapleMotorSim.java index d8da554..7aa263b 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/MapleMotorSim.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/MapleMotorSim.java @@ -1,16 +1,16 @@ package swervelib.simulation.ironmaple.simulation.motorsims; -import static edu.wpi.first.units.Units.*; - import edu.wpi.first.units.measure.*; import edu.wpi.first.wpilibj.simulation.DCMotorSim; +import static edu.wpi.first.units.Units.*; + /** * * - *

{@link edu.wpi.first.wpilibj.simulation.DCMotorSim} with a bit of extra spice.

+ *

{@link DCMotorSim} with a bit of extra spice.

* - *

This class extends the functionality of the original {@link edu.wpi.first.wpilibj.simulation.DCMotorSim} and + *

This class extends the functionality of the original {@link DCMotorSim} and * models the following aspects in addition: * *

    @@ -49,7 +49,7 @@ public MapleMotorSim(SimMotorConfigs configs) { * *

    Updates the simulation.

    * - *

    This is equivalent to{@link edu.wpi.first.wpilibj.simulation.DCMotorSim#update(double)}. + *

    This is equivalent to{@link DCMotorSim#update(double)}. */ public void update(Time dt) { this.appliedVoltage = controller.updateControlSignal( @@ -81,7 +81,7 @@ public SimulatedMotorController.GenericMotorController useSimpleDCMotorControlle * *

    Obtains the final position of the mechanism.

    * - *

    This is equivalent to {@link edu.wpi.first.wpilibj.simulation.DCMotorSim#getAngularPosition()}. + *

    This is equivalent to {@link DCMotorSim#getAngularPosition()}. * * @return the angular position of the mechanism, continuous */ @@ -105,7 +105,7 @@ public Angle getEncoderPosition() { * *

    Obtains the final velocity of the mechanism.

    * - *

    This is equivalent to {@link edu.wpi.first.wpilibj.simulation.DCMotorSim#getAngularVelocity()}. + *

    This is equivalent to {@link DCMotorSim#getAngularVelocity()}. * * @return the final angular velocity of the mechanism */ diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimMotorConfigs.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimMotorConfigs.java index b9cfb65..5084e59 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimMotorConfigs.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimMotorConfigs.java @@ -1,11 +1,10 @@ package swervelib.simulation.ironmaple.simulation.motorsims; -import static edu.wpi.first.units.Units.*; -import static edu.wpi.first.units.Units.Volts; - import edu.wpi.first.math.system.plant.DCMotor; import edu.wpi.first.units.measure.*; +import static edu.wpi.first.units.Units.*; + /** * * @@ -39,7 +38,7 @@ public final class SimMotorConfigs { public final MomentOfInertia loadMOI; public final Torque friction; - protected Angle forwardHardwareLimit, reverseHardwareLimit; + Angle forwardHardwareLimit, reverseHardwareLimit; /** * @@ -49,9 +48,9 @@ public final class SimMotorConfigs { *

    This constructor initializes a {@link SimMotorConfigs} object with the necessary parameters for motor * simulation, including the motor model, gearing ratio, load moment of inertia, and friction characteristics. * - * @param motor the motor model to be used in the simulation (e.g., Falcon 500, NEO). - * @param gearing the gear ratio between the motor and the load, affecting torque and speed output. - * @param loadMOI the moment of inertia of the load connected to the motor, representing rotational resistance. + * @param motor the motor model to be used in the simulation (e.g., Falcon 500, NEO). + * @param gearing the gear ratio between the motor and the load, affecting torque and speed output. + * @param loadMOI the moment of inertia of the load connected to the motor, representing rotational resistance. * @param frictionVoltage the voltage applied to simulate frictional torque losses in the motor. */ public SimMotorConfigs(DCMotor motor, double gearing, MomentOfInertia loadMOI, Voltage frictionVoltage) { @@ -71,10 +70,10 @@ public SimMotorConfigs(DCMotor motor, double gearing, MomentOfInertia loadMOI, V * *

    This method uses the {@link DCMotor} model to find the voltage for a given current and angular velocity. * - * @see DCMotor#getVoltage(double, double) for the underlying implementation. - * @param current the current flowing through the motor + * @param current the current flowing through the motor * @param mechanismVelocity the final angular velocity of the mechanism * @return the voltage required for the motor to achieve the specified current and angular velocity + * @see DCMotor#getVoltage(double, double) for the underlying implementation. */ public Voltage calculateVoltage(Current current, AngularVelocity mechanismVelocity) { return Volts.of(motor.getVoltage(current.in(Amps), mechanismVelocity.in(RadiansPerSecond) * gearing)); @@ -87,10 +86,10 @@ public Voltage calculateVoltage(Current current, AngularVelocity mechanismVeloci * *

    This method uses the {@link DCMotor} model to find the angular velocity for a given current and voltage. * - * @see DCMotor#getSpeed(double, double) for the underlying implementation. * @param current the current flowing through the motor. * @param voltage the voltage applied to the motor. * @return the final angular velocity of the mechanism. + * @see DCMotor#getSpeed(double, double) for the underlying implementation. */ public AngularVelocity calculateMechanismVelocity(Current current, Voltage voltage) { return RadiansPerSecond.of(motor.getSpeed(motor.getTorque(current.in(Amps)), voltage.in(Volts))) @@ -104,10 +103,10 @@ public AngularVelocity calculateMechanismVelocity(Current current, Voltage volta * *

    This method uses the {@link DCMotor} model to find the current for a given angular velocity and voltage. * - * @see DCMotor#getCurrent(double, double) for the underlying implementation. * @param mechanismVelocity the final angular velocity of the mechanism. - * @param voltage the voltage applied to the moto. + * @param voltage the voltage applied to the moto. * @return the current drawn by the motor. + * @see DCMotor#getCurrent(double, double) for the underlying implementation. */ public Current calculateCurrent(AngularVelocity mechanismVelocity, Voltage voltage) { return Amps.of(motor.getCurrent(mechanismVelocity.in(RadiansPerSecond) * gearing, voltage.in(Volts))); @@ -120,9 +119,9 @@ public Current calculateCurrent(AngularVelocity mechanismVelocity, Voltage volta * *

    This method uses the {@link DCMotor} model to find the current required for a given torque. * - * @see DCMotor#getCurrent(double) for the underlying implementation. * @param torque the final torque generated by the motor on the mechanism. * @return the current required to produce the specified torque. + * @see DCMotor#getCurrent(double) for the underlying implementation. */ public Current calculateCurrent(Torque torque) { return Amps.of(motor.getCurrent(torque.in(NewtonMeters) / gearing)); @@ -135,9 +134,9 @@ public Current calculateCurrent(Torque torque) { * *

    This method uses the {@link DCMotor} model to find the torque generated by a given current. * - * @see DCMotor#getTorque(double) for the underlying implementation. * @param current the current flowing through the motor. * @return the torque generated by the motor. + * @see DCMotor#getTorque(double) for the underlying implementation. */ public Torque calculateTorque(Current current) { return NewtonMeters.of(motor.getTorque(current.in(Amps)) * gearing); @@ -185,7 +184,7 @@ public Voltage nominalVoltage() { @Override protected SimMotorConfigs clone() { SimMotorConfigs cfg = new SimMotorConfigs( - motor, gearing, loadMOI, Volts.of(motor.getVoltage(friction.in(NewtonMeter), 0.0))) + motor, gearing, loadMOI, Volts.of(motor.getVoltage(friction.in(NewtonMeter), 0.0))) .withHardLimits(forwardHardwareLimit, reverseHardwareLimit); return cfg; diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimMotorState.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimMotorState.java index 86fc9a4..f912cb3 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimMotorState.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimMotorState.java @@ -1,9 +1,9 @@ package swervelib.simulation.ironmaple.simulation.motorsims; -import static edu.wpi.first.units.Units.*; - import edu.wpi.first.units.measure.*; +import static edu.wpi.first.units.Units.*; + /** * * @@ -49,8 +49,8 @@ public SimMotorState(Angle mechanismAngularPosition, AngularVelocity mechanismAn * * @param finalElectricTorque the final applied electric torque, in Newton-meters * @param finalFrictionTorque the final frictional torque, in Newton-meters - * @param loadMOI the moment of inertia of the load, in kilogram square meters - * @param dt the time step for the simulation, in seconds + * @param loadMOI the moment of inertia of the load, in kilogram square meters + * @param dt the time step for the simulation, in seconds */ public void step(Torque finalElectricTorque, Torque finalFrictionTorque, MomentOfInertia loadMOI, Time dt) { // Step 0: Convert all units to SI units (radians, radians per second, Newton-meters, seconds, kg*m²) @@ -76,7 +76,7 @@ public void step(Torque finalElectricTorque, Torque finalFrictionTorque, MomentO // If friction causes the motor to reverse direction, or if the velocity reaches zero, set the angular velocity // to zero. if ((currentAngularVelocityRadiansPerSecond + deltaAngularVelocityDueToFrictionRadPerSec) - * currentAngularVelocityRadiansPerSecond + * currentAngularVelocityRadiansPerSecond <= 0) // The velocity has reversed direction or reached zero, so stop the motor currentAngularVelocityRadiansPerSecond = 0; diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimulatedBattery.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimulatedBattery.java index 08cdfb6..0c4ed27 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimulatedBattery.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimulatedBattery.java @@ -1,8 +1,5 @@ package swervelib.simulation.ironmaple.simulation.motorsims; -import static edu.wpi.first.units.Units.Amps; -import static edu.wpi.first.units.Units.Volts; - import edu.wpi.first.math.MathUtil; import edu.wpi.first.math.filter.LinearFilter; import edu.wpi.first.units.measure.Current; @@ -11,10 +8,14 @@ import edu.wpi.first.wpilibj.simulation.BatterySim; import edu.wpi.first.wpilibj.simulation.RoboRioSim; import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; + import java.util.ArrayList; import java.util.List; import java.util.function.Supplier; +import static edu.wpi.first.units.Units.Amps; +import static edu.wpi.first.units.Units.Volts; + /** * * @@ -35,6 +36,17 @@ public class SimulatedBattery { // The current battery voltage in volts. private static double batteryVoltageVolts = BATTERY_NOMINAL_VOLTAGE; + private static boolean disableBatterySim = false; + + /** + * Disables the battery simulation. This is a lazy quick fix to help the opponent simulation. + */ + public static void disableBatterySim() { + disableBatterySim = true; + electricalAppliances.clear(); + batteryVoltageVolts = BATTERY_NOMINAL_VOLTAGE; + } + /** * * @@ -74,8 +86,6 @@ public static void simulationSubTick() { double totalCurrentAmps = getTotalCurrentDrawn().in(Amps); totalCurrentAmps = currentFilter.calculate(totalCurrentAmps); - batteryVoltageVolts = BatterySim.calculateLoadedBatteryVoltage(BATTERY_NOMINAL_VOLTAGE, 0.02, totalCurrentAmps); - if (Double.isNaN(batteryVoltageVolts)) { batteryVoltageVolts = 12.0; DriverStation.reportError( @@ -88,8 +98,13 @@ public static void simulationSubTick() { DriverStation.reportError("[MapleSim] BrownOut Detected, protecting battery voltage...", false); } - RoboRioSim.setVInVoltage(batteryVoltageVolts); + /// Quick fix to lock battery simulation to nominal voltage. + if (!disableBatterySim) { + batteryVoltageVolts = + BatterySim.calculateLoadedBatteryVoltage(BATTERY_NOMINAL_VOLTAGE, 0.02, totalCurrentAmps); + } + RoboRioSim.setVInVoltage(batteryVoltageVolts); SmartDashboard.putNumber("BatterySim/TotalCurrent (Amps)", totalCurrentAmps); SmartDashboard.putNumber("BatterySim/BatteryVoltage (Volts)", batteryVoltageVolts); } diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimulatedMotorController.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimulatedMotorController.java index 4eeddd1..381209b 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimulatedMotorController.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/motorsims/SimulatedMotorController.java @@ -1,13 +1,13 @@ package swervelib.simulation.ironmaple.simulation.motorsims; -import static edu.wpi.first.units.Units.*; - import edu.wpi.first.math.system.plant.DCMotor; import edu.wpi.first.units.measure.Angle; import edu.wpi.first.units.measure.AngularVelocity; import edu.wpi.first.units.measure.Current; import edu.wpi.first.units.measure.Voltage; +import static edu.wpi.first.units.Units.*; + public interface SimulatedMotorController { Voltage updateControlSignal( Angle mechanismAngle, @@ -53,41 +53,41 @@ public void requestVoltage(Voltage voltage) { * *

    Prevents motor from exceeding software limits * - * @param encoderAngle the angle of the encoder - * @param encoderVelocity the velocity of the encoder + * @param encoderAngle the angle of the encoder + * @param encoderVelocity the velocity of the encoder * @param requestedVoltage the requested voltage * @return the constrained voltage that satisfied the limits */ public Voltage constrainOutputVoltage( Angle encoderAngle, AngularVelocity encoderVelocity, Voltage requestedVoltage) { - final double kCurrentThreshold = 1.2; - - // don't use WpiLib Units for calculations + // Don't use WPILib Units final double motorCurrentVelocityRadPerSec = encoderVelocity.in(RadiansPerSecond); - final double currentLimitAmps = currentLimit.in(Amps); final double requestedOutputVoltageVolts = requestedVoltage.in(Volts); + final double currentLimitAmps = currentLimit.in(Amps); + final double kCurrentThreshold = 1.2; + final double thresholdedCurrentLimitAmps = kCurrentThreshold * currentLimitAmps; + final double currentAtRequestedVoltageAmps = model.getCurrent(motorCurrentVelocityRadPerSec, requestedOutputVoltageVolts); + double limitedVoltage = requestedOutputVoltageVolts; + // Resource for current limiting: // https://file.tavsys.net/control/controls-engineering-in-frc.pdf (sec 12.1.3) - double limitedVoltage = requestedOutputVoltageVolts; - final boolean currentTooHigh = - Math.abs(currentAtRequestedVoltageAmps) > (kCurrentThreshold * currentLimitAmps); - if (currentTooHigh) { + if (Math.abs(currentAtRequestedVoltageAmps) > thresholdedCurrentLimitAmps) { final double limitedCurrent = Math.copySign(currentLimitAmps, currentAtRequestedVoltageAmps); limitedVoltage = model.getVoltage(model.getTorque(limitedCurrent), motorCurrentVelocityRadPerSec); - } - // ensure the current limit doesn't cause an increase to output voltage - if (Math.abs(limitedVoltage) > Math.abs(requestedOutputVoltageVolts)) - limitedVoltage = requestedOutputVoltageVolts; + // Ensure the current limit doesn't cause an increase to output voltage + if (Math.abs(limitedVoltage) > Math.abs(requestedOutputVoltageVolts)) + limitedVoltage = requestedOutputVoltageVolts; + } - // apply software limits - if (encoderAngle.gte(forwardSoftwareLimit) && limitedVoltage > 0) limitedVoltage = 0; - if (encoderAngle.lte(reverseSoftwareLimit) && limitedVoltage < 0) limitedVoltage = 0; + // Apply software limits + if (limitedVoltage > 0 && encoderAngle.gte(forwardSoftwareLimit)) limitedVoltage = 0; + if (limitedVoltage < 0 && encoderAngle.lte(reverseSoftwareLimit)) limitedVoltage = 0; - // constrain the output voltage to the battery voltage + // Constrain the output voltage to the battery voltage return Volts.of(limitedVoltage); } diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/opponentsim/ManipulatorSim.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/opponentsim/ManipulatorSim.java new file mode 100644 index 0000000..5ecd0ea --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/opponentsim/ManipulatorSim.java @@ -0,0 +1,135 @@ +package swervelib.simulation.ironmaple.simulation.opponentsim; + +import edu.wpi.first.wpilibj2.command.Command; +import edu.wpi.first.wpilibj2.command.SubsystemBase; +import swervelib.simulation.ironmaple.simulation.IntakeSimulation; +import swervelib.simulation.ironmaple.simulation.SimulatedArena; +import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceProjectile; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Supplier; + +public class ManipulatorSim extends SubsystemBase { + /// Simulation Maps of saved manipulators + private final Map intakeSimulations; + private final Map> projectileSimulations; + + /** + * Creates a new manipulator simulation. + */ + public ManipulatorSim() { + this.intakeSimulations = new HashMap<>(); + this.projectileSimulations = new HashMap<>(); + } + + /** + * The Map of {@link IntakeSimulation} types. + * + * @return a Map of {@link IntakeSimulation} types. + */ + public Map getIntakeSimulations() { + return intakeSimulations; + } + + /** + * The Map of the {@link GamePieceProjectile} types. + * + * @return a Map of the {@link GamePieceProjectile} types. + */ + public Map> getProjectileSimulations() { + return projectileSimulations; + } + + /** + * Adds an intake simulation to the manipulator simulation. + * + * @param intakeName The name of the intake simulation. + * @param intakeSimulation The simulation to add. + * @return this, for chaining. + */ + public ManipulatorSim addIntakeSimulation(String intakeName, IntakeSimulation intakeSimulation) { + this.intakeSimulations.put(intakeName, intakeSimulation); + return this; + } + + /** + * Adds a projectile simulation to the manipulator simulation. + * + * @param projectileName The name of the projectile simulation. + * @param projectileSimulation The simulation to add. + * @return this, for chaining. + */ + public ManipulatorSim addProjectileSimulation( + String projectileName, Supplier projectileSimulation) { + this.projectileSimulations.put(projectileName, projectileSimulation); + return this; + } + + /** + * Gets an intake simulation from the manipulator simulation. + * + * @param intakeName The name of the intake simulation. + * @return The simulation. + */ + public IntakeSimulation getIntakeSimulation(String intakeName) { + return this.intakeSimulations.get(intakeName); + } + + /** + * Gets a projectile simulation from the manipulator simulation. + * + * @param projectileName The name of the simulation. + * @return The simulation. + */ + public Supplier getProjectileSimulation(String projectileName) { + return this.projectileSimulations.get(projectileName); + } + + /** + * Runs the intake, stops running the intake when the command ends. + * + * @param intakeName + * @return + */ + public Command intake(String intakeName) { + return runEnd(() -> getIntakeSimulation(intakeName).startIntake(), + () -> getIntakeSimulation(intakeName).stopIntake()); + } + + /** + * Runs intake(String) until the game piece count in the intake goes up. + * + * @param intakeName + * @return + */ + public Command intakeUntilCollected(String intakeName) { + final int count = getIntakeSimulation(intakeName).getGamePiecesAmount(); + return intake(intakeName) + .until(() -> count > getIntakeSimulation(intakeName).getGamePiecesAmount()); + } + + /** + * Adds a projectile to the simulation. + * + * @param projectileName The name of the projectile simulation. + * @return a command to add the game piece projectile to the simulation. + */ + public Command score(String projectileName) { + return runOnce(() -> SimulatedArena.getInstance() + .addGamePieceProjectile(getProjectileSimulation(projectileName).get())); + } + + /** + * A command that only calls score(String) when there is greater than zero(>0) + * {@link swervelib.simulation.ironmaple.simulation.gamepieces.GamePiece} in the intake. + * + * @param intakeName the intake to check. + * @param projectileName the piece to score. + * @return score(String) when valid. + */ + public Command scoreWithIntake(String intakeName, String projectileName) { + return score(projectileName) + .onlyIf(() -> getIntakeSimulation(intakeName).getGamePiecesAmount() > 0); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/opponentsim/OpponentManager.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/opponentsim/OpponentManager.java new file mode 100644 index 0000000..11b4b2d --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/opponentsim/OpponentManager.java @@ -0,0 +1,481 @@ +package swervelib.simulation.ironmaple.simulation.opponentsim; + +import com.pathplanner.lib.commands.PathfindingCommand; +import edu.wpi.first.math.Pair; +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.units.measure.Distance; +import edu.wpi.first.units.measure.Time; +import edu.wpi.first.wpilibj.DriverStation; +import swervelib.simulation.ironmaple.simulation.opponentsim.pathfinding.MapleADStar; + +import java.util.*; + +import static edu.wpi.first.units.Units.Meters; +import static edu.wpi.first.units.Units.Milliseconds; + +public class OpponentManager { + // Map of possible scoring poses and types. For example, Map<"Hoops", Map<"CourtLeft", Pose2d>> + protected static final Map> scoringMap = new HashMap<>(); + // Map of possible collecting poses and types. For example, Map<"CollectStation", Map<"StationCenter", Pose2d>> + protected static final Map> collectingMap = new HashMap<>(); + /// Cached opponent data for dynamic polling. + // Cached list of all opponent obstacles. + protected static final List> opponentObstacles = new ArrayList<>(); + protected double lastObstaclePoll = 0; + protected static final List> blueOpponentObstacles = new ArrayList<>(); + protected double lastBlueObstaclePoll = 0; + protected static final List> redOpponentObstacles = new ArrayList<>(); + protected double lastRedObstaclePoll = 0; + // Cached list of all opponent targets. + protected static final List> opponentTargets = new ArrayList<>(); + protected double lastTargetPoll = 0; + protected static final List> blueOpponentTargets = new ArrayList<>(); + protected double lastBlueTargetPoll = 0; + protected static final List> redOpponentTargets = new ArrayList<>(); + protected double lastRedTargetPoll = 0; + // Cached list of all opponent poses. + protected static final List opponentPoses = new ArrayList<>(); + protected double lastPosePoll = 0; + protected static final List blueOpponentPoses = new ArrayList<>(); + protected double lastBluePosePoll = 0; + protected static final List redOpponentPoses = new ArrayList<>(); + protected double lastRedPosePoll = 0; + // List of possible starting poses + protected static final List initialBluePoses = new ArrayList<>(); + protected static final List initialRedPoses = new ArrayList<>(); + // Map of queening poses + protected static final List queeningPoses = new ArrayList<>(); + // Bounding box buffer, used to determine how big to make the obstacles. + protected static Distance boundingBoxBuffer; + // Bounding box offset Translation2d + protected final Translation2d boundingBoxTranslation; + + /// List of all opponent robots. + protected static final List opponents = new ArrayList<>(); + + /** + * MapleSim Opponent currently relies on Pathplanner with a modified pathfinder. This is to be changed soon. ^TM + */ + public OpponentManager() { + boundingBoxBuffer = Meters.of(0.6); + this.boundingBoxTranslation = new Translation2d(boundingBoxBuffer, boundingBoxBuffer); + } + + /** + * MapleSim Opponent currently relies on Pathplanner with a modified pathfinder. This is to be changed soon. ^TM + * + * @param withDefaults whether to call withDefaults or not. + */ + public OpponentManager(boolean withDefaults) { + this(); + if (withDefaults) { + withDefaults(); + } + } + + /** + * Calls withDefaultQueeningPoses() and withDefaultInitialPoses(). Also warms up pathplanner. + * + * @return this, for chaining. + */ + public OpponentManager withDefaults() { + PathfindingCommand.warmupCommand().schedule(); + this + .withDefaultInitialPoses() + .withDefaultQueeningPoses(); + return this; + } + + /** + * Adds 6 default queening poses to the list. + * + * @return this, for chaining. + */ + public OpponentManager withDefaultQueeningPoses() { + /// Add 6 queening poses for 3v3 without any additional + queeningPoses.add(new Pose2d(-6, 0, new Rotation2d())); + queeningPoses.add(new Pose2d(-5, 0, new Rotation2d())); + queeningPoses.add(new Pose2d(-4, 0, new Rotation2d())); + queeningPoses.add(new Pose2d(-3, 0, new Rotation2d())); + queeningPoses.add(new Pose2d(-2, 0, new Rotation2d())); + queeningPoses.add(new Pose2d(-1, 0, new Rotation2d())); + return this; + } + + /** + * Add 6 basic starting positions, 3 on each side. + * + * @return this, for chaining. + */ + public OpponentManager withDefaultInitialPoses() { + /// Add 6 basic starting positions, 3 on each side. + initialRedPoses.add(new Pose2d(15, 6, Rotation2d.fromDegrees(180))); + initialRedPoses.add(new Pose2d(15, 4, Rotation2d.fromDegrees(180))); + initialRedPoses.add(new Pose2d(15, 2, Rotation2d.fromDegrees(180))); + initialBluePoses.add(new Pose2d(1.6, 6, Rotation2d.kZero)); + initialBluePoses.add(new Pose2d(1.6, 4, Rotation2d.kZero)); + initialBluePoses.add(new Pose2d(1.6, 2, Rotation2d.kZero)); + return this; + } + + /** + * Adds an opponent robot to the list of robots to grab things from. + * + * @param opponent the {@link SmartOpponent} to manage. + * @return this, for chaining. + */ + public OpponentManager registerOpponent(SmartOpponent opponent) { + opponents.add(opponent); + return this; + } + + /** + * Makes a list of opponents on the given alliance. + * + * @param alliance the {@link DriverStation.Alliance} to collect opponents from. + * @return a {@link List} of the given alliance. + */ + public List getOpponents(DriverStation.Alliance alliance) { + List allianceOpponents = new ArrayList<>(); + for (SmartOpponent opponent : opponents) { + if (opponent.config.alliance == alliance) { + allianceOpponents.add(opponent); + } + } + return allianceOpponents; + } + + /** + * Gets the list of all registered SmartOpponents. + * + * @return the {@link List} of registered opponents. + */ + public List getOpponents() { + return opponents; + } + + /** + * Returns only the opponent targets for the given alliance. + * + * @param alliance which {@link DriverStation.Alliance} targets to grab. + * @return a list of poses targeted by opponents on the given alliance. + */ + public List> getOpponentTargetsDynamic(DriverStation.Alliance alliance, Time pollRate) { + // If elapsed time is less than pollRate return our cached list. + final var isBlue = alliance == DriverStation.Alliance.Blue; + final var targetList = isBlue ? blueOpponentTargets : redOpponentTargets; + if (System.currentTimeMillis() - (isBlue ? lastBlueTargetPoll : lastRedTargetPoll) < pollRate.in(Milliseconds)) { + return targetList; + } + // New list to filter. + final var filteredOpponents = new ArrayList<>(opponents); + // If elapsed time exceeds our pollRate, refresh the list. + targetList.clear(); + filteredOpponents.stream() + // Remove all opponents not on given alliance. + .filter(opponent -> opponent.config.alliance != alliance) + // Collect all their poses. + .forEach(opponent -> targetList.add(opponent.getTarget())); + // Update our refresh timestamp. + if (isBlue) { + lastBlueTargetPoll = System.currentTimeMillis(); + } else { + lastRedTargetPoll = System.currentTimeMillis(); + } + return targetList; + } + + /** + * Dynamically caches and refreshed a list of opponent targets. + * + * @param pollRate how long to wait before refreshing + * @return the list of registered opponent target poses. + */ + public List> getOpponentTargetsDynamic(Time pollRate) { + // If elapsed time is less than pollRate return our cached list. + if (System.currentTimeMillis() - lastTargetPoll < pollRate.in(Milliseconds)) { + return opponentTargets; + } + // If elapsed time exceeds our pollRate, refresh the list. + opponentTargets.clear(); + // Call the other dynamic methods so we don't update if not needed. + opponentTargets.addAll(getOpponentTargetsDynamic(DriverStation.Alliance.Blue, pollRate)); + opponentTargets.addAll(getOpponentTargetsDynamic(DriverStation.Alliance.Red, pollRate)); + // Update our refresh timestamp. + lastTargetPoll = System.currentTimeMillis(); + return opponentTargets; + } + + /** + * Checks if the given pose is near any opponent target pose. + * + * @param pose the pose to check against. + * @param pollRate how long to wait before refreshing + * @param tolerance the translation tolerance in {@link Distance}. + * @return + */ + public boolean isNearTarget(Pose2d pose, Time pollRate, Distance tolerance) { + for (Pair existingTarget : getOpponentTargetsDynamic(pollRate)) { + // Check if the new target is within the tolerance distance of any existing target + if (Objects.nonNull(existingTarget)) { + if (existingTarget.getSecond().getTranslation().getDistance(pose.getTranslation()) < tolerance.in(Meters)) { + return true; + } + } + } + return false; + } + + /** + * Returns only the opponent poses for the given alliance. + * + * @param alliance which {@link DriverStation.Alliance} poses to grab. + * @return a list of opponent poses on the given alliance. + */ + public List getOpponentPosesDynamic(DriverStation.Alliance alliance, Time pollRate) { + // If elapsed time is less than pollRate return our cached list. + final var isBlue = alliance == DriverStation.Alliance.Blue; + final var poseList = isBlue ? blueOpponentPoses : redOpponentPoses; + if (System.currentTimeMillis() - (isBlue ? lastBluePosePoll : lastRedPosePoll) < pollRate.in(Milliseconds)) { + return poseList; + } + // New list to filter. + final var filteredOpponents = new ArrayList<>(opponents); + // If elapsed time exceeds our pollRate, refresh the list. + poseList.clear(); + filteredOpponents.stream() + // Remove all opponents not on a given alliance. + .filter(opponent -> opponent.config.alliance != alliance) + // Collect all their poses. + .forEach(opponent -> poseList.add(opponent.getOpponentPose())); + // Update our refresh timestamp. + if (isBlue) { + lastBluePosePoll = System.currentTimeMillis(); + } else { + lastRedPosePoll = System.currentTimeMillis(); + } + return poseList; + } + + /** + * Returns all registered opponent poses. + * + * @return a list of all opponents poses on the given alliance. + */ + public List getOpponentPosesDynamic(Time pollRate) { + // If elapsed time is less than pollRate return our cached list. + if (System.currentTimeMillis() - lastPosePoll < pollRate.in(Milliseconds)) { + return opponentPoses; + } + // If elapsed time exceeds our pollRate, refresh the list. + opponentPoses.clear(); + // Call the other dynamic methods so we don't update if not needed. + opponentPoses.addAll(getOpponentPosesDynamic(DriverStation.Alliance.Blue, pollRate)); + opponentPoses.addAll(getOpponentPosesDynamic(DriverStation.Alliance.Red, pollRate)); + // Update our refresh timestamp. + lastPosePoll = System.currentTimeMillis(); + return opponentPoses; + } + + /** + * Saves a list globally in {@link OpponentManager} and returns that list only updating it if the last update + * exceeds the given time. + * + * @param pollRate how long to wait before updating. + * @return a list of obstacles usable by {@link MapleADStar}. + */ + protected List> getObstaclesDynamic(DriverStation.Alliance alliance, Time pollRate) { + // If elapsed time is less than pollRate return our cached list. + final var isBlue = alliance == DriverStation.Alliance.Blue; + final var obstacleList = isBlue ? blueOpponentObstacles : redOpponentObstacles; + if (System.currentTimeMillis() - (isBlue ? lastBlueObstaclePoll : lastRedObstaclePoll) < pollRate.in(Milliseconds)) { + return obstacleList; + } + // New list to filter. + final var targets = isBlue + ? getOpponentTargetsDynamic(DriverStation.Alliance.Blue, pollRate) + : getOpponentTargetsDynamic(DriverStation.Alliance.Red, pollRate); + final var poses = isBlue + ? getOpponentPosesDynamic(DriverStation.Alliance.Blue, pollRate) + : getOpponentPosesDynamic(DriverStation.Alliance.Red, pollRate); + obstacleList.clear(); + // Format poses into obstacles and add them. + targets.forEach(target -> { + obstacleList.add(poseToObstacle(Objects.requireNonNullElse(target.getSecond(), Pose2d.kZero))); + }); + poses.forEach(pose -> { + obstacleList.add(poseToObstacle(pose)); + }); + // Update our refresh timestamp. + if (isBlue) { + lastBlueObstaclePoll = System.currentTimeMillis(); + } else { + lastRedObstaclePoll = System.currentTimeMillis(); + } + return obstacleList; + } + + /** + * Saves a list globally in {@link OpponentManager} and returns that list only updating it if the last update + * exceeds the given time. + * + * @param pollRate how long to wait before updating. + * @return a list of obstacles usable by {@link MapleADStar}. + */ + protected List> getObstaclesDynamic(Time pollRate) { + // If elapsed time is less than pollRate return our cached list. + if (System.currentTimeMillis() - lastObstaclePoll < pollRate.in(Milliseconds)) { + return opponentObstacles; + } + // If elapsed time exceeds our pollRate, refresh the list. + opponentObstacles.clear(); + // Call the other dynamic methods so we don't update if not needed. + opponentObstacles.addAll(getObstaclesDynamic(DriverStation.Alliance.Blue, pollRate)); + opponentObstacles.addAll(getObstaclesDynamic(DriverStation.Alliance.Red, pollRate)); + // Update our refresh timestamp. + lastObstaclePoll = System.currentTimeMillis(); + return opponentObstacles; + } + + /** + * Formats a pose2d as a bounding box for obstacles using the boundingBoxBuffer. + * + * @param pose the pose to format. + * @return an obstacle usable by pathplanner. + */ + protected Pair poseToObstacle(Pose2d pose) { + return Pair.of( + pose.getTranslation().plus(boundingBoxTranslation), + pose.getTranslation().minus(boundingBoxTranslation) + ); + } + + /** + * Gets a queening pose, removing it from the list. + * + * @return a queening pose. + */ + public Pose2d getQueeningPose() { + var pose = queeningPoses.get(0); + queeningPoses.remove(0); + return pose; + } + + /** + * Gets an initial pose, removing it from the list. + * + * @return a initial pose. + */ + public Pose2d getInitialPose(DriverStation.Alliance alliance) { + Pose2d pose; + if (alliance == DriverStation.Alliance.Blue) { + pose = initialBluePoses.get(0); + initialBluePoses.remove(0); + } else { + pose = initialRedPoses.get(0); + initialRedPoses.remove(0); + } + return pose; + } + + /** + * Adds a scoring pose. + * + * @param poseType The type of pose to add. For example, "Hoops". + * @param poseName The name of the pose to add. For example, "CourtLeft". + * @param pose The pose to add. + * @return this, for chaining. + */ + public OpponentManager addScoringPose(String poseType, String poseName, Pose2d pose) { + scoringMap.putIfAbsent(poseType, new HashMap<>()); + scoringMap.get(poseType).putIfAbsent(poseName, pose); + if (scoringMap.get(poseType).get(poseName) != pose) { + throw new IllegalArgumentException("Failed to add score pose: " + poseName + "/n"); + } + return this; + } + + /** + * Gets the raw scoring map. Setup as Map> + * + * @return the raw scoring map. + */ + public Map> getRawScoringMap() { + return scoringMap; + } + + /** + * Compiles a compacted scoring map. Setup as Map + * + * @return a compacted scoring map. + */ + public Map getScoringMap() { + Map scoringPoses = new HashMap<>(); + scoringMap.forEach((poseType, poseMap) -> poseMap.forEach((name, pose) -> { + scoringPoses.put(poseType + name, pose); + })); + return scoringPoses; + } + + /** + * Compiles a list of all scoring poses. + * + * @return a list of all scoring poses. + */ + public List getScoringPoses() { + List scoringPoses = new ArrayList<>(); + scoringMap.forEach((poseType, poseMap) -> poseMap.forEach((poseName, pose) -> scoringPoses.add(pose))); + return scoringPoses; + } + + /** + * Adds a collecting pose to the config. + * + * @param poseType The type of pose to add. For example, "CollectStation". + * @param poseName The name of the pose to add. For example, "StationCenter". + * @param pose The pose to add. + * @return this, for chaining. + */ + public OpponentManager addCollectingPose(String poseType, String poseName, Pose2d pose) { + collectingMap.putIfAbsent(poseType, new HashMap<>()); + collectingMap.get(poseType).putIfAbsent(poseName, pose); + if (collectingMap.get(poseType).get(poseName) != pose) { + throw new IllegalArgumentException("Failed to add collect pose: " + poseName + "/n"); + } + return this; + } + + /** + * Gets the raw collecting map. Setup as Map> + * + * @return the raw collecting map. + */ + public Map> getRawCollectingMap() { + return collectingMap; + } + + /** + * Compiles a compacted collecting map. Setup as Map + * + * @return a compacted collecting map. + */ + public Map getCollectingMap() { + Map collectingPoses = new HashMap<>(); + collectingMap.forEach( + (poseType, poseMap) -> poseMap.forEach((name, pose2d) -> collectingPoses.put(poseType + name, pose2d))); + return collectingPoses; + } + + /** + * Compiles a list of all collecting poses. + * + * @return a list of all collecting poses. + */ + public List getCollectingPoses() { + List collectingPoses = new ArrayList<>(); + collectingMap.forEach((poseType, poseMap) -> poseMap.forEach((poseName, pose) -> collectingPoses.add(pose))); + return collectingPoses; + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/opponentsim/SmartOpponent.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/opponentsim/SmartOpponent.java new file mode 100644 index 0000000..ee920ef --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/opponentsim/SmartOpponent.java @@ -0,0 +1,586 @@ +package swervelib.simulation.ironmaple.simulation.opponentsim; + +import com.pathplanner.lib.commands.FollowPathCommand; +import com.pathplanner.lib.config.PIDConstants; +import com.pathplanner.lib.config.RobotConfig; +import com.pathplanner.lib.controllers.PPHolonomicDriveController; +import com.pathplanner.lib.path.*; +import com.pathplanner.lib.trajectory.PathPlannerTrajectoryState; +import edu.wpi.first.math.MathUtil; +import edu.wpi.first.math.Pair; +import edu.wpi.first.math.filter.Debouncer; +import edu.wpi.first.math.filter.LinearFilter; +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.kinematics.ChassisSpeeds; +import edu.wpi.first.networktables.NetworkTableInstance; +import edu.wpi.first.networktables.StringPublisher; +import edu.wpi.first.networktables.StructPublisher; +import edu.wpi.first.units.measure.Angle; +import edu.wpi.first.units.measure.Distance; +import edu.wpi.first.units.measure.LinearVelocity; +import edu.wpi.first.units.measure.Time; +import edu.wpi.first.wpilibj.DriverStation; +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 edu.wpi.first.wpilibj2.command.SubsystemBase; +import edu.wpi.first.wpilibj2.command.button.RobotModeTriggers; +import swervelib.simulation.ironmaple.simulation.SimulatedArena; +import swervelib.simulation.ironmaple.simulation.drivesims.SelfControlledSwerveDriveSimulation; +import swervelib.simulation.ironmaple.simulation.opponentsim.pathfinding.MapleADStar; +import swervelib.simulation.ironmaple.utils.FieldMirroringUtils; + +import java.util.*; +import java.util.function.Supplier; + +import static edu.wpi.first.units.Units.*; + +public abstract class SmartOpponent extends SubsystemBase { + /// Publishers + protected StringPublisher statePublisher; + protected StructPublisher posePublisher; + // String used in telemetry for alliance. + protected String allianceString; + /// The SmartOpponentConfig to use. + protected SmartOpponentConfig config; + // The opponent manager if set + protected OpponentManager manager; + /// The drivetrain simulation. + protected SelfControlledSwerveDriveSimulation drivetrainSim; + /// The Manipulator Sim + protected ManipulatorSim manipulatorSim; + /// The pathplanner config + protected RobotConfig pathplannerConfig; + /// Pathplanner HolonomicDriveController + protected PPHolonomicDriveController driveController; + // Pathfinding class cloned for modification. + protected final MapleADStar mapleADStar; + // Behavior Chooser Publisher + protected StringPublisher selectedBehaviorPublisher; + // Target Pose + protected Pair target; + // Whether the state was interrupted and should restart. + protected boolean restartInterrupt; + /// Collision Detection + protected final Debouncer collisionDebouncer; + /// Not Moving Detection + protected final Timer notMovingTimer; + protected final LinearVelocity notMovingThreshold; + + /** + * The SmartOpponent base abstracted class. + * + * @param config the {@link SmartOpponentConfig} to base the opponent off of. + */ + public SmartOpponent(SmartOpponentConfig config) { + /// Create and verify config. + this.config = config; + config.validateConfigs(); // Throw an error if the config is invalid. + if (config.manager != null) { + this.manager = config.manager; + } + this.driveController = new PPHolonomicDriveController( + new PIDConstants(5), + new PIDConstants(5)); + // Cloned Pathfinder for use here. + this.mapleADStar = new MapleADStar(); + // Preset an empty manipulator + this.manipulatorSim = new ManipulatorSim(); + /// Initialize simulations + this.drivetrainSim = config.chassis.createDriveTrainSim(config.queeningPose); + this.pathplannerConfig = config.chassis.updatePathplannerConfig(); + // Alliance string for telemetry. + this.allianceString = DriverStation.Alliance.Blue.equals(config.alliance) ? "Blue Alliance/" : "Red Alliance/"; + // NetworkTable setup. + this.statePublisher = NetworkTableInstance.getDefault() + .getStringTopic(config.telemetryPath + "SimulatedOpponents/States/" + + allianceString + config.name + "'s Current State").publish(); + this.posePublisher = NetworkTableInstance.getDefault() + .getStructTopic(config.telemetryPath + "SimulatedOpponents/Poses/" + + allianceString + config.name + "'s Pose2d", Pose2d.struct).publish(); + this.selectedBehaviorPublisher = NetworkTableInstance.getDefault() + .getTable(config.telemetryPath + "SimulatedOpponents/Behaviors/" + + allianceString + config.name + "'s Behaviors") + .getStringTopic("selected").publish(); + /// Adds the required states to run the {@link swervelib.simulation.ironmaple.simulation.opponentsim.SmartOpponent}. + config.withState("Standby", this::standbyState); + config.withState("Starting", () -> startingState("Collect")); + config.withState("Collect", this::collectState); + config.withState("Score", this::scoreState); + setState("Standby"); + /// Adds options to the behavior sendable chooser. + config.withBehavior("Disabled", runState("Standby", true), true); + config.withBehavior("Enabled", runState("Starting", true)); + // Update the chooser and then publish it. + SmartDashboard.putData( + config.smartDashboardPath + + "SimulatedOpponents/Behaviors/" + + allianceString + config.name + + "'s Behaviors", + config.updateBehaviorChooser()); + /// Run behavior command when changed. + config.getBehaviorChooser().onChange(Command::schedule); + /// Finally, add our simulation + SimulatedArena.getInstance().addDriveTrainSimulation(drivetrainSim.getDriveTrainSimulation()); + if (config.isAutoEnable) { + RobotModeTriggers.teleop() + .onTrue(Commands.runOnce( + () -> config.getBehaviorChooser().getSelected().schedule())); + RobotModeTriggers.disabled().onTrue(standbyState()); + } + /// If a manager is set register with it + if (config.manager != null) { + config.manager.registerOpponent(this); + } + // Initialize an empty target. + this.target = Pair.of("None", Pose2d.kZero); + /// Collision Detection + this.collisionDebouncer = new Debouncer(1, Debouncer.DebounceType.kRising); + /// Not Moving Detection + this.notMovingThreshold = FeetPerSecond.of(1); + this.notMovingTimer = new Timer(); + // Caches weighted poses for a faster search later. + config.loadWeightedPoses(); + } + + /** + * Returns whether the opponent is on the given alliance. + * + * @param alliance the alliance to check. + * @return whether the opponent is on the given alliance. + */ + public boolean isAlliance(DriverStation.Alliance alliance) { + return this.config.alliance == alliance; + } + + /** + * Updates the selected behavior {@link edu.wpi.first.wpilibj.smartdashboard.SendableChooser}, as if it was + * changed from the dashboard. This is done with a {@link StringPublisher} pointing to the + * {@link edu.wpi.first.wpilibj.smartdashboard.SendableChooser} selected string. + * + * @param behavior which option to select. + * @return a command that updated the selected behavior. + */ + protected Command setSelectedBehavior(String behavior) { + return runOnce(() -> selectedBehaviorPublisher.set(behavior)); + } + + /** + * The standby state to run. + * + * @return a Command that runs the state. + */ + protected Command standbyState() { + return run(() -> { + drivetrainSim.setSimulationWorldPose(config.queeningPose); + drivetrainSim.runChassisSpeeds(new ChassisSpeeds(), new Translation2d(), false, false); + restartInterrupt = false; + }).ignoringDisable(true); + } + + /** + * The starting state to run. + * + * @return a Command that runs the state. + */ + protected Command startingState(String nextState) { + return runOnce(() -> drivetrainSim.runChassisSpeeds(new ChassisSpeeds(), new Translation2d(), false, false)) + .andThen(runOnce(() -> drivetrainSim.setSimulationWorldPose(config.initialPose))) + .andThen(Commands.waitSeconds(0.25)) + .finallyDo(() -> setState(nextState)) + .ignoringDisable(config.isAutoEnable); // Only move to the field while disabled if autoEnable is off. + } + + /** + * The collect state to run. + * + * @return a runnable that runs the state. + */ + protected abstract Command collectState(); + + /** + * The score state to run. + * + * @return a runnable that runs the state. + */ + protected abstract Command scoreState(); + + @Override + public void simulationPeriodic() { + // If command not in progress and standby isn't the desired state. Or if a restartInterrupt occurred, restarting the current state. + if (!config.commandInProgress && !Objects.equals("Standby", config.desiredState)) { + runState(config.desiredState, false).schedule(); + } + // If restart requested, do that now. + if (restartInterrupt) { + runState(config.desiredState, true).schedule(); + notMovingTimer.restart(); + restartInterrupt = false; + } + // If we are very stuck reload from start. + if (notMovingTimer.hasElapsed(5)) { + drivetrainSim.setSimulationWorldPose(config.initialPose); + runState(config.desiredState, true).schedule(); + } + // If the timer is not running and a command is running and the opponent is not moving, start the timer. + if (!notMovingTimer.isRunning() && config.commandInProgress && !isMoving(notMovingThreshold)) { + notMovingTimer.restart(); + } else { + notMovingTimer.stop(); + } + statePublisher.set(config.currentState); + posePublisher.set(drivetrainSim.getActualPoseInSimulationWorld()); + } + + /** + * Sets the current state of the robot. This waits its turn patiently for the command to finish. + * + * @param state The state to set. + * @return this, for chaining. + */ + protected SmartOpponent setState(String state) { + config.desiredState = state; + return this; + } + + /** + * Runs a state as a command. + * + * @param state The state to run. + * @param forceState Whether to force the state to run even if it is already running. + * @return The command to run the state. + */ + protected Command runState(String state, boolean forceState) { + // If forceState, cancel any commands. + if (forceState) { + Command currentCommand = getCurrentCommand(); + if (currentCommand != null) { + currentCommand.cancel(); + } + return config.getStates().get(state).get(); + } + // Don't force the state. If there's a command running or already in state, wait. + if (config.currentState.equals(state) + || getCurrentCommand() != null + || (getCurrentCommand() != null && !getCurrentCommand().isFinished()) + && (!RobotModeTriggers.disabled().getAsBoolean() && config.isAutoEnable)) { + setState(state); // Make state wait for command to finish. + return Commands.none(); + } + // Nothing in the way, get our state. + return config.getStates().get(state).get(); + } + + /** + * Gets the current actual opponent pose. + * + * @return the opponent {@link Pose2d}. + */ + public Pose2d getOpponentPose() { + return drivetrainSim.getActualPoseInSimulationWorld(); + } + + /** + * Gets the opponent's current active target pose. + * + * @return either the opponent target pose or null if there is no active target. + */ + public Pair getTarget() { + return target; + } + + protected boolean isColliding() { + final var collisionFactor = + LinearFilter.movingAverage(50).calculate(Math.abs( + (Arrays.stream(drivetrainSim.getDriveTrainSimulation().getModules()).findFirst().get().getDriveMotorSupplyCurrent()).in(Amps) + - Arrays.stream(drivetrainSim.getDriveTrainSimulation().getModules()).findAny().get().getDriveMotorAppliedVoltage().in(Volts))); + return collisionDebouncer.calculate(MathUtil.isNear(0.6, collisionFactor, 0.3)); + } + + /** + * Pathfinds to a target pose. + * + * @param target The target. + * @return A command to pathfind to the target pose. + */ + public Command pathfind(Pair target, LinearVelocity desiredVelocity) { + if (Objects.isNull(target)) { + System.out.println(config.name + " Opponent's target is null, skipping this cycle."); + return Commands.none(); + } + this.target = Pair.of(target.getFirst(), ifShouldFlip(target.getSecond())); + // Add offset after setting flipped generic target. + final Pose2d finalPose = this.target.getSecond().plus(config.pathfindOffset); + /// Set up the pathfinder + mapleADStar.setStartPosition(drivetrainSim.getActualPoseInSimulationWorld().getTranslation()); + mapleADStar.setGoalPosition(finalPose.getTranslation()); + mapleADStar.runThread(); + return Commands.run(() -> { + // Initialize our poses and targets + final var currentPose = drivetrainSim.getActualPoseInSimulationWorld(); + final var waypoints = mapleADStar.currentWaypoints; + final Translation2d targetTranslation; + final Rotation2d targetRotation; + // If waypoints exist, load our next target. + if (!waypoints.isEmpty()) { + // Set anchor as a target. + targetTranslation = waypoints.get(0).anchor(); + // Incorrectly interpolate rotation goal. + targetRotation = currentPose.getRotation().interpolate(finalPose.getRotation(), waypoints.size()); + // If close to current target transfer to the next. + if (currentPose.getTranslation().getDistance(targetTranslation) < config.chassis.driveToPoseTolerance.times(3).in(Meters)) { + waypoints.remove(0); + } + // If no waypoints, set the final pose as the target. + } else { + targetTranslation = finalPose.getTranslation(); + targetRotation = finalPose.getRotation(); + } + final var targetPose = new Pose2d(targetTranslation, targetRotation); + final PathPlannerTrajectoryState state = new PathPlannerTrajectoryState(); + state.pose = targetPose; + // Run out calculated speeds. + drivetrainSim.runChassisSpeeds( + driveController.calculateRobotRelativeSpeeds( + currentPose, + state), new Translation2d(), false, false); + }, this) + .until(() -> { // Run until no waypoints and within tolerances. + List waypoints = mapleADStar.currentWaypoints; + return waypoints.isEmpty() && nearPose(finalPose, config.chassis.driveToPoseTolerance, config.chassis.driveToPoseAngleTolerance); + }) // If an opponent seems stuck, restart. + .until(() -> { + final boolean bool = notMovingFor(Seconds.of(0.5)) || isColliding(); + if (bool) { + notMovingTimer.restart(); + restartInterrupt = true; + } + return bool; + }) + // When finished, stop moving. + .finallyDo(() -> drivetrainSim.runChassisSpeeds(new ChassisSpeeds(), new Translation2d(), false, false)); + } + + /** + * Has the opponent run a new FollowPathCommand. + * + * @param path the path to follow. + * @return a follow path command. + */ + protected Command followPath(PathPlannerPath path) { + return new FollowPathCommand( + path, + () -> drivetrainSim.getActualPoseInSimulationWorld(), + () -> drivetrainSim.getActualSpeedsRobotRelative(), + (speeds, ffNotUsed) -> drivetrainSim.runChassisSpeeds(speeds, new Translation2d(), false, false), + driveController, + pathplannerConfig, + () -> config.alliance == DriverStation.Alliance.Blue, + this); + } + + /** + * A {@link Command} to drive the {@link SmartOpponent}. Meant to be used for joystick drives. + * + * @param chassisSpeeds speeds supplier to run the robot. + * @return {@link Command} to drive the {@link SmartOpponent}. + */ + protected Command drive(Supplier chassisSpeeds, boolean fieldCentric) { + if (fieldCentric) { + return run(() -> { + // Blue alliance faces 180°, Red faces 0° + Rotation2d driverFacing = + config.alliance.equals(DriverStation.Alliance.Blue) ? Rotation2d.k180deg : Rotation2d.kZero; + + // Convert to field-centric and run + ChassisSpeeds fieldSpeeds = ChassisSpeeds.fromRobotRelativeSpeeds(chassisSpeeds.get(), driverFacing); + drivetrainSim.runChassisSpeeds(fieldSpeeds, new Translation2d(), true, false); + }); + } + + // Robot-relative + return run(() -> drivetrainSim.runChassisSpeeds(chassisSpeeds.get(), new Translation2d(), false, false)); + } + + /** + * Gets a random pose from a map. If the map is empty reports an error and returns null. + * + * @param poseMap The map to get a pose from. + * @return A random pose from the map. + */ + protected Pair getRandomFromMap(Map poseMap) { + Map.Entry randomEntry = poseMap.entrySet().stream() + .skip(new Random().nextInt(poseMap.size())) + .findFirst() + .orElse(null); + + return randomEntry != null ? Pair.of(randomEntry.getKey(), randomEntry.getValue()) : null; + } + + /** + * Gets a random pose from a map. + * If the map is empty returns null. + * + * @param poseMap The map to get a pose from. + * @return A random pose from the map, unless empty. + */ + protected Pair getTargetFromMap(Map poseMap) { + final Map newMap = new HashMap<>(poseMap); + // Remove all already targeted poses. + newMap.values().removeAll(manager.getOpponentTargetsDynamic(config.pollRate)); // ignore warning, if it doesn't exist or match, nothing will be removed. + // Return null if empty, otherwise continue. + return newMap.isEmpty() ? null : getRandomFromMap(newMap); + } + + /** + * Gets a random scoring target based on pose weights. + * + * @return a random scoring target based on pose weights. + */ + protected Pair getScoringTarget() { + // If no entries exist, fail. + if (config.cachedScoringEntries.isEmpty()) { + return null; + } + + // Cache opponent targets and weight map to avoid repeated calls. + final var opponentTargets = manager.getOpponentTargetsDynamic(config.alliance, config.pollRate); + final var scoringWeights = config.getScoringWeights(); + double random = Math.random(); + double cumulativeWeight = 0; + double totalWeight = 0; + + // First pass: calculate total weight of available entries. + for (var entry : config.cachedScoringEntries) { + // Check both that the target is not already taken and not near any existing targets + if (!opponentTargets.contains(entry.getValue()) && + !manager.isNearTarget(entry.getValue(), config.pollRate, Meters.of(1.0))) { + totalWeight += scoringWeights.getOrDefault(entry.getKey(), 1.0); + } + } + + // If no available targets, fail. + if (totalWeight == 0) { + return null; + } + + // Scale random value by total weight for weighted selection. + random *= totalWeight; + + // Second pass: find weighted target using cumulative weights. + for (var entry : config.cachedScoringEntries) { + if (!opponentTargets.contains(entry.getValue())) { + cumulativeWeight += scoringWeights.getOrDefault(entry.getKey(), 1.0); + if (random <= cumulativeWeight) { + return Pair.of(entry.getKey(), entry.getValue()); + } + } + } + + // No target found (shouldn't happen if totalWeight > 0). + return null; + } + + /** + * Gets a random collect target based on pose weights. + * + * @return a random collect target based on pose weights. + */ + protected Pair getCollectTarget() { + // If no entries exist, fail. + if (config.cachedCollectingEntries.isEmpty()) { + return null; + } + + final var opponentTargets = manager.getOpponentTargetsDynamic(config.alliance, config.pollRate); + final var collectWeights = config.getCollectWeights(); + double random = Math.random(); + double cumulativeWeight = 0; + double totalWeight = 0; + + // First pass: calculate total weight of available entries. + for (var entry : config.cachedCollectingEntries) { + // Check both that the target is not already taken and not near any existing targets + if (!opponentTargets.contains(entry.getValue()) && + !manager.isNearTarget(entry.getValue(), config.pollRate, Meters.of(1.0))) { + totalWeight += collectWeights.getOrDefault(entry.getKey(), 1.0); + } + } + + // If no available targets, fail. + if (totalWeight == 0) { + return null; + } + + // Scale random value by total weight for weighted selection. + random *= totalWeight; + + // Second pass: find weighted target using cumulative weights. + for (var entry : config.cachedCollectingEntries) { + if (!opponentTargets.contains(entry.getValue())) { + cumulativeWeight += collectWeights.getOrDefault(entry.getKey(), 1.0); + if (random <= cumulativeWeight) { + return Pair.of(entry.getKey(), entry.getValue()); + } + } + } + + // No target found (shouldn't happen if totalWeight > 0). + return null; + } + + /** + * Checks if the {@link SmartOpponent} is near the given pose within a given tolerance. + * + * @param pose the pose to check against. + * @param tolerance the translation tolerance in {@link Distance}. + * @param angleTolerance the rotation tolerance in {@link Angle}. + * @return + */ + public boolean nearPose(Pose2d pose, Distance tolerance, Angle angleTolerance) { + Pose2d robotPose = drivetrainSim.getActualPoseInSimulationWorld(); + return robotPose.getTranslation().getDistance(pose.getTranslation()) < tolerance.in(Meters) + && Math.abs(robotPose.getRotation().minus(pose.getRotation()).getDegrees()) + < angleTolerance.in(Degrees); + } + + /** + * Checks if the {@link SmartOpponent} is moving within the given tolerance. This checks only the linear velocity. + * + * @param tolerance the movement speed tolerance in {@link LinearVelocity}. + * @return true if the robot is moving faster than the given tolerance. + */ + public boolean isMoving(LinearVelocity tolerance) { + final var speeds = drivetrainSim.getActualSpeedsRobotRelative(); + return speeds.vxMetersPerSecond > tolerance.in(MetersPerSecond) + || speeds.vyMetersPerSecond > tolerance.in(MetersPerSecond); + } + + /** + * Checks if the {@link SmartOpponent} has not been moving for given time. + * + * @param elapsedTime how long the robot should be stuck for. + * @return true if the robot has been stopped for the elaspedTime. + */ + public boolean notMovingFor(Time elapsedTime) { + return notMovingTimer.hasElapsed(elapsedTime.in(Seconds)) && !isMoving(notMovingThreshold); + } + + /** + * If robot is red, returns pose as is. If the robot is blue, it returns the flipped pose. + * + * @param pose The pose to flip. + * @return The flipped pose. + */ + protected Pose2d ifShouldFlip(Pose2d pose) { + if (config.alliance == DriverStation.Alliance.Blue) { + return pose; + } else { + return new Pose2d( + FieldMirroringUtils.flip(pose.getTranslation()), FieldMirroringUtils.flip(pose.getRotation())); + } + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/opponentsim/SmartOpponentConfig.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/opponentsim/SmartOpponentConfig.java new file mode 100644 index 0000000..7df2a54 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/opponentsim/SmartOpponentConfig.java @@ -0,0 +1,1639 @@ +package swervelib.simulation.ironmaple.simulation.opponentsim; + +import com.pathplanner.lib.config.RobotConfig; +import edu.wpi.first.math.Pair; +import edu.wpi.first.math.geometry.Pose2d; +import edu.wpi.first.math.geometry.Transform2d; +import edu.wpi.first.math.system.plant.DCMotor; +import edu.wpi.first.units.measure.*; +import edu.wpi.first.wpilibj.DriverStation; +import edu.wpi.first.wpilibj.smartdashboard.SendableChooser; +import edu.wpi.first.wpilibj2.command.Command; +import edu.wpi.first.wpilibj2.command.button.Trigger; +import swervelib.simulation.ironmaple.simulation.SimulatedArena; +import swervelib.simulation.ironmaple.simulation.drivesims.*; +import swervelib.simulation.ironmaple.simulation.drivesims.configs.DriveTrainSimulationConfig; +import swervelib.simulation.ironmaple.simulation.drivesims.configs.SwerveModuleSimulationConfig; + +import java.util.*; +import java.util.function.Supplier; + +import static edu.wpi.first.units.Units.*; + +/** + * The config is required to make a {@link SmartOpponent}. + * It should throw if configured wrong. + */ +public class SmartOpponentConfig { + /// Basic Required Options + public String name; + public DriverStation.Alliance alliance; + public Pose2d queeningPose; + public Pose2d initialPose; + /// Basic Optional Options + // Telemetry Options + public String telemetryPath; + public String smartDashboardPath; + protected final SendableChooser behaviorChooser; + // Joystick Options + protected Optional joystick = Optional.empty(); + public double joystickDeadband = 0.15; + // Pathfind pose offset translation to compensate for different chassis' + public Transform2d pathfindOffset; + // Auto Enable and Disable Opponent Support + public boolean isAutoEnable; + + /// Opponent Chassis Options + public ChassisConfig chassis; + + /// Maps using a (key, value) pair. Used to + // Map of the robot states. + private final Map> states = new HashMap<>(); + // Map of behaviour options + private final Map> behavior = new HashMap<>(); + // Map of possible scoring poses and types. For example, Map<"Hoops", Map<"CourtLeft", Pose2d>> + private final Map> scoringMap = new HashMap<>(); + // Map of possible collecting poses and types. For example, Map<"CollectStation", Map<"StationCenter", Pose2d>> + private final Map> collectingMap = new HashMap<>(); + // Map of scoring pose weights, if a weight is not defined, it defaults to 1.0. + private final Map scoringWeightMap = new HashMap<>(); + // Map of collect pose weights, if a weight is not defined, it defaults to 1.0. + private final Map collectWeightMap = new HashMap<>(); + /// Cached weighted maps for faster targeting. + // Cached entries for each pose. + public final List> cachedScoringEntries = new ArrayList<>(); + // Cached cumulative weights for a binary search. + public final List cachedScoringWeights = new ArrayList<>(); + // Cached entries for each pose. + public final List> cachedCollectingEntries = new ArrayList<>(); + // Cached cumulative weights for a binary search. + public final List cachedCollectingWeights = new ArrayList<>(); + + /// Opponent Management + protected OpponentManager manager; + protected Time pollRate; + public boolean commandInProgress = false; + // Opponents current and last states. + public String currentState = ""; + public String desiredState; + + /// Sets of required basic options + private final Set requiredBasicOptions; + + /** + * Default Constructor for SmartOpponentConfig. + */ + public SmartOpponentConfig() { + /// Sets the required basic options. + this.requiredBasicOptions = EnumSet.allOf(BasicOptions.class); + withPathfindOffset(Transform2d.kZero); // Sets a zero offset for default use. + withPollRate(SimulatedArena.getSimulationDt()); + + /// Prepares empty config. + this.chassis = new ChassisConfig(); + + /// Prepares Telemetry + withTelemetryPath("MapleSim/"); + this.behaviorChooser = new SendableChooser<>(); + } + + public void loadWeightedPoses() { + // Reset and load scoring poses + cachedScoringEntries.clear(); + cachedScoringEntries.addAll(getScoringMap().entrySet()); + double totalScoringWeight = 0.0; + + /// Cache our targets with a weight + for (Map.Entry entry : scoringWeightMap.entrySet()) { + // If no weight is set, default to 1.0 + double weight = scoringWeightMap.getOrDefault(entry.getKey(), 1.0); + totalScoringWeight += weight; + // Save our cumulative weight for a binary search + cachedScoringWeights.add(totalScoringWeight); + } + + // Reset and load collect poses + cachedCollectingEntries.clear(); + cachedCollectingEntries.addAll(getCollectingMap().entrySet()); + double totalCollectWeight = 0.0; + /// Cache our targets with a weight + for (Map.Entry entry : collectWeightMap.entrySet()) { + // If no weight is set, default to 1.0 + double weight = collectWeightMap.getOrDefault(entry.getKey(), 1.0); + totalCollectWeight += weight; + // Save our cumulative weight for a binary search + cachedCollectingWeights.add(totalCollectWeight); + } + } + + /** + * Constructor for SmartOpponentConfig with all required options set. + * + * @param name The robot's name. + * @param alliance The robot's alliance. + * @param initialPose The robot's initial pose. + * @param queeningPose The robot's queening pose. + * @param chassisConfig The robot's chassis config. + */ + public SmartOpponentConfig( + String name, + DriverStation.Alliance alliance, + Pose2d initialPose, + Pose2d queeningPose, + ChassisConfig chassisConfig) { + /// Creates a new config using the empty base. + this(); + /// Add required options to the checklist. + this.withName(name) + .withAlliance(alliance) + .withQueeningPose(queeningPose) + .withStartingPose(initialPose) + .withChassisConfig(chassisConfig); + } + + /** + * Sets the robot name. + * + * @param name The robot name. + * @return this, for chaining. + */ + public SmartOpponentConfig withName(String name) { + this.name = name; + this.requiredBasicOptions.remove(BasicOptions.Name); + return this; + } + + /** + * Sets the robot alliance. + * + * @param alliance The robot alliance. + * @return this, for chaining. + */ + public SmartOpponentConfig withAlliance(DriverStation.Alliance alliance) { + this.alliance = alliance; + this.requiredBasicOptions.remove(BasicOptions.Alliance); + return this; + } + + /** + * Adds a {@link OpponentManager} to register with. Set alliance and name beforehand. Sets these values as well + * withStartingPose() withQueeningPose() withCollectingMap() withScoringMap() + * + * @param manager the {@link OpponentManager} to use. + * @return this, for chaining. + * @return this, for chaining. + */ + public SmartOpponentConfig withManager(OpponentManager manager) { + if (alliance == null) { + DriverStation.reportError("Alliance is null", true); + } + this.manager = manager; + withStartingPose(this.manager.getInitialPose(alliance)) + .withQueeningPose(this.manager.getQueeningPose()) + .withCollectingMap(this.manager.getRawCollectingMap()) + .withScoringMap(this.manager.getRawScoringMap()); + return this; + } + + /** + * Gets this opponent's manager if registered. + * + * @return the {@link OpponentManager} being used. + */ + public OpponentManager getManager() { + if (manager == null) { + DriverStation.reportWarning("MapleSim getManager() returned null, no manager was found.", false); + return null; + } + return manager; + } + + /** + * Sets the queening pose. + * + * @param pose The pose to set the robot to. + * @return this, for chaining. + */ + public SmartOpponentConfig withQueeningPose(Pose2d pose) { + this.queeningPose = pose; + this.requiredBasicOptions.remove(BasicOptions.QueeningPose); + return this; + } + + /** + * Sets the initial pose. + * + * @param initialPose The initial pose. + * @return this, for chaining. + */ + public SmartOpponentConfig withStartingPose(Pose2d initialPose) { + this.initialPose = initialPose; + this.requiredBasicOptions.remove(BasicOptions.InitialPose); + return this; + } + + /** + * Sets the telemetry path. + * + * @param telemetryPath The telemetry path. + * @return this, for chaining. + */ + public SmartOpponentConfig withTelemetryPath(String telemetryPath) { + // Force a smartdashboard path since it's needed for the SendableChooser. + this.telemetryPath = "SmartDashboard/" + telemetryPath; + this.smartDashboardPath = telemetryPath; + return this; + } + + /** + * Sets the joystick to use. May or may not be used depending on the opponent's setup. + * + * @param joystick The joystick to use. + * @return this, for chaining. + */ + public SmartOpponentConfig withJoystick(Object joystick) { + this.joystick = Optional.of(joystick); + return this; + } + + /** + * Gets the optional joystick {@link Object}. Needs cast properly for use. + * + * @return the optional joystick {@link Object}. + */ + public Object getJoystick() { + if (joystick.isPresent()) { + return joystick.get(); + } + DriverStation.reportError("Joystick not found, returning null. Joystick is: " + joystick, true); + return null; + } + + /** + * Sets the joystick deadband. + * + * @param deadband The joystick deadband. + * @return this, for chaining. + */ + public SmartOpponentConfig withJoystickDeadband(double deadband) { + this.joystickDeadband = deadband; + return this; + } + + /** + * Sets the Pathfinding offset. + * + * @param pathfindOffset value to transform targets by. + * @return this, for chaining. + */ + public SmartOpponentConfig withPathfindOffset(Transform2d pathfindOffset) { + this.pathfindOffset = pathfindOffset; + return this; + } + + /** + * This sets a dynamic poll rate for various obstacle and pose getters. + * + * @param pollRate how long to wait before refreshing our getters. + * @return this, for chaining. + */ + public SmartOpponentConfig withPollRate(Time pollRate) { + this.pollRate = pollRate; + return this; + } + + /** + * Adds a scoring weight to a target pose. + * The weight is 1 by default, raise it to go there more often. + * + * @param weights the map of weights to add. + * @return this, for chaining. + */ + public SmartOpponentConfig withScoringPoseWeights(Map weights) { + this.scoringWeightMap.putAll(weights); + return this; + } + + /** + * Adds a scoring weight to a target pose. + * The weight is 1 by default, raise it to go there more often. + * + * @param name the pose to add it to. + * @param weight the weight to add. + * @return this, for chaining. + */ + public SmartOpponentConfig withScoringPoseWeights(String name, double weight) { + this.scoringWeightMap.put(name, weight); + return this; + } + + /** + * Gets the map of scoring weights. + * + * @return the map of scoring weights. + */ + public Map getScoringWeights() { + return scoringWeightMap; + } + + /** + * Adds a scoring weight to a target pose. + * The weight is 1 by default, raise it to go there more often. + * + * @param weights the map of weights to add. + * @return this, for chaining. + */ + public SmartOpponentConfig withCollectPoseWeights(Map weights) { + this.collectWeightMap.putAll(weights); + return this; + } + + /** + * Adds a scoring weight to a target pose. + * The weight is 1 by default, raise it to go there more often. + * + * @param name the pose to add it to. + * @param weight the weight to add. + * @return this, for chaining. + */ + public SmartOpponentConfig withCollectPoseWeights(String name, double weight) { + this.collectWeightMap.put(name, weight); + return this; + } + + /** + * Gets the map of collect weights. + * + * @return the map of collect weights. + */ + public Map getCollectWeights() { + return collectWeightMap; + } + + /** + * Sets the chassis config. This is the only input to encourage full configuration of the robot. + * + * @param chassisConfig The chassis config to set. + * @return this, for chaining. + */ + public SmartOpponentConfig withChassisConfig(ChassisConfig chassisConfig) { + this.chassis = chassisConfig; + return this; + } + + /** + * Enables automatically updating behavior with the RobotBase + * + * @return this, for chaining. + */ + public SmartOpponentConfig withAutoEnable() { + this.isAutoEnable = true; + return this; + } + + /** + * Setting for automatically updating behavior with the RobotBase + * + * @param autoEnable whether to enable. + * @return this, for chaining. + */ + public SmartOpponentConfig withAutoEnable(boolean autoEnable) { + this.isAutoEnable = autoEnable; + return this; + } + + /** + * Sets the current state of the robot. This waits it's turn patiently for the command to finish. + * + * @param state The state to set. + * @return this, for chaining. + */ + public SmartOpponentConfig setState(String state) { + desiredState = state; + return this; + } + + /** + * Adds a state to the config. + * + * @param stateName The name of the state. + * @param stateCommand The command to run when the state is entered. + * @return this, for chaining. + */ + public SmartOpponentConfig withState(String stateName, Supplier stateCommand) { + states.put(stateName, () -> stateCommand + .get() + .beforeStarting(() -> { + setState(stateName); + currentState = stateName; + commandInProgress = true; + }) + .finallyDo(() -> { + commandInProgress = false; + })); + return this; + } + + /** + * Removes a state from the config. + * + * @param stateName The name of the state to remove. + * @return this, for chaining. + */ + public SmartOpponentConfig removeState(String stateName) { + states.remove(stateName); + return this; + } + + /** + * Replaces a state's command. + * + * @param stateName The name of the state to replace. + * @param newStateCommand The new command to run when the state is entered. + * @return this, for chaining. + */ + public SmartOpponentConfig replaceStateCommand(String stateName, Supplier newStateCommand) { + states.replace(stateName, () -> newStateCommand + .get() + .beforeStarting(() -> { + setState(stateName); + currentState = stateName; + commandInProgress = true; + }) + .finallyDo(() -> { + commandInProgress = false; + })); + return this; + } + + /** + * Returns the state map. + * + * @return the state map. + */ + public Map> getStates() { + return states; + } + + /** + * Checks if the current state is equal to the given state. + * + * @param state the state to check. + * @return return true if states are the same. + */ + public boolean isState(String state) { + return currentState.equals(state); + } + + /** + * Checks if the current state is equal to the given state. + * + * @param state the state to check. + * @return return true if states are the same. + */ + public Trigger isStateTrigger(String state) { + return new Trigger(() -> currentState.equals(state)); + } + + /** + * Adds a behavior to the config. + * + * @param behaviorName The name of the behavior. + * @param behaviorCommand The command to run when the behavior is entered. + * @param isDefault whether this option should be the default. There can only be one. + * @return this, for chaining. + */ + public SmartOpponentConfig withBehavior(String behaviorName, Command behaviorCommand, boolean isDefault) { + behavior.put(behaviorName, Pair.of(behaviorCommand, isDefault)); + return this; + } + + /** + * Adds a non-default behavior to the config. + * + * @param behaviorName The name of the behavior. + * @param behaviorCommand The command to run when the behavior is entered. + * @return this, for chaining. + */ + public SmartOpponentConfig withBehavior(String behaviorName, Command behaviorCommand) { + return withBehavior(behaviorName, behaviorCommand, false); + } + + /** + * Removes a behavior from the config. + * + * @param behaviorName The name of the behavior to remove. + * @return this, for chaining. + */ + public SmartOpponentConfig removeBehavior(String behaviorName) { + behavior.remove(name); + return this; + } + + /** + * Replaces a behavior's command. + * + * @param behaviorName The name of the behavior to replace. + * @param newBehaviorCommand The new command to run when the behavior is entered. + * @param isDefault whether this option should be the default. There can only be one. + * @return this, for chaining. + */ + public SmartOpponentConfig replaceBehaviourCommand( + String behaviorName, Command newBehaviorCommand, boolean isDefault) { + behavior.put(name, Pair.of(newBehaviorCommand, isDefault)); + return this; + } + + /** + * Returns the behavior map. + * + * @return the behavior map. + */ + public Map> getBehavior() { + return behavior; + } + + /** + * Updates and gets the refreshed behavior {@link SendableChooser}. + * + * @return the refreshed behavior {@link SendableChooser}. + */ + public SendableChooser updateBehaviorChooser() { + boolean hasDefault = false; + /// Load all behaviours + for (Map.Entry> entry : behavior.entrySet()) { + // if behavior wants to be default. + if (entry.getValue().getSecond()) { + // Check if there is already a default. + if (hasDefault) { + // If there's multiple defaults report it. + DriverStation.reportError( + "Behaviour Chooser has multiple defaults, ignoring future defaults.", false); + // Then add it as normal + behaviorChooser.addOption(entry.getKey(), entry.getValue().getFirst()); + } else { + // If there are no issues, add the default. + behaviorChooser.setDefaultOption( + entry.getKey(), entry.getValue().getFirst()); + hasDefault = true; + } + } else { + // Behavior isn't default, add it like normal. + behaviorChooser.addOption(entry.getKey(), entry.getValue().getFirst()); + } + } + return behaviorChooser; + } + + /** + * Gets the behavior {@link SendableChooser}. + * + * @return the behavior {@link SendableChooser}. + */ + public SendableChooser getBehaviorChooser() { + return this.behaviorChooser; + } + + /** + * Adds all poses from an existing pose map. + * + * @param scoringMap the map to add. + * @return this, for chaining. + */ + public SmartOpponentConfig withScoringMap(Map> scoringMap) { + this.scoringMap.putAll(scoringMap); + return this; + } + + /** + * Adds a scoring pose to the config. + * + * @param poseType The type of pose to add. For example, "Hoops". + * @param poseName The name of the pose to add. For example, "CourtLeft". + * @param pose The pose to add. + * @return this, for chaining. + */ + public SmartOpponentConfig withScoringPose(String poseType, String poseName, Pose2d pose) { + scoringMap.putIfAbsent(poseType, new HashMap<>()); + scoringMap.get(poseType).putIfAbsent(poseName, pose); + if (scoringMap.get(poseType).get(poseName) != pose) { + throw new IllegalArgumentException("Failed to add score pose: " + poseName + "/n"); + } + return this; + } + + /** + * Removes a scoring pose from the config. + * + * @param poseType The type of pose to remove. + * @param poseName The name of the pose to remove. + * @return this, for chaining. + */ + public SmartOpponentConfig removeScoringPose(String poseType, String poseName) { + scoringMap.get(poseType).remove(poseName); + return this; + } + + /** + * Removes all scoring poses of a certain type from the config. + * + * @param poseType The type of poses to remove. + * @return this, for chaining. + */ + public SmartOpponentConfig removeScoringPoseType(String poseType) { + scoringMap.remove(poseType); + return this; + } + + /** + * Replaces a scoring pose. + * + * @param poseType The type of pose to replace. + * @param poseName The name of the pose to replace. + * @param pose The pose to replace with. + * @return this, for chaining. + */ + public SmartOpponentConfig replaceScoringPose(String poseType, String poseName, Pose2d pose) { + scoringMap.get(poseType).replace(poseName, pose); + return this; + } + + /** + * Gets the raw scoring map. Setup as Map> + * + * @return the raw scoring map. + */ + public Map> getRawScoringMap() { + return scoringMap; + } + + /** + * Compiles a compacted scoring map. Setup as Map + * + * @return a compacted scoring map. + */ + public Map getScoringMap() { + Map scoringPoses = new HashMap<>(); + scoringMap.forEach((poseType, poseMap) -> poseMap.forEach((name, pose) -> { + scoringPoses.put(poseType + " " + name, pose); + })); + return scoringPoses; + } + + /** + * Compiles a list of all scoring poses. + * + * @return a list of all scoring poses. + */ + public List getScoringPoses() { + List scoringPoses = new ArrayList<>(); + scoringMap.forEach((poseType, poseMap) -> poseMap.forEach((poseName, pose) -> scoringPoses.add(pose))); + return scoringPoses; + } + + /** + * Adds all poses from an existing pose map. + * + * @param collectingMap the map to add. + * @return this, for chaining. + */ + public SmartOpponentConfig withCollectingMap(Map> collectingMap) { + this.collectingMap.putAll(collectingMap); + return this; + } + + /** + * Adds a collecting pose to the config. + * + * @param poseType The type of pose to add. For example, "CollectStation". + * @param poseName The name of the pose to add. For example, "StationCenter". + * @param pose The pose to add. + * @return this, for chaining. + */ + public SmartOpponentConfig withCollectingPose(String poseType, String poseName, Pose2d pose) { + collectingMap.putIfAbsent(poseType, new HashMap<>()); + collectingMap.get(poseType).putIfAbsent(poseName, pose); + if (collectingMap.get(poseType).get(poseName) != pose) { + throw new IllegalArgumentException("Failed to add collect pose: " + poseName + "/n"); + } + return this; + } + + /** + * Removes a collecting pose from the config. + * + * @param poseType The type of pose to remove. + * @param poseName The name of the pose to remove. + * @return this, for chaining. + */ + public SmartOpponentConfig removeCollectingPose(String poseType, String poseName) { + collectingMap.get(poseType).remove(poseName); + return this; + } + + /** + * Removes all collecting poses of a certain type from the config. + * + * @param poseType The type of poses to remove. + * @return this, for chaining. + */ + public SmartOpponentConfig removeCollectingPoseType(String poseType) { + collectingMap.remove(poseType); + return this; + } + + /** + * Replaces a collecting pose. + * + * @param poseType The type of pose to replace. + * @param poseName The name of the pose to replace. + * @param pose The pose to replace with. + * @return this, for chaining. + */ + public SmartOpponentConfig replaceCollectingPose(String poseType, String poseName, Pose2d pose) { + collectingMap.get(poseType).replace(poseName, pose); + return this; + } + + /** + * Gets the raw collecting map. Setup as Map> + * + * @return the raw collecting map. + */ + public Map> getRawCollectingMap() { + return collectingMap; + } + + /** + * Compiles a compacted collecting map. Setup as Map + * + * @return a compacted collecting map. + */ + public Map getCollectingMap() { + Map collectingPoses = new HashMap<>(); + collectingMap.forEach((poseType, poseMap) -> poseMap.forEach((name, pose) -> + collectingPoses.put(poseType + " " + name, pose))); + return collectingPoses; + } + + /** + * Compiles a list of all collecting poses. + * + * @return a list of all collecting poses. + */ + public List getCollectingPoses() { + List collectingPoses = new ArrayList<>(); + collectingMap.forEach((poseType, poseMap) -> poseMap.forEach((poseName, pose) -> collectingPoses.add(pose))); + return collectingPoses; + } + + /** + * Checks if the config is valid. + * + * @return true if the config is valid, false otherwise. + * @throws IllegalArgumentException if any config is incorrect. + */ + public boolean validateConfigs() { + boolean validConfig = chassis.validConfig() && requiredBasicOptions.isEmpty(); + // If not set correct, report settings to update. Then throw an error. + if (!validConfig) { + for (BasicOptions option : requiredBasicOptions) { + DriverStation.reportWarning( + "Required Option: " + option.toString() + " not set in SmartOpponentConfig", true); + } + throw new IllegalArgumentException( + "Invalid SmartOpponentConfig, check DriverStation Output for more info."); + } + // If any required options aren't removed, return false. + return validConfig; + } + + /** + * Basic Options that MUST be set for the {@link SmartOpponentConfig} to be valid. + */ + private enum BasicOptions { + /// Required Basic Options + /// Robot Name + Name, + /// Robot Alliance + Alliance, + /// Queening Pose + QueeningPose, + /// Starting Pose + InitialPose + } + + /** + * The SmartOpponent's Chassis Config, this is an inner config that is only chassis configuration. + */ + public static class ChassisConfig { + /// Required chassis options to be set later. + public Distance trackWidth; + public Distance trackLength; + public Distance bumperWidth; + public Distance bumperLength; + public Mass mass; + public MomentOfInertia moi; + public LinearVelocity maxLinearVelocity; + public AngularVelocity maxAngularVelocity; + public ModuleConfig module; + /// Optional chassis options + public Distance driveToPoseTolerance; + public Angle driveToPoseAngleTolerance; + public Supplier gyroSimulation; + /// Sets of required options set here. + public Set requiredChassisOptions; + public LinearAcceleration maxLinearAcceleration; + public AngularAcceleration maxAngularAcceleration; + // Saved simulation for later use + private SwerveModuleSimulationConfig moduleSimConfig; + public RobotConfig pathplannerConfig; + + /** + * Default constructor for ChassisConfig. Each Option must be set individually. + */ + ChassisConfig() { + /// Adds the required options to the checklist. + this.requiredChassisOptions = EnumSet.allOf(ChassisOptions.class); + /// Optional chassis options + this.driveToPoseTolerance = Inches.of(2); + this.driveToPoseAngleTolerance = Degrees.of(6); + this.gyroSimulation = COTS.ofGenericGyro(); + } + + /** + * Constructor for ChassisConfig. + * + * @param trackWidth the distance from one center of a rear wheel to the other. + * @param trackHeight the distance from one center of a left or right wheel to the other. + * @param bumperWidth the distance from the left of the robot to the right with bumpers. + * @param bumperHeight the distance from the front of the robot to the rear with the bumpers. + * @param mass the mass of the robot. + * @param moi the moment of inertia of the robot. + * @param maxLinearVelocity the max linear velocity of the robot. + * @param maxLinearAcceleration the max linear acceleration of the robot. + * @param maxAngularVelocity the max angular velocity of the robot. + * @param maxAngularAcceleration the max angular acceleration of the robot. + * @param module the {@link ModuleConfig} for the robot's swerve modules. + */ + ChassisConfig( + Distance trackWidth, + Distance trackHeight, + Distance bumperWidth, + Distance bumperHeight, + Mass mass, + MomentOfInertia moi, + LinearVelocity maxLinearVelocity, + LinearAcceleration maxLinearAcceleration, + AngularVelocity maxAngularVelocity, + AngularAcceleration maxAngularAcceleration, + ModuleConfig module) { + /// Creates a new config using the empty base. + this(); + /// Add required options to the checklist. + this.withTrackWidth(trackWidth) + .withTrackLength(trackHeight) + .withBumperWidth(bumperWidth) + .withBumperHeight(bumperHeight) + .withMass(mass) + .withMOI(moi) + .withMaxLinearVelocity(maxLinearVelocity) + .withMaxLinearAcceleration(maxLinearAcceleration) + .withMaxAngularVelocity(maxAngularVelocity) + .withMaxAngularAcceleration(maxAngularAcceleration) + .withModule(module); + } + + /** + * Constructor for ChassisConfig. + * + * @param mass The mass of the robot. + * @param moi The moment of inertia of the robot. + * @param maxLinearVelocity The max linear velocity of the robot. + * @param maxAngularVelocity The max angular velocity of the robot. + * @param wheelRadius the module's wheel radius. + * @param wheelCOF the module's drive Coefficient of Friction. + * @param driveMotor the module's drive motor. + * @param driveCurrentLimit the module's drive current limit. + */ + ChassisConfig( + Distance trackWidth, + Distance trackHeight, + Distance bumperWidth, + Distance bumperHeight, + Mass mass, + MomentOfInertia moi, + LinearVelocity maxLinearVelocity, + LinearAcceleration maxLinearAcceleration, + AngularVelocity maxAngularVelocity, + AngularAcceleration maxAngularAcceleration, + Distance wheelRadius, + double wheelCOF, + DCMotor driveMotor, + DCMotor steerMotor, + double driveGearRatio, + double steerGearRatio, + Voltage driveFrictionVoltage, + Voltage steerFrictionVoltage, + MomentOfInertia steerAngularInertia, + LinearVelocity maxDriveVelocity, + Current driveCurrentLimit) { + /// Creates a new config from the previous constructor with a manually set ModuleConfig + this( + trackWidth, + trackHeight, + bumperWidth, + bumperHeight, + mass, + moi, + maxLinearVelocity, + maxLinearAcceleration, + maxAngularVelocity, + maxAngularAcceleration, + new ModuleConfig( + wheelRadius, + wheelCOF, + driveMotor, + steerMotor, + driveGearRatio, + steerGearRatio, + driveFrictionVoltage, + steerFrictionVoltage, + steerAngularInertia, + maxDriveVelocity, + driveCurrentLimit)); + } + + /** + * Creates a new SwerveDriveSimulation from the current ChassisConfig. + * + * @param initialPose the initial pose of the robot. + * @return a new SwerveDriveSimulation from the current ChassisConfig. + */ + public SelfControlledSwerveDriveSimulation createDriveTrainSim(Pose2d initialPose) { + if (!validConfig()) { + throw new IllegalStateException("Config is not valid! Cannot create the driveTrain simulation!"); + } + if (module.driveMotor == null || module.steerMotor == null) { + throw new IllegalStateException( + "ModuleConfig has null motors! Drive: " + module.driveMotor + ", Steer: " + module.steerMotor); + } + return new SelfControlledSwerveDriveSimulation(new SwerveDriveSimulation( + new DriveTrainSimulationConfig( + mass, + bumperLength, + bumperWidth, + trackLength, + trackWidth, + gyroSimulation, + () -> new SwerveModuleSimulation(moduleSimConfig) // Force new sims from the config. + // Disable global battery draw quick fix. + ), + initialPose)); + } + + /** + * Creates a new RobotConfig from the current ChassisConfig. + * + * @return the new RobotConfig. + */ + public RobotConfig updatePathplannerConfig() { + this.pathplannerConfig = new RobotConfig(mass, moi, module.updatePathplannerModuleConfig(), trackWidth); + return this.pathplannerConfig; + } + + /** + * Checks if the config is valid. + * + * @return true if the config is valid, false otherwise. + */ + public boolean validConfig() { + boolean validConfig = module.validConfig() && requiredChassisOptions.isEmpty(); + if (!validConfig) { + for (ChassisOptions option : requiredChassisOptions) { + DriverStation.reportWarning( + "Required Option: " + option.toString() + " not set in ChassisConfig", false); + } + } + // If any required options aren't removed, return false. + return validConfig; + } + + /** + * Sets the track width of the robot. This is from one center of the wheel to the other. + * + * @param trackWidth The track width of the robot. + * @return this, for chaining. + */ + public ChassisConfig withTrackWidth(Distance trackWidth) { + this.trackWidth = trackWidth; + this.requiredChassisOptions.remove(ChassisOptions.TrackWidth); + return this; + } + + /** + * Sets the track height of the robot. + * + * @param trackHeight The track height of the robot. + * @return this, for chaining. + */ + public ChassisConfig withTrackLength(Distance trackHeight) { + this.trackLength = trackHeight; + this.requiredChassisOptions.remove(ChassisOptions.TrackLength); + return this; + } + + /** + * Sets the bumper width of the robot. + * + * @param bumperWidth The bumper width of the robot. + * @return this, for chaining. + */ + public ChassisConfig withBumperWidth(Distance bumperWidth) { + this.bumperWidth = bumperWidth; + this.requiredChassisOptions.remove(ChassisOptions.BumperWidth); + return this; + } + + /** + * Sets the bumper height of the robot. + * + * @param bumperHeight The bumper height of the robot. + * @return this, for chaining. + */ + public ChassisConfig withBumperHeight(Distance bumperHeight) { + this.bumperLength = bumperHeight; + this.requiredChassisOptions.remove(ChassisOptions.BumperLength); + return this; + } + + /** + * Simplified Chassis Configuration for a square robot. Sets the bumper width and height to the same value. + * + * @param bumperLength the length of the bumpers. + * @param trackLength the track width of the robot. This is from one center of the wheel to the other. + * @return this, for chaining. + */ + public ChassisConfig withSquareChassis(Distance bumperLength, Distance trackLength) { + return this.withBumperWidth(bumperLength) + .withBumperHeight(bumperLength) + .withTrackWidth(trackLength) + .withTrackLength(trackLength); + } + + /** + * Sets the mass of the robot. + * + * @param mass The mass of the robot. + * @return this, for chaining. + */ + public ChassisConfig withMass(Mass mass) { + this.mass = mass; + this.requiredChassisOptions.remove(ChassisOptions.Mass); + return this; + } + + /** + * Sets the moment of inertia of the robot. + * + * @param moi The moment of inertia of the robot. + * @return this, for chaining. + */ + public ChassisConfig withMOI(MomentOfInertia moi) { + this.moi = moi; + this.requiredChassisOptions.remove(ChassisOptions.MOI); + return this; + } + + /** + * Sets the max linear velocity of the robot. + * + * @param maxLinearVelocity The max linear velocity of the robot. + * @return this, for chaining. + */ + public ChassisConfig withMaxLinearVelocity(LinearVelocity maxLinearVelocity) { + this.maxLinearVelocity = maxLinearVelocity; + this.requiredChassisOptions.remove(ChassisOptions.MaxLinearVelocity); + return this; + } + + /** + * Sets the max linear acceleration of the robot. + * + * @param maxLinearAcceleration The max linear acceleration of the robot. + * @return this, for chaining. + */ + public ChassisConfig withMaxLinearAcceleration(LinearAcceleration maxLinearAcceleration) { + this.maxLinearAcceleration = maxLinearAcceleration; + this.requiredChassisOptions.remove(ChassisOptions.MaxLinearAcceleration); + return this; + } + + /** + * Sets the max angular velocity of the robot. + * + * @param maxAngularVelocity The max angular velocity of the robot. + * @return this, for chaining. + */ + public ChassisConfig withMaxAngularVelocity(AngularVelocity maxAngularVelocity) { + this.maxAngularVelocity = maxAngularVelocity; + this.requiredChassisOptions.remove(ChassisOptions.MaxAngularVelocity); + return this; + } + + /** + * Sets the max angular acceleration of the robot. + * + * @param maxAngularAcceleration The max angular acceleration of the robot. + * @return this, for chaining. + */ + public ChassisConfig withMaxAngularAcceleration(AngularAcceleration maxAngularAcceleration) { + this.maxAngularAcceleration = maxAngularAcceleration; + this.requiredChassisOptions.remove(ChassisOptions.MaxAngularAcceleration); + return this; + } + + /** + * Sets the module config. + * + * @param module The module config. + * @return this, for chaining. + */ + public ChassisConfig withModule(ModuleConfig module) { + this.module = module; + this.moduleSimConfig = module.createModuleSimConfig(); + this.requiredChassisOptions.remove(ChassisOptions.ModuleConfig); + return this; + } + + /** + * Sets the tolerance for the drive to pose command. + * + * @param tolerance the tolerance for the drive to pose command. + * @return this, for chaining. + */ + public ChassisConfig withDriveToPoseTolerance(Distance tolerance) { + this.driveToPoseTolerance = tolerance; + return this; + } + + public ChassisConfig withDriveToPoseAngleTolerance(Angle tolerance) { + this.driveToPoseAngleTolerance = tolerance; + return this; + } + + /** + * Sets the gyro simulation for the robot. + * + * @param gyroSimulation + * @return + */ + public ChassisConfig withGyroSimulation(Supplier gyroSimulation) { + this.gyroSimulation = gyroSimulation; + return this; + } + + /** + * Chassis Options that MUST be set for the {@link SmartOpponentConfig} to be valid. + */ + public enum ChassisOptions { + /// Required Opponent Chassis Options + /// Opponent Robot Track Width + TrackWidth, + /// Opponent Robot Track Height + TrackLength, + /// Opponent Robot Bumper Width + BumperWidth, + /// Opponent Robot Bumper Height + BumperLength, + /// Opponent Robot Mass + Mass, + /// Opponent Robot Moment of Inertia + MOI, + /// Opponent Robot Max Linear Velocity + MaxLinearVelocity, + /// Opponent Robot Max Linear Acceleration + MaxLinearAcceleration, + /// Opponent Robot Max Angular Velocity + MaxAngularVelocity, + /// Opponent Robot Max Angular Acceleration + MaxAngularAcceleration, + /// Opponent Module Config + ModuleConfig + } + + /** + * A few chassis presets to simplify configs that don't need to be specific. + */ + public enum Presets { + ///

    Opponent Swerve Chassis config presets to ease creation.

    + /// A simple config that defaults harder values to viable values. + SimpleSetup, + /// A basic square robot. Made to match the AdvantageScope basic assets. + SimpleSquareChassis; + + /** + * Returns a new ChassisConfig for the preset. Each call returns a fresh, independent instance. + * + * @return a new ChassisConfig for the preset. + */ + public ChassisConfig getConfig() { + return switch (this) { + case SimpleSetup -> new ChassisConfig() + .withMOI(KilogramSquareMeters.of(8)) + .withModule(ModuleConfig.Presets.SimpleSetup.getConfig()); + case SimpleSquareChassis -> new ChassisConfig() + .withSquareChassis(Inches.of(32), Inches.of(23)) // 32x32 bumper, 24 track width + .withMass(Kilograms.of(55)) + .withMOI(KilogramSquareMeters.of(8)) + .withMaxLinearVelocity(MetersPerSecond.of(8.5)) + .withMaxLinearAcceleration(MetersPerSecondPerSecond.of(12)) + .withMaxAngularVelocity(DegreesPerSecond.of(360)) + .withMaxAngularAcceleration(DegreesPerSecondPerSecond.of(480)) + .withModule(ModuleConfig.Presets.MK4i.getConfig()); + }; + } + } + + /** + * Loads another config into this config. + * + * @param other the config to copy. + * @return return the updated config. + */ + public ChassisConfig copy(ChassisConfig other) { + this.withTrackWidth(other.trackWidth) + .withTrackLength(other.trackLength) + .withBumperWidth(other.bumperWidth) + .withBumperHeight(other.bumperLength) + .withMass(other.mass) + .withMOI(other.moi) + .withMaxLinearVelocity(other.maxLinearVelocity) + .withMaxAngularVelocity(other.maxAngularVelocity) + .withModule(ModuleConfig.clone(other.module)); + return this; + } + + /** + * Creates a new clone of a config. + * + * @param other the config to clone. + * @return the newly cloned config. + */ + public static ChassisConfig clone(ChassisConfig other) { + return new ChassisConfig().copy(other); + } + } + + /** + * The SmartOpponent's Module Config, this is an inner config that is only the module configuration. + */ + public static class ModuleConfig { + /// Constants to be initialized in the constructor. + public Distance wheelRadius; + public double wheelCOF; + public DCMotor driveMotor; + public DCMotor steerMotor; + public double driveGearRatio; + public double steerGearRatio; + public Voltage driveFrictionVoltage; + public Voltage steerFrictionVoltage; + public MomentOfInertia steerAngularInertia; + public LinearVelocity maxDriveVelocity; + public Current driveCurrentLimit; + /// Set of required options for the ModuleConfig + public Set requiredModuleOptions; + // Saved objects for later use. + public SwerveModuleSimulation moduleSim; + public com.pathplanner.lib.config.ModuleConfig pathplannerModuleConfig; + + /** + * Empty constructor for ModuleConfig. Each Option must be set individually. + */ + ModuleConfig() { + /// Add required options to the checklist. + this.requiredModuleOptions = EnumSet.allOf(ModuleOptions.class); + } + + /** + * Constructor for ModuleConfig. + * + * @param wheelRadius the wheel radius. + * @param wheelCOF the wheel Coefficient of Friction. + * @param driveMotor the drive {@link DCMotor}. + * @param driveCurrentLimit the drive {@link Current} limit. + */ + ModuleConfig( + Distance wheelRadius, + double wheelCOF, + DCMotor driveMotor, + DCMotor steerMotor, + double driveGearRatio, + double steerGearRatio, + Voltage driveFrictionVoltage, + Voltage steerFrictionVoltage, + MomentOfInertia steerAngularInertia, + LinearVelocity maxDriveVelocity, + Current driveCurrentLimit) { + /// Creates a new config using the empty base. + this(); + /// Add required options to the checklist. + this.withWheelRadius(wheelRadius) + .withWheelCOF(wheelCOF) + .withDriveMotor(driveMotor) + .withSteerMotor(steerMotor) + .withDriveGearRatio(driveGearRatio) + .withSteerGearRatio(steerGearRatio) + .withDriveFrictionVoltage(driveFrictionVoltage) + .withSteerFrictionVoltage(steerFrictionVoltage) + .withSteerAngularInertia(steerAngularInertia) + .withMaxDriveVelocity(maxDriveVelocity) + .withDriveCurrentLimit(driveCurrentLimit); + } + + /** + * Creates a new {@link SwerveModuleSimulation} from a {@link com.pathplanner.lib.config.ModuleConfig}. Gets + * saved for later use. + * + * @return the new {@link SwerveModuleSimulation}. + */ + public SwerveModuleSimulationConfig createModuleSimConfig() { + return new SwerveModuleSimulationConfig( + driveMotor, + steerMotor, + driveGearRatio, + steerGearRatio, + driveFrictionVoltage, + steerFrictionVoltage, + wheelRadius, + steerAngularInertia, + wheelCOF); + } + + /** + * Creates a new {@link com.pathplanner.lib.config.ModuleConfig} from a + * {@link com.pathplanner.lib.config.ModuleConfig}. + * + * @return the new {@link com.pathplanner.lib.config.ModuleConfig}. + */ + public com.pathplanner.lib.config.ModuleConfig updatePathplannerModuleConfig() { + this.pathplannerModuleConfig = new com.pathplanner.lib.config.ModuleConfig( + wheelRadius, + maxDriveVelocity, + wheelCOF, + driveMotor, + driveCurrentLimit, + 1); // Hard set until someone complains + return this.pathplannerModuleConfig; + } + + /** + * Checks if the config is valid. + * + * @return true if the config is valid, false otherwise. + */ + public boolean validConfig() { + boolean validConfig = requiredModuleOptions.isEmpty(); + if (!validConfig) { + for (ModuleOptions option : requiredModuleOptions) { + DriverStation.reportError( + "Required Option: " + option.toString() + " not set in ModuleConfig", false); + } + } + return validConfig; + } + + /** + * Sets the wheel radius. + * + * @param wheelRadius The wheel radius. + * @return this, for chaining. + */ + public ModuleConfig withWheelRadius(Distance wheelRadius) { + this.wheelRadius = wheelRadius; + this.requiredModuleOptions.remove(ModuleOptions.WheelRadius); + return this; + } + + /** + * Sets the wheel Coefficient of Friction. + * + * @param wheelCOF The wheel Coefficient of Friction. + * @return this, for chaining. + */ + public ModuleConfig withWheelCOF(double wheelCOF) { + this.wheelCOF = wheelCOF; + this.requiredModuleOptions.remove(ModuleOptions.WheelCOF); + return this; + } + + /** + * Sets the drive {@link DCMotor}. + * + * @param driveMotor The drive {@link DCMotor}. + * @return this, for chaining. + */ + public ModuleConfig withDriveMotor(DCMotor driveMotor) { + this.driveMotor = driveMotor; + this.requiredModuleOptions.remove(ModuleOptions.DriveMotor); + return this; + } + + /** + * Sets the steer {@link DCMotor}. + * + * @param dcMotor The steer {@link DCMotor}. + * @return this, for chaining. + */ + public ModuleConfig withSteerMotor(DCMotor dcMotor) { + this.steerMotor = dcMotor; + this.requiredModuleOptions.remove(ModuleOptions.SteerMotor); + return this; + } + + /** + * Sets the gear ratios for the drive motor. + * + * @param driveGearRatio The gear ratio for the drive motor. + * @return this, for chaining. + */ + public ModuleConfig withDriveGearRatio(double driveGearRatio) { + this.driveGearRatio = driveGearRatio; + //this.driveMotor = driveMotor.withReduction(driveGearRatio); + this.requiredModuleOptions.remove(ModuleOptions.DriveRatio); + return this; + } + + /** + * Sets the gear ratio for the steer motor. + * + * @param steerGearRatio The gear ratio for the steer motor. + * @return this, for chaining. + */ + public ModuleConfig withSteerGearRatio(double steerGearRatio) { + this.steerGearRatio = steerGearRatio; + //this.steerMotor = steerMotor.withReduction(steerGearRatio); + this.requiredModuleOptions.remove(ModuleOptions.SteerRatio); + return this; + } + + /** + * Sets the friction voltage for the drive motor. + * + * @param driveFrictionVoltage The friction voltage for the drive motor. + * @return this, for chaining. + */ + public ModuleConfig withDriveFrictionVoltage(Voltage driveFrictionVoltage) { + this.driveFrictionVoltage = driveFrictionVoltage; + this.requiredModuleOptions.remove(ModuleOptions.DriveFrictionVoltage); + return this; + } + + /** + * Sets the friction voltage for the steer motor. + * + * @param steerFrictionVoltage The friction voltage for the steer motor. + * @return this, for chaining. + */ + public ModuleConfig withSteerFrictionVoltage(Voltage steerFrictionVoltage) { + this.steerFrictionVoltage = steerFrictionVoltage; + this.requiredModuleOptions.remove(ModuleOptions.SteerFrictionVoltage); + return this; + } + + /** + * Sets the steer angular inertia. + * + * @param steerAngularInertia The steer angular inertia. + * @return this, for chaining. + */ + public ModuleConfig withSteerAngularInertia(MomentOfInertia steerAngularInertia) { + this.steerAngularInertia = steerAngularInertia; + this.requiredModuleOptions.remove(ModuleOptions.SteerAngularInertia); + return this; + } + + /** + * Sets the max drive velocity. + * + * @param maxDriveVelocity The max drive velocity. + * @return this, for chaining. + */ + public ModuleConfig withMaxDriveVelocity(LinearVelocity maxDriveVelocity) { + this.maxDriveVelocity = maxDriveVelocity; + this.requiredModuleOptions.remove(ModuleOptions.MaxDriveVelocity); + return this; + } + + /** + * Sets the drive {@link Current} limit. + * + * @param driveCurrentLimit The drive {@link Current} limit. + * @return this, for chaining. + */ + public ModuleConfig withDriveCurrentLimit(Current driveCurrentLimit) { + this.driveCurrentLimit = driveCurrentLimit; + this.requiredModuleOptions.remove(ModuleOptions.DriveCurrentLimit); + return this; + } + + /** + * Module Options that MUST be set for the {@link SmartOpponentConfig} to be valid. + */ + public enum ModuleOptions { + /// Required Opponent Drive Module Options + /// Opponent Drive Module Wheel Radius + WheelRadius, + /// Opponent Drive Wheel Coefficient of Friction + WheelCOF, + /// Opponent Drive DCMotor + DriveMotor, + /// Opponent Steer DCMotor + SteerMotor, + /// Opponent Drive Ratio + DriveRatio, + /// Opponent Steer Ratio + SteerRatio, + /// Opponent Drive Friction Voltage + DriveFrictionVoltage, + /// Opponent Steer Friction Voltage + SteerFrictionVoltage, + /// Opponent Steer Angular Inertia + SteerAngularInertia, + /// Opponent Drive Motor Max Velocity + MaxDriveVelocity, + /// Opponent Drive Module Current Limit + DriveCurrentLimit + } + + /** + * A few module presets to simplify configs that don't need to be specific. + */ + public enum Presets { + ///

    Opponent Swerve module config presets to ease creation.

    + /// A simple config that defaults harder values to viable values. + SimpleSetup, + /// WCP MK4i Swerve Module with Neo Drive motor. + MK4i; + + /** + * Returns a new ModuleConfig for the preset. Each call returns a fresh, independent instance. + * + * @return a new ModuleConfig for the preset. + */ + public ModuleConfig getConfig() { + return switch (this) { + case SimpleSetup -> new ModuleConfig() + .withWheelRadius(Inches.of(2)) + .withWheelCOF(1.19) + .withDriveFrictionVoltage(Volts.of(0.3)) + .withSteerFrictionVoltage(Volts.of(0.2)) + .withDriveCurrentLimit(Amps.of(40)); + case MK4i -> new ModuleConfig() + .withWheelRadius(Inches.of(2)) + .withWheelCOF(1.19) + .withDriveMotor(DCMotor.getNEO(1)) + .withSteerMotor(DCMotor.getNEO(1)) + .withDriveGearRatio(6.75) // L2 Ratio + .withSteerGearRatio(150 / 7.0) // MK4i Steer Ratio Calculation + .withDriveFrictionVoltage(Volts.of(0.3)) + .withSteerFrictionVoltage(Volts.of(0.2)) + .withSteerAngularInertia(KilogramSquareMeters.of(0.03)) + .withMaxDriveVelocity(MetersPerSecond.of(10)) + .withDriveCurrentLimit(Amps.of(40)); + }; + } + } + + /** + * Copies the ModuleConfig from another ModuleConfig. + * + * @param other the other ModuleConfig to copy from. + * @return this, for chaining. + */ + public ModuleConfig copy(ModuleConfig other) { + withWheelRadius(other.wheelRadius); + withWheelCOF(other.wheelCOF); + withDriveMotor(other.driveMotor); + withSteerMotor(other.steerMotor); + withDriveGearRatio(other.driveGearRatio); + withSteerGearRatio(other.steerGearRatio); + withDriveFrictionVoltage(other.driveFrictionVoltage); + withSteerFrictionVoltage(other.steerFrictionVoltage); + withSteerAngularInertia(other.steerAngularInertia); + withMaxDriveVelocity(other.maxDriveVelocity); + withDriveCurrentLimit(other.driveCurrentLimit); + return this; + } + + /** + * Constructs a new {@link ModuleConfig} from a {@link ModuleConfig}. + * + * @param other the other ModuleConfig to copy from. + * @return the new ModuleConfig. + */ + public static ModuleConfig clone(ModuleConfig other) { + return new ModuleConfig().copy(other); + } + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/opponentsim/pathfinding/MapleADStar.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/opponentsim/pathfinding/MapleADStar.java new file mode 100644 index 0000000..ab1d580 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/opponentsim/pathfinding/MapleADStar.java @@ -0,0 +1,771 @@ +package swervelib.simulation.ironmaple.simulation.opponentsim.pathfinding; + +import com.pathplanner.lib.path.GoalEndState; +import com.pathplanner.lib.path.PathConstraints; +import com.pathplanner.lib.path.PathPlannerPath; +import com.pathplanner.lib.path.Waypoint; +import com.pathplanner.lib.pathfinding.Pathfinder; +import edu.wpi.first.math.Pair; +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.wpilibj.Filesystem; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.util.*; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * Implementation of AD* running locally in a background thread + *

    + * COPIED INTO MapleSim with minor modifications exposing things. + * + *

    I would like to apologize to anyone trying to understand this code. The implementation I + * translated it from was much worse. + */ +public class MapleADStar implements Pathfinder { + private static final double SMOOTHING_ANCHOR_PCT = 0.8; + private static final double EPS = 2.5; + public final Set requestObstacles = new HashSet<>(); + private final HashMap g = new HashMap<>(); + private final HashMap rhs = new HashMap<>(); + private final HashMap> open = new HashMap<>(); + private final HashMap> incons = new HashMap<>(); + private final Set closed = new HashSet<>(); + private final Set staticObstacles = new HashSet<>(); + private final Set dynamicObstacles = new HashSet<>(); + private final Thread planningThread; + private final ReadWriteLock pathLock = new ReentrantReadWriteLock(); + private final ReadWriteLock requestLock = new ReentrantReadWriteLock(); + public List currentWaypoints = new ArrayList<>(); + public List currentPathPoses = new ArrayList<>(); + public List currentPathFull = new ArrayList<>(); + private double fieldLength = 16.54; + private double fieldWidth = 8.02; + private double nodeSize = 0.2; + private int nodesX = (int) Math.ceil(fieldLength / nodeSize); + private int nodesY = (int) Math.ceil(fieldWidth / nodeSize); + private GridPosition requestStart; + private Translation2d requestRealStartPos; + private GridPosition requestGoal; + private Translation2d requestRealGoalPos; + private double eps; + private boolean requestMinor = true; + private boolean requestMajor = true; + private boolean requestReset = true; + private boolean newPathAvailable = false; + + /** + * Create a new pathfinder that runs AD* locally in a background thread + */ + public MapleADStar() { + planningThread = new Thread(this::runThread); + planningThread.setPriority(7); // Priority is 1-10. Higher is a greater priority. + + requestStart = new GridPosition(0, 0); + requestRealStartPos = Translation2d.kZero; + requestGoal = new GridPosition(0, 0); + requestRealGoalPos = Translation2d.kZero; + + staticObstacles.clear(); + dynamicObstacles.clear(); + + File navGridFile = new File(Filesystem.getDeployDirectory(), "pathplanner/navgrid.json"); + if (navGridFile.exists()) { + try (BufferedReader br = new BufferedReader(new FileReader(navGridFile))) { + StringBuilder fileContentBuilder = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) { + fileContentBuilder.append(line); + } + + String fileContent = fileContentBuilder.toString(); + JSONObject json = (JSONObject) new JSONParser().parse(fileContent); + + nodeSize = ((Number) json.get("nodeSizeMeters")).doubleValue(); + JSONArray grid = (JSONArray) json.get("grid"); + nodesY = grid.size(); + for (int row = 0; row < grid.size(); row++) { + JSONArray rowArray = (JSONArray) grid.get(row); + if (row == 0) { + nodesX = rowArray.size(); + } + for (int col = 0; col < rowArray.size(); col++) { + boolean isObstacle = (boolean) rowArray.get(col); + if (isObstacle) { + staticObstacles.add(new GridPosition(col, row)); + } + } + } + + JSONObject fieldSize = (JSONObject) json.get("field_size"); + fieldLength = ((Number) fieldSize.get("x")).doubleValue(); + fieldWidth = ((Number) fieldSize.get("y")).doubleValue(); + } catch (Exception e) { + // Do nothing, use defaults + } + } + + requestObstacles.clear(); + requestObstacles.addAll(staticObstacles); + requestObstacles.addAll(dynamicObstacles); + + requestReset = true; + requestMajor = true; + requestMinor = true; + + newPathAvailable = false; + + planningThread.setDaemon(true); + planningThread.setName("ADStar Planning Thread"); + planningThread.start(); + } + + /** + * Get if a new path has been calculated since the last time a path was retrieved + * + * @return True if a new path is available + */ + @Override + public boolean isNewPathAvailable() { + return newPathAvailable; + } + + /** + * Get the most recently calculated path + * + * @param constraints The path constraints to use when creating the path + * @param goalEndState The goal end state to use when creating the path + * @return The PathPlannerPath created from the points calculated by the pathfinder + */ + @Override + public PathPlannerPath getCurrentPath(PathConstraints constraints, GoalEndState goalEndState) { + List waypoints; + + pathLock.readLock().lock(); + waypoints = new ArrayList<>(currentWaypoints); + pathLock.readLock().unlock(); + + newPathAvailable = false; + + if (waypoints.size() < 2) { + // Not enough points. Something got borked somewhere + return null; + } + + return new PathPlannerPath(waypoints, constraints, null, goalEndState); + } + + /** + * Set the start position to pathfind from + * + * @param startPosition Start position on the field. If this is within an obstacle it will be + * moved to the nearest non-obstacle node. + */ + @Override + public void setStartPosition(Translation2d startPosition) { + GridPosition startPos = findClosestNonObstacle(getGridPos(startPosition), requestObstacles); + + if (startPos != null && !startPos.equals(requestStart)) { + requestLock.writeLock().lock(); + requestStart = startPos; + requestRealStartPos = startPosition; + + requestMinor = true; + newPathAvailable = false; + requestLock.writeLock().unlock(); + } + } + + /** + * Set the goal position to pathfind to + * + * @param goalPosition Goal position on the field. f this is within an obstacle it will be moved + * to the nearest non-obstacle node. + */ + @Override + public void setGoalPosition(Translation2d goalPosition) { + GridPosition gridPos = findClosestNonObstacle(getGridPos(goalPosition), requestObstacles); + + if (gridPos != null) { + requestLock.writeLock().lock(); + requestGoal = gridPos; + requestRealGoalPos = goalPosition; + + requestMinor = true; + requestMajor = true; + requestReset = true; + newPathAvailable = false; + requestLock.writeLock().unlock(); + } + } + + /** + * Set the dynamic obstacles that should be avoided while pathfinding. + * + * @param obs A List of Translation2d pairs representing obstacles. Each Translation2d represents + * opposite corners of a bounding box. + * @param currentRobotPos The current position of the robot. This is needed to change the start + * position of the path if the robot is now within an obstacle. + */ + @Override + public void setDynamicObstacles( + List> obs, Translation2d currentRobotPos) { + Set newObs = new HashSet<>(); + + for (var obstacle : obs) { + var gridPos1 = getGridPos(obstacle.getFirst()); + var gridPos2 = getGridPos(obstacle.getSecond()); + + int minX = Math.min(gridPos1.x, gridPos2.x); + int maxX = Math.max(gridPos1.x, gridPos2.x); + + int minY = Math.min(gridPos1.y, gridPos2.y); + int maxY = Math.max(gridPos1.y, gridPos2.y); + + for (int x = minX; x <= maxX; x++) { + for (int y = minY; y <= maxY; y++) { + newObs.add(new GridPosition(x, y)); + } + } + } + + dynamicObstacles.clear(); + dynamicObstacles.addAll(newObs); + requestLock.writeLock().lock(); + requestObstacles.clear(); + requestObstacles.addAll(staticObstacles); + requestObstacles.addAll(dynamicObstacles); + requestLock.writeLock().unlock(); + + pathLock.readLock().lock(); + boolean recalculate = false; + for (GridPosition pos : currentPathFull) { + if (requestObstacles.contains(pos)) { + recalculate = true; + break; + } + } + pathLock.readLock().unlock(); + + if (recalculate) { + setStartPosition(currentRobotPos); + setGoalPosition(requestRealGoalPos); + } + } + + public void runThread() { + try { + requestLock.readLock().lock(); + boolean reset = requestReset; + boolean minor = requestMinor; + boolean major = requestMajor; + GridPosition start = requestStart; + Translation2d realStart = requestRealStartPos; + GridPosition goal = requestGoal; + Translation2d realGoal = requestRealGoalPos; + + // Change the request booleans based on what will be done this loop + if (reset) { + requestReset = false; + } + + if (minor) { + requestMinor = false; + } else if (major && (eps - 0.5) <= 1.0) { + requestMajor = false; + } + requestLock.readLock().unlock(); + + if (reset || minor || major) { + doWork(reset, minor, major, start, goal, realStart, realGoal, requestObstacles); + } +// else { +// try { +// //Thread.sleep(10); +// } catch (InterruptedException e) { +// throw new RuntimeException(e); +// } +// } + } catch (Exception e) { + // Something messed up. Reset and hope for the best + requestLock.writeLock().lock(); + requestReset = true; + requestLock.writeLock().unlock(); + } + } + + private void doWork( + boolean needsReset, + boolean doMinor, + boolean doMajor, + GridPosition sStart, + GridPosition sGoal, + Translation2d realStartPos, + Translation2d realGoalPos, + Set obstacles) { + if (needsReset) { + reset(sStart, sGoal); + } + + if (doMinor) { + computeOrImprovePath(sStart, sGoal, obstacles); + + List pathPositions = extractPath(sStart, sGoal, obstacles); + List waypoints = + createWaypoints(pathPositions, realStartPos, realGoalPos, obstacles); + + pathLock.writeLock().lock(); + currentPathFull = pathPositions; + currentWaypoints = waypoints; + pathLock.writeLock().unlock(); + + newPathAvailable = true; + } else if (doMajor) { + if (eps > 1.0) { + eps -= 0.5; + open.putAll(incons); + + open.replaceAll((s, v) -> key(s, sStart)); + closed.clear(); + computeOrImprovePath(sStart, sGoal, obstacles); + + List pathPositions = extractPath(sStart, sGoal, obstacles); + List waypoints = + createWaypoints(pathPositions, realStartPos, realGoalPos, obstacles); + + pathLock.writeLock().lock(); + currentPathFull = pathPositions; + currentWaypoints = waypoints; + pathLock.writeLock().unlock(); + + newPathAvailable = true; + } + } + } + + private List extractPath( + GridPosition sStart, GridPosition sGoal, Set obstacles) { + if (sGoal.equals(sStart)) { + return new ArrayList<>(); + } + + List path = new ArrayList<>(); + path.add(sStart); + + var s = sStart; + + for (int k = 0; k < 200; k++) { + HashMap gList = new HashMap<>(); + + for (GridPosition x : getOpenNeighbors(s, obstacles)) { + gList.put(x, g.get(x)); + } + + Map.Entry min = Map.entry(sGoal, Double.POSITIVE_INFINITY); + for (var entry : gList.entrySet()) { + if (entry.getValue() < min.getValue()) { + min = entry; + } + } + s = min.getKey(); + + path.add(s); + if (s.equals(sGoal)) { + break; + } + } + + return path; + } + + private List createPathPoses( + List path, + Translation2d realStartPos, + Translation2d realGoalPos, + Set obstacles) { + if (path.isEmpty()) { + return new ArrayList<>(); + } + + List simplifiedPath = new ArrayList<>(); + simplifiedPath.add(path.get(0)); + for (int i = 1; i < path.size() - 1; i++) { + if (!walkable(simplifiedPath.get(simplifiedPath.size() - 1), path.get(i + 1), obstacles)) { + simplifiedPath.add(path.get(i)); + } + } + simplifiedPath.add(path.get(path.size() - 1)); + + List fieldPosPath = new ArrayList<>(); + for (GridPosition pos : simplifiedPath) { + fieldPosPath.add(gridPosToTranslation2d(pos)); + } + + if (fieldPosPath.size() < 2) { + return new ArrayList<>(); + } + + // Replace start and end positions with their real positions + fieldPosPath.set(0, realStartPos); + fieldPosPath.set(fieldPosPath.size() - 1, realGoalPos); + + List pathPoses = new ArrayList<>(); + pathPoses.add( + new Pose2d(fieldPosPath.get(0), fieldPosPath.get(1).minus(fieldPosPath.get(0)).getAngle())); + for (int i = 1; i < fieldPosPath.size() - 1; i++) { + Translation2d last = fieldPosPath.get(i - 1); + Translation2d current = fieldPosPath.get(i); + Translation2d next = fieldPosPath.get(i + 1); + + Translation2d anchor1 = current.minus(last).times(SMOOTHING_ANCHOR_PCT).plus(last); + Rotation2d heading1 = current.minus(last).getAngle(); + Translation2d anchor2 = current.minus(next).times(SMOOTHING_ANCHOR_PCT).plus(next); + Rotation2d heading2 = next.minus(anchor2).getAngle(); + + pathPoses.add(new Pose2d(anchor1, heading1)); + pathPoses.add(new Pose2d(anchor2, heading2)); + } + pathPoses.add( + new Pose2d( + fieldPosPath.get(fieldPosPath.size() - 1), + fieldPosPath + .get(fieldPosPath.size() - 1) + .minus(fieldPosPath.get(fieldPosPath.size() - 2)) + .getAngle())); + + return pathPoses; + } + + private List createWaypoints( + List path, + Translation2d realStartPos, + Translation2d realGoalPos, + Set obstacles) { + if (path.isEmpty()) { + return new ArrayList<>(); + } + + List simplifiedPath = new ArrayList<>(); + simplifiedPath.add(path.get(0)); + for (int i = 1; i < path.size() - 1; i++) { + if (!walkable(simplifiedPath.get(simplifiedPath.size() - 1), path.get(i + 1), obstacles)) { + simplifiedPath.add(path.get(i)); + } + } + simplifiedPath.add(path.get(path.size() - 1)); + + List fieldPosPath = new ArrayList<>(); + for (GridPosition pos : simplifiedPath) { + fieldPosPath.add(gridPosToTranslation2d(pos)); + } + + if (fieldPosPath.size() < 2) { + return new ArrayList<>(); + } + + // Replace start and end positions with their real positions + fieldPosPath.set(0, realStartPos); + fieldPosPath.set(fieldPosPath.size() - 1, realGoalPos); + + List pathPoses = new ArrayList<>(); + pathPoses.add( + new Pose2d(fieldPosPath.get(0), fieldPosPath.get(1).minus(fieldPosPath.get(0)).getAngle())); + for (int i = 1; i < fieldPosPath.size() - 1; i++) { + Translation2d last = fieldPosPath.get(i - 1); + Translation2d current = fieldPosPath.get(i); + Translation2d next = fieldPosPath.get(i + 1); + + Translation2d anchor1 = current.minus(last).times(SMOOTHING_ANCHOR_PCT).plus(last); + Rotation2d heading1 = current.minus(last).getAngle(); + Translation2d anchor2 = current.minus(next).times(SMOOTHING_ANCHOR_PCT).plus(next); + Rotation2d heading2 = next.minus(anchor2).getAngle(); + + pathPoses.add(new Pose2d(anchor1, heading1)); + pathPoses.add(new Pose2d(anchor2, heading2)); + } + pathPoses.add( + new Pose2d( + fieldPosPath.get(fieldPosPath.size() - 1), + fieldPosPath + .get(fieldPosPath.size() - 1) + .minus(fieldPosPath.get(fieldPosPath.size() - 2)) + .getAngle())); + this.currentPathPoses = pathPoses; + return PathPlannerPath.waypointsFromPoses(pathPoses); + } + + private GridPosition findClosestNonObstacle(GridPosition pos, Set obstacles) { + if (!obstacles.contains(pos)) { + return pos; + } + + Set visited = new HashSet<>(); + + Queue queue = new LinkedList<>(getAllNeighbors(pos)); + + while (!queue.isEmpty()) { + GridPosition check = queue.poll(); + if (!obstacles.contains(check)) { + return check; + } + visited.add(check); + + for (GridPosition neighbor : getAllNeighbors(check)) { + if (!visited.contains(neighbor) && !queue.contains(neighbor)) { + queue.add(neighbor); + } + } + } + return null; + } + + private boolean walkable(GridPosition s1, GridPosition s2, Set obstacles) { + int x0 = s1.x; + int y0 = s1.y; + int x1 = s2.x; + int y1 = s2.y; + + int dx = Math.abs(x1 - x0); + int dy = Math.abs(y1 - y0); + int x = x0; + int y = y0; + int n = 1 + dx + dy; + int xInc = (x1 > x0) ? 1 : -1; + int yInc = (y1 > y0) ? 1 : -1; + int error = dx - dy; + dx *= 2; + dy *= 2; + + for (; n > 0; n--) { + if (obstacles.contains(new GridPosition(x, y))) { + return false; + } + + if (error > 0) { + x += xInc; + error -= dy; + } else if (error < 0) { + y += yInc; + error += dx; + } else { + x += xInc; + y += yInc; + error -= dy; + error += dx; + n--; + } + } + + return true; + } + + private void reset(GridPosition sStart, GridPosition sGoal) { + g.clear(); + rhs.clear(); + open.clear(); + incons.clear(); + closed.clear(); + + for (int x = 0; x < nodesX; x++) { + for (int y = 0; y < nodesY; y++) { + g.put(new GridPosition(x, y), Double.POSITIVE_INFINITY); + rhs.put(new GridPosition(x, y), Double.POSITIVE_INFINITY); + } + } + + rhs.put(sGoal, 0.0); + + eps = EPS; + + open.put(sGoal, key(sGoal, sStart)); + } + + private void computeOrImprovePath( + GridPosition sStart, GridPosition sGoal, Set obstacles) { + while (true) { + var sv = topKey(); + if (sv == null) { + break; + } + var s = sv.getFirst(); + var v = sv.getSecond(); + + if (comparePair(v, key(sStart, sStart)) >= 0 && rhs.get(sStart).equals(g.get(sStart))) { + break; + } + + open.remove(s); + + if (g.get(s) > rhs.get(s)) { + g.put(s, rhs.get(s)); + closed.add(s); + + for (GridPosition sn : getOpenNeighbors(s, obstacles)) { + updateState(sn, sStart, sGoal, obstacles); + } + } else { + g.put(s, Double.POSITIVE_INFINITY); + for (GridPosition sn : getOpenNeighbors(s, obstacles)) { + updateState(sn, sStart, sGoal, obstacles); + } + updateState(s, sStart, sGoal, obstacles); + } + } + } + + private void updateState( + GridPosition s, GridPosition sStart, GridPosition sGoal, Set obstacles) { + if (!s.equals(sGoal)) { + rhs.put(s, Double.POSITIVE_INFINITY); + + for (GridPosition x : getOpenNeighbors(s, obstacles)) { + rhs.put(s, Math.min(rhs.get(s), g.get(x) + cost(s, x, obstacles))); + } + } + + open.remove(s); + + if (!g.get(s).equals(rhs.get(s))) { + if (!closed.contains(s)) { + open.put(s, key(s, sStart)); + } else { + incons.put(s, Pair.of(0.0, 0.0)); + } + } + } + + private double cost(GridPosition sStart, GridPosition sGoal, Set obstacles) { + if (isCollision(sStart, sGoal, obstacles)) { + return Double.POSITIVE_INFINITY; + } + + return heuristic(sStart, sGoal); + } + + private boolean isCollision(GridPosition sStart, GridPosition sEnd, Set obstacles) { + if (obstacles.contains(sStart) || obstacles.contains(sEnd)) { + return true; + } + + if (sStart.x != sEnd.x && sStart.y != sEnd.y) { + GridPosition s1; + GridPosition s2; + + if (sEnd.x - sStart.x == sStart.y - sEnd.y) { + s1 = new GridPosition(Math.min(sStart.x, sEnd.x), Math.min(sStart.y, sEnd.y)); + s2 = new GridPosition(Math.max(sStart.x, sEnd.x), Math.max(sStart.y, sEnd.y)); + } else { + s1 = new GridPosition(Math.min(sStart.x, sEnd.x), Math.max(sStart.y, sEnd.y)); + s2 = new GridPosition(Math.max(sStart.x, sEnd.x), Math.min(sStart.y, sEnd.y)); + } + + return obstacles.contains(s1) || obstacles.contains(s2); + } + + return false; + } + + private List getOpenNeighbors(GridPosition s, Set obstacles) { + List ret = new ArrayList<>(); + + for (int xMove = -1; xMove <= 1; xMove++) { + for (int yMove = -1; yMove <= 1; yMove++) { + GridPosition sNext = new GridPosition(s.x + xMove, s.y + yMove); + if (!obstacles.contains(sNext) + && sNext.x >= 0 + && sNext.x < nodesX + && sNext.y >= 0 + && sNext.y < nodesY) { + ret.add(sNext); + } + } + } + return ret; + } + + private List getAllNeighbors(GridPosition s) { + List ret = new ArrayList<>(); + + for (int xMove = -1; xMove <= 1; xMove++) { + for (int yMove = -1; yMove <= 1; yMove++) { + GridPosition sNext = new GridPosition(s.x + xMove, s.y + yMove); + if (sNext.x >= 0 && sNext.x < nodesX && sNext.y >= 0 && sNext.y < nodesY) { + ret.add(sNext); + } + } + } + return ret; + } + + private Pair key(GridPosition s, GridPosition sStart) { + if (g.get(s) > rhs.get(s)) { + return Pair.of(rhs.get(s) + eps * heuristic(sStart, s), rhs.get(s)); + } else { + return Pair.of(g.get(s) + heuristic(sStart, s), g.get(s)); + } + } + + private Pair> topKey() { + Map.Entry> min = null; + for (var entry : open.entrySet()) { + if (min == null || comparePair(entry.getValue(), min.getValue()) < 0) { + min = entry; + } + } + + if (min == null) { + return null; + } + + return Pair.of(min.getKey(), min.getValue()); + } + + private double heuristic(GridPosition sStart, GridPosition sGoal) { + return Math.hypot(sGoal.x - sStart.x, sGoal.y - sStart.y); + } + + private int comparePair(Pair a, Pair b) { + int first = Double.compare(a.getFirst(), b.getFirst()); + if (first == 0) { + return Double.compare(a.getSecond(), b.getSecond()); + } else { + return first; + } + } + + private GridPosition getGridPos(Translation2d pos) { + int x = (int) Math.floor(pos.getX() / nodeSize); + int y = (int) Math.floor(pos.getY() / nodeSize); + + return new GridPosition(x, y); + } + + private Translation2d gridPosToTranslation2d(GridPosition pos) { + return new Translation2d( + (pos.x * nodeSize) + (nodeSize / 2.0), (pos.y * nodeSize) + (nodeSize / 2.0)); + } + + /** + * Represents a node in the pathfinding grid + * + * @param x X index in the grid + * @param y Y index in the grid + */ + public record GridPosition(int x, int y) implements Comparable { + @Override + public int compareTo(GridPosition o) { + if (x == o.x) { + return Integer.compare(y, o.y); + } else { + return Integer.compare(x, o.x); + } + } + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/Arena2024Crescendo.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/Arena2024Crescendo.java index e8ce671..f68935f 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/Arena2024Crescendo.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/Arena2024Crescendo.java @@ -25,7 +25,9 @@ public class Arena2024Crescendo extends SimulatedArena { protected final CrescendoAmp redAmp; protected final CrescendoAmp blueAmp; - /** the obstacles on the 2024 competition field */ + /** + * the obstacles on the 2024 competition field + */ public static final class CrescendoFieldObstaclesMap extends FieldMap { private static final double FIELD_WIDTH = 16.54; @@ -74,18 +76,18 @@ public CrescendoFieldObstaclesMap() { } } - private static final Translation2d[] NOTE_INITIAL_POSITIONS = new Translation2d[] { - new Translation2d(2.9, 4.1), - new Translation2d(2.9, 5.55), - new Translation2d(2.9, 7), - new Translation2d(8.27, 0.75), - new Translation2d(8.27, 2.43), - new Translation2d(8.27, 4.1), - new Translation2d(8.27, 5.78), - new Translation2d(8.27, 7.46), - new Translation2d(13.64, 4.1), - new Translation2d(13.64, 5.55), - new Translation2d(13.64, 7), + private static final Translation2d[] NOTE_INITIAL_POSITIONS = new Translation2d[]{ + new Translation2d(2.9, 4.1), + new Translation2d(2.9, 5.55), + new Translation2d(2.9, 7), + new Translation2d(8.27, 0.75), + new Translation2d(8.27, 2.43), + new Translation2d(8.27, 4.1), + new Translation2d(8.27, 5.78), + new Translation2d(8.27, 7.46), + new Translation2d(13.64, 4.1), + new Translation2d(13.64, 5.55), + new Translation2d(13.64, 7), }; public Arena2024Crescendo() { @@ -144,7 +146,7 @@ public void simulationSubTick(int tickNum) { * * *

    Returns wether the specified team currently has an amped speaker

    - * + *

    * This function returns true during autonomous since the autonomous mode behaves exactly like amplified game play. * * @param isBlue Wether to check the blue or red alliance. diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoAmp.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoAmp.java index 03e5b30..56cf8ea 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoAmp.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoAmp.java @@ -1,13 +1,16 @@ package swervelib.simulation.ironmaple.simulation.seasonspecific.crescendo2024; -import static edu.wpi.first.units.Units.Centimeters; - -import edu.wpi.first.math.geometry.*; +import edu.wpi.first.math.geometry.Pose3d; +import edu.wpi.first.math.geometry.Rotation3d; +import edu.wpi.first.math.geometry.Translation3d; import edu.wpi.first.networktables.NetworkTableInstance; import edu.wpi.first.networktables.StructPublisher; -import java.util.*; import swervelib.simulation.ironmaple.simulation.Goal; +import java.util.List; + +import static edu.wpi.first.units.Units.Centimeters; + /** * * @@ -29,7 +32,7 @@ public class CrescendoAmp extends Goal { * *

    Creates an Amp of the specified color.

    * - * @param arena The host arena of this amp. + * @param arena The host arena of this amp. * @param isBlue Wether this is the blue amp or the red one. */ public CrescendoAmp(Arena2024Crescendo arena, boolean isBlue) { @@ -63,6 +66,5 @@ protected void addPoints() { @Override public void draw(List drawList) { - return; } } diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoHumanPlayerSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoHumanPlayerSimulation.java index be80ee6..6b94246 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoHumanPlayerSimulation.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoHumanPlayerSimulation.java @@ -1,13 +1,13 @@ package swervelib.simulation.ironmaple.simulation.seasonspecific.crescendo2024; -import static swervelib.simulation.ironmaple.utils.LegacyFieldMirroringUtils2024.toCurrentAllianceTranslation; - import edu.wpi.first.math.geometry.Translation2d; import edu.wpi.first.wpilibj.DriverStation; import edu.wpi.first.wpilibj.Timer; import swervelib.simulation.ironmaple.simulation.SimulatedArena; import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation; +import static swervelib.simulation.ironmaple.utils.LegacyFieldMirroringUtils2024.toCurrentAllianceTranslation; + public class CrescendoHumanPlayerSimulation implements SimulatedArena.Simulatable { private static final Translation2d BLUE_SOURCE_POSITION = new Translation2d(15.6, 0.8); private double previousThrowTimeSeconds = 0; diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoNoteOnField.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoNoteOnField.java index 7658c52..4df842b 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoNoteOnField.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoNoteOnField.java @@ -1,8 +1,5 @@ package swervelib.simulation.ironmaple.simulation.seasonspecific.crescendo2024; -import static edu.wpi.first.units.Units.Inches; -import static edu.wpi.first.units.Units.Kilograms; - import edu.wpi.first.math.geometry.Pose2d; import edu.wpi.first.math.geometry.Rotation2d; import edu.wpi.first.math.geometry.Translation2d; @@ -10,6 +7,9 @@ import org.dyn4j.geometry.Geometry; import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation; +import static edu.wpi.first.units.Units.Inches; +import static edu.wpi.first.units.Units.Kilograms; + public class CrescendoNoteOnField extends GamePieceOnFieldSimulation { /* https://www.andymark.com/products/frc-2024-am-4999 */ public static final GamePieceInfo CRESCENDO_NOTE_INFO = new GamePieceInfo( diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoSpeaker.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoSpeaker.java index acde813..6e9b872 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoSpeaker.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoSpeaker.java @@ -1,14 +1,17 @@ package swervelib.simulation.ironmaple.simulation.seasonspecific.crescendo2024; -import static edu.wpi.first.units.Units.Centimeters; - -import edu.wpi.first.math.geometry.*; +import edu.wpi.first.math.geometry.Pose3d; +import edu.wpi.first.math.geometry.Rotation3d; +import edu.wpi.first.math.geometry.Translation3d; import edu.wpi.first.networktables.NetworkTableInstance; import edu.wpi.first.networktables.StructPublisher; -import java.util.*; import swervelib.simulation.ironmaple.simulation.Goal; import swervelib.simulation.ironmaple.simulation.gamepieces.GamePiece; +import java.util.List; + +import static edu.wpi.first.units.Units.Centimeters; + /** * * @@ -29,7 +32,7 @@ public class CrescendoSpeaker extends Goal { * *

    Creates an Speaker of the specified color.

    * - * @param arena The host arena of this speaker. + * @param arena The host arena of this speaker. * @param isBlue Wether this is the blue speaker or the red one. */ public CrescendoSpeaker(Arena2024Crescendo arena, boolean isBlue) { @@ -63,6 +66,5 @@ protected void addPoints() { @Override public void draw(List drawList) { - return; } } diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/NoteOnFly.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/NoteOnFly.java index b393f0e..fe14d85 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/NoteOnFly.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/NoteOnFly.java @@ -1,7 +1,5 @@ package swervelib.simulation.ironmaple.simulation.seasonspecific.crescendo2024; -import static swervelib.simulation.ironmaple.simulation.seasonspecific.crescendo2024.CrescendoNoteOnField.*; - import edu.wpi.first.math.geometry.Rotation2d; import edu.wpi.first.math.geometry.Translation2d; import edu.wpi.first.math.geometry.Translation3d; @@ -12,6 +10,8 @@ import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceProjectile; import swervelib.simulation.ironmaple.utils.LegacyFieldMirroringUtils2024; +import static swervelib.simulation.ironmaple.simulation.seasonspecific.crescendo2024.CrescendoNoteOnField.CRESCENDO_NOTE_INFO; + public class NoteOnFly extends GamePieceProjectile { public NoteOnFly( Translation2d robotPosition, diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/evergreen/ArenaEvergreen.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/evergreen/ArenaEvergreen.java index b3391df..0172e99 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/evergreen/ArenaEvergreen.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/evergreen/ArenaEvergreen.java @@ -24,18 +24,13 @@ public EvergreenFieldObstacleMap() { */ public EvergreenFieldObstacleMap withWalls() { // blue wall - super.addBorderLine(new Translation2d(0, 1.270), new Translation2d(0, 6.782)); - + super.addBorderLine(new Translation2d(0, 0), new Translation2d(0, 8)); // red wall - super.addBorderLine(new Translation2d(17.548, 1.270), new Translation2d(17.548, 6.782)); - - // upper walls - super.addBorderLine(new Translation2d(1.672, 8.052), new Translation2d(11, 8.052)); - super.addBorderLine(new Translation2d(12, 8.052), new Translation2d(17.548 - 1.672, 8.052)); - - // lower walls - super.addBorderLine(new Translation2d(1.672, 0), new Translation2d(5.8, 0)); - super.addBorderLine(new Translation2d(6.3, 0), new Translation2d(17.548 - 1.672, 0)); + super.addBorderLine(new Translation2d(17.548, 0), new Translation2d(17.548, 8)); + // upper wall + super.addBorderLine(new Translation2d(0, 8.052), new Translation2d(20, 8.052)); + // lower wall + super.addBorderLine(new Translation2d(0, 0), new Translation2d(20, 0)); return this; } } @@ -49,8 +44,8 @@ public EvergreenFieldObstacleMap withWalls() { * * @param withWalls used to add wall obstacles when desired. */ - public ArenaEvergreen(boolean withWalls) { - super(withWalls ? new EvergreenFieldObstacleMap() : new EvergreenFieldObstacleMap().withWalls()); + public ArenaEvergreen(boolean withWalls) { + super(withWalls ? new EvergreenFieldObstacleMap().withWalls() : new EvergreenFieldObstacleMap()); } /** diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/Arena2025Reefscape.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/Arena2025Reefscape.java index 203244d..1b2a922 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/Arena2025Reefscape.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/Arena2025Reefscape.java @@ -5,11 +5,13 @@ import edu.wpi.first.math.geometry.Rotation2d; import edu.wpi.first.math.geometry.Translation2d; import edu.wpi.first.wpilibj.DriverStation; -import java.util.Arrays; -import java.util.List; import swervelib.simulation.ironmaple.simulation.SimulatedArena; +import swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025.opponentsim.ReefscapeOpponentManager; import swervelib.simulation.ironmaple.utils.FieldMirroringUtils; +import java.util.Arrays; +import java.util.List; + /** * * @@ -23,7 +25,6 @@ public class Arena2025Reefscape extends SimulatedArena { public static final class ReefscapeFieldObstacleMap extends FieldMap { public ReefscapeFieldObstacleMap() { super(); - // blue wall super.addBorderLine(new Translation2d(0, 1.270), new Translation2d(0, 6.782)); @@ -47,13 +48,13 @@ public ReefscapeFieldObstacleMap() { super.addBorderLine(new Translation2d(6.3, 0), new Translation2d(17.548 - 1.672, 0)); // blue reef - Translation2d[] reefVorticesBlue = new Translation2d[] { - new Translation2d(3.658, 3.546), - new Translation2d(3.658, 4.506), - new Translation2d(4.489, 4.987), - new Translation2d(5.3213, 4.506), - new Translation2d(5.3213, 3.546), - new Translation2d(4.489, 3.065) + Translation2d[] reefVorticesBlue = new Translation2d[]{ + new Translation2d(3.658, 3.546), + new Translation2d(3.658, 4.506), + new Translation2d(4.489, 4.987), + new Translation2d(5.3213, 4.506), + new Translation2d(5.3213, 3.546), + new Translation2d(4.489, 3.065) }; for (int i = 0; i < 6; i++) super.addBorderLine(reefVorticesBlue[i], reefVorticesBlue[(i + 1) % 6]); @@ -78,6 +79,7 @@ public ReefscapeFieldObstacleMap() { public Arena2025Reefscape() { super(new ReefscapeFieldObstacleMap()); + super.withOpponentManager(new ReefscapeOpponentManager()); redReefSimulation = new ReefscapeReefSimulation(this, false); super.addCustomSimulation(redReefSimulation); @@ -98,10 +100,23 @@ public Arena2025Reefscape() { super.addCustomSimulation(redProcessor); } + /** + * Gets the opponent manager for FRC 2025 Reefscape. + * + * @return this {@link ReefscapeOpponentManager}. + */ + @Override + public ReefscapeOpponentManager getOpponentManager() { + if (opponentManager == null) { + DriverStation.reportWarning("Something went wrong, no OpponentManager found in Arena2025Reefscape", false); + } + return (ReefscapeOpponentManager) opponentManager; + } + @Override public void placeGamePiecesOnField() { - Translation2d[] bluePositions = new Translation2d[] { - new Translation2d(1.219, 5.855), new Translation2d(1.219, 4.026), new Translation2d(1.219, 2.197), + Translation2d[] bluePositions = new Translation2d[]{ + new Translation2d(1.219, 5.855), new Translation2d(1.219, 4.026), new Translation2d(1.219, 2.197), }; for (Translation2d position : bluePositions) super.addGamePiece(new ReefscapeCoralAlgaeStack(position)); diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeAlgaeOnField.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeAlgaeOnField.java index dd9b4a1..08154c3 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeAlgaeOnField.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeAlgaeOnField.java @@ -1,13 +1,14 @@ package swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025; -import static edu.wpi.first.units.Units.*; - import edu.wpi.first.math.geometry.Pose2d; import edu.wpi.first.math.geometry.Rotation2d; import edu.wpi.first.math.geometry.Translation2d; import org.dyn4j.geometry.Circle; import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation; +import static edu.wpi.first.units.Units.Inches; +import static edu.wpi.first.units.Units.Kilograms; + /** * * diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeBargeSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeBargeSimulation.java index b824f36..728ca35 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeBargeSimulation.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeBargeSimulation.java @@ -1,16 +1,20 @@ package swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025; -import static edu.wpi.first.units.Units.Centimeters; - -import edu.wpi.first.math.geometry.*; +import edu.wpi.first.math.geometry.Pose3d; +import edu.wpi.first.math.geometry.Rotation3d; +import edu.wpi.first.math.geometry.Transform3d; +import edu.wpi.first.math.geometry.Translation3d; import edu.wpi.first.networktables.NetworkTableInstance; import edu.wpi.first.networktables.StructPublisher; import edu.wpi.first.units.Units; import edu.wpi.first.wpilibj.DriverStation; -import java.util.*; import swervelib.simulation.ironmaple.simulation.Goal; import swervelib.simulation.ironmaple.simulation.gamepieces.GamePiece; +import java.util.List; + +import static edu.wpi.first.units.Units.Centimeters; + /** * * @@ -29,7 +33,7 @@ public class ReefscapeBargeSimulation extends Goal { * *

    Creates an barge of the specified color.

    * - * @param arena The host arena of this barge. + * @param arena The host arena of this barge. * @param isBlue Wether this is the blue barge or the red one. */ public ReefscapeBargeSimulation(Arena2025Reefscape arena, boolean isBlue) { @@ -52,10 +56,10 @@ public ReefscapeBargeSimulation(Arena2025Reefscape arena, boolean isBlue) { public void draw(List algaePosesToDisplay) { for (int i = 0; i < gamePieceCount; i++) { algaePosesToDisplay.add(new Pose3d( - xyBox.getCenter().x, - xyBox.getCenter().y - xyBox.getHeight() / 2, - elevation.in(Units.Meters) + height.in(Units.Meters) / 2, - new Rotation3d()) + xyBox.getCenter().x, + xyBox.getCenter().y - xyBox.getHeight() / 2, + elevation.in(Units.Meters) + height.in(Units.Meters) / 2, + new Rotation3d()) .plus(new Transform3d(0, i * 0.35, 0, new Rotation3d()))); } } diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralAlgaeStack.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralAlgaeStack.java index 8a8b3a7..2c8c718 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralAlgaeStack.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralAlgaeStack.java @@ -1,15 +1,16 @@ package swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025; -import static edu.wpi.first.units.Units.*; - import edu.wpi.first.math.geometry.*; import edu.wpi.first.math.kinematics.ChassisSpeeds; -import java.util.List; import org.dyn4j.geometry.Circle; import swervelib.simulation.ironmaple.simulation.SimulatedArena; import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation; import swervelib.simulation.ironmaple.utils.mathutils.GeometryConvertor; +import java.util.List; + +import static edu.wpi.first.units.Units.*; + /** * * @@ -107,7 +108,9 @@ public static List getStackedCoralPoses() { return getStackedCoralPoses(SimulatedArena.getInstance()); } - /** @see #getStackedCoralPoses() */ + /** + * @see #getStackedCoralPoses() + */ private static final Transform3d STACK_TO_CORAL = new Transform3d(new Translation3d(0, 0, 0.15), new Rotation3d(0, Math.toRadians(90), 0)); @@ -131,7 +134,9 @@ public static List getStackedAlgaePoses() { private static final Transform3d STACK_TO_ALGAE = new Transform3d( new Translation3d(0, 0, 0.3 + edu.wpi.first.math.util.Units.inchesToMeters(8)), new Rotation3d()); - /** @see #getStackedAlgaePoses() */ + /** + * @see #getStackedAlgaePoses() + */ public static List getStackedAlgaePoses(SimulatedArena arena) { return arena.getGamePiecesPosesByType(REEFSCAPE_STACK_INFO.type()).stream() .map(stackPose -> stackPose.plus(STACK_TO_ALGAE)) diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralOnField.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralOnField.java index 31a2a4c..f3ddfad 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralOnField.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralOnField.java @@ -1,11 +1,12 @@ package swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025; -import static edu.wpi.first.units.Units.*; - import edu.wpi.first.math.geometry.Pose2d; import org.dyn4j.geometry.Rectangle; import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation; +import static edu.wpi.first.units.Units.Kilograms; +import static edu.wpi.first.units.Units.Meters; + /** * * diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralOnFly.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralOnFly.java index 1703492..461845b 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralOnFly.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeCoralOnFly.java @@ -1,7 +1,5 @@ package swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025; -import static edu.wpi.first.units.Units.*; - import edu.wpi.first.math.geometry.Pose2d; import edu.wpi.first.math.geometry.Rotation2d; import edu.wpi.first.math.geometry.Translation2d; @@ -15,6 +13,8 @@ import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceProjectile; import swervelib.simulation.ironmaple.utils.FieldMirroringUtils; +import static edu.wpi.first.units.Units.*; + public class ReefscapeCoralOnFly extends GamePieceProjectile { public ReefscapeCoralOnFly( Translation2d robotPosition, @@ -58,25 +58,25 @@ public static ReefscapeCoralOnFly DropFromCoralStation( : station.startingPose.getTranslation(); return isHorizontal ? new ReefscapeCoralOnFly( - pos, - new Translation2d(), - ChassisSpeeds.fromRobotRelativeSpeeds(new ChassisSpeeds(3.0, 0, 0), rot), - rot.rotateBy(Rotation2d.kCCW_90deg), - Centimeters.of(98), - MetersPerSecond.of(0), - Degrees.of(0)) + pos, + new Translation2d(), + ChassisSpeeds.fromRobotRelativeSpeeds(new ChassisSpeeds(3.0, 0, 0), rot), + rot.rotateBy(Rotation2d.kCCW_90deg), + Centimeters.of(98), + MetersPerSecond.of(0), + Degrees.of(0)) : new ReefscapeCoralOnFly( - alliance == DriverStation.Alliance.Red - ? FieldMirroringUtils.flip(station.startingPose.getTranslation()) - : station.startingPose.getTranslation(), - new Translation2d(), - new ChassisSpeeds(), - alliance == DriverStation.Alliance.Red - ? FieldMirroringUtils.flip(station.startingPose.getRotation()) - : station.startingPose.getRotation(), - Centimeters.of(98), - MetersPerSecond.of(3), - Degrees.of(-50)); + alliance == DriverStation.Alliance.Red + ? FieldMirroringUtils.flip(station.startingPose.getTranslation()) + : station.startingPose.getTranslation(), + new Translation2d(), + new ChassisSpeeds(), + alliance == DriverStation.Alliance.Red + ? FieldMirroringUtils.flip(station.startingPose.getRotation()) + : station.startingPose.getRotation(), + Centimeters.of(98), + MetersPerSecond.of(3), + Degrees.of(-50)); } @Override @@ -86,8 +86,8 @@ public void addGamePieceAfterTouchGround(SimulatedArena simulatedArena) { ReefscapeCoralOnField.REEFSCAPE_CORAL_INFO, () -> Math.max( ReefscapeCoralOnField.REEFSCAPE_CORAL_INFO - .gamePieceHeight() - .in(Meters) + .gamePieceHeight() + .in(Meters) / 2, getPositionAtTime(super.launchedTimer.get()).getZ()), new Pose2d( diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeProcessorSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeProcessorSimulation.java index 8df4d14..08f0fff 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeProcessorSimulation.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeProcessorSimulation.java @@ -1,17 +1,15 @@ package swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025; -import static edu.wpi.first.units.Units.Centimeters; -import static edu.wpi.first.units.Units.Degrees; -import static edu.wpi.first.units.Units.Meters; -import static edu.wpi.first.units.Units.MetersPerSecond; - import edu.wpi.first.math.geometry.*; import edu.wpi.first.math.kinematics.ChassisSpeeds; import edu.wpi.first.networktables.NetworkTableInstance; import edu.wpi.first.networktables.StructPublisher; -import java.util.*; import swervelib.simulation.ironmaple.simulation.Goal; +import java.util.List; + +import static edu.wpi.first.units.Units.*; + /** * * @@ -34,7 +32,7 @@ public class ReefscapeProcessorSimulation extends Goal { * *

    Creates an processor of the specified color.

    * - * @param arena The host arena of this processor. + * @param arena The host arena of this processor. * @param isBlue Wether this is the blue processor or the red one. */ public ReefscapeProcessorSimulation(Arena2025Reefscape arena, boolean isBlue) { @@ -82,6 +80,5 @@ protected void addPoints() { @Override public void draw(List drawList) { - return; } } diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefBranch.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefBranch.java index 89c0c0a..cbe3668 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefBranch.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefBranch.java @@ -1,22 +1,18 @@ package swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025; -import static edu.wpi.first.units.Units.Centimeters; -import static edu.wpi.first.units.Units.Degrees; - -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.geometry.Transform3d; -import edu.wpi.first.math.geometry.Translation2d; -import edu.wpi.first.math.geometry.Translation3d; +import edu.wpi.first.math.geometry.*; import edu.wpi.first.units.Units; import edu.wpi.first.wpilibj.DriverStation; -import java.util.Arrays; -import java.util.List; import swervelib.simulation.ironmaple.simulation.Goal; import swervelib.simulation.ironmaple.simulation.gamepieces.GamePiece; import swervelib.simulation.ironmaple.utils.FieldMirroringUtils; +import java.util.Arrays; +import java.util.List; + +import static edu.wpi.first.units.Units.Centimeters; +import static edu.wpi.first.units.Units.Degrees; + /** * * @@ -32,26 +28,26 @@ public class ReefscapeReefBranch extends Goal { public static final Translation2d origin = new Translation2d(FieldMirroringUtils.FIELD_WIDTH / 2, FieldMirroringUtils.FIELD_HEIGHT / 2); - public static final Translation2d[] branchesCenterPositionBlue = new Translation2d[] { - new Translation2d(-4.810, 0.164).plus(origin), // A - new Translation2d(-4.810, -0.164).plus(origin), // B - new Translation2d(-4.690, -0.373).plus(origin), // C - new Translation2d(-4.406, -0.538).plus(origin), // D - new Translation2d(-4.164, -0.537).plus(origin), // E - new Translation2d(-3.879, -0.374).plus(origin), // F - new Translation2d(-3.759, -0.164).plus(origin), // G - new Translation2d(-3.759, 0.164).plus(origin), // H - new Translation2d(-3.880, 0.373).plus(origin), // I - new Translation2d(-4.164, 0.538).plus(origin), // J - new Translation2d(-4.405, 0.538).plus(origin), // K - new Translation2d(-4.690, 0.374).plus(origin) // L + public static final Translation2d[] branchesCenterPositionBlue = new Translation2d[]{ + new Translation2d(-4.810, 0.164).plus(origin), // A + new Translation2d(-4.810, -0.164).plus(origin), // B + new Translation2d(-4.690, -0.373).plus(origin), // C + new Translation2d(-4.406, -0.538).plus(origin), // D + new Translation2d(-4.164, -0.537).plus(origin), // E + new Translation2d(-3.879, -0.374).plus(origin), // F + new Translation2d(-3.759, -0.164).plus(origin), // G + new Translation2d(-3.759, 0.164).plus(origin), // H + new Translation2d(-3.880, 0.373).plus(origin), // I + new Translation2d(-4.164, 0.538).plus(origin), // J + new Translation2d(-4.405, 0.538).plus(origin), // K + new Translation2d(-4.690, 0.374).plus(origin) // L }; - public static final Translation3d[] heights = new Translation3d[] { - new Translation3d(0, 0, 0.45), - new Translation3d(0, 0, 0.79), - new Translation3d(0, 0, 1.19), - new Translation3d(0, 0, 1.78) + public static final Translation3d[] heights = new Translation3d[]{ + new Translation3d(0, 0, 0.45), + new Translation3d(0, 0, 0.79), + new Translation3d(0, 0, 1.19), + new Translation3d(0, 0, 1.78) }; public static final Rotation3d flip90 = new Rotation3d(0, 0, Math.PI / 2); @@ -60,13 +56,13 @@ public class ReefscapeReefBranch extends Goal { .map(FieldMirroringUtils::flip) .toArray(Translation2d[]::new); - public static final Rotation2d[] branchesFacingOutwardsBlue = new Rotation2d[] { - Rotation2d.fromDegrees(180), Rotation2d.fromDegrees(180), // A and B - Rotation2d.fromDegrees(240), Rotation2d.fromDegrees(240), // C and D - Rotation2d.fromDegrees(300), Rotation2d.fromDegrees(300), // E and F - Rotation2d.fromDegrees(0), Rotation2d.fromDegrees(0), // G and H - Rotation2d.fromDegrees(60), Rotation2d.fromDegrees(60), // I and J - Rotation2d.fromDegrees(120), Rotation2d.fromDegrees(120), // K and L + public static final Rotation2d[] branchesFacingOutwardsBlue = new Rotation2d[]{ + Rotation2d.fromDegrees(180), Rotation2d.fromDegrees(180), // A and B + Rotation2d.fromDegrees(240), Rotation2d.fromDegrees(240), // C and D + Rotation2d.fromDegrees(300), Rotation2d.fromDegrees(300), // E and F + Rotation2d.fromDegrees(0), Rotation2d.fromDegrees(0), // G and H + Rotation2d.fromDegrees(60), Rotation2d.fromDegrees(60), // I and J + Rotation2d.fromDegrees(120), Rotation2d.fromDegrees(120), // K and L }; /** @@ -75,8 +71,8 @@ public class ReefscapeReefBranch extends Goal { *

    Returns the required pose of a reef branch at the designated position.

    * * @param isBlue Wether the position is on the blue reef or the red reef. - * @param level The level of the reef (0 indexed). Range of 0-3. - * @param col The pole or Colum of the reef (0 indexed). Range of 0-11. + * @param level The level of the reef (0 indexed). Range of 0-3. + * @param col The pole or Colum of the reef (0 indexed). Range of 0-11. * @return The pose of a reef branch with the specified stats. */ public static Translation3d getPoseOfBranchAt(boolean isBlue, int level, int col) { @@ -100,9 +96,9 @@ public static Translation3d getPoseOfBranchAt(boolean isBlue, int level, int col * *

    Creates a singular reef branch at the specified location

    * - * @param arena The host arena of this reef. + * @param arena The host arena of this reef. * @param isBlue Wether the position is on the blue reef or the red reef. - * @param level The level of the reef (0 indexed). Range of 0-3. + * @param level The level of the reef (0 indexed). Range of 0-3. * @param column The pole or Colum of the reef (0 indexed). Range of 0-11. */ public ReefscapeReefBranch(Arena2025Reefscape arena, boolean isBlue, int level, int column) { @@ -153,9 +149,6 @@ public Pose3d getPose() { public boolean checkRotation(GamePiece gamePiece) { if (level == 3) { Rotation3d rotation = gamePiece.getPose3d().getRotation(); - System.out.println(Math.abs(rotation.getY() + Math.PI / 2)); - System.out.println(Math.abs(rotation.getY() - Math.PI / 2)); - return Math.abs(rotation.getY() + Math.PI / 2) < Degrees.of(10).in(Units.Radians) || Math.abs(rotation.getY() - Math.PI / 2) < Degrees.of(10).in(Units.Radians); } else { @@ -167,7 +160,7 @@ public boolean checkRotation(GamePiece gamePiece) { protected void addPoints() { System.out.println("Coral scored on level: " + (level + 1) + " on the " + (isBlue ? "Blue " : "Red") + "reef"); arena.addValueToMatchBreakdown(isBlue, "Auto/CoralScoredInAuto", DriverStation.isAutonomous() ? 1 : 0); - arena.addValueToMatchBreakdown(isBlue, "CoralScoredOnLevel " + String.valueOf(level + 1), 1); + arena.addValueToMatchBreakdown(isBlue, "CoralScoredOnLevel " + (level + 1), 1); if (DriverStation.isAutonomous()) { switch (level) { diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefSimulation.java index 0113e0e..e00b887 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefSimulation.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefSimulation.java @@ -3,11 +3,12 @@ import edu.wpi.first.math.geometry.Pose3d; import edu.wpi.first.networktables.NetworkTableInstance; import edu.wpi.first.networktables.StructArrayPublisher; -import java.util.ArrayList; -import java.util.List; import swervelib.simulation.ironmaple.simulation.Goal; import swervelib.simulation.ironmaple.simulation.SimulatedArena; +import java.util.ArrayList; +import java.util.List; + /** * * @@ -20,7 +21,7 @@ public class ReefscapeReefSimulation implements SimulatedArena.Simulatable { protected final List branches; public ReefscapeAlgaeOnField algae; - private StructArrayPublisher reefPub; + private final StructArrayPublisher reefPub; Pose3d[] branchPoses; /** @@ -28,7 +29,7 @@ public class ReefscapeReefSimulation implements SimulatedArena.Simulatable { * *

    Creates an reef of the specified color.

    * - * @param arena The host arena of this reef. + * @param arena The host arena of this reef. * @param isBlue Wether this is the blue reef or the red one. */ ReefscapeReefSimulation(Arena2025Reefscape arena, boolean isBlue) { diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/opponentsim/KitBot.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/opponentsim/KitBot.java new file mode 100644 index 0000000..fc0f15b --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/opponentsim/KitBot.java @@ -0,0 +1,134 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025.opponentsim; + +import edu.wpi.first.math.MathUtil; +import edu.wpi.first.math.geometry.Rotation2d; +import edu.wpi.first.math.geometry.Translation2d; +import edu.wpi.first.math.kinematics.ChassisSpeeds; +import edu.wpi.first.wpilibj.DriverStation; +import edu.wpi.first.wpilibj2.command.Command; +import edu.wpi.first.wpilibj2.command.Commands; +import edu.wpi.first.wpilibj2.command.button.CommandXboxController; +import swervelib.simulation.ironmaple.simulation.IntakeSimulation; +import swervelib.simulation.ironmaple.simulation.opponentsim.SmartOpponent; +import swervelib.simulation.ironmaple.simulation.opponentsim.SmartOpponentConfig; +import swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025.Arena2025Reefscape; +import swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025.ReefscapeCoralOnFly; + +import static edu.wpi.first.units.Units.*; + +public class KitBot extends SmartOpponent { + /** + * A SmartOpponent for FRC Reefscape. + * + * @param name the opponent name. Typically just "SuperKitBot 1". + * Names should not be the same. + * @param alliance the opponents {@link DriverStation.Alliance}. + */ + public KitBot(String name, DriverStation.Alliance alliance) { + /// All Options should be set in the constructor. + super(new SmartOpponentConfig() + .withName(name) + .withAlliance(alliance) + .withManager(Arena2025Reefscape.getInstance().getOpponentManager()) + .withChassisConfig(SmartOpponentConfig.ChassisConfig.Presets.SimpleSquareChassis.getConfig() + .withMaxLinearVelocity(MetersPerSecond.of(4)) + .withMaxAngularVelocity(DegreesPerSecond.of(360))) + .removeScoringPoseType("Barge") + .withAutoEnable()); + /// Adds a separate subsystem thread for the manipulator, this allows better manual control support. + // TODO add better commenting + this.manipulatorSim + .addIntakeSimulation( + "Intake", + IntakeSimulation.InTheFrameIntake( + "Coral", + drivetrainSim.getDriveTrainSimulation(), + Inches.of(20), + IntakeSimulation.IntakeSide.FRONT, + 1)) + .addProjectileSimulation( + "Coral", + () -> new ReefscapeCoralOnFly( + drivetrainSim.getActualPoseInSimulationWorld().getTranslation(), + new Translation2d(Inches.of(0), Inches.of(-18)), // Shooter on bot + drivetrainSim + .getActualSpeedsFieldRelative() + .plus(ChassisSpeeds.fromRobotRelativeSpeeds( + new ChassisSpeeds( + 1, 0, 0), // Added chassis speeds to change coral velocity, + drivetrainSim + .getActualPoseInSimulationWorld() + .getRotation())), // this is because we want a horizontal score + drivetrainSim + .getActualPoseInSimulationWorld() + .getRotation() + .rotateBy( + Rotation2d.kCCW_90deg), // Rotated by 90 degrees for horizontal shooter. + Inches.of(30), // Shooter Height + MetersPerSecond.of(0), // Initial piece speed + Degrees.of(0))); // Shooter angle + } + + /** + * The collect state to run. + * + * @return a runnable that runs the state. + */ + @Override + protected Command collectState() { + return pathfind(getCollectTarget(), MetersPerSecond.of(2)) + .andThen(manipulatorSim.intake("Intake").withTimeout(1.5)) + .finallyDo(() -> setState("Score")) + .withTimeout(12); + } + + /** + * The score state to run. + * + * @return a runnable that runs the state. + */ + @Override + protected Command scoreState() { + return pathfind(getScoringTarget(), MetersPerSecond.of(2)) + .andThen(Commands.waitSeconds(1.5)) + .andThen(manipulatorSim.score("Coral")) + .andThen(Commands.waitSeconds(0.5)) + .finallyDo(() -> setState("Collect")) + .withTimeout(12); + } + + // TODO + public KitBot withXboxController(CommandXboxController xboxController) { + config.withJoystick(xboxController); + config.withState("Joystick", this::joystickState); + config.withBehavior( + "Player", + startingState("Joystick").andThen(startingState("Joystick").ignoringDisable(false))); + config.updateBehaviorChooser(); + /// Enable Manipulator control + xboxController.leftBumper().and(config.isStateTrigger("Joystick")).whileTrue(manipulatorSim.intake("Intake")); + xboxController.rightBumper().and(config.isStateTrigger("Joystick")).whileTrue(manipulatorSim.score("Coral")); + return this; + } + + /** + * The joystick state to run. Should be inaccessible when not set. + * + * @return the joystick state to run. + */ + private Command joystickState() { + final CommandXboxController xbox = ((CommandXboxController) config.getJoystick()); + return drive( + () -> new ChassisSpeeds( + MathUtil.applyDeadband( + xbox.getLeftY() * -config.chassis.maxLinearVelocity.in(MetersPerSecond), + config.joystickDeadband), + MathUtil.applyDeadband( + xbox.getLeftX() * -config.chassis.maxLinearVelocity.in(MetersPerSecond), + config.joystickDeadband), + MathUtil.applyDeadband( + xbox.getRightX() * -config.chassis.maxAngularVelocity.in(RadiansPerSecond), + config.joystickDeadband)), + false); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/opponentsim/ReefscapeNavGrid.json b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/opponentsim/ReefscapeNavGrid.json new file mode 100644 index 0000000..27fec13 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/opponentsim/ReefscapeNavGrid.json @@ -0,0 +1,1656 @@ +{ + "field_size": { + "x": 17.548, + "y": 8.052 + }, + "nodeSizeMeters": 0.3, + "grid": [ + [ + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true + ], + [ + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true + ], + [ + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true + ], + [ + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true + ], + [ + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true + ], + [ + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true + ], + [ + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true + ], + [ + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true + ], + [ + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true + ], + [ + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true + ] + ] +} \ No newline at end of file diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/opponentsim/ReefscapeOpponentManager.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/opponentsim/ReefscapeOpponentManager.java new file mode 100644 index 0000000..0da19a1 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/opponentsim/ReefscapeOpponentManager.java @@ -0,0 +1,97 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025.opponentsim; + +import edu.wpi.first.math.geometry.Pose2d; +import edu.wpi.first.math.geometry.Rotation2d; +import edu.wpi.first.math.geometry.Transform2d; +import edu.wpi.first.math.util.Units; +import swervelib.simulation.ironmaple.simulation.opponentsim.OpponentManager; + +public class ReefscapeOpponentManager extends OpponentManager { + public ReefscapeOpponentManager() { + super(true); // Default Starting and queening poses. + super + /// All reef scoring poses + .addScoringPose("Reef", "Reef South Left", PoseConstants.REEF_SOUTH_LEFT_POSE) + .addScoringPose("Reef", "Reef South Right", PoseConstants.REEF_SOUTH_RIGHT_POSE) + .addScoringPose("Reef", "Reef Southeast Left", PoseConstants.REEF_SOUTHEAST_LEFT_POSE) + .addScoringPose("Reef", "Reef Southeast Right", PoseConstants.REEF_SOUTHEAST_RIGHT_POSE) + .addScoringPose("Reef", "Reef Northeast Left", PoseConstants.REEF_NORTHEAST_LEFT_POSE) + .addScoringPose("Reef", "Reef Northeast Right", PoseConstants.REEF_NORTHEAST_RIGHT_POSE) + .addScoringPose("Reef", "Reef North Left", PoseConstants.REEF_NORTH_LEFT_POSE) + .addScoringPose("Reef", "Reef North Right", PoseConstants.REEF_NORTH_RIGHT_POSE) + .addScoringPose("Reef", "Reef Northwest Left", PoseConstants.REEF_NORTHWEST_LEFT_POSE) + .addScoringPose("Reef", "Reef Northwest Right", PoseConstants.REEF_NORTHWEST_RIGHT_POSE) + .addScoringPose("Reef", "Reef Southwest Left", PoseConstants.REEF_SOUTHWEST_LEFT_POSE) + .addScoringPose("Reef", "Reef Southwest Right", PoseConstants.REEF_SOUTHWEST_RIGHT_POSE) + /// Barge scoring pose + .addScoringPose("Barge", "Net", PoseConstants.BARGE_NET_POSE) + /// Coral Station Poses + .addCollectingPose( + "Left Station", "Left", PoseConstants.LEFT_STATION_POSE.plus(PoseConstants.SLOT_OFFSET_LEFT)) + .addCollectingPose( + "Left Station", "Center", PoseConstants.LEFT_STATION_POSE.plus(PoseConstants.SLOT_OFFSET_RIGHT)) + .addCollectingPose( + "Left Station", "Right", PoseConstants.LEFT_STATION_POSE.plus(PoseConstants.SLOT_OFFSET_RIGHT)) + .addCollectingPose( + "Right Station", "Left", PoseConstants.RIGHT_STATION_POSE.plus(PoseConstants.SLOT_OFFSET_LEFT)) + .addCollectingPose("Right Station", "Center", PoseConstants.RIGHT_STATION_POSE) + .addCollectingPose( + "Right Station", + "Right", + PoseConstants.RIGHT_STATION_POSE.plus(PoseConstants.SLOT_OFFSET_RIGHT)); + } + + /// Its end of the season, so I just copied my constants here and added them as such. + /// Typically, it would probably just be a new Pose2d()... + private static class PoseConstants { + public static final Transform2d STATION_OFFSET = + new Transform2d(Units.inchesToMeters(-17), Units.inchesToMeters(0), Rotation2d.kZero); + public static final Transform2d SLOT_OFFSET_LEFT = new Transform2d( + Units.inchesToMeters(0), + Units.inchesToMeters(24), // Added several times to achieve all 5 poses. + Rotation2d.kZero); + public static final Transform2d SLOT_OFFSET_RIGHT = new Transform2d( + Units.inchesToMeters(0), + Units.inchesToMeters(-30), // Added several times to achieve all 5 poses. + Rotation2d.kZero); + public static final Pose2d BARGE_NET_POSE = new Pose2d(7.5, 2, Rotation2d.fromDegrees(0)); + public static final Pose2d LEFT_STATION_CENTER_POSE = new Pose2d( + Units.inchesToMeters(33.526), Units.inchesToMeters(291.176), Rotation2d.fromDegrees(125.989)); + public static final Pose2d RIGHT_STATION_CENTER_POSE = + new Pose2d(Units.inchesToMeters(33.526), Units.inchesToMeters(25.824), Rotation2d.fromDegrees(234.011)); + public static final Pose2d LEFT_STATION_POSE = LEFT_STATION_CENTER_POSE.plus(STATION_OFFSET); + public static final Pose2d RIGHT_STATION_POSE = RIGHT_STATION_CENTER_POSE.plus(STATION_OFFSET); + public static final Pose2d SOUTH_FACE_POSE = + new Pose2d(Units.inchesToMeters(144.003), Units.inchesToMeters(158.500), Rotation2d.fromDegrees(0)); + public static final Pose2d SOUTHWEST_FACE_POSE = + new Pose2d(Units.inchesToMeters(160.373), Units.inchesToMeters(186.857), Rotation2d.fromDegrees(300)); + public static final Pose2d NORTHWEST_FACE_POSE = + new Pose2d(Units.inchesToMeters(193.116), Units.inchesToMeters(186.858), Rotation2d.fromDegrees(240)); + public static final Pose2d NORTH_FACE_POSE = + new Pose2d(Units.inchesToMeters(209.489), Units.inchesToMeters(158.502), Rotation2d.fromDegrees(180)); + public static final Pose2d NORTHEAST_FACE_POSE = + new Pose2d(Units.inchesToMeters(193.118), Units.inchesToMeters(130.145), Rotation2d.fromDegrees(120)); + public static final Pose2d SOUTHEAST_FACE_POSE = + new Pose2d(Units.inchesToMeters(160.375), Units.inchesToMeters(130.144), Rotation2d.fromDegrees(60)); + public static final Transform2d BRANCH_OFFSET_LEFT = new Transform2d( + Units.inchesToMeters(-28), // Offset away from the reef. + Units.inchesToMeters(13 / 2.0), // Offset to left branch. + Rotation2d.kZero); + public static final Transform2d BRANCH_OFFSET_RIGHT = new Transform2d( + Units.inchesToMeters(-28), // Offset away from the reef. + Units.inchesToMeters(-13 / 2.0), // Offset to the right branch. + Rotation2d.kZero); + public static final Pose2d REEF_NORTH_LEFT_POSE = NORTH_FACE_POSE.plus(BRANCH_OFFSET_LEFT); + public static final Pose2d REEF_NORTH_RIGHT_POSE = NORTH_FACE_POSE.plus(BRANCH_OFFSET_RIGHT); + public static final Pose2d REEF_NORTHEAST_LEFT_POSE = NORTHEAST_FACE_POSE.plus(BRANCH_OFFSET_LEFT); + public static final Pose2d REEF_NORTHEAST_RIGHT_POSE = NORTHEAST_FACE_POSE.plus(BRANCH_OFFSET_RIGHT); + public static final Pose2d REEF_NORTHWEST_LEFT_POSE = NORTHWEST_FACE_POSE.plus(BRANCH_OFFSET_LEFT); + public static final Pose2d REEF_NORTHWEST_RIGHT_POSE = NORTHWEST_FACE_POSE.plus(BRANCH_OFFSET_RIGHT); + public static final Pose2d REEF_SOUTH_LEFT_POSE = SOUTH_FACE_POSE.plus(BRANCH_OFFSET_LEFT); + public static final Pose2d REEF_SOUTH_RIGHT_POSE = SOUTH_FACE_POSE.plus(BRANCH_OFFSET_RIGHT); + public static final Pose2d REEF_SOUTHEAST_LEFT_POSE = SOUTHEAST_FACE_POSE.plus(BRANCH_OFFSET_LEFT); + public static final Pose2d REEF_SOUTHEAST_RIGHT_POSE = SOUTHEAST_FACE_POSE.plus(BRANCH_OFFSET_RIGHT); + public static final Pose2d REEF_SOUTHWEST_LEFT_POSE = SOUTHWEST_FACE_POSE.plus(BRANCH_OFFSET_LEFT); + public static final Pose2d REEF_SOUTHWEST_RIGHT_POSE = SOUTHWEST_FACE_POSE.plus(BRANCH_OFFSET_RIGHT); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/opponentsim/SuperKitBot.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/opponentsim/SuperKitBot.java new file mode 100644 index 0000000..ce62452 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/opponentsim/SuperKitBot.java @@ -0,0 +1,217 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025.opponentsim; + +import edu.wpi.first.math.MathUtil; +import edu.wpi.first.math.Pair; +import edu.wpi.first.math.geometry.Pose2d; +import edu.wpi.first.math.geometry.Translation2d; +import edu.wpi.first.math.kinematics.ChassisSpeeds; +import edu.wpi.first.units.measure.Angle; +import edu.wpi.first.units.measure.Distance; +import edu.wpi.first.wpilibj.DriverStation; +import edu.wpi.first.wpilibj2.command.Command; +import edu.wpi.first.wpilibj2.command.Commands; +import edu.wpi.first.wpilibj2.command.button.CommandXboxController; +import swervelib.simulation.ironmaple.simulation.IntakeSimulation; +import swervelib.simulation.ironmaple.simulation.opponentsim.SmartOpponent; +import swervelib.simulation.ironmaple.simulation.opponentsim.SmartOpponentConfig; +import swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025.Arena2025Reefscape; +import swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025.ReefscapeAlgaeOnFly; +import swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025.ReefscapeCoralOnFly; + +import java.util.Objects; + +import static edu.wpi.first.units.Units.*; + +public class SuperKitBot extends SmartOpponent { + /** + * A SmartOpponent for FRC Reefscape. This robot breaks rules, hence "Super" KitBot. + * + * @param name the opponent name. Typically just "SuperKitBot 1". + * Names should not be the same. + * @param alliance the opponents {@link DriverStation.Alliance}. + */ + public SuperKitBot(String name, DriverStation.Alliance alliance) { + /// All Options should be set in the constructor. + super(new SmartOpponentConfig() + .withName(name) + .withAlliance(alliance) + .withManager(Arena2025Reefscape.getInstance().getOpponentManager()) + .withScoringPoseWeights("Net", 10) + .withChassisConfig(SmartOpponentConfig.ChassisConfig.Presets.SimpleSquareChassis.getConfig() + .withBumperHeight(Inches.of(38)) + .withBumperWidth(Inches.of(28)) + .withTrackLength(Inches.of(28)) + .withTrackWidth(Inches.of(18))) + .withAutoEnable()); + /// Adds a new separate subsystem for the manipulator, this allows better manual control support. + this.manipulatorSim + /// Adds an intake to the manipulatorSim; you can add as many as you want with + // .addIntakeSimulation(String name, IntakeSimulation) + .addIntakeSimulation( + "Intake", + // Our new intake sim. + IntakeSimulation.InTheFrameIntake( + // This one focuses on coral. + "Coral", + // Our driveSim so the intake can tell if we collected a piece. + drivetrainSim.getDriveTrainSimulation(), + // How long the intake is from the center of the selected side. + Inches.of(20), + // Which side of the robot the intake is on. + IntakeSimulation.IntakeSide.FRONT, + // Max game piece capacity. + 1)) + .addProjectileSimulation( + "Algae", + () -> new ReefscapeAlgaeOnFly( + drivetrainSim.getActualPoseInSimulationWorld().getTranslation(), // Opponent Pose + new Translation2d(Inches.of(0), Inches.of(-18)), // Pose on bot + drivetrainSim.getActualSpeedsRobotRelative(), // Robot Relative opponent speeds + drivetrainSim.getActualPoseInSimulationWorld().getRotation(), // Shooter heading + Meters.of(2.5), // Shooter Height + MetersPerSecond.of(2), // Shooter speed + Degrees.of(20))) // Shooter angle + .addProjectileSimulation("Reef L1", () -> newCoral(Meters.of(.7))) + .addProjectileSimulation("Reef L2", () -> newCoral(Meters.of(1))) + .addProjectileSimulation("Reef L3", () -> newCoral(Meters.of(1.5))) + .addProjectileSimulation("Reef L4", () -> newCoral(Meters.of(3), Degrees.of(-75))); + + System.out.println("Projectile Simulation Started: " + manipulatorSim.getProjectileSimulations().toString()); + } + + /** + * Creates a new CoralOnTheFly with static variables for the reef. + * + * @param height initial coral height. + * @return the new {@link ReefscapeCoralOnFly}. + */ + private ReefscapeCoralOnFly newCoral(Distance height) { + return newCoral(height, Degrees.of(-15)); + } + + /** + * Creates a new CoralOnTheFly with static variables for the reef. + * + * @param height initial coral height. + * @param angle initial coral angle. + * @return the new {@link ReefscapeCoralOnFly}. + */ + private ReefscapeCoralOnFly newCoral(Distance height, Angle angle) { + return new ReefscapeCoralOnFly( + // Obtain robot position from drive simulation + drivetrainSim.getActualPoseInSimulationWorld().getTranslation(), + // The scoring mechanism is installed at (x, y) (meters) on the robot + new Translation2d(Inches.of(20), Inches.of(0)), + // Obtain robot speed from drive simulation + drivetrainSim.getActualSpeedsRobotRelative(), + // Obtain robot facing from drive simulation + drivetrainSim.getActualPoseInSimulationWorld().getRotation(), + // The height at which the coral is ejected + height, + // The initial speed of the coral + MetersPerSecond.of(2), + // The coral is ejected at a 35-degree slope + angle); + } + + /** + * The collect state to run. + * + * @return a runnable that runs the state. + */ + @Override + protected Command collectState() { + final Pair target = getCollectTarget(); + if (target == null) return Commands.none(); + return pathfind(target, MetersPerSecond.of(8)) + .andThen(manipulatorSim.intake("Intake").withTimeout(0.5)) + .finallyDo(() -> setState("Score")) + .withTimeout(12); + } + + /** + * Gets a random reef level to score. + * + * @return a random reef level to score. + */ + private Command scoreReef() { + // Random integer from 0-4; + final int target = (int) (Math.random() * 4); + return switch (target) { + case 1 -> manipulatorSim.score("Reef L2"); + case 2 -> manipulatorSim.score("Reef L3"); + case 3 -> manipulatorSim.score("Reef L4"); + default -> manipulatorSim.score("Reef L1"); + }; + } + + /** + * The score state to run. + * + * @return a runnable that runs the state. + */ + @Override + protected Command scoreState() { + final Pair target = getScoringTarget(); + if (target == null) return Commands.none(); + return pathfind(target, MetersPerSecond.of(8)) + .andThen(Commands.waitSeconds(0.5)) + .andThen(isCoralTarget() ? scoreReef() : manipulatorSim.score("Algae")) + .andThen(Commands.waitSeconds(0.2)) + .finallyDo(() -> setState("Collect")) + .withTimeout(12); + } + + /** + * Whether the current target is coral. + * + * @return whether the current target is coral. + */ + private boolean isCoralTarget() { + return !Objects.equals(target.getFirst(), "Barge Net"); + } + + /** + * SuperKitBot Specific joystick method. Has button bindings too. + * + * @param xboxController the controller to use. + * @return this, for chaining. + */ + public SuperKitBot withXboxController(CommandXboxController xboxController) { + config.withJoystick(xboxController); + config.withState("Joystick", this::joystickState); + config.withBehavior( + "Player", + startingState("Joystick").andThen(startingState("Joystick").ignoringDisable(true))); + config.updateBehaviorChooser(); + /// Enable Manipulator control + xboxController.leftBumper().and(config.isStateTrigger("Joystick")).whileTrue(manipulatorSim.intake("Intake")); + xboxController.rightBumper().and(config.isStateTrigger("Joystick")).onTrue(manipulatorSim.score("Reef L1")); + xboxController.b().and(config.isStateTrigger("Joystick")).onTrue(manipulatorSim.score("Reef L2")); + xboxController.x().and(config.isStateTrigger("Joystick")).onTrue(manipulatorSim.score("Reef L3")); + xboxController.y().and(config.isStateTrigger("Joystick")).onTrue(manipulatorSim.score("Reef L4")); + xboxController.a().and(config.isStateTrigger("Joystick")).onTrue(manipulatorSim.score("Algae")); + return this; + } + + /** + * The joystick state to run. Should be inaccessible when not set. + * + * @return the joystick state to run. + */ + private Command joystickState() { + final CommandXboxController xbox = ((CommandXboxController) config.getJoystick()); + return drive( + () -> new ChassisSpeeds( + MathUtil.applyDeadband( + xbox.getLeftY() * -config.chassis.maxLinearVelocity.in(MetersPerSecond), + config.joystickDeadband), + MathUtil.applyDeadband( + xbox.getLeftX() * -config.chassis.maxLinearVelocity.in(MetersPerSecond), + config.joystickDeadband), + MathUtil.applyDeadband( + xbox.getRightX() * -config.chassis.maxAngularVelocity.in(RadiansPerSecond), + config.joystickDeadband)), + false); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/utils/FieldMirroringUtils.java b/yagsl/java/swervelib/simulation/ironmaple/utils/FieldMirroringUtils.java index aeb3218..76759d1 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/utils/FieldMirroringUtils.java +++ b/yagsl/java/swervelib/simulation/ironmaple/utils/FieldMirroringUtils.java @@ -5,6 +5,7 @@ import edu.wpi.first.math.geometry.Translation2d; import edu.wpi.first.math.geometry.Translation3d; import edu.wpi.first.wpilibj.DriverStation; + import java.util.Optional; public class FieldMirroringUtils { diff --git a/yagsl/java/swervelib/simulation/ironmaple/utils/LegacyFieldMirroringUtils2024.java b/yagsl/java/swervelib/simulation/ironmaple/utils/LegacyFieldMirroringUtils2024.java index 9618877..78db638 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/utils/LegacyFieldMirroringUtils2024.java +++ b/yagsl/java/swervelib/simulation/ironmaple/utils/LegacyFieldMirroringUtils2024.java @@ -5,6 +5,7 @@ import edu.wpi.first.math.geometry.Translation2d; import edu.wpi.first.math.geometry.Translation3d; import edu.wpi.first.wpilibj.DriverStation; + import java.util.Optional; import java.util.function.Supplier; diff --git a/yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/GeometryConvertor.java b/yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/GeometryConvertor.java index 52ffbf9..c1d1508 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/GeometryConvertor.java +++ b/yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/GeometryConvertor.java @@ -8,7 +8,9 @@ import org.dyn4j.geometry.Transform; import org.dyn4j.geometry.Vector2; -/** utils to convert between WPILIB and dyn4j geometry classes */ +/** + * utils to convert between WPILIB and dyn4j geometry classes + */ public class GeometryConvertor { public static Vector2 toDyn4jVector2(Translation2d wpilibTranslation2d) { return new Vector2(wpilibTranslation2d.getX(), wpilibTranslation2d.getY()); diff --git a/yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/MapleCommonMath.java b/yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/MapleCommonMath.java index 9ade923..5a592d1 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/MapleCommonMath.java +++ b/yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/MapleCommonMath.java @@ -2,6 +2,7 @@ import edu.wpi.first.math.geometry.Rotation2d; import edu.wpi.first.math.geometry.Translation2d; + import java.util.Random; public class MapleCommonMath { @@ -10,7 +11,7 @@ public class MapleCommonMath { /** * using the random number generator of a fixed seed, generate the next random normal variable * - * @param mean the center of the distribution + * @param mean the center of the distribution * @param stdDev the standard deviation of the distribution * @return the next random variable x from the distribution */ @@ -27,7 +28,7 @@ public static double generateRandomNormal(double mean, double stdDev) { * *

    Constrains the magnitude of a value.

    * - * @param value the value to constrain + * @param value the value to constrain * @param maxMagnitude the maximum allowed magnitude * @return the constrained value */ diff --git a/yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/SwerveStateProjection.java b/yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/SwerveStateProjection.java index 0a31e76..6b2c850 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/SwerveStateProjection.java +++ b/yagsl/java/swervelib/simulation/ironmaple/utils/mathutils/SwerveStateProjection.java @@ -8,7 +8,7 @@ public class SwerveStateProjection { /** * Projects the swerve module speed onto the direction of the current swerve facing. * - * @param swerveSpeed The current speed and direction of the swerve module. + * @param swerveSpeed The current speed and direction of the swerve module. * @param currentSwerveFacing The desired direction to project onto. * @return The projected speed in the direction of currentSwerveFacing. */ From a7235feedd5e6265ee213a74d3f3e239b2e4628a Mon Sep 17 00:00:00 2001 From: thenetworkgrinch Date: Sun, 11 Jan 2026 17:11:45 -0600 Subject: [PATCH 07/62] Fixed maplesime oppo --- examples/clock_drive_drivebase/build.gradle | 2 +- .../vendordeps/PathplannerLib-2026.1.2.json | 38 ++ ...eta-1.json => Phoenix5-replay-5.36.0.json} | 44 +- .../vendordeps/Phoenix6-replay-26.1.0.json} | 114 ++-- .../vendordeps/REVLib.json | 20 +- .../vendordeps/Studica-2026.0.0-beta.json | 71 --- .../vendordeps/StudicaLib.json | 71 --- .../vendordeps/ThriftyLib.json | 20 - .../vendordeps/WPILibNewCommands.json | 76 +-- .../vendordeps/PathplannerLib-2026.1.2.json | 38 ++ .../vendordeps/Phoenix5-replay-5.36.0.json} | 44 +- .../vendordeps/Phoenix6-replay-26.1.0.json} | 114 ++-- .../vendordeps/REVLib.json | 20 +- .../vendordeps/Studica-2026.0.0-beta.json | 71 --- .../vendordeps/StudicaLib.json | 71 --- .../vendordeps/ThriftyLib.json | 20 - .../vendordeps/WPILibNewCommands.json | 76 +-- .../vendordeps/PathplannerLib-2026.1.2.json | 38 ++ .../vendordeps/Phoenix5-replay-5.36.0.json} | 44 +- ...eta-1.json => Phoenix6-replay-26.1.0.json} | 114 ++-- .../vendordeps/REVLib.json | 20 +- .../vendordeps/Studica-2026.0.0-beta.json | 71 --- .../vendordeps/StudicaLib.json | 71 --- .../vendordeps/ThriftyLib.json | 20 - .../vendordeps/WPILibNewCommands.json | 76 +-- .../field_oriented_drivebase/build.gradle | 2 +- .../vendordeps/PathplannerLib-2026.1.2.json | 38 ++ ...eta-1.json => Phoenix5-replay-5.36.0.json} | 44 +- ...eta-1.json => Phoenix6-replay-26.1.0.json} | 114 ++-- examples/full_example/vendordeps/REVLib.json | 20 +- .../vendordeps/Studica-2026.0.0-beta.json | 71 --- .../full_example/vendordeps/StudicaLib.json | 71 --- .../full_example/vendordeps/ThriftyLib.json | 20 - .../vendordeps/WPILibNewCommands.json | 76 +-- .../robot_relative_drivebase/build.gradle | 2 +- .../vendordeps/PathplannerLib-2026.1.2.json | 38 ++ .../Phoenix5-replay-5.36.0-beta-1.json | 221 -------- .../vendordeps/Phoenix5-replay-5.36.0.json | 221 ++++++++ .../Phoenix6-replay-26.0.0-beta-1.json | 453 ---------------- .../vendordeps/Phoenix6-replay-26.1.0.json | 497 ++++++++++++++++++ .../vendordeps/REVLib.json | 20 +- .../vendordeps/Studica-2026.0.0-beta.json | 71 --- .../vendordeps/StudicaLib.json | 71 --- .../vendordeps/ThriftyLib.json | 20 - .../vendordeps/WPILibNewCommands.json | 76 +-- .../vendordeps/PathplannerLib-2026.1.2.json | 38 ++ .../Phoenix5-replay-5.36.0-beta-1.json | 221 -------- .../vendordeps/Phoenix5-replay-5.36.0.json | 221 ++++++++ .../Phoenix6-replay-26.0.0-beta-1.json | 453 ---------------- .../vendordeps/Phoenix6-replay-26.1.0.json | 497 ++++++++++++++++++ vendordep/vendordeps/REVLib.json | 20 +- .../vendordeps/Studica-2026.0.0-beta.json | 71 --- vendordep/vendordeps/StudicaLib.json | 71 --- vendordep/vendordeps/ThriftyLib.json | 20 - vendordep/vendordeps/WPILibNewCommands.json | 76 +-- .../opponentsim/OpponentManager.java | 3 +- .../simulation/opponentsim/SmartOpponent.java | 11 +- 57 files changed, 2367 insertions(+), 2845 deletions(-) create mode 100644 examples/clock_drive_drivebase/vendordeps/PathplannerLib-2026.1.2.json rename examples/clock_drive_drivebase/vendordeps/{Phoenix5-replay-5.36.0-beta-1.json => Phoenix5-replay-5.36.0.json} (86%) rename examples/{drivebase_with_PathPlanner/vendordeps/Phoenix6-replay-26.0.0-beta-1.json => clock_drive_drivebase/vendordeps/Phoenix6-replay-26.1.0.json} (83%) delete mode 100644 examples/clock_drive_drivebase/vendordeps/Studica-2026.0.0-beta.json delete mode 100644 examples/clock_drive_drivebase/vendordeps/StudicaLib.json delete mode 100644 examples/clock_drive_drivebase/vendordeps/ThriftyLib.json create mode 100644 examples/drivebase_with_PathPlanner/vendordeps/PathplannerLib-2026.1.2.json rename examples/{drivebase_with_PhotonVision/vendordeps/Phoenix5-replay-5.36.0-beta-1.json => drivebase_with_PathPlanner/vendordeps/Phoenix5-replay-5.36.0.json} (86%) rename examples/{clock_drive_drivebase/vendordeps/Phoenix6-replay-26.0.0-beta-1.json => drivebase_with_PathPlanner/vendordeps/Phoenix6-replay-26.1.0.json} (83%) delete mode 100644 examples/drivebase_with_PathPlanner/vendordeps/Studica-2026.0.0-beta.json delete mode 100644 examples/drivebase_with_PathPlanner/vendordeps/StudicaLib.json delete mode 100644 examples/drivebase_with_PathPlanner/vendordeps/ThriftyLib.json create mode 100644 examples/drivebase_with_PhotonVision/vendordeps/PathplannerLib-2026.1.2.json rename examples/{drivebase_with_PathPlanner/vendordeps/Phoenix5-replay-5.36.0-beta-1.json => drivebase_with_PhotonVision/vendordeps/Phoenix5-replay-5.36.0.json} (86%) rename examples/drivebase_with_PhotonVision/vendordeps/{Phoenix6-replay-26.0.0-beta-1.json => Phoenix6-replay-26.1.0.json} (83%) delete mode 100644 examples/drivebase_with_PhotonVision/vendordeps/Studica-2026.0.0-beta.json delete mode 100644 examples/drivebase_with_PhotonVision/vendordeps/StudicaLib.json delete mode 100644 examples/drivebase_with_PhotonVision/vendordeps/ThriftyLib.json create mode 100644 examples/full_example/vendordeps/PathplannerLib-2026.1.2.json rename examples/full_example/vendordeps/{Phoenix5-replay-5.36.0-beta-1.json => Phoenix5-replay-5.36.0.json} (86%) rename examples/full_example/vendordeps/{Phoenix6-replay-26.0.0-beta-1.json => Phoenix6-replay-26.1.0.json} (83%) delete mode 100644 examples/full_example/vendordeps/Studica-2026.0.0-beta.json delete mode 100644 examples/full_example/vendordeps/StudicaLib.json delete mode 100644 examples/full_example/vendordeps/ThriftyLib.json create mode 100644 examples/robot_relative_drivebase/vendordeps/PathplannerLib-2026.1.2.json delete mode 100644 examples/robot_relative_drivebase/vendordeps/Phoenix5-replay-5.36.0-beta-1.json create mode 100644 examples/robot_relative_drivebase/vendordeps/Phoenix5-replay-5.36.0.json delete mode 100644 examples/robot_relative_drivebase/vendordeps/Phoenix6-replay-26.0.0-beta-1.json create mode 100644 examples/robot_relative_drivebase/vendordeps/Phoenix6-replay-26.1.0.json delete mode 100644 examples/robot_relative_drivebase/vendordeps/Studica-2026.0.0-beta.json delete mode 100644 examples/robot_relative_drivebase/vendordeps/StudicaLib.json delete mode 100644 examples/robot_relative_drivebase/vendordeps/ThriftyLib.json create mode 100644 vendordep/vendordeps/PathplannerLib-2026.1.2.json delete mode 100644 vendordep/vendordeps/Phoenix5-replay-5.36.0-beta-1.json create mode 100644 vendordep/vendordeps/Phoenix5-replay-5.36.0.json delete mode 100644 vendordep/vendordeps/Phoenix6-replay-26.0.0-beta-1.json create mode 100644 vendordep/vendordeps/Phoenix6-replay-26.1.0.json delete mode 100644 vendordep/vendordeps/Studica-2026.0.0-beta.json delete mode 100644 vendordep/vendordeps/StudicaLib.json delete mode 100644 vendordep/vendordeps/ThriftyLib.json diff --git a/examples/clock_drive_drivebase/build.gradle b/examples/clock_drive_drivebase/build.gradle index 4233229..faa789c 100644 --- a/examples/clock_drive_drivebase/build.gradle +++ b/examples/clock_drive_drivebase/build.gradle @@ -1,6 +1,6 @@ plugins { id "java" - id "edu.wpi.first.GradleRIO" version "2026.1.1-beta-1" + id "edu.wpi.first.GradleRIO" version "2026.1.1" } java { diff --git a/examples/clock_drive_drivebase/vendordeps/PathplannerLib-2026.1.2.json b/examples/clock_drive_drivebase/vendordeps/PathplannerLib-2026.1.2.json new file mode 100644 index 0000000..f72fa41 --- /dev/null +++ b/examples/clock_drive_drivebase/vendordeps/PathplannerLib-2026.1.2.json @@ -0,0 +1,38 @@ +{ + "fileName": "PathplannerLib-2026.1.2.json", + "name": "PathplannerLib", + "version": "2026.1.2", + "uuid": "1b42324f-17c6-4875-8e77-1c312bc8c786", + "frcYear": "2026", + "mavenUrls": [ + "https://3015rangerrobotics.github.io/pathplannerlib/repo" + ], + "jsonUrl": "https://3015rangerrobotics.github.io/pathplannerlib/PathplannerLib.json", + "javaDependencies": [ + { + "groupId": "com.pathplanner.lib", + "artifactId": "PathplannerLib-java", + "version": "2026.1.2" + } + ], + "jniDependencies": [], + "cppDependencies": [ + { + "groupId": "com.pathplanner.lib", + "artifactId": "PathplannerLib-cpp", + "version": "2026.1.2", + "libName": "PathplannerLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal", + "linuxathena", + "linuxarm32", + "linuxarm64" + ] + } + ] +} \ No newline at end of file diff --git a/examples/clock_drive_drivebase/vendordeps/Phoenix5-replay-5.36.0-beta-1.json b/examples/clock_drive_drivebase/vendordeps/Phoenix5-replay-5.36.0.json similarity index 86% rename from examples/clock_drive_drivebase/vendordeps/Phoenix5-replay-5.36.0-beta-1.json rename to examples/clock_drive_drivebase/vendordeps/Phoenix5-replay-5.36.0.json index 4a78551..0e799ed 100644 --- a/examples/clock_drive_drivebase/vendordeps/Phoenix5-replay-5.36.0-beta-1.json +++ b/examples/clock_drive_drivebase/vendordeps/Phoenix5-replay-5.36.0.json @@ -1,50 +1,50 @@ { - "fileName": "Phoenix5-replay-5.36.0-beta-1.json", + "fileName": "Phoenix5-replay-5.36.0.json", "name": "CTRE-Phoenix (v5)", - "version": "5.36.0-beta-1", - "frcYear": "2026beta", + "version": "5.36.0", + "frcYear": "2026", "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", "mavenUrls": [ "https://maven.ctr-electronics.com/release/" ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-beta-latest.json", + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-latest.json", "requires": [ { "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", - "offlineFileName": "Phoenix6-replay-frc2026-beta-latest.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json" + "offlineFileName": "Phoenix6-replay-frc2026-latest.json", + "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-latest.json" } ], "conflictsWith": [ { "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", "errorMessage": "Users must use the regular Phoenix 5 vendordep when using the regular Phoenix 6 vendordep.", - "offlineFileName": "Phoenix6-frc2026-beta-latest.json" + "offlineFileName": "Phoenix6-frc2026-latest.json" }, { "uuid": "ab676553-b602-441f-a38d-f1296eff6537", "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", - "offlineFileName": "Phoenix5-frc2026-beta-latest.json" + "offlineFileName": "Phoenix5-frc2026-latest.json" } ], "javaDependencies": [ { "groupId": "com.ctre.phoenix", "artifactId": "api-java", - "version": "5.36.0-beta-1" + "version": "5.36.0" }, { "groupId": "com.ctre.phoenix", "artifactId": "wpiapi-java", - "version": "5.36.0-beta-1" + "version": "5.36.0" } ], "jniDependencies": [ { "groupId": "com.ctre.phoenix", "artifactId": "cci", - "version": "5.36.0-beta-1", + "version": "5.36.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -55,7 +55,7 @@ { "groupId": "com.ctre.phoenix.replay", "artifactId": "cci-replay", - "version": "5.36.0-beta-1", + "version": "5.36.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -69,7 +69,7 @@ { "groupId": "com.ctre.phoenix.sim", "artifactId": "cci-sim", - "version": "5.36.0-beta-1", + "version": "5.36.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -85,7 +85,7 @@ { "groupId": "com.ctre.phoenix", "artifactId": "wpiapi-cpp", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_Phoenix_WPI", "headerClassifier": "headers", "sharedLibrary": true, @@ -98,7 +98,7 @@ { "groupId": "com.ctre.phoenix", "artifactId": "api-cpp", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_Phoenix", "headerClassifier": "headers", "sharedLibrary": true, @@ -111,7 +111,7 @@ { "groupId": "com.ctre.phoenix", "artifactId": "cci", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_PhoenixCCI", "headerClassifier": "headers", "sharedLibrary": true, @@ -124,7 +124,7 @@ { "groupId": "com.ctre.phoenix.replay", "artifactId": "wpiapi-cpp-replay", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_Phoenix_WPIReplay", "headerClassifier": "headers", "sharedLibrary": true, @@ -140,7 +140,7 @@ { "groupId": "com.ctre.phoenix.replay", "artifactId": "api-cpp-replay", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_PhoenixReplay", "headerClassifier": "headers", "sharedLibrary": true, @@ -156,7 +156,7 @@ { "groupId": "com.ctre.phoenix.replay", "artifactId": "cci-replay", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_PhoenixCCIReplay", "headerClassifier": "headers", "sharedLibrary": true, @@ -172,7 +172,7 @@ { "groupId": "com.ctre.phoenix.sim", "artifactId": "wpiapi-cpp-sim", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_Phoenix_WPISim", "headerClassifier": "headers", "sharedLibrary": true, @@ -188,7 +188,7 @@ { "groupId": "com.ctre.phoenix.sim", "artifactId": "api-cpp-sim", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_PhoenixSim", "headerClassifier": "headers", "sharedLibrary": true, @@ -204,7 +204,7 @@ { "groupId": "com.ctre.phoenix.sim", "artifactId": "cci-sim", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_PhoenixCCISim", "headerClassifier": "headers", "sharedLibrary": true, diff --git a/examples/drivebase_with_PathPlanner/vendordeps/Phoenix6-replay-26.0.0-beta-1.json b/examples/clock_drive_drivebase/vendordeps/Phoenix6-replay-26.1.0.json similarity index 83% rename from examples/drivebase_with_PathPlanner/vendordeps/Phoenix6-replay-26.0.0-beta-1.json rename to examples/clock_drive_drivebase/vendordeps/Phoenix6-replay-26.1.0.json index 5312c86..e49c760 100644 --- a/examples/drivebase_with_PathPlanner/vendordeps/Phoenix6-replay-26.0.0-beta-1.json +++ b/examples/clock_drive_drivebase/vendordeps/Phoenix6-replay-26.1.0.json @@ -1,32 +1,32 @@ { - "fileName": "Phoenix6-replay-26.0.0-beta-1.json", + "fileName": "Phoenix6-replay-26.1.0.json", "name": "CTRE-Phoenix (v6) Replay", - "version": "26.0.0-beta-1", - "frcYear": "2026beta", + "version": "26.1.0", + "frcYear": "2026", "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", "mavenUrls": [ "https://maven.ctr-electronics.com/release/" ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json", + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-latest.json", "conflictsWith": [ { "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", "errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.", - "offlineFileName": "Phoenix6-frc2026-beta-latest.json" + "offlineFileName": "Phoenix6-frc2026-latest.json" } ], "javaDependencies": [ { "groupId": "com.ctre.phoenix6", "artifactId": "wpiapi-java", - "version": "26.0.0-beta-1" + "version": "26.1.0" } ], "jniDependencies": [ { "groupId": "com.ctre.phoenix6", "artifactId": "api-cpp", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -37,7 +37,7 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "tools", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -48,7 +48,7 @@ { "groupId": "com.ctre.phoenix6.replay", "artifactId": "api-cpp-replay", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -62,7 +62,7 @@ { "groupId": "com.ctre.phoenix6.replay", "artifactId": "tools-replay", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -76,7 +76,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "api-cpp-sim", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -90,7 +90,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "tools-sim", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -104,7 +104,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simTalonSRX", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -118,7 +118,21 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simVictorSPX", - "version": "26.0.0-beta-1", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simPigeonIMU", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -132,7 +146,21 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProTalonFX", - "version": "26.0.0-beta-1", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFXS", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -146,7 +174,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANcoder", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -160,7 +188,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProPigeon2", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -174,7 +202,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANrange", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -188,7 +216,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdi", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -202,7 +230,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdle", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -218,7 +246,7 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "wpiapi-cpp", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_Phoenix6_WPI", "headerClassifier": "headers", "sharedLibrary": true, @@ -231,7 +259,7 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "tools", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_PhoenixTools", "headerClassifier": "headers", "sharedLibrary": true, @@ -244,7 +272,7 @@ { "groupId": "com.ctre.phoenix6.replay", "artifactId": "wpiapi-cpp-replay", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_Phoenix6_WPIReplay", "headerClassifier": "headers", "sharedLibrary": true, @@ -260,7 +288,7 @@ { "groupId": "com.ctre.phoenix6.replay", "artifactId": "tools-replay", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_PhoenixTools_Replay", "headerClassifier": "headers", "sharedLibrary": true, @@ -276,7 +304,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "wpiapi-cpp-sim", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_Phoenix6_WPISim", "headerClassifier": "headers", "sharedLibrary": true, @@ -292,7 +320,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "tools-sim", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_PhoenixTools_Sim", "headerClassifier": "headers", "sharedLibrary": true, @@ -308,7 +336,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simTalonSRX", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimTalonSRX", "headerClassifier": "headers", "sharedLibrary": true, @@ -324,7 +352,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simVictorSPX", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimVictorSPX", "headerClassifier": "headers", "sharedLibrary": true, @@ -340,7 +368,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simPigeonIMU", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimPigeonIMU", "headerClassifier": "headers", "sharedLibrary": true, @@ -356,7 +384,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProTalonFX", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProTalonFX", "headerClassifier": "headers", "sharedLibrary": true, @@ -369,10 +397,26 @@ ], "simMode": "swsim" }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFXS", + "version": "26.1.0", + "libName": "CTRE_SimProTalonFXS", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANcoder", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProCANcoder", "headerClassifier": "headers", "sharedLibrary": true, @@ -388,7 +432,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProPigeon2", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProPigeon2", "headerClassifier": "headers", "sharedLibrary": true, @@ -404,7 +448,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANrange", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProCANrange", "headerClassifier": "headers", "sharedLibrary": true, @@ -420,7 +464,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdi", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProCANdi", "headerClassifier": "headers", "sharedLibrary": true, @@ -436,7 +480,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdle", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProCANdle", "headerClassifier": "headers", "sharedLibrary": true, diff --git a/examples/clock_drive_drivebase/vendordeps/REVLib.json b/examples/clock_drive_drivebase/vendordeps/REVLib.json index 0f666c9..4f96af8 100644 --- a/examples/clock_drive_drivebase/vendordeps/REVLib.json +++ b/examples/clock_drive_drivebase/vendordeps/REVLib.json @@ -1,8 +1,8 @@ { "fileName": "REVLib.json", "name": "REVLib", - "version": "2026.0.0-beta-1", - "frcYear": "2026beta", + "version": "2026.0.0", + "frcYear": "2026", "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", "mavenUrls": [ "https://maven.revrobotics.com/" @@ -12,14 +12,14 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-java", - "version": "2026.0.0-beta-1" + "version": "2026.0.0" } ], "jniDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -34,7 +34,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -49,7 +49,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibWpiBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -66,7 +66,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-cpp", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "REVLib", "headerClassifier": "headers", "sharedLibrary": false, @@ -83,7 +83,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "REVLibDriver", "headerClassifier": "headers", "sharedLibrary": false, @@ -100,7 +100,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "BackendDriver", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -116,7 +116,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibWpiBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "REVLibWpi", "sharedLibrary": true, "skipInvalidPlatforms": true, diff --git a/examples/clock_drive_drivebase/vendordeps/Studica-2026.0.0-beta.json b/examples/clock_drive_drivebase/vendordeps/Studica-2026.0.0-beta.json deleted file mode 100644 index c5d48c7..0000000 --- a/examples/clock_drive_drivebase/vendordeps/Studica-2026.0.0-beta.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "Studica-2026.0.0-beta.json", - "name": "Studica", - "version": "2026.0.0-beta", - "frcYear": "2026beta", - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", - "mavenUrls": [ - "https://dev.studica.com/maven/release/2026/" - ], - "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0-beta.json", - "javaDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "Studica-java", - "version": "2026.0.0-beta" - } - ], - "jniDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "Studica-driver", - "version": "2026.0.0-beta", - "skipInvalidPlatforms": true, - "isJar": false, - "validPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ], - "cppDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "Studica-cpp", - "version": "2026.0.0-beta", - "libName": "Studica", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - }, - { - "groupId": "com.studica.frc", - "artifactId": "Studica-driver", - "version": "2026.0.0-beta", - "libName": "StudicaDriver", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ] -} \ No newline at end of file diff --git a/examples/clock_drive_drivebase/vendordeps/StudicaLib.json b/examples/clock_drive_drivebase/vendordeps/StudicaLib.json deleted file mode 100644 index b6ed33e..0000000 --- a/examples/clock_drive_drivebase/vendordeps/StudicaLib.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "StudicaLib.json", - "name": "StudicaLib", - "version": "2026.0.1-beta", - "frcYear": "2026beta", - "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", - "mavenUrls": [ - "https://dev.studica.com/maven/release/2026/" - ], - "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.1-beta.json", - "javaDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-java", - "version": "2026.0.1-beta" - } - ], - "jniDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-driver", - "version": "2026.0.1-beta", - "skipInvalidPlatforms": true, - "isJar": false, - "validPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ], - "cppDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-cpp", - "version": "2026.0.1-beta", - "libName": "StudicaLib", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - }, - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-driver", - "version": "2026.0.1-beta", - "libName": "StudicaLibDriver", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ] -} \ No newline at end of file diff --git a/examples/clock_drive_drivebase/vendordeps/ThriftyLib.json b/examples/clock_drive_drivebase/vendordeps/ThriftyLib.json deleted file mode 100644 index 1e59797..0000000 --- a/examples/clock_drive_drivebase/vendordeps/ThriftyLib.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "fileName": "ThriftyLib.json", - "name": "ThriftyLib", - "version": "2026.0.0", - "frcYear": "2026beta", - "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", - "mavenUrls": [ - "https://docs.home.thethriftybot.com" - ], - "jsonUrl": "https://docs.home.thethriftybot.com/ThriftyLib.json", - "javaDependencies": [ - { - "groupId": "com.thethriftybot.frc", - "artifactId": "ThriftyLib-java", - "version": "2026.0.0" - } - ], - "jniDependencies": [], - "cppDependencies": [] -} diff --git a/examples/clock_drive_drivebase/vendordeps/WPILibNewCommands.json b/examples/clock_drive_drivebase/vendordeps/WPILibNewCommands.json index 7ebc954..69348e4 100644 --- a/examples/clock_drive_drivebase/vendordeps/WPILibNewCommands.json +++ b/examples/clock_drive_drivebase/vendordeps/WPILibNewCommands.json @@ -1,39 +1,39 @@ { - "fileName": "WPILibNewCommands.json", - "name": "WPILib-New-Commands", - "version": "1.0.0", - "uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266", - "frcYear": "2026beta", - "mavenUrls": [], - "jsonUrl": "", - "javaDependencies": [ - { - "groupId": "edu.wpi.first.wpilibNewCommands", - "artifactId": "wpilibNewCommands-java", - "version": "wpilib" - } - ], - "jniDependencies": [], - "cppDependencies": [ - { - "groupId": "edu.wpi.first.wpilibNewCommands", - "artifactId": "wpilibNewCommands-cpp", - "version": "wpilib", - "libName": "wpilibNewCommands", - "headerClassifier": "headers", - "sourcesClassifier": "sources", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxsystemcore", - "linuxathena", - "linuxarm32", - "linuxarm64", - "windowsx86-64", - "windowsx86", - "linuxx86-64", - "osxuniversal" - ] - } - ] -} + "fileName": "WPILibNewCommands.json", + "name": "WPILib-New-Commands", + "version": "1.0.0", + "uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266", + "frcYear": "2026", + "mavenUrls": [], + "jsonUrl": "", + "javaDependencies": [ + { + "groupId": "edu.wpi.first.wpilibNewCommands", + "artifactId": "wpilibNewCommands-java", + "version": "wpilib" + } + ], + "jniDependencies": [], + "cppDependencies": [ + { + "groupId": "edu.wpi.first.wpilibNewCommands", + "artifactId": "wpilibNewCommands-cpp", + "version": "wpilib", + "libName": "wpilibNewCommands", + "headerClassifier": "headers", + "sourcesClassifier": "sources", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxsystemcore", + "linuxathena", + "linuxarm32", + "linuxarm64", + "windowsx86-64", + "windowsx86", + "linuxx86-64", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/examples/drivebase_with_PathPlanner/vendordeps/PathplannerLib-2026.1.2.json b/examples/drivebase_with_PathPlanner/vendordeps/PathplannerLib-2026.1.2.json new file mode 100644 index 0000000..f72fa41 --- /dev/null +++ b/examples/drivebase_with_PathPlanner/vendordeps/PathplannerLib-2026.1.2.json @@ -0,0 +1,38 @@ +{ + "fileName": "PathplannerLib-2026.1.2.json", + "name": "PathplannerLib", + "version": "2026.1.2", + "uuid": "1b42324f-17c6-4875-8e77-1c312bc8c786", + "frcYear": "2026", + "mavenUrls": [ + "https://3015rangerrobotics.github.io/pathplannerlib/repo" + ], + "jsonUrl": "https://3015rangerrobotics.github.io/pathplannerlib/PathplannerLib.json", + "javaDependencies": [ + { + "groupId": "com.pathplanner.lib", + "artifactId": "PathplannerLib-java", + "version": "2026.1.2" + } + ], + "jniDependencies": [], + "cppDependencies": [ + { + "groupId": "com.pathplanner.lib", + "artifactId": "PathplannerLib-cpp", + "version": "2026.1.2", + "libName": "PathplannerLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal", + "linuxathena", + "linuxarm32", + "linuxarm64" + ] + } + ] +} \ No newline at end of file diff --git a/examples/drivebase_with_PhotonVision/vendordeps/Phoenix5-replay-5.36.0-beta-1.json b/examples/drivebase_with_PathPlanner/vendordeps/Phoenix5-replay-5.36.0.json similarity index 86% rename from examples/drivebase_with_PhotonVision/vendordeps/Phoenix5-replay-5.36.0-beta-1.json rename to examples/drivebase_with_PathPlanner/vendordeps/Phoenix5-replay-5.36.0.json index 4a78551..0e799ed 100644 --- a/examples/drivebase_with_PhotonVision/vendordeps/Phoenix5-replay-5.36.0-beta-1.json +++ b/examples/drivebase_with_PathPlanner/vendordeps/Phoenix5-replay-5.36.0.json @@ -1,50 +1,50 @@ { - "fileName": "Phoenix5-replay-5.36.0-beta-1.json", + "fileName": "Phoenix5-replay-5.36.0.json", "name": "CTRE-Phoenix (v5)", - "version": "5.36.0-beta-1", - "frcYear": "2026beta", + "version": "5.36.0", + "frcYear": "2026", "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", "mavenUrls": [ "https://maven.ctr-electronics.com/release/" ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-beta-latest.json", + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-latest.json", "requires": [ { "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", - "offlineFileName": "Phoenix6-replay-frc2026-beta-latest.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json" + "offlineFileName": "Phoenix6-replay-frc2026-latest.json", + "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-latest.json" } ], "conflictsWith": [ { "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", "errorMessage": "Users must use the regular Phoenix 5 vendordep when using the regular Phoenix 6 vendordep.", - "offlineFileName": "Phoenix6-frc2026-beta-latest.json" + "offlineFileName": "Phoenix6-frc2026-latest.json" }, { "uuid": "ab676553-b602-441f-a38d-f1296eff6537", "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", - "offlineFileName": "Phoenix5-frc2026-beta-latest.json" + "offlineFileName": "Phoenix5-frc2026-latest.json" } ], "javaDependencies": [ { "groupId": "com.ctre.phoenix", "artifactId": "api-java", - "version": "5.36.0-beta-1" + "version": "5.36.0" }, { "groupId": "com.ctre.phoenix", "artifactId": "wpiapi-java", - "version": "5.36.0-beta-1" + "version": "5.36.0" } ], "jniDependencies": [ { "groupId": "com.ctre.phoenix", "artifactId": "cci", - "version": "5.36.0-beta-1", + "version": "5.36.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -55,7 +55,7 @@ { "groupId": "com.ctre.phoenix.replay", "artifactId": "cci-replay", - "version": "5.36.0-beta-1", + "version": "5.36.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -69,7 +69,7 @@ { "groupId": "com.ctre.phoenix.sim", "artifactId": "cci-sim", - "version": "5.36.0-beta-1", + "version": "5.36.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -85,7 +85,7 @@ { "groupId": "com.ctre.phoenix", "artifactId": "wpiapi-cpp", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_Phoenix_WPI", "headerClassifier": "headers", "sharedLibrary": true, @@ -98,7 +98,7 @@ { "groupId": "com.ctre.phoenix", "artifactId": "api-cpp", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_Phoenix", "headerClassifier": "headers", "sharedLibrary": true, @@ -111,7 +111,7 @@ { "groupId": "com.ctre.phoenix", "artifactId": "cci", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_PhoenixCCI", "headerClassifier": "headers", "sharedLibrary": true, @@ -124,7 +124,7 @@ { "groupId": "com.ctre.phoenix.replay", "artifactId": "wpiapi-cpp-replay", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_Phoenix_WPIReplay", "headerClassifier": "headers", "sharedLibrary": true, @@ -140,7 +140,7 @@ { "groupId": "com.ctre.phoenix.replay", "artifactId": "api-cpp-replay", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_PhoenixReplay", "headerClassifier": "headers", "sharedLibrary": true, @@ -156,7 +156,7 @@ { "groupId": "com.ctre.phoenix.replay", "artifactId": "cci-replay", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_PhoenixCCIReplay", "headerClassifier": "headers", "sharedLibrary": true, @@ -172,7 +172,7 @@ { "groupId": "com.ctre.phoenix.sim", "artifactId": "wpiapi-cpp-sim", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_Phoenix_WPISim", "headerClassifier": "headers", "sharedLibrary": true, @@ -188,7 +188,7 @@ { "groupId": "com.ctre.phoenix.sim", "artifactId": "api-cpp-sim", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_PhoenixSim", "headerClassifier": "headers", "sharedLibrary": true, @@ -204,7 +204,7 @@ { "groupId": "com.ctre.phoenix.sim", "artifactId": "cci-sim", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_PhoenixCCISim", "headerClassifier": "headers", "sharedLibrary": true, diff --git a/examples/clock_drive_drivebase/vendordeps/Phoenix6-replay-26.0.0-beta-1.json b/examples/drivebase_with_PathPlanner/vendordeps/Phoenix6-replay-26.1.0.json similarity index 83% rename from examples/clock_drive_drivebase/vendordeps/Phoenix6-replay-26.0.0-beta-1.json rename to examples/drivebase_with_PathPlanner/vendordeps/Phoenix6-replay-26.1.0.json index 5312c86..e49c760 100644 --- a/examples/clock_drive_drivebase/vendordeps/Phoenix6-replay-26.0.0-beta-1.json +++ b/examples/drivebase_with_PathPlanner/vendordeps/Phoenix6-replay-26.1.0.json @@ -1,32 +1,32 @@ { - "fileName": "Phoenix6-replay-26.0.0-beta-1.json", + "fileName": "Phoenix6-replay-26.1.0.json", "name": "CTRE-Phoenix (v6) Replay", - "version": "26.0.0-beta-1", - "frcYear": "2026beta", + "version": "26.1.0", + "frcYear": "2026", "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", "mavenUrls": [ "https://maven.ctr-electronics.com/release/" ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json", + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-latest.json", "conflictsWith": [ { "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", "errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.", - "offlineFileName": "Phoenix6-frc2026-beta-latest.json" + "offlineFileName": "Phoenix6-frc2026-latest.json" } ], "javaDependencies": [ { "groupId": "com.ctre.phoenix6", "artifactId": "wpiapi-java", - "version": "26.0.0-beta-1" + "version": "26.1.0" } ], "jniDependencies": [ { "groupId": "com.ctre.phoenix6", "artifactId": "api-cpp", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -37,7 +37,7 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "tools", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -48,7 +48,7 @@ { "groupId": "com.ctre.phoenix6.replay", "artifactId": "api-cpp-replay", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -62,7 +62,7 @@ { "groupId": "com.ctre.phoenix6.replay", "artifactId": "tools-replay", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -76,7 +76,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "api-cpp-sim", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -90,7 +90,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "tools-sim", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -104,7 +104,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simTalonSRX", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -118,7 +118,21 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simVictorSPX", - "version": "26.0.0-beta-1", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simPigeonIMU", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -132,7 +146,21 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProTalonFX", - "version": "26.0.0-beta-1", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFXS", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -146,7 +174,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANcoder", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -160,7 +188,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProPigeon2", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -174,7 +202,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANrange", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -188,7 +216,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdi", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -202,7 +230,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdle", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -218,7 +246,7 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "wpiapi-cpp", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_Phoenix6_WPI", "headerClassifier": "headers", "sharedLibrary": true, @@ -231,7 +259,7 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "tools", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_PhoenixTools", "headerClassifier": "headers", "sharedLibrary": true, @@ -244,7 +272,7 @@ { "groupId": "com.ctre.phoenix6.replay", "artifactId": "wpiapi-cpp-replay", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_Phoenix6_WPIReplay", "headerClassifier": "headers", "sharedLibrary": true, @@ -260,7 +288,7 @@ { "groupId": "com.ctre.phoenix6.replay", "artifactId": "tools-replay", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_PhoenixTools_Replay", "headerClassifier": "headers", "sharedLibrary": true, @@ -276,7 +304,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "wpiapi-cpp-sim", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_Phoenix6_WPISim", "headerClassifier": "headers", "sharedLibrary": true, @@ -292,7 +320,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "tools-sim", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_PhoenixTools_Sim", "headerClassifier": "headers", "sharedLibrary": true, @@ -308,7 +336,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simTalonSRX", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimTalonSRX", "headerClassifier": "headers", "sharedLibrary": true, @@ -324,7 +352,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simVictorSPX", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimVictorSPX", "headerClassifier": "headers", "sharedLibrary": true, @@ -340,7 +368,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simPigeonIMU", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimPigeonIMU", "headerClassifier": "headers", "sharedLibrary": true, @@ -356,7 +384,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProTalonFX", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProTalonFX", "headerClassifier": "headers", "sharedLibrary": true, @@ -369,10 +397,26 @@ ], "simMode": "swsim" }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFXS", + "version": "26.1.0", + "libName": "CTRE_SimProTalonFXS", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANcoder", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProCANcoder", "headerClassifier": "headers", "sharedLibrary": true, @@ -388,7 +432,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProPigeon2", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProPigeon2", "headerClassifier": "headers", "sharedLibrary": true, @@ -404,7 +448,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANrange", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProCANrange", "headerClassifier": "headers", "sharedLibrary": true, @@ -420,7 +464,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdi", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProCANdi", "headerClassifier": "headers", "sharedLibrary": true, @@ -436,7 +480,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdle", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProCANdle", "headerClassifier": "headers", "sharedLibrary": true, diff --git a/examples/drivebase_with_PathPlanner/vendordeps/REVLib.json b/examples/drivebase_with_PathPlanner/vendordeps/REVLib.json index 0f666c9..4f96af8 100644 --- a/examples/drivebase_with_PathPlanner/vendordeps/REVLib.json +++ b/examples/drivebase_with_PathPlanner/vendordeps/REVLib.json @@ -1,8 +1,8 @@ { "fileName": "REVLib.json", "name": "REVLib", - "version": "2026.0.0-beta-1", - "frcYear": "2026beta", + "version": "2026.0.0", + "frcYear": "2026", "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", "mavenUrls": [ "https://maven.revrobotics.com/" @@ -12,14 +12,14 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-java", - "version": "2026.0.0-beta-1" + "version": "2026.0.0" } ], "jniDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -34,7 +34,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -49,7 +49,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibWpiBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -66,7 +66,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-cpp", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "REVLib", "headerClassifier": "headers", "sharedLibrary": false, @@ -83,7 +83,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "REVLibDriver", "headerClassifier": "headers", "sharedLibrary": false, @@ -100,7 +100,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "BackendDriver", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -116,7 +116,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibWpiBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "REVLibWpi", "sharedLibrary": true, "skipInvalidPlatforms": true, diff --git a/examples/drivebase_with_PathPlanner/vendordeps/Studica-2026.0.0-beta.json b/examples/drivebase_with_PathPlanner/vendordeps/Studica-2026.0.0-beta.json deleted file mode 100644 index c5d48c7..0000000 --- a/examples/drivebase_with_PathPlanner/vendordeps/Studica-2026.0.0-beta.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "Studica-2026.0.0-beta.json", - "name": "Studica", - "version": "2026.0.0-beta", - "frcYear": "2026beta", - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", - "mavenUrls": [ - "https://dev.studica.com/maven/release/2026/" - ], - "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0-beta.json", - "javaDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "Studica-java", - "version": "2026.0.0-beta" - } - ], - "jniDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "Studica-driver", - "version": "2026.0.0-beta", - "skipInvalidPlatforms": true, - "isJar": false, - "validPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ], - "cppDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "Studica-cpp", - "version": "2026.0.0-beta", - "libName": "Studica", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - }, - { - "groupId": "com.studica.frc", - "artifactId": "Studica-driver", - "version": "2026.0.0-beta", - "libName": "StudicaDriver", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ] -} \ No newline at end of file diff --git a/examples/drivebase_with_PathPlanner/vendordeps/StudicaLib.json b/examples/drivebase_with_PathPlanner/vendordeps/StudicaLib.json deleted file mode 100644 index b6ed33e..0000000 --- a/examples/drivebase_with_PathPlanner/vendordeps/StudicaLib.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "StudicaLib.json", - "name": "StudicaLib", - "version": "2026.0.1-beta", - "frcYear": "2026beta", - "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", - "mavenUrls": [ - "https://dev.studica.com/maven/release/2026/" - ], - "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.1-beta.json", - "javaDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-java", - "version": "2026.0.1-beta" - } - ], - "jniDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-driver", - "version": "2026.0.1-beta", - "skipInvalidPlatforms": true, - "isJar": false, - "validPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ], - "cppDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-cpp", - "version": "2026.0.1-beta", - "libName": "StudicaLib", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - }, - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-driver", - "version": "2026.0.1-beta", - "libName": "StudicaLibDriver", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ] -} \ No newline at end of file diff --git a/examples/drivebase_with_PathPlanner/vendordeps/ThriftyLib.json b/examples/drivebase_with_PathPlanner/vendordeps/ThriftyLib.json deleted file mode 100644 index 1e59797..0000000 --- a/examples/drivebase_with_PathPlanner/vendordeps/ThriftyLib.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "fileName": "ThriftyLib.json", - "name": "ThriftyLib", - "version": "2026.0.0", - "frcYear": "2026beta", - "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", - "mavenUrls": [ - "https://docs.home.thethriftybot.com" - ], - "jsonUrl": "https://docs.home.thethriftybot.com/ThriftyLib.json", - "javaDependencies": [ - { - "groupId": "com.thethriftybot.frc", - "artifactId": "ThriftyLib-java", - "version": "2026.0.0" - } - ], - "jniDependencies": [], - "cppDependencies": [] -} diff --git a/examples/drivebase_with_PathPlanner/vendordeps/WPILibNewCommands.json b/examples/drivebase_with_PathPlanner/vendordeps/WPILibNewCommands.json index 7ebc954..69348e4 100644 --- a/examples/drivebase_with_PathPlanner/vendordeps/WPILibNewCommands.json +++ b/examples/drivebase_with_PathPlanner/vendordeps/WPILibNewCommands.json @@ -1,39 +1,39 @@ { - "fileName": "WPILibNewCommands.json", - "name": "WPILib-New-Commands", - "version": "1.0.0", - "uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266", - "frcYear": "2026beta", - "mavenUrls": [], - "jsonUrl": "", - "javaDependencies": [ - { - "groupId": "edu.wpi.first.wpilibNewCommands", - "artifactId": "wpilibNewCommands-java", - "version": "wpilib" - } - ], - "jniDependencies": [], - "cppDependencies": [ - { - "groupId": "edu.wpi.first.wpilibNewCommands", - "artifactId": "wpilibNewCommands-cpp", - "version": "wpilib", - "libName": "wpilibNewCommands", - "headerClassifier": "headers", - "sourcesClassifier": "sources", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxsystemcore", - "linuxathena", - "linuxarm32", - "linuxarm64", - "windowsx86-64", - "windowsx86", - "linuxx86-64", - "osxuniversal" - ] - } - ] -} + "fileName": "WPILibNewCommands.json", + "name": "WPILib-New-Commands", + "version": "1.0.0", + "uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266", + "frcYear": "2026", + "mavenUrls": [], + "jsonUrl": "", + "javaDependencies": [ + { + "groupId": "edu.wpi.first.wpilibNewCommands", + "artifactId": "wpilibNewCommands-java", + "version": "wpilib" + } + ], + "jniDependencies": [], + "cppDependencies": [ + { + "groupId": "edu.wpi.first.wpilibNewCommands", + "artifactId": "wpilibNewCommands-cpp", + "version": "wpilib", + "libName": "wpilibNewCommands", + "headerClassifier": "headers", + "sourcesClassifier": "sources", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxsystemcore", + "linuxathena", + "linuxarm32", + "linuxarm64", + "windowsx86-64", + "windowsx86", + "linuxx86-64", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/examples/drivebase_with_PhotonVision/vendordeps/PathplannerLib-2026.1.2.json b/examples/drivebase_with_PhotonVision/vendordeps/PathplannerLib-2026.1.2.json new file mode 100644 index 0000000..f72fa41 --- /dev/null +++ b/examples/drivebase_with_PhotonVision/vendordeps/PathplannerLib-2026.1.2.json @@ -0,0 +1,38 @@ +{ + "fileName": "PathplannerLib-2026.1.2.json", + "name": "PathplannerLib", + "version": "2026.1.2", + "uuid": "1b42324f-17c6-4875-8e77-1c312bc8c786", + "frcYear": "2026", + "mavenUrls": [ + "https://3015rangerrobotics.github.io/pathplannerlib/repo" + ], + "jsonUrl": "https://3015rangerrobotics.github.io/pathplannerlib/PathplannerLib.json", + "javaDependencies": [ + { + "groupId": "com.pathplanner.lib", + "artifactId": "PathplannerLib-java", + "version": "2026.1.2" + } + ], + "jniDependencies": [], + "cppDependencies": [ + { + "groupId": "com.pathplanner.lib", + "artifactId": "PathplannerLib-cpp", + "version": "2026.1.2", + "libName": "PathplannerLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal", + "linuxathena", + "linuxarm32", + "linuxarm64" + ] + } + ] +} \ No newline at end of file diff --git a/examples/drivebase_with_PathPlanner/vendordeps/Phoenix5-replay-5.36.0-beta-1.json b/examples/drivebase_with_PhotonVision/vendordeps/Phoenix5-replay-5.36.0.json similarity index 86% rename from examples/drivebase_with_PathPlanner/vendordeps/Phoenix5-replay-5.36.0-beta-1.json rename to examples/drivebase_with_PhotonVision/vendordeps/Phoenix5-replay-5.36.0.json index 4a78551..0e799ed 100644 --- a/examples/drivebase_with_PathPlanner/vendordeps/Phoenix5-replay-5.36.0-beta-1.json +++ b/examples/drivebase_with_PhotonVision/vendordeps/Phoenix5-replay-5.36.0.json @@ -1,50 +1,50 @@ { - "fileName": "Phoenix5-replay-5.36.0-beta-1.json", + "fileName": "Phoenix5-replay-5.36.0.json", "name": "CTRE-Phoenix (v5)", - "version": "5.36.0-beta-1", - "frcYear": "2026beta", + "version": "5.36.0", + "frcYear": "2026", "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", "mavenUrls": [ "https://maven.ctr-electronics.com/release/" ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-beta-latest.json", + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-latest.json", "requires": [ { "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", - "offlineFileName": "Phoenix6-replay-frc2026-beta-latest.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json" + "offlineFileName": "Phoenix6-replay-frc2026-latest.json", + "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-latest.json" } ], "conflictsWith": [ { "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", "errorMessage": "Users must use the regular Phoenix 5 vendordep when using the regular Phoenix 6 vendordep.", - "offlineFileName": "Phoenix6-frc2026-beta-latest.json" + "offlineFileName": "Phoenix6-frc2026-latest.json" }, { "uuid": "ab676553-b602-441f-a38d-f1296eff6537", "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", - "offlineFileName": "Phoenix5-frc2026-beta-latest.json" + "offlineFileName": "Phoenix5-frc2026-latest.json" } ], "javaDependencies": [ { "groupId": "com.ctre.phoenix", "artifactId": "api-java", - "version": "5.36.0-beta-1" + "version": "5.36.0" }, { "groupId": "com.ctre.phoenix", "artifactId": "wpiapi-java", - "version": "5.36.0-beta-1" + "version": "5.36.0" } ], "jniDependencies": [ { "groupId": "com.ctre.phoenix", "artifactId": "cci", - "version": "5.36.0-beta-1", + "version": "5.36.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -55,7 +55,7 @@ { "groupId": "com.ctre.phoenix.replay", "artifactId": "cci-replay", - "version": "5.36.0-beta-1", + "version": "5.36.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -69,7 +69,7 @@ { "groupId": "com.ctre.phoenix.sim", "artifactId": "cci-sim", - "version": "5.36.0-beta-1", + "version": "5.36.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -85,7 +85,7 @@ { "groupId": "com.ctre.phoenix", "artifactId": "wpiapi-cpp", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_Phoenix_WPI", "headerClassifier": "headers", "sharedLibrary": true, @@ -98,7 +98,7 @@ { "groupId": "com.ctre.phoenix", "artifactId": "api-cpp", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_Phoenix", "headerClassifier": "headers", "sharedLibrary": true, @@ -111,7 +111,7 @@ { "groupId": "com.ctre.phoenix", "artifactId": "cci", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_PhoenixCCI", "headerClassifier": "headers", "sharedLibrary": true, @@ -124,7 +124,7 @@ { "groupId": "com.ctre.phoenix.replay", "artifactId": "wpiapi-cpp-replay", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_Phoenix_WPIReplay", "headerClassifier": "headers", "sharedLibrary": true, @@ -140,7 +140,7 @@ { "groupId": "com.ctre.phoenix.replay", "artifactId": "api-cpp-replay", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_PhoenixReplay", "headerClassifier": "headers", "sharedLibrary": true, @@ -156,7 +156,7 @@ { "groupId": "com.ctre.phoenix.replay", "artifactId": "cci-replay", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_PhoenixCCIReplay", "headerClassifier": "headers", "sharedLibrary": true, @@ -172,7 +172,7 @@ { "groupId": "com.ctre.phoenix.sim", "artifactId": "wpiapi-cpp-sim", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_Phoenix_WPISim", "headerClassifier": "headers", "sharedLibrary": true, @@ -188,7 +188,7 @@ { "groupId": "com.ctre.phoenix.sim", "artifactId": "api-cpp-sim", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_PhoenixSim", "headerClassifier": "headers", "sharedLibrary": true, @@ -204,7 +204,7 @@ { "groupId": "com.ctre.phoenix.sim", "artifactId": "cci-sim", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_PhoenixCCISim", "headerClassifier": "headers", "sharedLibrary": true, diff --git a/examples/drivebase_with_PhotonVision/vendordeps/Phoenix6-replay-26.0.0-beta-1.json b/examples/drivebase_with_PhotonVision/vendordeps/Phoenix6-replay-26.1.0.json similarity index 83% rename from examples/drivebase_with_PhotonVision/vendordeps/Phoenix6-replay-26.0.0-beta-1.json rename to examples/drivebase_with_PhotonVision/vendordeps/Phoenix6-replay-26.1.0.json index 5312c86..e49c760 100644 --- a/examples/drivebase_with_PhotonVision/vendordeps/Phoenix6-replay-26.0.0-beta-1.json +++ b/examples/drivebase_with_PhotonVision/vendordeps/Phoenix6-replay-26.1.0.json @@ -1,32 +1,32 @@ { - "fileName": "Phoenix6-replay-26.0.0-beta-1.json", + "fileName": "Phoenix6-replay-26.1.0.json", "name": "CTRE-Phoenix (v6) Replay", - "version": "26.0.0-beta-1", - "frcYear": "2026beta", + "version": "26.1.0", + "frcYear": "2026", "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", "mavenUrls": [ "https://maven.ctr-electronics.com/release/" ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json", + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-latest.json", "conflictsWith": [ { "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", "errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.", - "offlineFileName": "Phoenix6-frc2026-beta-latest.json" + "offlineFileName": "Phoenix6-frc2026-latest.json" } ], "javaDependencies": [ { "groupId": "com.ctre.phoenix6", "artifactId": "wpiapi-java", - "version": "26.0.0-beta-1" + "version": "26.1.0" } ], "jniDependencies": [ { "groupId": "com.ctre.phoenix6", "artifactId": "api-cpp", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -37,7 +37,7 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "tools", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -48,7 +48,7 @@ { "groupId": "com.ctre.phoenix6.replay", "artifactId": "api-cpp-replay", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -62,7 +62,7 @@ { "groupId": "com.ctre.phoenix6.replay", "artifactId": "tools-replay", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -76,7 +76,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "api-cpp-sim", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -90,7 +90,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "tools-sim", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -104,7 +104,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simTalonSRX", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -118,7 +118,21 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simVictorSPX", - "version": "26.0.0-beta-1", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simPigeonIMU", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -132,7 +146,21 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProTalonFX", - "version": "26.0.0-beta-1", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFXS", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -146,7 +174,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANcoder", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -160,7 +188,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProPigeon2", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -174,7 +202,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANrange", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -188,7 +216,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdi", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -202,7 +230,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdle", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -218,7 +246,7 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "wpiapi-cpp", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_Phoenix6_WPI", "headerClassifier": "headers", "sharedLibrary": true, @@ -231,7 +259,7 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "tools", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_PhoenixTools", "headerClassifier": "headers", "sharedLibrary": true, @@ -244,7 +272,7 @@ { "groupId": "com.ctre.phoenix6.replay", "artifactId": "wpiapi-cpp-replay", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_Phoenix6_WPIReplay", "headerClassifier": "headers", "sharedLibrary": true, @@ -260,7 +288,7 @@ { "groupId": "com.ctre.phoenix6.replay", "artifactId": "tools-replay", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_PhoenixTools_Replay", "headerClassifier": "headers", "sharedLibrary": true, @@ -276,7 +304,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "wpiapi-cpp-sim", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_Phoenix6_WPISim", "headerClassifier": "headers", "sharedLibrary": true, @@ -292,7 +320,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "tools-sim", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_PhoenixTools_Sim", "headerClassifier": "headers", "sharedLibrary": true, @@ -308,7 +336,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simTalonSRX", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimTalonSRX", "headerClassifier": "headers", "sharedLibrary": true, @@ -324,7 +352,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simVictorSPX", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimVictorSPX", "headerClassifier": "headers", "sharedLibrary": true, @@ -340,7 +368,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simPigeonIMU", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimPigeonIMU", "headerClassifier": "headers", "sharedLibrary": true, @@ -356,7 +384,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProTalonFX", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProTalonFX", "headerClassifier": "headers", "sharedLibrary": true, @@ -369,10 +397,26 @@ ], "simMode": "swsim" }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFXS", + "version": "26.1.0", + "libName": "CTRE_SimProTalonFXS", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANcoder", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProCANcoder", "headerClassifier": "headers", "sharedLibrary": true, @@ -388,7 +432,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProPigeon2", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProPigeon2", "headerClassifier": "headers", "sharedLibrary": true, @@ -404,7 +448,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANrange", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProCANrange", "headerClassifier": "headers", "sharedLibrary": true, @@ -420,7 +464,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdi", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProCANdi", "headerClassifier": "headers", "sharedLibrary": true, @@ -436,7 +480,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdle", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProCANdle", "headerClassifier": "headers", "sharedLibrary": true, diff --git a/examples/drivebase_with_PhotonVision/vendordeps/REVLib.json b/examples/drivebase_with_PhotonVision/vendordeps/REVLib.json index 0f666c9..4f96af8 100644 --- a/examples/drivebase_with_PhotonVision/vendordeps/REVLib.json +++ b/examples/drivebase_with_PhotonVision/vendordeps/REVLib.json @@ -1,8 +1,8 @@ { "fileName": "REVLib.json", "name": "REVLib", - "version": "2026.0.0-beta-1", - "frcYear": "2026beta", + "version": "2026.0.0", + "frcYear": "2026", "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", "mavenUrls": [ "https://maven.revrobotics.com/" @@ -12,14 +12,14 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-java", - "version": "2026.0.0-beta-1" + "version": "2026.0.0" } ], "jniDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -34,7 +34,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -49,7 +49,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibWpiBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -66,7 +66,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-cpp", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "REVLib", "headerClassifier": "headers", "sharedLibrary": false, @@ -83,7 +83,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "REVLibDriver", "headerClassifier": "headers", "sharedLibrary": false, @@ -100,7 +100,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "BackendDriver", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -116,7 +116,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibWpiBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "REVLibWpi", "sharedLibrary": true, "skipInvalidPlatforms": true, diff --git a/examples/drivebase_with_PhotonVision/vendordeps/Studica-2026.0.0-beta.json b/examples/drivebase_with_PhotonVision/vendordeps/Studica-2026.0.0-beta.json deleted file mode 100644 index c5d48c7..0000000 --- a/examples/drivebase_with_PhotonVision/vendordeps/Studica-2026.0.0-beta.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "Studica-2026.0.0-beta.json", - "name": "Studica", - "version": "2026.0.0-beta", - "frcYear": "2026beta", - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", - "mavenUrls": [ - "https://dev.studica.com/maven/release/2026/" - ], - "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0-beta.json", - "javaDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "Studica-java", - "version": "2026.0.0-beta" - } - ], - "jniDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "Studica-driver", - "version": "2026.0.0-beta", - "skipInvalidPlatforms": true, - "isJar": false, - "validPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ], - "cppDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "Studica-cpp", - "version": "2026.0.0-beta", - "libName": "Studica", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - }, - { - "groupId": "com.studica.frc", - "artifactId": "Studica-driver", - "version": "2026.0.0-beta", - "libName": "StudicaDriver", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ] -} \ No newline at end of file diff --git a/examples/drivebase_with_PhotonVision/vendordeps/StudicaLib.json b/examples/drivebase_with_PhotonVision/vendordeps/StudicaLib.json deleted file mode 100644 index b6ed33e..0000000 --- a/examples/drivebase_with_PhotonVision/vendordeps/StudicaLib.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "StudicaLib.json", - "name": "StudicaLib", - "version": "2026.0.1-beta", - "frcYear": "2026beta", - "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", - "mavenUrls": [ - "https://dev.studica.com/maven/release/2026/" - ], - "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.1-beta.json", - "javaDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-java", - "version": "2026.0.1-beta" - } - ], - "jniDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-driver", - "version": "2026.0.1-beta", - "skipInvalidPlatforms": true, - "isJar": false, - "validPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ], - "cppDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-cpp", - "version": "2026.0.1-beta", - "libName": "StudicaLib", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - }, - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-driver", - "version": "2026.0.1-beta", - "libName": "StudicaLibDriver", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ] -} \ No newline at end of file diff --git a/examples/drivebase_with_PhotonVision/vendordeps/ThriftyLib.json b/examples/drivebase_with_PhotonVision/vendordeps/ThriftyLib.json deleted file mode 100644 index 1e59797..0000000 --- a/examples/drivebase_with_PhotonVision/vendordeps/ThriftyLib.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "fileName": "ThriftyLib.json", - "name": "ThriftyLib", - "version": "2026.0.0", - "frcYear": "2026beta", - "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", - "mavenUrls": [ - "https://docs.home.thethriftybot.com" - ], - "jsonUrl": "https://docs.home.thethriftybot.com/ThriftyLib.json", - "javaDependencies": [ - { - "groupId": "com.thethriftybot.frc", - "artifactId": "ThriftyLib-java", - "version": "2026.0.0" - } - ], - "jniDependencies": [], - "cppDependencies": [] -} diff --git a/examples/drivebase_with_PhotonVision/vendordeps/WPILibNewCommands.json b/examples/drivebase_with_PhotonVision/vendordeps/WPILibNewCommands.json index 7ebc954..69348e4 100644 --- a/examples/drivebase_with_PhotonVision/vendordeps/WPILibNewCommands.json +++ b/examples/drivebase_with_PhotonVision/vendordeps/WPILibNewCommands.json @@ -1,39 +1,39 @@ { - "fileName": "WPILibNewCommands.json", - "name": "WPILib-New-Commands", - "version": "1.0.0", - "uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266", - "frcYear": "2026beta", - "mavenUrls": [], - "jsonUrl": "", - "javaDependencies": [ - { - "groupId": "edu.wpi.first.wpilibNewCommands", - "artifactId": "wpilibNewCommands-java", - "version": "wpilib" - } - ], - "jniDependencies": [], - "cppDependencies": [ - { - "groupId": "edu.wpi.first.wpilibNewCommands", - "artifactId": "wpilibNewCommands-cpp", - "version": "wpilib", - "libName": "wpilibNewCommands", - "headerClassifier": "headers", - "sourcesClassifier": "sources", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxsystemcore", - "linuxathena", - "linuxarm32", - "linuxarm64", - "windowsx86-64", - "windowsx86", - "linuxx86-64", - "osxuniversal" - ] - } - ] -} + "fileName": "WPILibNewCommands.json", + "name": "WPILib-New-Commands", + "version": "1.0.0", + "uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266", + "frcYear": "2026", + "mavenUrls": [], + "jsonUrl": "", + "javaDependencies": [ + { + "groupId": "edu.wpi.first.wpilibNewCommands", + "artifactId": "wpilibNewCommands-java", + "version": "wpilib" + } + ], + "jniDependencies": [], + "cppDependencies": [ + { + "groupId": "edu.wpi.first.wpilibNewCommands", + "artifactId": "wpilibNewCommands-cpp", + "version": "wpilib", + "libName": "wpilibNewCommands", + "headerClassifier": "headers", + "sourcesClassifier": "sources", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxsystemcore", + "linuxathena", + "linuxarm32", + "linuxarm64", + "windowsx86-64", + "windowsx86", + "linuxx86-64", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/examples/field_oriented_drivebase/build.gradle b/examples/field_oriented_drivebase/build.gradle index 4233229..faa789c 100644 --- a/examples/field_oriented_drivebase/build.gradle +++ b/examples/field_oriented_drivebase/build.gradle @@ -1,6 +1,6 @@ plugins { id "java" - id "edu.wpi.first.GradleRIO" version "2026.1.1-beta-1" + id "edu.wpi.first.GradleRIO" version "2026.1.1" } java { diff --git a/examples/full_example/vendordeps/PathplannerLib-2026.1.2.json b/examples/full_example/vendordeps/PathplannerLib-2026.1.2.json new file mode 100644 index 0000000..f72fa41 --- /dev/null +++ b/examples/full_example/vendordeps/PathplannerLib-2026.1.2.json @@ -0,0 +1,38 @@ +{ + "fileName": "PathplannerLib-2026.1.2.json", + "name": "PathplannerLib", + "version": "2026.1.2", + "uuid": "1b42324f-17c6-4875-8e77-1c312bc8c786", + "frcYear": "2026", + "mavenUrls": [ + "https://3015rangerrobotics.github.io/pathplannerlib/repo" + ], + "jsonUrl": "https://3015rangerrobotics.github.io/pathplannerlib/PathplannerLib.json", + "javaDependencies": [ + { + "groupId": "com.pathplanner.lib", + "artifactId": "PathplannerLib-java", + "version": "2026.1.2" + } + ], + "jniDependencies": [], + "cppDependencies": [ + { + "groupId": "com.pathplanner.lib", + "artifactId": "PathplannerLib-cpp", + "version": "2026.1.2", + "libName": "PathplannerLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal", + "linuxathena", + "linuxarm32", + "linuxarm64" + ] + } + ] +} \ No newline at end of file diff --git a/examples/full_example/vendordeps/Phoenix5-replay-5.36.0-beta-1.json b/examples/full_example/vendordeps/Phoenix5-replay-5.36.0.json similarity index 86% rename from examples/full_example/vendordeps/Phoenix5-replay-5.36.0-beta-1.json rename to examples/full_example/vendordeps/Phoenix5-replay-5.36.0.json index 4a78551..0e799ed 100644 --- a/examples/full_example/vendordeps/Phoenix5-replay-5.36.0-beta-1.json +++ b/examples/full_example/vendordeps/Phoenix5-replay-5.36.0.json @@ -1,50 +1,50 @@ { - "fileName": "Phoenix5-replay-5.36.0-beta-1.json", + "fileName": "Phoenix5-replay-5.36.0.json", "name": "CTRE-Phoenix (v5)", - "version": "5.36.0-beta-1", - "frcYear": "2026beta", + "version": "5.36.0", + "frcYear": "2026", "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", "mavenUrls": [ "https://maven.ctr-electronics.com/release/" ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-beta-latest.json", + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-latest.json", "requires": [ { "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", - "offlineFileName": "Phoenix6-replay-frc2026-beta-latest.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json" + "offlineFileName": "Phoenix6-replay-frc2026-latest.json", + "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-latest.json" } ], "conflictsWith": [ { "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", "errorMessage": "Users must use the regular Phoenix 5 vendordep when using the regular Phoenix 6 vendordep.", - "offlineFileName": "Phoenix6-frc2026-beta-latest.json" + "offlineFileName": "Phoenix6-frc2026-latest.json" }, { "uuid": "ab676553-b602-441f-a38d-f1296eff6537", "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", - "offlineFileName": "Phoenix5-frc2026-beta-latest.json" + "offlineFileName": "Phoenix5-frc2026-latest.json" } ], "javaDependencies": [ { "groupId": "com.ctre.phoenix", "artifactId": "api-java", - "version": "5.36.0-beta-1" + "version": "5.36.0" }, { "groupId": "com.ctre.phoenix", "artifactId": "wpiapi-java", - "version": "5.36.0-beta-1" + "version": "5.36.0" } ], "jniDependencies": [ { "groupId": "com.ctre.phoenix", "artifactId": "cci", - "version": "5.36.0-beta-1", + "version": "5.36.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -55,7 +55,7 @@ { "groupId": "com.ctre.phoenix.replay", "artifactId": "cci-replay", - "version": "5.36.0-beta-1", + "version": "5.36.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -69,7 +69,7 @@ { "groupId": "com.ctre.phoenix.sim", "artifactId": "cci-sim", - "version": "5.36.0-beta-1", + "version": "5.36.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -85,7 +85,7 @@ { "groupId": "com.ctre.phoenix", "artifactId": "wpiapi-cpp", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_Phoenix_WPI", "headerClassifier": "headers", "sharedLibrary": true, @@ -98,7 +98,7 @@ { "groupId": "com.ctre.phoenix", "artifactId": "api-cpp", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_Phoenix", "headerClassifier": "headers", "sharedLibrary": true, @@ -111,7 +111,7 @@ { "groupId": "com.ctre.phoenix", "artifactId": "cci", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_PhoenixCCI", "headerClassifier": "headers", "sharedLibrary": true, @@ -124,7 +124,7 @@ { "groupId": "com.ctre.phoenix.replay", "artifactId": "wpiapi-cpp-replay", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_Phoenix_WPIReplay", "headerClassifier": "headers", "sharedLibrary": true, @@ -140,7 +140,7 @@ { "groupId": "com.ctre.phoenix.replay", "artifactId": "api-cpp-replay", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_PhoenixReplay", "headerClassifier": "headers", "sharedLibrary": true, @@ -156,7 +156,7 @@ { "groupId": "com.ctre.phoenix.replay", "artifactId": "cci-replay", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_PhoenixCCIReplay", "headerClassifier": "headers", "sharedLibrary": true, @@ -172,7 +172,7 @@ { "groupId": "com.ctre.phoenix.sim", "artifactId": "wpiapi-cpp-sim", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_Phoenix_WPISim", "headerClassifier": "headers", "sharedLibrary": true, @@ -188,7 +188,7 @@ { "groupId": "com.ctre.phoenix.sim", "artifactId": "api-cpp-sim", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_PhoenixSim", "headerClassifier": "headers", "sharedLibrary": true, @@ -204,7 +204,7 @@ { "groupId": "com.ctre.phoenix.sim", "artifactId": "cci-sim", - "version": "5.36.0-beta-1", + "version": "5.36.0", "libName": "CTRE_PhoenixCCISim", "headerClassifier": "headers", "sharedLibrary": true, diff --git a/examples/full_example/vendordeps/Phoenix6-replay-26.0.0-beta-1.json b/examples/full_example/vendordeps/Phoenix6-replay-26.1.0.json similarity index 83% rename from examples/full_example/vendordeps/Phoenix6-replay-26.0.0-beta-1.json rename to examples/full_example/vendordeps/Phoenix6-replay-26.1.0.json index 5312c86..e49c760 100644 --- a/examples/full_example/vendordeps/Phoenix6-replay-26.0.0-beta-1.json +++ b/examples/full_example/vendordeps/Phoenix6-replay-26.1.0.json @@ -1,32 +1,32 @@ { - "fileName": "Phoenix6-replay-26.0.0-beta-1.json", + "fileName": "Phoenix6-replay-26.1.0.json", "name": "CTRE-Phoenix (v6) Replay", - "version": "26.0.0-beta-1", - "frcYear": "2026beta", + "version": "26.1.0", + "frcYear": "2026", "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", "mavenUrls": [ "https://maven.ctr-electronics.com/release/" ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json", + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-latest.json", "conflictsWith": [ { "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", "errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.", - "offlineFileName": "Phoenix6-frc2026-beta-latest.json" + "offlineFileName": "Phoenix6-frc2026-latest.json" } ], "javaDependencies": [ { "groupId": "com.ctre.phoenix6", "artifactId": "wpiapi-java", - "version": "26.0.0-beta-1" + "version": "26.1.0" } ], "jniDependencies": [ { "groupId": "com.ctre.phoenix6", "artifactId": "api-cpp", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -37,7 +37,7 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "tools", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -48,7 +48,7 @@ { "groupId": "com.ctre.phoenix6.replay", "artifactId": "api-cpp-replay", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -62,7 +62,7 @@ { "groupId": "com.ctre.phoenix6.replay", "artifactId": "tools-replay", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -76,7 +76,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "api-cpp-sim", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -90,7 +90,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "tools-sim", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -104,7 +104,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simTalonSRX", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -118,7 +118,21 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simVictorSPX", - "version": "26.0.0-beta-1", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simPigeonIMU", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -132,7 +146,21 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProTalonFX", - "version": "26.0.0-beta-1", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFXS", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -146,7 +174,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANcoder", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -160,7 +188,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProPigeon2", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -174,7 +202,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANrange", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -188,7 +216,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdi", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -202,7 +230,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdle", - "version": "26.0.0-beta-1", + "version": "26.1.0", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -218,7 +246,7 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "wpiapi-cpp", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_Phoenix6_WPI", "headerClassifier": "headers", "sharedLibrary": true, @@ -231,7 +259,7 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "tools", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_PhoenixTools", "headerClassifier": "headers", "sharedLibrary": true, @@ -244,7 +272,7 @@ { "groupId": "com.ctre.phoenix6.replay", "artifactId": "wpiapi-cpp-replay", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_Phoenix6_WPIReplay", "headerClassifier": "headers", "sharedLibrary": true, @@ -260,7 +288,7 @@ { "groupId": "com.ctre.phoenix6.replay", "artifactId": "tools-replay", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_PhoenixTools_Replay", "headerClassifier": "headers", "sharedLibrary": true, @@ -276,7 +304,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "wpiapi-cpp-sim", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_Phoenix6_WPISim", "headerClassifier": "headers", "sharedLibrary": true, @@ -292,7 +320,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "tools-sim", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_PhoenixTools_Sim", "headerClassifier": "headers", "sharedLibrary": true, @@ -308,7 +336,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simTalonSRX", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimTalonSRX", "headerClassifier": "headers", "sharedLibrary": true, @@ -324,7 +352,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simVictorSPX", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimVictorSPX", "headerClassifier": "headers", "sharedLibrary": true, @@ -340,7 +368,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simPigeonIMU", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimPigeonIMU", "headerClassifier": "headers", "sharedLibrary": true, @@ -356,7 +384,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProTalonFX", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProTalonFX", "headerClassifier": "headers", "sharedLibrary": true, @@ -369,10 +397,26 @@ ], "simMode": "swsim" }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFXS", + "version": "26.1.0", + "libName": "CTRE_SimProTalonFXS", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANcoder", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProCANcoder", "headerClassifier": "headers", "sharedLibrary": true, @@ -388,7 +432,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProPigeon2", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProPigeon2", "headerClassifier": "headers", "sharedLibrary": true, @@ -404,7 +448,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANrange", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProCANrange", "headerClassifier": "headers", "sharedLibrary": true, @@ -420,7 +464,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdi", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProCANdi", "headerClassifier": "headers", "sharedLibrary": true, @@ -436,7 +480,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdle", - "version": "26.0.0-beta-1", + "version": "26.1.0", "libName": "CTRE_SimProCANdle", "headerClassifier": "headers", "sharedLibrary": true, diff --git a/examples/full_example/vendordeps/REVLib.json b/examples/full_example/vendordeps/REVLib.json index 0f666c9..4f96af8 100644 --- a/examples/full_example/vendordeps/REVLib.json +++ b/examples/full_example/vendordeps/REVLib.json @@ -1,8 +1,8 @@ { "fileName": "REVLib.json", "name": "REVLib", - "version": "2026.0.0-beta-1", - "frcYear": "2026beta", + "version": "2026.0.0", + "frcYear": "2026", "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", "mavenUrls": [ "https://maven.revrobotics.com/" @@ -12,14 +12,14 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-java", - "version": "2026.0.0-beta-1" + "version": "2026.0.0" } ], "jniDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -34,7 +34,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -49,7 +49,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibWpiBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -66,7 +66,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-cpp", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "REVLib", "headerClassifier": "headers", "sharedLibrary": false, @@ -83,7 +83,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "REVLibDriver", "headerClassifier": "headers", "sharedLibrary": false, @@ -100,7 +100,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "BackendDriver", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -116,7 +116,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibWpiBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "REVLibWpi", "sharedLibrary": true, "skipInvalidPlatforms": true, diff --git a/examples/full_example/vendordeps/Studica-2026.0.0-beta.json b/examples/full_example/vendordeps/Studica-2026.0.0-beta.json deleted file mode 100644 index c5d48c7..0000000 --- a/examples/full_example/vendordeps/Studica-2026.0.0-beta.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "Studica-2026.0.0-beta.json", - "name": "Studica", - "version": "2026.0.0-beta", - "frcYear": "2026beta", - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", - "mavenUrls": [ - "https://dev.studica.com/maven/release/2026/" - ], - "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0-beta.json", - "javaDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "Studica-java", - "version": "2026.0.0-beta" - } - ], - "jniDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "Studica-driver", - "version": "2026.0.0-beta", - "skipInvalidPlatforms": true, - "isJar": false, - "validPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ], - "cppDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "Studica-cpp", - "version": "2026.0.0-beta", - "libName": "Studica", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - }, - { - "groupId": "com.studica.frc", - "artifactId": "Studica-driver", - "version": "2026.0.0-beta", - "libName": "StudicaDriver", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ] -} \ No newline at end of file diff --git a/examples/full_example/vendordeps/StudicaLib.json b/examples/full_example/vendordeps/StudicaLib.json deleted file mode 100644 index b6ed33e..0000000 --- a/examples/full_example/vendordeps/StudicaLib.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "StudicaLib.json", - "name": "StudicaLib", - "version": "2026.0.1-beta", - "frcYear": "2026beta", - "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", - "mavenUrls": [ - "https://dev.studica.com/maven/release/2026/" - ], - "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.1-beta.json", - "javaDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-java", - "version": "2026.0.1-beta" - } - ], - "jniDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-driver", - "version": "2026.0.1-beta", - "skipInvalidPlatforms": true, - "isJar": false, - "validPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ], - "cppDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-cpp", - "version": "2026.0.1-beta", - "libName": "StudicaLib", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - }, - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-driver", - "version": "2026.0.1-beta", - "libName": "StudicaLibDriver", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ] -} \ No newline at end of file diff --git a/examples/full_example/vendordeps/ThriftyLib.json b/examples/full_example/vendordeps/ThriftyLib.json deleted file mode 100644 index 1e59797..0000000 --- a/examples/full_example/vendordeps/ThriftyLib.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "fileName": "ThriftyLib.json", - "name": "ThriftyLib", - "version": "2026.0.0", - "frcYear": "2026beta", - "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", - "mavenUrls": [ - "https://docs.home.thethriftybot.com" - ], - "jsonUrl": "https://docs.home.thethriftybot.com/ThriftyLib.json", - "javaDependencies": [ - { - "groupId": "com.thethriftybot.frc", - "artifactId": "ThriftyLib-java", - "version": "2026.0.0" - } - ], - "jniDependencies": [], - "cppDependencies": [] -} diff --git a/examples/full_example/vendordeps/WPILibNewCommands.json b/examples/full_example/vendordeps/WPILibNewCommands.json index 7ebc954..69348e4 100644 --- a/examples/full_example/vendordeps/WPILibNewCommands.json +++ b/examples/full_example/vendordeps/WPILibNewCommands.json @@ -1,39 +1,39 @@ { - "fileName": "WPILibNewCommands.json", - "name": "WPILib-New-Commands", - "version": "1.0.0", - "uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266", - "frcYear": "2026beta", - "mavenUrls": [], - "jsonUrl": "", - "javaDependencies": [ - { - "groupId": "edu.wpi.first.wpilibNewCommands", - "artifactId": "wpilibNewCommands-java", - "version": "wpilib" - } - ], - "jniDependencies": [], - "cppDependencies": [ - { - "groupId": "edu.wpi.first.wpilibNewCommands", - "artifactId": "wpilibNewCommands-cpp", - "version": "wpilib", - "libName": "wpilibNewCommands", - "headerClassifier": "headers", - "sourcesClassifier": "sources", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxsystemcore", - "linuxathena", - "linuxarm32", - "linuxarm64", - "windowsx86-64", - "windowsx86", - "linuxx86-64", - "osxuniversal" - ] - } - ] -} + "fileName": "WPILibNewCommands.json", + "name": "WPILib-New-Commands", + "version": "1.0.0", + "uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266", + "frcYear": "2026", + "mavenUrls": [], + "jsonUrl": "", + "javaDependencies": [ + { + "groupId": "edu.wpi.first.wpilibNewCommands", + "artifactId": "wpilibNewCommands-java", + "version": "wpilib" + } + ], + "jniDependencies": [], + "cppDependencies": [ + { + "groupId": "edu.wpi.first.wpilibNewCommands", + "artifactId": "wpilibNewCommands-cpp", + "version": "wpilib", + "libName": "wpilibNewCommands", + "headerClassifier": "headers", + "sourcesClassifier": "sources", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxsystemcore", + "linuxathena", + "linuxarm32", + "linuxarm64", + "windowsx86-64", + "windowsx86", + "linuxx86-64", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/examples/robot_relative_drivebase/build.gradle b/examples/robot_relative_drivebase/build.gradle index 4233229..faa789c 100644 --- a/examples/robot_relative_drivebase/build.gradle +++ b/examples/robot_relative_drivebase/build.gradle @@ -1,6 +1,6 @@ plugins { id "java" - id "edu.wpi.first.GradleRIO" version "2026.1.1-beta-1" + id "edu.wpi.first.GradleRIO" version "2026.1.1" } java { diff --git a/examples/robot_relative_drivebase/vendordeps/PathplannerLib-2026.1.2.json b/examples/robot_relative_drivebase/vendordeps/PathplannerLib-2026.1.2.json new file mode 100644 index 0000000..f72fa41 --- /dev/null +++ b/examples/robot_relative_drivebase/vendordeps/PathplannerLib-2026.1.2.json @@ -0,0 +1,38 @@ +{ + "fileName": "PathplannerLib-2026.1.2.json", + "name": "PathplannerLib", + "version": "2026.1.2", + "uuid": "1b42324f-17c6-4875-8e77-1c312bc8c786", + "frcYear": "2026", + "mavenUrls": [ + "https://3015rangerrobotics.github.io/pathplannerlib/repo" + ], + "jsonUrl": "https://3015rangerrobotics.github.io/pathplannerlib/PathplannerLib.json", + "javaDependencies": [ + { + "groupId": "com.pathplanner.lib", + "artifactId": "PathplannerLib-java", + "version": "2026.1.2" + } + ], + "jniDependencies": [], + "cppDependencies": [ + { + "groupId": "com.pathplanner.lib", + "artifactId": "PathplannerLib-cpp", + "version": "2026.1.2", + "libName": "PathplannerLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal", + "linuxathena", + "linuxarm32", + "linuxarm64" + ] + } + ] +} \ No newline at end of file diff --git a/examples/robot_relative_drivebase/vendordeps/Phoenix5-replay-5.36.0-beta-1.json b/examples/robot_relative_drivebase/vendordeps/Phoenix5-replay-5.36.0-beta-1.json deleted file mode 100644 index 4a78551..0000000 --- a/examples/robot_relative_drivebase/vendordeps/Phoenix5-replay-5.36.0-beta-1.json +++ /dev/null @@ -1,221 +0,0 @@ -{ - "fileName": "Phoenix5-replay-5.36.0-beta-1.json", - "name": "CTRE-Phoenix (v5)", - "version": "5.36.0-beta-1", - "frcYear": "2026beta", - "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", - "mavenUrls": [ - "https://maven.ctr-electronics.com/release/" - ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-beta-latest.json", - "requires": [ - { - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", - "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", - "offlineFileName": "Phoenix6-replay-frc2026-beta-latest.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json" - } - ], - "conflictsWith": [ - { - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "errorMessage": "Users must use the regular Phoenix 5 vendordep when using the regular Phoenix 6 vendordep.", - "offlineFileName": "Phoenix6-frc2026-beta-latest.json" - }, - { - "uuid": "ab676553-b602-441f-a38d-f1296eff6537", - "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", - "offlineFileName": "Phoenix5-frc2026-beta-latest.json" - } - ], - "javaDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "api-java", - "version": "5.36.0-beta-1" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "wpiapi-java", - "version": "5.36.0-beta-1" - } - ], - "jniDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "cci", - "version": "5.36.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.replay", - "artifactId": "cci-replay", - "version": "5.36.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "cci-sim", - "version": "5.36.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ], - "cppDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "wpiapi-cpp", - "version": "5.36.0-beta-1", - "libName": "CTRE_Phoenix_WPI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "api-cpp", - "version": "5.36.0-beta-1", - "libName": "CTRE_Phoenix", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "cci", - "version": "5.36.0-beta-1", - "libName": "CTRE_PhoenixCCI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.replay", - "artifactId": "wpiapi-cpp-replay", - "version": "5.36.0-beta-1", - "libName": "CTRE_Phoenix_WPIReplay", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.replay", - "artifactId": "api-cpp-replay", - "version": "5.36.0-beta-1", - "libName": "CTRE_PhoenixReplay", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.replay", - "artifactId": "cci-replay", - "version": "5.36.0-beta-1", - "libName": "CTRE_PhoenixCCIReplay", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "wpiapi-cpp-sim", - "version": "5.36.0-beta-1", - "libName": "CTRE_Phoenix_WPISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "api-cpp-sim", - "version": "5.36.0-beta-1", - "libName": "CTRE_PhoenixSim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "cci-sim", - "version": "5.36.0-beta-1", - "libName": "CTRE_PhoenixCCISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ] -} \ No newline at end of file diff --git a/examples/robot_relative_drivebase/vendordeps/Phoenix5-replay-5.36.0.json b/examples/robot_relative_drivebase/vendordeps/Phoenix5-replay-5.36.0.json new file mode 100644 index 0000000..0e799ed --- /dev/null +++ b/examples/robot_relative_drivebase/vendordeps/Phoenix5-replay-5.36.0.json @@ -0,0 +1,221 @@ +{ + "fileName": "Phoenix5-replay-5.36.0.json", + "name": "CTRE-Phoenix (v5)", + "version": "5.36.0", + "frcYear": "2026", + "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", + "mavenUrls": [ + "https://maven.ctr-electronics.com/release/" + ], + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-latest.json", + "requires": [ + { + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", + "offlineFileName": "Phoenix6-replay-frc2026-latest.json", + "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-latest.json" + } + ], + "conflictsWith": [ + { + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "errorMessage": "Users must use the regular Phoenix 5 vendordep when using the regular Phoenix 6 vendordep.", + "offlineFileName": "Phoenix6-frc2026-latest.json" + }, + { + "uuid": "ab676553-b602-441f-a38d-f1296eff6537", + "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", + "offlineFileName": "Phoenix5-frc2026-latest.json" + } + ], + "javaDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-java", + "version": "5.36.0" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-java", + "version": "5.36.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "cci-replay", + "version": "5.36.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ], + "cppDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-cpp", + "version": "5.36.0", + "libName": "CTRE_Phoenix_WPI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-cpp", + "version": "5.36.0", + "libName": "CTRE_Phoenix", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0", + "libName": "CTRE_PhoenixCCI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "wpiapi-cpp-replay", + "version": "5.36.0", + "libName": "CTRE_Phoenix_WPIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "api-cpp-replay", + "version": "5.36.0", + "libName": "CTRE_PhoenixReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "cci-replay", + "version": "5.36.0", + "libName": "CTRE_PhoenixCCIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "wpiapi-cpp-sim", + "version": "5.36.0", + "libName": "CTRE_Phoenix_WPISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "api-cpp-sim", + "version": "5.36.0", + "libName": "CTRE_PhoenixSim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0", + "libName": "CTRE_PhoenixCCISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ] +} \ No newline at end of file diff --git a/examples/robot_relative_drivebase/vendordeps/Phoenix6-replay-26.0.0-beta-1.json b/examples/robot_relative_drivebase/vendordeps/Phoenix6-replay-26.0.0-beta-1.json deleted file mode 100644 index 5312c86..0000000 --- a/examples/robot_relative_drivebase/vendordeps/Phoenix6-replay-26.0.0-beta-1.json +++ /dev/null @@ -1,453 +0,0 @@ -{ - "fileName": "Phoenix6-replay-26.0.0-beta-1.json", - "name": "CTRE-Phoenix (v6) Replay", - "version": "26.0.0-beta-1", - "frcYear": "2026beta", - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", - "mavenUrls": [ - "https://maven.ctr-electronics.com/release/" - ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json", - "conflictsWith": [ - { - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.", - "offlineFileName": "Phoenix6-frc2026-beta-latest.json" - } - ], - "javaDependencies": [ - { - "groupId": "com.ctre.phoenix6", - "artifactId": "wpiapi-java", - "version": "26.0.0-beta-1" - } - ], - "jniDependencies": [ - { - "groupId": "com.ctre.phoenix6", - "artifactId": "api-cpp", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6", - "artifactId": "tools", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6.replay", - "artifactId": "api-cpp-replay", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6.replay", - "artifactId": "tools-replay", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "api-cpp-sim", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "tools-sim", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simTalonSRX", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simVictorSPX", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFX", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANcoder", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProPigeon2", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANrange", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANdi", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANdle", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ], - "cppDependencies": [ - { - "groupId": "com.ctre.phoenix6", - "artifactId": "wpiapi-cpp", - "version": "26.0.0-beta-1", - "libName": "CTRE_Phoenix6_WPI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6", - "artifactId": "tools", - "version": "26.0.0-beta-1", - "libName": "CTRE_PhoenixTools", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6.replay", - "artifactId": "wpiapi-cpp-replay", - "version": "26.0.0-beta-1", - "libName": "CTRE_Phoenix6_WPIReplay", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6.replay", - "artifactId": "tools-replay", - "version": "26.0.0-beta-1", - "libName": "CTRE_PhoenixTools_Replay", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "wpiapi-cpp-sim", - "version": "26.0.0-beta-1", - "libName": "CTRE_Phoenix6_WPISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "tools-sim", - "version": "26.0.0-beta-1", - "libName": "CTRE_PhoenixTools_Sim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simTalonSRX", - "version": "26.0.0-beta-1", - "libName": "CTRE_SimTalonSRX", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simVictorSPX", - "version": "26.0.0-beta-1", - "libName": "CTRE_SimVictorSPX", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simPigeonIMU", - "version": "26.0.0-beta-1", - "libName": "CTRE_SimPigeonIMU", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFX", - "version": "26.0.0-beta-1", - "libName": "CTRE_SimProTalonFX", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANcoder", - "version": "26.0.0-beta-1", - "libName": "CTRE_SimProCANcoder", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProPigeon2", - "version": "26.0.0-beta-1", - "libName": "CTRE_SimProPigeon2", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANrange", - "version": "26.0.0-beta-1", - "libName": "CTRE_SimProCANrange", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANdi", - "version": "26.0.0-beta-1", - "libName": "CTRE_SimProCANdi", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANdle", - "version": "26.0.0-beta-1", - "libName": "CTRE_SimProCANdle", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ] -} \ No newline at end of file diff --git a/examples/robot_relative_drivebase/vendordeps/Phoenix6-replay-26.1.0.json b/examples/robot_relative_drivebase/vendordeps/Phoenix6-replay-26.1.0.json new file mode 100644 index 0000000..e49c760 --- /dev/null +++ b/examples/robot_relative_drivebase/vendordeps/Phoenix6-replay-26.1.0.json @@ -0,0 +1,497 @@ +{ + "fileName": "Phoenix6-replay-26.1.0.json", + "name": "CTRE-Phoenix (v6) Replay", + "version": "26.1.0", + "frcYear": "2026", + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "mavenUrls": [ + "https://maven.ctr-electronics.com/release/" + ], + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-latest.json", + "conflictsWith": [ + { + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.", + "offlineFileName": "Phoenix6-frc2026-latest.json" + } + ], + "javaDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "wpiapi-java", + "version": "26.1.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "api-cpp", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6", + "artifactId": "tools", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "api-cpp-replay", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "tools-replay", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "api-cpp-sim", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "tools-sim", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simTalonSRX", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simVictorSPX", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simPigeonIMU", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFX", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFXS", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANcoder", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProPigeon2", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANrange", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdi", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdle", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ], + "cppDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "wpiapi-cpp", + "version": "26.1.0", + "libName": "CTRE_Phoenix6_WPI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6", + "artifactId": "tools", + "version": "26.1.0", + "libName": "CTRE_PhoenixTools", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "wpiapi-cpp-replay", + "version": "26.1.0", + "libName": "CTRE_Phoenix6_WPIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "tools-replay", + "version": "26.1.0", + "libName": "CTRE_PhoenixTools_Replay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "wpiapi-cpp-sim", + "version": "26.1.0", + "libName": "CTRE_Phoenix6_WPISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "tools-sim", + "version": "26.1.0", + "libName": "CTRE_PhoenixTools_Sim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simTalonSRX", + "version": "26.1.0", + "libName": "CTRE_SimTalonSRX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simVictorSPX", + "version": "26.1.0", + "libName": "CTRE_SimVictorSPX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simPigeonIMU", + "version": "26.1.0", + "libName": "CTRE_SimPigeonIMU", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFX", + "version": "26.1.0", + "libName": "CTRE_SimProTalonFX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFXS", + "version": "26.1.0", + "libName": "CTRE_SimProTalonFXS", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANcoder", + "version": "26.1.0", + "libName": "CTRE_SimProCANcoder", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProPigeon2", + "version": "26.1.0", + "libName": "CTRE_SimProPigeon2", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANrange", + "version": "26.1.0", + "libName": "CTRE_SimProCANrange", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdi", + "version": "26.1.0", + "libName": "CTRE_SimProCANdi", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdle", + "version": "26.1.0", + "libName": "CTRE_SimProCANdle", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ] +} \ No newline at end of file diff --git a/examples/robot_relative_drivebase/vendordeps/REVLib.json b/examples/robot_relative_drivebase/vendordeps/REVLib.json index 0f666c9..4f96af8 100644 --- a/examples/robot_relative_drivebase/vendordeps/REVLib.json +++ b/examples/robot_relative_drivebase/vendordeps/REVLib.json @@ -1,8 +1,8 @@ { "fileName": "REVLib.json", "name": "REVLib", - "version": "2026.0.0-beta-1", - "frcYear": "2026beta", + "version": "2026.0.0", + "frcYear": "2026", "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", "mavenUrls": [ "https://maven.revrobotics.com/" @@ -12,14 +12,14 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-java", - "version": "2026.0.0-beta-1" + "version": "2026.0.0" } ], "jniDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -34,7 +34,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -49,7 +49,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibWpiBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -66,7 +66,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-cpp", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "REVLib", "headerClassifier": "headers", "sharedLibrary": false, @@ -83,7 +83,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "REVLibDriver", "headerClassifier": "headers", "sharedLibrary": false, @@ -100,7 +100,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "BackendDriver", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -116,7 +116,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibWpiBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "REVLibWpi", "sharedLibrary": true, "skipInvalidPlatforms": true, diff --git a/examples/robot_relative_drivebase/vendordeps/Studica-2026.0.0-beta.json b/examples/robot_relative_drivebase/vendordeps/Studica-2026.0.0-beta.json deleted file mode 100644 index c5d48c7..0000000 --- a/examples/robot_relative_drivebase/vendordeps/Studica-2026.0.0-beta.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "Studica-2026.0.0-beta.json", - "name": "Studica", - "version": "2026.0.0-beta", - "frcYear": "2026beta", - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", - "mavenUrls": [ - "https://dev.studica.com/maven/release/2026/" - ], - "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0-beta.json", - "javaDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "Studica-java", - "version": "2026.0.0-beta" - } - ], - "jniDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "Studica-driver", - "version": "2026.0.0-beta", - "skipInvalidPlatforms": true, - "isJar": false, - "validPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ], - "cppDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "Studica-cpp", - "version": "2026.0.0-beta", - "libName": "Studica", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - }, - { - "groupId": "com.studica.frc", - "artifactId": "Studica-driver", - "version": "2026.0.0-beta", - "libName": "StudicaDriver", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ] -} \ No newline at end of file diff --git a/examples/robot_relative_drivebase/vendordeps/StudicaLib.json b/examples/robot_relative_drivebase/vendordeps/StudicaLib.json deleted file mode 100644 index b6ed33e..0000000 --- a/examples/robot_relative_drivebase/vendordeps/StudicaLib.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "StudicaLib.json", - "name": "StudicaLib", - "version": "2026.0.1-beta", - "frcYear": "2026beta", - "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", - "mavenUrls": [ - "https://dev.studica.com/maven/release/2026/" - ], - "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.1-beta.json", - "javaDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-java", - "version": "2026.0.1-beta" - } - ], - "jniDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-driver", - "version": "2026.0.1-beta", - "skipInvalidPlatforms": true, - "isJar": false, - "validPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ], - "cppDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-cpp", - "version": "2026.0.1-beta", - "libName": "StudicaLib", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - }, - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-driver", - "version": "2026.0.1-beta", - "libName": "StudicaLibDriver", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ] -} \ No newline at end of file diff --git a/examples/robot_relative_drivebase/vendordeps/ThriftyLib.json b/examples/robot_relative_drivebase/vendordeps/ThriftyLib.json deleted file mode 100644 index 1e59797..0000000 --- a/examples/robot_relative_drivebase/vendordeps/ThriftyLib.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "fileName": "ThriftyLib.json", - "name": "ThriftyLib", - "version": "2026.0.0", - "frcYear": "2026beta", - "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", - "mavenUrls": [ - "https://docs.home.thethriftybot.com" - ], - "jsonUrl": "https://docs.home.thethriftybot.com/ThriftyLib.json", - "javaDependencies": [ - { - "groupId": "com.thethriftybot.frc", - "artifactId": "ThriftyLib-java", - "version": "2026.0.0" - } - ], - "jniDependencies": [], - "cppDependencies": [] -} diff --git a/examples/robot_relative_drivebase/vendordeps/WPILibNewCommands.json b/examples/robot_relative_drivebase/vendordeps/WPILibNewCommands.json index 7ebc954..69348e4 100644 --- a/examples/robot_relative_drivebase/vendordeps/WPILibNewCommands.json +++ b/examples/robot_relative_drivebase/vendordeps/WPILibNewCommands.json @@ -1,39 +1,39 @@ { - "fileName": "WPILibNewCommands.json", - "name": "WPILib-New-Commands", - "version": "1.0.0", - "uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266", - "frcYear": "2026beta", - "mavenUrls": [], - "jsonUrl": "", - "javaDependencies": [ - { - "groupId": "edu.wpi.first.wpilibNewCommands", - "artifactId": "wpilibNewCommands-java", - "version": "wpilib" - } - ], - "jniDependencies": [], - "cppDependencies": [ - { - "groupId": "edu.wpi.first.wpilibNewCommands", - "artifactId": "wpilibNewCommands-cpp", - "version": "wpilib", - "libName": "wpilibNewCommands", - "headerClassifier": "headers", - "sourcesClassifier": "sources", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxsystemcore", - "linuxathena", - "linuxarm32", - "linuxarm64", - "windowsx86-64", - "windowsx86", - "linuxx86-64", - "osxuniversal" - ] - } - ] -} + "fileName": "WPILibNewCommands.json", + "name": "WPILib-New-Commands", + "version": "1.0.0", + "uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266", + "frcYear": "2026", + "mavenUrls": [], + "jsonUrl": "", + "javaDependencies": [ + { + "groupId": "edu.wpi.first.wpilibNewCommands", + "artifactId": "wpilibNewCommands-java", + "version": "wpilib" + } + ], + "jniDependencies": [], + "cppDependencies": [ + { + "groupId": "edu.wpi.first.wpilibNewCommands", + "artifactId": "wpilibNewCommands-cpp", + "version": "wpilib", + "libName": "wpilibNewCommands", + "headerClassifier": "headers", + "sourcesClassifier": "sources", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxsystemcore", + "linuxathena", + "linuxarm32", + "linuxarm64", + "windowsx86-64", + "windowsx86", + "linuxx86-64", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/vendordep/vendordeps/PathplannerLib-2026.1.2.json b/vendordep/vendordeps/PathplannerLib-2026.1.2.json new file mode 100644 index 0000000..f72fa41 --- /dev/null +++ b/vendordep/vendordeps/PathplannerLib-2026.1.2.json @@ -0,0 +1,38 @@ +{ + "fileName": "PathplannerLib-2026.1.2.json", + "name": "PathplannerLib", + "version": "2026.1.2", + "uuid": "1b42324f-17c6-4875-8e77-1c312bc8c786", + "frcYear": "2026", + "mavenUrls": [ + "https://3015rangerrobotics.github.io/pathplannerlib/repo" + ], + "jsonUrl": "https://3015rangerrobotics.github.io/pathplannerlib/PathplannerLib.json", + "javaDependencies": [ + { + "groupId": "com.pathplanner.lib", + "artifactId": "PathplannerLib-java", + "version": "2026.1.2" + } + ], + "jniDependencies": [], + "cppDependencies": [ + { + "groupId": "com.pathplanner.lib", + "artifactId": "PathplannerLib-cpp", + "version": "2026.1.2", + "libName": "PathplannerLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal", + "linuxathena", + "linuxarm32", + "linuxarm64" + ] + } + ] +} \ No newline at end of file diff --git a/vendordep/vendordeps/Phoenix5-replay-5.36.0-beta-1.json b/vendordep/vendordeps/Phoenix5-replay-5.36.0-beta-1.json deleted file mode 100644 index 4a78551..0000000 --- a/vendordep/vendordeps/Phoenix5-replay-5.36.0-beta-1.json +++ /dev/null @@ -1,221 +0,0 @@ -{ - "fileName": "Phoenix5-replay-5.36.0-beta-1.json", - "name": "CTRE-Phoenix (v5)", - "version": "5.36.0-beta-1", - "frcYear": "2026beta", - "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", - "mavenUrls": [ - "https://maven.ctr-electronics.com/release/" - ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-beta-latest.json", - "requires": [ - { - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", - "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", - "offlineFileName": "Phoenix6-replay-frc2026-beta-latest.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json" - } - ], - "conflictsWith": [ - { - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "errorMessage": "Users must use the regular Phoenix 5 vendordep when using the regular Phoenix 6 vendordep.", - "offlineFileName": "Phoenix6-frc2026-beta-latest.json" - }, - { - "uuid": "ab676553-b602-441f-a38d-f1296eff6537", - "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", - "offlineFileName": "Phoenix5-frc2026-beta-latest.json" - } - ], - "javaDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "api-java", - "version": "5.36.0-beta-1" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "wpiapi-java", - "version": "5.36.0-beta-1" - } - ], - "jniDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "cci", - "version": "5.36.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.replay", - "artifactId": "cci-replay", - "version": "5.36.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "cci-sim", - "version": "5.36.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ], - "cppDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "wpiapi-cpp", - "version": "5.36.0-beta-1", - "libName": "CTRE_Phoenix_WPI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "api-cpp", - "version": "5.36.0-beta-1", - "libName": "CTRE_Phoenix", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "cci", - "version": "5.36.0-beta-1", - "libName": "CTRE_PhoenixCCI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.replay", - "artifactId": "wpiapi-cpp-replay", - "version": "5.36.0-beta-1", - "libName": "CTRE_Phoenix_WPIReplay", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.replay", - "artifactId": "api-cpp-replay", - "version": "5.36.0-beta-1", - "libName": "CTRE_PhoenixReplay", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.replay", - "artifactId": "cci-replay", - "version": "5.36.0-beta-1", - "libName": "CTRE_PhoenixCCIReplay", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "wpiapi-cpp-sim", - "version": "5.36.0-beta-1", - "libName": "CTRE_Phoenix_WPISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "api-cpp-sim", - "version": "5.36.0-beta-1", - "libName": "CTRE_PhoenixSim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "cci-sim", - "version": "5.36.0-beta-1", - "libName": "CTRE_PhoenixCCISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ] -} \ No newline at end of file diff --git a/vendordep/vendordeps/Phoenix5-replay-5.36.0.json b/vendordep/vendordeps/Phoenix5-replay-5.36.0.json new file mode 100644 index 0000000..0e799ed --- /dev/null +++ b/vendordep/vendordeps/Phoenix5-replay-5.36.0.json @@ -0,0 +1,221 @@ +{ + "fileName": "Phoenix5-replay-5.36.0.json", + "name": "CTRE-Phoenix (v5)", + "version": "5.36.0", + "frcYear": "2026", + "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", + "mavenUrls": [ + "https://maven.ctr-electronics.com/release/" + ], + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-latest.json", + "requires": [ + { + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", + "offlineFileName": "Phoenix6-replay-frc2026-latest.json", + "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-latest.json" + } + ], + "conflictsWith": [ + { + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "errorMessage": "Users must use the regular Phoenix 5 vendordep when using the regular Phoenix 6 vendordep.", + "offlineFileName": "Phoenix6-frc2026-latest.json" + }, + { + "uuid": "ab676553-b602-441f-a38d-f1296eff6537", + "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", + "offlineFileName": "Phoenix5-frc2026-latest.json" + } + ], + "javaDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-java", + "version": "5.36.0" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-java", + "version": "5.36.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "cci-replay", + "version": "5.36.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ], + "cppDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-cpp", + "version": "5.36.0", + "libName": "CTRE_Phoenix_WPI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-cpp", + "version": "5.36.0", + "libName": "CTRE_Phoenix", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0", + "libName": "CTRE_PhoenixCCI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "wpiapi-cpp-replay", + "version": "5.36.0", + "libName": "CTRE_Phoenix_WPIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "api-cpp-replay", + "version": "5.36.0", + "libName": "CTRE_PhoenixReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.replay", + "artifactId": "cci-replay", + "version": "5.36.0", + "libName": "CTRE_PhoenixCCIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "wpiapi-cpp-sim", + "version": "5.36.0", + "libName": "CTRE_Phoenix_WPISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "api-cpp-sim", + "version": "5.36.0", + "libName": "CTRE_PhoenixSim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0", + "libName": "CTRE_PhoenixCCISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ] +} \ No newline at end of file diff --git a/vendordep/vendordeps/Phoenix6-replay-26.0.0-beta-1.json b/vendordep/vendordeps/Phoenix6-replay-26.0.0-beta-1.json deleted file mode 100644 index 5312c86..0000000 --- a/vendordep/vendordeps/Phoenix6-replay-26.0.0-beta-1.json +++ /dev/null @@ -1,453 +0,0 @@ -{ - "fileName": "Phoenix6-replay-26.0.0-beta-1.json", - "name": "CTRE-Phoenix (v6) Replay", - "version": "26.0.0-beta-1", - "frcYear": "2026beta", - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", - "mavenUrls": [ - "https://maven.ctr-electronics.com/release/" - ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json", - "conflictsWith": [ - { - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.", - "offlineFileName": "Phoenix6-frc2026-beta-latest.json" - } - ], - "javaDependencies": [ - { - "groupId": "com.ctre.phoenix6", - "artifactId": "wpiapi-java", - "version": "26.0.0-beta-1" - } - ], - "jniDependencies": [ - { - "groupId": "com.ctre.phoenix6", - "artifactId": "api-cpp", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6", - "artifactId": "tools", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6.replay", - "artifactId": "api-cpp-replay", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6.replay", - "artifactId": "tools-replay", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "api-cpp-sim", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "tools-sim", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simTalonSRX", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simVictorSPX", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFX", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANcoder", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProPigeon2", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANrange", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANdi", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANdle", - "version": "26.0.0-beta-1", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ], - "cppDependencies": [ - { - "groupId": "com.ctre.phoenix6", - "artifactId": "wpiapi-cpp", - "version": "26.0.0-beta-1", - "libName": "CTRE_Phoenix6_WPI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6", - "artifactId": "tools", - "version": "26.0.0-beta-1", - "libName": "CTRE_PhoenixTools", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6.replay", - "artifactId": "wpiapi-cpp-replay", - "version": "26.0.0-beta-1", - "libName": "CTRE_Phoenix6_WPIReplay", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6.replay", - "artifactId": "tools-replay", - "version": "26.0.0-beta-1", - "libName": "CTRE_PhoenixTools_Replay", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "wpiapi-cpp-sim", - "version": "26.0.0-beta-1", - "libName": "CTRE_Phoenix6_WPISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "tools-sim", - "version": "26.0.0-beta-1", - "libName": "CTRE_PhoenixTools_Sim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simTalonSRX", - "version": "26.0.0-beta-1", - "libName": "CTRE_SimTalonSRX", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simVictorSPX", - "version": "26.0.0-beta-1", - "libName": "CTRE_SimVictorSPX", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simPigeonIMU", - "version": "26.0.0-beta-1", - "libName": "CTRE_SimPigeonIMU", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProTalonFX", - "version": "26.0.0-beta-1", - "libName": "CTRE_SimProTalonFX", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANcoder", - "version": "26.0.0-beta-1", - "libName": "CTRE_SimProCANcoder", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProPigeon2", - "version": "26.0.0-beta-1", - "libName": "CTRE_SimProPigeon2", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANrange", - "version": "26.0.0-beta-1", - "libName": "CTRE_SimProCANrange", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANdi", - "version": "26.0.0-beta-1", - "libName": "CTRE_SimProCANdi", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix6.sim", - "artifactId": "simProCANdle", - "version": "26.0.0-beta-1", - "libName": "CTRE_SimProCANdle", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ] -} \ No newline at end of file diff --git a/vendordep/vendordeps/Phoenix6-replay-26.1.0.json b/vendordep/vendordeps/Phoenix6-replay-26.1.0.json new file mode 100644 index 0000000..e49c760 --- /dev/null +++ b/vendordep/vendordeps/Phoenix6-replay-26.1.0.json @@ -0,0 +1,497 @@ +{ + "fileName": "Phoenix6-replay-26.1.0.json", + "name": "CTRE-Phoenix (v6) Replay", + "version": "26.1.0", + "frcYear": "2026", + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "mavenUrls": [ + "https://maven.ctr-electronics.com/release/" + ], + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-latest.json", + "conflictsWith": [ + { + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.", + "offlineFileName": "Phoenix6-frc2026-latest.json" + } + ], + "javaDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "wpiapi-java", + "version": "26.1.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "api-cpp", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6", + "artifactId": "tools", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "api-cpp-replay", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "tools-replay", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "api-cpp-sim", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "tools-sim", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simTalonSRX", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simVictorSPX", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simPigeonIMU", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFX", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFXS", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANcoder", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProPigeon2", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANrange", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdi", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdle", + "version": "26.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ], + "cppDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "wpiapi-cpp", + "version": "26.1.0", + "libName": "CTRE_Phoenix6_WPI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6", + "artifactId": "tools", + "version": "26.1.0", + "libName": "CTRE_PhoenixTools", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "wpiapi-cpp-replay", + "version": "26.1.0", + "libName": "CTRE_Phoenix6_WPIReplay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.replay", + "artifactId": "tools-replay", + "version": "26.1.0", + "libName": "CTRE_PhoenixTools_Replay", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "wpiapi-cpp-sim", + "version": "26.1.0", + "libName": "CTRE_Phoenix6_WPISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "tools-sim", + "version": "26.1.0", + "libName": "CTRE_PhoenixTools_Sim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simTalonSRX", + "version": "26.1.0", + "libName": "CTRE_SimTalonSRX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simVictorSPX", + "version": "26.1.0", + "libName": "CTRE_SimVictorSPX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simPigeonIMU", + "version": "26.1.0", + "libName": "CTRE_SimPigeonIMU", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFX", + "version": "26.1.0", + "libName": "CTRE_SimProTalonFX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFXS", + "version": "26.1.0", + "libName": "CTRE_SimProTalonFXS", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANcoder", + "version": "26.1.0", + "libName": "CTRE_SimProCANcoder", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProPigeon2", + "version": "26.1.0", + "libName": "CTRE_SimProPigeon2", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANrange", + "version": "26.1.0", + "libName": "CTRE_SimProCANrange", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdi", + "version": "26.1.0", + "libName": "CTRE_SimProCANdi", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANdle", + "version": "26.1.0", + "libName": "CTRE_SimProCANdle", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ] +} \ No newline at end of file diff --git a/vendordep/vendordeps/REVLib.json b/vendordep/vendordeps/REVLib.json index 0f666c9..4f96af8 100644 --- a/vendordep/vendordeps/REVLib.json +++ b/vendordep/vendordeps/REVLib.json @@ -1,8 +1,8 @@ { "fileName": "REVLib.json", "name": "REVLib", - "version": "2026.0.0-beta-1", - "frcYear": "2026beta", + "version": "2026.0.0", + "frcYear": "2026", "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", "mavenUrls": [ "https://maven.revrobotics.com/" @@ -12,14 +12,14 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-java", - "version": "2026.0.0-beta-1" + "version": "2026.0.0" } ], "jniDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -34,7 +34,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -49,7 +49,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibWpiBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -66,7 +66,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-cpp", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "REVLib", "headerClassifier": "headers", "sharedLibrary": false, @@ -83,7 +83,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "REVLibDriver", "headerClassifier": "headers", "sharedLibrary": false, @@ -100,7 +100,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "BackendDriver", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -116,7 +116,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibWpiBackendDriver", - "version": "2026.0.0-beta-1", + "version": "2026.0.0", "libName": "REVLibWpi", "sharedLibrary": true, "skipInvalidPlatforms": true, diff --git a/vendordep/vendordeps/Studica-2026.0.0-beta.json b/vendordep/vendordeps/Studica-2026.0.0-beta.json deleted file mode 100644 index c5d48c7..0000000 --- a/vendordep/vendordeps/Studica-2026.0.0-beta.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "Studica-2026.0.0-beta.json", - "name": "Studica", - "version": "2026.0.0-beta", - "frcYear": "2026beta", - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", - "mavenUrls": [ - "https://dev.studica.com/maven/release/2026/" - ], - "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0-beta.json", - "javaDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "Studica-java", - "version": "2026.0.0-beta" - } - ], - "jniDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "Studica-driver", - "version": "2026.0.0-beta", - "skipInvalidPlatforms": true, - "isJar": false, - "validPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ], - "cppDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "Studica-cpp", - "version": "2026.0.0-beta", - "libName": "Studica", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - }, - { - "groupId": "com.studica.frc", - "artifactId": "Studica-driver", - "version": "2026.0.0-beta", - "libName": "StudicaDriver", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ] -} \ No newline at end of file diff --git a/vendordep/vendordeps/StudicaLib.json b/vendordep/vendordeps/StudicaLib.json deleted file mode 100644 index b6ed33e..0000000 --- a/vendordep/vendordeps/StudicaLib.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "StudicaLib.json", - "name": "StudicaLib", - "version": "2026.0.1-beta", - "frcYear": "2026beta", - "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", - "mavenUrls": [ - "https://dev.studica.com/maven/release/2026/" - ], - "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.1-beta.json", - "javaDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-java", - "version": "2026.0.1-beta" - } - ], - "jniDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-driver", - "version": "2026.0.1-beta", - "skipInvalidPlatforms": true, - "isJar": false, - "validPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ], - "cppDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-cpp", - "version": "2026.0.1-beta", - "libName": "StudicaLib", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - }, - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-driver", - "version": "2026.0.1-beta", - "libName": "StudicaLibDriver", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ] -} \ No newline at end of file diff --git a/vendordep/vendordeps/ThriftyLib.json b/vendordep/vendordeps/ThriftyLib.json deleted file mode 100644 index 1e59797..0000000 --- a/vendordep/vendordeps/ThriftyLib.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "fileName": "ThriftyLib.json", - "name": "ThriftyLib", - "version": "2026.0.0", - "frcYear": "2026beta", - "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", - "mavenUrls": [ - "https://docs.home.thethriftybot.com" - ], - "jsonUrl": "https://docs.home.thethriftybot.com/ThriftyLib.json", - "javaDependencies": [ - { - "groupId": "com.thethriftybot.frc", - "artifactId": "ThriftyLib-java", - "version": "2026.0.0" - } - ], - "jniDependencies": [], - "cppDependencies": [] -} diff --git a/vendordep/vendordeps/WPILibNewCommands.json b/vendordep/vendordeps/WPILibNewCommands.json index 7ebc954..69348e4 100644 --- a/vendordep/vendordeps/WPILibNewCommands.json +++ b/vendordep/vendordeps/WPILibNewCommands.json @@ -1,39 +1,39 @@ { - "fileName": "WPILibNewCommands.json", - "name": "WPILib-New-Commands", - "version": "1.0.0", - "uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266", - "frcYear": "2026beta", - "mavenUrls": [], - "jsonUrl": "", - "javaDependencies": [ - { - "groupId": "edu.wpi.first.wpilibNewCommands", - "artifactId": "wpilibNewCommands-java", - "version": "wpilib" - } - ], - "jniDependencies": [], - "cppDependencies": [ - { - "groupId": "edu.wpi.first.wpilibNewCommands", - "artifactId": "wpilibNewCommands-cpp", - "version": "wpilib", - "libName": "wpilibNewCommands", - "headerClassifier": "headers", - "sourcesClassifier": "sources", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxsystemcore", - "linuxathena", - "linuxarm32", - "linuxarm64", - "windowsx86-64", - "windowsx86", - "linuxx86-64", - "osxuniversal" - ] - } - ] -} + "fileName": "WPILibNewCommands.json", + "name": "WPILib-New-Commands", + "version": "1.0.0", + "uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266", + "frcYear": "2026", + "mavenUrls": [], + "jsonUrl": "", + "javaDependencies": [ + { + "groupId": "edu.wpi.first.wpilibNewCommands", + "artifactId": "wpilibNewCommands-java", + "version": "wpilib" + } + ], + "jniDependencies": [], + "cppDependencies": [ + { + "groupId": "edu.wpi.first.wpilibNewCommands", + "artifactId": "wpilibNewCommands-cpp", + "version": "wpilib", + "libName": "wpilibNewCommands", + "headerClassifier": "headers", + "sourcesClassifier": "sources", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxsystemcore", + "linuxathena", + "linuxarm32", + "linuxarm64", + "windowsx86-64", + "windowsx86", + "linuxx86-64", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/opponentsim/OpponentManager.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/opponentsim/OpponentManager.java index 11b4b2d..e7c36c0 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/opponentsim/OpponentManager.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/opponentsim/OpponentManager.java @@ -8,6 +8,7 @@ import edu.wpi.first.units.measure.Distance; import edu.wpi.first.units.measure.Time; import edu.wpi.first.wpilibj.DriverStation; +import edu.wpi.first.wpilibj2.command.CommandScheduler; import swervelib.simulation.ironmaple.simulation.opponentsim.pathfinding.MapleADStar; import java.util.*; @@ -81,7 +82,7 @@ public OpponentManager(boolean withDefaults) { * @return this, for chaining. */ public OpponentManager withDefaults() { - PathfindingCommand.warmupCommand().schedule(); + CommandScheduler.getInstance().schedule(PathfindingCommand.warmupCommand()); this .withDefaultInitialPoses() .withDefaultQueeningPoses(); diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/opponentsim/SmartOpponent.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/opponentsim/SmartOpponent.java index ee920ef..79f17da 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/opponentsim/SmartOpponent.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/opponentsim/SmartOpponent.java @@ -25,6 +25,7 @@ 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.CommandScheduler; import edu.wpi.first.wpilibj2.command.Commands; import edu.wpi.first.wpilibj2.command.SubsystemBase; import edu.wpi.first.wpilibj2.command.button.RobotModeTriggers; @@ -122,13 +123,13 @@ public SmartOpponent(SmartOpponentConfig config) { + "'s Behaviors", config.updateBehaviorChooser()); /// Run behavior command when changed. - config.getBehaviorChooser().onChange(Command::schedule); + config.getBehaviorChooser().onChange(a -> CommandScheduler.getInstance().schedule(a)); /// Finally, add our simulation SimulatedArena.getInstance().addDriveTrainSimulation(drivetrainSim.getDriveTrainSimulation()); if (config.isAutoEnable) { RobotModeTriggers.teleop() .onTrue(Commands.runOnce( - () -> config.getBehaviorChooser().getSelected().schedule())); + () -> CommandScheduler.getInstance().schedule(config.getBehaviorChooser().getSelected()))); RobotModeTriggers.disabled().onTrue(standbyState()); } /// If a manager is set register with it @@ -212,18 +213,18 @@ protected Command startingState(String nextState) { public void simulationPeriodic() { // If command not in progress and standby isn't the desired state. Or if a restartInterrupt occurred, restarting the current state. if (!config.commandInProgress && !Objects.equals("Standby", config.desiredState)) { - runState(config.desiredState, false).schedule(); + CommandScheduler.getInstance().schedule(runState(config.desiredState, false)); } // If restart requested, do that now. if (restartInterrupt) { - runState(config.desiredState, true).schedule(); + CommandScheduler.getInstance().schedule(runState(config.desiredState, true)); notMovingTimer.restart(); restartInterrupt = false; } // If we are very stuck reload from start. if (notMovingTimer.hasElapsed(5)) { drivetrainSim.setSimulationWorldPose(config.initialPose); - runState(config.desiredState, true).schedule(); + CommandScheduler.getInstance().schedule(runState(config.desiredState, true)); } // If the timer is not running and a command is running and the opponent is not moving, start the timer. if (!notMovingTimer.isRunning() && config.commandInProgress && !isMoving(notMovingThreshold)) { From 6d67b1b3ca343e931c6e438df5542d1923a027bb Mon Sep 17 00:00:00 2001 From: thenetworkgrinch Date: Sun, 11 Jan 2026 17:13:28 -0600 Subject: [PATCH 08/62] Update the wpilib --- vendordep/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vendordep/build.gradle b/vendordep/build.gradle index ad96031..c13d431 100644 --- a/vendordep/build.gradle +++ b/vendordep/build.gradle @@ -4,13 +4,13 @@ plugins { id 'google-test' id 'edu.wpi.first.wpilib.repositories.WPILibRepositoriesPlugin' version '2025.0' id 'edu.wpi.first.NativeUtils' version '2026.0.1' - id "edu.wpi.first.GradleRIO" version "2026.1.1-beta-1" // Version supplied here + id "edu.wpi.first.GradleRIO" version "2026.1.1" // Version supplied here id 'edu.wpi.first.GradleJni' version '1.1.0' id 'edu.wpi.first.GradleVsCode' version '2.1.0' id "com.diffplug.spotless" version "6.11.0" } -ext.wpilibVersion = "2026.1.1-beta-1" // and again here, thanks gradle.... +ext.wpilibVersion = "2026.1.1" // and again here, thanks gradle.... ext.releasePath = "$buildDir/maven" ext.pubVersion = System.getenv("releaseVersion") ?: System.getenv("releaseName") ?: "test" From eecaba9a61f3f62f4105284771368097698d5d6d Mon Sep 17 00:00:00 2001 From: twisterjafla Date: Sun, 11 Jan 2026 23:48:47 -0700 Subject: [PATCH 09/62] made changes --- .../simulation/ironmaple/simulation/Goal.java | 86 ++-- .../simulation/IntakeSimulation.java | 84 ++-- .../ironmaple/simulation/SimulatedArena.java | 95 ++-- .../crescendo2024/CrescendoAmp.java | 3 +- .../crescendo2024/CrescendoSpeaker.java | 3 +- .../rebuilt2026/Arena2026Rebuilt.java | 419 ++++++++++++++++++ .../rebuilt2026/RebuiltFuelOnField.java | 25 ++ .../rebuilt2026/RebuiltFuelOnFly.java | 62 +++ .../rebuilt2026/RebuiltHub.java | 123 +++++ .../rebuilt2026/RebuiltOutpost.java | 196 ++++++++ .../ReefscapeBargeSimulation.java | 3 +- .../ReefscapeProcessorSimulation.java | 3 +- .../reefscape2025/ReefscapeReefBranch.java | 3 +- .../ironmaple/utils/FieldMirroringUtils.java | 8 + 14 files changed, 974 insertions(+), 139 deletions(-) create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/Arena2026Rebuilt.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltFuelOnField.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltFuelOnFly.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltHub.java create mode 100644 yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltOutpost.java diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java index 42d5327..4ca3343 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java @@ -1,18 +1,18 @@ package swervelib.simulation.ironmaple.simulation; +import static edu.wpi.first.units.Units.Degrees; + import edu.wpi.first.math.geometry.Pose3d; import edu.wpi.first.math.geometry.Rotation3d; import edu.wpi.first.math.geometry.Translation3d; import edu.wpi.first.units.Units; import edu.wpi.first.units.measure.Angle; import edu.wpi.first.units.measure.Distance; -import org.dyn4j.geometry.Rectangle; -import org.dyn4j.geometry.Vector2; import swervelib.simulation.ironmaple.simulation.gamepieces.GamePiece; import java.util.List; - -import static edu.wpi.first.units.Units.Degrees; +import org.dyn4j.geometry.Rectangle; +import org.dyn4j.geometry.Vector2; /** * @@ -35,6 +35,11 @@ public abstract class Goal implements SimulatedArena.Simulatable { protected Rotation3d pieceAngle = null; protected Angle pieceAngleTolerance = Angle.ofBaseUnits(15, Degrees); + protected final double minZ; + protected final double maxZ; + + protected final boolean allowGrounded; + /** * * @@ -52,14 +57,15 @@ public static Rotation3d flipRotation(Rotation3d toFlip) { * *

    Creates a goal object

    * - * @param arena The host arena of this goal - * @param xDimension The x dimension of the default box collider. - * @param yDimension The y dimension of the default box collider. - * @param height The height or z dimension of the default box collider. + * @param arena The host arena of this goal + * @param xDimension The x dimension of the default box collider. + * @param yDimension The y dimension of the default box collider. + * @param height The height or z dimension of the default box collider. * @param gamePieceType the string game piece type to be handled by this goal. - * @param position The position of this goal. - * @param isBlue Wether this is a blue goal or a red one. - * @param max How many pieces can be scored in this goal. + * @param position The position of this goal. + * @param isBlue Wether this is a blue goal or a red one. + * @param max How many pieces can be scored in this goal. + * @param allowsGrounded Wether or not grounded pieces can be scored in this goal */ public Goal( SimulatedArena arena, @@ -69,7 +75,8 @@ public Goal( String gamePieceType, Translation3d position, boolean isBlue, - int max) { + int max, + boolean allowGrounded) { xyBox = new Rectangle(xDimension.in(Units.Meters), yDimension.in(Units.Meters)); this.height = height; @@ -80,6 +87,11 @@ public Goal( this.elevation = position.getMeasureZ(); this.isBlue = isBlue; + this.allowGrounded = allowGrounded; + + minZ = elevation.in(Units.Meters); + maxZ = minZ + height.in(Units.Meters); + xyBox.translate(new Vector2(position.getX(), position.getY())); } @@ -88,13 +100,14 @@ public Goal( * *

    Creates a goal object with no scoring max.

    * - * @param arena The host arena of this goal. - * @param xDimension The x dimension of the default box collider. - * @param yDimension The y dimension of the default box collider. - * @param height The height or z dimension of the default box collider. + * @param arena The host arena of this goal. + * @param xDimension The x dimension of the default box collider. + * @param yDimension The y dimension of the default box collider. + * @param height The height or z dimension of the default box collider. * @param gamePieceType the string game piece type to be handled by this goal. - * @param position The position of this goal. - * @param isBlue Wether this is a blue goal or a red one. + * @param position The position of this goal. + * @param isBlue Wether this is a blue goal or a red one. + * @param allowsGrounded Wether or not grounded pieces can be scored in this goal */ public Goal( SimulatedArena arena, @@ -103,8 +116,9 @@ public Goal( Distance height, String gamePieceType, Translation3d position, - boolean isBlue) { - this(arena, xDimension, yDimension, height, gamePieceType, position, isBlue, 99999); + boolean isBlue, + boolean allowsGrounded) { + this(arena, xDimension, yDimension, height, gamePieceType, position, isBlue, 99999, allowsGrounded); } /** @@ -118,7 +132,7 @@ public void simulationSubTick(int subTickNum) { /// Use list filtering for more efficient bulk checking. // Get all pieces of our type as a list. arena.getGamePiecesByType(gamePieceType).stream() - .filter(gamePiece -> !checkGrounded(gamePiece)) + .filter(gamePiece -> checkGrounded(gamePiece)) .filter(this::checkValidity) .limit(max - gamePieceCount) // Only score what we can .forEach( @@ -134,7 +148,7 @@ public void simulationSubTick(int subTickNum) { * *

    Sets the angle to be used when checking game piece rotation. * - * @param angle The angle that pieces should have when interacting with this goal + * @param angle The angle that pieces should have when interacting with this goal * @param angleTolerance The tolerance to be used in checking said angle. */ public void setNeededAngle(Rotation3d angle, Angle angleTolerance) { @@ -176,20 +190,20 @@ protected boolean checkValidity(GamePiece gamePiece) { /** * * - *

    Checks whether the submitted game piece is grounded

    + *

    Checks whether the submitted game piece is grounded and if this is acceptable

    * * @param gamePiece The game piece to have its groundedness checked. - * @return Whether the piece is grounded. + * @return Whether the piece is acceptable for this goal. */ protected boolean checkGrounded(GamePiece gamePiece) { - return gamePiece.isGrounded(); + return allowGrounded || !gamePiece.isGrounded(); } /** * * *

    Checks wether or not the submitted game piece has a rotation able to be scored in this goal

    - *

    + * * By default the rotation needed and tolerance may be set using the {@link Goal#setNeededAngle(Rotation3d, Angle)} * function. However rotation checks may be handled differently by some children making this not apply. Additionally * be aware that this function only supports pitch and yaw, not role. If support for roll is needed a custom @@ -208,13 +222,13 @@ protected boolean checkRotation(GamePiece gamePiece) { flipRotation(gamePiece.getPose3d().getRotation()).minus(pieceAngle); return new Rotation3d(Degrees.of(0), normalDiff.getMeasureZ(), normalDiff.getMeasureZ()) - .getMeasureAngle() - .in(Degrees) - < pieceAngleTolerance.in(Degrees) + .getMeasureAngle() + .in(Degrees) + < pieceAngleTolerance.in(Degrees) || new Rotation3d(Degrees.of(0), flippedDiff.getMeasureZ(), flippedDiff.getMeasureZ()) - .getMeasureAngle() - .in(Degrees) - < pieceAngleTolerance.in(Degrees); + .getMeasureAngle() + .in(Degrees) + < pieceAngleTolerance.in(Degrees); } /** @@ -228,8 +242,6 @@ protected boolean checkRotation(GamePiece gamePiece) { protected boolean checkCollision(GamePiece gamePiece) { // Call our values just once. var pose = gamePiece.getPose3d(); - double minZ = elevation.in(Units.Meters); - double maxZ = minZ + height.in(Units.Meters); return xyBox.contains(new Vector2(pose.getX(), pose.getY())) && pose.getZ() >= minZ && pose.getZ() <= maxZ; } @@ -238,7 +250,7 @@ protected boolean checkCollision(GamePiece gamePiece) { * * *

    Function to check wether the velocity of potential game pieces is acceptable.

    - *

    + * * The default implementation of this function always returns true so any velocity checks will need to be * implemented by children classes. * @@ -273,7 +285,7 @@ public boolean isFull() { * * *

    Adds points when a piece has been successfully scored in this goal

    - *

    + * * Since this function is the only trigger called when a piece is scored it may handle other small things outside of * adding points. */ @@ -285,7 +297,7 @@ public boolean isFull() { *

    Displays game pieces to advantage scope if applicable.

    * * @param drawList a list of {@link Pose3d} objects used to visualize the positions of the game pieces on - * AdvantageScope + * AdvantageScope */ public abstract void draw(List drawList); diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/IntakeSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/IntakeSimulation.java index dab313d..5988a2d 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/IntakeSimulation.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/IntakeSimulation.java @@ -1,7 +1,17 @@ package swervelib.simulation.ironmaple.simulation; +import static edu.wpi.first.units.Units.Meters; + import edu.wpi.first.math.MathUtil; import edu.wpi.first.units.measure.Distance; +import swervelib.simulation.ironmaple.simulation.drivesims.AbstractDriveTrainSimulation; +import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation; +import swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025.ReefscapeCoralAlgaeStack; + +import java.util.ArrayDeque; +import java.util.Objects; +import java.util.Queue; +import java.util.function.Predicate; import org.dyn4j.collision.CollisionBody; import org.dyn4j.collision.Fixture; import org.dyn4j.dynamics.Body; @@ -13,16 +23,6 @@ import org.dyn4j.geometry.Vector2; import org.dyn4j.world.ContactCollisionData; import org.dyn4j.world.listener.ContactListener; -import swervelib.simulation.ironmaple.simulation.drivesims.AbstractDriveTrainSimulation; -import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation; -import swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025.ReefscapeCoralAlgaeStack; - -import java.util.ArrayDeque; -import java.util.Objects; -import java.util.Queue; -import java.util.function.Predicate; - -import static edu.wpi.first.units.Units.Meters; /** * @@ -43,9 +43,9 @@ *

    A game piece is collected if the following conditions are met: * *

      - *
    • 1. The type of the game piece ({@link swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation#type}) + *
    • 1. The type of the game piece ({@link org.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation#type}) * matches {@link #targetedGamePieceType}. - *
    • 2. The {@link swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation} is in contact with the intake + *
    • 2. The {@link org.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation} is in contact with the intake * (and not other parts of the robot). *
    • 3. The intake is turned on via {@link #startIntake()}. *
    • 4. The number of game pieces in the intake ({@link #gamePiecesInIntakeCount}) is less than {@link #capacity}. @@ -79,10 +79,10 @@ public enum IntakeSide { *

      This typically represents an In-The-Frame (ITF) Intake. * * @param targetedGamePieceType the type of game pieces that this intake can collect - * @param driveTrainSimulation the chassis to which this intake is attached - * @param width the width of the intake - * @param side the side of the chassis where the intake is attached - * @param capacity the maximum number of game pieces that the intake can hold + * @param driveTrainSimulation the chassis to which this intake is attached + * @param width the width of the intake + * @param side the side of the chassis where the intake is attached + * @param capacity the maximum number of game pieces that the intake can hold */ public static IntakeSimulation InTheFrameIntake( String targetedGamePieceType, @@ -101,11 +101,11 @@ public static IntakeSimulation InTheFrameIntake( *

      This typically represents an Over-The-Bumper (OTB) Intake. * * @param targetedGamePieceType the type of game pieces that this intake can collect - * @param driveTrainSimulation the chassis to which this intake is attached - * @param width the valid width of the intake - * @param lengthExtended the length the intake extends out from the chassis when activated - * @param side the side of the chassis where the intake is attached - * @param capacity the maximum number of game pieces that the intake can hold + * @param driveTrainSimulation the chassis to which this intake is attached + * @param width the valid width of the intake + * @param lengthExtended the length the intake extends out from the chassis when activated + * @param side the side of the chassis where the intake is attached + * @param capacity the maximum number of game pieces that the intake can hold * @return a new instance of {@link IntakeSimulation} that extends over the bumper */ public static IntakeSimulation OverTheBumperIntake( @@ -154,9 +154,9 @@ private static Rectangle getIntakeRectangle( *

      This constructor initializes an intake with a custom shape that is used when the intake is fully extended. * * @param targetedGamePieceType the type of game pieces that this intake can collect - * @param driveTrainSimulation the chassis to which this intake is attached - * @param shape the shape of the intake when fully extended, represented as a {@link Convex} object - * @param capacity the maximum number of game pieces that the intake can hold + * @param driveTrainSimulation the chassis to which this intake is attached + * @param shape the shape of the intake when fully extended, represented as a {@link Convex} object + * @param capacity the maximum number of game pieces that the intake can hold */ public IntakeSimulation( String targetedGamePieceType, @@ -257,6 +257,22 @@ public boolean addGamePieceToIntake() { return toReturn; } + /** + * + * + *

      Adds a number of game pieces to the intake.

      + * + * If the number of pieces added would drive the intake above capacity the intake will only add pieces up to max. + * + * @param piecesToAdd The number of pieces to add too the intake. + * @return Wether or not all game pieces could be added to the intake. Just because this returns false does not mean + * that no pieces were added. + */ + public boolean addGamePiecesToIntake(int piecesToAdd) { + boolean toReturn = gamePiecesInIntakeCount + piecesToAdd <= capacity; + gamePiecesInIntakeCount = Math.max(gamePiecesInIntakeCount + piecesToAdd, capacity); + return toReturn; + } /** * @@ -318,28 +334,22 @@ private void flagGamePieceForRemoval(GamePieceOnFieldSimulation gamePiece) { /* functions not used */ @Override - public void persist(ContactCollisionData collision, Contact oldContact, Contact newContact) { - } + public void persist(ContactCollisionData collision, Contact oldContact, Contact newContact) {} @Override - public void end(ContactCollisionData collision, Contact contact) { - } + public void end(ContactCollisionData collision, Contact contact) {} @Override - public void destroyed(ContactCollisionData collision, Contact contact) { - } + public void destroyed(ContactCollisionData collision, Contact contact) {} @Override - public void collision(ContactCollisionData collision) { - } + public void collision(ContactCollisionData collision) {} @Override - public void preSolve(ContactCollisionData collision, Contact contact) { - } + public void preSolve(ContactCollisionData collision, Contact contact) {} @Override - public void postSolve(ContactCollisionData collision, SolvedContact contact) { - } + public void postSolve(ContactCollisionData collision, SolvedContact contact) {} } /** @@ -405,7 +415,7 @@ public boolean isRunning() { * intake, and the intake is turned on, and it is the target game piece. * * @param customIntakeCondition a {@link Predicate} representing the custom condition for intake eligibility of game - * pieces on the field + * pieces on the field */ public void setCustomIntakeCondition(Predicate customIntakeCondition) { this.customIntakeCondition = customIntakeCondition; diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java index cf916a4..fc04e28 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java @@ -1,9 +1,15 @@ package swervelib.simulation.ironmaple.simulation; +import static edu.wpi.first.units.Units.Seconds; + import edu.wpi.first.math.geometry.Pose2d; import edu.wpi.first.math.geometry.Pose3d; import edu.wpi.first.math.geometry.Translation2d; -import edu.wpi.first.networktables.*; +import edu.wpi.first.networktables.BooleanPublisher; +import edu.wpi.first.networktables.BooleanSubscriber; +import edu.wpi.first.networktables.DoublePublisher; +import edu.wpi.first.networktables.NetworkTable; +import edu.wpi.first.networktables.NetworkTableInstance; import edu.wpi.first.units.Units; import edu.wpi.first.units.measure.Time; import edu.wpi.first.wpilibj.DriverStation; @@ -11,25 +17,22 @@ import edu.wpi.first.wpilibj.RobotBase; import edu.wpi.first.wpilibj.TimedRobot; import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; -import org.dyn4j.dynamics.Body; -import org.dyn4j.dynamics.BodyFixture; -import org.dyn4j.geometry.Convex; -import org.dyn4j.geometry.Geometry; -import org.dyn4j.geometry.MassType; -import org.dyn4j.world.PhysicsWorld; -import org.dyn4j.world.World; import swervelib.simulation.ironmaple.simulation.drivesims.AbstractDriveTrainSimulation; import swervelib.simulation.ironmaple.simulation.gamepieces.GamePiece; import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation; import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceProjectile; import swervelib.simulation.ironmaple.simulation.motorsims.SimulatedBattery; -import swervelib.simulation.ironmaple.simulation.opponentsim.OpponentManager; -import swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025.Arena2025Reefscape; +import swervelib.simulation.ironmaple.simulation.seasonspecific.rebuilt2026.Arena2026Rebuilt; import swervelib.simulation.ironmaple.utils.mathutils.GeometryConvertor; import java.util.*; - -import static edu.wpi.first.units.Units.Seconds; +import org.dyn4j.dynamics.Body; +import org.dyn4j.dynamics.BodyFixture; +import org.dyn4j.geometry.Convex; +import org.dyn4j.geometry.Geometry; +import org.dyn4j.geometry.MassType; +import org.dyn4j.world.PhysicsWorld; +import org.dyn4j.world.World; /** * @@ -57,9 +60,7 @@ *
    */ public abstract class SimulatedArena { - /** - * Whether to allow the simulation to run a real robot This feature is HIGHLY RECOMMENDED to be turned OFF - */ + /** Whether to allow the simulation to run a real robot This feature is HIGHLY RECOMMENDED to be turned OFF */ public static boolean ALLOW_CREATION_ON_REAL_ROBOT = false; protected int redScore = 0; @@ -92,7 +93,6 @@ public abstract class SimulatedArena { Boolean shouldPublishMatchBreakdown = true; private static SimulatedArena instance = null; - protected OpponentManager opponentManager; /** * @@ -109,7 +109,7 @@ public static SimulatedArena getInstance() { throw new IllegalStateException( "MapleSim is running on a real robot! (If you would actually want that, set SimulatedArena.ALLOW_CREATION_ON_REAL_ROBOT to true)."); - if (instance == null) instance = new Arena2025Reefscape(); + if (instance == null) instance = new Arena2026Rebuilt(); return instance; } @@ -128,22 +128,17 @@ public static SimulatedArena getInstance() { * @param newInstance the new simulation arena instance to override the current one */ public static void overrideInstance(SimulatedArena newInstance) { - if (instance != null) instance = new Arena2025Reefscape(); + if (instance != null) instance = new Arena2026Rebuilt(); instance = newInstance; } - /** - * The number of sub-ticks the simulator will run in each robot period. - */ + /** The number of sub-ticks the simulator will run in each robot period. */ private static int SIMULATION_SUB_TICKS_IN_1_PERIOD = 5; public static int getSimulationSubTicksIn1Period() { return SIMULATION_SUB_TICKS_IN_1_PERIOD; } - - /** - * The period length of each sub-tick, in seconds. - */ + /** The period length of each sub-tick, in seconds. */ private static Time SIMULATION_DT = Seconds.of(TimedRobot.kDefaultPeriod / SIMULATION_SUB_TICKS_IN_1_PERIOD); public static Time getSimulationDt() { @@ -174,32 +169,13 @@ public int getScore(Alliance allianceColor) { return getScore(allianceColor == Alliance.Blue); } - /** - * Adds an OpponentManager to the SimulatedArena. - * - * @param opponentManager the OpponentManager to use. - */ - protected void withOpponentManager(OpponentManager opponentManager) { - this.opponentManager = opponentManager; - } - - /** - * Gets the current {@link OpponentManager}. Use casting for your Arena, some arenas may override with castless - * methods. - * - * @return the {@link OpponentManager} in use. - */ - public OpponentManager getOpponentManager() { - return opponentManager; - } - /** * * *

    Adds to the score of the specified team

    * * @param isBlue Wether to add to the blue or red team score. - * @param toAdd How many points to add. + * @param toAdd How many points to add. */ public void addToScore(boolean isBlue, int toAdd) { if (isBlue) blueScore += toAdd; @@ -225,10 +201,10 @@ public void addToScore(boolean isBlue, int toAdd) { * *

    It is also recommended to keep the simulation frequency above 200 Hz for accurate simulation results. * - * @param robotPeriod the time between two calls of {@link #simulationPeriodic()}, usually obtained from - * {@link TimedRobot#getPeriod()} + * @param robotPeriod the time between two calls of {@link #simulationPeriodic()}, usually obtained from + * {@link TimedRobot#getPeriod()} * @param simulationSubTicksPerPeriod the number of Iterations, or {@link #simulationSubTick(int)} that the - * simulation runs per each call to {@link #simulationPeriodic()} + * simulation runs per each call to {@link #simulationPeriodic()} */ public static synchronized void overrideSimulationTimings(Time robotPeriod, int simulationSubTicksPerPeriod) { SIMULATION_SUB_TICKS_IN_1_PERIOD = simulationSubTicksPerPeriod; @@ -314,7 +290,7 @@ public synchronized void addCustomSimulation(Simulatable simulatable) { *

    The intake simulation should be bound to an {@link AbstractDriveTrainSimulation} and becomes part of its * collision space. * - *

    This method immediately starts the {@link swervelib.simulation.ironmaple.simulation.IntakeSimulation.GamePieceContactListener}, + *

    This method immediately starts the {@link org.ironmaple.simulation.IntakeSimulation.GamePieceContactListener}, * which listens for contact between the intake and any game piece. * * @param intakeSimulation the intake simulation to be registered @@ -407,8 +383,8 @@ protected void publishBreakdown() { *

    replaces or adds a value to the match scoring breakdown published to network tables

    * * @param isBlueTeam Wether to add to the blue teams match breakdown or the red teams match breakdown - * @param valueKey The name of the value to be added - * @param value The value to be added + * @param valueKey The name of the value to be added + * @param value The value to be added */ public void replaceValueInMatchBreakDown(boolean isBlueTeam, String valueKey, Double value) { if (isBlueTeam) blueScoringBreakdown.put(valueKey, value); @@ -434,8 +410,8 @@ public void setupValueForMatchBreakdown(String valueKey) { *

    replaces or adds a value to the match scoring breakdown published to network tables

    * * @param isBlueTeam Wether to add to the blue teams match breakdown or the red teams match breakdown - * @param valueKey The name of the value to be added - * @param value The value to be added + * @param valueKey The name of the value to be added + * @param value The value to be added */ public void replaceValueInMatchBreakDown(boolean isBlueTeam, String valueKey, Integer value) { replaceValueInMatchBreakDown(isBlueTeam, valueKey, (double) value); @@ -448,8 +424,8 @@ public void replaceValueInMatchBreakDown(boolean isBlueTeam, String valueKey, In * be defaulted to 0 and then added too * * @param isBlueTeam Wether to add to the blue teams match breakdown or the red teams match breakdown - * @param ValueKey The name of the value to be added too - * @param toAdd how much to be added to specified value + * @param ValueKey The name of the value to be added too + * @param toAdd how much to be added to specified value */ public void addValueToMatchBreakdown(boolean isBlueTeam, String ValueKey, Double toAdd) { if (isBlueTeam) { @@ -468,8 +444,8 @@ public void addValueToMatchBreakdown(boolean isBlueTeam, String ValueKey, Double * be defaulted to 0 and then added too * * @param isBlueTeam Wether to add to the blue teams match breakdown or the red teams match breakdown - * @param valueKey The name of the value to be added too - * @param toAdd how much to be added to specified value + * @param valueKey The name of the value to be added too + * @param toAdd how much to be added to specified value */ public void addValueToMatchBreakdown(boolean isBlueTeam, String valueKey, int toAdd) { addValueToMatchBreakdown(isBlueTeam, valueKey, (double) toAdd); @@ -671,7 +647,7 @@ public synchronized Set gamePieceLaunched() { * *
      *
    • The type is determined in the constructor of {@link GamePieceOnFieldSimulation}. - *
    • For example, {@link swervelib.simulation.ironmaple.simulation.seasonspecific.crescendo2024.CrescendoNoteOnField} has the + *
    • For example, {@link org.ironmaple.simulation.seasonspecific.crescendo2024.CrescendoNoteOnField} has the * type "Note". *
    * @@ -707,8 +683,7 @@ public synchronized Pose3d[] getGamePiecesArrayByType(String type) { */ public synchronized List getGamePiecesByType(String type) { final List gamePiecesPoses = new ArrayList<>(this.gamePieces); - gamePiecesPoses.stream().filter( - gamePiece -> !Objects.equals(gamePiece.getType(), type)); + gamePiecesPoses.stream().filter(gamePiece -> !Objects.equals(gamePiece.getType(), type)); return gamePiecesPoses; } diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoAmp.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoAmp.java index 56cf8ea..d40a7a7 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoAmp.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoAmp.java @@ -43,7 +43,8 @@ public CrescendoAmp(Arena2024Crescendo arena, boolean isBlue) { Centimeters.of(46), "Note", isBlue ? blueAmpPose : redAmpPose, - isBlue); + isBlue, + false); crescendoArena = arena; diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoSpeaker.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoSpeaker.java index 6e9b872..c3f8fa7 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoSpeaker.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoSpeaker.java @@ -43,7 +43,8 @@ public CrescendoSpeaker(Arena2024Crescendo arena, boolean isBlue) { Centimeters.of(100), "Note", isBlue ? blueSpeakerPose : redSpeakerPose, - isBlue); + isBlue, + false); crescendoArena = arena; StructPublisher speakerPosePublisher = NetworkTableInstance.getDefault() diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/Arena2026Rebuilt.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/Arena2026Rebuilt.java new file mode 100644 index 0000000..ea04913 --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/Arena2026Rebuilt.java @@ -0,0 +1,419 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.rebuilt2026; + +import static edu.wpi.first.units.Units.Degrees; +import static edu.wpi.first.units.Units.Inches; +import static edu.wpi.first.units.Units.Meters; +import static edu.wpi.first.units.Units.MetersPerSecond; + +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.geometry.Translation2d; +import edu.wpi.first.math.kinematics.ChassisSpeeds; +import edu.wpi.first.networktables.BooleanPublisher; +import edu.wpi.first.networktables.DoublePublisher; +import edu.wpi.first.units.Units; +import edu.wpi.first.units.measure.Angle; +import edu.wpi.first.units.measure.Distance; +import edu.wpi.first.units.measure.LinearVelocity; +import edu.wpi.first.wpilibj.DriverStation; +import edu.wpi.first.wpilibj.DriverStation.Alliance; +import swervelib.simulation.ironmaple.simulation.SimulatedArena; +import swervelib.simulation.ironmaple.simulation.SimulatedArena.FieldMap; + +import java.util.List; +import org.dyn4j.dynamics.Settings; + +public class Arena2026Rebuilt extends SimulatedArena { + + protected boolean shouldClock = true; + + protected double clock = 0; + protected boolean blueIsOnClock = Math.random() < 0.5; + + protected DoublePublisher phaseClockPublisher = + genericInfoTable.getDoubleTopic("Time left in current phase").publish(); + + protected BooleanPublisher redActivePublisher = + redTable.getBooleanTopic("Red is active").publish(); + protected BooleanPublisher blueActivePublisher = + blueTable.getBooleanTopic("Blue is active").publish(); + + protected RebuiltHub blueHub; + protected RebuiltHub redHub; + + protected RebuiltOutpost blueOutpost; + protected RebuiltOutpost redOutpost; + + protected boolean isInEfficiencyMode = true; + + protected static Translation2d centerPieceBottomRightCorner = new Translation2d(7.35737, 1.724406); + protected static Translation2d redDepotBottomRightCorner = new Translation2d(0.02, 5.53); + protected static Translation2d blueDepotBottomRightCorner = new Translation2d(16.0274, 1.646936); + + /** the obstacles on the 2024 competition field */ + public static final class RebuiltFieldObstaclesMap extends FieldMap { + private static final double FIELD_WIDTH = 16.54; + + public RebuiltFieldObstaclesMap(boolean AddRampCollider) { + super.addBorderLine(new Translation2d(0, 0), new Translation2d(0, 8.052)); + + // red wall + super.addBorderLine(new Translation2d(16.540988, 0), new Translation2d(16.540988, 8.052)); + + // upper walls + super.addBorderLine(new Translation2d(16.540988, 8.052), new Translation2d(0, 8.052)); + + // lower walls + super.addBorderLine(new Translation2d(0, 0), new Translation2d(16.540988, 0)); + + // Trench Walls (47 inch height, 12 inch width) + double trenchWallDistX = + Inches.of(120.0).in(Meters) + Inches.of(47.0 / 2).in(Meters); + + double trenchWallDistY = Inches.of(73.0).in(Meters) + + Inches.of(47.0 / 2).in(Meters) + + Inches.of(6).in(Meters); + + super.addRectangularObstacle( + Inches.of(53).in(Meters), + Inches.of(12).in(Meters), + new Pose2d(8.27 - trenchWallDistX, 4.035 - trenchWallDistY, Rotation2d.kZero)); + super.addRectangularObstacle( + Inches.of(53).in(Meters), + Inches.of(12).in(Meters), + new Pose2d(8.27 + trenchWallDistX, 4.035 - trenchWallDistY, Rotation2d.kZero)); + super.addRectangularObstacle( + Inches.of(53).in(Meters), + Inches.of(12).in(Meters), + new Pose2d(8.27 - trenchWallDistX, 4.035 + trenchWallDistY, Rotation2d.kZero)); + super.addRectangularObstacle( + Inches.of(53).in(Meters), + Inches.of(12).in(Meters), + new Pose2d(8.27 - trenchWallDistX, 4.035 - trenchWallDistY, Rotation2d.kZero)); + + // poles of the tower + super.addRectangularObstacle( + Inches.of(2).in(Meters), + Inches.of(47).in(Meters), + new Pose2d(new Translation2d(Inches.of(42), Inches.of(159)), new Rotation2d())); + + super.addRectangularObstacle( + Inches.of(2).in(Meters), + Inches.of(47).in(Meters), + new Pose2d(new Translation2d(Inches.of(651 - 42), Inches.of(170)), new Rotation2d())); + + // Colliders to describe the hub plus ramps + if (AddRampCollider) { + super.addRectangularObstacle( + Inches.of(47).in(Meters), + Inches.of(217).in(Meters), + new Pose2d(RebuiltHub.blueHubPose.toTranslation2d(), new Rotation2d())); + + super.addRectangularObstacle( + Inches.of(47).in(Meters), + Inches.of(217).in(Meters), + new Pose2d(RebuiltHub.redHubPose.toTranslation2d(), new Rotation2d())); + } + + // Colliders to describe just the hub + else { + super.addRectangularObstacle( + Inches.of(47).in(Meters), + Inches.of(47).in(Meters), + new Pose2d(RebuiltHub.blueHubPose.toTranslation2d(), new Rotation2d())); + + super.addRectangularObstacle( + Inches.of(47).in(Meters), + Inches.of(47).in(Meters), + new Pose2d(RebuiltHub.redHubPose.toTranslation2d(), new Rotation2d())); + } + } + } + /** + * + * + *

    Creates an Arena for the 2026 FRC game rebuilt

    + * + *

    This will create an Arena with the ramp areas marked as inaccessible. If you would like to change that use + * {@link #Arena2026Rebuilt(boolean)}. Additionally due to performance issues the arena will not spawn all fuel by + * default. If you would like to change this use {@link #setEfficiencyMode(boolean)} + */ + public Arena2026Rebuilt() { + this(true); + } + + /** + * + * + *

    Creates an Arena for the 2026 FRC game rebuilt

    + * + *

    Due to the nature of maple sim they can not be fully simulated and so ether must be non existent or treated as + * full colliders. This behavior can be changed with the AddRampCollider variable. Additionally due to performance + * issues the arena will not spawn all fuel by default. If you would like to change this use + * {@link #setEfficiencyMode(boolean)} + * + * @param AddRampCollider Whether or not the ramps should be added as colliders. + */ + public Arena2026Rebuilt(boolean AddRampCollider) { + super(new RebuiltFieldObstaclesMap(AddRampCollider)); + + Settings settings = physicsWorld.getSettings(); + + // settings.setVelocityConstraintSolverIterations(3); + // settings.setPositionConstraintSolverIterations(2); + settings.setMinimumAtRestTime(0.02); + + physicsWorld.setSettings(settings); + + blueHub = new RebuiltHub(this, true); + super.addCustomSimulation(blueHub); + + redHub = new RebuiltHub(this, false); + super.addCustomSimulation(redHub); + + blueOutpost = new RebuiltOutpost(this, true); + super.addCustomSimulation(blueOutpost); + + redOutpost = new RebuiltOutpost(this, false); + super.addCustomSimulation(redOutpost); + } + + /** + * + * + *

    Generates a random number within a range centered on 0 with a variance set by the parameter.

    + * + * @param variance the length of range used to generate the random number. + * @return A random number in range. + */ + public static double randomInRange(double variance) { + return (Math.random() - 0.5) * variance; + } + + /** + * + * + *

    Adds a game piece too the arena with a certain random variance.

    + * + * This method is useful for certain spawners like the return cutes on the hub to prevent the game pieces from being + * returned to the exact same position every time. + * + * @param info the info of the game piece + * @param robotPosition the position of the robot (not the shooter) at the time of launching the game piece + * @param shooterPositionOnRobot the translation from the shooter's position to the robot's center, in the robot's + * frame of reference + * @param chassisSpeedsFieldRelative the field-relative velocity of the robot chassis when launching the game piece, + * influencing the initial velocity of the game piece + * @param shooterFacing the direction in which the shooter is facing at launch + * @param initialHeight the initial height of the game piece when launched, i.e., the height of the shooter from the + * ground + * @param launchingSpeed the speed at which the game piece is launch + * @param shooterAngle the pitch angle of the shooter when launching + * @param xVariance The max amount of variance that should be added too the x coordinate of the game piece. + * @param yVariance The max amount of variance that should be added too the y coordinate of the game piece. + * @param yawVariance The max amount of variance that should be added too the yaw of the game piece. + * @param speedVariance The max amount of variance that should be added too the speed of the game piece. + * @param pitchVariance The max amount of variance that should be added too the pitch of the game piece. + */ + public void addPieceWithVariance( + Translation2d piecePose, + Rotation2d yaw, + Distance height, + LinearVelocity speed, + Angle pitch, + double xVariance, + double yVariance, + double yawVariance, + double speedVariance, + double pitchVariance) { + addGamePieceProjectile(new RebuiltFuelOnFly( + piecePose.plus(new Translation2d(randomInRange(xVariance), randomInRange(yVariance))), + new Translation2d(), + new ChassisSpeeds(), + yaw.plus(Rotation2d.fromDegrees(randomInRange(yawVariance))), + height, + speed.plus(MetersPerSecond.of(randomInRange(speedVariance))), + Degrees.of(pitch.in(Degrees) + randomInRange(pitchVariance)))); + } + + @Override + public void placeGamePiecesOnField() { + blueOutpost.reset(); + redOutpost.reset(); + + for (int x = 0; x < 12; x += 1) { + for (int y = 0; y < 30; y += isInEfficiencyMode ? 3 : 1) { + addGamePiece(new RebuiltFuelOnField(centerPieceBottomRightCorner.plus( + new Translation2d(Inches.of(5.991 * x), Inches.of(5.95 * y))))); + } + } + + boolean isOnBlue = !DriverStation.getAlliance().isEmpty() + && DriverStation.getAlliance().get() == Alliance.Blue; + + if (isOnBlue || !isInEfficiencyMode) { + for (int x = 0; x < 4; x++) { + for (int y = 0; y < 6; y++) { + addGamePiece(new RebuiltFuelOnField(blueDepotBottomRightCorner.plus( + new Translation2d(Inches.of(5.991 * x), Inches.of(5.95 * y))))); + } + } + } + + if (!isOnBlue || !isInEfficiencyMode) { + for (int x = 0; x < 4; x++) { + for (int y = 0; y < 6; y++) { + addGamePiece(new RebuiltFuelOnField(redDepotBottomRightCorner.plus( + new Translation2d(Inches.of(5.991 * x), Inches.of(5.95 * y))))); + } + } + } + + setupValueForMatchBreakdown("CurrentFuelInOutpost"); + setupValueForMatchBreakdown("TotalFuelInOutpost"); + setupValueForMatchBreakdown("TotalFuelInHub"); + setupValueForMatchBreakdown("WastedFuel"); + } + + @Override + public synchronized List getGamePiecesPosesByType(String type) { + List poses = super.getGamePiecesPosesByType(type); + + blueOutpost.draw(poses); + redOutpost.draw(poses); + + return poses; + } + + @Override + public void simulationSubTick(int tickNum) { + + clock -= getSimulationDt().in(Units.Seconds); + + if (clock <= 0) { + clock = 25; + blueIsOnClock = !blueIsOnClock; + } + + super.simulationSubTick(tickNum); + + blueActivePublisher.set(isActive(true)); + redActivePublisher.set(isActive(false)); + + phaseClockPublisher.set((shouldClock || DriverStation.isAutonomous() ? clock : null)); + } + + /** + * + * + *

    Returns wether the specified team currently has an active HUB

    + * + * This function returns true during autonomous or when shouldClock (set by {@link #setShouldRunClock(boolean)}) is + * false. + * + * @param isBlue Wether to check the blue or red alliance. + * @return Wether the specified alliance's HUB is currently active + */ + public boolean isActive(boolean isBlue) { + if (isBlue) { + return blueIsOnClock || DriverStation.isAutonomous() || !shouldClock; + } else { + return !blueIsOnClock || DriverStation.isAutonomous() || !shouldClock; + } + } + + /** + * + * + *

    Used to determine wether the arena should time which goal is active.

    + * + * When this is set too false both goals will always be set to active. Ths can be useful for testing or too simulate + * endgame. + * + * @param shouldRunClock + */ + public void setShouldRunClock(boolean shouldRunClock) { + shouldClock = shouldRunClock; + } + + /** + * + * + *

    Dumps game pieces from the specified outpost.

    + * + * This function will dump up to 24 game pieces, dependent on how many game pieces are currently stored in the + * outpost. For more manual control of the game pieces in the outpost use {@link #outpostThrow(boolean, Rotation2d, + * Angle, LinearVelocity)}. To have a human player attempt to throw a game piece into the hub use + * {@link #outpostThrowForGoal(boolean)}. + * + * @param isBlue wether to dump the blue or red outpost + */ + public void outpostDump(boolean isBlue) { + (isBlue ? blueOutpost : redOutpost).dump(); + } + + /** + * + * + *

    Attempts too throw a game piece at the specified goal.

    + * + *

    This method comes with variance built in (to simulate human inconsistency) and will therefore only hit about + * half the time. Additionally if the hub does not have game pieces stored this method will not do anything. If you + * would like to manually control how the human player throws game pieces use {@link #outpostThrow(boolean, + * Rotation2d, Angle, LinearVelocity)} + * + * @param isBlue whether too throw for the blue or red HUB. + */ + public void outpostThrowForGoal(boolean isBlue) { + (isBlue ? blueOutpost : redOutpost).throwForGoal(); + } + + /** + * + * + *

    Throws a game piece from the outpost at the specified angle and speed.

    + * + *

    This method comes with variance built in (to simulate human inconsistency). Additionally if the hub does not + * have game pieces stored this method will not do anything. If you would like to have the human player throw at the + * hub use {@link #outpostThrowForGoal(boolean)} + * + * @param isBlue Wether too throw from the blue or red OUTPOST. + * @param throwYaw The yaw at which too throw the ball. + * @param throwPitch The pitch at which too throw the ball. + * @param speed The speed at which too throw the ball. + */ + public void outpostThrow(boolean isBlue, Rotation2d throwYaw, Angle throwPitch, LinearVelocity speed) { + (isBlue ? blueOutpost : redOutpost).throwFuel(throwYaw, throwPitch, speed); + } + + /** + * + * + *

    Determines wether the arena is in efficiency mode

    + * + *

    For changes too take effect call {@link #resetFieldForAuto()}.

    + * + *

    Efficiency mode reduces the amount of game pieces on the field too increase performance. MapleSim was not + * designed with 400 game pieces in mind and so can struggle with the large number of game pieces present in + * rebuilt. + * + * @param efficiencyMode Wether efficiency mode should be on or off. + */ + public void setEfficiencyMode(boolean efficiencyMode) { + isInEfficiencyMode = efficiencyMode; + } + + /** + * + * + *

    Returns wether or not the arena is in Efficiency mode

    + * + * For more information see {@link #setEfficiencyMode(boolean)} + * + * @return Wether or not the Arena is in efficiency mode. + */ + public boolean getEfficiencyMode() { + return isInEfficiencyMode; + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltFuelOnField.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltFuelOnField.java new file mode 100644 index 0000000..31714bf --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltFuelOnField.java @@ -0,0 +1,25 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.rebuilt2026; + +import static edu.wpi.first.units.Units.*; + +import edu.wpi.first.math.geometry.Pose2d; +import edu.wpi.first.math.geometry.Rotation2d; +import edu.wpi.first.math.geometry.Translation2d; +import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation; +import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation.GamePieceInfo; + +import org.dyn4j.geometry.Circle; + +/** + * + * + *

    Represents an Fuel in the 2026 rebuilt game.

    +*/ +public class RebuiltFuelOnField extends GamePieceOnFieldSimulation { + public static final GamePieceInfo REBUILT_FUEL_INFO = new GamePieceInfo( + "Fuel", new Circle(Centimeters.of(7.5).in(Meters)), Centimeter.of(15), Kilograms.of(2.13), 1.8, 5, 0.8); + + public RebuiltFuelOnField(Translation2d initialPosition) { + super(REBUILT_FUEL_INFO, new Pose2d(initialPosition, new Rotation2d())); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltFuelOnFly.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltFuelOnFly.java new file mode 100644 index 0000000..608201c --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltFuelOnFly.java @@ -0,0 +1,62 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.rebuilt2026; + +import static edu.wpi.first.units.Units.Inches; +import static edu.wpi.first.units.Units.Meters; + +import edu.wpi.first.math.geometry.Rotation2d; +import edu.wpi.first.math.geometry.Translation2d; +import edu.wpi.first.math.kinematics.ChassisSpeeds; +import edu.wpi.first.units.measure.Angle; +import edu.wpi.first.units.measure.Distance; +import edu.wpi.first.units.measure.LinearVelocity; +import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceProjectile; +import swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025.ReefscapeAlgaeOnField; + +/** + * + * + *

    Represents an FUEL launched into the air.

    + * + *

    This class models a {@link RebuiltFuelOnField} launched into the air. + * + *

    The simulation will determine if the FUEL hits its target—the HUB. + * + *

    The user can specify a callback using {@link #setHitNetCallBack(Runnable)}, which will be triggered when the FUEL + * hits the HUB. + */ +public class RebuiltFuelOnFly extends GamePieceProjectile { + private static Runnable hitNetCallBack = () -> {}; + + /** + * + * + *

    Specifies a callback for when any fuel launched into the air hits the hub.

    + * + * @param callBack a {@link Runnable} to be invoked when an fuel hits the hub + */ + public static void setHitNetCallBack(Runnable callBack) { + hitNetCallBack = callBack; + } + + public RebuiltFuelOnFly( + Translation2d robotPosition, + Translation2d shooterPositionOnRobot, + ChassisSpeeds chassisSpeeds, + Rotation2d shooterFacing, + Distance initialHeight, + LinearVelocity launchingSpeed, + Angle shooterAngle) { + super( + RebuiltFuelOnField.REBUILT_FUEL_INFO, + robotPosition, + shooterPositionOnRobot, + chassisSpeeds, + shooterFacing, + initialHeight, + launchingSpeed, + shooterAngle); + + super.withTouchGroundHeight(Inches.of(3).in(Meters)); + super.enableBecomesGamePieceOnFieldAfterTouchGround(); + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltHub.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltHub.java new file mode 100644 index 0000000..36a685e --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltHub.java @@ -0,0 +1,123 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.rebuilt2026; + +import static edu.wpi.first.units.Units.Degrees; +import static edu.wpi.first.units.Units.Inches; +import static edu.wpi.first.units.Units.MetersPerSecond; + +import edu.wpi.first.math.geometry.*; +import edu.wpi.first.networktables.NetworkTableInstance; +import edu.wpi.first.networktables.StructPublisher; +import swervelib.simulation.ironmaple.simulation.Goal; +import swervelib.simulation.ironmaple.simulation.gamepieces.GamePiece; +import swervelib.simulation.ironmaple.utils.FieldMirroringUtils; + +import java.util.*; + +/** + * + * + *

    Simulates a HUBs on the field.

    + * + *

    This class simulates the HUBs on the field where FUELs can be scored. Whether it + * is active can be determined by using {@link Arena2026Rebuilt#isActive(boolean)} + */ +public class RebuiltHub extends Goal { + + protected static final Translation3d blueHubPose = new Translation3d(4.5974, 4.034536, 1.5748); + protected static final Translation3d redHubPose = new Translation3d(11.938, 4.034536, 1.5748); + protected static final Pose3d[] blueShootPoses = { + new Pose3d( + blueHubPose.plus(new Translation3d(0.5969, 0.447675, -0.5)), + new Rotation3d(Degrees.of(0), Degrees.of(-15), Degrees.of(33.75))), + new Pose3d( + blueHubPose.plus(new Translation3d(0.5969, 0.149225, -0.5)), + new Rotation3d(Degrees.of(0), Degrees.of(-15), Degrees.of(11.25))), + new Pose3d( + blueHubPose.plus(new Translation3d(0.5969, -0.149225, -0.5)), + new Rotation3d(Degrees.of(0), Degrees.of(-15), Degrees.of(11.25))), + new Pose3d( + blueHubPose.plus(new Translation3d(0.5969, -0.447675, -0.5)), + new Rotation3d(Degrees.of(0), Degrees.of(-15), Degrees.of(-33.75))) + }; + + public static final double GoalRadius = 0.5969; + static final Random rng = new Random(); + + public static final Pose3d[] redShootPoses = Arrays.stream(blueShootPoses) + .map(FieldMirroringUtils::flip) + .map((Pose3d toRotate) -> { + return toRotate.rotateBy(new Rotation3d(Rotation2d.fromDegrees(180))); + }) + .toArray(Pose3d[]::new); + + StructPublisher posePublisher; + protected final Arena2026Rebuilt arena; + + /** + * + * + *

    Creates an HUB of the specified color.

    + * + * @param arena The host arena of this HUB. + * @param isBlue Wether this is the blue HUB or the red one. + */ + public RebuiltHub(Arena2026Rebuilt arena, boolean isBlue) { + super( + arena, + Inches.of(47), + Inches.of(47), + Inches.of(10), + "Fuel", + isBlue ? blueHubPose : redHubPose, + isBlue, + false); + + this.arena = arena; + StructPublisher HubPosePublisher = NetworkTableInstance.getDefault() + .getStructTopic(isBlue ? "BlueHub" : "RedHub", Pose3d.struct) + .publish(); + HubPosePublisher.set(new Pose3d(position, new Rotation3d())); + } + + @Override + protected boolean checkVel(GamePiece gamePiece) { + return gamePiece.getVelocity3dMPS().getZ() < 0; + } + + @Override + protected boolean checkCollision(GamePiece GamePiece) { + System.out.println(Math.pow(GamePiece.getPose3d().getX() - position.getX(), 2) + + Math.pow(GamePiece.getPose3d().getY() - position.getY(), 2) + + Math.pow(GamePiece.getPose3d().getZ() - position.getZ(), 2)); + return Math.pow(GamePiece.getPose3d().getX() - position.getX(), 2) + + Math.pow(GamePiece.getPose3d().getY() - position.getY(), 2) + + Math.pow(GamePiece.getPose3d().getZ() - position.getZ(), 2) + < Math.pow(GoalRadius, 2); + } + + @Override + protected void addPoints() { + arena.addValueToMatchBreakdown(isBlue, "TotalFuelInHub", 1); + arena.addValueToMatchBreakdown(isBlue, "WastedFuel", arena.isActive(isBlue) ? 0 : 1); + arena.addToScore(isBlue, arena.isActive(isBlue) ? 1 : 0); + + Pose3d shootPose = isBlue ? blueShootPoses[rng.nextInt(4)] : redShootPoses[rng.nextInt(4)]; + + arena.addPieceWithVariance( + shootPose.getTranslation().toTranslation2d(), + new Rotation2d(shootPose.getRotation().getZ()), + shootPose.getMeasureZ(), + MetersPerSecond.of(2), + shootPose.getRotation().getMeasureY(), + 0, + 0.02, + 15, + 0.2, + 5); + } + + @Override + public void draw(List drawList) { + return; + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltOutpost.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltOutpost.java new file mode 100644 index 0000000..8986dab --- /dev/null +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltOutpost.java @@ -0,0 +1,196 @@ +package swervelib.simulation.ironmaple.simulation.seasonspecific.rebuilt2026; + +import static edu.wpi.first.units.Units.Centimeters; +import static edu.wpi.first.units.Units.Degrees; +import static edu.wpi.first.units.Units.Inches; +import static edu.wpi.first.units.Units.Meters; +import static edu.wpi.first.units.Units.MetersPerSecond; + +import edu.wpi.first.math.geometry.*; +import edu.wpi.first.networktables.NetworkTableInstance; +import edu.wpi.first.networktables.StructPublisher; +import edu.wpi.first.units.measure.Angle; +import edu.wpi.first.units.measure.LinearVelocity; +import swervelib.simulation.ironmaple.simulation.Goal; + +import java.util.*; + +/** + * + * + *

    Simulates a OUTPOSTs on the field.

    + * + *

    This class simulates a outpost on the field where fuel can be scored. It has a store of fuel which can be added + * too by scoring in it. This fuel can then be dumped via {@link #dump()} or + * {@link Arena2026Rebuilt#outpostDump(boolean)}, thrown at the goal via {@link #throwForGoal()} or + * {@link Arena2026Rebuilt#outpostThrowForGoal(boolean)}, or thrown with specific parameters via + * {@link #throwFuel(Rotation2d, Angle, LinearVelocity)} or {@link Arena2026Rebuilt#outpostThrow(boolean, Rotation2d, + * Angle, LinearVelocity)}, + */ +public class RebuiltOutpost extends Goal { + + protected static final Translation3d redOutpostPose = new Translation3d(16.621, 7.403338, 0); + protected static final Translation3d redLaunchPose = new Translation3d(16, 8.2, 0); + protected static final Translation3d redDumpPose = new Translation3d(16.421, 7.2, 0); + + protected static final Translation3d blueOutpostPose = new Translation3d(0, 0.665988, 0); + protected static final Translation3d blueDumpPose = new Translation3d(0.2, 0.665988, 0); + protected static final Translation3d blueLaunchPose = new Translation3d(0.665988, -0.254, 0); + + protected static final Translation3d redRenderPose = new Translation3d(16.640988, 7.7, 0.844502); + protected static final Translation3d blueRenderPose = new Translation3d(-0.12, 0.325, 0.844502); + + StructPublisher posePublisher; + + protected Arena2026Rebuilt arena; + + /** + * + * + *

    Creates an outpost of the specified color.

    + * + * @param arena The host arena of this outpost. + * @param isBlue Wether this is the blue outpost or the red one. + */ + public RebuiltOutpost(Arena2026Rebuilt arena, boolean isBlue) { + super( + arena, + Centimeters.of(3), + Inches.of(21), + Centimeters.of(10), + "Fuel", + isBlue ? blueOutpostPose : redOutpostPose, + isBlue, + true); + + this.arena = arena; + gamePieceCount = 24; + + StructPublisher OutpostPublisher = NetworkTableInstance.getDefault() + .getStructTopic(isBlue ? "BlueOutpost" : "RedOutpost", Pose3d.struct) + .publish(); + + StructPublisher OutpostThrowPublisher = NetworkTableInstance.getDefault() + .getStructTopic(isBlue ? "BlueOutpostThrow" : "RedOutpostThrow", Pose3d.struct) + .publish(); + StructPublisher OutpostDumpPublisher = NetworkTableInstance.getDefault() + .getStructTopic(isBlue ? "BlueOutpostDump" : "RedOutpostDump", Pose3d.struct) + .publish(); + + OutpostPublisher.set(new Pose3d(position, new Rotation3d())); + OutpostDumpPublisher.set(new Pose3d(isBlue ? blueDumpPose : redDumpPose, new Rotation3d())); + OutpostThrowPublisher.set(new Pose3d(isBlue ? blueLaunchPose : redLaunchPose, new Rotation3d())); + } + + @Override + protected void addPoints() { + arena.addValueToMatchBreakdown(isBlue, "TotalFuelInOutpost", 1); + this.gamePieceCount++; + } + + @Override + public void simulationSubTick(int subTickNum) { + super.simulationSubTick(subTickNum); + arena.replaceValueInMatchBreakDown(isBlue, "CurrentFuelInOutpost", gamePieceCount); + } + + @Override + public void draw(List drawList) { + + int count = 0; + for (int col = 0; col < 5 && count < gamePieceCount; col++) { + for (int row = 0; row < 5 && count < gamePieceCount; row++) { + count++; + if (isBlue) { + drawList.add(new Pose3d( + blueRenderPose.plus( + new Translation3d(Inches.of(-6 * col), Inches.of(6 * row), Inches.of(1.3 * col))), + new Rotation3d())); + } else { + drawList.add(new Pose3d( + redRenderPose.plus( + new Translation3d(Inches.of(6 * col), Inches.of(-6 * row), Inches.of(1.3 * col))), + new Rotation3d())); + } + } + } + } + + /** Resets the outposts internal fuel counter too 24. */ + public void reset() { + gamePieceCount = 24; + } + + /** + * + * + *

    Attempts too throw a game piece at the specified goal.

    + * + *

    This method comes with variance built in (to simulate human inconsistency) and will therefore only hit about + * half the time. Additionally if the hub does not have game pieces stored this method will not do anything. If you + * would like to manually control how the human player throws game pieces use {@link #outpostThrow(boolean, + * Rotation2d, Angle, LinearVelocity)} + */ + public void throwForGoal() { + throwFuel( + isBlue ? Rotation2d.fromDegrees(45) : Rotation2d.fromDegrees(220), + Degrees.of(75), + MetersPerSecond.of(11.2)); + } + + /** + * + * + *

    Dumps game pieces from the specified outpost.

    + * + * This function will dump up to 24 game pieces, dependent on how many game pieces are currently stored in the + * outpost. For more manual control of the game pieces in the outpost use {@link #outpostThrow(boolean, Rotation2d, + * Angle, LinearVelocity)}. To have a human player attempt to throw a game piece into the hub use + * {@link #outpostThrowForGoal(boolean)}. + */ + public void dump() { + for (int i = 0; i < 24 && gamePieceCount > 0; i++) { + gamePieceCount--; + this.arena.addPieceWithVariance( + isBlue ? blueDumpPose.toTranslation2d() : redDumpPose.toTranslation2d(), + new Rotation2d(), + Meters.of(1.7), + isBlue ? MetersPerSecond.of(2) : MetersPerSecond.of(-2), + Degrees.of(0), + 0, + 0.2, + 5, + 0.2, + 5.0); + } + } + + /** + * + * + *

    Throws a game piece from the outpost at the specified angle and speed.

    + * + *

    This method comes with variance built in (to simulate human inconsistency). Additionally if the hub does not + * have game pieces stored this method will not do anything. If you would like to have the human player throw at the + * hub use {@link #outpostThrowForGoal(boolean)} + * + * @param throwYaw The yaw at which too throw the ball. + * @param throwPitch The pitch at which too throw the ball. + */ + public void throwFuel(Rotation2d yaw, Angle pitch, LinearVelocity speed) { + if (gamePieceCount > 0) { + gamePieceCount--; + arena.addPieceWithVariance( + isBlue ? blueLaunchPose.toTranslation2d() : redLaunchPose.toTranslation2d(), + yaw, + Meters.of(1.7), + speed, + pitch, + 0, + 0, + 15, + 2, + 5); + } + } +} diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeBargeSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeBargeSimulation.java index 728ca35..afe13a9 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeBargeSimulation.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeBargeSimulation.java @@ -44,7 +44,8 @@ public ReefscapeBargeSimulation(Arena2025Reefscape arena, boolean isBlue) { Centimeters.of(100), "Algae", isBlue ? blueBargePose : redBargePose, - isBlue); + isBlue, + false); StructPublisher heldAlgaePublisher = NetworkTableInstance.getDefault() .getStructTopic(isBlue ? "BlueBarge" : "RedBarge", Pose3d.struct) diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeProcessorSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeProcessorSimulation.java index 08f0fff..229eb5b 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeProcessorSimulation.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeProcessorSimulation.java @@ -43,7 +43,8 @@ public ReefscapeProcessorSimulation(Arena2025Reefscape arena, boolean isBlue) { Centimeters.of(100), "Algae", isBlue ? blueProcessorPose : redProcessorPose, - isBlue); + isBlue, + true); StructPublisher heldAlgaePublisher = NetworkTableInstance.getDefault() .getStructTopic(isBlue ? "BlueProcessor" : "RedProcessor", Pose3d.struct) diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefBranch.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefBranch.java index cbe3668..9beb6d2 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefBranch.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefBranch.java @@ -110,7 +110,8 @@ public ReefscapeReefBranch(Arena2025Reefscape arena, boolean isBlue, int level, "Coral", getPoseOfBranchAt(isBlue, level, column), isBlue, - level == 0 ? 2 : 1); + level == 0 ? 2 : 1, + false); if (level == 1 || level == 2) { if (isBlue) { diff --git a/yagsl/java/swervelib/simulation/ironmaple/utils/FieldMirroringUtils.java b/yagsl/java/swervelib/simulation/ironmaple/utils/FieldMirroringUtils.java index 76759d1..2c0f9ae 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/utils/FieldMirroringUtils.java +++ b/yagsl/java/swervelib/simulation/ironmaple/utils/FieldMirroringUtils.java @@ -1,6 +1,7 @@ package swervelib.simulation.ironmaple.utils; 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.geometry.Translation2d; import edu.wpi.first.math.geometry.Translation3d; @@ -28,6 +29,13 @@ public static Translation2d flip(Translation2d translation) { return new Translation2d(FIELD_WIDTH - translation.getX(), FIELD_HEIGHT - translation.getY()); } + public static Pose3d flip(Pose3d toFlip) { + return new Pose3d( + new Translation3d(FIELD_WIDTH - toFlip.getX(), FIELD_HEIGHT - toFlip.getY(), toFlip.getZ()), + toFlip.getRotation()); + } + + public static Translation3d toCurrentAllianceTranslation(Translation3d translation3dAtBlueSide) { final Translation2d translation3dAtCurrentAlliance = toCurrentAllianceTranslation(translation3dAtBlueSide.toTranslation2d()); From 745470964609136c40855d6f07e1edc35061dc20 Mon Sep 17 00:00:00 2001 From: twisterjafla Date: Mon, 12 Jan 2026 00:06:12 -0700 Subject: [PATCH 10/62] fixed issue --- .../ironmaple/simulation/SimulatedArena.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java index fc04e28..28b926c 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java @@ -22,6 +22,7 @@ import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation; import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceProjectile; import swervelib.simulation.ironmaple.simulation.motorsims.SimulatedBattery; +import swervelib.simulation.ironmaple.simulation.opponentsim.OpponentManager; import swervelib.simulation.ironmaple.simulation.seasonspecific.rebuilt2026.Arena2026Rebuilt; import swervelib.simulation.ironmaple.utils.mathutils.GeometryConvertor; @@ -93,6 +94,7 @@ public abstract class SimulatedArena { Boolean shouldPublishMatchBreakdown = true; private static SimulatedArena instance = null; + protected OpponentManager opponentManager; /** * @@ -169,6 +171,27 @@ public int getScore(Alliance allianceColor) { return getScore(allianceColor == Alliance.Blue); } + + /** + * Adds an OpponentManager to the SimulatedArena. + * + * @param opponentManager the OpponentManager to use. + */ + protected void withOpponentManager(OpponentManager opponentManager) { + this.opponentManager = opponentManager; + } + + /** + * Gets the current {@link OpponentManager}. Use casting for your Arena, some arenas may override with castless + * methods. + * + * @return the {@link OpponentManager} in use. + */ + public OpponentManager getOpponentManager() { + return opponentManager; + } + + /** * * From 2ec8861de3200702d86368b373998302bf53cd5c Mon Sep 17 00:00:00 2001 From: twisterjafla Date: Mon, 12 Jan 2026 02:06:20 -0700 Subject: [PATCH 11/62] clock update --- .../rebuilt2026/Arena2026Rebuilt.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/Arena2026Rebuilt.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/Arena2026Rebuilt.java index ea04913..0b432ca 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/Arena2026Rebuilt.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/Arena2026Rebuilt.java @@ -289,19 +289,23 @@ public synchronized List getGamePiecesPosesByType(String type) { @Override public void simulationSubTick(int tickNum) { - clock -= getSimulationDt().in(Units.Seconds); + if (shouldClock && !DriverStation.isAutonomous() && DriverStation.isEnabled()) { + clock -= getSimulationDt().in(Units.Seconds); - if (clock <= 0) { + if (clock <= 0) { + clock = 25; + blueIsOnClock = !blueIsOnClock; + } + } else { clock = 25; - blueIsOnClock = !blueIsOnClock; } + phaseClockPublisher.set((clock)); + super.simulationSubTick(tickNum); blueActivePublisher.set(isActive(true)); redActivePublisher.set(isActive(false)); - - phaseClockPublisher.set((shouldClock || DriverStation.isAutonomous() ? clock : null)); } /** From a250e20b3a465d05646080cc8fe7569197185c3c Mon Sep 17 00:00:00 2001 From: T Grinch <10247070+thenetworkgrinch@users.noreply.github.com> Date: Mon, 12 Jan 2026 12:28:47 -0600 Subject: [PATCH 12/62] Update yagsl.json --- vendordep/yagsl.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendordep/yagsl.json b/vendordep/yagsl.json index 9433483..4e30d1e 100644 --- a/vendordep/yagsl.json +++ b/vendordep/yagsl.json @@ -2,7 +2,7 @@ "fileName": "yagsl-${version}.json", "name": "YAGSL", "version": "${version}", - "frcYear": "2026beta", + "frcYear": "2026", "uuid": "1ccce5a4-acd2-4d18-bca3-4b8047188400", "mavenUrls": [ "https://yet-another-software-suite.github.io/YAGSL/releases/", From b89407b2c65f161fddb8376ebb2837fa5d3a83fd Mon Sep 17 00:00:00 2001 From: thenetworkgrinch Date: Mon, 12 Jan 2026 16:46:55 -0600 Subject: [PATCH 13/62] Updated vendordep json to point to full 2026 vdeps. Included reduxlib, thriftylib, and studica. Signed-off-by: thenetworkgrinch --- .../vendordeps/ReduxLib-2026.1.1.json | 69 ++ .../vendordeps/Studica-2026.0.0.json | 71 ++ .../vendordeps/StudicaLib-2026.0.0.json | 71 ++ .../vendordeps/ThriftyLib-2026.0.0.json | 18 + .../vendordeps/ReduxLib-2026.1.1.json | 69 ++ .../vendordeps/Studica-2026.0.0.json | 71 ++ .../vendordeps/StudicaLib-2026.0.0.json | 71 ++ .../vendordeps/ThriftyLib-2026.0.0.json | 18 + .../vendordeps/ReduxLib-2026.1.1.json | 69 ++ .../vendordeps/Studica-2026.0.0.json | 71 ++ .../vendordeps/StudicaLib-2026.0.0.json | 71 ++ .../vendordeps/ThriftyLib-2026.0.0.json | 18 + .../vendordeps/ReduxLib-2026.1.1.json | 69 ++ .../vendordeps/Studica-2026.0.0.json | 71 ++ .../vendordeps/StudicaLib-2026.0.0.json | 71 ++ .../vendordeps/ThriftyLib-2026.0.0.json | 18 + .../vendordeps/ReduxLib-2026.1.1.json | 69 ++ .../vendordeps/Studica-2026.0.0.json | 71 ++ .../vendordeps/StudicaLib-2026.0.0.json | 71 ++ .../vendordeps/ThriftyLib-2026.0.0.json | 18 + .../vendordeps/ReduxLib-2026.1.1.json | 69 ++ .../vendordeps/Studica-2026.0.0.json | 71 ++ .../vendordeps/StudicaLib-2026.0.0.json | 71 ++ .../vendordeps/ThriftyLib-2026.0.0.json | 18 + .../vendordeps/ReduxLib-2026.1.1.json | 69 ++ .../vendordeps/Studica-2026.0.0.json | 71 ++ .../vendordeps/StudicaLib-2026.0.0.json | 71 ++ .../vendordeps/ThriftyLib-2026.0.0.json | 18 + vendordep/vendordeps/ReduxLib-2026.1.1.json | 69 ++ vendordep/vendordeps/Studica-2026.0.0.json | 71 ++ vendordep/vendordeps/StudicaLib-2026.0.0.json | 71 ++ vendordep/vendordeps/ThriftyLib-2026.0.0.json | 18 + vendordep/yagsl.json | 30 +- .../swervelib/encoders/CanAndMagSwerve.java | 226 ++-- .../encoders/ThriftyNovaEncoderSwerve.java | 282 ++--- .../java/swervelib/imu/CanandgyroSwerve.java | 282 ++--- yagsl/java/swervelib/imu/NavX3Swerve.java | 342 +++--- yagsl/java/swervelib/imu/NavXSwerve.java | 336 ++--- .../swervelib/motors/ThriftyNovaSwerve.java | 1078 ++++++++--------- .../swervelib/parser/json/DeviceJson.java | 66 +- .../swervelib/parser/json/ModuleJson.java | 12 +- 41 files changed, 3162 insertions(+), 1324 deletions(-) create mode 100644 examples/clock_drive_drivebase/vendordeps/ReduxLib-2026.1.1.json create mode 100644 examples/clock_drive_drivebase/vendordeps/Studica-2026.0.0.json create mode 100644 examples/clock_drive_drivebase/vendordeps/StudicaLib-2026.0.0.json create mode 100644 examples/clock_drive_drivebase/vendordeps/ThriftyLib-2026.0.0.json create mode 100644 examples/drivebase_only_2026/vendordeps/ReduxLib-2026.1.1.json create mode 100644 examples/drivebase_only_2026/vendordeps/Studica-2026.0.0.json create mode 100644 examples/drivebase_only_2026/vendordeps/StudicaLib-2026.0.0.json create mode 100644 examples/drivebase_only_2026/vendordeps/ThriftyLib-2026.0.0.json create mode 100644 examples/drivebase_with_PathPlanner/vendordeps/ReduxLib-2026.1.1.json create mode 100644 examples/drivebase_with_PathPlanner/vendordeps/Studica-2026.0.0.json create mode 100644 examples/drivebase_with_PathPlanner/vendordeps/StudicaLib-2026.0.0.json create mode 100644 examples/drivebase_with_PathPlanner/vendordeps/ThriftyLib-2026.0.0.json create mode 100644 examples/drivebase_with_PhotonVision/vendordeps/ReduxLib-2026.1.1.json create mode 100644 examples/drivebase_with_PhotonVision/vendordeps/Studica-2026.0.0.json create mode 100644 examples/drivebase_with_PhotonVision/vendordeps/StudicaLib-2026.0.0.json create mode 100644 examples/drivebase_with_PhotonVision/vendordeps/ThriftyLib-2026.0.0.json create mode 100644 examples/field_oriented_drivebase/vendordeps/ReduxLib-2026.1.1.json create mode 100644 examples/field_oriented_drivebase/vendordeps/Studica-2026.0.0.json create mode 100644 examples/field_oriented_drivebase/vendordeps/StudicaLib-2026.0.0.json create mode 100644 examples/field_oriented_drivebase/vendordeps/ThriftyLib-2026.0.0.json create mode 100644 examples/full_example/vendordeps/ReduxLib-2026.1.1.json create mode 100644 examples/full_example/vendordeps/Studica-2026.0.0.json create mode 100644 examples/full_example/vendordeps/StudicaLib-2026.0.0.json create mode 100644 examples/full_example/vendordeps/ThriftyLib-2026.0.0.json create mode 100644 examples/robot_relative_drivebase/vendordeps/ReduxLib-2026.1.1.json create mode 100644 examples/robot_relative_drivebase/vendordeps/Studica-2026.0.0.json create mode 100644 examples/robot_relative_drivebase/vendordeps/StudicaLib-2026.0.0.json create mode 100644 examples/robot_relative_drivebase/vendordeps/ThriftyLib-2026.0.0.json create mode 100644 vendordep/vendordeps/ReduxLib-2026.1.1.json create mode 100644 vendordep/vendordeps/Studica-2026.0.0.json create mode 100644 vendordep/vendordeps/StudicaLib-2026.0.0.json create mode 100644 vendordep/vendordeps/ThriftyLib-2026.0.0.json diff --git a/examples/clock_drive_drivebase/vendordeps/ReduxLib-2026.1.1.json b/examples/clock_drive_drivebase/vendordeps/ReduxLib-2026.1.1.json new file mode 100644 index 0000000..3dba1cb --- /dev/null +++ b/examples/clock_drive_drivebase/vendordeps/ReduxLib-2026.1.1.json @@ -0,0 +1,69 @@ +{ + "fileName": "ReduxLib-2026.1.1.json", + "name": "ReduxLib", + "version": "2026.1.1", + "frcYear": "2026", + "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", + "mavenUrls": [ + "https://maven.reduxrobotics.com/" + ], + "jsonUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2026.json", + "javaDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-java", + "version": "2026.1.1" + } + ], + "jniDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-fifo", + "version": "2026.1.1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-cpp", + "version": "2026.1.1", + "libName": "ReduxLib", + "headerClassifier": "headers", + "sourcesClassifier": "sources", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + }, + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-fifo", + "version": "2026.1.1", + "libName": "reduxfifo", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + } + ] +} \ No newline at end of file diff --git a/examples/clock_drive_drivebase/vendordeps/Studica-2026.0.0.json b/examples/clock_drive_drivebase/vendordeps/Studica-2026.0.0.json new file mode 100644 index 0000000..7a1f3bb --- /dev/null +++ b/examples/clock_drive_drivebase/vendordeps/Studica-2026.0.0.json @@ -0,0 +1,71 @@ +{ + "fileName": "Studica.json", + "name": "Studica", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-cpp", + "version": "2026.0.0", + "libName": "Studica", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0", + "libName": "StudicaDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} diff --git a/examples/clock_drive_drivebase/vendordeps/StudicaLib-2026.0.0.json b/examples/clock_drive_drivebase/vendordeps/StudicaLib-2026.0.0.json new file mode 100644 index 0000000..7447f74 --- /dev/null +++ b/examples/clock_drive_drivebase/vendordeps/StudicaLib-2026.0.0.json @@ -0,0 +1,71 @@ +{ + "fileName": "StudicaLib.json", + "name": "StudicaLib", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.0.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.0", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-cpp", + "version": "2026.0.0", + "libName": "StudicaLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.0", + "libName": "StudicaLibDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} diff --git a/examples/clock_drive_drivebase/vendordeps/ThriftyLib-2026.0.0.json b/examples/clock_drive_drivebase/vendordeps/ThriftyLib-2026.0.0.json new file mode 100644 index 0000000..56ff85e --- /dev/null +++ b/examples/clock_drive_drivebase/vendordeps/ThriftyLib-2026.0.0.json @@ -0,0 +1,18 @@ +{ + "fileName": "ThriftyLib-2026.0.0.json", + "name": "ThriftyLib", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", + "mavenUrls": ["https://docs.home.thethriftybot.com"], + "jsonUrl": "https://docs.home.thethriftybot.com/ThriftyLib-2026.json", + "javaDependencies": [ + { + "groupId": "com.thethriftybot.frc", + "artifactId": "ThriftyLib-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [], + "cppDependencies": [] +} diff --git a/examples/drivebase_only_2026/vendordeps/ReduxLib-2026.1.1.json b/examples/drivebase_only_2026/vendordeps/ReduxLib-2026.1.1.json new file mode 100644 index 0000000..3dba1cb --- /dev/null +++ b/examples/drivebase_only_2026/vendordeps/ReduxLib-2026.1.1.json @@ -0,0 +1,69 @@ +{ + "fileName": "ReduxLib-2026.1.1.json", + "name": "ReduxLib", + "version": "2026.1.1", + "frcYear": "2026", + "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", + "mavenUrls": [ + "https://maven.reduxrobotics.com/" + ], + "jsonUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2026.json", + "javaDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-java", + "version": "2026.1.1" + } + ], + "jniDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-fifo", + "version": "2026.1.1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-cpp", + "version": "2026.1.1", + "libName": "ReduxLib", + "headerClassifier": "headers", + "sourcesClassifier": "sources", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + }, + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-fifo", + "version": "2026.1.1", + "libName": "reduxfifo", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + } + ] +} \ No newline at end of file diff --git a/examples/drivebase_only_2026/vendordeps/Studica-2026.0.0.json b/examples/drivebase_only_2026/vendordeps/Studica-2026.0.0.json new file mode 100644 index 0000000..7a1f3bb --- /dev/null +++ b/examples/drivebase_only_2026/vendordeps/Studica-2026.0.0.json @@ -0,0 +1,71 @@ +{ + "fileName": "Studica.json", + "name": "Studica", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-cpp", + "version": "2026.0.0", + "libName": "Studica", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0", + "libName": "StudicaDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} diff --git a/examples/drivebase_only_2026/vendordeps/StudicaLib-2026.0.0.json b/examples/drivebase_only_2026/vendordeps/StudicaLib-2026.0.0.json new file mode 100644 index 0000000..7447f74 --- /dev/null +++ b/examples/drivebase_only_2026/vendordeps/StudicaLib-2026.0.0.json @@ -0,0 +1,71 @@ +{ + "fileName": "StudicaLib.json", + "name": "StudicaLib", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.0.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.0", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-cpp", + "version": "2026.0.0", + "libName": "StudicaLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.0", + "libName": "StudicaLibDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} diff --git a/examples/drivebase_only_2026/vendordeps/ThriftyLib-2026.0.0.json b/examples/drivebase_only_2026/vendordeps/ThriftyLib-2026.0.0.json new file mode 100644 index 0000000..56ff85e --- /dev/null +++ b/examples/drivebase_only_2026/vendordeps/ThriftyLib-2026.0.0.json @@ -0,0 +1,18 @@ +{ + "fileName": "ThriftyLib-2026.0.0.json", + "name": "ThriftyLib", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", + "mavenUrls": ["https://docs.home.thethriftybot.com"], + "jsonUrl": "https://docs.home.thethriftybot.com/ThriftyLib-2026.json", + "javaDependencies": [ + { + "groupId": "com.thethriftybot.frc", + "artifactId": "ThriftyLib-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [], + "cppDependencies": [] +} diff --git a/examples/drivebase_with_PathPlanner/vendordeps/ReduxLib-2026.1.1.json b/examples/drivebase_with_PathPlanner/vendordeps/ReduxLib-2026.1.1.json new file mode 100644 index 0000000..3dba1cb --- /dev/null +++ b/examples/drivebase_with_PathPlanner/vendordeps/ReduxLib-2026.1.1.json @@ -0,0 +1,69 @@ +{ + "fileName": "ReduxLib-2026.1.1.json", + "name": "ReduxLib", + "version": "2026.1.1", + "frcYear": "2026", + "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", + "mavenUrls": [ + "https://maven.reduxrobotics.com/" + ], + "jsonUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2026.json", + "javaDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-java", + "version": "2026.1.1" + } + ], + "jniDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-fifo", + "version": "2026.1.1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-cpp", + "version": "2026.1.1", + "libName": "ReduxLib", + "headerClassifier": "headers", + "sourcesClassifier": "sources", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + }, + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-fifo", + "version": "2026.1.1", + "libName": "reduxfifo", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + } + ] +} \ No newline at end of file diff --git a/examples/drivebase_with_PathPlanner/vendordeps/Studica-2026.0.0.json b/examples/drivebase_with_PathPlanner/vendordeps/Studica-2026.0.0.json new file mode 100644 index 0000000..7a1f3bb --- /dev/null +++ b/examples/drivebase_with_PathPlanner/vendordeps/Studica-2026.0.0.json @@ -0,0 +1,71 @@ +{ + "fileName": "Studica.json", + "name": "Studica", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-cpp", + "version": "2026.0.0", + "libName": "Studica", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0", + "libName": "StudicaDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} diff --git a/examples/drivebase_with_PathPlanner/vendordeps/StudicaLib-2026.0.0.json b/examples/drivebase_with_PathPlanner/vendordeps/StudicaLib-2026.0.0.json new file mode 100644 index 0000000..7447f74 --- /dev/null +++ b/examples/drivebase_with_PathPlanner/vendordeps/StudicaLib-2026.0.0.json @@ -0,0 +1,71 @@ +{ + "fileName": "StudicaLib.json", + "name": "StudicaLib", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.0.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.0", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-cpp", + "version": "2026.0.0", + "libName": "StudicaLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.0", + "libName": "StudicaLibDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} diff --git a/examples/drivebase_with_PathPlanner/vendordeps/ThriftyLib-2026.0.0.json b/examples/drivebase_with_PathPlanner/vendordeps/ThriftyLib-2026.0.0.json new file mode 100644 index 0000000..56ff85e --- /dev/null +++ b/examples/drivebase_with_PathPlanner/vendordeps/ThriftyLib-2026.0.0.json @@ -0,0 +1,18 @@ +{ + "fileName": "ThriftyLib-2026.0.0.json", + "name": "ThriftyLib", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", + "mavenUrls": ["https://docs.home.thethriftybot.com"], + "jsonUrl": "https://docs.home.thethriftybot.com/ThriftyLib-2026.json", + "javaDependencies": [ + { + "groupId": "com.thethriftybot.frc", + "artifactId": "ThriftyLib-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [], + "cppDependencies": [] +} diff --git a/examples/drivebase_with_PhotonVision/vendordeps/ReduxLib-2026.1.1.json b/examples/drivebase_with_PhotonVision/vendordeps/ReduxLib-2026.1.1.json new file mode 100644 index 0000000..3dba1cb --- /dev/null +++ b/examples/drivebase_with_PhotonVision/vendordeps/ReduxLib-2026.1.1.json @@ -0,0 +1,69 @@ +{ + "fileName": "ReduxLib-2026.1.1.json", + "name": "ReduxLib", + "version": "2026.1.1", + "frcYear": "2026", + "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", + "mavenUrls": [ + "https://maven.reduxrobotics.com/" + ], + "jsonUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2026.json", + "javaDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-java", + "version": "2026.1.1" + } + ], + "jniDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-fifo", + "version": "2026.1.1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-cpp", + "version": "2026.1.1", + "libName": "ReduxLib", + "headerClassifier": "headers", + "sourcesClassifier": "sources", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + }, + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-fifo", + "version": "2026.1.1", + "libName": "reduxfifo", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + } + ] +} \ No newline at end of file diff --git a/examples/drivebase_with_PhotonVision/vendordeps/Studica-2026.0.0.json b/examples/drivebase_with_PhotonVision/vendordeps/Studica-2026.0.0.json new file mode 100644 index 0000000..7a1f3bb --- /dev/null +++ b/examples/drivebase_with_PhotonVision/vendordeps/Studica-2026.0.0.json @@ -0,0 +1,71 @@ +{ + "fileName": "Studica.json", + "name": "Studica", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-cpp", + "version": "2026.0.0", + "libName": "Studica", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0", + "libName": "StudicaDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} diff --git a/examples/drivebase_with_PhotonVision/vendordeps/StudicaLib-2026.0.0.json b/examples/drivebase_with_PhotonVision/vendordeps/StudicaLib-2026.0.0.json new file mode 100644 index 0000000..7447f74 --- /dev/null +++ b/examples/drivebase_with_PhotonVision/vendordeps/StudicaLib-2026.0.0.json @@ -0,0 +1,71 @@ +{ + "fileName": "StudicaLib.json", + "name": "StudicaLib", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.0.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.0", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-cpp", + "version": "2026.0.0", + "libName": "StudicaLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.0", + "libName": "StudicaLibDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} diff --git a/examples/drivebase_with_PhotonVision/vendordeps/ThriftyLib-2026.0.0.json b/examples/drivebase_with_PhotonVision/vendordeps/ThriftyLib-2026.0.0.json new file mode 100644 index 0000000..56ff85e --- /dev/null +++ b/examples/drivebase_with_PhotonVision/vendordeps/ThriftyLib-2026.0.0.json @@ -0,0 +1,18 @@ +{ + "fileName": "ThriftyLib-2026.0.0.json", + "name": "ThriftyLib", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", + "mavenUrls": ["https://docs.home.thethriftybot.com"], + "jsonUrl": "https://docs.home.thethriftybot.com/ThriftyLib-2026.json", + "javaDependencies": [ + { + "groupId": "com.thethriftybot.frc", + "artifactId": "ThriftyLib-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [], + "cppDependencies": [] +} diff --git a/examples/field_oriented_drivebase/vendordeps/ReduxLib-2026.1.1.json b/examples/field_oriented_drivebase/vendordeps/ReduxLib-2026.1.1.json new file mode 100644 index 0000000..3dba1cb --- /dev/null +++ b/examples/field_oriented_drivebase/vendordeps/ReduxLib-2026.1.1.json @@ -0,0 +1,69 @@ +{ + "fileName": "ReduxLib-2026.1.1.json", + "name": "ReduxLib", + "version": "2026.1.1", + "frcYear": "2026", + "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", + "mavenUrls": [ + "https://maven.reduxrobotics.com/" + ], + "jsonUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2026.json", + "javaDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-java", + "version": "2026.1.1" + } + ], + "jniDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-fifo", + "version": "2026.1.1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-cpp", + "version": "2026.1.1", + "libName": "ReduxLib", + "headerClassifier": "headers", + "sourcesClassifier": "sources", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + }, + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-fifo", + "version": "2026.1.1", + "libName": "reduxfifo", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + } + ] +} \ No newline at end of file diff --git a/examples/field_oriented_drivebase/vendordeps/Studica-2026.0.0.json b/examples/field_oriented_drivebase/vendordeps/Studica-2026.0.0.json new file mode 100644 index 0000000..7a1f3bb --- /dev/null +++ b/examples/field_oriented_drivebase/vendordeps/Studica-2026.0.0.json @@ -0,0 +1,71 @@ +{ + "fileName": "Studica.json", + "name": "Studica", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-cpp", + "version": "2026.0.0", + "libName": "Studica", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0", + "libName": "StudicaDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} diff --git a/examples/field_oriented_drivebase/vendordeps/StudicaLib-2026.0.0.json b/examples/field_oriented_drivebase/vendordeps/StudicaLib-2026.0.0.json new file mode 100644 index 0000000..7447f74 --- /dev/null +++ b/examples/field_oriented_drivebase/vendordeps/StudicaLib-2026.0.0.json @@ -0,0 +1,71 @@ +{ + "fileName": "StudicaLib.json", + "name": "StudicaLib", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.0.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.0", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-cpp", + "version": "2026.0.0", + "libName": "StudicaLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.0", + "libName": "StudicaLibDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} diff --git a/examples/field_oriented_drivebase/vendordeps/ThriftyLib-2026.0.0.json b/examples/field_oriented_drivebase/vendordeps/ThriftyLib-2026.0.0.json new file mode 100644 index 0000000..56ff85e --- /dev/null +++ b/examples/field_oriented_drivebase/vendordeps/ThriftyLib-2026.0.0.json @@ -0,0 +1,18 @@ +{ + "fileName": "ThriftyLib-2026.0.0.json", + "name": "ThriftyLib", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", + "mavenUrls": ["https://docs.home.thethriftybot.com"], + "jsonUrl": "https://docs.home.thethriftybot.com/ThriftyLib-2026.json", + "javaDependencies": [ + { + "groupId": "com.thethriftybot.frc", + "artifactId": "ThriftyLib-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [], + "cppDependencies": [] +} diff --git a/examples/full_example/vendordeps/ReduxLib-2026.1.1.json b/examples/full_example/vendordeps/ReduxLib-2026.1.1.json new file mode 100644 index 0000000..3dba1cb --- /dev/null +++ b/examples/full_example/vendordeps/ReduxLib-2026.1.1.json @@ -0,0 +1,69 @@ +{ + "fileName": "ReduxLib-2026.1.1.json", + "name": "ReduxLib", + "version": "2026.1.1", + "frcYear": "2026", + "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", + "mavenUrls": [ + "https://maven.reduxrobotics.com/" + ], + "jsonUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2026.json", + "javaDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-java", + "version": "2026.1.1" + } + ], + "jniDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-fifo", + "version": "2026.1.1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-cpp", + "version": "2026.1.1", + "libName": "ReduxLib", + "headerClassifier": "headers", + "sourcesClassifier": "sources", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + }, + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-fifo", + "version": "2026.1.1", + "libName": "reduxfifo", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + } + ] +} \ No newline at end of file diff --git a/examples/full_example/vendordeps/Studica-2026.0.0.json b/examples/full_example/vendordeps/Studica-2026.0.0.json new file mode 100644 index 0000000..7a1f3bb --- /dev/null +++ b/examples/full_example/vendordeps/Studica-2026.0.0.json @@ -0,0 +1,71 @@ +{ + "fileName": "Studica.json", + "name": "Studica", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-cpp", + "version": "2026.0.0", + "libName": "Studica", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0", + "libName": "StudicaDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} diff --git a/examples/full_example/vendordeps/StudicaLib-2026.0.0.json b/examples/full_example/vendordeps/StudicaLib-2026.0.0.json new file mode 100644 index 0000000..7447f74 --- /dev/null +++ b/examples/full_example/vendordeps/StudicaLib-2026.0.0.json @@ -0,0 +1,71 @@ +{ + "fileName": "StudicaLib.json", + "name": "StudicaLib", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.0.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.0", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-cpp", + "version": "2026.0.0", + "libName": "StudicaLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.0", + "libName": "StudicaLibDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} diff --git a/examples/full_example/vendordeps/ThriftyLib-2026.0.0.json b/examples/full_example/vendordeps/ThriftyLib-2026.0.0.json new file mode 100644 index 0000000..56ff85e --- /dev/null +++ b/examples/full_example/vendordeps/ThriftyLib-2026.0.0.json @@ -0,0 +1,18 @@ +{ + "fileName": "ThriftyLib-2026.0.0.json", + "name": "ThriftyLib", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", + "mavenUrls": ["https://docs.home.thethriftybot.com"], + "jsonUrl": "https://docs.home.thethriftybot.com/ThriftyLib-2026.json", + "javaDependencies": [ + { + "groupId": "com.thethriftybot.frc", + "artifactId": "ThriftyLib-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [], + "cppDependencies": [] +} diff --git a/examples/robot_relative_drivebase/vendordeps/ReduxLib-2026.1.1.json b/examples/robot_relative_drivebase/vendordeps/ReduxLib-2026.1.1.json new file mode 100644 index 0000000..3dba1cb --- /dev/null +++ b/examples/robot_relative_drivebase/vendordeps/ReduxLib-2026.1.1.json @@ -0,0 +1,69 @@ +{ + "fileName": "ReduxLib-2026.1.1.json", + "name": "ReduxLib", + "version": "2026.1.1", + "frcYear": "2026", + "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", + "mavenUrls": [ + "https://maven.reduxrobotics.com/" + ], + "jsonUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2026.json", + "javaDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-java", + "version": "2026.1.1" + } + ], + "jniDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-fifo", + "version": "2026.1.1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-cpp", + "version": "2026.1.1", + "libName": "ReduxLib", + "headerClassifier": "headers", + "sourcesClassifier": "sources", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + }, + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-fifo", + "version": "2026.1.1", + "libName": "reduxfifo", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + } + ] +} \ No newline at end of file diff --git a/examples/robot_relative_drivebase/vendordeps/Studica-2026.0.0.json b/examples/robot_relative_drivebase/vendordeps/Studica-2026.0.0.json new file mode 100644 index 0000000..7a1f3bb --- /dev/null +++ b/examples/robot_relative_drivebase/vendordeps/Studica-2026.0.0.json @@ -0,0 +1,71 @@ +{ + "fileName": "Studica.json", + "name": "Studica", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-cpp", + "version": "2026.0.0", + "libName": "Studica", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0", + "libName": "StudicaDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} diff --git a/examples/robot_relative_drivebase/vendordeps/StudicaLib-2026.0.0.json b/examples/robot_relative_drivebase/vendordeps/StudicaLib-2026.0.0.json new file mode 100644 index 0000000..7447f74 --- /dev/null +++ b/examples/robot_relative_drivebase/vendordeps/StudicaLib-2026.0.0.json @@ -0,0 +1,71 @@ +{ + "fileName": "StudicaLib.json", + "name": "StudicaLib", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.0.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.0", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-cpp", + "version": "2026.0.0", + "libName": "StudicaLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.0", + "libName": "StudicaLibDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} diff --git a/examples/robot_relative_drivebase/vendordeps/ThriftyLib-2026.0.0.json b/examples/robot_relative_drivebase/vendordeps/ThriftyLib-2026.0.0.json new file mode 100644 index 0000000..56ff85e --- /dev/null +++ b/examples/robot_relative_drivebase/vendordeps/ThriftyLib-2026.0.0.json @@ -0,0 +1,18 @@ +{ + "fileName": "ThriftyLib-2026.0.0.json", + "name": "ThriftyLib", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", + "mavenUrls": ["https://docs.home.thethriftybot.com"], + "jsonUrl": "https://docs.home.thethriftybot.com/ThriftyLib-2026.json", + "javaDependencies": [ + { + "groupId": "com.thethriftybot.frc", + "artifactId": "ThriftyLib-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [], + "cppDependencies": [] +} diff --git a/vendordep/vendordeps/ReduxLib-2026.1.1.json b/vendordep/vendordeps/ReduxLib-2026.1.1.json new file mode 100644 index 0000000..3dba1cb --- /dev/null +++ b/vendordep/vendordeps/ReduxLib-2026.1.1.json @@ -0,0 +1,69 @@ +{ + "fileName": "ReduxLib-2026.1.1.json", + "name": "ReduxLib", + "version": "2026.1.1", + "frcYear": "2026", + "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", + "mavenUrls": [ + "https://maven.reduxrobotics.com/" + ], + "jsonUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2026.json", + "javaDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-java", + "version": "2026.1.1" + } + ], + "jniDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-fifo", + "version": "2026.1.1", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-cpp", + "version": "2026.1.1", + "libName": "ReduxLib", + "headerClassifier": "headers", + "sourcesClassifier": "sources", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + }, + { + "groupId": "com.reduxrobotics.frc", + "artifactId": "ReduxLib-fifo", + "version": "2026.1.1", + "libName": "reduxfifo", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena", + "linuxx86-64", + "linuxarm64", + "osxuniversal", + "windowsx86-64" + ] + } + ] +} \ No newline at end of file diff --git a/vendordep/vendordeps/Studica-2026.0.0.json b/vendordep/vendordeps/Studica-2026.0.0.json new file mode 100644 index 0000000..7a1f3bb --- /dev/null +++ b/vendordep/vendordeps/Studica-2026.0.0.json @@ -0,0 +1,71 @@ +{ + "fileName": "Studica.json", + "name": "Studica", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "Studica-cpp", + "version": "2026.0.0", + "libName": "Studica", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "Studica-driver", + "version": "2026.0.0", + "libName": "StudicaDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} diff --git a/vendordep/vendordeps/StudicaLib-2026.0.0.json b/vendordep/vendordeps/StudicaLib-2026.0.0.json new file mode 100644 index 0000000..7447f74 --- /dev/null +++ b/vendordep/vendordeps/StudicaLib-2026.0.0.json @@ -0,0 +1,71 @@ +{ + "fileName": "StudicaLib.json", + "name": "StudicaLib", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.0.json", + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.0", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-cpp", + "version": "2026.0.0", + "libName": "StudicaLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.0", + "libName": "StudicaLibDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} diff --git a/vendordep/vendordeps/ThriftyLib-2026.0.0.json b/vendordep/vendordeps/ThriftyLib-2026.0.0.json new file mode 100644 index 0000000..56ff85e --- /dev/null +++ b/vendordep/vendordeps/ThriftyLib-2026.0.0.json @@ -0,0 +1,18 @@ +{ + "fileName": "ThriftyLib-2026.0.0.json", + "name": "ThriftyLib", + "version": "2026.0.0", + "frcYear": "2026", + "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", + "mavenUrls": ["https://docs.home.thethriftybot.com"], + "jsonUrl": "https://docs.home.thethriftybot.com/ThriftyLib-2026.json", + "javaDependencies": [ + { + "groupId": "com.thethriftybot.frc", + "artifactId": "ThriftyLib-java", + "version": "2026.0.0" + } + ], + "jniDependencies": [], + "cppDependencies": [] +} diff --git a/vendordep/yagsl.json b/vendordep/yagsl.json index 4e30d1e..245e884 100644 --- a/vendordep/yagsl.json +++ b/vendordep/yagsl.json @@ -22,6 +22,12 @@ } ], "requires": [ + { + "uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd", + "errorMessage": "ReduxLib is required!", + "offlineFileName": "ReduxLib.json", + "onlineUrl": "https://frcsdk.reduxrobotics.com/ReduxLib_2026.json" + }, { "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", "errorMessage": "REVLib is required!", @@ -29,28 +35,34 @@ "onlineUrl": "https://software-metadata.revrobotics.com/REVLib-2026.json" }, { - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", "errorMessage": "Phoenix6 is required!", - "offlineFileName": "Phoenix6-replay-26.0.0-beta-1", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-beta-latest.json" + "offlineFileName": "Phoenix6-replay-26.1.0.json", + "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-latest.json" }, { - "uuid": "ab676553-b602-441f-a38d-f1296eff6537", + "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", "errorMessage": "Phoenix5 is required!", - "offlineFileName": "Phoenix5-replay-5.36.0-beta-1.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-beta-latest.json" + "offlineFileName": "Phoenix5-replay-5.36.0.json", + "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-latest.json" }, { - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", + "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", "errorMessage": "Studica is required!", "offlineFileName": "StudicaLib.json", - "onlineUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.1-beta.json" + "onlineUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.0.json" + }, + { + "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", + "errorMessage": "Studica is required!", + "offlineFileName": "Studica.json", + "onlineUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0.json" }, { "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", "errorMessage": "ThriftyLib is required!", "offlineFileName": "ThriftyLib.json", - "onlineUrl": "https://docs.home.thethriftybot.com/ThriftyLib.json" + "onlineUrl": "https://docs.home.thethriftybot.com/ThriftyLib-2026.json" } ], "jniDependencies": [], diff --git a/yagsl/java/swervelib/encoders/CanAndMagSwerve.java b/yagsl/java/swervelib/encoders/CanAndMagSwerve.java index 2a25f1c..5ed9e90 100644 --- a/yagsl/java/swervelib/encoders/CanAndMagSwerve.java +++ b/yagsl/java/swervelib/encoders/CanAndMagSwerve.java @@ -1,115 +1,115 @@ package swervelib.encoders; -//import com.reduxrobotics.sensors.canandmag.Canandmag; -//import com.reduxrobotics.sensors.canandmag.CanandmagSettings; -// -///** -// * HELIUM {@link Canandmag} from ReduxRobotics absolute encoder, attached through the CAN bus. -// */ -//public class CanAndMagSwerve extends SwerveAbsoluteEncoder -//{ -// -// /** -// * The {@link Canandmag} representing the CANandMag on the CAN bus. -// */ -// public Canandmag encoder; -// /** -// * The {@link Canandmag} settings object to use. -// */ -// public CanandmagSettings settings; -// -// /** -// * Create the {@link Canandmag} -// * -// * @param canid The CAN ID whenever the CANandMag is operating on the CANBus. -// */ -// public CanAndMagSwerve(int canid) -// { -// encoder = new Canandmag(canid); -// settings = new CanandmagSettings(); -// } -// -// @Override -// public void close() -// { -// encoder.close(); -// } -// -// /** -// * Reset the encoder to factory defaults. -// *

    -// * This will not clear the stored zero offset. -// */ -// @Override -// public void factoryDefault() -// { -// encoder.resetFactoryDefaults(false); -// } -// -// /** -// * Clear sticky faults on the encoder. -// */ -// @Override -// public void clearStickyFaults() -// { -// encoder.clearStickyFaults(); -// } -// -// /** -// * Configure the CANandMag to read from [0, 360) per second. -// * -// * @param inverted Whether the encoder is inverted. -// */ -// @Override -// public void configure(boolean inverted) -// { -// settings.setInvertDirection(inverted); -// encoder.setSettings(settings); -// } -// -// /** -// * Get the absolute position of the encoder. -// * -// * @return Absolute position in degrees from [0, 360). -// */ -// @Override -// public double getAbsolutePosition() -// { -// return encoder.getAbsPosition() * 360; -// } -// -// /** -// * Get the instantiated absolute encoder Object. -// * -// * @return Absolute encoder object. -// */ -// @Override -// public Object getAbsoluteEncoder() -// { -// return encoder; -// } -// -// /** -// * Cannot set the offset of the CANandMag. -// * -// * @param offset the offset the Absolute Encoder uses as the zero point. -// * @return true if setting the zero point succeeded, false otherwise -// */ -// @Override -// public boolean setAbsoluteEncoderOffset(double offset) -// { -// settings.setZeroOffset(offset); -// return encoder.setSettings(settings); -// } -// -// /** -// * Get the velocity in degrees/sec. -// * -// * @return velocity in degrees/sec. -// */ -// @Override -// public double getVelocity() -// { -// return encoder.getVelocity() * 360; -// } -//} +import com.reduxrobotics.sensors.canandmag.Canandmag; +import com.reduxrobotics.sensors.canandmag.CanandmagSettings; + +/** + * HELIUM {@link Canandmag} from ReduxRobotics absolute encoder, attached through the CAN bus. + */ +public class CanAndMagSwerve extends SwerveAbsoluteEncoder +{ + + /** + * The {@link Canandmag} representing the CANandMag on the CAN bus. + */ + public Canandmag encoder; + /** + * The {@link Canandmag} settings object to use. + */ + public CanandmagSettings settings; + + /** + * Create the {@link Canandmag} + * + * @param canid The CAN ID whenever the CANandMag is operating on the CANBus. + */ + public CanAndMagSwerve(int canid) + { + encoder = new Canandmag(canid); + settings = new CanandmagSettings(); + } + + @Override + public void close() + { + encoder.close(); + } + + /** + * Reset the encoder to factory defaults. + *

    + * This will not clear the stored zero offset. + */ + @Override + public void factoryDefault() + { + encoder.resetFactoryDefaults(false); + } + + /** + * Clear sticky faults on the encoder. + */ + @Override + public void clearStickyFaults() + { + encoder.clearStickyFaults(); + } + + /** + * Configure the CANandMag to read from [0, 360) per second. + * + * @param inverted Whether the encoder is inverted. + */ + @Override + public void configure(boolean inverted) + { + settings.setInvertDirection(inverted); + encoder.setSettings(settings); + } + + /** + * Get the absolute position of the encoder. + * + * @return Absolute position in degrees from [0, 360). + */ + @Override + public double getAbsolutePosition() + { + return encoder.getAbsPosition() * 360; + } + + /** + * Get the instantiated absolute encoder Object. + * + * @return Absolute encoder object. + */ + @Override + public Object getAbsoluteEncoder() + { + return encoder; + } + + /** + * Cannot set the offset of the CANandMag. + * + * @param offset the offset the Absolute Encoder uses as the zero point. + * @return true if setting the zero point succeeded, false otherwise + */ + @Override + public boolean setAbsoluteEncoderOffset(double offset) + { + settings.setZeroOffset(offset); + return encoder.setSettings(settings); + } + + /** + * Get the velocity in degrees/sec. + * + * @return velocity in degrees/sec. + */ + @Override + public double getVelocity() + { + return encoder.getVelocity() * 360; + } +} diff --git a/yagsl/java/swervelib/encoders/ThriftyNovaEncoderSwerve.java b/yagsl/java/swervelib/encoders/ThriftyNovaEncoderSwerve.java index 7cdfdd6..70b8f25 100644 --- a/yagsl/java/swervelib/encoders/ThriftyNovaEncoderSwerve.java +++ b/yagsl/java/swervelib/encoders/ThriftyNovaEncoderSwerve.java @@ -1,141 +1,141 @@ -//package swervelib.encoders; -// -// -//import com.thethriftybot.devices.ThriftyNova; -//import com.thethriftybot.devices.ThriftyNova.EncoderType; -//import com.thethriftybot.devices.ThriftyNova.ExternalEncoder; -//import com.thethriftybot.util.Conversion; -//import com.thethriftybot.util.Conversion.PositionUnit; -//import com.thethriftybot.util.Conversion.VelocityUnit; -//import swervelib.motors.SwerveMotor; -//import swervelib.motors.ThriftyNovaSwerve; -// -///** -// * Thrifty Nova absolute encoder, attached through the data port. -// */ -//public class ThriftyNovaEncoderSwerve extends SwerveAbsoluteEncoder -//{ -// -// /** -// * The absolute encoder is directly interfaced through the Thrifty Nova motor. -// */ -// protected ThriftyNova motor; -// /** -// * Inversion state of the attached encoder. -// */ -// protected boolean inverted = false; -// /** -// * Offset of the absolute encoder. -// */ -// protected double offset = 0.0; -// /** -// * Position conversion object for the motor encoder -// */ -// private Conversion positionConversion; -// /** -// * Velocity conversion object for the motor encoder -// */ -// private Conversion velocityConversion; -// -// /** -// * Create the {@link ThriftyNovaEncoderSwerve} object as an absolute encoder from the {@link ThriftyNovaSwerve} -// * motor. -// * -// * @param motor {@link SwerveMotor} through which to interface with the attached encoder . -// * @param encoderType the type of encoder to use (options: "REV_ENCODER", "REDUX_ENCODER", "SRX_MAG_ENCODER") -// */ -// public ThriftyNovaEncoderSwerve(SwerveMotor motor, String encoderType) -// { -// this.motor = (ThriftyNova) motor.getMotor(); -// velocityConversion = new Conversion(VelocityUnit.DEGREES_PER_SEC, EncoderType.ABS); -// positionConversion = new Conversion(PositionUnit.DEGREES, EncoderType.ABS); -// ExternalEncoder externalEncoderType = ExternalEncoder.valueOf(encoderType); -// this.motor.setExternalEncoder(externalEncoderType); -// setAbsoluteEncoderOffset(offset); -// if (ExternalEncoder.REDUX_ENCODER == externalEncoderType) { -// this.motor.setAbsoluteWrapping(true); -// } -// } -// -// @Override -// public void close() -// { -// // ThriftyNova encoder gets closed with the motor -// // I don't think an encoder getting closed should -// // close the entire motor so i will keep this empty -// } -// -// /** -// * Set factory default. -// */ -// @Override -// public void factoryDefault() -// { -// } -// -// /** -// * Clear sticky faults. -// */ -// @Override -// public void clearStickyFaults() -// { -// } -// -// /** -// * Configure the absolute encoder. -// * -// * @param inverted Whether the encoder is inverted. -// */ -// @Override -// public void configure(boolean inverted) -// { -// this.inverted = inverted; -// } -// -// /** -// * Get the absolute position of the encoder. -// * -// * @return Absolute position in degrees from [0, 360). -// */ -// @Override -// public double getAbsolutePosition() -// { -// double rawMotor = motor.getPositionAbs(); -// double convertedPosition = positionConversion.fromMotor(rawMotor); -// return convertedPosition * (inverted ? -1.0 : 1.0); -// } -// -// /** -// * Get the instantiated absolute encoder Object. -// */ -// @Override -// public Object getAbsoluteEncoder() -// { -// return null; -// } -// -// /** -// * Set the absolute encoder offset. -// * -// * @param offset offset in degrees from [0, 360). -// * @return true if successful. -// */ -// @Override -// public boolean setAbsoluteEncoderOffset(double offset) -// { -// this.offset = offset; -// motor.setAbsOffset((int) offset); -// return true; -// } -// -// /** -// * Get the absolute encoder velocity. WARNING: Angular velocity is generally not measurable at high speeds. -// * -// * @return Velocity in degrees per second. -// */ -// @Override -// public double getVelocity() -// { -// return velocityConversion.fromMotor(motor.getVelocity()) * (inverted ? -1.0 : 1.0); -// } -//} +package swervelib.encoders; + + +import com.thethriftybot.devices.ThriftyNova; +import com.thethriftybot.devices.ThriftyNova.EncoderType; +import com.thethriftybot.devices.ThriftyNova.ExternalEncoder; +import com.thethriftybot.util.Conversion; +import com.thethriftybot.util.Conversion.PositionUnit; +import com.thethriftybot.util.Conversion.VelocityUnit; +import swervelib.motors.SwerveMotor; +import swervelib.motors.ThriftyNovaSwerve; + +/** + * Thrifty Nova absolute encoder, attached through the data port. + */ +public class ThriftyNovaEncoderSwerve extends SwerveAbsoluteEncoder +{ + + /** + * The absolute encoder is directly interfaced through the Thrifty Nova motor. + */ + protected ThriftyNova motor; + /** + * Inversion state of the attached encoder. + */ + protected boolean inverted = false; + /** + * Offset of the absolute encoder. + */ + protected double offset = 0.0; + /** + * Position conversion object for the motor encoder + */ + private Conversion positionConversion; + /** + * Velocity conversion object for the motor encoder + */ + private Conversion velocityConversion; + + /** + * Create the {@link ThriftyNovaEncoderSwerve} object as an absolute encoder from the {@link ThriftyNovaSwerve} + * motor. + * + * @param motor {@link SwerveMotor} through which to interface with the attached encoder . + * @param encoderType the type of encoder to use (options: "REV_ENCODER", "REDUX_ENCODER", "SRX_MAG_ENCODER") + */ + public ThriftyNovaEncoderSwerve(SwerveMotor motor, String encoderType) + { + this.motor = (ThriftyNova) motor.getMotor(); + velocityConversion = new Conversion(VelocityUnit.DEGREES_PER_SEC, EncoderType.ABS); + positionConversion = new Conversion(PositionUnit.DEGREES, EncoderType.ABS); + ExternalEncoder externalEncoderType = ExternalEncoder.valueOf(encoderType); + this.motor.setExternalEncoder(externalEncoderType); + setAbsoluteEncoderOffset(offset); + if (ExternalEncoder.REDUX_ENCODER == externalEncoderType) { + this.motor.setAbsoluteWrapping(true); + } + } + + @Override + public void close() + { + // ThriftyNova encoder gets closed with the motor + // I don't think an encoder getting closed should + // close the entire motor so i will keep this empty + } + + /** + * Set factory default. + */ + @Override + public void factoryDefault() + { + } + + /** + * Clear sticky faults. + */ + @Override + public void clearStickyFaults() + { + } + + /** + * Configure the absolute encoder. + * + * @param inverted Whether the encoder is inverted. + */ + @Override + public void configure(boolean inverted) + { + this.inverted = inverted; + } + + /** + * Get the absolute position of the encoder. + * + * @return Absolute position in degrees from [0, 360). + */ + @Override + public double getAbsolutePosition() + { + double rawMotor = motor.getPositionAbs(); + double convertedPosition = positionConversion.fromMotor(rawMotor); + return convertedPosition * (inverted ? -1.0 : 1.0); + } + + /** + * Get the instantiated absolute encoder Object. + */ + @Override + public Object getAbsoluteEncoder() + { + return null; + } + + /** + * Set the absolute encoder offset. + * + * @param offset offset in degrees from [0, 360). + * @return true if successful. + */ + @Override + public boolean setAbsoluteEncoderOffset(double offset) + { + this.offset = offset; + motor.setAbsOffset((int) offset); + return true; + } + + /** + * Get the absolute encoder velocity. WARNING: Angular velocity is generally not measurable at high speeds. + * + * @return Velocity in degrees per second. + */ + @Override + public double getVelocity() + { + return velocityConversion.fromMotor(motor.getVelocity()) * (inverted ? -1.0 : 1.0); + } +} diff --git a/yagsl/java/swervelib/imu/CanandgyroSwerve.java b/yagsl/java/swervelib/imu/CanandgyroSwerve.java index fc5b331..9991418 100644 --- a/yagsl/java/swervelib/imu/CanandgyroSwerve.java +++ b/yagsl/java/swervelib/imu/CanandgyroSwerve.java @@ -1,144 +1,144 @@ package swervelib.imu; import static edu.wpi.first.units.Units.RotationsPerSecond; -// -//import com.reduxrobotics.sensors.canandgyro.Canandgyro; -//import edu.wpi.first.math.geometry.Rotation3d; -//import edu.wpi.first.math.geometry.Translation3d; -//import edu.wpi.first.units.measure.MutAngularVelocity; -//import java.util.Optional; -// -///** -// * SwerveIMU interface for the Boron {@link Canandgyro} by Redux Robotics -// */ -//public class CanandgyroSwerve extends SwerveIMU -//{ -// -// /** -// * Wait time for status frames to show up. -// */ -// public static double STATUS_TIMEOUT_SECONDS = 0.04; -// /** -// * Boron {@link Canandgyro} by Redux Robotics. -// */ -// private final Canandgyro imu; -// /** -// * Mutable {@link MutAngularVelocity} for readings. -// */ -// private final MutAngularVelocity yawVel = new MutAngularVelocity(0, 0, RotationsPerSecond); -// /** -// * Offset for the Boron {@link Canandgyro}. -// */ -// private Rotation3d offset = new Rotation3d(); -// /** -// * Inversion for the gyro -// */ -// private boolean invertedIMU = false; -// -// /** -// * Generate the SwerveIMU for {@link Canandgyro}. -// * -// * @param canid CAN ID for the Boron {@link Canandgyro} -// */ -// public CanandgyroSwerve(int canid) -// { -// imu = new Canandgyro(canid); -// } -// -// @Override -// public void close() -// { -// imu.close(); -// } -// -// /** -// * Reset {@link Canandgyro} to factory default. -// */ -// @Override -// public void factoryDefault() -// { -// imu.resetFactoryDefaults(STATUS_TIMEOUT_SECONDS); -// } -// -// /** -// * Clear sticky faults on {@link Canandgyro}. -// */ -// @Override -// public void clearStickyFaults() -// { -// imu.clearStickyFaults(); -// } -// -// /** -// * Set the gyro offset. -// * -// * @param offset gyro offset as a {@link Rotation3d}. -// */ -// public void setOffset(Rotation3d offset) -// { -// this.offset = offset; -// } -// -// /** -// * Set the gyro to invert its default direction -// * -// * @param invertIMU invert gyro direction -// */ -// public void setInverted(boolean invertIMU) -// { -// invertedIMU = invertIMU; -// } -// -// /** -// * Fetch the {@link Rotation3d} from the IMU without any zeroing. Robot relative. -// * -// * @return {@link Rotation3d} from the IMU. -// */ -// @Override -// public Rotation3d getRawRotation3d() -// { -// Rotation3d reading = imu.getRotation3d(); -// return invertedIMU ? reading.unaryMinus() : reading; -// } -// -// /** -// * Fetch the {@link Rotation3d} from the IMU. Robot relative. -// * -// * @return {@link Rotation3d} from the IMU. -// */ -// @Override -// public Rotation3d getRotation3d() -// { -// return getRawRotation3d().rotateBy(offset.unaryMinus()); -// } -// -// /** -// * Fetch the acceleration [x, y, z] from the IMU in meters per second squared. If acceleration isn't supported returns -// * empty. -// * -// * @return {@link Translation3d} of the acceleration as an {@link Optional}. -// */ -// @Override -// public Optional getAccel() -// { -// -// return Optional.of(new Translation3d(imu.getAccelerationFrame().getValue()).times(9.81 / 16384.0)); -// } -// -// @Override -// public MutAngularVelocity getYawAngularVelocity() -// { -// return yawVel.mut_setMagnitude(imu.getAngularVelocityYaw()); -// } -// -// /** -// * Get the instantiated {@link Canandgyro} IMU object. -// * -// * @return IMU object. -// */ -// @Override -// public Object getIMU() -// { -// return imu; -// } -//} + +import com.reduxrobotics.sensors.canandgyro.Canandgyro; +import edu.wpi.first.math.geometry.Rotation3d; +import edu.wpi.first.math.geometry.Translation3d; +import edu.wpi.first.units.measure.MutAngularVelocity; +import java.util.Optional; + +/** + * SwerveIMU interface for the Boron {@link Canandgyro} by Redux Robotics + */ +public class CanandgyroSwerve extends SwerveIMU +{ + + /** + * Wait time for status frames to show up. + */ + public static double STATUS_TIMEOUT_SECONDS = 0.04; + /** + * Boron {@link Canandgyro} by Redux Robotics. + */ + private final Canandgyro imu; + /** + * Mutable {@link MutAngularVelocity} for readings. + */ + private final MutAngularVelocity yawVel = new MutAngularVelocity(0, 0, RotationsPerSecond); + /** + * Offset for the Boron {@link Canandgyro}. + */ + private Rotation3d offset = new Rotation3d(); + /** + * Inversion for the gyro + */ + private boolean invertedIMU = false; + + /** + * Generate the SwerveIMU for {@link Canandgyro}. + * + * @param canid CAN ID for the Boron {@link Canandgyro} + */ + public CanandgyroSwerve(int canid) + { + imu = new Canandgyro(canid); + } + + @Override + public void close() + { + imu.close(); + } + + /** + * Reset {@link Canandgyro} to factory default. + */ + @Override + public void factoryDefault() + { + imu.resetFactoryDefaults(STATUS_TIMEOUT_SECONDS); + } + + /** + * Clear sticky faults on {@link Canandgyro}. + */ + @Override + public void clearStickyFaults() + { + imu.clearStickyFaults(); + } + + /** + * Set the gyro offset. + * + * @param offset gyro offset as a {@link Rotation3d}. + */ + public void setOffset(Rotation3d offset) + { + this.offset = offset; + } + + /** + * Set the gyro to invert its default direction + * + * @param invertIMU invert gyro direction + */ + public void setInverted(boolean invertIMU) + { + invertedIMU = invertIMU; + } + + /** + * Fetch the {@link Rotation3d} from the IMU without any zeroing. Robot relative. + * + * @return {@link Rotation3d} from the IMU. + */ + @Override + public Rotation3d getRawRotation3d() + { + Rotation3d reading = imu.getRotation3d(); + return invertedIMU ? reading.unaryMinus() : reading; + } + + /** + * Fetch the {@link Rotation3d} from the IMU. Robot relative. + * + * @return {@link Rotation3d} from the IMU. + */ + @Override + public Rotation3d getRotation3d() + { + return getRawRotation3d().rotateBy(offset.unaryMinus()); + } + + /** + * Fetch the acceleration [x, y, z] from the IMU in meters per second squared. If acceleration isn't supported returns + * empty. + * + * @return {@link Translation3d} of the acceleration as an {@link Optional}. + */ + @Override + public Optional getAccel() + { + + return Optional.of(new Translation3d(imu.getAccelerationFrame().getValue()).times(9.81 / 16384.0)); + } + + @Override + public MutAngularVelocity getYawAngularVelocity() + { + return yawVel.mut_setMagnitude(imu.getAngularVelocityYaw()); + } + + /** + * Get the instantiated {@link Canandgyro} IMU object. + * + * @return IMU object. + */ + @Override + public Object getIMU() + { + return imu; + } +} diff --git a/yagsl/java/swervelib/imu/NavX3Swerve.java b/yagsl/java/swervelib/imu/NavX3Swerve.java index 34cb84b..c38698c 100644 --- a/yagsl/java/swervelib/imu/NavX3Swerve.java +++ b/yagsl/java/swervelib/imu/NavX3Swerve.java @@ -1,174 +1,168 @@ -//package swervelib.imu; -// -//import static edu.wpi.first.units.Units.Degree; -//import static edu.wpi.first.units.Units.DegreesPerSecond; -//import static edu.wpi.first.units.Units.Milliseconds; -// -//import com.studica.frc.AHRS; -//import com.studica.frc.AHRS.NavXComType; -//import com.studica.frc.Navx; -//import edu.wpi.first.math.geometry.Rotation3d; -//import edu.wpi.first.math.geometry.Translation3d; -//import edu.wpi.first.units.measure.MutAngularVelocity; -//import edu.wpi.first.wpilibj.Alert; -//import edu.wpi.first.wpilibj.Alert.AlertType; -//import edu.wpi.first.wpilibj.Timer; -//import java.util.Optional; -// -///** -// * Communicates with the NavX({@link AHRS}) as the IMU. -// */ -//public class NavX3Swerve extends SwerveIMU -//{ -// -// /** -// * Mutable {@link MutAngularVelocity} for readings. -// */ -// private final MutAngularVelocity yawVel = new MutAngularVelocity(0, 0, DegreesPerSecond); -// /** -// * NavX IMU. -// */ -// private Navx imu; -// /** -// * Offset for the NavX. -// */ -// private Rotation3d offset = new Rotation3d(); -// /** -// * An {@link Alert} for if there is an error instantiating the NavX. -// */ -// private Alert navXError; -// /** -// * Inversion state of the {@link AHRS}. -// */ -// private boolean inverted = false; -// -// /** -// * Constructor for the NavX({@link com.studica.frc.Navx}) swerve. -// * -// * @param canid CAN ID of the NavX3. -// */ -// public NavX3Swerve(int canid) -// { -// navXError = new Alert("IMU", "Error instantiating NavX.", AlertType.kError); -// try -// { -// imu = new Navx(canid); -// for(int i = 0; i < 4; i++) -// { -// if (imu.start() == 0) -// break; -// Timer.delay(Milliseconds.of(5)); -// } -// -// } catch (RuntimeException ex) -// { -// navXError.setText("Error instantiating NavX: " + ex.getMessage()); -// navXError.set(true); -// } -// } -// -// @Override -// public void close() -// { -//// imu.close(); -// } -// -// /** -// * Reset offset to current gyro reading. Does not call NavX({@link AHRS#reset()}) because it has been reported to be -// * too slow. -// */ -// @Override -// public void factoryDefault() -// { -// // gyro.reset(); // Reported to be slow -// offset = new Rotation3d(Degree.of(imu.getRoll()), Degree.of(imu.getPitch()), Degree.of(imu.getYaw())); -// } -// -// /** -// * Clear sticky faults on IMU. -// */ -// @Override -// public void clearStickyFaults() -// { -// } -// -// /** -// * Set the gyro offset. -// * -// * @param offset gyro offset as a {@link Rotation3d}. -// */ -// public void setOffset(Rotation3d offset) -// { -// this.offset = offset; -// } -// -// /** -// * Set the gyro to invert its default direction -// * -// * @param invertIMU invert gyro direction -// */ -// public void setInverted(boolean invertIMU) -// { -// inverted = invertIMU; -//// setOffset(getRawRotation3d()); -// } -// -// private Rotation3d negate(Rotation3d rot) { -// return new Rotation3d(-rot.getX(), -rot.getY(), -rot.getZ()); -// } -// -// /** -// * Fetch the {@link Rotation3d} from the IMU without any zeroing. Robot relative. -// * -// * @return {@link Rotation3d} from the IMU. -// */ -// @Override -// public Rotation3d getRawRotation3d() -// { -// Rotation3d rotation = new Rotation3d(Degree.of(imu.getRoll()), Degree.of(imu.getPitch()), Degree.of(imu.getYaw())); -// return inverted ? negate(rotation) : rotation; -// } -// -// /** -// * Fetch the {@link Rotation3d} from the IMU. Robot relative. -// * -// * @return {@link Rotation3d} from the IMU. -// */ -// @Override -// public Rotation3d getRotation3d() -// { -// return getRawRotation3d().rotateBy(offset.unaryMinus()); -// } -// -// /** -// * Fetch the acceleration [x, y, z] from the IMU in meters per second squared. If acceleration isn't supported returns -// * empty. -// * -// * @return {@link Translation3d} of the acceleration as an {@link Optional}. -// */ -// @Override -// public Optional getAccel() -// { -// return Optional.empty(); -// } -// -// @Override -// public MutAngularVelocity getYawAngularVelocity() -// { -// // x, y, z -// float[] angularVelocity = {0,0,0}; -// imu.getAngularVel(angularVelocity); -// return yawVel.mut_setMagnitude(angularVelocity[2]); -// } -// -// /** -// * Get the instantiated NavX({@link AHRS}) IMU object. -// * -// * @return IMU object. -// */ -// @Override -// public Object getIMU() -// { -// return imu; -// } -//} +package swervelib.imu; + +import static edu.wpi.first.units.Units.Degree; +import static edu.wpi.first.units.Units.DegreesPerSecond; +import static edu.wpi.first.units.Units.Milliseconds; + +import com.studica.frc.AHRS; +import com.studica.frc.AHRS.NavXComType; +import com.studica.frc.Navx; +import edu.wpi.first.math.geometry.Rotation3d; +import edu.wpi.first.math.geometry.Translation3d; +import edu.wpi.first.units.measure.AngularVelocity; +import edu.wpi.first.units.measure.MutAngularVelocity; +import edu.wpi.first.wpilibj.Alert; +import edu.wpi.first.wpilibj.Alert.AlertType; +import edu.wpi.first.wpilibj.Timer; +import java.util.Optional; + +/** + * Communicates with the NavX({@link AHRS}) as the IMU. + */ +public class NavX3Swerve extends SwerveIMU +{ + + /** + * Mutable {@link MutAngularVelocity} for readings. + */ + private final MutAngularVelocity yawVel = new MutAngularVelocity(0, 0, DegreesPerSecond); + /** + * NavX IMU. + */ + private Navx imu; + /** + * Offset for the NavX. + */ + private Rotation3d offset = new Rotation3d(); + /** + * An {@link Alert} for if there is an error instantiating the NavX. + */ + private Alert navXError; + /** + * Inversion state of the {@link AHRS}. + */ + private boolean inverted = false; + + /** + * Constructor for the NavX({@link com.studica.frc.Navx}) swerve. + * + * @param canid CAN ID of the NavX3. + */ + public NavX3Swerve(int canid) + { + navXError = new Alert("IMU", "Error instantiating NavX.", AlertType.kError); + try + { + imu = new Navx(canid); + + } catch (RuntimeException ex) + { + navXError.setText("Error instantiating NavX: " + ex.getMessage()); + navXError.set(true); + } + } + + @Override + public void close() + { +// imu.close(); + } + + /** + * Reset offset to current gyro reading. Does not call NavX({@link AHRS#reset()}) because it has been reported to be + * too slow. + */ + @Override + public void factoryDefault() + { + // gyro.reset(); // Reported to be slow + offset = imu.getRotation3d(); + } + + /** + * Clear sticky faults on IMU. + */ + @Override + public void clearStickyFaults() + { + } + + /** + * Set the gyro offset. + * + * @param offset gyro offset as a {@link Rotation3d}. + */ + public void setOffset(Rotation3d offset) + { + this.offset = offset; + } + + /** + * Set the gyro to invert its default direction + * + * @param invertIMU invert gyro direction + */ + public void setInverted(boolean invertIMU) + { + inverted = invertIMU; +// setOffset(getRawRotation3d()); + } + + private Rotation3d negate(Rotation3d rot) { + return new Rotation3d(-rot.getX(), -rot.getY(), -rot.getZ()); + } + + /** + * Fetch the {@link Rotation3d} from the IMU without any zeroing. Robot relative. + * + * @return {@link Rotation3d} from the IMU. + */ + @Override + public Rotation3d getRawRotation3d() + { + Rotation3d rotation = imu.getRotation3d(); + return inverted ? negate(rotation) : rotation; + } + + /** + * Fetch the {@link Rotation3d} from the IMU. Robot relative. + * + * @return {@link Rotation3d} from the IMU. + */ + @Override + public Rotation3d getRotation3d() + { + return getRawRotation3d().rotateBy(offset.unaryMinus()); + } + + /** + * Fetch the acceleration [x, y, z] from the IMU in meters per second squared. If acceleration isn't supported returns + * empty. + * + * @return {@link Translation3d} of the acceleration as an {@link Optional}. + */ + @Override + public Optional getAccel() + { + return Optional.empty(); + } + + @Override + public MutAngularVelocity getYawAngularVelocity() + { + // x, y, z + AngularVelocity[] angularVelocity = imu.getAngularVel(); + return yawVel.mut_replace(angularVelocity[2]); + } + + /** + * Get the instantiated NavX({@link AHRS}) IMU object. + * + * @return IMU object. + */ + @Override + public Object getIMU() + { + return imu; + } +} diff --git a/yagsl/java/swervelib/imu/NavXSwerve.java b/yagsl/java/swervelib/imu/NavXSwerve.java index 1331719..071f3a1 100644 --- a/yagsl/java/swervelib/imu/NavXSwerve.java +++ b/yagsl/java/swervelib/imu/NavXSwerve.java @@ -1,168 +1,168 @@ -//package swervelib.imu; -// -//import static edu.wpi.first.units.Units.DegreesPerSecond; -// -//import com.studica.frc.AHRS; -//import com.studica.frc.AHRS.NavXComType; -//import edu.wpi.first.math.geometry.Rotation3d; -//import edu.wpi.first.math.geometry.Translation3d; -//import edu.wpi.first.units.measure.MutAngularVelocity; -//import edu.wpi.first.wpilibj.Alert; -//import edu.wpi.first.wpilibj.Alert.AlertType; -//import java.util.Optional; -// -///** -// * Communicates with the NavX({@link AHRS}) as the IMU. -// */ -//public class NavXSwerve extends SwerveIMU -//{ -// -// /** -// * Mutable {@link MutAngularVelocity} for readings. -// */ -// private final MutAngularVelocity yawVel = new MutAngularVelocity(0, 0, DegreesPerSecond); -// /** -// * NavX IMU. -// */ -// private AHRS imu; -// /** -// * Offset for the NavX. -// */ -// private Rotation3d offset = new Rotation3d(); -// /** -// * An {@link Alert} for if there is an error instantiating the NavX. -// */ -// private Alert navXError; -// /** -// * Inversion state of the {@link AHRS}. -// */ -// private boolean inverted = false; -// -// /** -// * Constructor for the NavX({@link AHRS}) swerve. -// * -// * @param port Serial Port to connect to. -// */ -// public NavXSwerve(NavXComType port) -// { -// navXError = new Alert("IMU", "Error instantiating NavX.", AlertType.kError); -// try -// { -// /* Communicate w/navX-MXP via the MXP SPI Bus. */ -// /* Alternatively: I2C.Port.kMXP, SerialPort.Port.kMXP or SerialPort.Port.kUSB */ -// /* See http://navx-mxp.kauailabs.com/guidance/selecting-an-interface/ for details. */ -// imu = new AHRS(port); -// factoryDefault(); -// } catch (RuntimeException ex) -// { -// navXError.setText("Error instantiating NavX: " + ex.getMessage()); -// navXError.set(true); -// } -// } -// -// @Override -// public void close() -// { -// imu.close(); -// } -// -// /** -// * Reset offset to current gyro reading. Does not call NavX({@link AHRS#reset()}) because it has been reported to be -// * too slow. -// */ -// @Override -// public void factoryDefault() -// { -// // gyro.reset(); // Reported to be slow -// offset = imu.getRotation3d(); -// } -// -// /** -// * Clear sticky faults on IMU. -// */ -// @Override -// public void clearStickyFaults() -// { -// } -// -// /** -// * Set the gyro offset. -// * -// * @param offset gyro offset as a {@link Rotation3d}. -// */ -// public void setOffset(Rotation3d offset) -// { -// this.offset = offset; -// } -// -// /** -// * Set the gyro to invert its default direction -// * -// * @param invertIMU invert gyro direction -// */ -// public void setInverted(boolean invertIMU) -// { -// inverted = invertIMU; -//// setOffset(getRawRotation3d()); -// } -// -// private Rotation3d negate(Rotation3d rot) { -// return new Rotation3d(-rot.getX(), -rot.getY(), -rot.getZ()); -// } -// -// /** -// * Fetch the {@link Rotation3d} from the IMU without any zeroing. Robot relative. -// * -// * @return {@link Rotation3d} from the IMU. -// */ -// @Override -// public Rotation3d getRawRotation3d() -// { -// return inverted ? negate(imu.getRotation3d()) : imu.getRotation3d(); -// } -// -// /** -// * Fetch the {@link Rotation3d} from the IMU. Robot relative. -// * -// * @return {@link Rotation3d} from the IMU. -// */ -// @Override -// public Rotation3d getRotation3d() -// { -// return getRawRotation3d().rotateBy(offset.unaryMinus()); -// } -// -// /** -// * Fetch the acceleration [x, y, z] from the IMU in meters per second squared. If acceleration isn't supported returns -// * empty. -// * -// * @return {@link Translation3d} of the acceleration as an {@link Optional}. -// */ -// @Override -// public Optional getAccel() -// { -// return Optional.of( -// new Translation3d( -// imu.getWorldLinearAccelX(), -// imu.getWorldLinearAccelY(), -// imu.getWorldLinearAccelZ()) -// .times(9.81)); -// } -// -// @Override -// public MutAngularVelocity getYawAngularVelocity() -// { -// return yawVel.mut_setMagnitude(imu.getRate()); -// } -// -// /** -// * Get the instantiated NavX({@link AHRS}) IMU object. -// * -// * @return IMU object. -// */ -// @Override -// public Object getIMU() -// { -// return imu; -// } -//} +package swervelib.imu; + +import static edu.wpi.first.units.Units.DegreesPerSecond; + +import com.studica.frc.AHRS; +import com.studica.frc.AHRS.NavXComType; +import edu.wpi.first.math.geometry.Rotation3d; +import edu.wpi.first.math.geometry.Translation3d; +import edu.wpi.first.units.measure.MutAngularVelocity; +import edu.wpi.first.wpilibj.Alert; +import edu.wpi.first.wpilibj.Alert.AlertType; +import java.util.Optional; + +/** + * Communicates with the NavX({@link AHRS}) as the IMU. + */ +public class NavXSwerve extends SwerveIMU +{ + + /** + * Mutable {@link MutAngularVelocity} for readings. + */ + private final MutAngularVelocity yawVel = new MutAngularVelocity(0, 0, DegreesPerSecond); + /** + * NavX IMU. + */ + private AHRS imu; + /** + * Offset for the NavX. + */ + private Rotation3d offset = new Rotation3d(); + /** + * An {@link Alert} for if there is an error instantiating the NavX. + */ + private Alert navXError; + /** + * Inversion state of the {@link AHRS}. + */ + private boolean inverted = false; + + /** + * Constructor for the NavX({@link AHRS}) swerve. + * + * @param port Serial Port to connect to. + */ + public NavXSwerve(NavXComType port) + { + navXError = new Alert("IMU", "Error instantiating NavX.", AlertType.kError); + try + { + /* Communicate w/navX-MXP via the MXP SPI Bus. */ + /* Alternatively: I2C.Port.kMXP, SerialPort.Port.kMXP or SerialPort.Port.kUSB */ + /* See http://navx-mxp.kauailabs.com/guidance/selecting-an-interface/ for details. */ + imu = new AHRS(port); + factoryDefault(); + } catch (RuntimeException ex) + { + navXError.setText("Error instantiating NavX: " + ex.getMessage()); + navXError.set(true); + } + } + + @Override + public void close() + { + imu.close(); + } + + /** + * Reset offset to current gyro reading. Does not call NavX({@link AHRS#reset()}) because it has been reported to be + * too slow. + */ + @Override + public void factoryDefault() + { + // gyro.reset(); // Reported to be slow + offset = imu.getRotation3d(); + } + + /** + * Clear sticky faults on IMU. + */ + @Override + public void clearStickyFaults() + { + } + + /** + * Set the gyro offset. + * + * @param offset gyro offset as a {@link Rotation3d}. + */ + public void setOffset(Rotation3d offset) + { + this.offset = offset; + } + + /** + * Set the gyro to invert its default direction + * + * @param invertIMU invert gyro direction + */ + public void setInverted(boolean invertIMU) + { + inverted = invertIMU; +// setOffset(getRawRotation3d()); + } + + private Rotation3d negate(Rotation3d rot) { + return new Rotation3d(-rot.getX(), -rot.getY(), -rot.getZ()); + } + + /** + * Fetch the {@link Rotation3d} from the IMU without any zeroing. Robot relative. + * + * @return {@link Rotation3d} from the IMU. + */ + @Override + public Rotation3d getRawRotation3d() + { + return inverted ? negate(imu.getRotation3d()) : imu.getRotation3d(); + } + + /** + * Fetch the {@link Rotation3d} from the IMU. Robot relative. + * + * @return {@link Rotation3d} from the IMU. + */ + @Override + public Rotation3d getRotation3d() + { + return getRawRotation3d().rotateBy(offset.unaryMinus()); + } + + /** + * Fetch the acceleration [x, y, z] from the IMU in meters per second squared. If acceleration isn't supported returns + * empty. + * + * @return {@link Translation3d} of the acceleration as an {@link Optional}. + */ + @Override + public Optional getAccel() + { + return Optional.of( + new Translation3d( + imu.getWorldLinearAccelX(), + imu.getWorldLinearAccelY(), + imu.getWorldLinearAccelZ()) + .times(9.81)); + } + + @Override + public MutAngularVelocity getYawAngularVelocity() + { + return yawVel.mut_setMagnitude(imu.getRate()); + } + + /** + * Get the instantiated NavX({@link AHRS}) IMU object. + * + * @return IMU object. + */ + @Override + public Object getIMU() + { + return imu; + } +} diff --git a/yagsl/java/swervelib/motors/ThriftyNovaSwerve.java b/yagsl/java/swervelib/motors/ThriftyNovaSwerve.java index bd9f6a4..f7f471e 100644 --- a/yagsl/java/swervelib/motors/ThriftyNovaSwerve.java +++ b/yagsl/java/swervelib/motors/ThriftyNovaSwerve.java @@ -1,539 +1,539 @@ -//// 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 swervelib.motors; -// -//import com.thethriftybot.devices.ThriftyNova; -//import com.thethriftybot.devices.ThriftyNova.CurrentType; -//import com.thethriftybot.devices.ThriftyNova.EncoderType; -//import com.thethriftybot.devices.ThriftyNova.PIDSlot; -//import com.thethriftybot.util.Conversion; -//import com.thethriftybot.util.Conversion.PositionUnit; -//import com.thethriftybot.util.Conversion.VelocityUnit; -//import java.util.List; -//import java.util.Optional; -//import java.util.function.Supplier; -// -// -//import edu.wpi.first.math.controller.PIDController; -//import edu.wpi.first.math.system.plant.DCMotor; -//import edu.wpi.first.wpilibj.DataLogManager; -//import edu.wpi.first.wpilibj.RobotBase; -//import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; -//import swervelib.encoders.SwerveAbsoluteEncoder; -//import swervelib.parser.PIDFConfig; -//import swervelib.telemetry.SwerveDriveTelemetry; -//import swervelib.telemetry.SwerveDriveTelemetry.TelemetryVerbosity; -// -///** -// * An implementation of {@link ThriftyNova} as a {@link SwerveMotor}. -// */ -//public class ThriftyNovaSwerve extends SwerveMotor -//{ -// -// /** -// * {@link DCMotor} for simulation and calculations. -// */ -// private final DCMotor simMotor; -// /** -// * Closed-loop PID controller. -// */ -// public PIDController pid; -// /** -// * ThriftyNova Instance. -// */ -// private ThriftyNova motor; -// /** -// * Factory default already occurred. -// */ -// private boolean factoryDefaultOccurred = false; -// /** -// * Position conversion object for the motor encoder -// */ -// private Conversion positionConversion; -// /** -// * Velocity conversion object for the motor encoder -// */ -// private Conversion velocityConversion; -// /** -// * The position conversion factor for the encoder -// */ -// private double positionConversionFactor = 1.0; -// /** -// * The position conversion factor for the encoder -// */ -// private double velocityConversionFactor = 1.0 / 60.0; -// /** -// * Absolute encoder attached to the SparkMax (if exists) -// */ -// private Optional absoluteEncoder = Optional.empty(); -// /** -// * Supplier for the velocity of the motor controller. -// */ -// private Supplier velocity; -// /** -// * Supplier for the position of the motor controller. -// */ -// private Supplier position; -// -// /** -// * Initialize the swerve motor. -// * -// * @param motor The SwerveMotor as a ThriftyNova object. -// * @param isDriveMotor Is the motor being initialized a drive motor? -// * @param motorType {@link DCMotor} controlled by the {@link ThriftyNova} -// */ -// public ThriftyNovaSwerve(ThriftyNova motor, boolean isDriveMotor, DCMotor motorType) -// { -// this.motor = motor; -// this.isDriveMotor = isDriveMotor; -// this.simMotor = motorType; -// factoryDefaults(); -// clearStickyFaults(); -// -// motor.usePIDSlot(PIDSlot.SLOT0); -// pid = new PIDController(0, 0, 0); -// motor.pid0.setPID(pid); -// -// if (isDriveMotor) -// { -// positionConversion = new Conversion(PositionUnit.ROTATIONS, EncoderType.INTERNAL); -// velocityConversion = new Conversion(VelocityUnit.ROTATIONS_PER_SEC, EncoderType.INTERNAL); -// } else -// { -// positionConversion = new Conversion(PositionUnit.ROTATIONS, EncoderType.INTERNAL); -// velocityConversion = new Conversion(VelocityUnit.ROTATIONS_PER_SEC, EncoderType.INTERNAL); -// } -// -// position = this::getConvertedPosition; -// velocity = this::getConvertedVelocity; -// } -// -// /** -// * Initialize the {@link SwerveMotor} as a {@link ThriftyNova} connected to a Brushless Motor. -// * -// * @param id CAN ID of the ThriftyNova. -// * @param isDriveMotor Is the motor being initialized a drive motor? -// * @param motor {@link DCMotor} controlled by the {@link ThriftyNova} -// */ -// public ThriftyNovaSwerve(int id, boolean isDriveMotor, DCMotor motor) -// { -// this(new ThriftyNova(id), isDriveMotor, motor); -// } -// -// /** -// * Close the motor controller and release any resources it may have acquired. -// * -// * @throws RuntimeException If an exception is thrown while closing the motor. -// */ -// @Override -// public void close() { -// try { -// motor.close(); -// } catch (Exception e) { -// throw new RuntimeException(e); -// } -// } -// -// private double getConvertedPosition() { -// double motorPosition = motor.getPosition(); -// double convertedPosition = motorPosition / positionConversionFactor; -// return convertedPosition; -// } -// -// /** -// * Get the velocity of the motor in meters per second or degrees per second after conversion. -// * -// * @return velocity in meters per second or degrees per second. -// */ -// private double getConvertedVelocity() { -// double motorVelocity = motor.getVelocity(); -// double convertedVelocity = motorVelocity / velocityConversionFactor; -// -// return convertedVelocity; -// } -// -// /** -// * Set factory defaults on the motor controller. -// */ -// @Override -// public void factoryDefaults() -// { -// // Factory defaults from https://docs.thethriftybot.com/thrifty-nova/gqCPUYXcVoOZ4KW3DqIr/software-resources/configure-controller-settings/factory-default -// if (!factoryDefaultOccurred) -// { -// if (RobotBase.isReal()) -// { -// motor.factoryReset(); -// } -// factoryDefaultOccurred = true; -// } -// } -// -// /** -// * Clear the sticky faults on the motor controller. -// */ -// @Override -// public void clearStickyFaults() -// { -// if (RobotBase.isReal()) { -// motor.clearErrors(); -// } -// } -// -// /** -// * Set the absolute encoder to be a compatible absolute encoder. -// * -// * @param encoder The encoder to use. -// * @return The {@link SwerveMotor} for easy instantiation. -// */ -// @Override -// public SwerveMotor setAbsoluteEncoder(SwerveAbsoluteEncoder encoder) -// { -// if (encoder == null) -// { -// motor.useEncoderType(EncoderType.INTERNAL); -// position = this::getConvertedPosition; -// velocity = this::getConvertedVelocity; -// } -// else -// { -// absoluteEncoder = Optional.of(encoder); -// position = absoluteEncoder.get()::getAbsolutePosition; -// velocity = absoluteEncoder.get()::getVelocity; -// motor.useEncoderType(EncoderType.ABS); -// } -// return this; -// } -// -// /** -// * Configure the integrated encoder for the ThriftyNova swerve module. Sets the conversion -// * factors for position and velocity, and configures the CAN status frames. -// * -// * @param positionConversionFactor The conversion factor to apply for position. -// */ -// @Override -// public void configureIntegratedEncoder(double positionConversionFactor) -// { -// this.positionConversionFactor = positionConversionFactor; -// this.velocityConversionFactor = positionConversionFactor; -// -// motor.useEncoderType(EncoderType.INTERNAL); -// configureCANStatusFrames(0.25, 0.01, 0.01, 0.02, 0.20); -// } -// -// /** -// * Set the CAN status frames. -// * -// * @param fault Fault transmission rate -// * @param sensor Sensor transmission rate -// * @param quadSensor External quad encoder transmission rate -// * @param control Control frame transmission rate -// * @param current Current feedback transmission rate -// */ -// public void configureCANStatusFrames( -// double fault, double sensor, double quadSensor, double control, double current) -// { -// if (RobotBase.isReal()) -// { -// motor.canFreq.setFault(fault); -// motor.canFreq.setSensor(sensor); -// motor.canFreq.setQuadSensor(quadSensor); -// motor.canFreq.setControl(control); -// motor.canFreq.setCurrent(current); -// checkErrors("Configuring CAN status frames failed: "); -// } -// } -// -// /** -// * Configure the PIDF values for the closed loop controller. 0 is disabled or off. -// * -// * @param config Configuration class holding the PIDF values. -// */ -// @Override -// public void configurePIDF(PIDFConfig config) -// { -// if (RobotBase.isReal()) -// { -// motor.pid0.setP(config.p).setI(config.i).setD(config.d); -// motor.usePIDSlot(PIDSlot.SLOT0); -// checkErrors("Configuring PIDF failed: "); -// } -// } -// -// /** -// * Configure the PID wrapping for the position closed loop controller. -// * -// * @param minInput Minimum PID input. -// * @param maxInput Maximum PID input. -// */ -// @Override -// public void configurePIDWrapping(double minInput, double maxInput) -// { -// // Do nothing -// } -// -// /** -// * Disable PID Wrapping on the motor. -// */ -// @Override -// public void disablePIDWrapping() -// { -// // Do nothing -// } -// -// /** -// * Set the idle mode. -// * -// * @param isBrakeMode Set the brake mode. -// */ -// @Override -// public void setMotorBrake(boolean isBrakeMode) -// { -// if (RobotBase.isReal()) { -// motor.setBrakeMode(isBrakeMode); -// checkErrors("Setting motor brake mode failed: "); -// } -// } -// -// /** -// * Set the motor to be inverted. -// * -// * @param inverted State of inversion. -// */ -// @Override -// public void setInverted(boolean inverted) -// { -// if (RobotBase.isReal()) { -// motor.setInverted(inverted); -// checkErrors("Setting motor inversion failed: "); -// } -// } -// -// /** -// * Save the configurations from flash to EEPROM. -// */ -// @Override -// public void burnFlash() -// { -// // Do nothing -// } -// -// /** -// * Set the percentage output. -// * -// * @param percentOutput percent out for the motor controller. -// */ -// @Override -// public void set(double percentOutput) -// { -// motor.setPercent(percentOutput); -// } -// -// /** -// * Set the closed loop PID controller reference point. -// * -// * @param setpoint Setpoint in MPS or Angle in degrees. -// * @param feedforward Feedforward in volt-meter-per-second or kV. -// */ -// @Override -// public void setReference(double setpoint, double feedforward) -// { -// setReference(setpoint, feedforward, getPosition()); -// } -// -// /** -// * Set the closed loop PID controller reference point. -// * -// * @param setpoint Setpoint in meters per second or angle in degrees. -// * @param feedforward Feedforward in volt-meter-per-second or kV. -// * @param position Only used on the angle motor, the position of the motor in degrees. -// */ -// @Override -// public void setReference(double setpoint, double feedforward, double position) -// { -// if (RobotBase.isReal()) { -// if (isDriveMotor) -// { -// double convertedSetpoint = setpoint / velocityConversionFactor; -// double motorSetpoint = velocityConversion.toMotor(convertedSetpoint); -// motor.setVelocity(motorSetpoint, feedforward); -// } else -// { -// double convertedSetpoint = absoluteEncoder.map(it -> setpoint).orElse(setpoint / positionConversionFactor); -// double motorSetpoint = positionConversion.toMotor(convertedSetpoint); -// motor.setPosition(motorSetpoint); -// } -// } -// } -// -// /** -// * Get the voltage output of the motor controller. -// * -// * @return Voltage output. -// */ -// @Override -// public double getVoltage() -// { -// return motor.getVoltage(); -// } -// -// /** -// * Set the voltage of the motor. -// * -// * @param voltage Voltage to set. -// */ -// @Override -// public void setVoltage(double voltage) -// { -// motor.setVoltage(voltage); -// } -// -// /** -// * Get the voltage output of the motor controller. -// * -// * @return Voltage output. -// */ -// @Override -// public double getAppliedOutput() -// { -// return motor.getStatorCurrent(); -// } -// -// /** -// * Get the velocity of the integrated encoder. -// * -// * @return velocity in Meters Per Second, or Degrees per Second. -// */ -// @Override -// public double getVelocity() -// { -// return velocity.get(); -// } -// -// /** -// * Get the position of the integrated encoder. -// * -// * @return Position in Meters or Degrees. -// */ -// @Override -// public double getPosition() -// { -// return position.get(); -// } -// -// /** -// * Set the integrated encoder position. -// * -// * @param position Integrated encoder position. Should be angle in degrees or meters. -// */ -// @Override -// public void setPosition(double position) -// { -// if (!absoluteEncoder.isPresent()) -// { -// double convertedPosition = position / positionConversionFactor; -// double motorPosition = positionConversion.toMotor(convertedPosition); -// motor.setEncoderPosition(motorPosition); -// } -// } -// -// /** -// * Set the voltage compensation for the swerve module motor. -// * -// * @param nominalVoltage Nominal voltage for operation to output to. -// */ -// @Override -// public void setVoltageCompensation(double nominalVoltage) -// { -// motor.setVoltageCompensation(nominalVoltage); -// } -// -// /** -// * Set the current limit for the swerve drive motor, remember this may cause jumping if used in conjunction with -// * voltage compensation. This is useful to protect the motor from current spikes. -// * -// * @param currentLimit Current limit in AMPS at free speed. -// */ -// @Override -// public void setCurrentLimit(int currentLimit) -// { -// if (RobotBase.isReal()) { -// motor.setMaxCurrent(CurrentType.STATOR, currentLimit); -// checkErrors("Setting current limit failed: "); -// } -// } -// -// /** -// * Set the maximum rate the open/closed loop output can change by. -// * -// * @param rampRate Time in seconds to go from 0 to full throttle. -// */ -// @Override -// public void setLoopRampRate(double rampRate) -// { -// if (RobotBase.isReal()) { -// motor.setRampUp(rampRate); -// motor.setRampDown(rampRate); -// checkErrors("Setting loop ramp rate failed: "); -// } -// } -// -// /** -// * Get the motor object from the module. -// * -// * @return Motor object. -// */ -// @Override -// public Object getMotor() -// { -// return motor; -// } -// -// /** -// * Queries whether the absolute encoder is directly attached to the motor controller. -// * -// * @return connected absolute encoder state. -// */ -// @Override -// public boolean usingExternalFeedbackSensor() -// { -// return absoluteEncoder.isPresent(); -// } -// -// /** -// * Checks for errors in the motor and logs them if any are found. -// * -// * @param message the message to prepend to the log and print statement -// */ -// private void checkErrors(String message) -// { -// if (SwerveDriveTelemetry.verbosity.ordinal() >= TelemetryVerbosity.HIGH.ordinal()) -// { -// List errors = motor.getErrors(); -// if (errors.size() > 0) -// { -// for (ThriftyNova.Error error : errors) -// { -// if (SwerveDriveTelemetry.verbosity.ordinal() >= TelemetryVerbosity.MACHINE.ordinal()) { -// System.out.println(this.getClass().getSimpleName() + ": " + message + error.toString()); -// } -// DataLogManager.log(this.getClass().getSimpleName() + ": " + message + error.toString()); -// } -// } -// motor.clearErrors(); -// } -// } -// -// /** -// * Get the simulated {@link DCMotor} associated with this motor controller. -// * -// * @return Simulated {@link DCMotor} instance. -// */ -// @Override -// public DCMotor getSimMotor() -// { -// return simMotor; -// } -//} +// 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 swervelib.motors; + +import com.thethriftybot.devices.ThriftyNova; +import com.thethriftybot.devices.ThriftyNova.CurrentType; +import com.thethriftybot.devices.ThriftyNova.EncoderType; +import com.thethriftybot.devices.ThriftyNova.PIDSlot; +import com.thethriftybot.util.Conversion; +import com.thethriftybot.util.Conversion.PositionUnit; +import com.thethriftybot.util.Conversion.VelocityUnit; +import java.util.List; +import java.util.Optional; +import java.util.function.Supplier; + + +import edu.wpi.first.math.controller.PIDController; +import edu.wpi.first.math.system.plant.DCMotor; +import edu.wpi.first.wpilibj.DataLogManager; +import edu.wpi.first.wpilibj.RobotBase; +import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; +import swervelib.encoders.SwerveAbsoluteEncoder; +import swervelib.parser.PIDFConfig; +import swervelib.telemetry.SwerveDriveTelemetry; +import swervelib.telemetry.SwerveDriveTelemetry.TelemetryVerbosity; + +/** + * An implementation of {@link ThriftyNova} as a {@link SwerveMotor}. + */ +public class ThriftyNovaSwerve extends SwerveMotor +{ + + /** + * {@link DCMotor} for simulation and calculations. + */ + private final DCMotor simMotor; + /** + * Closed-loop PID controller. + */ + public PIDController pid; + /** + * ThriftyNova Instance. + */ + private ThriftyNova motor; + /** + * Factory default already occurred. + */ + private boolean factoryDefaultOccurred = false; + /** + * Position conversion object for the motor encoder + */ + private Conversion positionConversion; + /** + * Velocity conversion object for the motor encoder + */ + private Conversion velocityConversion; + /** + * The position conversion factor for the encoder + */ + private double positionConversionFactor = 1.0; + /** + * The position conversion factor for the encoder + */ + private double velocityConversionFactor = 1.0 / 60.0; + /** + * Absolute encoder attached to the SparkMax (if exists) + */ + private Optional absoluteEncoder = Optional.empty(); + /** + * Supplier for the velocity of the motor controller. + */ + private Supplier velocity; + /** + * Supplier for the position of the motor controller. + */ + private Supplier position; + + /** + * Initialize the swerve motor. + * + * @param motor The SwerveMotor as a ThriftyNova object. + * @param isDriveMotor Is the motor being initialized a drive motor? + * @param motorType {@link DCMotor} controlled by the {@link ThriftyNova} + */ + public ThriftyNovaSwerve(ThriftyNova motor, boolean isDriveMotor, DCMotor motorType) + { + this.motor = motor; + this.isDriveMotor = isDriveMotor; + this.simMotor = motorType; + factoryDefaults(); + clearStickyFaults(); + + motor.usePIDSlot(PIDSlot.SLOT0); + pid = new PIDController(0, 0, 0); + motor.pid0.setPID(pid); + + if (isDriveMotor) + { + positionConversion = new Conversion(PositionUnit.ROTATIONS, EncoderType.INTERNAL); + velocityConversion = new Conversion(VelocityUnit.ROTATIONS_PER_SEC, EncoderType.INTERNAL); + } else + { + positionConversion = new Conversion(PositionUnit.ROTATIONS, EncoderType.INTERNAL); + velocityConversion = new Conversion(VelocityUnit.ROTATIONS_PER_SEC, EncoderType.INTERNAL); + } + + position = this::getConvertedPosition; + velocity = this::getConvertedVelocity; + } + + /** + * Initialize the {@link SwerveMotor} as a {@link ThriftyNova} connected to a Brushless Motor. + * + * @param id CAN ID of the ThriftyNova. + * @param isDriveMotor Is the motor being initialized a drive motor? + * @param motor {@link DCMotor} controlled by the {@link ThriftyNova} + */ + public ThriftyNovaSwerve(int id, boolean isDriveMotor, DCMotor motor) + { + this(new ThriftyNova(id), isDriveMotor, motor); + } + + /** + * Close the motor controller and release any resources it may have acquired. + * + * @throws RuntimeException If an exception is thrown while closing the motor. + */ + @Override + public void close() { + try { + motor.close(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private double getConvertedPosition() { + double motorPosition = motor.getPosition(); + double convertedPosition = motorPosition / positionConversionFactor; + return convertedPosition; + } + + /** + * Get the velocity of the motor in meters per second or degrees per second after conversion. + * + * @return velocity in meters per second or degrees per second. + */ + private double getConvertedVelocity() { + double motorVelocity = motor.getVelocity(); + double convertedVelocity = motorVelocity / velocityConversionFactor; + + return convertedVelocity; + } + + /** + * Set factory defaults on the motor controller. + */ + @Override + public void factoryDefaults() + { + // Factory defaults from https://docs.thethriftybot.com/thrifty-nova/gqCPUYXcVoOZ4KW3DqIr/software-resources/configure-controller-settings/factory-default + if (!factoryDefaultOccurred) + { + if (RobotBase.isReal()) + { + motor.factoryReset(); + } + factoryDefaultOccurred = true; + } + } + + /** + * Clear the sticky faults on the motor controller. + */ + @Override + public void clearStickyFaults() + { + if (RobotBase.isReal()) { + motor.clearErrors(); + } + } + + /** + * Set the absolute encoder to be a compatible absolute encoder. + * + * @param encoder The encoder to use. + * @return The {@link SwerveMotor} for easy instantiation. + */ + @Override + public SwerveMotor setAbsoluteEncoder(SwerveAbsoluteEncoder encoder) + { + if (encoder == null) + { + motor.useEncoderType(EncoderType.INTERNAL); + position = this::getConvertedPosition; + velocity = this::getConvertedVelocity; + } + else + { + absoluteEncoder = Optional.of(encoder); + position = absoluteEncoder.get()::getAbsolutePosition; + velocity = absoluteEncoder.get()::getVelocity; + motor.useEncoderType(EncoderType.ABS); + } + return this; + } + + /** + * Configure the integrated encoder for the ThriftyNova swerve module. Sets the conversion + * factors for position and velocity, and configures the CAN status frames. + * + * @param positionConversionFactor The conversion factor to apply for position. + */ + @Override + public void configureIntegratedEncoder(double positionConversionFactor) + { + this.positionConversionFactor = positionConversionFactor; + this.velocityConversionFactor = positionConversionFactor; + + motor.useEncoderType(EncoderType.INTERNAL); + configureCANStatusFrames(0.25, 0.01, 0.01, 0.02, 0.20); + } + + /** + * Set the CAN status frames. + * + * @param fault Fault transmission rate + * @param sensor Sensor transmission rate + * @param quadSensor External quad encoder transmission rate + * @param control Control frame transmission rate + * @param current Current feedback transmission rate + */ + public void configureCANStatusFrames( + double fault, double sensor, double quadSensor, double control, double current) + { + if (RobotBase.isReal()) + { + motor.canFreq.setFault(fault); + motor.canFreq.setSensor(sensor); + motor.canFreq.setQuadSensor(quadSensor); + motor.canFreq.setControl(control); + motor.canFreq.setCurrent(current); + checkErrors("Configuring CAN status frames failed: "); + } + } + + /** + * Configure the PIDF values for the closed loop controller. 0 is disabled or off. + * + * @param config Configuration class holding the PIDF values. + */ + @Override + public void configurePIDF(PIDFConfig config) + { + if (RobotBase.isReal()) + { + motor.pid0.setP(config.p).setI(config.i).setD(config.d); + motor.usePIDSlot(PIDSlot.SLOT0); + checkErrors("Configuring PIDF failed: "); + } + } + + /** + * Configure the PID wrapping for the position closed loop controller. + * + * @param minInput Minimum PID input. + * @param maxInput Maximum PID input. + */ + @Override + public void configurePIDWrapping(double minInput, double maxInput) + { + // Do nothing + } + + /** + * Disable PID Wrapping on the motor. + */ + @Override + public void disablePIDWrapping() + { + // Do nothing + } + + /** + * Set the idle mode. + * + * @param isBrakeMode Set the brake mode. + */ + @Override + public void setMotorBrake(boolean isBrakeMode) + { + if (RobotBase.isReal()) { + motor.setBrakeMode(isBrakeMode); + checkErrors("Setting motor brake mode failed: "); + } + } + + /** + * Set the motor to be inverted. + * + * @param inverted State of inversion. + */ + @Override + public void setInverted(boolean inverted) + { + if (RobotBase.isReal()) { + motor.setInverted(inverted); + checkErrors("Setting motor inversion failed: "); + } + } + + /** + * Save the configurations from flash to EEPROM. + */ + @Override + public void burnFlash() + { + // Do nothing + } + + /** + * Set the percentage output. + * + * @param percentOutput percent out for the motor controller. + */ + @Override + public void set(double percentOutput) + { + motor.setPercent(percentOutput); + } + + /** + * Set the closed loop PID controller reference point. + * + * @param setpoint Setpoint in MPS or Angle in degrees. + * @param feedforward Feedforward in volt-meter-per-second or kV. + */ + @Override + public void setReference(double setpoint, double feedforward) + { + setReference(setpoint, feedforward, getPosition()); + } + + /** + * Set the closed loop PID controller reference point. + * + * @param setpoint Setpoint in meters per second or angle in degrees. + * @param feedforward Feedforward in volt-meter-per-second or kV. + * @param position Only used on the angle motor, the position of the motor in degrees. + */ + @Override + public void setReference(double setpoint, double feedforward, double position) + { + if (RobotBase.isReal()) { + if (isDriveMotor) + { + double convertedSetpoint = setpoint / velocityConversionFactor; + double motorSetpoint = velocityConversion.toMotor(convertedSetpoint); + motor.setVelocity(motorSetpoint, feedforward); + } else + { + double convertedSetpoint = absoluteEncoder.map(it -> setpoint).orElse(setpoint / positionConversionFactor); + double motorSetpoint = positionConversion.toMotor(convertedSetpoint); + motor.setPosition(motorSetpoint); + } + } + } + + /** + * Get the voltage output of the motor controller. + * + * @return Voltage output. + */ + @Override + public double getVoltage() + { + return motor.getVoltage(); + } + + /** + * Set the voltage of the motor. + * + * @param voltage Voltage to set. + */ + @Override + public void setVoltage(double voltage) + { + motor.setVoltage(voltage); + } + + /** + * Get the voltage output of the motor controller. + * + * @return Voltage output. + */ + @Override + public double getAppliedOutput() + { + return motor.getStatorCurrent(); + } + + /** + * Get the velocity of the integrated encoder. + * + * @return velocity in Meters Per Second, or Degrees per Second. + */ + @Override + public double getVelocity() + { + return velocity.get(); + } + + /** + * Get the position of the integrated encoder. + * + * @return Position in Meters or Degrees. + */ + @Override + public double getPosition() + { + return position.get(); + } + + /** + * Set the integrated encoder position. + * + * @param position Integrated encoder position. Should be angle in degrees or meters. + */ + @Override + public void setPosition(double position) + { + if (!absoluteEncoder.isPresent()) + { + double convertedPosition = position / positionConversionFactor; + double motorPosition = positionConversion.toMotor(convertedPosition); + motor.setEncoderPosition(motorPosition); + } + } + + /** + * Set the voltage compensation for the swerve module motor. + * + * @param nominalVoltage Nominal voltage for operation to output to. + */ + @Override + public void setVoltageCompensation(double nominalVoltage) + { + motor.setVoltageCompensation(nominalVoltage); + } + + /** + * Set the current limit for the swerve drive motor, remember this may cause jumping if used in conjunction with + * voltage compensation. This is useful to protect the motor from current spikes. + * + * @param currentLimit Current limit in AMPS at free speed. + */ + @Override + public void setCurrentLimit(int currentLimit) + { + if (RobotBase.isReal()) { + motor.setMaxCurrent(CurrentType.STATOR, currentLimit); + checkErrors("Setting current limit failed: "); + } + } + + /** + * Set the maximum rate the open/closed loop output can change by. + * + * @param rampRate Time in seconds to go from 0 to full throttle. + */ + @Override + public void setLoopRampRate(double rampRate) + { + if (RobotBase.isReal()) { + motor.setRampUp(rampRate); + motor.setRampDown(rampRate); + checkErrors("Setting loop ramp rate failed: "); + } + } + + /** + * Get the motor object from the module. + * + * @return Motor object. + */ + @Override + public Object getMotor() + { + return motor; + } + + /** + * Queries whether the absolute encoder is directly attached to the motor controller. + * + * @return connected absolute encoder state. + */ + @Override + public boolean usingExternalFeedbackSensor() + { + return absoluteEncoder.isPresent(); + } + + /** + * Checks for errors in the motor and logs them if any are found. + * + * @param message the message to prepend to the log and print statement + */ + private void checkErrors(String message) + { + if (SwerveDriveTelemetry.verbosity.ordinal() >= TelemetryVerbosity.HIGH.ordinal()) + { + List errors = motor.getErrors(); + if (errors.size() > 0) + { + for (ThriftyNova.Error error : errors) + { + if (SwerveDriveTelemetry.verbosity.ordinal() >= TelemetryVerbosity.MACHINE.ordinal()) { + System.out.println(this.getClass().getSimpleName() + ": " + message + error.toString()); + } + DataLogManager.log(this.getClass().getSimpleName() + ": " + message + error.toString()); + } + } + motor.clearErrors(); + } + } + + /** + * Get the simulated {@link DCMotor} associated with this motor controller. + * + * @return Simulated {@link DCMotor} instance. + */ + @Override + public DCMotor getSimMotor() + { + return simMotor; + } +} diff --git a/yagsl/java/swervelib/parser/json/DeviceJson.java b/yagsl/java/swervelib/parser/json/DeviceJson.java index 340bc2b..b94cbaf 100644 --- a/yagsl/java/swervelib/parser/json/DeviceJson.java +++ b/yagsl/java/swervelib/parser/json/DeviceJson.java @@ -5,13 +5,13 @@ import static swervelib.telemetry.SwerveDriveTelemetry.serialCommsIssueWarning; import com.ctre.phoenix.motorcontrol.FeedbackDevice; -//import com.studica.frc.AHRS.NavXComType; +import com.studica.frc.AHRS.NavXComType; import edu.wpi.first.math.system.plant.DCMotor; import edu.wpi.first.wpilibj.DriverStation; import swervelib.encoders.AnalogAbsoluteEncoderSwerve; import swervelib.encoders.CANCoderSwerve; -//import swervelib.encoders.CanAndMagSwerve; +import swervelib.encoders.CanAndMagSwerve; import swervelib.encoders.DIODutyCycleEncoderSwerve; import swervelib.encoders.SparkFlexEncoderSwerve; import swervelib.encoders.SparkMaxAnalogEncoderSwerve; @@ -22,9 +22,9 @@ import swervelib.imu.ADIS16470Swerve; import swervelib.imu.ADXRS450Swerve; import swervelib.imu.AnalogGyroSwerve; -//import swervelib.imu.CanandgyroSwerve; -//import swervelib.imu.NavX3Swerve; -//import swervelib.imu.NavXSwerve; +import swervelib.imu.CanandgyroSwerve; +import swervelib.imu.NavX3Swerve; +import swervelib.imu.NavXSwerve; import swervelib.imu.Pigeon2Swerve; import swervelib.imu.PigeonSwerve; import swervelib.imu.PigeonViaTalonSRXSwerve; @@ -37,7 +37,7 @@ import swervelib.motors.TalonFXSSwerve; import swervelib.motors.TalonFXSwerve; import swervelib.motors.TalonSRXSwerve; -//import swervelib.motors.ThriftyNovaSwerve; +import swervelib.motors.ThriftyNovaSwerve; import swervelib.parser.deserializer.ReflectionsManager; import swervelib.parser.deserializer.ReflectionsManager.VENDOR; @@ -92,8 +92,8 @@ public SwerveAbsoluteEncoder createEncoder(SwerveMotor motor) case "sparkflex_canandcoder": return new SparkFlexEncoderSwerve(motor, 360); case "canandcoder_can": -// case "canandmag_can": -// return new CanAndMagSwerve(id); + case "canandmag_can": + return new CanAndMagSwerve(id); case "ctre_mag": case "rev_hex": case "throughbore": @@ -154,29 +154,29 @@ public SwerveIMU createIMU() return new ADXRS450Swerve(); case "analog": return new AnalogGyroSwerve(id); -// case "canandgyro": -// return new CanandgyroSwerve(id); -// case "navx": -// case "navx_spi": -// return new NavXSwerve(NavXComType.kMXP_SPI); -// case "navx3": -// return new NavX3Swerve(id); -// case "navx_i2c": -// DriverStation.reportWarning( -// "WARNING: There exists an I2C lockup issue on the roboRIO that could occur, more information here: " + -// "\nhttps://docs.wpilib.org/en/stable/docs/yearly-overview/known-issues" + -// ".html#onboard-i2c-causing-system-lockups", -// false); -// i2cLockupWarning.set(true); -// return new NavXSwerve(NavXComType.kI2C); -// case "navx_usb": -// DriverStation.reportWarning("WARNING: There is issues when using USB camera's and the NavX like this!\n" + -// "https://pdocs.kauailabs.com/navx-mxp/guidance/selecting-an-interface/", false); -// serialCommsIssueWarning.set(true); -// return new NavXSwerve(NavXComType.kUSB1); -// case "navx_mxp_serial": -// serialCommsIssueWarning.set(true); -// return new NavXSwerve(NavXComType.kMXP_UART); + case "canandgyro": + return new CanandgyroSwerve(id); + case "navx": + case "navx_spi": + return new NavXSwerve(NavXComType.kMXP_SPI); + case "navx3": + return new NavX3Swerve(id); + case "navx_i2c": + DriverStation.reportWarning( + "WARNING: There exists an I2C lockup issue on the roboRIO that could occur, more information here: " + + "\nhttps://docs.wpilib.org/en/stable/docs/yearly-overview/known-issues" + + ".html#onboard-i2c-causing-system-lockups", + false); + i2cLockupWarning.set(true); + return new NavXSwerve(NavXComType.kI2C); + case "navx_usb": + DriverStation.reportWarning("WARNING: There is issues when using USB camera's and the NavX like this!\n" + + "https://pdocs.kauailabs.com/navx-mxp/guidance/selecting-an-interface/", false); + serialCommsIssueWarning.set(true); + return new NavXSwerve(NavXComType.kUSB1); + case "navx_mxp_serial": + serialCommsIssueWarning.set(true); + return new NavXSwerve(NavXComType.kMXP_UART); case "pigeon": return new PigeonSwerve(id); case "pigeon_via_talonsrx": @@ -298,8 +298,8 @@ public SwerveMotor createMotor(boolean isDriveMotor) new Class[]{int.class, boolean.class, DCMotor.class}, new Object[]{id, isDriveMotor, DCMotor.getNeoVortex(1)}); -// case "nova_minion": -// return new ThriftyNovaSwerve(id, isDriveMotor, DCMotor.getMinion(1)); + case "nova_minion": + return new ThriftyNovaSwerve(id, isDriveMotor, DCMotor.getMinion(1)); case "nova_pulsar": throw new UnsupportedOperationException("Cannot create pulsar combination"); default: diff --git a/yagsl/java/swervelib/parser/json/ModuleJson.java b/yagsl/java/swervelib/parser/json/ModuleJson.java index b2b33a0..d2917e7 100644 --- a/yagsl/java/swervelib/parser/json/ModuleJson.java +++ b/yagsl/java/swervelib/parser/json/ModuleJson.java @@ -4,9 +4,9 @@ import edu.wpi.first.math.util.Units; import swervelib.encoders.SparkMaxEncoderSwerve; import swervelib.encoders.SwerveAbsoluteEncoder; -//import swervelib.encoders.ThriftyNovaEncoderSwerve; +import swervelib.encoders.ThriftyNovaEncoderSwerve; import swervelib.motors.SwerveMotor; -//import swervelib.motors.ThriftyNovaSwerve; +import swervelib.motors.ThriftyNovaSwerve; import swervelib.parser.PIDFConfig; import swervelib.parser.SwerveModuleConfiguration; import swervelib.parser.SwerveModulePhysicalCharacteristics; @@ -117,10 +117,10 @@ public SwerveModuleConfiguration createModuleConfiguration( { angleMotor.setAbsoluteEncoder(absEncoder); } -// else if ((absEncoder instanceof ThriftyNovaEncoderSwerve && angleMotor instanceof ThriftyNovaSwerve)) -// { -// angleMotor.setAbsoluteEncoder(absEncoder); -// } + else if ((absEncoder instanceof ThriftyNovaEncoderSwerve && angleMotor instanceof ThriftyNovaSwerve)) + { + angleMotor.setAbsoluteEncoder(absEncoder); + } return new SwerveModuleConfiguration( drive.createMotor(true), From 059acd7eaa72366fbecd75ff9bc61b5d233fc075 Mon Sep 17 00:00:00 2001 From: twisterjafla Date: Tue, 13 Jan 2026 00:05:16 -0700 Subject: [PATCH 14/62] retrobuzz changes --- .../simulation/ironmaple/simulation/Goal.java | 1 + .../simulation/gamepieces/GamePiece.java | 6 ++++++ .../gamepieces/GamePieceOnFieldSimulation.java | 5 +++++ .../gamepieces/GamePieceProjectile.java | 15 +++++++++++++++ .../rebuilt2026/RebuiltFuelOnFly.java | 17 ++++------------- .../reefscape2025/ReefscapeAlgaeOnFly.java | 11 ----------- 6 files changed, 31 insertions(+), 24 deletions(-) diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java index 4ca3343..ba0a493 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java @@ -139,6 +139,7 @@ public void simulationSubTick(int subTickNum) { gamePiece -> { // If a piece passes, score it. gamePieceCount++; this.addPoints(); + gamePiece.triggerHitTargeCallBack();; arena.removePiece(gamePiece); }); } diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePiece.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePiece.java index 68cb93d..424b38f 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePiece.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePiece.java @@ -42,6 +42,12 @@ public interface GamePiece { */ Translation3d getVelocity3dMPS(); + + /** + *

    Internal function called to trigger a callback whenever this game piece is scored in a goal

    + */ + public void triggerHitTargeCallBack(); + /** * * diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceOnFieldSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceOnFieldSimulation.java index 9c94425..55758a4 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceOnFieldSimulation.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceOnFieldSimulation.java @@ -179,4 +179,9 @@ public Translation3d getVelocity3dMPS() { public boolean isGrounded() { return true; } + + @Override + public void triggerHitTargeCallBack(){ + return; + } } diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceProjectile.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceProjectile.java index d4c589b..701a7d6 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceProjectile.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceProjectile.java @@ -654,4 +654,19 @@ public String getType() { public boolean isGrounded() { return false; } + + public void triggerHitTargeCallBack(){ + hitTargetCallBack.run(); + } + + /** + *

    Registers a function that will be called whenever this game piece interacts with a goal object or collides with the specified target.

    + * Note: Certain goals like the rebuilt hub or the reefscape processor appear to reintroduce scored pieces into the field. + * However these pieces are actually new objects and so will not save any call back functions. + * @param hitTargetCallBack The call back to be set. + */ + public void setHitTargetCallBack(Runnable hitTargetCallBack){ + this.hitTargetCallBack = hitTargetCallBack; + } + } diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltFuelOnFly.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltFuelOnFly.java index 608201c..412f3cc 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltFuelOnFly.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltFuelOnFly.java @@ -1,5 +1,6 @@ package swervelib.simulation.ironmaple.simulation.seasonspecific.rebuilt2026; +import static edu.wpi.first.units.Units.Centimeter; import static edu.wpi.first.units.Units.Inches; import static edu.wpi.first.units.Units.Meters; @@ -21,22 +22,12 @@ * *

    The simulation will determine if the FUEL hits its target—the HUB. * - *

    The user can specify a callback using {@link #setHitNetCallBack(Runnable)}, which will be triggered when the FUEL + *

    The user can specify a callback using {@link #setHitHubCallBack(Runnable)}, which will be triggered when the FUEL * hits the HUB. */ public class RebuiltFuelOnFly extends GamePieceProjectile { - private static Runnable hitNetCallBack = () -> {}; - /** - * - * - *

    Specifies a callback for when any fuel launched into the air hits the hub.

    - * - * @param callBack a {@link Runnable} to be invoked when an fuel hits the hub - */ - public static void setHitNetCallBack(Runnable callBack) { - hitNetCallBack = callBack; - } + public RebuiltFuelOnFly( Translation2d robotPosition, @@ -56,7 +47,7 @@ public RebuiltFuelOnFly( launchingSpeed, shooterAngle); - super.withTouchGroundHeight(Inches.of(3).in(Meters)); + super.withTouchGroundHeight(Centimeter.of(7.5).in(Meters)); super.enableBecomesGamePieceOnFieldAfterTouchGround(); } } diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeAlgaeOnFly.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeAlgaeOnFly.java index 89d7875..6041f95 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeAlgaeOnFly.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeAlgaeOnFly.java @@ -21,18 +21,7 @@ * hits the NET. */ public class ReefscapeAlgaeOnFly extends GamePieceProjectile { - private static Runnable hitNetCallBack = () -> System.out.println("hit target!"); - /** - * - * - *

    Specifies a callback for when any ALGAE launched into the air hits the NET.

    - * - * @param callBack a {@link Runnable} to be invoked when an ALGAE hits the NET - */ - public static void setHitNetCallBack(Runnable callBack) { - hitNetCallBack = callBack; - } public ReefscapeAlgaeOnFly( Translation2d robotPosition, From bba2b2a57bd8b646abe236ce22e2e91ba425762e Mon Sep 17 00:00:00 2001 From: twisterjafla Date: Tue, 13 Jan 2026 11:43:18 -0700 Subject: [PATCH 15/62] Fixed typo --- yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java | 2 +- .../simulation/ironmaple/simulation/gamepieces/GamePiece.java | 3 ++- .../simulation/gamepieces/GamePieceOnFieldSimulation.java | 2 +- .../ironmaple/simulation/gamepieces/GamePieceProjectile.java | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java index ba0a493..ed378c5 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java @@ -139,7 +139,7 @@ public void simulationSubTick(int subTickNum) { gamePiece -> { // If a piece passes, score it. gamePieceCount++; this.addPoints(); - gamePiece.triggerHitTargeCallBack();; + gamePiece.triggerHitTargetCallBack();; arena.removePiece(gamePiece); }); } diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePiece.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePiece.java index 424b38f..49952e5 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePiece.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePiece.java @@ -45,8 +45,9 @@ public interface GamePiece { /** *

    Internal function called to trigger a callback whenever this game piece is scored in a goal

    + * */ - public void triggerHitTargeCallBack(); + public void triggerHitTargetCallBack(); /** * diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceOnFieldSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceOnFieldSimulation.java index 55758a4..fcbc661 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceOnFieldSimulation.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceOnFieldSimulation.java @@ -181,7 +181,7 @@ public boolean isGrounded() { } @Override - public void triggerHitTargeCallBack(){ + public void triggerHitTargetCallBack(){ return; } } diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceProjectile.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceProjectile.java index 701a7d6..789dca7 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceProjectile.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceProjectile.java @@ -655,7 +655,7 @@ public boolean isGrounded() { return false; } - public void triggerHitTargeCallBack(){ + public void triggerHitTargetCallBack(){ hitTargetCallBack.run(); } From 2f799aa688105e4625a50370a3a5cfb2b782642d Mon Sep 17 00:00:00 2001 From: twisterjafla Date: Tue, 13 Jan 2026 13:09:57 -0700 Subject: [PATCH 16/62] removed bonus semi colon --- yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java index ed378c5..8cca5cb 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java @@ -139,7 +139,7 @@ public void simulationSubTick(int subTickNum) { gamePiece -> { // If a piece passes, score it. gamePieceCount++; this.addPoints(); - gamePiece.triggerHitTargetCallBack();; + gamePiece.triggerHitTargetCallBack(); arena.removePiece(gamePiece); }); } From 506f260d71f90c12bfc88b89096358db015ea8c7 Mon Sep 17 00:00:00 2001 From: twisterjafla Date: Tue, 13 Jan 2026 14:02:06 -0700 Subject: [PATCH 17/62] removed hit trigger callback --- .../simulation/ironmaple/simulation/Goal.java | 1 - .../ironmaple/simulation/gamepieces/GamePiece.java | 5 ----- .../gamepieces/GamePieceOnFieldSimulation.java | 4 ---- .../simulation/gamepieces/GamePieceProjectile.java | 14 -------------- 4 files changed, 24 deletions(-) diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java index 8cca5cb..4ca3343 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java @@ -139,7 +139,6 @@ public void simulationSubTick(int subTickNum) { gamePiece -> { // If a piece passes, score it. gamePieceCount++; this.addPoints(); - gamePiece.triggerHitTargetCallBack(); arena.removePiece(gamePiece); }); } diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePiece.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePiece.java index 49952e5..d445b10 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePiece.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePiece.java @@ -43,11 +43,6 @@ public interface GamePiece { Translation3d getVelocity3dMPS(); - /** - *

    Internal function called to trigger a callback whenever this game piece is scored in a goal

    - * - */ - public void triggerHitTargetCallBack(); /** * diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceOnFieldSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceOnFieldSimulation.java index fcbc661..55ea347 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceOnFieldSimulation.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceOnFieldSimulation.java @@ -180,8 +180,4 @@ public boolean isGrounded() { return true; } - @Override - public void triggerHitTargetCallBack(){ - return; - } } diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceProjectile.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceProjectile.java index 789dca7..118f8f9 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceProjectile.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/gamepieces/GamePieceProjectile.java @@ -655,18 +655,4 @@ public boolean isGrounded() { return false; } - public void triggerHitTargetCallBack(){ - hitTargetCallBack.run(); - } - - /** - *

    Registers a function that will be called whenever this game piece interacts with a goal object or collides with the specified target.

    - * Note: Certain goals like the rebuilt hub or the reefscape processor appear to reintroduce scored pieces into the field. - * However these pieces are actually new objects and so will not save any call back functions. - * @param hitTargetCallBack The call back to be set. - */ - public void setHitTargetCallBack(Runnable hitTargetCallBack){ - this.hitTargetCallBack = hitTargetCallBack; - } - } From f2143a0600f63f7f95cff1ac3bdc014834c0e42d Mon Sep 17 00:00:00 2001 From: twisterjafla Date: Tue, 13 Jan 2026 15:57:08 -0700 Subject: [PATCH 18/62] updated fuel weight --- .../seasonspecific/rebuilt2026/RebuiltFuelOnField.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltFuelOnField.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltFuelOnField.java index 31714bf..a95301f 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltFuelOnField.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltFuelOnField.java @@ -17,7 +17,7 @@ */ public class RebuiltFuelOnField extends GamePieceOnFieldSimulation { public static final GamePieceInfo REBUILT_FUEL_INFO = new GamePieceInfo( - "Fuel", new Circle(Centimeters.of(7.5).in(Meters)), Centimeter.of(15), Kilograms.of(2.13), 1.8, 5, 0.8); + "Fuel", new Circle(Centimeters.of(7.5).in(Meters)), Centimeter.of(15), Pounds.of(0.5), 1.8, 5, 0.8); public RebuiltFuelOnField(Translation2d initialPosition) { super(REBUILT_FUEL_INFO, new Pose2d(initialPosition, new Rotation2d())); From ea558de82bbdf2cc69b96b33e45aa6840dfd034e Mon Sep 17 00:00:00 2001 From: twisterjafla <122408604+twisterjafla@users.noreply.github.com> Date: Tue, 13 Jan 2026 23:21:31 -0700 Subject: [PATCH 19/62] updated vendor dep error messages for clarity (#10) --- vendordep/yagsl.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/vendordep/yagsl.json b/vendordep/yagsl.json index 245e884..9a53630 100644 --- a/vendordep/yagsl.json +++ b/vendordep/yagsl.json @@ -35,24 +35,25 @@ "onlineUrl": "https://software-metadata.revrobotics.com/REVLib-2026.json" }, { + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", - "errorMessage": "Phoenix6 is required!", + "errorMessage": "Phoenix6 Replay is required!", "offlineFileName": "Phoenix6-replay-26.1.0.json", "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-latest.json" }, { "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", - "errorMessage": "Phoenix5 is required!", + "errorMessage": "Phoenix5 Replay Compatibility is required!", "offlineFileName": "Phoenix5-replay-5.36.0.json", "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-latest.json" }, { "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", - "errorMessage": "Studica is required!", + "errorMessage": "Studica Lib is required!", "offlineFileName": "StudicaLib.json", "onlineUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.0.json" }, - { + { "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", "errorMessage": "Studica is required!", "offlineFileName": "Studica.json", From 0b8500a37db8cdc7d1275187e0a4f0ea813e7c70 Mon Sep 17 00:00:00 2001 From: T Grinch <10247070+thenetworkgrinch@users.noreply.github.com> Date: Wed, 14 Jan 2026 10:08:19 -0600 Subject: [PATCH 20/62] Update config.gradle --- vendordep/config.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendordep/config.gradle b/vendordep/config.gradle index a6d008c..0e1f0cb 100644 --- a/vendordep/config.gradle +++ b/vendordep/config.gradle @@ -8,7 +8,7 @@ nativeUtils { configureDependencies { wpiVersion = wpilibVersion opencvYear = "frc2025" - niLibVersion = "2025.0.0" + niLibVersion = "2026.1.0" opencvVersion = "4.10.0-2" } } From 44135d59ac94751ab0634f8bcbc76ac1a191b1f6 Mon Sep 17 00:00:00 2001 From: thenetworkgrinch Date: Wed, 14 Jan 2026 10:46:49 -0600 Subject: [PATCH 21/62] Made studicalib reflective. Signed-off-by: thenetworkgrinch --- vendordep/yagsl.json | 12 -------- yagsl/java/swervelib/imu/NavXSwerve.java | 22 +++++++++++++++ .../parser/SwerveDriveConfiguration.java | 5 ---- .../deserializer/ReflectionsManager.java | 8 +++++- .../swervelib/parser/json/DeviceJson.java | 28 +++++++++++++------ 5 files changed, 49 insertions(+), 26 deletions(-) diff --git a/vendordep/yagsl.json b/vendordep/yagsl.json index 9a53630..544b27e 100644 --- a/vendordep/yagsl.json +++ b/vendordep/yagsl.json @@ -47,18 +47,6 @@ "offlineFileName": "Phoenix5-replay-5.36.0.json", "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-latest.json" }, - { - "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", - "errorMessage": "Studica Lib is required!", - "offlineFileName": "StudicaLib.json", - "onlineUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.0.json" - }, - { - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", - "errorMessage": "Studica is required!", - "offlineFileName": "Studica.json", - "onlineUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0.json" - }, { "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", "errorMessage": "ThriftyLib is required!", diff --git a/yagsl/java/swervelib/imu/NavXSwerve.java b/yagsl/java/swervelib/imu/NavXSwerve.java index 071f3a1..c4b8322 100644 --- a/yagsl/java/swervelib/imu/NavXSwerve.java +++ b/yagsl/java/swervelib/imu/NavXSwerve.java @@ -60,6 +60,28 @@ public NavXSwerve(NavXComType port) } } + /** + * Constructor for the NavX({@link AHRS}) swerve. + * + * @param port Serial Port to connect to. + */ + public NavXSwerve(String port) + { + navXError = new Alert("IMU", "Error instantiating NavX.", AlertType.kError); + try + { + /* Communicate w/navX-MXP via the MXP SPI Bus. */ + /* Alternatively: I2C.Port.kMXP, SerialPort.Port.kMXP or SerialPort.Port.kUSB */ + /* See http://navx-mxp.kauailabs.com/guidance/selecting-an-interface/ for details. */ + imu = new AHRS(NavXComType.valueOf(port)); + factoryDefault(); + } catch (RuntimeException ex) + { + navXError.setText("Error instantiating NavX: " + ex.getMessage()); + navXError.set(true); + } + } + @Override public void close() { diff --git a/yagsl/java/swervelib/parser/SwerveDriveConfiguration.java b/yagsl/java/swervelib/parser/SwerveDriveConfiguration.java index 4d724d7..653a4a3 100644 --- a/yagsl/java/swervelib/parser/SwerveDriveConfiguration.java +++ b/yagsl/java/swervelib/parser/SwerveDriveConfiguration.java @@ -6,7 +6,6 @@ import swervelib.simulation.ironmaple.simulation.drivesims.COTS; import swervelib.simulation.ironmaple.simulation.drivesims.GyroSimulation; import swervelib.SwerveModule; -//import swervelib.imu.NavXSwerve; import swervelib.imu.Pigeon2Swerve; import swervelib.imu.SwerveIMU; import swervelib.math.SwerveMath; @@ -156,10 +155,6 @@ public Supplier getGyroSim() { return COTS.ofPigeon2(); } -// else if (imu instanceof NavXSwerve) -// { -// return COTS.ofNav2X(); -// } return COTS.ofGenericGyro(); } diff --git a/yagsl/java/swervelib/parser/deserializer/ReflectionsManager.java b/yagsl/java/swervelib/parser/deserializer/ReflectionsManager.java index f889522..999bdbb 100644 --- a/yagsl/java/swervelib/parser/deserializer/ReflectionsManager.java +++ b/yagsl/java/swervelib/parser/deserializer/ReflectionsManager.java @@ -27,7 +27,8 @@ public enum VENDOR /** * StudicaLib */ - STUDICA + STUDICA, + STUDICA2 } /** @@ -68,6 +69,11 @@ public static boolean checkIfVendorLibExists(VENDOR vendor) library = Class.forName("com.studica.frc.AHRS"); break; } + case STUDICA2 -> + { + library = Class.forName("com.studica.frc.Navx"); + break; + } default -> { return false; diff --git a/yagsl/java/swervelib/parser/json/DeviceJson.java b/yagsl/java/swervelib/parser/json/DeviceJson.java index b94cbaf..5e85f6c 100644 --- a/yagsl/java/swervelib/parser/json/DeviceJson.java +++ b/yagsl/java/swervelib/parser/json/DeviceJson.java @@ -5,7 +5,6 @@ import static swervelib.telemetry.SwerveDriveTelemetry.serialCommsIssueWarning; import com.ctre.phoenix.motorcontrol.FeedbackDevice; -import com.studica.frc.AHRS.NavXComType; import edu.wpi.first.math.system.plant.DCMotor; import edu.wpi.first.wpilibj.DriverStation; @@ -23,8 +22,6 @@ import swervelib.imu.ADXRS450Swerve; import swervelib.imu.AnalogGyroSwerve; import swervelib.imu.CanandgyroSwerve; -import swervelib.imu.NavX3Swerve; -import swervelib.imu.NavXSwerve; import swervelib.imu.Pigeon2Swerve; import swervelib.imu.PigeonSwerve; import swervelib.imu.PigeonViaTalonSRXSwerve; @@ -158,9 +155,15 @@ public SwerveIMU createIMU() return new CanandgyroSwerve(id); case "navx": case "navx_spi": - return new NavXSwerve(NavXComType.kMXP_SPI); + return ReflectionsManager.create(VENDOR.STUDICA, + "swervelib.imu.NavXSwerve", + new Class[]{String.class}, + new Object[]{"kMXP_SPI"}); case "navx3": - return new NavX3Swerve(id); + return ReflectionsManager.create(VENDOR.STUDICA2, + "swervelib.imu.NavX3Swerve", + new Class[]{Integer.class}, + new Object[]{id}); case "navx_i2c": DriverStation.reportWarning( "WARNING: There exists an I2C lockup issue on the roboRIO that could occur, more information here: " + @@ -168,15 +171,24 @@ public SwerveIMU createIMU() ".html#onboard-i2c-causing-system-lockups", false); i2cLockupWarning.set(true); - return new NavXSwerve(NavXComType.kI2C); + return ReflectionsManager.create(VENDOR.STUDICA, + "swervelib.imu.NavXSwerve", + new Class[]{String.class}, + new Object[]{"kI2C"}); case "navx_usb": DriverStation.reportWarning("WARNING: There is issues when using USB camera's and the NavX like this!\n" + "https://pdocs.kauailabs.com/navx-mxp/guidance/selecting-an-interface/", false); serialCommsIssueWarning.set(true); - return new NavXSwerve(NavXComType.kUSB1); + return ReflectionsManager.create(VENDOR.STUDICA, + "swervelib.imu.NavXSwerve", + new Class[]{String.class}, + new Object[]{"kUSB1"}); case "navx_mxp_serial": serialCommsIssueWarning.set(true); - return new NavXSwerve(NavXComType.kMXP_UART); + return ReflectionsManager.create(VENDOR.STUDICA, + "swervelib.imu.NavXSwerve", + new Class[]{String.class}, + new Object[]{"kMXP_UART"}); case "pigeon": return new PigeonSwerve(id); case "pigeon_via_talonsrx": From 917469eb95fdfce039116fc6c4de8a525ee4920c Mon Sep 17 00:00:00 2001 From: twisterjafla <122408604+twisterjafla@users.noreply.github.com> Date: Wed, 14 Jan 2026 17:07:17 -0700 Subject: [PATCH 22/62] Removed an extra println (#11) --- vendordep/yagsl.json | 1 - .../simulation/seasonspecific/rebuilt2026/RebuiltHub.java | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/vendordep/yagsl.json b/vendordep/yagsl.json index 544b27e..b974014 100644 --- a/vendordep/yagsl.json +++ b/vendordep/yagsl.json @@ -35,7 +35,6 @@ "onlineUrl": "https://software-metadata.revrobotics.com/REVLib-2026.json" }, { - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", "errorMessage": "Phoenix6 Replay is required!", "offlineFileName": "Phoenix6-replay-26.1.0.json", diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltHub.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltHub.java index 36a685e..687a808 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltHub.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltHub.java @@ -86,9 +86,7 @@ protected boolean checkVel(GamePiece gamePiece) { @Override protected boolean checkCollision(GamePiece GamePiece) { - System.out.println(Math.pow(GamePiece.getPose3d().getX() - position.getX(), 2) - + Math.pow(GamePiece.getPose3d().getY() - position.getY(), 2) - + Math.pow(GamePiece.getPose3d().getZ() - position.getZ(), 2)); + return Math.pow(GamePiece.getPose3d().getX() - position.getX(), 2) + Math.pow(GamePiece.getPose3d().getY() - position.getY(), 2) + Math.pow(GamePiece.getPose3d().getZ() - position.getZ(), 2) From 6cbfda2df1facf395d1a66cdae865d18d626a7e0 Mon Sep 17 00:00:00 2001 From: thenetworkgrinch Date: Sat, 17 Jan 2026 10:29:08 -0600 Subject: [PATCH 23/62] Added TalonFXSEncoderAnalogSwerve Signed-off-by: thenetworkgrinch --- vendordep/config.gradle | 2 +- .../encoders/TalonFXSEncoderAnalogSwerve.java | 100 ++++++++++++++++++ .../swervelib/parser/json/DeviceJson.java | 3 + 3 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 yagsl/java/swervelib/encoders/TalonFXSEncoderAnalogSwerve.java diff --git a/vendordep/config.gradle b/vendordep/config.gradle index 0e1f0cb..cad08d2 100644 --- a/vendordep/config.gradle +++ b/vendordep/config.gradle @@ -8,7 +8,7 @@ nativeUtils { configureDependencies { wpiVersion = wpilibVersion opencvYear = "frc2025" - niLibVersion = "2026.1.0" + niLibVersion = "2026.1.2" opencvVersion = "4.10.0-2" } } diff --git a/yagsl/java/swervelib/encoders/TalonFXSEncoderAnalogSwerve.java b/yagsl/java/swervelib/encoders/TalonFXSEncoderAnalogSwerve.java new file mode 100644 index 0000000..193dc01 --- /dev/null +++ b/yagsl/java/swervelib/encoders/TalonFXSEncoderAnalogSwerve.java @@ -0,0 +1,100 @@ +package swervelib.encoders; + +import static edu.wpi.first.units.Units.Degrees; +import static edu.wpi.first.units.Units.Rotations; + +import com.ctre.phoenix6.StatusSignal; +import com.ctre.phoenix6.configs.TalonFXSConfiguration; +import com.ctre.phoenix6.configs.TalonFXSConfigurator; +import com.ctre.phoenix6.hardware.TalonFXS; +import com.ctre.phoenix6.signals.ExternalFeedbackSensorSourceValue; +import edu.wpi.first.units.measure.Angle; +import edu.wpi.first.units.measure.Voltage; +import swervelib.motors.SwerveMotor; +import swervelib.motors.TalonFXSSwerve; + +/** + * Swerve Absolute Encoder for CTRE TalonFXS. + */ +public class TalonFXSEncoderAnalogSwerve extends SwerveAbsoluteEncoder +{ + + /** + * + * Reference to a TalonFXS for polling its attached absolute encoder. + */ + private final TalonFXS talonFXS; + /** + * Analog absolute encoder voltage. + */ + private final StatusSignal analogVoltage; + /** + * Offset of the absolute encoder. + */ + private Angle offset = Degrees.of(0); + /** + * Inverted state of the encoder. + */ + private boolean inverted = false; + + public TalonFXSEncoderAnalogSwerve(SwerveMotor motor) + { + if(!(motor instanceof TalonFXSSwerve)) + { + throw new IllegalArgumentException("Motor must be a TalonFXSSwerve"); + } + talonFXS = (TalonFXS)motor.getMotor(); + analogVoltage = talonFXS.getAnalogVoltage(); + } + + + @Override + public void close() + { + // Do nothing + } + + @Override + public void factoryDefault() + { + // Do nothing + } + + @Override + public void clearStickyFaults() + { + // Do nothing + } + + @Override + public void configure(boolean inverted) + { + this.inverted = inverted; + } + + @Override + public double getAbsolutePosition() + { + var angle = Rotations.of(analogVoltage.refresh().getValueAsDouble() / 5.0); + return (inverted ? Rotations.of(1).minus(angle) : angle).minus(offset).in(Degrees); + } + + @Override + public Object getAbsoluteEncoder() + { + return analogVoltage; + } + + @Override + public boolean setAbsoluteEncoderOffset(double offset) + { + this.offset = Degrees.of(offset); + return true; + } + + @Override + public double getVelocity() + { + return 0; + } +} diff --git a/yagsl/java/swervelib/parser/json/DeviceJson.java b/yagsl/java/swervelib/parser/json/DeviceJson.java index 5e85f6c..a029fbd 100644 --- a/yagsl/java/swervelib/parser/json/DeviceJson.java +++ b/yagsl/java/swervelib/parser/json/DeviceJson.java @@ -16,6 +16,7 @@ import swervelib.encoders.SparkMaxAnalogEncoderSwerve; import swervelib.encoders.SparkMaxEncoderSwerve; import swervelib.encoders.SwerveAbsoluteEncoder; +import swervelib.encoders.TalonFXSEncoderAnalogSwerve; import swervelib.encoders.TalonSRXEncoderSwerve; import swervelib.imu.ADIS16448Swerve; import swervelib.imu.ADIS16470Swerve; @@ -88,6 +89,8 @@ public SwerveAbsoluteEncoder createEncoder(SwerveMotor motor) case "sparkflex_canandmag": case "sparkflex_canandcoder": return new SparkFlexEncoderSwerve(motor, 360); + case "talonfxs_analog": + return new TalonFXSEncoderAnalogSwerve(motor); case "canandcoder_can": case "canandmag_can": return new CanAndMagSwerve(id); From dc4dabac8817fc7d74b12ab537e36bb2df95a32a Mon Sep 17 00:00:00 2001 From: T Grinch <10247070+thenetworkgrinch@users.noreply.github.com> Date: Sat, 17 Jan 2026 17:44:53 -0600 Subject: [PATCH 24/62] Update voltage divisor in getAbsolutePosition method --- yagsl/java/swervelib/encoders/TalonFXSEncoderAnalogSwerve.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yagsl/java/swervelib/encoders/TalonFXSEncoderAnalogSwerve.java b/yagsl/java/swervelib/encoders/TalonFXSEncoderAnalogSwerve.java index 193dc01..e7b12fd 100644 --- a/yagsl/java/swervelib/encoders/TalonFXSEncoderAnalogSwerve.java +++ b/yagsl/java/swervelib/encoders/TalonFXSEncoderAnalogSwerve.java @@ -75,7 +75,7 @@ public void configure(boolean inverted) @Override public double getAbsolutePosition() { - var angle = Rotations.of(analogVoltage.refresh().getValueAsDouble() / 5.0); + var angle = Rotations.of(analogVoltage.refresh().getValueAsDouble() / 3.3); return (inverted ? Rotations.of(1).minus(angle) : angle).minus(offset).in(Degrees); } From 09d3451213320fd81f26c496c5674e2cbddc1ee5 Mon Sep 17 00:00:00 2001 From: twisterjafla <122408604+twisterjafla@users.noreply.github.com> Date: Sat, 17 Jan 2026 21:40:14 -0700 Subject: [PATCH 25/62] Changes where MapleSim publishes goal poses. (#13) * updated vendor dep error messages for clarity * I cant read * unremoved studica * additional clarification * removed extra print line * changed where goal poses are published * fixes timing issues --- .../ironmaple/simulation/SimulatedArena.java | 4 +++- .../seasonspecific/crescendo2024/CrescendoAmp.java | 2 +- .../crescendo2024/CrescendoSpeaker.java | 2 +- .../rebuilt2026/Arena2026Rebuilt.java | 14 +++++++------- .../seasonspecific/rebuilt2026/RebuiltHub.java | 2 +- .../seasonspecific/rebuilt2026/RebuiltOutpost.java | 6 +++--- .../reefscape2025/ReefscapeBargeSimulation.java | 2 +- .../ReefscapeProcessorSimulation.java | 2 +- .../reefscape2025/ReefscapeReefSimulation.java | 2 +- 9 files changed, 19 insertions(+), 17 deletions(-) diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java index 28b926c..350a4b0 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java @@ -67,6 +67,7 @@ public abstract class SimulatedArena { protected int redScore = 0; protected int blueScore = 0; protected double matchClock = 0; + protected double lastMeasuredTimestamp=System.currentTimeMillis(); public Map redScoringBreakdown = new Hashtable(); public Map blueScoringBreakdown = new Hashtable(); @@ -571,7 +572,8 @@ public synchronized void simulationPeriodic() { // move through a few sub-periods in each update for (int i = 0; i < SIMULATION_SUB_TICKS_IN_1_PERIOD; i++) simulationSubTick(i); - matchClock += getSimulationDt().in(Units.Seconds); + matchClock += (System.currentTimeMillis() - lastMeasuredTimestamp)/1000.0; + lastMeasuredTimestamp = System.currentTimeMillis(); SmartDashboard.putNumber("MapleArenaSimulation/Dyn4jEngineCPUTimeMS", (System.nanoTime() - t0) / 1000000.0); diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoAmp.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoAmp.java index d40a7a7..e71f1fa 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoAmp.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoAmp.java @@ -51,7 +51,7 @@ public CrescendoAmp(Arena2024Crescendo arena, boolean isBlue) { setNeededAngle(new Rotation3d(0, Math.PI / 2, Math.PI / 2)); StructPublisher ampPublisher = NetworkTableInstance.getDefault() - .getStructTopic(isBlue ? "BlueAmp" : "RedAmp", Pose3d.struct) + .getStructTopic("/SmartDashboard/MapleSim/Goals/" + (isBlue ? "BlueAmp" : "RedAmp"), Pose3d.struct) .publish(); ampPublisher.set(new Pose3d(position, this.pieceAngle)); } diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoSpeaker.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoSpeaker.java index c3f8fa7..de32a84 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoSpeaker.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/crescendo2024/CrescendoSpeaker.java @@ -48,7 +48,7 @@ public CrescendoSpeaker(Arena2024Crescendo arena, boolean isBlue) { crescendoArena = arena; StructPublisher speakerPosePublisher = NetworkTableInstance.getDefault() - .getStructTopic(isBlue ? "BlueSpeaker" : "RedSpeaker", Pose3d.struct) + .getStructTopic("/SmartDashboard/MapleSim/Goals/" + (isBlue ? "BlueSpeaker" : "RedSpeaker"), Pose3d.struct) .publish(); speakerPosePublisher.set(new Pose3d(position, new Rotation3d())); } diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/Arena2026Rebuilt.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/Arena2026Rebuilt.java index 0b432ca..ad32971 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/Arena2026Rebuilt.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/Arena2026Rebuilt.java @@ -28,7 +28,7 @@ public class Arena2026Rebuilt extends SimulatedArena { protected boolean shouldClock = true; - protected double clock = 0; + protected double nextClockSwapTime=0; protected boolean blueIsOnClock = Math.random() < 0.5; protected DoublePublisher phaseClockPublisher = @@ -290,18 +290,18 @@ public synchronized List getGamePiecesPosesByType(String type) { public void simulationSubTick(int tickNum) { if (shouldClock && !DriverStation.isAutonomous() && DriverStation.isEnabled()) { - clock -= getSimulationDt().in(Units.Seconds); - if (clock <= 0) { - clock = 25; + if (matchClock >= nextClockSwapTime) { + nextClockSwapTime = matchClock + 25; blueIsOnClock = !blueIsOnClock; } + phaseClockPublisher.set((nextClockSwapTime-matchClock)); + + } else { - clock = 25; + phaseClockPublisher.set((25)); } - phaseClockPublisher.set((clock)); - super.simulationSubTick(tickNum); blueActivePublisher.set(isActive(true)); diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltHub.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltHub.java index 687a808..f01049d 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltHub.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltHub.java @@ -74,7 +74,7 @@ public RebuiltHub(Arena2026Rebuilt arena, boolean isBlue) { this.arena = arena; StructPublisher HubPosePublisher = NetworkTableInstance.getDefault() - .getStructTopic(isBlue ? "BlueHub" : "RedHub", Pose3d.struct) + .getStructTopic("/SmartDashboard/MapleSim/Goals/" + (isBlue ? "BlueHub" : "RedHub"), Pose3d.struct) .publish(); HubPosePublisher.set(new Pose3d(position, new Rotation3d())); } diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltOutpost.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltOutpost.java index 8986dab..b616087 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltOutpost.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/rebuilt2026/RebuiltOutpost.java @@ -67,14 +67,14 @@ public RebuiltOutpost(Arena2026Rebuilt arena, boolean isBlue) { gamePieceCount = 24; StructPublisher OutpostPublisher = NetworkTableInstance.getDefault() - .getStructTopic(isBlue ? "BlueOutpost" : "RedOutpost", Pose3d.struct) + .getStructTopic("/SmartDashboard/MapleSim/Goals/" + (isBlue ? "BlueOutpost" : "RedOutpost"), Pose3d.struct) .publish(); StructPublisher OutpostThrowPublisher = NetworkTableInstance.getDefault() - .getStructTopic(isBlue ? "BlueOutpostThrow" : "RedOutpostThrow", Pose3d.struct) + .getStructTopic("/SmartDashboard/MapleSim/Goals/" + (isBlue ? "BlueOutpostThrow" : "RedOutpostThrow"), Pose3d.struct) .publish(); StructPublisher OutpostDumpPublisher = NetworkTableInstance.getDefault() - .getStructTopic(isBlue ? "BlueOutpostDump" : "RedOutpostDump", Pose3d.struct) + .getStructTopic("/SmartDashboard/MapleSim/Goals/" + (isBlue ? "BlueOutpostDump" : "RedOutpostDump"), Pose3d.struct) .publish(); OutpostPublisher.set(new Pose3d(position, new Rotation3d())); diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeBargeSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeBargeSimulation.java index afe13a9..fea8c56 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeBargeSimulation.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeBargeSimulation.java @@ -48,7 +48,7 @@ public ReefscapeBargeSimulation(Arena2025Reefscape arena, boolean isBlue) { false); StructPublisher heldAlgaePublisher = NetworkTableInstance.getDefault() - .getStructTopic(isBlue ? "BlueBarge" : "RedBarge", Pose3d.struct) + .getStructTopic("/SmartDashboard/MapleSim/Goals/" + (isBlue ? "BlueBarge" : "RedBarge"), Pose3d.struct) .publish(); heldAlgaePublisher.set(new Pose3d(position, new Rotation3d())); } diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeProcessorSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeProcessorSimulation.java index 229eb5b..8fba430 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeProcessorSimulation.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeProcessorSimulation.java @@ -47,7 +47,7 @@ public ReefscapeProcessorSimulation(Arena2025Reefscape arena, boolean isBlue) { true); StructPublisher heldAlgaePublisher = NetworkTableInstance.getDefault() - .getStructTopic(isBlue ? "BlueProcessor" : "RedProcessor", Pose3d.struct) + .getStructTopic("/SmartDashboard/MapleSim/Goals/" + (isBlue ? "BlueProcessor" : "RedProcessor"), Pose3d.struct) .publish(); heldAlgaePublisher.set(new Pose3d(position, new Rotation3d())); } diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefSimulation.java index e00b887..c02dcdf 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefSimulation.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/seasonspecific/reefscape2025/ReefscapeReefSimulation.java @@ -47,7 +47,7 @@ public class ReefscapeReefSimulation implements SimulatedArena.Simulatable { } } reefPub = NetworkTableInstance.getDefault() - .getStructArrayTopic(isBlue ? "BlueReef" : "RedReef", Pose3d.struct) + .getStructArrayTopic("/SmartDashboard/MapleSim/Goals/" + (isBlue ? "BlueReef" : "RedReef"), Pose3d.struct) .publish(); reefPub.set(branchPoses); From 90b4a4ace865234e3ae57e77d57c6b3c76f091f3 Mon Sep 17 00:00:00 2001 From: T Grinch <10247070+thenetworkgrinch@users.noreply.github.com> Date: Sat, 17 Jan 2026 22:40:49 -0600 Subject: [PATCH 26/62] Update GradleRIO and wpilibVersion to 2026.2.1 --- vendordep/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vendordep/build.gradle b/vendordep/build.gradle index c13d431..adb987b 100644 --- a/vendordep/build.gradle +++ b/vendordep/build.gradle @@ -4,13 +4,13 @@ plugins { id 'google-test' id 'edu.wpi.first.wpilib.repositories.WPILibRepositoriesPlugin' version '2025.0' id 'edu.wpi.first.NativeUtils' version '2026.0.1' - id "edu.wpi.first.GradleRIO" version "2026.1.1" // Version supplied here + id "edu.wpi.first.GradleRIO" version "2026.2.1" // Version supplied here id 'edu.wpi.first.GradleJni' version '1.1.0' id 'edu.wpi.first.GradleVsCode' version '2.1.0' id "com.diffplug.spotless" version "6.11.0" } -ext.wpilibVersion = "2026.1.1" // and again here, thanks gradle.... +ext.wpilibVersion = "2026.2.1" // and again here, thanks gradle.... ext.releasePath = "$buildDir/maven" ext.pubVersion = System.getenv("releaseVersion") ?: System.getenv("releaseName") ?: "test" From fbd17b21cf5679fdeaea6f5446617713adafa9d1 Mon Sep 17 00:00:00 2001 From: thenetworkgrinch Date: Tue, 20 Jan 2026 15:19:04 -0600 Subject: [PATCH 27/62] Fixed TalonFXS to use commutation and apply the ratio correctly. Signed-off-by: thenetworkgrinch --- .../java/swervelib/motors/TalonFXSSwerve.java | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/yagsl/java/swervelib/motors/TalonFXSSwerve.java b/yagsl/java/swervelib/motors/TalonFXSSwerve.java index b5fa088..3521b8d 100644 --- a/yagsl/java/swervelib/motors/TalonFXSSwerve.java +++ b/yagsl/java/swervelib/motors/TalonFXSSwerve.java @@ -11,6 +11,7 @@ import com.ctre.phoenix6.controls.VelocityVoltage; import com.ctre.phoenix6.hardware.TalonFXS; import com.ctre.phoenix6.signals.AdvancedHallSupportValue; +import com.ctre.phoenix6.signals.ExternalFeedbackSensorSourceValue; import com.ctre.phoenix6.signals.FeedbackSensorSourceValue; import com.ctre.phoenix6.signals.InvertedValue; import com.ctre.phoenix6.signals.MotorArrangementValue; @@ -132,6 +133,19 @@ public void factoryDefaults() configuration.Commutation.withAdvancedHallSupport(AdvancedHallSupportValue.Enabled); configuration.Commutation.withMotorArrangement(MotorArrangementValue.Minion_JST); } + else if (isMotor(simMotor, DCMotor.getNEO(1))) + { + configuration.Commutation.withAdvancedHallSupport(AdvancedHallSupportValue.Disabled); + configuration.Commutation.withMotorArrangement(MotorArrangementValue.NEO_JST); + } else if (isMotor(simMotor, DCMotor.getNeo550(1))) + { + configuration.Commutation.withAdvancedHallSupport(AdvancedHallSupportValue.Disabled); + configuration.Commutation.withMotorArrangement(MotorArrangementValue.NEO550_JST); + } else if (isMotor(simMotor, DCMotor.getNeoVortex(1))) + { + configuration.Commutation.withAdvancedHallSupport(AdvancedHallSupportValue.Disabled); + configuration.Commutation.withMotorArrangement(MotorArrangementValue.NEO_JST); + } } } @@ -207,10 +221,10 @@ public void configureIntegratedEncoder(double positionConversionFactor) .withMotionMagicExpo_kV(0.12 * positionConversionFactor) .withMotionMagicExpo_kA(0.1); - /* - configuration.Feedback.withFeedbackSensorSource(FeedbackSensorSourceValue.RotorSensor) + + configuration.ExternalFeedback.withExternalFeedbackSensorSource(ExternalFeedbackSensorSourceValue.Commutation) .withSensorToMechanismRatio(positionConversionFactor); - */ + cfg.apply(configuration); } From a5c1f30cad8dbeafe7de565dc818dbc792e5f5d9 Mon Sep 17 00:00:00 2001 From: thenetworkgrinch Date: Tue, 20 Jan 2026 15:21:49 -0600 Subject: [PATCH 28/62] Fixed position to read in degrees. Signed-off-by: thenetworkgrinch --- yagsl/java/swervelib/motors/TalonFXSSwerve.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yagsl/java/swervelib/motors/TalonFXSSwerve.java b/yagsl/java/swervelib/motors/TalonFXSSwerve.java index 3521b8d..faa16d1 100644 --- a/yagsl/java/swervelib/motors/TalonFXSSwerve.java +++ b/yagsl/java/swervelib/motors/TalonFXSSwerve.java @@ -404,7 +404,7 @@ public double getVelocity() @Override public double getPosition() { - return motor.getPosition().getValue().magnitude(); + return motor.getPosition().getValue().in(Degrees); } /** From 08d29dff9ec2d0af3affd33e8cb226aaaad4d387 Mon Sep 17 00:00:00 2001 From: thenetworkgrinch Date: Tue, 20 Jan 2026 15:24:40 -0600 Subject: [PATCH 29/62] Revert position casting. Signed-off-by: thenetworkgrinch --- yagsl/java/swervelib/motors/TalonFXSSwerve.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/yagsl/java/swervelib/motors/TalonFXSSwerve.java b/yagsl/java/swervelib/motors/TalonFXSSwerve.java index faa16d1..583cc99 100644 --- a/yagsl/java/swervelib/motors/TalonFXSSwerve.java +++ b/yagsl/java/swervelib/motors/TalonFXSSwerve.java @@ -1,6 +1,7 @@ package swervelib.motors; import static edu.wpi.first.units.Units.Degrees; +import static edu.wpi.first.units.Units.Meters; import static edu.wpi.first.units.Units.Rotations; import static edu.wpi.first.units.Units.Volts; @@ -404,7 +405,7 @@ public double getVelocity() @Override public double getPosition() { - return motor.getPosition().getValue().in(Degrees); + return motor.getPosition().getValue().magnitude(); } /** From 8db5a2ca32ebfa2b1791e8fe148bdb7f3965b260 Mon Sep 17 00:00:00 2001 From: T Grinch <10247070+thenetworkgrinch@users.noreply.github.com> Date: Tue, 20 Jan 2026 16:00:45 -0600 Subject: [PATCH 30/62] Update TalonFXSSwerve.java --- yagsl/java/swervelib/motors/TalonFXSSwerve.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yagsl/java/swervelib/motors/TalonFXSSwerve.java b/yagsl/java/swervelib/motors/TalonFXSSwerve.java index 583cc99..2fd6f27 100644 --- a/yagsl/java/swervelib/motors/TalonFXSSwerve.java +++ b/yagsl/java/swervelib/motors/TalonFXSSwerve.java @@ -349,7 +349,7 @@ public void setReference(double setpoint, double feedforward, double position) motor.setControl(m_velocityVoltageSetter.withVelocity(setpoint).withFeedForward(feedforward)); } else { - motor.setControl(m_angleVoltageSetter.withPosition(setpoint / 360.0)); + motor.setControl(m_angleVoltageSetter.withPosition(setpoint)); } } @@ -418,7 +418,7 @@ public void setPosition(double position) { if (!absoluteEncoder && !SwerveDriveTelemetry.isSimulation) { - cfg.setPosition(Degrees.of(position).in(Rotations)); + cfg.setPosition(Degrees.of(position).in(Degrees)); } } From 32b3c6b717e8a958536e9cb975293cb9efdd6ed1 Mon Sep 17 00:00:00 2001 From: KonnorR Date: Sat, 24 Jan 2026 19:36:03 -0500 Subject: [PATCH 31/62] Disable Bump Collision (#16) --- .../simulation/ironmaple/simulation/SimulatedArena.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java index 350a4b0..c42302d 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java @@ -112,7 +112,7 @@ public static SimulatedArena getInstance() { throw new IllegalStateException( "MapleSim is running on a real robot! (If you would actually want that, set SimulatedArena.ALLOW_CREATION_ON_REAL_ROBOT to true)."); - if (instance == null) instance = new Arena2026Rebuilt(); + if (instance == null) instance = new Arena2026Rebuilt(false); return instance; } From 1cc10643618144991e635c5eace46a17cf23282c Mon Sep 17 00:00:00 2001 From: T Grinch <10247070+thenetworkgrinch@users.noreply.github.com> Date: Sun, 25 Jan 2026 23:34:15 -0600 Subject: [PATCH 32/62] Update ReflectionsManager.java --- .../java/swervelib/parser/deserializer/ReflectionsManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yagsl/java/swervelib/parser/deserializer/ReflectionsManager.java b/yagsl/java/swervelib/parser/deserializer/ReflectionsManager.java index 999bdbb..26e0a4a 100644 --- a/yagsl/java/swervelib/parser/deserializer/ReflectionsManager.java +++ b/yagsl/java/swervelib/parser/deserializer/ReflectionsManager.java @@ -61,7 +61,7 @@ public static boolean checkIfVendorLibExists(VENDOR vendor) } case THRIFTYBOT -> { - library = Class.forName("com.thethriftybot.ThriftyNova"); + library = Class.forName("com.thethriftybot.devices.ThriftyNova"); break; } case STUDICA -> From 5475f3f6e5d820926e4e2d01381e8d1ce4aed8bf Mon Sep 17 00:00:00 2001 From: T Grinch <10247070+thenetworkgrinch@users.noreply.github.com> Date: Mon, 26 Jan 2026 18:48:45 -0600 Subject: [PATCH 33/62] Update to the new ThriftyLib. Fixed ThriftyNovaSwerve to not crash in sim. (#17) Signed-off-by: thenetworkgrinch Co-authored-by: thenetworkgrinch --- .../.wpilib/wpilib_preferences.json | 2 +- examples/drivebase_only_2026/build.gradle | 2 +- .../vendordeps/REVLib.json | 18 ++-- .../vendordeps/StudicaLib-2026.0.0.json | 71 ---------------- ...Lib-2026.0.0.json => ThriftyLib-2026.json} | 12 +-- .../swervelib/motors/ThriftyNovaSwerve.java | 83 ++++++++++--------- 6 files changed, 64 insertions(+), 124 deletions(-) delete mode 100644 examples/drivebase_only_2026/vendordeps/StudicaLib-2026.0.0.json rename examples/drivebase_only_2026/vendordeps/{ThriftyLib-2026.0.0.json => ThriftyLib-2026.json} (68%) diff --git a/examples/drivebase_only_2026/.wpilib/wpilib_preferences.json b/examples/drivebase_only_2026/.wpilib/wpilib_preferences.json index f727ea3..8959180 100644 --- a/examples/drivebase_only_2026/.wpilib/wpilib_preferences.json +++ b/examples/drivebase_only_2026/.wpilib/wpilib_preferences.json @@ -1,6 +1,6 @@ { "enableCppIntellisense": false, "currentLanguage": "java", - "projectYear": "2026beta", + "projectYear": "2026", "teamNumber": 3481 } \ No newline at end of file diff --git a/examples/drivebase_only_2026/build.gradle b/examples/drivebase_only_2026/build.gradle index faa789c..e06c9f1 100644 --- a/examples/drivebase_only_2026/build.gradle +++ b/examples/drivebase_only_2026/build.gradle @@ -1,6 +1,6 @@ plugins { id "java" - id "edu.wpi.first.GradleRIO" version "2026.1.1" + id "edu.wpi.first.GradleRIO" version "2026.2.1" } java { diff --git a/examples/drivebase_only_2026/vendordeps/REVLib.json b/examples/drivebase_only_2026/vendordeps/REVLib.json index 4f96af8..d35e593 100644 --- a/examples/drivebase_only_2026/vendordeps/REVLib.json +++ b/examples/drivebase_only_2026/vendordeps/REVLib.json @@ -1,7 +1,7 @@ { "fileName": "REVLib.json", "name": "REVLib", - "version": "2026.0.0", + "version": "2026.0.1", "frcYear": "2026", "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb", "mavenUrls": [ @@ -12,14 +12,14 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-java", - "version": "2026.0.0" + "version": "2026.0.1" } ], "jniDependencies": [ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2026.0.0", + "version": "2026.0.1", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -34,7 +34,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibBackendDriver", - "version": "2026.0.0", + "version": "2026.0.1", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -49,7 +49,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibWpiBackendDriver", - "version": "2026.0.0", + "version": "2026.0.1", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -66,7 +66,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-cpp", - "version": "2026.0.0", + "version": "2026.0.1", "libName": "REVLib", "headerClassifier": "headers", "sharedLibrary": false, @@ -83,7 +83,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "REVLib-driver", - "version": "2026.0.0", + "version": "2026.0.1", "libName": "REVLibDriver", "headerClassifier": "headers", "sharedLibrary": false, @@ -100,7 +100,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibBackendDriver", - "version": "2026.0.0", + "version": "2026.0.1", "libName": "BackendDriver", "sharedLibrary": true, "skipInvalidPlatforms": true, @@ -116,7 +116,7 @@ { "groupId": "com.revrobotics.frc", "artifactId": "RevLibWpiBackendDriver", - "version": "2026.0.0", + "version": "2026.0.1", "libName": "REVLibWpi", "sharedLibrary": true, "skipInvalidPlatforms": true, diff --git a/examples/drivebase_only_2026/vendordeps/StudicaLib-2026.0.0.json b/examples/drivebase_only_2026/vendordeps/StudicaLib-2026.0.0.json deleted file mode 100644 index 7447f74..0000000 --- a/examples/drivebase_only_2026/vendordeps/StudicaLib-2026.0.0.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "StudicaLib.json", - "name": "StudicaLib", - "version": "2026.0.0", - "frcYear": "2026", - "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", - "mavenUrls": [ - "https://dev.studica.com/maven/release/2026/" - ], - "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.0.json", - "javaDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-java", - "version": "2026.0.0" - } - ], - "jniDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-driver", - "version": "2026.0.0", - "skipInvalidPlatforms": true, - "isJar": false, - "validPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ], - "cppDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-cpp", - "version": "2026.0.0", - "libName": "StudicaLib", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - }, - { - "groupId": "com.studica.frc", - "artifactId": "StudicaLib-driver", - "version": "2026.0.0", - "libName": "StudicaLibDriver", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ] -} diff --git a/examples/drivebase_only_2026/vendordeps/ThriftyLib-2026.0.0.json b/examples/drivebase_only_2026/vendordeps/ThriftyLib-2026.json similarity index 68% rename from examples/drivebase_only_2026/vendordeps/ThriftyLib-2026.0.0.json rename to examples/drivebase_only_2026/vendordeps/ThriftyLib-2026.json index 56ff85e..9aa5808 100644 --- a/examples/drivebase_only_2026/vendordeps/ThriftyLib-2026.0.0.json +++ b/examples/drivebase_only_2026/vendordeps/ThriftyLib-2026.json @@ -1,18 +1,20 @@ { - "fileName": "ThriftyLib-2026.0.0.json", + "fileName": "ThriftyLib-2026.json", "name": "ThriftyLib", - "version": "2026.0.0", + "version": "2026.0.1", "frcYear": "2026", "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", - "mavenUrls": ["https://docs.home.thethriftybot.com"], + "mavenUrls": [ + "https://docs.home.thethriftybot.com" + ], "jsonUrl": "https://docs.home.thethriftybot.com/ThriftyLib-2026.json", "javaDependencies": [ { "groupId": "com.thethriftybot.frc", "artifactId": "ThriftyLib-java", - "version": "2026.0.0" + "version": "2026.0.1" } ], "jniDependencies": [], "cppDependencies": [] -} +} \ No newline at end of file diff --git a/yagsl/java/swervelib/motors/ThriftyNovaSwerve.java b/yagsl/java/swervelib/motors/ThriftyNovaSwerve.java index f7f471e..20c90c6 100644 --- a/yagsl/java/swervelib/motors/ThriftyNovaSwerve.java +++ b/yagsl/java/swervelib/motors/ThriftyNovaSwerve.java @@ -11,16 +11,13 @@ import com.thethriftybot.util.Conversion; import com.thethriftybot.util.Conversion.PositionUnit; import com.thethriftybot.util.Conversion.VelocityUnit; -import java.util.List; -import java.util.Optional; -import java.util.function.Supplier; - - import edu.wpi.first.math.controller.PIDController; import edu.wpi.first.math.system.plant.DCMotor; import edu.wpi.first.wpilibj.DataLogManager; import edu.wpi.first.wpilibj.RobotBase; -import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; +import java.util.List; +import java.util.Optional; +import java.util.function.Supplier; import swervelib.encoders.SwerveAbsoluteEncoder; import swervelib.parser.PIDFConfig; import swervelib.telemetry.SwerveDriveTelemetry; @@ -35,39 +32,39 @@ public class ThriftyNovaSwerve extends SwerveMotor /** * {@link DCMotor} for simulation and calculations. */ - private final DCMotor simMotor; + private final DCMotor simMotor; /** * Closed-loop PID controller. */ - public PIDController pid; + public PIDController pid; /** * ThriftyNova Instance. */ - private ThriftyNova motor; + private ThriftyNova motor; /** * Factory default already occurred. */ - private boolean factoryDefaultOccurred = false; + private boolean factoryDefaultOccurred = false; /** * Position conversion object for the motor encoder */ - private Conversion positionConversion; + private Conversion positionConversion; /** * Velocity conversion object for the motor encoder */ - private Conversion velocityConversion; + private Conversion velocityConversion; /** * The position conversion factor for the encoder */ - private double positionConversionFactor = 1.0; + private double positionConversionFactor = 1.0; /** * The position conversion factor for the encoder */ - private double velocityConversionFactor = 1.0 / 60.0; + private double velocityConversionFactor = 1.0 / 60.0; /** * Absolute encoder attached to the SparkMax (if exists) */ - private Optional absoluteEncoder = Optional.empty(); + private Optional absoluteEncoder = Optional.empty(); /** * Supplier for the velocity of the motor controller. */ @@ -94,7 +91,8 @@ public ThriftyNovaSwerve(ThriftyNova motor, boolean isDriveMotor, DCMotor motorT motor.usePIDSlot(PIDSlot.SLOT0); pid = new PIDController(0, 0, 0); - motor.pid0.setPID(pid); + if (RobotBase.isReal()) + {motor.pid0.setPID(pid);} if (isDriveMotor) { @@ -128,16 +126,20 @@ public ThriftyNovaSwerve(int id, boolean isDriveMotor, DCMotor motor) * @throws RuntimeException If an exception is thrown while closing the motor. */ @Override - public void close() { - try { + public void close() + { + try + { motor.close(); - } catch (Exception e) { + } catch (Exception e) + { throw new RuntimeException(e); } } - private double getConvertedPosition() { - double motorPosition = motor.getPosition(); + private double getConvertedPosition() + { + double motorPosition = motor.getPosition(); double convertedPosition = motorPosition / positionConversionFactor; return convertedPosition; } @@ -147,8 +149,9 @@ private double getConvertedPosition() { * * @return velocity in meters per second or degrees per second. */ - private double getConvertedVelocity() { - double motorVelocity = motor.getVelocity(); + private double getConvertedVelocity() + { + double motorVelocity = motor.getVelocity(); double convertedVelocity = motorVelocity / velocityConversionFactor; return convertedVelocity; @@ -177,7 +180,8 @@ public void factoryDefaults() @Override public void clearStickyFaults() { - if (RobotBase.isReal()) { + if (RobotBase.isReal()) + { motor.clearErrors(); } } @@ -196,8 +200,7 @@ public SwerveMotor setAbsoluteEncoder(SwerveAbsoluteEncoder encoder) motor.useEncoderType(EncoderType.INTERNAL); position = this::getConvertedPosition; velocity = this::getConvertedVelocity; - } - else + } else { absoluteEncoder = Optional.of(encoder); position = absoluteEncoder.get()::getAbsolutePosition; @@ -208,8 +211,8 @@ public SwerveMotor setAbsoluteEncoder(SwerveAbsoluteEncoder encoder) } /** - * Configure the integrated encoder for the ThriftyNova swerve module. Sets the conversion - * factors for position and velocity, and configures the CAN status frames. + * Configure the integrated encoder for the ThriftyNova swerve module. Sets the conversion factors for position and + * velocity, and configures the CAN status frames. * * @param positionConversionFactor The conversion factor to apply for position. */ @@ -291,7 +294,8 @@ public void disablePIDWrapping() @Override public void setMotorBrake(boolean isBrakeMode) { - if (RobotBase.isReal()) { + if (RobotBase.isReal()) + { motor.setBrakeMode(isBrakeMode); checkErrors("Setting motor brake mode failed: "); } @@ -305,7 +309,8 @@ public void setMotorBrake(boolean isBrakeMode) @Override public void setInverted(boolean inverted) { - if (RobotBase.isReal()) { + if (RobotBase.isReal()) + { motor.setInverted(inverted); checkErrors("Setting motor inversion failed: "); } @@ -353,16 +358,17 @@ public void setReference(double setpoint, double feedforward) @Override public void setReference(double setpoint, double feedforward, double position) { - if (RobotBase.isReal()) { + if (RobotBase.isReal()) + { if (isDriveMotor) { double convertedSetpoint = setpoint / velocityConversionFactor; - double motorSetpoint = velocityConversion.toMotor(convertedSetpoint); + double motorSetpoint = velocityConversion.toMotor(convertedSetpoint); motor.setVelocity(motorSetpoint, feedforward); } else { double convertedSetpoint = absoluteEncoder.map(it -> setpoint).orElse(setpoint / positionConversionFactor); - double motorSetpoint = positionConversion.toMotor(convertedSetpoint); + double motorSetpoint = positionConversion.toMotor(convertedSetpoint); motor.setPosition(motorSetpoint); } } @@ -434,7 +440,7 @@ public void setPosition(double position) if (!absoluteEncoder.isPresent()) { double convertedPosition = position / positionConversionFactor; - double motorPosition = positionConversion.toMotor(convertedPosition); + double motorPosition = positionConversion.toMotor(convertedPosition); motor.setEncoderPosition(motorPosition); } } @@ -459,7 +465,8 @@ public void setVoltageCompensation(double nominalVoltage) @Override public void setCurrentLimit(int currentLimit) { - if (RobotBase.isReal()) { + if (RobotBase.isReal()) + { motor.setMaxCurrent(CurrentType.STATOR, currentLimit); checkErrors("Setting current limit failed: "); } @@ -473,7 +480,8 @@ public void setCurrentLimit(int currentLimit) @Override public void setLoopRampRate(double rampRate) { - if (RobotBase.isReal()) { + if (RobotBase.isReal()) + { motor.setRampUp(rampRate); motor.setRampDown(rampRate); checkErrors("Setting loop ramp rate failed: "); @@ -516,7 +524,8 @@ private void checkErrors(String message) { for (ThriftyNova.Error error : errors) { - if (SwerveDriveTelemetry.verbosity.ordinal() >= TelemetryVerbosity.MACHINE.ordinal()) { + if (SwerveDriveTelemetry.verbosity.ordinal() >= TelemetryVerbosity.MACHINE.ordinal()) + { System.out.println(this.getClass().getSimpleName() + ": " + message + error.toString()); } DataLogManager.log(this.getClass().getSimpleName() + ": " + message + error.toString()); From 51a5cb76b17a48905fd824dd623c7b7b05a99928 Mon Sep 17 00:00:00 2001 From: thenetworkgrinch Date: Fri, 30 Jan 2026 16:21:23 -0600 Subject: [PATCH 34/62] Fixed navX3 json loading. Signed-off-by: thenetworkgrinch --- .../main/deploy/swerve/neo/swervedrive.json | 2 +- .../vendordeps/Studica-2026.0.0.json | 71 ------------------- yagsl/java/swervelib/imu/NavX3Swerve.java | 13 ++-- .../deserializer/ReflectionsManager.java | 3 +- 4 files changed, 8 insertions(+), 81 deletions(-) delete mode 100644 examples/drivebase_only_2026/vendordeps/Studica-2026.0.0.json diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/neo/swervedrive.json b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/swervedrive.json index 89ae3b1..462d9e0 100644 --- a/examples/drivebase_only_2026/src/main/deploy/swerve/neo/swervedrive.json +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/swervedrive.json @@ -1,7 +1,7 @@ { "$schema": "https://broncbotz3481.github.io/YAGSL-Example/schemas/swervedrive_schema.json", "imu": { - "type": "pigeon2", + "type": "navx3", "id": 13, "canbus": "canivore" }, diff --git a/examples/drivebase_only_2026/vendordeps/Studica-2026.0.0.json b/examples/drivebase_only_2026/vendordeps/Studica-2026.0.0.json deleted file mode 100644 index 7a1f3bb..0000000 --- a/examples/drivebase_only_2026/vendordeps/Studica-2026.0.0.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "fileName": "Studica.json", - "name": "Studica", - "version": "2026.0.0", - "frcYear": "2026", - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", - "mavenUrls": [ - "https://dev.studica.com/maven/release/2026/" - ], - "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0.json", - "javaDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "Studica-java", - "version": "2026.0.0" - } - ], - "jniDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "Studica-driver", - "version": "2026.0.0", - "skipInvalidPlatforms": true, - "isJar": false, - "validPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ], - "cppDependencies": [ - { - "groupId": "com.studica.frc", - "artifactId": "Studica-cpp", - "version": "2026.0.0", - "libName": "Studica", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - }, - { - "groupId": "com.studica.frc", - "artifactId": "Studica-driver", - "version": "2026.0.0", - "libName": "StudicaDriver", - "headerClassifier": "headers", - "sharedLibrary": false, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxarm64", - "linuxx86-64", - "linuxathena", - "linuxarm32", - "osxuniversal" - ] - } - ] -} diff --git a/yagsl/java/swervelib/imu/NavX3Swerve.java b/yagsl/java/swervelib/imu/NavX3Swerve.java index c38698c..d9e095e 100644 --- a/yagsl/java/swervelib/imu/NavX3Swerve.java +++ b/yagsl/java/swervelib/imu/NavX3Swerve.java @@ -4,8 +4,6 @@ import static edu.wpi.first.units.Units.DegreesPerSecond; import static edu.wpi.first.units.Units.Milliseconds; -import com.studica.frc.AHRS; -import com.studica.frc.AHRS.NavXComType; import com.studica.frc.Navx; import edu.wpi.first.math.geometry.Rotation3d; import edu.wpi.first.math.geometry.Translation3d; @@ -17,7 +15,7 @@ import java.util.Optional; /** - * Communicates with the NavX({@link AHRS}) as the IMU. + * Communicates with the NavX({@link Navx}) as the IMU. */ public class NavX3Swerve extends SwerveIMU { @@ -39,7 +37,7 @@ public class NavX3Swerve extends SwerveIMU */ private Alert navXError; /** - * Inversion state of the {@link AHRS}. + * Inversion state of the {@link Navx}. */ private boolean inverted = false; @@ -48,7 +46,7 @@ public class NavX3Swerve extends SwerveIMU * * @param canid CAN ID of the NavX3. */ - public NavX3Swerve(int canid) + public NavX3Swerve(Integer canid) { navXError = new Alert("IMU", "Error instantiating NavX.", AlertType.kError); try @@ -69,8 +67,7 @@ public void close() } /** - * Reset offset to current gyro reading. Does not call NavX({@link AHRS#reset()}) because it has been reported to be - * too slow. + * Reset offset to current gyro reading. */ @Override public void factoryDefault() @@ -156,7 +153,7 @@ public MutAngularVelocity getYawAngularVelocity() } /** - * Get the instantiated NavX({@link AHRS}) IMU object. + * Get the instantiated NavX({@link Navx}) IMU object. * * @return IMU object. */ diff --git a/yagsl/java/swervelib/parser/deserializer/ReflectionsManager.java b/yagsl/java/swervelib/parser/deserializer/ReflectionsManager.java index 26e0a4a..6a3445b 100644 --- a/yagsl/java/swervelib/parser/deserializer/ReflectionsManager.java +++ b/yagsl/java/swervelib/parser/deserializer/ReflectionsManager.java @@ -105,7 +105,8 @@ public static T create(VENDOR v, String className, Class[] parameterTypes try { Class wrapper = Class.forName(className); - Object vendorObj = wrapper.getDeclaredConstructor(parameterTypes).newInstance(parameters); + var vendorCtr = wrapper.getDeclaredConstructor(parameterTypes); + var vendorObj = vendorCtr.newInstance(parameters); return (T) vendorObj; } catch (Exception e) { From 964edabf3f13e41ab22a7a96fd9308b7f117736e Mon Sep 17 00:00:00 2001 From: thenetworkgrinch Date: Fri, 30 Jan 2026 16:21:23 -0600 Subject: [PATCH 35/62] Fixed navX3 json loading. Signed-off-by: thenetworkgrinch --- .../main/deploy/swerve/neo/swervedrive.json | 2 +- ...{Studica-2026.0.0.json => StudicaLib.json} | 35 ++++++++++--------- yagsl/java/swervelib/imu/NavX3Swerve.java | 13 +++---- .../deserializer/ReflectionsManager.java | 3 +- 4 files changed, 27 insertions(+), 26 deletions(-) rename examples/drivebase_only_2026/vendordeps/{Studica-2026.0.0.json => StudicaLib.json} (71%) diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/neo/swervedrive.json b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/swervedrive.json index 89ae3b1..462d9e0 100644 --- a/examples/drivebase_only_2026/src/main/deploy/swerve/neo/swervedrive.json +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/swervedrive.json @@ -1,7 +1,7 @@ { "$schema": "https://broncbotz3481.github.io/YAGSL-Example/schemas/swervedrive_schema.json", "imu": { - "type": "pigeon2", + "type": "navx3", "id": 13, "canbus": "canivore" }, diff --git a/examples/drivebase_only_2026/vendordeps/Studica-2026.0.0.json b/examples/drivebase_only_2026/vendordeps/StudicaLib.json similarity index 71% rename from examples/drivebase_only_2026/vendordeps/Studica-2026.0.0.json rename to examples/drivebase_only_2026/vendordeps/StudicaLib.json index 7a1f3bb..813182a 100644 --- a/examples/drivebase_only_2026/vendordeps/Studica-2026.0.0.json +++ b/examples/drivebase_only_2026/vendordeps/StudicaLib.json @@ -1,25 +1,28 @@ { - "fileName": "Studica.json", - "name": "Studica", - "version": "2026.0.0", + "fileName": "StudicaLib.json", + "name": "StudicaLib", + "version": "2026.0.1", "frcYear": "2026", - "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", + "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", "mavenUrls": [ "https://dev.studica.com/maven/release/2026/" ], - "jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0.json", + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.1.json", + "conflictsWith": [ + + ], "javaDependencies": [ { "groupId": "com.studica.frc", - "artifactId": "Studica-java", - "version": "2026.0.0" + "artifactId": "StudicaLib-java", + "version": "2026.0.1" } ], "jniDependencies": [ { "groupId": "com.studica.frc", - "artifactId": "Studica-driver", - "version": "2026.0.0", + "artifactId": "StudicaLib-driver", + "version": "2026.0.1", "skipInvalidPlatforms": true, "isJar": false, "validPlatforms": [ @@ -35,9 +38,9 @@ "cppDependencies": [ { "groupId": "com.studica.frc", - "artifactId": "Studica-cpp", - "version": "2026.0.0", - "libName": "Studica", + "artifactId": "StudicaLib-cpp", + "version": "2026.0.1", + "libName": "StudicaLib", "headerClassifier": "headers", "sharedLibrary": false, "skipInvalidPlatforms": true, @@ -52,9 +55,9 @@ }, { "groupId": "com.studica.frc", - "artifactId": "Studica-driver", - "version": "2026.0.0", - "libName": "StudicaDriver", + "artifactId": "StudicaLib-driver", + "version": "2026.0.1", + "libName": "StudicaLibDriver", "headerClassifier": "headers", "sharedLibrary": false, "skipInvalidPlatforms": true, @@ -68,4 +71,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/yagsl/java/swervelib/imu/NavX3Swerve.java b/yagsl/java/swervelib/imu/NavX3Swerve.java index c38698c..d9e095e 100644 --- a/yagsl/java/swervelib/imu/NavX3Swerve.java +++ b/yagsl/java/swervelib/imu/NavX3Swerve.java @@ -4,8 +4,6 @@ import static edu.wpi.first.units.Units.DegreesPerSecond; import static edu.wpi.first.units.Units.Milliseconds; -import com.studica.frc.AHRS; -import com.studica.frc.AHRS.NavXComType; import com.studica.frc.Navx; import edu.wpi.first.math.geometry.Rotation3d; import edu.wpi.first.math.geometry.Translation3d; @@ -17,7 +15,7 @@ import java.util.Optional; /** - * Communicates with the NavX({@link AHRS}) as the IMU. + * Communicates with the NavX({@link Navx}) as the IMU. */ public class NavX3Swerve extends SwerveIMU { @@ -39,7 +37,7 @@ public class NavX3Swerve extends SwerveIMU */ private Alert navXError; /** - * Inversion state of the {@link AHRS}. + * Inversion state of the {@link Navx}. */ private boolean inverted = false; @@ -48,7 +46,7 @@ public class NavX3Swerve extends SwerveIMU * * @param canid CAN ID of the NavX3. */ - public NavX3Swerve(int canid) + public NavX3Swerve(Integer canid) { navXError = new Alert("IMU", "Error instantiating NavX.", AlertType.kError); try @@ -69,8 +67,7 @@ public void close() } /** - * Reset offset to current gyro reading. Does not call NavX({@link AHRS#reset()}) because it has been reported to be - * too slow. + * Reset offset to current gyro reading. */ @Override public void factoryDefault() @@ -156,7 +153,7 @@ public MutAngularVelocity getYawAngularVelocity() } /** - * Get the instantiated NavX({@link AHRS}) IMU object. + * Get the instantiated NavX({@link Navx}) IMU object. * * @return IMU object. */ diff --git a/yagsl/java/swervelib/parser/deserializer/ReflectionsManager.java b/yagsl/java/swervelib/parser/deserializer/ReflectionsManager.java index 26e0a4a..6a3445b 100644 --- a/yagsl/java/swervelib/parser/deserializer/ReflectionsManager.java +++ b/yagsl/java/swervelib/parser/deserializer/ReflectionsManager.java @@ -105,7 +105,8 @@ public static T create(VENDOR v, String className, Class[] parameterTypes try { Class wrapper = Class.forName(className); - Object vendorObj = wrapper.getDeclaredConstructor(parameterTypes).newInstance(parameters); + var vendorCtr = wrapper.getDeclaredConstructor(parameterTypes); + var vendorObj = vendorCtr.newInstance(parameters); return (T) vendorObj; } catch (Exception e) { From fef44069df91e0444f884578ef9a87ad49b8f171 Mon Sep 17 00:00:00 2001 From: T Grinch <10247070+thenetworkgrinch@users.noreply.github.com> Date: Sun, 1 Feb 2026 16:03:21 -0600 Subject: [PATCH 36/62] Made CTRE stuff reflective. (#20) * Made CTRE stuff reflective. Signed-off-by: thenetworkgrinch * Removed required vdep on CTRE. Signed-off-by: thenetworkgrinch --------- Signed-off-by: thenetworkgrinch Co-authored-by: thenetworkgrinch --- .../deploy/swerve/falcon/swervedrive.json | 3 +- .../deploy/swerve/neo/modules/backleft.json | 2 +- .../deploy/swerve/neo/modules/backright.json | 2 +- .../deploy/swerve/neo/modules/frontleft.json | 2 +- .../deploy/swerve/neo/modules/frontright.json | 2 +- .../main/java/frc/robot/RobotContainer.java | 2 +- .../vendordeps/Phoenix5-replay-5.36.0.json | 221 ------------------ ...eplay-26.1.0.json => Phoenix6-26.1.1.json} | 136 ++++------- .../vendordeps/StudicaLib.json | 78 +++++++ vendordep/yagsl.json | 12 - yagsl/java/swervelib/SwerveDrive.java | 35 ++- .../parser/SwerveDriveConfiguration.java | 5 - .../swervelib/parser/json/DeviceJson.java | 160 ++++++++++--- 13 files changed, 267 insertions(+), 393 deletions(-) delete mode 100644 examples/drivebase_only_2026/vendordeps/Phoenix5-replay-5.36.0.json rename examples/drivebase_only_2026/vendordeps/{Phoenix6-replay-26.1.0.json => Phoenix6-26.1.1.json} (81%) create mode 100644 examples/drivebase_only_2026/vendordeps/StudicaLib.json diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/swervedrive.json b/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/swervedrive.json index f4631eb..fb2b0b8 100644 --- a/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/swervedrive.json +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/falcon/swervedrive.json @@ -1,7 +1,6 @@ { - "$schema": "https://broncbotz3481.github.io/YAGSL-Example/schemas/swervedrive_schema.json", "imu": { - "type": "navx", + "type": "pigeon2", "id": 13, "canbus": "canivore" }, diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/backleft.json b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/backleft.json index 6c6c7d9..a435434 100644 --- a/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/backleft.json +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/backleft.json @@ -10,7 +10,7 @@ "canbus": null }, "encoder": { - "type": "cancoder", + "type": "canandmag", "id": 12, "canbus": null }, diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/backright.json b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/backright.json index 4f9f082..30a3aaa 100644 --- a/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/backright.json +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/backright.json @@ -10,7 +10,7 @@ "canbus": null }, "encoder": { - "type": "cancoder", + "type": "canandmag", "id": 11, "canbus": null }, diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/frontleft.json b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/frontleft.json index a3ef16b..7ae6e18 100644 --- a/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/frontleft.json +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/frontleft.json @@ -10,7 +10,7 @@ "canbus": null }, "encoder": { - "type": "cancoder", + "type": "canandmag", "id": 9, "canbus": null }, diff --git a/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/frontright.json b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/frontright.json index b60f22f..4405471 100644 --- a/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/frontright.json +++ b/examples/drivebase_only_2026/src/main/deploy/swerve/neo/modules/frontright.json @@ -10,7 +10,7 @@ "canbus": null }, "encoder": { - "type": "cancoder", + "type": "canandmag", "id": 10, "canbus": null }, diff --git a/examples/drivebase_only_2026/src/main/java/frc/robot/RobotContainer.java b/examples/drivebase_only_2026/src/main/java/frc/robot/RobotContainer.java index 28294a8..1746482 100644 --- a/examples/drivebase_only_2026/src/main/java/frc/robot/RobotContainer.java +++ b/examples/drivebase_only_2026/src/main/java/frc/robot/RobotContainer.java @@ -37,7 +37,7 @@ public class RobotContainer final CommandXboxController driverXbox = new CommandXboxController(0); // The robot's subsystems and commands are defined here... private final SwerveSubsystem drivebase = new SwerveSubsystem(new File(Filesystem.getDeployDirectory(), - "swerve/neo")); + "swerve/falcon")); // Establish a Sendable Chooser that will be able to be sent to the SmartDashboard, allowing selection of desired auto private final SendableChooser autoChooser = new SendableChooser<>(); diff --git a/examples/drivebase_only_2026/vendordeps/Phoenix5-replay-5.36.0.json b/examples/drivebase_only_2026/vendordeps/Phoenix5-replay-5.36.0.json deleted file mode 100644 index 0e799ed..0000000 --- a/examples/drivebase_only_2026/vendordeps/Phoenix5-replay-5.36.0.json +++ /dev/null @@ -1,221 +0,0 @@ -{ - "fileName": "Phoenix5-replay-5.36.0.json", - "name": "CTRE-Phoenix (v5)", - "version": "5.36.0", - "frcYear": "2026", - "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", - "mavenUrls": [ - "https://maven.ctr-electronics.com/release/" - ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-latest.json", - "requires": [ - { - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", - "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", - "offlineFileName": "Phoenix6-replay-frc2026-latest.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-latest.json" - } - ], - "conflictsWith": [ - { - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", - "errorMessage": "Users must use the regular Phoenix 5 vendordep when using the regular Phoenix 6 vendordep.", - "offlineFileName": "Phoenix6-frc2026-latest.json" - }, - { - "uuid": "ab676553-b602-441f-a38d-f1296eff6537", - "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", - "offlineFileName": "Phoenix5-frc2026-latest.json" - } - ], - "javaDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "api-java", - "version": "5.36.0" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "wpiapi-java", - "version": "5.36.0" - } - ], - "jniDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "cci", - "version": "5.36.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.replay", - "artifactId": "cci-replay", - "version": "5.36.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "cci-sim", - "version": "5.36.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ], - "cppDependencies": [ - { - "groupId": "com.ctre.phoenix", - "artifactId": "wpiapi-cpp", - "version": "5.36.0", - "libName": "CTRE_Phoenix_WPI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "api-cpp", - "version": "5.36.0", - "libName": "CTRE_Phoenix", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix", - "artifactId": "cci", - "version": "5.36.0", - "libName": "CTRE_PhoenixCCI", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.replay", - "artifactId": "wpiapi-cpp-replay", - "version": "5.36.0", - "libName": "CTRE_Phoenix_WPIReplay", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.replay", - "artifactId": "api-cpp-replay", - "version": "5.36.0", - "libName": "CTRE_PhoenixReplay", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.replay", - "artifactId": "cci-replay", - "version": "5.36.0", - "libName": "CTRE_PhoenixCCIReplay", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "wpiapi-cpp-sim", - "version": "5.36.0", - "libName": "CTRE_Phoenix_WPISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "api-cpp-sim", - "version": "5.36.0", - "libName": "CTRE_PhoenixSim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - }, - { - "groupId": "com.ctre.phoenix.sim", - "artifactId": "cci-sim", - "version": "5.36.0", - "libName": "CTRE_PhoenixCCISim", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" - ], - "simMode": "swsim" - } - ] -} \ No newline at end of file diff --git a/examples/drivebase_only_2026/vendordeps/Phoenix6-replay-26.1.0.json b/examples/drivebase_only_2026/vendordeps/Phoenix6-26.1.1.json similarity index 81% rename from examples/drivebase_only_2026/vendordeps/Phoenix6-replay-26.1.0.json rename to examples/drivebase_only_2026/vendordeps/Phoenix6-26.1.1.json index e49c760..7a0eca0 100644 --- a/examples/drivebase_only_2026/vendordeps/Phoenix6-replay-26.1.0.json +++ b/examples/drivebase_only_2026/vendordeps/Phoenix6-26.1.1.json @@ -1,82 +1,60 @@ { - "fileName": "Phoenix6-replay-26.1.0.json", - "name": "CTRE-Phoenix (v6) Replay", - "version": "26.1.0", + "fileName": "Phoenix6-26.1.1.json", + "name": "CTRE-Phoenix (v6)", + "version": "26.1.1", "frcYear": "2026", - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", "mavenUrls": [ "https://maven.ctr-electronics.com/release/" ], - "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-latest.json", + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2026-latest.json", "conflictsWith": [ { - "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", "errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.", - "offlineFileName": "Phoenix6-frc2026-latest.json" + "offlineFileName": "Phoenix6-replay-frc2026-latest.json" } ], "javaDependencies": [ { "groupId": "com.ctre.phoenix6", "artifactId": "wpiapi-java", - "version": "26.1.0" + "version": "26.1.1" } ], "jniDependencies": [ { "groupId": "com.ctre.phoenix6", "artifactId": "api-cpp", - "version": "26.1.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6", - "artifactId": "tools", - "version": "26.1.0", - "isJar": false, - "skipInvalidPlatforms": true, - "validPlatforms": [ - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6.replay", - "artifactId": "api-cpp-replay", - "version": "26.1.0", + "version": "26.1.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ "windowsx86-64", "linuxx86-64", "linuxarm64", - "osxuniversal" + "linuxathena" ], "simMode": "hwsim" }, { - "groupId": "com.ctre.phoenix6.replay", - "artifactId": "tools-replay", - "version": "26.1.0", + "groupId": "com.ctre.phoenix6", + "artifactId": "tools", + "version": "26.1.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ "windowsx86-64", "linuxx86-64", "linuxarm64", - "osxuniversal" + "linuxathena" ], "simMode": "hwsim" }, { "groupId": "com.ctre.phoenix6.sim", "artifactId": "api-cpp-sim", - "version": "26.1.0", + "version": "26.1.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -90,7 +68,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "tools-sim", - "version": "26.1.0", + "version": "26.1.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -104,7 +82,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simTalonSRX", - "version": "26.1.0", + "version": "26.1.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -118,7 +96,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simVictorSPX", - "version": "26.1.0", + "version": "26.1.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -132,7 +110,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simPigeonIMU", - "version": "26.1.0", + "version": "26.1.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -146,7 +124,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProTalonFX", - "version": "26.1.0", + "version": "26.1.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -160,7 +138,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProTalonFXS", - "version": "26.1.0", + "version": "26.1.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -174,7 +152,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANcoder", - "version": "26.1.0", + "version": "26.1.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -188,7 +166,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProPigeon2", - "version": "26.1.0", + "version": "26.1.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -202,7 +180,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANrange", - "version": "26.1.0", + "version": "26.1.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -216,7 +194,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdi", - "version": "26.1.0", + "version": "26.1.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -230,7 +208,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdle", - "version": "26.1.0", + "version": "26.1.1", "isJar": false, "skipInvalidPlatforms": true, "validPlatforms": [ @@ -246,12 +224,15 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "wpiapi-cpp", - "version": "26.1.0", + "version": "26.1.1", "libName": "CTRE_Phoenix6_WPI", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", "linuxathena" ], "simMode": "hwsim" @@ -259,52 +240,23 @@ { "groupId": "com.ctre.phoenix6", "artifactId": "tools", - "version": "26.1.0", + "version": "26.1.1", "libName": "CTRE_PhoenixTools", "headerClassifier": "headers", "sharedLibrary": true, "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "linuxathena" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6.replay", - "artifactId": "wpiapi-cpp-replay", - "version": "26.1.0", - "libName": "CTRE_Phoenix6_WPIReplay", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, "binaryPlatforms": [ "windowsx86-64", "linuxx86-64", "linuxarm64", - "osxuniversal" - ], - "simMode": "hwsim" - }, - { - "groupId": "com.ctre.phoenix6.replay", - "artifactId": "tools-replay", - "version": "26.1.0", - "libName": "CTRE_PhoenixTools_Replay", - "headerClassifier": "headers", - "sharedLibrary": true, - "skipInvalidPlatforms": true, - "binaryPlatforms": [ - "windowsx86-64", - "linuxx86-64", - "linuxarm64", - "osxuniversal" + "linuxathena" ], "simMode": "hwsim" }, { "groupId": "com.ctre.phoenix6.sim", "artifactId": "wpiapi-cpp-sim", - "version": "26.1.0", + "version": "26.1.1", "libName": "CTRE_Phoenix6_WPISim", "headerClassifier": "headers", "sharedLibrary": true, @@ -320,7 +272,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "tools-sim", - "version": "26.1.0", + "version": "26.1.1", "libName": "CTRE_PhoenixTools_Sim", "headerClassifier": "headers", "sharedLibrary": true, @@ -336,7 +288,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simTalonSRX", - "version": "26.1.0", + "version": "26.1.1", "libName": "CTRE_SimTalonSRX", "headerClassifier": "headers", "sharedLibrary": true, @@ -352,7 +304,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simVictorSPX", - "version": "26.1.0", + "version": "26.1.1", "libName": "CTRE_SimVictorSPX", "headerClassifier": "headers", "sharedLibrary": true, @@ -368,7 +320,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simPigeonIMU", - "version": "26.1.0", + "version": "26.1.1", "libName": "CTRE_SimPigeonIMU", "headerClassifier": "headers", "sharedLibrary": true, @@ -384,7 +336,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProTalonFX", - "version": "26.1.0", + "version": "26.1.1", "libName": "CTRE_SimProTalonFX", "headerClassifier": "headers", "sharedLibrary": true, @@ -400,7 +352,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProTalonFXS", - "version": "26.1.0", + "version": "26.1.1", "libName": "CTRE_SimProTalonFXS", "headerClassifier": "headers", "sharedLibrary": true, @@ -416,7 +368,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANcoder", - "version": "26.1.0", + "version": "26.1.1", "libName": "CTRE_SimProCANcoder", "headerClassifier": "headers", "sharedLibrary": true, @@ -432,7 +384,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProPigeon2", - "version": "26.1.0", + "version": "26.1.1", "libName": "CTRE_SimProPigeon2", "headerClassifier": "headers", "sharedLibrary": true, @@ -448,7 +400,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANrange", - "version": "26.1.0", + "version": "26.1.1", "libName": "CTRE_SimProCANrange", "headerClassifier": "headers", "sharedLibrary": true, @@ -464,7 +416,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdi", - "version": "26.1.0", + "version": "26.1.1", "libName": "CTRE_SimProCANdi", "headerClassifier": "headers", "sharedLibrary": true, @@ -480,7 +432,7 @@ { "groupId": "com.ctre.phoenix6.sim", "artifactId": "simProCANdle", - "version": "26.1.0", + "version": "26.1.1", "libName": "CTRE_SimProCANdle", "headerClassifier": "headers", "sharedLibrary": true, diff --git a/examples/drivebase_only_2026/vendordeps/StudicaLib.json b/examples/drivebase_only_2026/vendordeps/StudicaLib.json new file mode 100644 index 0000000..0fdd1d4 --- /dev/null +++ b/examples/drivebase_only_2026/vendordeps/StudicaLib.json @@ -0,0 +1,78 @@ +{ + "fileName": "StudicaLib.json", + "name": "StudicaLib", + "version": "2026.0.1", + "frcYear": "2026", + "uuid": "963ef341-8abd-4981-a969-c8ae3f592e82", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2026/" + ], + "jsonUrl": "https://dev.studica.com/maven/release/2026/json/StudicaLib-2026.0.1.json", + "conflictsWith": [ + { + "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", + "errorMessage": "StudicaLib (newer devices) is not compatible with Studica (NavX, NavX2)", + "offlineFileName": "Studica.json" + } + ], + "javaDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-java", + "version": "2026.0.1" + } + ], + "jniDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.1", + "skipInvalidPlatforms": true, + "isJar": false, + "validPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-cpp", + "version": "2026.0.1", + "libName": "StudicaLib", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + }, + { + "groupId": "com.studica.frc", + "artifactId": "StudicaLib-driver", + "version": "2026.0.1", + "libName": "StudicaLibDriver", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxarm64", + "linuxx86-64", + "linuxathena", + "linuxarm32", + "osxuniversal" + ] + } + ] +} \ No newline at end of file diff --git a/vendordep/yagsl.json b/vendordep/yagsl.json index b974014..41150c2 100644 --- a/vendordep/yagsl.json +++ b/vendordep/yagsl.json @@ -34,18 +34,6 @@ "offlineFileName": "REVLib.json", "onlineUrl": "https://software-metadata.revrobotics.com/REVLib-2026.json" }, - { - "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", - "errorMessage": "Phoenix6 Replay is required!", - "offlineFileName": "Phoenix6-replay-26.1.0.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-replay-frc2026-latest.json" - }, - { - "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", - "errorMessage": "Phoenix5 Replay Compatibility is required!", - "offlineFileName": "Phoenix5-replay-5.36.0.json", - "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-replay-frc2026-latest.json" - }, { "uuid": "60b2694b-9e6e-4026-81ee-6f167946f4b0", "errorMessage": "ThriftyLib is required!", diff --git a/yagsl/java/swervelib/SwerveDrive.java b/yagsl/java/swervelib/SwerveDrive.java index 9ccb6a5..46ddce2 100644 --- a/yagsl/java/swervelib/SwerveDrive.java +++ b/yagsl/java/swervelib/SwerveDrive.java @@ -51,16 +51,15 @@ import java.util.Optional; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; +import swervelib.parser.deserializer.ReflectionsManager; +import swervelib.parser.deserializer.ReflectionsManager.VENDOR; import swervelib.simulation.ironmaple.simulation.SimulatedArena; import swervelib.simulation.ironmaple.simulation.drivesims.AbstractDriveTrainSimulation; import swervelib.simulation.ironmaple.simulation.drivesims.SwerveDriveSimulation; import swervelib.simulation.ironmaple.simulation.drivesims.configs.DriveTrainSimulationConfig; import swervelib.simulation.ironmaple.simulation.drivesims.configs.SwerveModuleSimulationConfig; -import swervelib.encoders.CANCoderSwerve; -import swervelib.imu.Pigeon2Swerve; import swervelib.imu.SwerveIMU; import swervelib.math.SwerveMath; -import swervelib.motors.TalonFXSwerve; import swervelib.parser.Cache; import swervelib.parser.SwerveControllerConfiguration; import swervelib.parser.SwerveDriveConfiguration; @@ -371,21 +370,21 @@ public void updateCacheValidityPeriods(long imu, long driveMotor, long absoluteE */ private void checkIfTunerXCompatible() { - boolean compatible = imu instanceof Pigeon2Swerve; - for (SwerveModule module : swerveModules) - { - compatible = compatible && module.getDriveMotor() instanceof TalonFXSwerve && - module.getAngleMotor() instanceof TalonFXSwerve && - module.getAbsoluteEncoder() instanceof CANCoderSwerve; - if (!compatible) - { - break; - } - } - if (compatible) - { - tunerXRecommendation.set(true); - } +// boolean compatible = imu instanceof Pigeon2Swerve; +// for (SwerveModule module : swerveModules) +// { +// compatible = compatible && module.getDriveMotor() instanceof TalonFXSwerve && +// module.getAngleMotor() instanceof TalonFXSwerve && +// module.getAbsoluteEncoder() instanceof CANCoderSwerve; +// if (!compatible) +// { +// break; +// } +// } +// if (compatible) +// { +// tunerXRecommendation.set(true); +// } } diff --git a/yagsl/java/swervelib/parser/SwerveDriveConfiguration.java b/yagsl/java/swervelib/parser/SwerveDriveConfiguration.java index 653a4a3..8a4ac32 100644 --- a/yagsl/java/swervelib/parser/SwerveDriveConfiguration.java +++ b/yagsl/java/swervelib/parser/SwerveDriveConfiguration.java @@ -6,7 +6,6 @@ import swervelib.simulation.ironmaple.simulation.drivesims.COTS; import swervelib.simulation.ironmaple.simulation.drivesims.GyroSimulation; import swervelib.SwerveModule; -import swervelib.imu.Pigeon2Swerve; import swervelib.imu.SwerveIMU; import swervelib.math.SwerveMath; @@ -151,10 +150,6 @@ public DCMotor getAngleMotorSim() */ public Supplier getGyroSim() { - if (imu instanceof Pigeon2Swerve) - { - return COTS.ofPigeon2(); - } return COTS.ofGenericGyro(); } diff --git a/yagsl/java/swervelib/parser/json/DeviceJson.java b/yagsl/java/swervelib/parser/json/DeviceJson.java index a029fbd..27c0c09 100644 --- a/yagsl/java/swervelib/parser/json/DeviceJson.java +++ b/yagsl/java/swervelib/parser/json/DeviceJson.java @@ -4,37 +4,26 @@ import static swervelib.telemetry.SwerveDriveTelemetry.i2cLockupWarning; import static swervelib.telemetry.SwerveDriveTelemetry.serialCommsIssueWarning; -import com.ctre.phoenix.motorcontrol.FeedbackDevice; - import edu.wpi.first.math.system.plant.DCMotor; import edu.wpi.first.wpilibj.DriverStation; import swervelib.encoders.AnalogAbsoluteEncoderSwerve; -import swervelib.encoders.CANCoderSwerve; import swervelib.encoders.CanAndMagSwerve; import swervelib.encoders.DIODutyCycleEncoderSwerve; import swervelib.encoders.SparkFlexEncoderSwerve; import swervelib.encoders.SparkMaxAnalogEncoderSwerve; import swervelib.encoders.SparkMaxEncoderSwerve; import swervelib.encoders.SwerveAbsoluteEncoder; -import swervelib.encoders.TalonFXSEncoderAnalogSwerve; -import swervelib.encoders.TalonSRXEncoderSwerve; import swervelib.imu.ADIS16448Swerve; import swervelib.imu.ADIS16470Swerve; import swervelib.imu.ADXRS450Swerve; import swervelib.imu.AnalogGyroSwerve; import swervelib.imu.CanandgyroSwerve; -import swervelib.imu.Pigeon2Swerve; -import swervelib.imu.PigeonSwerve; -import swervelib.imu.PigeonViaTalonSRXSwerve; import swervelib.imu.SwerveIMU; import swervelib.motors.SparkFlexSwerve; import swervelib.motors.SparkMaxBrushedMotorSwerve; import swervelib.motors.SparkMaxBrushedMotorSwerve.Type; import swervelib.motors.SparkMaxSwerve; import swervelib.motors.SwerveMotor; -import swervelib.motors.TalonFXSSwerve; -import swervelib.motors.TalonFXSwerve; -import swervelib.motors.TalonSRXSwerve; import swervelib.motors.ThriftyNovaSwerve; import swervelib.parser.deserializer.ReflectionsManager; import swervelib.parser.deserializer.ReflectionsManager.VENDOR; @@ -90,7 +79,11 @@ public SwerveAbsoluteEncoder createEncoder(SwerveMotor motor) case "sparkflex_canandcoder": return new SparkFlexEncoderSwerve(motor, 360); case "talonfxs_analog": - return new TalonFXSEncoderAnalogSwerve(motor); + return ReflectionsManager.create(VENDOR.PHOENIX6, + "swervelib.encoders.TalonFXSEncoderAnalogSwerve", + new Class[]{SwerveMotor.class}, + new Object[]{motor}); +// return new TalonFXSEncoderAnalogSwerve(motor); case "canandcoder_can": case "canandmag_can": return new CanAndMagSwerve(id); @@ -105,14 +98,42 @@ public SwerveAbsoluteEncoder createEncoder(SwerveMotor motor) case "analog": return new AnalogAbsoluteEncoderSwerve(id); case "cancoder": - return new CANCoderSwerve(id, canbus != null ? canbus : ""); + return ReflectionsManager.create(VENDOR.PHOENIX6, + "swervelib.encoders.CANCoderSwerve", + new Class[]{int.class, String.class}, + new Object[]{id, canbus != null ? canbus : ""}); +// return new CANCoderSwerve(id, canbus != null ? canbus : ""); case "srxmag_standalone": - return new TalonSRXEncoderSwerve(new TalonSRXSwerve(id, false, DCMotor.getCIM(1)), - FeedbackDevice.PulseWidthEncodedPosition); + return ReflectionsManager.create(VENDOR.PHOENIX6, + "swervelib.encoders.TalonSRXEncoderSwerve", + new Class[]{SwerveMotor.class, String.class}, + new Object[]{ + ReflectionsManager.create(VENDOR.PHOENIX5, + "swervelib.motors.TalonSRXSwerve", + new Class[]{ + int.class, + boolean.class, + DCMotor.class}, + new Object[]{ + id, + false, + DCMotor.getCIM( + 1)}), + "PulseWidthEncodedPosition"}); +// return new TalonSRXEncoderSwerve(new TalonSRXSwerve(id, false, DCMotor.getCIM(1)), +// FeedbackDevice.PulseWidthEncodedPosition); case "talonsrx_pwm": - return new TalonSRXEncoderSwerve(motor, FeedbackDevice.PulseWidthEncodedPosition); + return ReflectionsManager.create(VENDOR.PHOENIX5, + "swervelib.encoders.TalonSRXEncoderSwerve", + new Class[]{SwerveMotor.class, String.class}, + new Object[]{motor, "PulseWidthEncodedPosition"}); +// return new TalonSRXEncoderSwerve(motor, FeedbackDevice.PulseWidthEncodedPosition); case "talonsrx_analog": - return new TalonSRXEncoderSwerve(motor, FeedbackDevice.Analog); + return ReflectionsManager.create(VENDOR.PHOENIX5, + "swervelib.encoders.TalonSRXEncoderSwerve", + new Class[]{SwerveMotor.class, String.class}, + new Object[]{motor, "Analog"}); +// return new TalonSRXEncoderSwerve(motor, FeedbackDevice.Analog); case "thrifty_nova_rev": return ReflectionsManager.create(VENDOR.THRIFTYBOT, "swervelib.encoders.ThriftyNovaEncoderSwerve", @@ -124,10 +145,10 @@ public SwerveAbsoluteEncoder createEncoder(SwerveMotor motor) new Class[]{SwerveMotor.class, String.class}, new Object[]{motor, "REDUX_ENCODER"}); case "thrifty_nova_srx_mag": - return ReflectionsManager.create(VENDOR.THRIFTYBOT, - "swervelib.encoders.ThriftyNovaEncoderSwerve", - new Class[]{SwerveMotor.class, String.class}, - new Object[]{motor, "SRX_MAG_ENCODER"}); + return ReflectionsManager.create(VENDOR.THRIFTYBOT, + "swervelib.encoders.ThriftyNovaEncoderSwerve", + new Class[]{SwerveMotor.class, String.class}, + new Object[]{motor, "SRX_MAG_ENCODER"}); default: throw new RuntimeException(type + " is not a recognized absolute encoder type."); } @@ -159,13 +180,13 @@ public SwerveIMU createIMU() case "navx": case "navx_spi": return ReflectionsManager.create(VENDOR.STUDICA, - "swervelib.imu.NavXSwerve", - new Class[]{String.class}, - new Object[]{"kMXP_SPI"}); + "swervelib.imu.NavXSwerve", + new Class[]{String.class}, + new Object[]{"kMXP_SPI"}); case "navx3": return ReflectionsManager.create(VENDOR.STUDICA2, "swervelib.imu.NavX3Swerve", - new Class[]{Integer.class}, + new Class[]{int.class}, new Object[]{id}); case "navx_i2c": DriverStation.reportWarning( @@ -193,11 +214,20 @@ public SwerveIMU createIMU() new Class[]{String.class}, new Object[]{"kMXP_UART"}); case "pigeon": - return new PigeonSwerve(id); + ReflectionsManager.create(VENDOR.PHOENIX5, + "swervelib.imu.PigeonSwerve", + new Class[]{int.class}, + new Object[]{id}); case "pigeon_via_talonsrx": - return new PigeonViaTalonSRXSwerve(id); + return ReflectionsManager.create(VENDOR.PHOENIX5, + "swervelib.imu.PigeonViaTalonSRXSwerve", + new Class[]{int.class}, + new Object[]{id}); case "pigeon2": - return new Pigeon2Swerve(id, canbus != null ? canbus : ""); + return ReflectionsManager.create(VENDOR.PHOENIX6, + "swervelib.imu.Pigeon2Swerve", + new Class[]{int.class, String.class}, + new Object[]{id, canbus != null ? canbus : ""}); default: throw new RuntimeException(type + " is not a recognized imu/gyroscope type."); } @@ -218,13 +248,33 @@ public SwerveMotor createMotor(boolean isDriveMotor) switch (type) { case "talonfxs_neo": - return new TalonFXSSwerve(id, canbus != null ? canbus : "", isDriveMotor, DCMotor.getNEO(1)); + return ReflectionsManager.create(VENDOR.PHOENIX6, + "swervelib.motors.TalonFXSSwerve", + new Class[]{int.class, String.class, boolean.class, + DCMotor.class}, + new Object[]{id, canbus != null ? canbus : "", isDriveMotor, + DCMotor.getNEO(1)}); case "talonfxs_neo550": - return new TalonFXSSwerve(id, canbus != null ? canbus : "", isDriveMotor, DCMotor.getNeo550(1)); + return ReflectionsManager.create(VENDOR.PHOENIX6, + "swervelib.motors.TalonFXSSwerve", + new Class[]{int.class, String.class, boolean.class, + DCMotor.class}, + new Object[]{id, canbus != null ? canbus : "", isDriveMotor, + DCMotor.getNeo550(1)}); case "talonfxs_vortex": - return new TalonFXSSwerve(id, canbus != null ? canbus : "", isDriveMotor, DCMotor.getNeoVortex(1)); + return ReflectionsManager.create(VENDOR.PHOENIX6, + "swervelib.motors.TalonFXSSwerve", + new Class[]{int.class, String.class, boolean.class, + DCMotor.class}, + new Object[]{id, canbus != null ? canbus : "", isDriveMotor, + DCMotor.getNeoVortex(1)}); case "talonfxs_minion": - return new TalonFXSSwerve(id, canbus != null ? canbus : "", isDriveMotor, DCMotor.getMinion(1)); + return ReflectionsManager.create(VENDOR.PHOENIX6, + "swervelib.motors.TalonFXSSwerve", + new Class[]{int.class, String.class, boolean.class, + DCMotor.class}, + new Object[]{id, canbus != null ? canbus : "", isDriveMotor, + DCMotor.getMinion(1)}); case "talonfxs_pulsar": throw new UnsupportedOperationException("Cannot create pulsar combination"); case "sparkmax_neo": @@ -253,18 +303,52 @@ public SwerveMotor createMotor(boolean isDriveMotor) throw new UnsupportedOperationException("Cannot create pulsar combination"); case "falcon500": case "falcon": - return new TalonFXSwerve(id, canbus != null ? canbus : "", isDriveMotor, DCMotor.getFalcon500(1)); + return ReflectionsManager.create(VENDOR.PHOENIX6, + "swervelib.motors.TalonFXSwerve", + new Class[]{int.class, String.class, boolean.class, + DCMotor.class}, + new Object[]{id, canbus != null ? canbus : "", isDriveMotor, + DCMotor.getFalcon500(1)}); +// return new TalonFXSwerve(id, canbus != null ? canbus : "", isDriveMotor, DCMotor.getFalcon500(1)); case "falcon500foc": - return new TalonFXSwerve(id, canbus != null ? canbus : "", isDriveMotor, DCMotor.getFalcon500Foc(1)); + return ReflectionsManager.create(VENDOR.PHOENIX6, + "swervelib.motors.TalonFXSwerve", + new Class[]{int.class, String.class, boolean.class, + DCMotor.class}, + new Object[]{id, canbus != null ? canbus : "", isDriveMotor, + DCMotor.getFalcon500Foc(1)}); +// return new TalonFXSwerve(id, canbus != null ? canbus : "", isDriveMotor, DCMotor.getFalcon500Foc(1)); case "krakenx44": - return new TalonFXSwerve(id, canbus != null ? canbus : "", isDriveMotor, DCMotor.getKrakenX44(1)); + return ReflectionsManager.create(VENDOR.PHOENIX6, + "swervelib.motors.TalonFXSwerve", + new Class[]{int.class, String.class, boolean.class, + DCMotor.class}, + new Object[]{id, canbus != null ? canbus : "", isDriveMotor, + DCMotor.getKrakenX44(1)}); +// return new TalonFXSwerve(id, canbus != null ? canbus : "", isDriveMotor, DCMotor.getKrakenX44(1)); case "krakenx60": case "talonfx": - return new TalonFXSwerve(id, canbus != null ? canbus : "", isDriveMotor, DCMotor.getKrakenX60(1)); + return ReflectionsManager.create(VENDOR.PHOENIX6, + "swervelib.motors.TalonFXSwerve", + new Class[]{int.class, String.class, boolean.class, + DCMotor.class}, + new Object[]{id, canbus != null ? canbus : "", isDriveMotor, + DCMotor.getKrakenX60(1)}); +// return new TalonFXSwerve(id, canbus != null ? canbus : "", isDriveMotor, DCMotor.getKrakenX60(1)); case "krakenx60foc": - return new TalonFXSwerve(id, canbus != null ? canbus : "", isDriveMotor, DCMotor.getKrakenX60Foc(1)); + return ReflectionsManager.create(VENDOR.PHOENIX6, + "swervelib.motors.TalonFXSwerve", + new Class[]{int.class, String.class, boolean.class, + DCMotor.class}, + new Object[]{id, canbus != null ? canbus : "", isDriveMotor, + DCMotor.getKrakenX60Foc(1)}); +// return new TalonFXSwerve(id, canbus != null ? canbus : "", isDriveMotor, DCMotor.getKrakenX60Foc(1)); case "talonsrx": - return new TalonSRXSwerve(id, isDriveMotor, DCMotor.getCIM(1)); + return ReflectionsManager.create(VENDOR.PHOENIX5, + "swervelib.motors.TalonSRXSwerve", + new Class[]{int.class, boolean.class, DCMotor.class}, + new Object[]{id, isDriveMotor, DCMotor.getCIM(1)}); +// return new TalonSRXSwerve(id, isDriveMotor, DCMotor.getCIM(1)); case "sparkmax_brushed": if (canbus == null) { From 852754ea25e906944f49a1956377d95c5c81296e Mon Sep 17 00:00:00 2001 From: Nicholas McCurry Date: Tue, 3 Feb 2026 17:34:24 -0700 Subject: [PATCH 37/62] Fix broken link in README.md (#18) Update the configuration website link in the README.md file, the current link leads to a 404 page on the BroncBotz website. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e488ec6..d562cbf 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Development happens here! # Support our developers! Visit our organization [here](https://yetanothersoftwaresuite.com) -### TL;DR Generate and download your configuration [here](https://broncbotz3481.github.io/YAGSL-Example/) and unzip it so that it follows structure below: +### TL;DR Generate and download your configuration [here](https://yet-another-software-suite.github.io/YAGSL/config_generator/) and unzip it so that it follows structure below: ```text deploy From 9a097ea8cb2e47a16a3b7d6a1495c90c448c063d Mon Sep 17 00:00:00 2001 From: thenetworkgrinch Date: Tue, 3 Feb 2026 21:45:40 -0600 Subject: [PATCH 38/62] Fixed NavX3 again. Signed-off-by: thenetworkgrinch --- yagsl/java/swervelib/parser/json/DeviceJson.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yagsl/java/swervelib/parser/json/DeviceJson.java b/yagsl/java/swervelib/parser/json/DeviceJson.java index 27c0c09..a30bcba 100644 --- a/yagsl/java/swervelib/parser/json/DeviceJson.java +++ b/yagsl/java/swervelib/parser/json/DeviceJson.java @@ -186,7 +186,7 @@ public SwerveIMU createIMU() case "navx3": return ReflectionsManager.create(VENDOR.STUDICA2, "swervelib.imu.NavX3Swerve", - new Class[]{int.class}, + new Class[]{Integer.class}, new Object[]{id}); case "navx_i2c": DriverStation.reportWarning( From 375769f37679a15fbc0c54d18d0a1282b387b8a9 Mon Sep 17 00:00:00 2001 From: Scaratek <153395462+Scaratech@users.noreply.github.com> Date: Sat, 7 Feb 2026 12:00:02 -0500 Subject: [PATCH 39/62] fix: do not round vales parsed from JSON (#22) --- yagsl/java/swervelib/parser/json/ModuleJson.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yagsl/java/swervelib/parser/json/ModuleJson.java b/yagsl/java/swervelib/parser/json/ModuleJson.java index d2917e7..3d0198c 100644 --- a/yagsl/java/swervelib/parser/json/ModuleJson.java +++ b/yagsl/java/swervelib/parser/json/ModuleJson.java @@ -128,8 +128,8 @@ else if ((absEncoder instanceof ThriftyNovaEncoderSwerve && angleMotor instanceo conversionFactors, absEncoder, absoluteEncoderOffset, - Units.inchesToMeters(Math.round(location.front)), - Units.inchesToMeters(Math.round(location.left)), + Units.inchesToMeters(location.front), + Units.inchesToMeters(location.left), anglePIDF, velocityPIDF, physicalCharacteristics, From b79ca369909497b7cc7edefd01c4d4e6b88f7690 Mon Sep 17 00:00:00 2001 From: XM2TBE <112593148+XM2TBE@users.noreply.github.com> Date: Sat, 7 Feb 2026 09:03:12 -0800 Subject: [PATCH 40/62] Update incorrect DefautCommand (#25) driveFieldOrientedAnglularVelocity rather than driveAngularVelocity --- .../src/main/java/frc/robot/RobotContainer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/field_oriented_drivebase/src/main/java/frc/robot/RobotContainer.java b/examples/field_oriented_drivebase/src/main/java/frc/robot/RobotContainer.java index a6058c8..c8965ed 100644 --- a/examples/field_oriented_drivebase/src/main/java/frc/robot/RobotContainer.java +++ b/examples/field_oriented_drivebase/src/main/java/frc/robot/RobotContainer.java @@ -82,7 +82,7 @@ public RobotContainer() private void configureBindings() { Command driveFieldOrientedAnglularVelocity = drivebase.driveFieldOriented(driveAngularVelocity); - drivebase.setDefaultCommand(driveAngularVelocity); + drivebase.setDefaultCommand(driveFieldOrientedAnglularVelocity); } From a36f9b32ae357fd10bce0bfdff48ae44e545ab2d Mon Sep 17 00:00:00 2001 From: XM2TBE <112593148+XM2TBE@users.noreply.github.com> Date: Sat, 7 Feb 2026 09:03:44 -0800 Subject: [PATCH 41/62] Refactor blueAlliance variable initialization (#24) Refactor blueAlliance initialization to use DriverStation alliance. --- .../frc/robot/subsystems/swervedrive/SwerveSubsystem.java | 4 +++- .../frc/robot/subsystems/swervedrive/SwerveSubsystem.java | 3 ++- .../frc/robot/subsystems/swervedrive/SwerveSubsystem.java | 3 ++- .../frc/robot/subsystems/swervedrive/SwerveSubsystem.java | 3 ++- .../frc/robot/subsystems/swervedrive/SwerveSubsystem.java | 3 ++- .../frc/robot/subsystems/swervedrive/SwerveSubsystem.java | 3 ++- .../frc/robot/subsystems/swervedrive/SwerveSubsystem.java | 3 ++- 7 files changed, 15 insertions(+), 7 deletions(-) diff --git a/examples/clock_drive_drivebase/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java b/examples/clock_drive_drivebase/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java index 1d70326..6c6e74a 100644 --- a/examples/clock_drive_drivebase/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java +++ b/examples/clock_drive_drivebase/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java @@ -14,6 +14,7 @@ import edu.wpi.first.math.kinematics.SwerveDriveKinematics; import edu.wpi.first.math.trajectory.Trajectory; import edu.wpi.first.wpilibj.DriverStation; +import edu.wpi.first.wpilibj.DriverStation.Alliance; import edu.wpi.first.wpilibj2.command.Command; import edu.wpi.first.wpilibj2.command.SubsystemBase; import edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine.Config; @@ -46,7 +47,8 @@ public class SwerveSubsystem extends SubsystemBase */ public SwerveSubsystem(File directory) { - boolean blueAlliance = false; + boolean blueAlliance = DriverStation.getAlliance().isPresent() && DriverStation.getAlliance().get() == Alliance.Blue; + Pose2d startingPose = blueAlliance ? new Pose2d(new Translation2d(Meter.of(1), Meter.of(4)), Rotation2d.fromDegrees(0)) diff --git a/examples/drivebase_only_2026/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java b/examples/drivebase_only_2026/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java index 1d70326..eefc88d 100644 --- a/examples/drivebase_only_2026/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java +++ b/examples/drivebase_only_2026/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java @@ -14,6 +14,7 @@ import edu.wpi.first.math.kinematics.SwerveDriveKinematics; import edu.wpi.first.math.trajectory.Trajectory; import edu.wpi.first.wpilibj.DriverStation; +import edu.wpi.first.wpilibj.DriverStation.Alliance; import edu.wpi.first.wpilibj2.command.Command; import edu.wpi.first.wpilibj2.command.SubsystemBase; import edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine.Config; @@ -46,7 +47,7 @@ public class SwerveSubsystem extends SubsystemBase */ public SwerveSubsystem(File directory) { - boolean blueAlliance = false; + boolean blueAlliance = DriverStation.getAlliance().isPresent() && DriverStation.getAlliance().get() == Alliance.Blue; Pose2d startingPose = blueAlliance ? new Pose2d(new Translation2d(Meter.of(1), Meter.of(4)), Rotation2d.fromDegrees(0)) diff --git a/examples/drivebase_with_PathPlanner/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java b/examples/drivebase_with_PathPlanner/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java index 409aeb8..f8856f7 100644 --- a/examples/drivebase_with_PathPlanner/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java +++ b/examples/drivebase_with_PathPlanner/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java @@ -26,6 +26,7 @@ import edu.wpi.first.math.trajectory.Trajectory; 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.Timer; import edu.wpi.first.wpilibj2.command.Command; import edu.wpi.first.wpilibj2.command.Commands; @@ -63,7 +64,7 @@ public class SwerveSubsystem extends SubsystemBase */ public SwerveSubsystem(File directory) { - boolean blueAlliance = false; + boolean blueAlliance = DriverStation.getAlliance().isPresent() && DriverStation.getAlliance().get() == Alliance.Blue; Pose2d startingPose = blueAlliance ? new Pose2d(new Translation2d(Meter.of(1), Meter.of(4)), Rotation2d.fromDegrees(0)) diff --git a/examples/drivebase_with_PhotonVision/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java b/examples/drivebase_with_PhotonVision/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java index 5589ff3..c3dcab9 100644 --- a/examples/drivebase_with_PhotonVision/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java +++ b/examples/drivebase_with_PhotonVision/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java @@ -26,6 +26,7 @@ import edu.wpi.first.math.trajectory.Trajectory; 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.Timer; import edu.wpi.first.wpilibj2.command.Command; import edu.wpi.first.wpilibj2.command.Commands; @@ -76,7 +77,7 @@ public class SwerveSubsystem extends SubsystemBase */ public SwerveSubsystem(File directory) { - boolean blueAlliance = false; + boolean blueAlliance = DriverStation.getAlliance().isPresent() && DriverStation.getAlliance().get() == Alliance.Blue; Pose2d startingPose = blueAlliance ? new Pose2d(new Translation2d(Meter.of(1), Meter.of(4)), Rotation2d.fromDegrees(0)) diff --git a/examples/field_oriented_drivebase/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java b/examples/field_oriented_drivebase/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java index 1d70326..eefc88d 100644 --- a/examples/field_oriented_drivebase/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java +++ b/examples/field_oriented_drivebase/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java @@ -14,6 +14,7 @@ import edu.wpi.first.math.kinematics.SwerveDriveKinematics; import edu.wpi.first.math.trajectory.Trajectory; import edu.wpi.first.wpilibj.DriverStation; +import edu.wpi.first.wpilibj.DriverStation.Alliance; import edu.wpi.first.wpilibj2.command.Command; import edu.wpi.first.wpilibj2.command.SubsystemBase; import edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine.Config; @@ -46,7 +47,7 @@ public class SwerveSubsystem extends SubsystemBase */ public SwerveSubsystem(File directory) { - boolean blueAlliance = false; + boolean blueAlliance = DriverStation.getAlliance().isPresent() && DriverStation.getAlliance().get() == Alliance.Blue; Pose2d startingPose = blueAlliance ? new Pose2d(new Translation2d(Meter.of(1), Meter.of(4)), Rotation2d.fromDegrees(0)) diff --git a/examples/full_example/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java b/examples/full_example/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java index 5589ff3..c3dcab9 100644 --- a/examples/full_example/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java +++ b/examples/full_example/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java @@ -26,6 +26,7 @@ import edu.wpi.first.math.trajectory.Trajectory; 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.Timer; import edu.wpi.first.wpilibj2.command.Command; import edu.wpi.first.wpilibj2.command.Commands; @@ -76,7 +77,7 @@ public class SwerveSubsystem extends SubsystemBase */ public SwerveSubsystem(File directory) { - boolean blueAlliance = false; + boolean blueAlliance = DriverStation.getAlliance().isPresent() && DriverStation.getAlliance().get() == Alliance.Blue; Pose2d startingPose = blueAlliance ? new Pose2d(new Translation2d(Meter.of(1), Meter.of(4)), Rotation2d.fromDegrees(0)) diff --git a/examples/robot_relative_drivebase/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java b/examples/robot_relative_drivebase/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java index ab0a6d4..a480957 100644 --- a/examples/robot_relative_drivebase/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java +++ b/examples/robot_relative_drivebase/src/main/java/frc/robot/subsystems/swervedrive/SwerveSubsystem.java @@ -14,6 +14,7 @@ import edu.wpi.first.math.kinematics.SwerveDriveKinematics; import edu.wpi.first.math.trajectory.Trajectory; import edu.wpi.first.wpilibj.DriverStation; +import edu.wpi.first.wpilibj.DriverStation.Alliance; import edu.wpi.first.wpilibj2.command.Command; import edu.wpi.first.wpilibj2.command.SubsystemBase; import edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine.Config; @@ -52,7 +53,7 @@ public class SwerveSubsystem extends SubsystemBase */ public SwerveSubsystem(File directory) { - boolean blueAlliance = false; + boolean blueAlliance = DriverStation.getAlliance().isPresent() && DriverStation.getAlliance().get() == Alliance.Blue; Pose2d startingPose = blueAlliance ? blueAllianceStartingPose : redAllianceStartingPose; // Configure the Telemetry before creating the SwerveDrive to avoid unnecessary objects being created. SwerveDriveTelemetry.verbosity = TelemetryVerbosity.HIGH; From f14243ffd000ba329707c73d10300387ed2abaac Mon Sep 17 00:00:00 2001 From: Curt Date: Sun, 8 Feb 2026 14:26:40 -0500 Subject: [PATCH 42/62] Fix some simulation issues (#26) --- .../simulation/ironmaple/simulation/IntakeSimulation.java | 2 +- .../simulation/ironmaple/simulation/SimulatedArena.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/IntakeSimulation.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/IntakeSimulation.java index 5988a2d..8a76977 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/IntakeSimulation.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/IntakeSimulation.java @@ -270,7 +270,7 @@ public boolean addGamePieceToIntake() { */ public boolean addGamePiecesToIntake(int piecesToAdd) { boolean toReturn = gamePiecesInIntakeCount + piecesToAdd <= capacity; - gamePiecesInIntakeCount = Math.max(gamePiecesInIntakeCount + piecesToAdd, capacity); + gamePiecesInIntakeCount = Math.min(gamePiecesInIntakeCount + piecesToAdd, capacity); return toReturn; } diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java index c42302d..1eed656 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java @@ -708,8 +708,7 @@ public synchronized Pose3d[] getGamePiecesArrayByType(String type) { */ public synchronized List getGamePiecesByType(String type) { final List gamePiecesPoses = new ArrayList<>(this.gamePieces); - gamePiecesPoses.stream().filter(gamePiece -> !Objects.equals(gamePiece.getType(), type)); - return gamePiecesPoses; + return gamePiecesPoses.stream().filter(gamePiece -> !Objects.equals(gamePiece.getType(), type)); } /** From 15c74e63315fc4186cd4151708a9ad92730ed3cf Mon Sep 17 00:00:00 2001 From: thenetworkgrinch Date: Sat, 21 Feb 2026 07:47:14 -0600 Subject: [PATCH 43/62] Fixed build issue. Signed-off-by: thenetworkgrinch --- .../vendordeps/Phoenix5-5.36.0.json | 171 ++++++++++++++++++ .../ironmaple/simulation/SimulatedArena.java | 26 +-- 2 files changed, 186 insertions(+), 11 deletions(-) create mode 100644 examples/drivebase_only_2026/vendordeps/Phoenix5-5.36.0.json diff --git a/examples/drivebase_only_2026/vendordeps/Phoenix5-5.36.0.json b/examples/drivebase_only_2026/vendordeps/Phoenix5-5.36.0.json new file mode 100644 index 0000000..fb0f20f --- /dev/null +++ b/examples/drivebase_only_2026/vendordeps/Phoenix5-5.36.0.json @@ -0,0 +1,171 @@ +{ + "fileName": "Phoenix5-5.36.0.json", + "name": "CTRE-Phoenix (v5)", + "version": "5.36.0", + "frcYear": "2026", + "uuid": "ab676553-b602-441f-a38d-f1296eff6537", + "mavenUrls": [ + "https://maven.ctr-electronics.com/release/" + ], + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-frc2026-latest.json", + "requires": [ + { + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", + "offlineFileName": "Phoenix6-frc2026-latest.json", + "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2026-latest.json" + } + ], + "conflictsWith": [ + { + "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af", + "errorMessage": "Users must use the Phoenix 5 replay vendordep when using the Phoenix 6 replay vendordep.", + "offlineFileName": "Phoenix6-replay-frc2026-latest.json" + }, + { + "uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df", + "errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.", + "offlineFileName": "Phoenix5-replay-frc2026-latest.json" + } + ], + "javaDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-java", + "version": "5.36.0" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-java", + "version": "5.36.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ], + "cppDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-cpp", + "version": "5.36.0", + "libName": "CTRE_Phoenix_WPI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-cpp", + "version": "5.36.0", + "libName": "CTRE_Phoenix", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.36.0", + "libName": "CTRE_PhoenixCCI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "wpiapi-cpp-sim", + "version": "5.36.0", + "libName": "CTRE_Phoenix_WPISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "api-cpp-sim", + "version": "5.36.0", + "libName": "CTRE_PhoenixSim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.36.0", + "libName": "CTRE_PhoenixCCISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxarm64", + "osxuniversal" + ], + "simMode": "swsim" + } + ] +} \ No newline at end of file diff --git a/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java b/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java index 1eed656..5796f2e 100644 --- a/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java +++ b/yagsl/java/swervelib/simulation/ironmaple/simulation/SimulatedArena.java @@ -10,13 +10,26 @@ import edu.wpi.first.networktables.DoublePublisher; import edu.wpi.first.networktables.NetworkTable; import edu.wpi.first.networktables.NetworkTableInstance; -import edu.wpi.first.units.Units; import edu.wpi.first.units.measure.Time; import edu.wpi.first.wpilibj.DriverStation; import edu.wpi.first.wpilibj.DriverStation.Alliance; import edu.wpi.first.wpilibj.RobotBase; import edu.wpi.first.wpilibj.TimedRobot; import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import org.dyn4j.dynamics.Body; +import org.dyn4j.dynamics.BodyFixture; +import org.dyn4j.geometry.Convex; +import org.dyn4j.geometry.Geometry; +import org.dyn4j.geometry.MassType; +import org.dyn4j.world.PhysicsWorld; +import org.dyn4j.world.World; import swervelib.simulation.ironmaple.simulation.drivesims.AbstractDriveTrainSimulation; import swervelib.simulation.ironmaple.simulation.gamepieces.GamePiece; import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation; @@ -26,15 +39,6 @@ import swervelib.simulation.ironmaple.simulation.seasonspecific.rebuilt2026.Arena2026Rebuilt; import swervelib.simulation.ironmaple.utils.mathutils.GeometryConvertor; -import java.util.*; -import org.dyn4j.dynamics.Body; -import org.dyn4j.dynamics.BodyFixture; -import org.dyn4j.geometry.Convex; -import org.dyn4j.geometry.Geometry; -import org.dyn4j.geometry.MassType; -import org.dyn4j.world.PhysicsWorld; -import org.dyn4j.world.World; - /** * * @@ -708,7 +712,7 @@ public synchronized Pose3d[] getGamePiecesArrayByType(String type) { */ public synchronized List getGamePiecesByType(String type) { final List gamePiecesPoses = new ArrayList<>(this.gamePieces); - return gamePiecesPoses.stream().filter(gamePiece -> !Objects.equals(gamePiece.getType(), type)); + return gamePiecesPoses.stream().filter(gamePiece -> !Objects.equals(gamePiece.getType(), type)).toList(); } /** From 32d8ecb8d5943c3589586a9d28abe371be9d73c3 Mon Sep 17 00:00:00 2001 From: thenetworkgrinch Date: Sun, 22 Feb 2026 17:38:49 -0600 Subject: [PATCH 44/62] Improved SwevreInputStream aim function. Signed-off-by: thenetworkgrinch --- yagsl/java/swervelib/SwerveInputStream.java | 193 ++++++++++++++------ 1 file changed, 138 insertions(+), 55 deletions(-) diff --git a/yagsl/java/swervelib/SwerveInputStream.java b/yagsl/java/swervelib/SwerveInputStream.java index c01ae92..302bc01 100644 --- a/yagsl/java/swervelib/SwerveInputStream.java +++ b/yagsl/java/swervelib/SwerveInputStream.java @@ -1,9 +1,12 @@ package swervelib; +import static edu.wpi.first.units.Units.Seconds; + import edu.wpi.first.math.MathUtil; import edu.wpi.first.math.Nat; import edu.wpi.first.math.Vector; import edu.wpi.first.math.controller.ProfiledPIDController; +import edu.wpi.first.math.controller.SimpleMotorFeedforward; import edu.wpi.first.math.geometry.Pose2d; import edu.wpi.first.math.geometry.Rotation2d; import edu.wpi.first.math.geometry.Transform2d; @@ -11,9 +14,12 @@ import edu.wpi.first.math.kinematics.ChassisSpeeds; import edu.wpi.first.math.numbers.N2; import edu.wpi.first.math.trajectory.TrapezoidProfile.State; +import edu.wpi.first.units.measure.Angle; +import edu.wpi.first.units.measure.Time; import edu.wpi.first.wpilibj.DriverStation; import edu.wpi.first.wpilibj.DriverStation.Alliance; import edu.wpi.first.wpilibj.XboxController; +import edu.wpi.first.wpilibj2.command.button.Trigger; import java.util.Optional; import java.util.function.BooleanSupplier; import java.util.function.DoubleSupplier; @@ -50,107 +56,119 @@ public class SwerveInputStream implements Supplier /** * Translation suppliers. */ - private final DoubleSupplier controllerTranslationX; + private final DoubleSupplier controllerTranslationX; /** * Translational supplier. */ - private final DoubleSupplier controllerTranslationY; + private final DoubleSupplier controllerTranslationY; /** * {@link SwerveDrive} object for transformations. */ - private final SwerveDrive swerveDrive; + private final SwerveDrive swerveDrive; /** * Rotation supplier as angular velocity. */ - private Optional controllerOmega = Optional.empty(); + private Optional controllerOmega = Optional.empty(); /** * Controller supplier as heading. */ - private Optional controllerHeadingX = Optional.empty(); + private Optional controllerHeadingX = Optional.empty(); /** * Controller supplier as heading. */ - private Optional controllerHeadingY = Optional.empty(); + private Optional controllerHeadingY = Optional.empty(); /** * Axis deadband for the controller. */ - private Optional axisDeadband = Optional.empty(); + private Optional axisDeadband = Optional.empty(); /** * Translational axis scalar value, should be between (0, 1]. */ - private Optional translationAxisScale = Optional.empty(); + private Optional translationAxisScale = Optional.empty(); /** * Angular velocity axis scalar value, should be between (0, 1] */ - private Optional omegaAxisScale = Optional.empty(); + private Optional omegaAxisScale = Optional.empty(); /** * Target to aim at. */ - private Optional aimTarget = Optional.empty(); + private Optional aimTarget = Optional.empty(); /** * Target {@link Supplier} to drive towards when driveToPose is enabled. */ - private Optional> driveToPose = Optional.empty(); + private Optional> driveToPose = Optional.empty(); /** * {@link ProfiledPIDController} for the translation while driving to a pose. Units are m/s */ - private Optional driveToPoseTranslationPIDController = Optional.empty(); + private Optional driveToPoseTranslationPIDController = Optional.empty(); /** * {@link ProfiledPIDController} for the Rotational axis while driving to a pose. Units are m/s */ - private Optional driveToPoseOmegaPIDController = Optional.empty(); + private Optional driveToPoseOmegaPIDController = Optional.empty(); /** * Output {@link ChassisSpeeds} based on heading while this is True. */ - private Optional headingEnabled = Optional.empty(); + private Optional headingEnabled = Optional.empty(); /** * Locked heading for {@link SwerveInputMode#TRANSLATION_ONLY} */ - private Optional lockedHeading = Optional.empty(); + private Optional lockedHeading = Optional.empty(); /** * Output {@link ChassisSpeeds} based on aim while this is True. */ - private Optional aimEnabled = Optional.empty(); + private Optional aimEnabled = Optional.empty(); /** * Output {@link ChassisSpeeds} to move to a specific {@link Pose2d}. */ - private Optional driveToPoseEnabled = Optional.empty(); + private Optional driveToPoseEnabled = Optional.empty(); /** * Maintain current heading and drive without rotating, ideally. */ - private Optional translationOnlyEnabled = Optional.empty(); + private Optional translationOnlyEnabled = Optional.empty(); /** * Cube the translation magnitude from the controller. */ - private Optional translationCube = Optional.empty(); + private Optional translationCube = Optional.empty(); /** * Cube the angular velocity axis from the controller. */ - private Optional omegaCube = Optional.empty(); + private Optional omegaCube = Optional.empty(); /** * Robot relative oriented output expected. */ - private Optional robotRelative = Optional.empty(); + private Optional robotRelative = Optional.empty(); /** * Field oriented chassis output is relative to your current alliance. */ - private Optional allianceRelative = Optional.empty(); + private Optional allianceRelative = Optional.empty(); /** * Heading offset enable state. */ - private Optional translationHeadingOffsetEnabled = Optional.empty(); + private Optional translationHeadingOffsetEnabled = Optional.empty(); /** * Heading offset to apply during heading based control. */ - private Optional translationHeadingOffset = Optional.empty(); + private Optional translationHeadingOffset = Optional.empty(); + /** + * Aim current pose lookahead time. + */ + private Optional