diff --git a/.automation/cpp_template/WPILib-License.md b/.automation/cpp_template/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/.automation/cpp_template/WPILib-License.md +++ b/.automation/cpp_template/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/.automation/cpp_template/settings.gradle b/.automation/cpp_template/settings.gradle index c493958a..25f6f6e8 100644 --- a/.automation/cpp_template/settings.gradle +++ b/.automation/cpp_template/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') diff --git a/.automation/java_template/.vscode/settings.json b/.automation/java_template/.vscode/settings.json index 612cdd0d..5e6ede86 100644 --- a/.automation/java_template/.vscode/settings.json +++ b/.automation/java_template/.vscode/settings.json @@ -56,5 +56,6 @@ "edu.wpi.first.math.proto.*", "edu.wpi.first.math.**.proto.*", "edu.wpi.first.math.**.struct.*", - ] + ], + "java.dependency.enableDependencyCheckup": false } diff --git a/.automation/java_template/WPILib-License.md b/.automation/java_template/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/.automation/java_template/WPILib-License.md +++ b/.automation/java_template/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/.automation/java_template/build.gradle b/.automation/java_template/build.gradle index f3438298..e9b0020a 100644 --- a/.automation/java_template/build.gradle +++ b/.automation/java_template/build.gradle @@ -43,7 +43,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. @@ -88,7 +89,9 @@ wpi.sim.addDriverstation() // knows where to look for our Robot Class. jar { from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } - from sourceSets.main.allSource + from('src') { into 'backup/src' } + from('vendordeps') { into 'backup/vendordeps' } + from('build.gradle') { into 'backup' } manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) duplicatesStrategy = DuplicatesStrategy.INCLUDE } diff --git a/.automation/java_template/settings.gradle b/.automation/java_template/settings.gradle index c493958a..25f6f6e8 100644 --- a/.automation/java_template/settings.gradle +++ b/.automation/java_template/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') diff --git a/.automation/python_template/pyproject.toml b/.automation/python_template/pyproject.toml index a4f083ae..9735d7ee 100644 --- a/.automation/python_template/pyproject.toml +++ b/.automation/python_template/pyproject.toml @@ -8,25 +8,25 @@ # Version of robotpy this project depends on robotpy_version = "2026.1.1b1" -# Which extra RobotPy components should be installed +# Which core WPILib components should be installed # -> equivalent to `pip install robotpy[extra1, ...] components = [ # "all", # "apriltag", "commands2", # "cscore", - # "navx", -] - -# Other pip packages to install -requires = [ - "phoenix6~=26.1.0", - # "pathplannerlib", - # "phoenix5", - # "photonvision", - # "playingwithfusion", - # "rev", # "romi", # "sim", # "xrp", ] + +# Other pip packages to install (including vendor packages) +requires = [ + "phoenix6~=26.1", + # "photonlibpy", + # "robotpy-ctre", # Phoenix 5 + # "robotpy-navx", + # "robotpy-pathplannerlib", + # "robotpy-playingwithfusion", + # "robotpy-rev", +] diff --git a/cpp/ArcadeDrive/WPILib-License.md b/cpp/ArcadeDrive/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/cpp/ArcadeDrive/WPILib-License.md +++ b/cpp/ArcadeDrive/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/cpp/ArcadeDrive/settings.gradle b/cpp/ArcadeDrive/settings.gradle index c493958a..25f6f6e8 100644 --- a/cpp/ArcadeDrive/settings.gradle +++ b/cpp/ArcadeDrive/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') diff --git a/cpp/BasicLatencyCompensation/WPILib-License.md b/cpp/BasicLatencyCompensation/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/cpp/BasicLatencyCompensation/WPILib-License.md +++ b/cpp/BasicLatencyCompensation/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/cpp/BasicLatencyCompensation/settings.gradle b/cpp/BasicLatencyCompensation/settings.gradle index c493958a..25f6f6e8 100644 --- a/cpp/BasicLatencyCompensation/settings.gradle +++ b/cpp/BasicLatencyCompensation/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') diff --git a/cpp/CANcoder/WPILib-License.md b/cpp/CANcoder/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/cpp/CANcoder/WPILib-License.md +++ b/cpp/CANcoder/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/cpp/CANcoder/settings.gradle b/cpp/CANcoder/settings.gradle index c493958a..25f6f6e8 100644 --- a/cpp/CANcoder/settings.gradle +++ b/cpp/CANcoder/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') diff --git a/cpp/CANdi/WPILib-License.md b/cpp/CANdi/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/cpp/CANdi/WPILib-License.md +++ b/cpp/CANdi/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/cpp/CANdi/settings.gradle b/cpp/CANdi/settings.gradle index c493958a..25f6f6e8 100644 --- a/cpp/CANdi/settings.gradle +++ b/cpp/CANdi/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') diff --git a/cpp/CANdle/WPILib-License.md b/cpp/CANdle/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/cpp/CANdle/WPILib-License.md +++ b/cpp/CANdle/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/cpp/CANdle/settings.gradle b/cpp/CANdle/settings.gradle index c493958a..25f6f6e8 100644 --- a/cpp/CANdle/settings.gradle +++ b/cpp/CANdle/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') diff --git a/cpp/CANrange/.gitignore b/cpp/CANrange/.gitignore index 9a9ca7be..34cbaac1 100644 --- a/cpp/CANrange/.gitignore +++ b/cpp/CANrange/.gitignore @@ -1,187 +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 +# 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/cpp/CANrange/.vscode/launch.json b/cpp/CANrange/.vscode/launch.json index 5b804e84..c9c9713d 100644 --- a/cpp/CANrange/.vscode/launch.json +++ b/cpp/CANrange/.vscode/launch.json @@ -1,21 +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, - } - ] -} +{ + // 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/cpp/CANrange/.vscode/settings.json b/cpp/CANrange/.vscode/settings.json index d2d2fe11..5e795ffd 100644 --- a/cpp/CANrange/.vscode/settings.json +++ b/cpp/CANrange/.vscode/settings.json @@ -1,18 +1,18 @@ -{ - "java.configuration.updateBuildConfiguration": "disabled", - "java.import.gradle.enabled": false, - "files.exclude": { - "**/.git": true, - "**/.svn": true, - "**/.hg": true, - "**/CVS": true, - "**/.DS_Store": true, - "bin/": true, - "**/.classpath": true, - "**/.project": true, - "**/.settings": true, - "**/.factorypath": true, - "**/*~": true - }, - "C_Cpp.default.configurationProvider": "vscode-wpilib" -} +{ + "java.configuration.updateBuildConfiguration": "disabled", + "java.import.gradle.enabled": false, + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true, + "bin/": true, + "**/.classpath": true, + "**/.project": true, + "**/.settings": true, + "**/.factorypath": true, + "**/*~": true + }, + "C_Cpp.default.configurationProvider": "vscode-wpilib" +} diff --git a/cpp/CANrange/WPILib-License.md b/cpp/CANrange/WPILib-License.md index e7cd597b..eb3061b0 100644 --- a/cpp/CANrange/WPILib-License.md +++ b/cpp/CANrange/WPILib-License.md @@ -1,24 +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. +Copyright (c) 2009-2026 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/cpp/CANrange/build.gradle b/cpp/CANrange/build.gradle index 5d8f58fc..03d5d2df 100644 --- a/cpp/CANrange/build.gradle +++ b/cpp/CANrange/build.gradle @@ -1,101 +1,101 @@ -plugins { - id "cpp" - id "google-test-test-suite" - id "edu.wpi.first.GradleRIO" version "2026.1.1" -} - -// 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 - - frcCpp(getArtifactTypeClass('FRCNativeArtifact')) { - } - - // 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.frcCpp - -// Set this to true to enable desktop support. -def includeDesktopSupport = true - -// Set to true to run simulation in debug mode -wpi.cpp.debugSimulation = false - -// Default enable simgui -wpi.sim.addGui().defaultEnabled = true -// Enable DS but not by default -wpi.sim.addDriverstation() - -model { - components { - frcUserProgram(NativeExecutableSpec) { - targetPlatform wpi.platforms.roborio - if (includeDesktopSupport) { - targetPlatform wpi.platforms.desktop - } - - sources.cpp { - source { - srcDir 'src/main/cpp' - include '**/*.cpp', '**/*.cc' - } - exportedHeaders { - srcDir 'src/main/include' - } - } - - // Set deploy task to deploy this component - deployArtifact.component = it - - // Enable run tasks for this component - wpi.cpp.enableExternalTasks(it) - - // Enable simulation for this component - wpi.sim.enable(it) - // Defining my dependencies. In this case, WPILib (+ friends), and vendor libraries. - wpi.cpp.vendor.cpp(it) - wpi.cpp.deps.wpilib(it) - } - } - testSuites { - frcUserProgramTest(GoogleTestTestSuiteSpec) { - testing $.components.frcUserProgram - - sources.cpp { - source { - srcDir 'src/test/cpp' - include '**/*.cpp' - } - } - - // Enable run tasks for this component - wpi.cpp.enableExternalTasks(it) - - wpi.cpp.vendor.cpp(it) - wpi.cpp.deps.wpilib(it) - wpi.cpp.deps.googleTest(it) - } - } -} +plugins { + id "cpp" + id "google-test-test-suite" + id "edu.wpi.first.GradleRIO" version "2026.1.1" +} + +// 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 + + frcCpp(getArtifactTypeClass('FRCNativeArtifact')) { + } + + // 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.frcCpp + +// Set this to true to enable desktop support. +def includeDesktopSupport = true + +// Set to true to run simulation in debug mode +wpi.cpp.debugSimulation = false + +// Default enable simgui +wpi.sim.addGui().defaultEnabled = true +// Enable DS but not by default +wpi.sim.addDriverstation() + +model { + components { + frcUserProgram(NativeExecutableSpec) { + targetPlatform wpi.platforms.roborio + if (includeDesktopSupport) { + targetPlatform wpi.platforms.desktop + } + + sources.cpp { + source { + srcDir 'src/main/cpp' + include '**/*.cpp', '**/*.cc' + } + exportedHeaders { + srcDir 'src/main/include' + } + } + + // Set deploy task to deploy this component + deployArtifact.component = it + + // Enable run tasks for this component + wpi.cpp.enableExternalTasks(it) + + // Enable simulation for this component + wpi.sim.enable(it) + // Defining my dependencies. In this case, WPILib (+ friends), and vendor libraries. + wpi.cpp.vendor.cpp(it) + wpi.cpp.deps.wpilib(it) + } + } + testSuites { + frcUserProgramTest(GoogleTestTestSuiteSpec) { + testing $.components.frcUserProgram + + sources.cpp { + source { + srcDir 'src/test/cpp' + include '**/*.cpp' + } + } + + // Enable run tasks for this component + wpi.cpp.enableExternalTasks(it) + + wpi.cpp.vendor.cpp(it) + wpi.cpp.deps.wpilib(it) + wpi.cpp.deps.googleTest(it) + } + } +} diff --git a/cpp/CANrange/gradle/wrapper/gradle-wrapper.properties b/cpp/CANrange/gradle/wrapper/gradle-wrapper.properties index 8e975a5f..34bd9ce9 100644 --- a/cpp/CANrange/gradle/wrapper/gradle-wrapper.properties +++ b/cpp/CANrange/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +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 +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/cpp/CANrange/gradlew.bat b/cpp/CANrange/gradlew.bat index 9b42019c..9d21a218 100644 --- a/cpp/CANrange/gradlew.bat +++ b/cpp/CANrange/gradlew.bat @@ -1,94 +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 +@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/cpp/CANrange/settings.gradle b/cpp/CANrange/settings.gradle index 3bc070a1..25f6f6e8 100644 --- a/cpp/CANrange/settings.gradle +++ b/cpp/CANrange/settings.gradle @@ -1,30 +1,30 @@ -import org.gradle.internal.os.OperatingSystem - -pluginManagement { - repositories { - mavenLocal() - gradlePluginPortal() - String frcYear = '2025' - 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"); +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/cpp/CommandBasedDrive/WPILib-License.md b/cpp/CommandBasedDrive/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/cpp/CommandBasedDrive/WPILib-License.md +++ b/cpp/CommandBasedDrive/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/cpp/CommandBasedDrive/settings.gradle b/cpp/CommandBasedDrive/settings.gradle index c493958a..25f6f6e8 100644 --- a/cpp/CommandBasedDrive/settings.gradle +++ b/cpp/CommandBasedDrive/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') diff --git a/cpp/ControlRequestLimits/WPILib-License.md b/cpp/ControlRequestLimits/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/cpp/ControlRequestLimits/WPILib-License.md +++ b/cpp/ControlRequestLimits/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/cpp/ControlRequestLimits/settings.gradle b/cpp/ControlRequestLimits/settings.gradle index c493958a..25f6f6e8 100644 --- a/cpp/ControlRequestLimits/settings.gradle +++ b/cpp/ControlRequestLimits/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') diff --git a/cpp/CurrentLimits/WPILib-License.md b/cpp/CurrentLimits/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/cpp/CurrentLimits/WPILib-License.md +++ b/cpp/CurrentLimits/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/cpp/CurrentLimits/settings.gradle b/cpp/CurrentLimits/settings.gradle index c493958a..25f6f6e8 100644 --- a/cpp/CurrentLimits/settings.gradle +++ b/cpp/CurrentLimits/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') diff --git a/cpp/FusedCANcoder/WPILib-License.md b/cpp/FusedCANcoder/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/cpp/FusedCANcoder/WPILib-License.md +++ b/cpp/FusedCANcoder/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/cpp/FusedCANcoder/settings.gradle b/cpp/FusedCANcoder/settings.gradle index c493958a..25f6f6e8 100644 --- a/cpp/FusedCANcoder/settings.gradle +++ b/cpp/FusedCANcoder/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') diff --git a/cpp/MotionMagic/WPILib-License.md b/cpp/MotionMagic/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/cpp/MotionMagic/WPILib-License.md +++ b/cpp/MotionMagic/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/cpp/MotionMagic/settings.gradle b/cpp/MotionMagic/settings.gradle index c493958a..25f6f6e8 100644 --- a/cpp/MotionMagic/settings.gradle +++ b/cpp/MotionMagic/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') diff --git a/cpp/PWMTalonFXS/WPILib-License.md b/cpp/PWMTalonFXS/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/cpp/PWMTalonFXS/WPILib-License.md +++ b/cpp/PWMTalonFXS/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/cpp/PWMTalonFXS/settings.gradle b/cpp/PWMTalonFXS/settings.gradle index c493958a..25f6f6e8 100644 --- a/cpp/PWMTalonFXS/settings.gradle +++ b/cpp/PWMTalonFXS/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') diff --git a/cpp/PhoenixSysId/WPILib-License.md b/cpp/PhoenixSysId/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/cpp/PhoenixSysId/WPILib-License.md +++ b/cpp/PhoenixSysId/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/cpp/PhoenixSysId/settings.gradle b/cpp/PhoenixSysId/settings.gradle index c493958a..25f6f6e8 100644 --- a/cpp/PhoenixSysId/settings.gradle +++ b/cpp/PhoenixSysId/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') diff --git a/cpp/Pigeon2/WPILib-License.md b/cpp/Pigeon2/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/cpp/Pigeon2/WPILib-License.md +++ b/cpp/Pigeon2/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/cpp/Pigeon2/settings.gradle b/cpp/Pigeon2/settings.gradle index c493958a..25f6f6e8 100644 --- a/cpp/Pigeon2/settings.gradle +++ b/cpp/Pigeon2/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') diff --git a/cpp/PositionClosedLoop/WPILib-License.md b/cpp/PositionClosedLoop/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/cpp/PositionClosedLoop/WPILib-License.md +++ b/cpp/PositionClosedLoop/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/cpp/PositionClosedLoop/settings.gradle b/cpp/PositionClosedLoop/settings.gradle index c493958a..25f6f6e8 100644 --- a/cpp/PositionClosedLoop/settings.gradle +++ b/cpp/PositionClosedLoop/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') diff --git a/cpp/Simulation/WPILib-License.md b/cpp/Simulation/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/cpp/Simulation/WPILib-License.md +++ b/cpp/Simulation/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/cpp/Simulation/settings.gradle b/cpp/Simulation/settings.gradle index c493958a..25f6f6e8 100644 --- a/cpp/Simulation/settings.gradle +++ b/cpp/Simulation/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') diff --git a/cpp/SwerveWithPathPlanner/WPILib-License.md b/cpp/SwerveWithPathPlanner/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/cpp/SwerveWithPathPlanner/WPILib-License.md +++ b/cpp/SwerveWithPathPlanner/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/cpp/SwerveWithPathPlanner/build.gradle b/cpp/SwerveWithPathPlanner/build.gradle index 03d5d2df..011f7578 100644 --- a/cpp/SwerveWithPathPlanner/build.gradle +++ b/cpp/SwerveWithPathPlanner/build.gradle @@ -27,7 +27,7 @@ deploy { frcStaticFileDeploy(getArtifactTypeClass('FileTreeArtifact')) { files = project.fileTree('src/main/deploy') directory = '/home/lvuser/deploy' - deleteOldFiles = false // Change to true to delete files on roboRIO that no + deleteOldFiles = true // Change to true to delete files on roboRIO that no // longer exist in deploy directory of this project } } diff --git a/cpp/SwerveWithPathPlanner/settings.gradle b/cpp/SwerveWithPathPlanner/settings.gradle index c493958a..25f6f6e8 100644 --- a/cpp/SwerveWithPathPlanner/settings.gradle +++ b/cpp/SwerveWithPathPlanner/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') diff --git a/cpp/SwerveWithPathPlanner/src/main/cpp/Robot.cpp b/cpp/SwerveWithPathPlanner/src/main/cpp/Robot.cpp index 4c7a5ea5..1b20ac48 100644 --- a/cpp/SwerveWithPathPlanner/src/main/cpp/Robot.cpp +++ b/cpp/SwerveWithPathPlanner/src/main/cpp/Robot.cpp @@ -10,27 +10,28 @@ Robot::Robot() {} void Robot::RobotPeriodic() { - frc2::CommandScheduler::GetInstance().Run(); - - /* - * This example of adding Limelight is very simple and may not be sufficient for on-field use. - * Users typically need to provide a standard deviation that scales with the distance to target - * and changes with number of tags available. - * - * This example is sufficient to show that vision integration is possible, though exact implementation - * of how to use vision should be tuned per-robot and to the team's specification. - */ - if (kUseLimelight) { - auto const driveState = m_container.drivetrain.GetState(); - auto const heading = driveState.Pose.Rotation().Degrees(); - auto const omega = driveState.Speeds.omega; - - LimelightHelpers::SetRobotOrientation("limelight", heading.value(), 0, 0, 0, 0, 0); - auto llMeasurement = LimelightHelpers::getBotPoseEstimate_wpiBlue_MegaTag2("limelight"); - if (llMeasurement && llMeasurement->tagCount > 0 && units::math::abs(omega) < 2_tps) { - m_container.drivetrain.AddVisionMeasurement(llMeasurement->pose, llMeasurement->timestampSeconds); + m_timeAndJoystickReplay.Update(); + frc2::CommandScheduler::GetInstance().Run(); + + /* + * This example of adding Limelight is very simple and may not be sufficient for on-field use. + * Users typically need to provide a standard deviation that scales with the distance to target + * and changes with number of tags available. + * + * This example is sufficient to show that vision integration is possible, though exact implementation + * of how to use vision should be tuned per-robot and to the team's specification. + */ + if (kUseLimelight) { + auto const driveState = m_container.drivetrain.GetState(); + auto const heading = driveState.Pose.Rotation().Degrees(); + auto const omega = driveState.Speeds.omega; + + LimelightHelpers::SetRobotOrientation("limelight", heading.value(), 0, 0, 0, 0, 0); + auto llMeasurement = LimelightHelpers::getBotPoseEstimate_wpiBlue_MegaTag2("limelight"); + if (llMeasurement && llMeasurement->tagCount > 0 && units::math::abs(omega) < 2_tps) { + m_container.drivetrain.AddVisionMeasurement(llMeasurement->pose, llMeasurement->timestampSeconds); + } } - } } void Robot::DisabledInit() {} @@ -40,11 +41,11 @@ void Robot::DisabledPeriodic() {} void Robot::DisabledExit() {} void Robot::AutonomousInit() { - m_autonomousCommand = m_container.GetAutonomousCommand(); + m_autonomousCommand = m_container.GetAutonomousCommand(); - if (m_autonomousCommand) { - m_autonomousCommand->Schedule(); - } + if (m_autonomousCommand) { + frc2::CommandScheduler::GetInstance().Schedule(m_autonomousCommand.value()); + } } void Robot::AutonomousPeriodic() {} @@ -52,9 +53,9 @@ void Robot::AutonomousPeriodic() {} void Robot::AutonomousExit() {} void Robot::TeleopInit() { - if (m_autonomousCommand) { - m_autonomousCommand->Cancel(); - } + if (m_autonomousCommand) { + frc2::CommandScheduler::GetInstance().Cancel(m_autonomousCommand.value()); + } } void Robot::TeleopPeriodic() {} @@ -62,7 +63,7 @@ void Robot::TeleopPeriodic() {} void Robot::TeleopExit() {} void Robot::TestInit() { - frc2::CommandScheduler::GetInstance().CancelAll(); + frc2::CommandScheduler::GetInstance().CancelAll(); } void Robot::TestPeriodic() {} @@ -71,6 +72,6 @@ void Robot::TestExit() {} #ifndef RUNNING_FRC_TESTS int main() { - return frc::StartRobot(); + return frc::StartRobot(); } #endif diff --git a/cpp/SwerveWithPathPlanner/src/main/cpp/RobotContainer.cpp b/cpp/SwerveWithPathPlanner/src/main/cpp/RobotContainer.cpp index 71aa4b28..c4adab33 100644 --- a/cpp/SwerveWithPathPlanner/src/main/cpp/RobotContainer.cpp +++ b/cpp/SwerveWithPathPlanner/src/main/cpp/RobotContainer.cpp @@ -43,6 +43,17 @@ void RobotContainer::ConfigureBindings() return point.WithModuleDirection(frc::Rotation2d{-joystick.GetLeftY(), -joystick.GetLeftX()}); })); + joystick.POVUp().WhileTrue( + drivetrain.ApplyRequest([this]() -> auto&& { + return forwardStraight.WithVelocityX(0.5_mps).WithVelocityY(0_mps); + }) + ); + joystick.POVDown().WhileTrue( + drivetrain.ApplyRequest([this]() -> auto&& { + return forwardStraight.WithVelocityX(-0.5_mps).WithVelocityY(0_mps); + }) + ); + // Run SysId routines when holding back/start and X/Y. // Note that each routine should be run exactly once in a single log. (joystick.Back() && joystick.Y()).WhileTrue(drivetrain.SysIdDynamic(frc2::sysid::Direction::kForward)); diff --git a/cpp/SwerveWithPathPlanner/src/main/cpp/Telemetry.cpp b/cpp/SwerveWithPathPlanner/src/main/cpp/Telemetry.cpp index 8324f3eb..f09bdc75 100644 --- a/cpp/SwerveWithPathPlanner/src/main/cpp/Telemetry.cpp +++ b/cpp/SwerveWithPathPlanner/src/main/cpp/Telemetry.cpp @@ -3,6 +3,16 @@ using namespace ctre::phoenix6; +Telemetry::Telemetry(units::meters_per_second_t maxSpeed) : MaxSpeed{maxSpeed} +{ + SignalLogger::Start(); + + /* Set up the module state Mechanism2d telemetry */ + for (size_t i = 0; i < m_moduleSpeeds.size(); ++i) { + frc::SmartDashboard::PutData("Module " + std::to_string(i), &m_moduleMechanisms[i]); + } +} + void Telemetry::Telemeterize(subsystems::CommandSwerveDrivetrain::SwerveDriveState const &state) { /* Telemeterize the swerve drive state */ @@ -15,17 +25,11 @@ void Telemetry::Telemeterize(subsystems::CommandSwerveDrivetrain::SwerveDriveSta driveOdometryFrequency.Set(1.0 / state.OdometryPeriod.value()); /* Also write to log file */ - std::array moduleStatesArray{}; - std::array moduleTargetsArray{}; - for (int i = 0; i < 4; ++i) { - moduleStatesArray[i*2 + 0] = state.ModuleStates[i].angle.Radians().value(); - moduleStatesArray[i*2 + 1] = state.ModuleStates[i].speed.value(); - moduleTargetsArray[i*2 + 0] = state.ModuleTargets[i].angle.Radians().value(); - moduleTargetsArray[i*2 + 1] = state.ModuleTargets[i].speed.value(); - } - SignalLogger::WriteDoubleArray("DriveState/Pose", std::array{state.Pose.X().value(), state.Pose.Y().value(), state.Pose.Rotation().Degrees().value()}); - SignalLogger::WriteDoubleArray("DriveState/ModuleStates", moduleStatesArray); - SignalLogger::WriteDoubleArray("DriveState/ModuleTargets", moduleTargetsArray); + SignalLogger::WriteStruct("DriveState/Pose", state.Pose); + SignalLogger::WriteStruct("DriveState/Speeds", state.Speeds); + SignalLogger::WriteStructArray("DriveState/ModuleStates", state.ModuleStates); + SignalLogger::WriteStructArray("DriveState/ModuleTargets", state.ModuleTargets); + SignalLogger::WriteStructArray("DriveState/ModulePositions", state.ModulePositions); SignalLogger::WriteValue("DriveState/OdometryPeriod", state.OdometryPeriod); /* Telemeterize the pose to a Field2d */ @@ -36,12 +40,10 @@ void Telemetry::Telemeterize(subsystems::CommandSwerveDrivetrain::SwerveDriveSta state.Pose.Rotation().Degrees().value() }); - /* Telemeterize the module states to a Mechanism2d */ + /* Telemeterize each module state to a Mechanism2d */ for (size_t i = 0; i < m_moduleSpeeds.size(); ++i) { m_moduleDirections[i]->SetAngle(state.ModuleStates[i].angle.Degrees()); m_moduleSpeeds[i]->SetAngle(state.ModuleStates[i].angle.Degrees()); m_moduleSpeeds[i]->SetLength(state.ModuleStates[i].speed / (2 * MaxSpeed)); - - frc::SmartDashboard::PutData("Module " + std::to_string(i), &m_moduleMechanisms[i]); } } diff --git a/cpp/SwerveWithPathPlanner/src/main/cpp/subsystems/CommandSwerveDrivetrain.cpp b/cpp/SwerveWithPathPlanner/src/main/cpp/subsystems/CommandSwerveDrivetrain.cpp index 4c309794..66c7823f 100644 --- a/cpp/SwerveWithPathPlanner/src/main/cpp/subsystems/CommandSwerveDrivetrain.cpp +++ b/cpp/SwerveWithPathPlanner/src/main/cpp/subsystems/CommandSwerveDrivetrain.cpp @@ -64,6 +64,8 @@ void CommandSwerveDrivetrain::Periodic() void CommandSwerveDrivetrain::StartSimThread() { m_lastSimTime = utils::GetCurrentTime(); + + /* Run simulation at a faster rate so PID gains behave more reasonably */ m_simNotifier = std::make_unique([this] { units::second_t const currentTime = utils::GetCurrentTime(); auto const deltaTime = currentTime - m_lastSimTime; diff --git a/cpp/SwerveWithPathPlanner/src/main/include/Robot.h b/cpp/SwerveWithPathPlanner/src/main/include/Robot.h index 576bcff8..6136f580 100644 --- a/cpp/SwerveWithPathPlanner/src/main/include/Robot.h +++ b/cpp/SwerveWithPathPlanner/src/main/include/Robot.h @@ -4,34 +4,38 @@ #pragma once -#include +#include "ctre/phoenix6/HootAutoReplay.hpp" #include #include +#include #include "RobotContainer.h" class Robot : public frc::TimedRobot { - public: - Robot(); - void RobotPeriodic() override; - void DisabledInit() override; - void DisabledPeriodic() override; - void DisabledExit() override; - void AutonomousInit() override; - void AutonomousPeriodic() override; - void AutonomousExit() override; - void TeleopInit() override; - void TeleopPeriodic() override; - void TeleopExit() override; - void TestInit() override; - void TestPeriodic() override; - void TestExit() override; - - private: - frc2::Command *m_autonomousCommand; - - RobotContainer m_container; - - static constexpr bool kUseLimelight = false; +public: + Robot(); + void RobotPeriodic() override; + void DisabledInit() override; + void DisabledPeriodic() override; + void DisabledExit() override; + void AutonomousInit() override; + void AutonomousPeriodic() override; + void AutonomousExit() override; + void TeleopInit() override; + void TeleopPeriodic() override; + void TeleopExit() override; + void TestInit() override; + void TestPeriodic() override; + void TestExit() override; + +private: + frc2::Command *m_autonomousCommand; + + RobotContainer m_container; + + /* log and replay timestamp and joystick data */ + ctre::phoenix6::HootAutoReplay m_timeAndJoystickReplay = ctre::phoenix6::HootAutoReplay{} + .WithTimestampReplay() + .WithJoystickReplay(); }; diff --git a/cpp/SwerveWithPathPlanner/src/main/include/RobotContainer.h b/cpp/SwerveWithPathPlanner/src/main/include/RobotContainer.h index b7b0f93c..46a21d93 100644 --- a/cpp/SwerveWithPathPlanner/src/main/include/RobotContainer.h +++ b/cpp/SwerveWithPathPlanner/src/main/include/RobotContainer.h @@ -12,7 +12,7 @@ class RobotContainer { private: - units::meters_per_second_t MaxSpeed = TunerConstants::kSpeedAt12Volts; // kSpeedAt12Volts desired top speed + units::meters_per_second_t MaxSpeed = 1.0 * TunerConstants::kSpeedAt12Volts; // kSpeedAt12Volts desired top speed units::radians_per_second_t MaxAngularRate = 0.75_tps; // 3/4 of a rotation per second max angular velocity /* Setting up bindings for necessary control of the swerve drive platform */ diff --git a/cpp/SwerveWithPathPlanner/src/main/include/Telemetry.h b/cpp/SwerveWithPathPlanner/src/main/include/Telemetry.h index 9d3a88e9..f01173c0 100644 --- a/cpp/SwerveWithPathPlanner/src/main/include/Telemetry.h +++ b/cpp/SwerveWithPathPlanner/src/main/include/Telemetry.h @@ -66,10 +66,7 @@ class Telemetry { * * \param maxSpeed Maximum speed */ - Telemetry(units::meters_per_second_t maxSpeed) : MaxSpeed{maxSpeed} - { - ctre::phoenix6::SignalLogger::Start(); - } + Telemetry(units::meters_per_second_t maxSpeed); /** Accept the swerve drive state and telemeterize it to SmartDashboard and SignalLogger. */ void Telemeterize(subsystems::CommandSwerveDrivetrain::SwerveDriveState const &state); diff --git a/cpp/SwerveWithPathPlanner/src/main/include/generated/TunerConstants.h b/cpp/SwerveWithPathPlanner/src/main/include/generated/TunerConstants.h index d20964b1..f64ec6ad 100644 --- a/cpp/SwerveWithPathPlanner/src/main/include/generated/TunerConstants.h +++ b/cpp/SwerveWithPathPlanner/src/main/include/generated/TunerConstants.h @@ -1,6 +1,8 @@ #pragma once #include "ctre/phoenix6/swerve/SwerveDrivetrain.hpp" +#include "ctre/phoenix6/CANcoder.hpp" +#include "ctre/phoenix6/TalonFX.hpp" using namespace ctre::phoenix6; @@ -9,7 +11,7 @@ namespace subsystems { class CommandSwerveDrivetrain; } -// Generated by the Tuner X Swerve Project Generator +// Generated by the 2026 Tuner X Swerve Project Generator // https://v6.docs.ctr-electronics.com/en/stable/docs/tuner/tuner-swerve/index.html class TunerConstants { // Both sets of gains need to be tuned to your individual robot. @@ -57,7 +59,6 @@ class TunerConstants { .WithStatorCurrentLimit(60_A) .WithStatorCurrentLimitEnable(true) ); - static constexpr configs::CANcoderConfiguration encoderInitialConfigs{}; // Configs for the Pigeon 2; leave this nullopt to skip applying Pigeon 2 configs static constexpr std::optional pigeonConfigs = std::nullopt; diff --git a/cpp/SwerveWithPathPlanner/src/main/include/subsystems/CommandSwerveDrivetrain.h b/cpp/SwerveWithPathPlanner/src/main/include/subsystems/CommandSwerveDrivetrain.h index 98533a16..21c1263e 100644 --- a/cpp/SwerveWithPathPlanner/src/main/include/subsystems/CommandSwerveDrivetrain.h +++ b/cpp/SwerveWithPathPlanner/src/main/include/subsystems/CommandSwerveDrivetrain.h @@ -17,9 +17,12 @@ namespace subsystems { /** * \brief Class that extends the Phoenix 6 SwerveDrivetrain class and implements * Subsystem so it can easily be used in command-based projects. + * + * Generated by the 2026 Tuner X Swerve Project Generator + * https://v6.docs.ctr-electronics.com/en/stable/docs/tuner/tuner-swerve/index.html */ class CommandSwerveDrivetrain : public frc2::SubsystemBase, public TunerSwerveDrivetrain { - static constexpr units::second_t kSimLoopPeriod = 5_ms; + static constexpr units::second_t kSimLoopPeriod = 4_ms; std::unique_ptr m_simNotifier; units::second_t m_lastSimTime; @@ -286,6 +289,17 @@ class CommandSwerveDrivetrain : public frc2::SubsystemBase, public TunerSwerveDr TunerSwerveDrivetrain::AddVisionMeasurement(std::move(visionRobotPose), utils::FPGAToCurrentTime(timestamp), visionMeasurementStdDevs); } + /** + * \brief Return the pose at a given timestamp, if the buffer is not empty. + * + * \param timestamp The timestamp of the pose in seconds. + * \returns The pose at the given timestamp (or std::nullopt if the buffer is empty). + */ + std::optional SamplePoseAt(units::second_t timestamp) const override + { + return _drivetrain.SamplePoseAt(utils::FPGAToCurrentTime(timestamp)); + } + private: void ConfigureAutoBuilder(); void StartSimThread(); diff --git a/cpp/VelocityClosedLoop/WPILib-License.md b/cpp/VelocityClosedLoop/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/cpp/VelocityClosedLoop/WPILib-License.md +++ b/cpp/VelocityClosedLoop/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/cpp/VelocityClosedLoop/settings.gradle b/cpp/VelocityClosedLoop/settings.gradle index c493958a..25f6f6e8 100644 --- a/cpp/VelocityClosedLoop/settings.gradle +++ b/cpp/VelocityClosedLoop/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') diff --git a/cpp/WaitForAll/WPILib-License.md b/cpp/WaitForAll/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/cpp/WaitForAll/WPILib-License.md +++ b/cpp/WaitForAll/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/cpp/WaitForAll/settings.gradle b/cpp/WaitForAll/settings.gradle index c493958a..25f6f6e8 100644 --- a/cpp/WaitForAll/settings.gradle +++ b/cpp/WaitForAll/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') diff --git a/java/ArcadeDrive/.vscode/settings.json b/java/ArcadeDrive/.vscode/settings.json index 612cdd0d..5e6ede86 100644 --- a/java/ArcadeDrive/.vscode/settings.json +++ b/java/ArcadeDrive/.vscode/settings.json @@ -56,5 +56,6 @@ "edu.wpi.first.math.proto.*", "edu.wpi.first.math.**.proto.*", "edu.wpi.first.math.**.struct.*", - ] + ], + "java.dependency.enableDependencyCheckup": false } diff --git a/java/ArcadeDrive/WPILib-License.md b/java/ArcadeDrive/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/java/ArcadeDrive/WPILib-License.md +++ b/java/ArcadeDrive/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/java/ArcadeDrive/build.gradle b/java/ArcadeDrive/build.gradle index f3438298..e9b0020a 100644 --- a/java/ArcadeDrive/build.gradle +++ b/java/ArcadeDrive/build.gradle @@ -43,7 +43,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. @@ -88,7 +89,9 @@ wpi.sim.addDriverstation() // knows where to look for our Robot Class. jar { from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } - from sourceSets.main.allSource + from('src') { into 'backup/src' } + from('vendordeps') { into 'backup/vendordeps' } + from('build.gradle') { into 'backup' } manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) duplicatesStrategy = DuplicatesStrategy.INCLUDE } diff --git a/java/ArcadeDrive/settings.gradle b/java/ArcadeDrive/settings.gradle index c493958a..25f6f6e8 100644 --- a/java/ArcadeDrive/settings.gradle +++ b/java/ArcadeDrive/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') diff --git a/java/BasicLatencyCompensation/.vscode/settings.json b/java/BasicLatencyCompensation/.vscode/settings.json index 612cdd0d..5e6ede86 100644 --- a/java/BasicLatencyCompensation/.vscode/settings.json +++ b/java/BasicLatencyCompensation/.vscode/settings.json @@ -56,5 +56,6 @@ "edu.wpi.first.math.proto.*", "edu.wpi.first.math.**.proto.*", "edu.wpi.first.math.**.struct.*", - ] + ], + "java.dependency.enableDependencyCheckup": false } diff --git a/java/BasicLatencyCompensation/WPILib-License.md b/java/BasicLatencyCompensation/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/java/BasicLatencyCompensation/WPILib-License.md +++ b/java/BasicLatencyCompensation/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/java/BasicLatencyCompensation/build.gradle b/java/BasicLatencyCompensation/build.gradle index f3438298..e9b0020a 100644 --- a/java/BasicLatencyCompensation/build.gradle +++ b/java/BasicLatencyCompensation/build.gradle @@ -43,7 +43,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. @@ -88,7 +89,9 @@ wpi.sim.addDriverstation() // knows where to look for our Robot Class. jar { from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } - from sourceSets.main.allSource + from('src') { into 'backup/src' } + from('vendordeps') { into 'backup/vendordeps' } + from('build.gradle') { into 'backup' } manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) duplicatesStrategy = DuplicatesStrategy.INCLUDE } diff --git a/java/BasicLatencyCompensation/settings.gradle b/java/BasicLatencyCompensation/settings.gradle index c493958a..25f6f6e8 100644 --- a/java/BasicLatencyCompensation/settings.gradle +++ b/java/BasicLatencyCompensation/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') diff --git a/java/CANcoder/.vscode/settings.json b/java/CANcoder/.vscode/settings.json index 612cdd0d..5e6ede86 100644 --- a/java/CANcoder/.vscode/settings.json +++ b/java/CANcoder/.vscode/settings.json @@ -56,5 +56,6 @@ "edu.wpi.first.math.proto.*", "edu.wpi.first.math.**.proto.*", "edu.wpi.first.math.**.struct.*", - ] + ], + "java.dependency.enableDependencyCheckup": false } diff --git a/java/CANcoder/WPILib-License.md b/java/CANcoder/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/java/CANcoder/WPILib-License.md +++ b/java/CANcoder/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/java/CANcoder/build.gradle b/java/CANcoder/build.gradle index f3438298..e9b0020a 100644 --- a/java/CANcoder/build.gradle +++ b/java/CANcoder/build.gradle @@ -43,7 +43,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. @@ -88,7 +89,9 @@ wpi.sim.addDriverstation() // knows where to look for our Robot Class. jar { from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } - from sourceSets.main.allSource + from('src') { into 'backup/src' } + from('vendordeps') { into 'backup/vendordeps' } + from('build.gradle') { into 'backup' } manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) duplicatesStrategy = DuplicatesStrategy.INCLUDE } diff --git a/java/CANcoder/settings.gradle b/java/CANcoder/settings.gradle index c493958a..25f6f6e8 100644 --- a/java/CANcoder/settings.gradle +++ b/java/CANcoder/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') diff --git a/java/CANdi/.vscode/settings.json b/java/CANdi/.vscode/settings.json index 612cdd0d..5e6ede86 100644 --- a/java/CANdi/.vscode/settings.json +++ b/java/CANdi/.vscode/settings.json @@ -56,5 +56,6 @@ "edu.wpi.first.math.proto.*", "edu.wpi.first.math.**.proto.*", "edu.wpi.first.math.**.struct.*", - ] + ], + "java.dependency.enableDependencyCheckup": false } diff --git a/java/CANdi/WPILib-License.md b/java/CANdi/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/java/CANdi/WPILib-License.md +++ b/java/CANdi/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/java/CANdi/build.gradle b/java/CANdi/build.gradle index f3438298..e9b0020a 100644 --- a/java/CANdi/build.gradle +++ b/java/CANdi/build.gradle @@ -43,7 +43,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. @@ -88,7 +89,9 @@ wpi.sim.addDriverstation() // knows where to look for our Robot Class. jar { from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } - from sourceSets.main.allSource + from('src') { into 'backup/src' } + from('vendordeps') { into 'backup/vendordeps' } + from('build.gradle') { into 'backup' } manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) duplicatesStrategy = DuplicatesStrategy.INCLUDE } diff --git a/java/CANdi/settings.gradle b/java/CANdi/settings.gradle index c493958a..25f6f6e8 100644 --- a/java/CANdi/settings.gradle +++ b/java/CANdi/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') diff --git a/java/CANdle/.vscode/settings.json b/java/CANdle/.vscode/settings.json index 612cdd0d..5e6ede86 100644 --- a/java/CANdle/.vscode/settings.json +++ b/java/CANdle/.vscode/settings.json @@ -56,5 +56,6 @@ "edu.wpi.first.math.proto.*", "edu.wpi.first.math.**.proto.*", "edu.wpi.first.math.**.struct.*", - ] + ], + "java.dependency.enableDependencyCheckup": false } diff --git a/java/CANdle/WPILib-License.md b/java/CANdle/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/java/CANdle/WPILib-License.md +++ b/java/CANdle/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/java/CANdle/build.gradle b/java/CANdle/build.gradle index f3438298..e9b0020a 100644 --- a/java/CANdle/build.gradle +++ b/java/CANdle/build.gradle @@ -43,7 +43,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. @@ -88,7 +89,9 @@ wpi.sim.addDriverstation() // knows where to look for our Robot Class. jar { from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } - from sourceSets.main.allSource + from('src') { into 'backup/src' } + from('vendordeps') { into 'backup/vendordeps' } + from('build.gradle') { into 'backup' } manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) duplicatesStrategy = DuplicatesStrategy.INCLUDE } diff --git a/java/CANdle/settings.gradle b/java/CANdle/settings.gradle index c493958a..25f6f6e8 100644 --- a/java/CANdle/settings.gradle +++ b/java/CANdle/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') diff --git a/java/CANrange/.gitignore b/java/CANrange/.gitignore index 9a9ca7be..34cbaac1 100644 --- a/java/CANrange/.gitignore +++ b/java/CANrange/.gitignore @@ -1,187 +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 +# 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/java/CANrange/.vscode/launch.json b/java/CANrange/.vscode/launch.json index 5b804e84..c9c9713d 100644 --- a/java/CANrange/.vscode/launch.json +++ b/java/CANrange/.vscode/launch.json @@ -1,21 +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, - } - ] -} +{ + // 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/java/CANrange/.vscode/settings.json b/java/CANrange/.vscode/settings.json index dccbc7c3..5e6ede86 100644 --- a/java/CANrange/.vscode/settings.json +++ b/java/CANrange/.vscode/settings.json @@ -1,60 +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.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/java/CANrange/WPILib-License.md b/java/CANrange/WPILib-License.md index e7cd597b..eb3061b0 100644 --- a/java/CANrange/WPILib-License.md +++ b/java/CANrange/WPILib-License.md @@ -1,24 +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. +Copyright (c) 2009-2026 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/java/CANrange/build.gradle b/java/CANrange/build.gradle index 68941625..e9b0020a 100644 --- a/java/CANrange/build.gradle +++ b/java/CANrange/build.gradle @@ -1,104 +1,107 @@ -plugins { - id "java" - id "edu.wpi.first.GradleRIO" version "2026.1.1" -} - -java { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 -} - -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 JNI. -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() - - 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' -} +plugins { + id "java" + id "edu.wpi.first.GradleRIO" version "2026.1.1" +} + +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} + +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() + + 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('src') { into 'backup/src' } + from('vendordeps') { into 'backup/vendordeps' } + from('build.gradle') { into 'backup' } + 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/java/CANrange/gradle/wrapper/gradle-wrapper.properties b/java/CANrange/gradle/wrapper/gradle-wrapper.properties index 8e975a5f..34bd9ce9 100644 --- a/java/CANrange/gradle/wrapper/gradle-wrapper.properties +++ b/java/CANrange/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +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 +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/java/CANrange/gradlew.bat b/java/CANrange/gradlew.bat index 9b42019c..9d21a218 100644 --- a/java/CANrange/gradlew.bat +++ b/java/CANrange/gradlew.bat @@ -1,94 +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 +@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/java/CANrange/settings.gradle b/java/CANrange/settings.gradle index 3bc070a1..25f6f6e8 100644 --- a/java/CANrange/settings.gradle +++ b/java/CANrange/settings.gradle @@ -1,30 +1,30 @@ -import org.gradle.internal.os.OperatingSystem - -pluginManagement { - repositories { - mavenLocal() - gradlePluginPortal() - String frcYear = '2025' - 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"); +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/java/CommandBasedDrive/.vscode/settings.json b/java/CommandBasedDrive/.vscode/settings.json index 612cdd0d..5e6ede86 100644 --- a/java/CommandBasedDrive/.vscode/settings.json +++ b/java/CommandBasedDrive/.vscode/settings.json @@ -56,5 +56,6 @@ "edu.wpi.first.math.proto.*", "edu.wpi.first.math.**.proto.*", "edu.wpi.first.math.**.struct.*", - ] + ], + "java.dependency.enableDependencyCheckup": false } diff --git a/java/CommandBasedDrive/WPILib-License.md b/java/CommandBasedDrive/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/java/CommandBasedDrive/WPILib-License.md +++ b/java/CommandBasedDrive/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/java/CommandBasedDrive/build.gradle b/java/CommandBasedDrive/build.gradle index f3438298..e9b0020a 100644 --- a/java/CommandBasedDrive/build.gradle +++ b/java/CommandBasedDrive/build.gradle @@ -43,7 +43,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. @@ -88,7 +89,9 @@ wpi.sim.addDriverstation() // knows where to look for our Robot Class. jar { from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } - from sourceSets.main.allSource + from('src') { into 'backup/src' } + from('vendordeps') { into 'backup/vendordeps' } + from('build.gradle') { into 'backup' } manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) duplicatesStrategy = DuplicatesStrategy.INCLUDE } diff --git a/java/CommandBasedDrive/settings.gradle b/java/CommandBasedDrive/settings.gradle index c493958a..25f6f6e8 100644 --- a/java/CommandBasedDrive/settings.gradle +++ b/java/CommandBasedDrive/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') diff --git a/java/ControlRequestLimits/.vscode/settings.json b/java/ControlRequestLimits/.vscode/settings.json index 612cdd0d..5e6ede86 100644 --- a/java/ControlRequestLimits/.vscode/settings.json +++ b/java/ControlRequestLimits/.vscode/settings.json @@ -56,5 +56,6 @@ "edu.wpi.first.math.proto.*", "edu.wpi.first.math.**.proto.*", "edu.wpi.first.math.**.struct.*", - ] + ], + "java.dependency.enableDependencyCheckup": false } diff --git a/java/ControlRequestLimits/WPILib-License.md b/java/ControlRequestLimits/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/java/ControlRequestLimits/WPILib-License.md +++ b/java/ControlRequestLimits/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/java/ControlRequestLimits/build.gradle b/java/ControlRequestLimits/build.gradle index f3438298..e9b0020a 100644 --- a/java/ControlRequestLimits/build.gradle +++ b/java/ControlRequestLimits/build.gradle @@ -43,7 +43,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. @@ -88,7 +89,9 @@ wpi.sim.addDriverstation() // knows where to look for our Robot Class. jar { from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } - from sourceSets.main.allSource + from('src') { into 'backup/src' } + from('vendordeps') { into 'backup/vendordeps' } + from('build.gradle') { into 'backup' } manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) duplicatesStrategy = DuplicatesStrategy.INCLUDE } diff --git a/java/ControlRequestLimits/settings.gradle b/java/ControlRequestLimits/settings.gradle index c493958a..25f6f6e8 100644 --- a/java/ControlRequestLimits/settings.gradle +++ b/java/ControlRequestLimits/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') diff --git a/java/CurrentLimits/.vscode/settings.json b/java/CurrentLimits/.vscode/settings.json index 612cdd0d..5e6ede86 100644 --- a/java/CurrentLimits/.vscode/settings.json +++ b/java/CurrentLimits/.vscode/settings.json @@ -56,5 +56,6 @@ "edu.wpi.first.math.proto.*", "edu.wpi.first.math.**.proto.*", "edu.wpi.first.math.**.struct.*", - ] + ], + "java.dependency.enableDependencyCheckup": false } diff --git a/java/CurrentLimits/WPILib-License.md b/java/CurrentLimits/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/java/CurrentLimits/WPILib-License.md +++ b/java/CurrentLimits/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/java/CurrentLimits/build.gradle b/java/CurrentLimits/build.gradle index f3438298..e9b0020a 100644 --- a/java/CurrentLimits/build.gradle +++ b/java/CurrentLimits/build.gradle @@ -43,7 +43,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. @@ -88,7 +89,9 @@ wpi.sim.addDriverstation() // knows where to look for our Robot Class. jar { from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } - from sourceSets.main.allSource + from('src') { into 'backup/src' } + from('vendordeps') { into 'backup/vendordeps' } + from('build.gradle') { into 'backup' } manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) duplicatesStrategy = DuplicatesStrategy.INCLUDE } diff --git a/java/CurrentLimits/settings.gradle b/java/CurrentLimits/settings.gradle index c493958a..25f6f6e8 100644 --- a/java/CurrentLimits/settings.gradle +++ b/java/CurrentLimits/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') diff --git a/java/FusedCANcoder/.vscode/settings.json b/java/FusedCANcoder/.vscode/settings.json index 612cdd0d..5e6ede86 100644 --- a/java/FusedCANcoder/.vscode/settings.json +++ b/java/FusedCANcoder/.vscode/settings.json @@ -56,5 +56,6 @@ "edu.wpi.first.math.proto.*", "edu.wpi.first.math.**.proto.*", "edu.wpi.first.math.**.struct.*", - ] + ], + "java.dependency.enableDependencyCheckup": false } diff --git a/java/FusedCANcoder/WPILib-License.md b/java/FusedCANcoder/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/java/FusedCANcoder/WPILib-License.md +++ b/java/FusedCANcoder/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/java/FusedCANcoder/build.gradle b/java/FusedCANcoder/build.gradle index f3438298..e9b0020a 100644 --- a/java/FusedCANcoder/build.gradle +++ b/java/FusedCANcoder/build.gradle @@ -43,7 +43,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. @@ -88,7 +89,9 @@ wpi.sim.addDriverstation() // knows where to look for our Robot Class. jar { from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } - from sourceSets.main.allSource + from('src') { into 'backup/src' } + from('vendordeps') { into 'backup/vendordeps' } + from('build.gradle') { into 'backup' } manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) duplicatesStrategy = DuplicatesStrategy.INCLUDE } diff --git a/java/FusedCANcoder/settings.gradle b/java/FusedCANcoder/settings.gradle index c493958a..25f6f6e8 100644 --- a/java/FusedCANcoder/settings.gradle +++ b/java/FusedCANcoder/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') diff --git a/java/MotionMagic/.vscode/settings.json b/java/MotionMagic/.vscode/settings.json index 612cdd0d..5e6ede86 100644 --- a/java/MotionMagic/.vscode/settings.json +++ b/java/MotionMagic/.vscode/settings.json @@ -56,5 +56,6 @@ "edu.wpi.first.math.proto.*", "edu.wpi.first.math.**.proto.*", "edu.wpi.first.math.**.struct.*", - ] + ], + "java.dependency.enableDependencyCheckup": false } diff --git a/java/MotionMagic/WPILib-License.md b/java/MotionMagic/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/java/MotionMagic/WPILib-License.md +++ b/java/MotionMagic/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/java/MotionMagic/build.gradle b/java/MotionMagic/build.gradle index f3438298..e9b0020a 100644 --- a/java/MotionMagic/build.gradle +++ b/java/MotionMagic/build.gradle @@ -43,7 +43,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. @@ -88,7 +89,9 @@ wpi.sim.addDriverstation() // knows where to look for our Robot Class. jar { from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } - from sourceSets.main.allSource + from('src') { into 'backup/src' } + from('vendordeps') { into 'backup/vendordeps' } + from('build.gradle') { into 'backup' } manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) duplicatesStrategy = DuplicatesStrategy.INCLUDE } diff --git a/java/MotionMagic/settings.gradle b/java/MotionMagic/settings.gradle index c493958a..25f6f6e8 100644 --- a/java/MotionMagic/settings.gradle +++ b/java/MotionMagic/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') diff --git a/java/MotionMagicExpo/.vscode/settings.json b/java/MotionMagicExpo/.vscode/settings.json index 612cdd0d..5e6ede86 100644 --- a/java/MotionMagicExpo/.vscode/settings.json +++ b/java/MotionMagicExpo/.vscode/settings.json @@ -56,5 +56,6 @@ "edu.wpi.first.math.proto.*", "edu.wpi.first.math.**.proto.*", "edu.wpi.first.math.**.struct.*", - ] + ], + "java.dependency.enableDependencyCheckup": false } diff --git a/java/MotionMagicExpo/WPILib-License.md b/java/MotionMagicExpo/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/java/MotionMagicExpo/WPILib-License.md +++ b/java/MotionMagicExpo/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/java/MotionMagicExpo/build.gradle b/java/MotionMagicExpo/build.gradle index f3438298..e9b0020a 100644 --- a/java/MotionMagicExpo/build.gradle +++ b/java/MotionMagicExpo/build.gradle @@ -43,7 +43,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. @@ -88,7 +89,9 @@ wpi.sim.addDriverstation() // knows where to look for our Robot Class. jar { from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } - from sourceSets.main.allSource + from('src') { into 'backup/src' } + from('vendordeps') { into 'backup/vendordeps' } + from('build.gradle') { into 'backup' } manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) duplicatesStrategy = DuplicatesStrategy.INCLUDE } diff --git a/java/MotionMagicExpo/settings.gradle b/java/MotionMagicExpo/settings.gradle index c493958a..25f6f6e8 100644 --- a/java/MotionMagicExpo/settings.gradle +++ b/java/MotionMagicExpo/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') diff --git a/java/PWMTalonFXS/.vscode/settings.json b/java/PWMTalonFXS/.vscode/settings.json index 612cdd0d..5e6ede86 100644 --- a/java/PWMTalonFXS/.vscode/settings.json +++ b/java/PWMTalonFXS/.vscode/settings.json @@ -56,5 +56,6 @@ "edu.wpi.first.math.proto.*", "edu.wpi.first.math.**.proto.*", "edu.wpi.first.math.**.struct.*", - ] + ], + "java.dependency.enableDependencyCheckup": false } diff --git a/java/PWMTalonFXS/WPILib-License.md b/java/PWMTalonFXS/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/java/PWMTalonFXS/WPILib-License.md +++ b/java/PWMTalonFXS/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/java/PWMTalonFXS/build.gradle b/java/PWMTalonFXS/build.gradle index f3438298..e9b0020a 100644 --- a/java/PWMTalonFXS/build.gradle +++ b/java/PWMTalonFXS/build.gradle @@ -43,7 +43,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. @@ -88,7 +89,9 @@ wpi.sim.addDriverstation() // knows where to look for our Robot Class. jar { from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } - from sourceSets.main.allSource + from('src') { into 'backup/src' } + from('vendordeps') { into 'backup/vendordeps' } + from('build.gradle') { into 'backup' } manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) duplicatesStrategy = DuplicatesStrategy.INCLUDE } diff --git a/java/PWMTalonFXS/settings.gradle b/java/PWMTalonFXS/settings.gradle index c493958a..25f6f6e8 100644 --- a/java/PWMTalonFXS/settings.gradle +++ b/java/PWMTalonFXS/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') diff --git a/java/PhoenixSysId/.vscode/settings.json b/java/PhoenixSysId/.vscode/settings.json index 612cdd0d..5e6ede86 100644 --- a/java/PhoenixSysId/.vscode/settings.json +++ b/java/PhoenixSysId/.vscode/settings.json @@ -56,5 +56,6 @@ "edu.wpi.first.math.proto.*", "edu.wpi.first.math.**.proto.*", "edu.wpi.first.math.**.struct.*", - ] + ], + "java.dependency.enableDependencyCheckup": false } diff --git a/java/PhoenixSysId/WPILib-License.md b/java/PhoenixSysId/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/java/PhoenixSysId/WPILib-License.md +++ b/java/PhoenixSysId/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/java/PhoenixSysId/build.gradle b/java/PhoenixSysId/build.gradle index f3438298..e9b0020a 100644 --- a/java/PhoenixSysId/build.gradle +++ b/java/PhoenixSysId/build.gradle @@ -43,7 +43,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. @@ -88,7 +89,9 @@ wpi.sim.addDriverstation() // knows where to look for our Robot Class. jar { from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } - from sourceSets.main.allSource + from('src') { into 'backup/src' } + from('vendordeps') { into 'backup/vendordeps' } + from('build.gradle') { into 'backup' } manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) duplicatesStrategy = DuplicatesStrategy.INCLUDE } diff --git a/java/PhoenixSysId/settings.gradle b/java/PhoenixSysId/settings.gradle index c493958a..25f6f6e8 100644 --- a/java/PhoenixSysId/settings.gradle +++ b/java/PhoenixSysId/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') diff --git a/java/Pigeon2/.vscode/settings.json b/java/Pigeon2/.vscode/settings.json index 612cdd0d..5e6ede86 100644 --- a/java/Pigeon2/.vscode/settings.json +++ b/java/Pigeon2/.vscode/settings.json @@ -56,5 +56,6 @@ "edu.wpi.first.math.proto.*", "edu.wpi.first.math.**.proto.*", "edu.wpi.first.math.**.struct.*", - ] + ], + "java.dependency.enableDependencyCheckup": false } diff --git a/java/Pigeon2/WPILib-License.md b/java/Pigeon2/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/java/Pigeon2/WPILib-License.md +++ b/java/Pigeon2/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/java/Pigeon2/build.gradle b/java/Pigeon2/build.gradle index f3438298..e9b0020a 100644 --- a/java/Pigeon2/build.gradle +++ b/java/Pigeon2/build.gradle @@ -43,7 +43,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. @@ -88,7 +89,9 @@ wpi.sim.addDriverstation() // knows where to look for our Robot Class. jar { from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } - from sourceSets.main.allSource + from('src') { into 'backup/src' } + from('vendordeps') { into 'backup/vendordeps' } + from('build.gradle') { into 'backup' } manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) duplicatesStrategy = DuplicatesStrategy.INCLUDE } diff --git a/java/Pigeon2/settings.gradle b/java/Pigeon2/settings.gradle index c493958a..25f6f6e8 100644 --- a/java/Pigeon2/settings.gradle +++ b/java/Pigeon2/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') diff --git a/java/PositionClosedLoop/.vscode/settings.json b/java/PositionClosedLoop/.vscode/settings.json index 612cdd0d..5e6ede86 100644 --- a/java/PositionClosedLoop/.vscode/settings.json +++ b/java/PositionClosedLoop/.vscode/settings.json @@ -56,5 +56,6 @@ "edu.wpi.first.math.proto.*", "edu.wpi.first.math.**.proto.*", "edu.wpi.first.math.**.struct.*", - ] + ], + "java.dependency.enableDependencyCheckup": false } diff --git a/java/PositionClosedLoop/WPILib-License.md b/java/PositionClosedLoop/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/java/PositionClosedLoop/WPILib-License.md +++ b/java/PositionClosedLoop/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/java/PositionClosedLoop/build.gradle b/java/PositionClosedLoop/build.gradle index f3438298..e9b0020a 100644 --- a/java/PositionClosedLoop/build.gradle +++ b/java/PositionClosedLoop/build.gradle @@ -43,7 +43,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. @@ -88,7 +89,9 @@ wpi.sim.addDriverstation() // knows where to look for our Robot Class. jar { from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } - from sourceSets.main.allSource + from('src') { into 'backup/src' } + from('vendordeps') { into 'backup/vendordeps' } + from('build.gradle') { into 'backup' } manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) duplicatesStrategy = DuplicatesStrategy.INCLUDE } diff --git a/java/PositionClosedLoop/settings.gradle b/java/PositionClosedLoop/settings.gradle index c493958a..25f6f6e8 100644 --- a/java/PositionClosedLoop/settings.gradle +++ b/java/PositionClosedLoop/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') diff --git a/java/Simulation/.vscode/settings.json b/java/Simulation/.vscode/settings.json index 612cdd0d..5e6ede86 100644 --- a/java/Simulation/.vscode/settings.json +++ b/java/Simulation/.vscode/settings.json @@ -56,5 +56,6 @@ "edu.wpi.first.math.proto.*", "edu.wpi.first.math.**.proto.*", "edu.wpi.first.math.**.struct.*", - ] + ], + "java.dependency.enableDependencyCheckup": false } diff --git a/java/Simulation/WPILib-License.md b/java/Simulation/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/java/Simulation/WPILib-License.md +++ b/java/Simulation/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/java/Simulation/build.gradle b/java/Simulation/build.gradle index f3438298..e9b0020a 100644 --- a/java/Simulation/build.gradle +++ b/java/Simulation/build.gradle @@ -43,7 +43,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. @@ -88,7 +89,9 @@ wpi.sim.addDriverstation() // knows where to look for our Robot Class. jar { from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } - from sourceSets.main.allSource + from('src') { into 'backup/src' } + from('vendordeps') { into 'backup/vendordeps' } + from('build.gradle') { into 'backup' } manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) duplicatesStrategy = DuplicatesStrategy.INCLUDE } diff --git a/java/Simulation/settings.gradle b/java/Simulation/settings.gradle index c493958a..25f6f6e8 100644 --- a/java/Simulation/settings.gradle +++ b/java/Simulation/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') diff --git a/java/SwerveWithChoreo/.vscode/settings.json b/java/SwerveWithChoreo/.vscode/settings.json index 612cdd0d..5e6ede86 100644 --- a/java/SwerveWithChoreo/.vscode/settings.json +++ b/java/SwerveWithChoreo/.vscode/settings.json @@ -56,5 +56,6 @@ "edu.wpi.first.math.proto.*", "edu.wpi.first.math.**.proto.*", "edu.wpi.first.math.**.struct.*", - ] + ], + "java.dependency.enableDependencyCheckup": false } diff --git a/java/SwerveWithChoreo/WPILib-License.md b/java/SwerveWithChoreo/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/java/SwerveWithChoreo/WPILib-License.md +++ b/java/SwerveWithChoreo/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/java/SwerveWithChoreo/build.gradle b/java/SwerveWithChoreo/build.gradle index f3438298..89820809 100644 --- a/java/SwerveWithChoreo/build.gradle +++ b/java/SwerveWithChoreo/build.gradle @@ -33,7 +33,7 @@ deploy { frcStaticFileDeploy(getArtifactTypeClass('FileTreeArtifact')) { files = project.fileTree('src/main/deploy') directory = '/home/lvuser/deploy' - deleteOldFiles = false // Change to true to delete files on roboRIO that no + deleteOldFiles = true // Change to true to delete files on roboRIO that no // longer exist in deploy directory of this project } } @@ -43,7 +43,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. @@ -88,7 +89,9 @@ wpi.sim.addDriverstation() // knows where to look for our Robot Class. jar { from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } - from sourceSets.main.allSource + from('src') { into 'backup/src' } + from('vendordeps') { into 'backup/vendordeps' } + from('build.gradle') { into 'backup' } manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) duplicatesStrategy = DuplicatesStrategy.INCLUDE } diff --git a/java/SwerveWithChoreo/settings.gradle b/java/SwerveWithChoreo/settings.gradle index c493958a..25f6f6e8 100644 --- a/java/SwerveWithChoreo/settings.gradle +++ b/java/SwerveWithChoreo/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') diff --git a/java/SwerveWithChoreo/src/main/java/frc/robot/Robot.java b/java/SwerveWithChoreo/src/main/java/frc/robot/Robot.java index ddf68776..a09abd69 100644 --- a/java/SwerveWithChoreo/src/main/java/frc/robot/Robot.java +++ b/java/SwerveWithChoreo/src/main/java/frc/robot/Robot.java @@ -4,95 +4,103 @@ package frc.robot; +import com.ctre.phoenix6.HootAutoReplay; + import edu.wpi.first.math.util.Units; import edu.wpi.first.wpilibj.TimedRobot; import edu.wpi.first.wpilibj2.command.Command; import edu.wpi.first.wpilibj2.command.CommandScheduler; public class Robot extends TimedRobot { - private Command m_autonomousCommand; - - private final RobotContainer m_robotContainer; - - private final boolean kUseLimelight = false; - - public Robot() { - m_robotContainer = new RobotContainer(); - } - - @Override - public void robotPeriodic() { - CommandScheduler.getInstance().run(); - - /* - * This example of adding Limelight is very simple and may not be sufficient for on-field use. - * Users typically need to provide a standard deviation that scales with the distance to target - * and changes with number of tags available. - * - * This example is sufficient to show that vision integration is possible, though exact implementation - * of how to use vision should be tuned per-robot and to the team's specification. - */ - if (kUseLimelight) { - var driveState = m_robotContainer.drivetrain.getState(); - double headingDeg = driveState.Pose.getRotation().getDegrees(); - double omegaRps = Units.radiansToRotations(driveState.Speeds.omegaRadiansPerSecond); - - LimelightHelpers.SetRobotOrientation("limelight", headingDeg, 0, 0, 0, 0, 0); - var llMeasurement = LimelightHelpers.getBotPoseEstimate_wpiBlue_MegaTag2("limelight"); - if (llMeasurement != null && llMeasurement.tagCount > 0 && Math.abs(omegaRps) < 2.0) { - m_robotContainer.drivetrain.addVisionMeasurement(llMeasurement.pose, llMeasurement.timestampSeconds); - } + private Command m_autonomousCommand; + + private final RobotContainer m_robotContainer; + + /* log and replay timestamp and joystick data */ + private final HootAutoReplay m_timeAndJoystickReplay = new HootAutoReplay() + .withTimestampReplay() + .withJoystickReplay(); + + private final boolean kUseLimelight = false; + + public Robot() { + m_robotContainer = new RobotContainer(); + } + + @Override + public void robotPeriodic() { + m_timeAndJoystickReplay.update(); + CommandScheduler.getInstance().run(); + + /* + * This example of adding Limelight is very simple and may not be sufficient for on-field use. + * Users typically need to provide a standard deviation that scales with the distance to target + * and changes with number of tags available. + * + * This example is sufficient to show that vision integration is possible, though exact implementation + * of how to use vision should be tuned per-robot and to the team's specification. + */ + if (kUseLimelight) { + var driveState = m_robotContainer.drivetrain.getState(); + double headingDeg = driveState.Pose.getRotation().getDegrees(); + double omegaRps = Units.radiansToRotations(driveState.Speeds.omegaRadiansPerSecond); + + LimelightHelpers.SetRobotOrientation("limelight", headingDeg, 0, 0, 0, 0, 0); + var llMeasurement = LimelightHelpers.getBotPoseEstimate_wpiBlue_MegaTag2("limelight"); + if (llMeasurement != null && llMeasurement.tagCount > 0 && Math.abs(omegaRps) < 2.0) { + m_robotContainer.drivetrain.addVisionMeasurement(llMeasurement.pose, llMeasurement.timestampSeconds); + } + } } - } - @Override - public void disabledInit() {} + @Override + public void disabledInit() {} - @Override - public void disabledPeriodic() {} + @Override + public void disabledPeriodic() {} - @Override - public void disabledExit() {} + @Override + public void disabledExit() {} - @Override - public void autonomousInit() { - m_autonomousCommand = m_robotContainer.getAutonomousCommand(); + @Override + public void autonomousInit() { + m_autonomousCommand = m_robotContainer.getAutonomousCommand(); - if (m_autonomousCommand != null) { - m_autonomousCommand.schedule(); + if (m_autonomousCommand != null) { + CommandScheduler.getInstance().schedule(m_autonomousCommand); + } } - } - @Override - public void autonomousPeriodic() {} + @Override + public void autonomousPeriodic() {} - @Override - public void autonomousExit() {} + @Override + public void autonomousExit() {} - @Override - public void teleopInit() { - if (m_autonomousCommand != null) { - m_autonomousCommand.cancel(); + @Override + public void teleopInit() { + if (m_autonomousCommand != null) { + CommandScheduler.getInstance().cancel(m_autonomousCommand); + } } - } - @Override - public void teleopPeriodic() {} + @Override + public void teleopPeriodic() {} - @Override - public void teleopExit() {} + @Override + public void teleopExit() {} - @Override - public void testInit() { - CommandScheduler.getInstance().cancelAll(); - } + @Override + public void testInit() { + CommandScheduler.getInstance().cancelAll(); + } - @Override - public void testPeriodic() {} + @Override + public void testPeriodic() {} - @Override - public void testExit() {} + @Override + public void testExit() {} - @Override - public void simulationPeriodic() {} + @Override + public void simulationPeriodic() {} } diff --git a/java/SwerveWithChoreo/src/main/java/frc/robot/RobotContainer.java b/java/SwerveWithChoreo/src/main/java/frc/robot/RobotContainer.java index 87870ae4..79695836 100644 --- a/java/SwerveWithChoreo/src/main/java/frc/robot/RobotContainer.java +++ b/java/SwerveWithChoreo/src/main/java/frc/robot/RobotContainer.java @@ -16,13 +16,14 @@ import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; import edu.wpi.first.wpilibj2.command.Command; import edu.wpi.first.wpilibj2.command.button.CommandXboxController; +import edu.wpi.first.wpilibj2.command.button.RobotModeTriggers; import edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine.Direction; import frc.robot.generated.TunerConstants; import frc.robot.subsystems.CommandSwerveDrivetrain; public class RobotContainer { - private double MaxSpeed = TunerConstants.kSpeedAt12Volts.in(MetersPerSecond); // kSpeedAt12Volts desired top speed + private double MaxSpeed = 1.0 * TunerConstants.kSpeedAt12Volts.in(MetersPerSecond); // kSpeedAt12Volts desired top speed private double MaxAngularRate = RotationsPerSecond.of(0.75).in(RadiansPerSecond); // 3/4 of a rotation per second max angular velocity /* Setting up bindings for necessary control of the swerve drive platform */ @@ -67,15 +68,22 @@ private void configureBindings() { ) ); + // Idle while the robot is disabled. This ensures the configured + // neutral mode is applied to the drive motors while disabled. + final var idle = new SwerveRequest.Idle(); + RobotModeTriggers.disabled().whileTrue( + drivetrain.applyRequest(() -> idle).ignoringDisable(true) + ); + joystick.a().whileTrue(drivetrain.applyRequest(() -> brake)); joystick.b().whileTrue(drivetrain.applyRequest(() -> point.withModuleDirection(new Rotation2d(-joystick.getLeftY(), -joystick.getLeftX())) )); - joystick.pov(0).whileTrue(drivetrain.applyRequest(() -> + joystick.povUp().whileTrue(drivetrain.applyRequest(() -> forwardStraight.withVelocityX(0.5).withVelocityY(0)) ); - joystick.pov(180).whileTrue(drivetrain.applyRequest(() -> + joystick.povDown().whileTrue(drivetrain.applyRequest(() -> forwardStraight.withVelocityX(-0.5).withVelocityY(0)) ); @@ -86,8 +94,8 @@ private void configureBindings() { joystick.start().and(joystick.y()).whileTrue(drivetrain.sysIdQuasistatic(Direction.kForward)); joystick.start().and(joystick.x()).whileTrue(drivetrain.sysIdQuasistatic(Direction.kReverse)); - // reset the field-centric heading on left bumper press - joystick.leftBumper().onTrue(drivetrain.runOnce(() -> drivetrain.seedFieldCentric())); + // Reset the field-centric heading on left bumper press. + joystick.leftBumper().onTrue(drivetrain.runOnce(drivetrain::seedFieldCentric)); drivetrain.registerTelemetry(logger::telemeterize); } diff --git a/java/SwerveWithChoreo/src/main/java/frc/robot/Telemetry.java b/java/SwerveWithChoreo/src/main/java/frc/robot/Telemetry.java index edf1979f..f9da9480 100644 --- a/java/SwerveWithChoreo/src/main/java/frc/robot/Telemetry.java +++ b/java/SwerveWithChoreo/src/main/java/frc/robot/Telemetry.java @@ -31,6 +31,11 @@ public class Telemetry { public Telemetry(double maxSpeed) { MaxSpeed = maxSpeed; SignalLogger.start(); + + /* Set up the module state Mechanism2d telemetry */ + for (int i = 0; i < 4; ++i) { + SmartDashboard.putData("Module " + i, m_moduleMechanisms[i]); + } } /* What to publish over networktables for telemetry */ @@ -78,8 +83,6 @@ public Telemetry(double maxSpeed) { }; private final double[] m_poseArray = new double[3]; - private final double[] m_moduleStatesArray = new double[8]; - private final double[] m_moduleTargetsArray = new double[8]; /** Accept the swerve drive state and telemeterize it to SmartDashboard and SignalLogger. */ public void telemeterize(SwerveDriveState state) { @@ -93,32 +96,26 @@ public void telemeterize(SwerveDriveState state) { driveOdometryFrequency.set(1.0 / state.OdometryPeriod); /* Also write to log file */ - m_poseArray[0] = state.Pose.getX(); - m_poseArray[1] = state.Pose.getY(); - m_poseArray[2] = state.Pose.getRotation().getDegrees(); - for (int i = 0; i < 4; ++i) { - m_moduleStatesArray[i*2 + 0] = state.ModuleStates[i].angle.getRadians(); - m_moduleStatesArray[i*2 + 1] = state.ModuleStates[i].speedMetersPerSecond; - m_moduleTargetsArray[i*2 + 0] = state.ModuleTargets[i].angle.getRadians(); - m_moduleTargetsArray[i*2 + 1] = state.ModuleTargets[i].speedMetersPerSecond; - } - - SignalLogger.writeDoubleArray("DriveState/Pose", m_poseArray); - SignalLogger.writeDoubleArray("DriveState/ModuleStates", m_moduleStatesArray); - SignalLogger.writeDoubleArray("DriveState/ModuleTargets", m_moduleTargetsArray); + SignalLogger.writeStruct("DriveState/Pose", Pose2d.struct, state.Pose); + SignalLogger.writeStruct("DriveState/Speeds", ChassisSpeeds.struct, state.Speeds); + SignalLogger.writeStructArray("DriveState/ModuleStates", SwerveModuleState.struct, state.ModuleStates); + SignalLogger.writeStructArray("DriveState/ModuleTargets", SwerveModuleState.struct, state.ModuleTargets); + SignalLogger.writeStructArray("DriveState/ModulePositions", SwerveModulePosition.struct, state.ModulePositions); SignalLogger.writeDouble("DriveState/OdometryPeriod", state.OdometryPeriod, "seconds"); /* Telemeterize the pose to a Field2d */ fieldTypePub.set("Field2d"); + + m_poseArray[0] = state.Pose.getX(); + m_poseArray[1] = state.Pose.getY(); + m_poseArray[2] = state.Pose.getRotation().getDegrees(); fieldPub.set(m_poseArray); - /* Telemeterize the module states to a Mechanism2d */ + /* Telemeterize each module state to a Mechanism2d */ for (int i = 0; i < 4; ++i) { m_moduleSpeeds[i].setAngle(state.ModuleStates[i].angle); m_moduleDirections[i].setAngle(state.ModuleStates[i].angle); m_moduleSpeeds[i].setLength(state.ModuleStates[i].speedMetersPerSecond / (2 * MaxSpeed)); - - SmartDashboard.putData("Module " + i, m_moduleMechanisms[i]); } } } diff --git a/java/SwerveWithChoreo/src/main/java/frc/robot/generated/TunerConstants.java b/java/SwerveWithChoreo/src/main/java/frc/robot/generated/TunerConstants.java index 4979012b..675bcbd7 100644 --- a/java/SwerveWithChoreo/src/main/java/frc/robot/generated/TunerConstants.java +++ b/java/SwerveWithChoreo/src/main/java/frc/robot/generated/TunerConstants.java @@ -1,286 +1,286 @@ -package frc.robot.generated; - -import static edu.wpi.first.units.Units.*; - -import com.ctre.phoenix6.CANBus; -import com.ctre.phoenix6.configs.*; -import com.ctre.phoenix6.hardware.*; -import com.ctre.phoenix6.signals.*; -import com.ctre.phoenix6.swerve.*; -import com.ctre.phoenix6.swerve.SwerveModuleConstants.*; - -import edu.wpi.first.math.Matrix; -import edu.wpi.first.math.numbers.N1; -import edu.wpi.first.math.numbers.N3; -import edu.wpi.first.units.measure.*; - -import frc.robot.subsystems.CommandSwerveDrivetrain; - -// Generated by the Tuner X Swerve Project Generator -// https://v6.docs.ctr-electronics.com/en/stable/docs/tuner/tuner-swerve/index.html -public class TunerConstants { - // Both sets of gains need to be tuned to your individual robot. - - // The steer motor uses any SwerveModule.SteerRequestType control request with the - // output type specified by SwerveModuleConstants.SteerMotorClosedLoopOutput - private static final Slot0Configs steerGains = new Slot0Configs() - .withKP(100).withKI(0).withKD(0.5) - .withKS(0.1).withKV(1.91).withKA(0) - .withStaticFeedforwardSign(StaticFeedforwardSignValue.UseClosedLoopSign); - // When using closed-loop control, the drive motor uses the control - // output type specified by SwerveModuleConstants.DriveMotorClosedLoopOutput - private static final Slot0Configs driveGains = new Slot0Configs() - .withKP(0.1).withKI(0).withKD(0) - .withKS(0).withKV(0.124); - - // The closed-loop output type to use for the steer motors; - // This affects the PID/FF gains for the steer motors - private static final ClosedLoopOutputType kSteerClosedLoopOutput = ClosedLoopOutputType.Voltage; - // The closed-loop output type to use for the drive motors; - // This affects the PID/FF gains for the drive motors - private static final ClosedLoopOutputType kDriveClosedLoopOutput = ClosedLoopOutputType.Voltage; - - // The type of motor used for the drive motor - private static final DriveMotorArrangement kDriveMotorType = DriveMotorArrangement.TalonFX_Integrated; - // The type of motor used for the drive motor - private static final SteerMotorArrangement kSteerMotorType = SteerMotorArrangement.TalonFX_Integrated; - - // The remote sensor feedback type to use for the steer motors; - // When not Pro-licensed, Fused*/Sync* automatically fall back to Remote* - private static final SteerFeedbackType kSteerFeedbackType = SteerFeedbackType.FusedCANcoder; - - // The stator current at which the wheels start to slip; - // This needs to be tuned to your individual robot - private static final Current kSlipCurrent = Amps.of(120.0); - - // Initial configs for the drive and steer motors and the azimuth encoder; these cannot be null. - // Some configs will be overwritten; check the `with*InitialConfigs()` API documentation. - private static final TalonFXConfiguration driveInitialConfigs = new TalonFXConfiguration(); - private static final TalonFXConfiguration steerInitialConfigs = new TalonFXConfiguration() - .withCurrentLimits( - new CurrentLimitsConfigs() - // Swerve azimuth does not require much torque output, so we can set a relatively low - // stator current limit to help avoid brownouts without impacting performance. - .withStatorCurrentLimit(Amps.of(60.0)) - .withStatorCurrentLimitEnable(true) - ); - private static final CANcoderConfiguration encoderInitialConfigs = new CANcoderConfiguration(); - // Configs for the Pigeon 2; leave this null to skip applying Pigeon 2 configs - private static final Pigeon2Configuration pigeonConfigs = null; - - // CAN bus that the devices are located on; - // All swerve devices must share the same CAN bus - public static final CANBus kCANBus = new CANBus("canivore", "./logs/example.hoot"); - - // Theoretical free speed (m/s) at 12 V applied output; - // This needs to be tuned to your individual robot - public static final LinearVelocity kSpeedAt12Volts = MetersPerSecond.of(4.54); - - // Every 1 rotation of the azimuth results in kCoupleRatio drive motor turns; - // This may need to be tuned to your individual robot - private static final double kCoupleRatio = 3.8181818181818183; - - private static final double kDriveGearRatio = 7.363636363636365; - private static final double kSteerGearRatio = 15.42857142857143; - private static final Distance kWheelRadius = Inches.of(2.167); - - private static final boolean kInvertLeftSide = false; - private static final boolean kInvertRightSide = true; - - private static final int kPigeonId = 1; - - // These are only used for simulation - private static final MomentOfInertia kSteerInertia = KilogramSquareMeters.of(0.01); - private static final MomentOfInertia kDriveInertia = KilogramSquareMeters.of(0.01); - // Simulated voltage necessary to overcome friction - private static final Voltage kSteerFrictionVoltage = Volts.of(0.2); - private static final Voltage kDriveFrictionVoltage = Volts.of(0.2); - - public static final SwerveDrivetrainConstants DrivetrainConstants = new SwerveDrivetrainConstants() - .withCANBusName(kCANBus.getName()) - .withPigeon2Id(kPigeonId) - .withPigeon2Configs(pigeonConfigs); - - private static final SwerveModuleConstantsFactory ConstantCreator = - new SwerveModuleConstantsFactory() - .withDriveMotorGearRatio(kDriveGearRatio) - .withSteerMotorGearRatio(kSteerGearRatio) - .withCouplingGearRatio(kCoupleRatio) - .withWheelRadius(kWheelRadius) - .withSteerMotorGains(steerGains) - .withDriveMotorGains(driveGains) - .withSteerMotorClosedLoopOutput(kSteerClosedLoopOutput) - .withDriveMotorClosedLoopOutput(kDriveClosedLoopOutput) - .withSlipCurrent(kSlipCurrent) - .withSpeedAt12Volts(kSpeedAt12Volts) - .withDriveMotorType(kDriveMotorType) - .withSteerMotorType(kSteerMotorType) - .withFeedbackSource(kSteerFeedbackType) - .withDriveMotorInitialConfigs(driveInitialConfigs) - .withSteerMotorInitialConfigs(steerInitialConfigs) - .withEncoderInitialConfigs(encoderInitialConfigs) - .withSteerInertia(kSteerInertia) - .withDriveInertia(kDriveInertia) - .withSteerFrictionVoltage(kSteerFrictionVoltage) - .withDriveFrictionVoltage(kDriveFrictionVoltage); - - - // Front Left - private static final int kFrontLeftDriveMotorId = 3; - private static final int kFrontLeftSteerMotorId = 2; - private static final int kFrontLeftEncoderId = 1; - private static final Angle kFrontLeftEncoderOffset = Rotations.of(0.15234375); - private static final boolean kFrontLeftSteerMotorInverted = true; - private static final boolean kFrontLeftEncoderInverted = false; - - private static final Distance kFrontLeftXPos = Inches.of(10); - private static final Distance kFrontLeftYPos = Inches.of(10); - - // Front Right - private static final int kFrontRightDriveMotorId = 1; - private static final int kFrontRightSteerMotorId = 0; - private static final int kFrontRightEncoderId = 0; - private static final Angle kFrontRightEncoderOffset = Rotations.of(-0.4873046875); - private static final boolean kFrontRightSteerMotorInverted = true; - private static final boolean kFrontRightEncoderInverted = false; - - private static final Distance kFrontRightXPos = Inches.of(10); - private static final Distance kFrontRightYPos = Inches.of(-10); - - // Back Left - private static final int kBackLeftDriveMotorId = 7; - private static final int kBackLeftSteerMotorId = 6; - private static final int kBackLeftEncoderId = 3; - private static final Angle kBackLeftEncoderOffset = Rotations.of(-0.219482421875); - private static final boolean kBackLeftSteerMotorInverted = true; - private static final boolean kBackLeftEncoderInverted = false; - - private static final Distance kBackLeftXPos = Inches.of(-10); - private static final Distance kBackLeftYPos = Inches.of(10); - - // Back Right - private static final int kBackRightDriveMotorId = 5; - private static final int kBackRightSteerMotorId = 4; - private static final int kBackRightEncoderId = 2; - private static final Angle kBackRightEncoderOffset = Rotations.of(0.17236328125); - private static final boolean kBackRightSteerMotorInverted = true; - private static final boolean kBackRightEncoderInverted = false; - - private static final Distance kBackRightXPos = Inches.of(-10); - private static final Distance kBackRightYPos = Inches.of(-10); - - - public static final SwerveModuleConstants FrontLeft = - ConstantCreator.createModuleConstants( - kFrontLeftSteerMotorId, kFrontLeftDriveMotorId, kFrontLeftEncoderId, kFrontLeftEncoderOffset, - kFrontLeftXPos, kFrontLeftYPos, kInvertLeftSide, kFrontLeftSteerMotorInverted, kFrontLeftEncoderInverted - ); - public static final SwerveModuleConstants FrontRight = - ConstantCreator.createModuleConstants( - kFrontRightSteerMotorId, kFrontRightDriveMotorId, kFrontRightEncoderId, kFrontRightEncoderOffset, - kFrontRightXPos, kFrontRightYPos, kInvertRightSide, kFrontRightSteerMotorInverted, kFrontRightEncoderInverted - ); - public static final SwerveModuleConstants BackLeft = - ConstantCreator.createModuleConstants( - kBackLeftSteerMotorId, kBackLeftDriveMotorId, kBackLeftEncoderId, kBackLeftEncoderOffset, - kBackLeftXPos, kBackLeftYPos, kInvertLeftSide, kBackLeftSteerMotorInverted, kBackLeftEncoderInverted - ); - public static final SwerveModuleConstants BackRight = - ConstantCreator.createModuleConstants( - kBackRightSteerMotorId, kBackRightDriveMotorId, kBackRightEncoderId, kBackRightEncoderOffset, - kBackRightXPos, kBackRightYPos, kInvertRightSide, kBackRightSteerMotorInverted, kBackRightEncoderInverted - ); - - /** - * Creates a CommandSwerveDrivetrain instance. - * This should only be called once in your robot program,. - */ - public static CommandSwerveDrivetrain createDrivetrain() { - return new CommandSwerveDrivetrain( - DrivetrainConstants, FrontLeft, FrontRight, BackLeft, BackRight - ); - } - - - /** - * Swerve Drive class utilizing CTR Electronics' Phoenix 6 API with the selected device types. - */ - public static class TunerSwerveDrivetrain extends SwerveDrivetrain { - /** - * Constructs a CTRE SwerveDrivetrain using the specified constants. - *

- * This constructs the underlying hardware devices, so users should not construct - * the devices themselves. If they need the devices, they can access them through - * getters in the classes. - * - * @param drivetrainConstants Drivetrain-wide constants for the swerve drive - * @param modules Constants for each specific module - */ - public TunerSwerveDrivetrain( - SwerveDrivetrainConstants drivetrainConstants, - SwerveModuleConstants... modules - ) { - super( - TalonFX::new, TalonFX::new, CANcoder::new, - drivetrainConstants, modules - ); - } - - /** - * Constructs a CTRE SwerveDrivetrain using the specified constants. - *

- * This constructs the underlying hardware devices, so users should not construct - * the devices themselves. If they need the devices, they can access them through - * getters in the classes. - * - * @param drivetrainConstants Drivetrain-wide constants for the swerve drive - * @param odometryUpdateFrequency The frequency to run the odometry loop. If - * unspecified or set to 0 Hz, this is 250 Hz on - * CAN FD, and 100 Hz on CAN 2.0. - * @param modules Constants for each specific module - */ - public TunerSwerveDrivetrain( - SwerveDrivetrainConstants drivetrainConstants, - double odometryUpdateFrequency, - SwerveModuleConstants... modules - ) { - super( - TalonFX::new, TalonFX::new, CANcoder::new, - drivetrainConstants, odometryUpdateFrequency, modules - ); - } - - /** - * Constructs a CTRE SwerveDrivetrain using the specified constants. - *

- * This constructs the underlying hardware devices, so users should not construct - * the devices themselves. If they need the devices, they can access them through - * getters in the classes. - * - * @param drivetrainConstants Drivetrain-wide constants for the swerve drive - * @param odometryUpdateFrequency The frequency to run the odometry loop. If - * unspecified or set to 0 Hz, this is 250 Hz on - * CAN FD, and 100 Hz on CAN 2.0. - * @param odometryStandardDeviation The standard deviation for odometry calculation - * in the form [x, y, theta]ᵀ, with units in meters - * and radians - * @param visionStandardDeviation The standard deviation for vision calculation - * in the form [x, y, theta]ᵀ, with units in meters - * and radians - * @param modules Constants for each specific module - */ - public TunerSwerveDrivetrain( - SwerveDrivetrainConstants drivetrainConstants, - double odometryUpdateFrequency, - Matrix odometryStandardDeviation, - Matrix visionStandardDeviation, - SwerveModuleConstants... modules - ) { - super( - TalonFX::new, TalonFX::new, CANcoder::new, - drivetrainConstants, odometryUpdateFrequency, - odometryStandardDeviation, visionStandardDeviation, modules - ); - } - } -} +package frc.robot.generated; + +import static edu.wpi.first.units.Units.*; + +import com.ctre.phoenix6.CANBus; +import com.ctre.phoenix6.configs.*; +import com.ctre.phoenix6.hardware.*; +import com.ctre.phoenix6.signals.*; +import com.ctre.phoenix6.swerve.*; +import com.ctre.phoenix6.swerve.SwerveModuleConstants.*; + +import edu.wpi.first.math.Matrix; +import edu.wpi.first.math.numbers.N1; +import edu.wpi.first.math.numbers.N3; +import edu.wpi.first.units.measure.*; + +import frc.robot.subsystems.CommandSwerveDrivetrain; + +// Generated by the 2026 Tuner X Swerve Project Generator +// https://v6.docs.ctr-electronics.com/en/stable/docs/tuner/tuner-swerve/index.html +public class TunerConstants { + // Both sets of gains need to be tuned to your individual robot. + + // The steer motor uses any SwerveModule.SteerRequestType control request with the + // output type specified by SwerveModuleConstants.SteerMotorClosedLoopOutput + private static final Slot0Configs steerGains = new Slot0Configs() + .withKP(100).withKI(0).withKD(0.5) + .withKS(0.1).withKV(1.91).withKA(0) + .withStaticFeedforwardSign(StaticFeedforwardSignValue.UseClosedLoopSign); + // When using closed-loop control, the drive motor uses the control + // output type specified by SwerveModuleConstants.DriveMotorClosedLoopOutput + private static final Slot0Configs driveGains = new Slot0Configs() + .withKP(0.1).withKI(0).withKD(0) + .withKS(0).withKV(0.124); + + // The closed-loop output type to use for the steer motors; + // This affects the PID/FF gains for the steer motors + private static final ClosedLoopOutputType kSteerClosedLoopOutput = ClosedLoopOutputType.Voltage; + // The closed-loop output type to use for the drive motors; + // This affects the PID/FF gains for the drive motors + private static final ClosedLoopOutputType kDriveClosedLoopOutput = ClosedLoopOutputType.Voltage; + + // The type of motor used for the drive motor + private static final DriveMotorArrangement kDriveMotorType = DriveMotorArrangement.TalonFX_Integrated; + // The type of motor used for the drive motor + private static final SteerMotorArrangement kSteerMotorType = SteerMotorArrangement.TalonFX_Integrated; + + // The remote sensor feedback type to use for the steer motors; + // When not Pro-licensed, Fused*/Sync* automatically fall back to Remote* + private static final SteerFeedbackType kSteerFeedbackType = SteerFeedbackType.FusedCANcoder; + + // The stator current at which the wheels start to slip; + // This needs to be tuned to your individual robot + private static final Current kSlipCurrent = Amps.of(120); + + // Initial configs for the drive and steer motors and the azimuth encoder; these cannot be null. + // Some configs will be overwritten; check the `with*InitialConfigs()` API documentation. + private static final TalonFXConfiguration driveInitialConfigs = new TalonFXConfiguration(); + private static final TalonFXConfiguration steerInitialConfigs = new TalonFXConfiguration() + .withCurrentLimits( + new CurrentLimitsConfigs() + // Swerve azimuth does not require much torque output, so we can set a relatively low + // stator current limit to help avoid brownouts without impacting performance. + .withStatorCurrentLimit(Amps.of(60)) + .withStatorCurrentLimitEnable(true) + ); + private static final CANcoderConfiguration encoderInitialConfigs = new CANcoderConfiguration(); + // Configs for the Pigeon 2; leave this null to skip applying Pigeon 2 configs + private static final Pigeon2Configuration pigeonConfigs = null; + + // CAN bus that the devices are located on; + // All swerve devices must share the same CAN bus + public static final CANBus kCANBus = new CANBus("canivore", "./logs/example.hoot"); + + // Theoretical free speed (m/s) at 12 V applied output; + // This needs to be tuned to your individual robot + public static final LinearVelocity kSpeedAt12Volts = MetersPerSecond.of(4.54); + + // Every 1 rotation of the azimuth results in kCoupleRatio drive motor turns; + // This may need to be tuned to your individual robot + private static final double kCoupleRatio = 3.8181818181818183; + + private static final double kDriveGearRatio = 7.363636363636365; + private static final double kSteerGearRatio = 15.42857142857143; + private static final Distance kWheelRadius = Inches.of(2.167); + + private static final boolean kInvertLeftSide = false; + private static final boolean kInvertRightSide = true; + + private static final int kPigeonId = 1; + + // These are only used for simulation + private static final MomentOfInertia kSteerInertia = KilogramSquareMeters.of(0.01); + private static final MomentOfInertia kDriveInertia = KilogramSquareMeters.of(0.01); + // Simulated voltage necessary to overcome friction + private static final Voltage kSteerFrictionVoltage = Volts.of(0.2); + private static final Voltage kDriveFrictionVoltage = Volts.of(0.2); + + public static final SwerveDrivetrainConstants DrivetrainConstants = new SwerveDrivetrainConstants() + .withCANBusName(kCANBus.getName()) + .withPigeon2Id(kPigeonId) + .withPigeon2Configs(pigeonConfigs); + + private static final SwerveModuleConstantsFactory ConstantCreator = + new SwerveModuleConstantsFactory() + .withDriveMotorGearRatio(kDriveGearRatio) + .withSteerMotorGearRatio(kSteerGearRatio) + .withCouplingGearRatio(kCoupleRatio) + .withWheelRadius(kWheelRadius) + .withSteerMotorGains(steerGains) + .withDriveMotorGains(driveGains) + .withSteerMotorClosedLoopOutput(kSteerClosedLoopOutput) + .withDriveMotorClosedLoopOutput(kDriveClosedLoopOutput) + .withSlipCurrent(kSlipCurrent) + .withSpeedAt12Volts(kSpeedAt12Volts) + .withDriveMotorType(kDriveMotorType) + .withSteerMotorType(kSteerMotorType) + .withFeedbackSource(kSteerFeedbackType) + .withDriveMotorInitialConfigs(driveInitialConfigs) + .withSteerMotorInitialConfigs(steerInitialConfigs) + .withEncoderInitialConfigs(encoderInitialConfigs) + .withSteerInertia(kSteerInertia) + .withDriveInertia(kDriveInertia) + .withSteerFrictionVoltage(kSteerFrictionVoltage) + .withDriveFrictionVoltage(kDriveFrictionVoltage); + + + // Front Left + private static final int kFrontLeftDriveMotorId = 3; + private static final int kFrontLeftSteerMotorId = 2; + private static final int kFrontLeftEncoderId = 1; + private static final Angle kFrontLeftEncoderOffset = Rotations.of(0.15234375); + private static final boolean kFrontLeftSteerMotorInverted = true; + private static final boolean kFrontLeftEncoderInverted = false; + + private static final Distance kFrontLeftXPos = Inches.of(10); + private static final Distance kFrontLeftYPos = Inches.of(10); + + // Front Right + private static final int kFrontRightDriveMotorId = 1; + private static final int kFrontRightSteerMotorId = 0; + private static final int kFrontRightEncoderId = 0; + private static final Angle kFrontRightEncoderOffset = Rotations.of(-0.4873046875); + private static final boolean kFrontRightSteerMotorInverted = true; + private static final boolean kFrontRightEncoderInverted = false; + + private static final Distance kFrontRightXPos = Inches.of(10); + private static final Distance kFrontRightYPos = Inches.of(-10); + + // Back Left + private static final int kBackLeftDriveMotorId = 7; + private static final int kBackLeftSteerMotorId = 6; + private static final int kBackLeftEncoderId = 3; + private static final Angle kBackLeftEncoderOffset = Rotations.of(-0.219482421875); + private static final boolean kBackLeftSteerMotorInverted = true; + private static final boolean kBackLeftEncoderInverted = false; + + private static final Distance kBackLeftXPos = Inches.of(-10); + private static final Distance kBackLeftYPos = Inches.of(10); + + // Back Right + private static final int kBackRightDriveMotorId = 5; + private static final int kBackRightSteerMotorId = 4; + private static final int kBackRightEncoderId = 2; + private static final Angle kBackRightEncoderOffset = Rotations.of(0.17236328125); + private static final boolean kBackRightSteerMotorInverted = true; + private static final boolean kBackRightEncoderInverted = false; + + private static final Distance kBackRightXPos = Inches.of(-10); + private static final Distance kBackRightYPos = Inches.of(-10); + + + public static final SwerveModuleConstants FrontLeft = + ConstantCreator.createModuleConstants( + kFrontLeftSteerMotorId, kFrontLeftDriveMotorId, kFrontLeftEncoderId, kFrontLeftEncoderOffset, + kFrontLeftXPos, kFrontLeftYPos, kInvertLeftSide, kFrontLeftSteerMotorInverted, kFrontLeftEncoderInverted + ); + public static final SwerveModuleConstants FrontRight = + ConstantCreator.createModuleConstants( + kFrontRightSteerMotorId, kFrontRightDriveMotorId, kFrontRightEncoderId, kFrontRightEncoderOffset, + kFrontRightXPos, kFrontRightYPos, kInvertRightSide, kFrontRightSteerMotorInverted, kFrontRightEncoderInverted + ); + public static final SwerveModuleConstants BackLeft = + ConstantCreator.createModuleConstants( + kBackLeftSteerMotorId, kBackLeftDriveMotorId, kBackLeftEncoderId, kBackLeftEncoderOffset, + kBackLeftXPos, kBackLeftYPos, kInvertLeftSide, kBackLeftSteerMotorInverted, kBackLeftEncoderInverted + ); + public static final SwerveModuleConstants BackRight = + ConstantCreator.createModuleConstants( + kBackRightSteerMotorId, kBackRightDriveMotorId, kBackRightEncoderId, kBackRightEncoderOffset, + kBackRightXPos, kBackRightYPos, kInvertRightSide, kBackRightSteerMotorInverted, kBackRightEncoderInverted + ); + + /** + * Creates a CommandSwerveDrivetrain instance. + * This should only be called once in your robot program,. + */ + public static CommandSwerveDrivetrain createDrivetrain() { + return new CommandSwerveDrivetrain( + DrivetrainConstants, FrontLeft, FrontRight, BackLeft, BackRight + ); + } + + + /** + * Swerve Drive class utilizing CTR Electronics' Phoenix 6 API with the selected device types. + */ + public static class TunerSwerveDrivetrain extends SwerveDrivetrain { + /** + * Constructs a CTRE SwerveDrivetrain using the specified constants. + *

+ * This constructs the underlying hardware devices, so users should not construct + * the devices themselves. If they need the devices, they can access them through + * getters in the classes. + * + * @param drivetrainConstants Drivetrain-wide constants for the swerve drive + * @param modules Constants for each specific module + */ + public TunerSwerveDrivetrain( + SwerveDrivetrainConstants drivetrainConstants, + SwerveModuleConstants... modules + ) { + super( + TalonFX::new, TalonFX::new, CANcoder::new, + drivetrainConstants, modules + ); + } + + /** + * Constructs a CTRE SwerveDrivetrain using the specified constants. + *

+ * This constructs the underlying hardware devices, so users should not construct + * the devices themselves. If they need the devices, they can access them through + * getters in the classes. + * + * @param drivetrainConstants Drivetrain-wide constants for the swerve drive + * @param odometryUpdateFrequency The frequency to run the odometry loop. If + * unspecified or set to 0 Hz, this is 250 Hz on + * CAN FD, and 100 Hz on CAN 2.0. + * @param modules Constants for each specific module + */ + public TunerSwerveDrivetrain( + SwerveDrivetrainConstants drivetrainConstants, + double odometryUpdateFrequency, + SwerveModuleConstants... modules + ) { + super( + TalonFX::new, TalonFX::new, CANcoder::new, + drivetrainConstants, odometryUpdateFrequency, modules + ); + } + + /** + * Constructs a CTRE SwerveDrivetrain using the specified constants. + *

+ * This constructs the underlying hardware devices, so users should not construct + * the devices themselves. If they need the devices, they can access them through + * getters in the classes. + * + * @param drivetrainConstants Drivetrain-wide constants for the swerve drive + * @param odometryUpdateFrequency The frequency to run the odometry loop. If + * unspecified or set to 0 Hz, this is 250 Hz on + * CAN FD, and 100 Hz on CAN 2.0. + * @param odometryStandardDeviation The standard deviation for odometry calculation + * in the form [x, y, theta]ᵀ, with units in meters + * and radians + * @param visionStandardDeviation The standard deviation for vision calculation + * in the form [x, y, theta]ᵀ, with units in meters + * and radians + * @param modules Constants for each specific module + */ + public TunerSwerveDrivetrain( + SwerveDrivetrainConstants drivetrainConstants, + double odometryUpdateFrequency, + Matrix odometryStandardDeviation, + Matrix visionStandardDeviation, + SwerveModuleConstants... modules + ) { + super( + TalonFX::new, TalonFX::new, CANcoder::new, + drivetrainConstants, odometryUpdateFrequency, + odometryStandardDeviation, visionStandardDeviation, modules + ); + } + } +} diff --git a/java/SwerveWithChoreo/src/main/java/frc/robot/subsystems/CommandSwerveDrivetrain.java b/java/SwerveWithChoreo/src/main/java/frc/robot/subsystems/CommandSwerveDrivetrain.java index 4686dd32..9cb433c6 100644 --- a/java/SwerveWithChoreo/src/main/java/frc/robot/subsystems/CommandSwerveDrivetrain.java +++ b/java/SwerveWithChoreo/src/main/java/frc/robot/subsystems/CommandSwerveDrivetrain.java @@ -2,6 +2,7 @@ import static edu.wpi.first.units.Units.*; +import java.util.Optional; import java.util.function.Supplier; import com.ctre.phoenix6.SignalLogger; @@ -32,9 +33,12 @@ /** * Class that extends the Phoenix 6 SwerveDrivetrain class and implements * Subsystem so it can easily be used in command-based projects. + * + * Generated by the 2026 Tuner X Swerve Project Generator + * https://v6.docs.ctr-electronics.com/en/stable/docs/tuner/tuner-swerve/index.html */ public class CommandSwerveDrivetrain extends TunerSwerveDrivetrain implements Subsystem { - private static final double kSimLoopPeriod = 0.005; // 5 ms + private static final double kSimLoopPeriod = 0.004; // 4 ms private Notifier m_simNotifier = null; private double m_lastSimTime; @@ -125,8 +129,8 @@ public class CommandSwerveDrivetrain extends TunerSwerveDrivetrain implements Su * the devices themselves. If they need the devices, they can access them through * getters in the classes. * - * @param drivetrainConstants Drivetrain-wide constants for the swerve drive - * @param modules Constants for each specific module + * @param drivetrainConstants Drivetrain-wide constants for the swerve drive + * @param modules Constants for each specific module */ public CommandSwerveDrivetrain( SwerveDrivetrainConstants drivetrainConstants, @@ -145,11 +149,11 @@ public CommandSwerveDrivetrain( * the devices themselves. If they need the devices, they can access them through * getters in the classes. * - * @param drivetrainConstants Drivetrain-wide constants for the swerve drive - * @param odometryUpdateFrequency The frequency to run the odometry loop. If - * unspecified or set to 0 Hz, this is 250 Hz on - * CAN FD, and 100 Hz on CAN 2.0. - * @param modules Constants for each specific module + * @param drivetrainConstants Drivetrain-wide constants for the swerve drive + * @param odometryUpdateFrequency The frequency to run the odometry loop. If + * unspecified or set to 0 Hz, this is 250 Hz on + * CAN FD, and 100 Hz on CAN 2.0. + * @param modules Constants for each specific module */ public CommandSwerveDrivetrain( SwerveDrivetrainConstants drivetrainConstants, @@ -169,17 +173,17 @@ public CommandSwerveDrivetrain( * the devices themselves. If they need the devices, they can access them through * getters in the classes. * - * @param drivetrainConstants Drivetrain-wide constants for the swerve drive - * @param odometryUpdateFrequency The frequency to run the odometry loop. If - * unspecified or set to 0 Hz, this is 250 Hz on - * CAN FD, and 100 Hz on CAN 2.0. - * @param odometryStandardDeviation The standard deviation for odometry calculation + * @param drivetrainConstants Drivetrain-wide constants for the swerve drive + * @param odometryUpdateFrequency The frequency to run the odometry loop. If + * unspecified or set to 0 Hz, this is 250 Hz on + * CAN FD, and 100 Hz on CAN 2.0. + * @param odometryStandardDeviation The standard deviation for odometry calculation * in the form [x, y, theta]ᵀ, with units in meters * and radians * @param visionStandardDeviation The standard deviation for vision calculation * in the form [x, y, theta]ᵀ, with units in meters * and radians - * @param modules Constants for each specific module + * @param modules Constants for each specific module */ public CommandSwerveDrivetrain( SwerveDrivetrainConstants drivetrainConstants, @@ -227,8 +231,8 @@ public AutoFactory createAutoFactory(TrajectoryLogger trajLogger) * @param request Function returning the request to apply * @return Command to run */ - public Command applyRequest(Supplier requestSupplier) { - return run(() -> this.setControl(requestSupplier.get())); + public Command applyRequest(Supplier request) { + return run(() -> this.setControl(request.get())); } /** @@ -350,4 +354,15 @@ public void addVisionMeasurement( ) { super.addVisionMeasurement(visionRobotPoseMeters, Utils.fpgaToCurrentTime(timestampSeconds), visionMeasurementStdDevs); } + + /** + * Return the pose at a given timestamp, if the buffer is not empty. + * + * @param timestampSeconds The timestamp of the pose in seconds. + * @return The pose at the given timestamp (or Optional.empty() if the buffer is empty). + */ + @Override + public Optional samplePoseAt(double timestampSeconds) { + return super.samplePoseAt(Utils.fpgaToCurrentTime(timestampSeconds)); + } } diff --git a/java/SwerveWithPathPlanner/.vscode/settings.json b/java/SwerveWithPathPlanner/.vscode/settings.json index 612cdd0d..5e6ede86 100644 --- a/java/SwerveWithPathPlanner/.vscode/settings.json +++ b/java/SwerveWithPathPlanner/.vscode/settings.json @@ -56,5 +56,6 @@ "edu.wpi.first.math.proto.*", "edu.wpi.first.math.**.proto.*", "edu.wpi.first.math.**.struct.*", - ] + ], + "java.dependency.enableDependencyCheckup": false } diff --git a/java/SwerveWithPathPlanner/WPILib-License.md b/java/SwerveWithPathPlanner/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/java/SwerveWithPathPlanner/WPILib-License.md +++ b/java/SwerveWithPathPlanner/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/java/SwerveWithPathPlanner/build.gradle b/java/SwerveWithPathPlanner/build.gradle index f3438298..89820809 100644 --- a/java/SwerveWithPathPlanner/build.gradle +++ b/java/SwerveWithPathPlanner/build.gradle @@ -33,7 +33,7 @@ deploy { frcStaticFileDeploy(getArtifactTypeClass('FileTreeArtifact')) { files = project.fileTree('src/main/deploy') directory = '/home/lvuser/deploy' - deleteOldFiles = false // Change to true to delete files on roboRIO that no + deleteOldFiles = true // Change to true to delete files on roboRIO that no // longer exist in deploy directory of this project } } @@ -43,7 +43,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. @@ -88,7 +89,9 @@ wpi.sim.addDriverstation() // knows where to look for our Robot Class. jar { from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } - from sourceSets.main.allSource + from('src') { into 'backup/src' } + from('vendordeps') { into 'backup/vendordeps' } + from('build.gradle') { into 'backup' } manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) duplicatesStrategy = DuplicatesStrategy.INCLUDE } diff --git a/java/SwerveWithPathPlanner/settings.gradle b/java/SwerveWithPathPlanner/settings.gradle index c493958a..25f6f6e8 100644 --- a/java/SwerveWithPathPlanner/settings.gradle +++ b/java/SwerveWithPathPlanner/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') diff --git a/java/SwerveWithPathPlanner/src/main/java/frc/robot/Robot.java b/java/SwerveWithPathPlanner/src/main/java/frc/robot/Robot.java index ddf68776..a09abd69 100644 --- a/java/SwerveWithPathPlanner/src/main/java/frc/robot/Robot.java +++ b/java/SwerveWithPathPlanner/src/main/java/frc/robot/Robot.java @@ -4,95 +4,103 @@ package frc.robot; +import com.ctre.phoenix6.HootAutoReplay; + import edu.wpi.first.math.util.Units; import edu.wpi.first.wpilibj.TimedRobot; import edu.wpi.first.wpilibj2.command.Command; import edu.wpi.first.wpilibj2.command.CommandScheduler; public class Robot extends TimedRobot { - private Command m_autonomousCommand; - - private final RobotContainer m_robotContainer; - - private final boolean kUseLimelight = false; - - public Robot() { - m_robotContainer = new RobotContainer(); - } - - @Override - public void robotPeriodic() { - CommandScheduler.getInstance().run(); - - /* - * This example of adding Limelight is very simple and may not be sufficient for on-field use. - * Users typically need to provide a standard deviation that scales with the distance to target - * and changes with number of tags available. - * - * This example is sufficient to show that vision integration is possible, though exact implementation - * of how to use vision should be tuned per-robot and to the team's specification. - */ - if (kUseLimelight) { - var driveState = m_robotContainer.drivetrain.getState(); - double headingDeg = driveState.Pose.getRotation().getDegrees(); - double omegaRps = Units.radiansToRotations(driveState.Speeds.omegaRadiansPerSecond); - - LimelightHelpers.SetRobotOrientation("limelight", headingDeg, 0, 0, 0, 0, 0); - var llMeasurement = LimelightHelpers.getBotPoseEstimate_wpiBlue_MegaTag2("limelight"); - if (llMeasurement != null && llMeasurement.tagCount > 0 && Math.abs(omegaRps) < 2.0) { - m_robotContainer.drivetrain.addVisionMeasurement(llMeasurement.pose, llMeasurement.timestampSeconds); - } + private Command m_autonomousCommand; + + private final RobotContainer m_robotContainer; + + /* log and replay timestamp and joystick data */ + private final HootAutoReplay m_timeAndJoystickReplay = new HootAutoReplay() + .withTimestampReplay() + .withJoystickReplay(); + + private final boolean kUseLimelight = false; + + public Robot() { + m_robotContainer = new RobotContainer(); + } + + @Override + public void robotPeriodic() { + m_timeAndJoystickReplay.update(); + CommandScheduler.getInstance().run(); + + /* + * This example of adding Limelight is very simple and may not be sufficient for on-field use. + * Users typically need to provide a standard deviation that scales with the distance to target + * and changes with number of tags available. + * + * This example is sufficient to show that vision integration is possible, though exact implementation + * of how to use vision should be tuned per-robot and to the team's specification. + */ + if (kUseLimelight) { + var driveState = m_robotContainer.drivetrain.getState(); + double headingDeg = driveState.Pose.getRotation().getDegrees(); + double omegaRps = Units.radiansToRotations(driveState.Speeds.omegaRadiansPerSecond); + + LimelightHelpers.SetRobotOrientation("limelight", headingDeg, 0, 0, 0, 0, 0); + var llMeasurement = LimelightHelpers.getBotPoseEstimate_wpiBlue_MegaTag2("limelight"); + if (llMeasurement != null && llMeasurement.tagCount > 0 && Math.abs(omegaRps) < 2.0) { + m_robotContainer.drivetrain.addVisionMeasurement(llMeasurement.pose, llMeasurement.timestampSeconds); + } + } } - } - @Override - public void disabledInit() {} + @Override + public void disabledInit() {} - @Override - public void disabledPeriodic() {} + @Override + public void disabledPeriodic() {} - @Override - public void disabledExit() {} + @Override + public void disabledExit() {} - @Override - public void autonomousInit() { - m_autonomousCommand = m_robotContainer.getAutonomousCommand(); + @Override + public void autonomousInit() { + m_autonomousCommand = m_robotContainer.getAutonomousCommand(); - if (m_autonomousCommand != null) { - m_autonomousCommand.schedule(); + if (m_autonomousCommand != null) { + CommandScheduler.getInstance().schedule(m_autonomousCommand); + } } - } - @Override - public void autonomousPeriodic() {} + @Override + public void autonomousPeriodic() {} - @Override - public void autonomousExit() {} + @Override + public void autonomousExit() {} - @Override - public void teleopInit() { - if (m_autonomousCommand != null) { - m_autonomousCommand.cancel(); + @Override + public void teleopInit() { + if (m_autonomousCommand != null) { + CommandScheduler.getInstance().cancel(m_autonomousCommand); + } } - } - @Override - public void teleopPeriodic() {} + @Override + public void teleopPeriodic() {} - @Override - public void teleopExit() {} + @Override + public void teleopExit() {} - @Override - public void testInit() { - CommandScheduler.getInstance().cancelAll(); - } + @Override + public void testInit() { + CommandScheduler.getInstance().cancelAll(); + } - @Override - public void testPeriodic() {} + @Override + public void testPeriodic() {} - @Override - public void testExit() {} + @Override + public void testExit() {} - @Override - public void simulationPeriodic() {} + @Override + public void simulationPeriodic() {} } diff --git a/java/SwerveWithPathPlanner/src/main/java/frc/robot/RobotContainer.java b/java/SwerveWithPathPlanner/src/main/java/frc/robot/RobotContainer.java index 02a7e59a..4f26f422 100644 --- a/java/SwerveWithPathPlanner/src/main/java/frc/robot/RobotContainer.java +++ b/java/SwerveWithPathPlanner/src/main/java/frc/robot/RobotContainer.java @@ -24,7 +24,7 @@ import frc.robot.subsystems.CommandSwerveDrivetrain; public class RobotContainer { - private double MaxSpeed = TunerConstants.kSpeedAt12Volts.in(MetersPerSecond); // kSpeedAt12Volts desired top speed + private double MaxSpeed = 1.0 * TunerConstants.kSpeedAt12Volts.in(MetersPerSecond); // kSpeedAt12Volts desired top speed private double MaxAngularRate = RotationsPerSecond.of(0.75).in(RadiansPerSecond); // 3/4 of a rotation per second max angular velocity /* Setting up bindings for necessary control of the swerve drive platform */ @@ -79,10 +79,10 @@ private void configureBindings() { point.withModuleDirection(new Rotation2d(-joystick.getLeftY(), -joystick.getLeftX())) )); - joystick.pov(0).whileTrue(drivetrain.applyRequest(() -> + joystick.povUp().whileTrue(drivetrain.applyRequest(() -> forwardStraight.withVelocityX(0.5).withVelocityY(0)) ); - joystick.pov(180).whileTrue(drivetrain.applyRequest(() -> + joystick.povDown().whileTrue(drivetrain.applyRequest(() -> forwardStraight.withVelocityX(-0.5).withVelocityY(0)) ); @@ -93,8 +93,8 @@ private void configureBindings() { joystick.start().and(joystick.y()).whileTrue(drivetrain.sysIdQuasistatic(Direction.kForward)); joystick.start().and(joystick.x()).whileTrue(drivetrain.sysIdQuasistatic(Direction.kReverse)); - // reset the field-centric heading on left bumper press - joystick.leftBumper().onTrue(drivetrain.runOnce(() -> drivetrain.seedFieldCentric())); + // Reset the field-centric heading on left bumper press. + joystick.leftBumper().onTrue(drivetrain.runOnce(drivetrain::seedFieldCentric)); drivetrain.registerTelemetry(logger::telemeterize); } diff --git a/java/SwerveWithPathPlanner/src/main/java/frc/robot/Telemetry.java b/java/SwerveWithPathPlanner/src/main/java/frc/robot/Telemetry.java index edf1979f..f9da9480 100644 --- a/java/SwerveWithPathPlanner/src/main/java/frc/robot/Telemetry.java +++ b/java/SwerveWithPathPlanner/src/main/java/frc/robot/Telemetry.java @@ -31,6 +31,11 @@ public class Telemetry { public Telemetry(double maxSpeed) { MaxSpeed = maxSpeed; SignalLogger.start(); + + /* Set up the module state Mechanism2d telemetry */ + for (int i = 0; i < 4; ++i) { + SmartDashboard.putData("Module " + i, m_moduleMechanisms[i]); + } } /* What to publish over networktables for telemetry */ @@ -78,8 +83,6 @@ public Telemetry(double maxSpeed) { }; private final double[] m_poseArray = new double[3]; - private final double[] m_moduleStatesArray = new double[8]; - private final double[] m_moduleTargetsArray = new double[8]; /** Accept the swerve drive state and telemeterize it to SmartDashboard and SignalLogger. */ public void telemeterize(SwerveDriveState state) { @@ -93,32 +96,26 @@ public void telemeterize(SwerveDriveState state) { driveOdometryFrequency.set(1.0 / state.OdometryPeriod); /* Also write to log file */ - m_poseArray[0] = state.Pose.getX(); - m_poseArray[1] = state.Pose.getY(); - m_poseArray[2] = state.Pose.getRotation().getDegrees(); - for (int i = 0; i < 4; ++i) { - m_moduleStatesArray[i*2 + 0] = state.ModuleStates[i].angle.getRadians(); - m_moduleStatesArray[i*2 + 1] = state.ModuleStates[i].speedMetersPerSecond; - m_moduleTargetsArray[i*2 + 0] = state.ModuleTargets[i].angle.getRadians(); - m_moduleTargetsArray[i*2 + 1] = state.ModuleTargets[i].speedMetersPerSecond; - } - - SignalLogger.writeDoubleArray("DriveState/Pose", m_poseArray); - SignalLogger.writeDoubleArray("DriveState/ModuleStates", m_moduleStatesArray); - SignalLogger.writeDoubleArray("DriveState/ModuleTargets", m_moduleTargetsArray); + SignalLogger.writeStruct("DriveState/Pose", Pose2d.struct, state.Pose); + SignalLogger.writeStruct("DriveState/Speeds", ChassisSpeeds.struct, state.Speeds); + SignalLogger.writeStructArray("DriveState/ModuleStates", SwerveModuleState.struct, state.ModuleStates); + SignalLogger.writeStructArray("DriveState/ModuleTargets", SwerveModuleState.struct, state.ModuleTargets); + SignalLogger.writeStructArray("DriveState/ModulePositions", SwerveModulePosition.struct, state.ModulePositions); SignalLogger.writeDouble("DriveState/OdometryPeriod", state.OdometryPeriod, "seconds"); /* Telemeterize the pose to a Field2d */ fieldTypePub.set("Field2d"); + + m_poseArray[0] = state.Pose.getX(); + m_poseArray[1] = state.Pose.getY(); + m_poseArray[2] = state.Pose.getRotation().getDegrees(); fieldPub.set(m_poseArray); - /* Telemeterize the module states to a Mechanism2d */ + /* Telemeterize each module state to a Mechanism2d */ for (int i = 0; i < 4; ++i) { m_moduleSpeeds[i].setAngle(state.ModuleStates[i].angle); m_moduleDirections[i].setAngle(state.ModuleStates[i].angle); m_moduleSpeeds[i].setLength(state.ModuleStates[i].speedMetersPerSecond / (2 * MaxSpeed)); - - SmartDashboard.putData("Module " + i, m_moduleMechanisms[i]); } } } diff --git a/java/SwerveWithPathPlanner/src/main/java/frc/robot/generated/TunerConstants.java b/java/SwerveWithPathPlanner/src/main/java/frc/robot/generated/TunerConstants.java index 4979012b..675bcbd7 100644 --- a/java/SwerveWithPathPlanner/src/main/java/frc/robot/generated/TunerConstants.java +++ b/java/SwerveWithPathPlanner/src/main/java/frc/robot/generated/TunerConstants.java @@ -1,286 +1,286 @@ -package frc.robot.generated; - -import static edu.wpi.first.units.Units.*; - -import com.ctre.phoenix6.CANBus; -import com.ctre.phoenix6.configs.*; -import com.ctre.phoenix6.hardware.*; -import com.ctre.phoenix6.signals.*; -import com.ctre.phoenix6.swerve.*; -import com.ctre.phoenix6.swerve.SwerveModuleConstants.*; - -import edu.wpi.first.math.Matrix; -import edu.wpi.first.math.numbers.N1; -import edu.wpi.first.math.numbers.N3; -import edu.wpi.first.units.measure.*; - -import frc.robot.subsystems.CommandSwerveDrivetrain; - -// Generated by the Tuner X Swerve Project Generator -// https://v6.docs.ctr-electronics.com/en/stable/docs/tuner/tuner-swerve/index.html -public class TunerConstants { - // Both sets of gains need to be tuned to your individual robot. - - // The steer motor uses any SwerveModule.SteerRequestType control request with the - // output type specified by SwerveModuleConstants.SteerMotorClosedLoopOutput - private static final Slot0Configs steerGains = new Slot0Configs() - .withKP(100).withKI(0).withKD(0.5) - .withKS(0.1).withKV(1.91).withKA(0) - .withStaticFeedforwardSign(StaticFeedforwardSignValue.UseClosedLoopSign); - // When using closed-loop control, the drive motor uses the control - // output type specified by SwerveModuleConstants.DriveMotorClosedLoopOutput - private static final Slot0Configs driveGains = new Slot0Configs() - .withKP(0.1).withKI(0).withKD(0) - .withKS(0).withKV(0.124); - - // The closed-loop output type to use for the steer motors; - // This affects the PID/FF gains for the steer motors - private static final ClosedLoopOutputType kSteerClosedLoopOutput = ClosedLoopOutputType.Voltage; - // The closed-loop output type to use for the drive motors; - // This affects the PID/FF gains for the drive motors - private static final ClosedLoopOutputType kDriveClosedLoopOutput = ClosedLoopOutputType.Voltage; - - // The type of motor used for the drive motor - private static final DriveMotorArrangement kDriveMotorType = DriveMotorArrangement.TalonFX_Integrated; - // The type of motor used for the drive motor - private static final SteerMotorArrangement kSteerMotorType = SteerMotorArrangement.TalonFX_Integrated; - - // The remote sensor feedback type to use for the steer motors; - // When not Pro-licensed, Fused*/Sync* automatically fall back to Remote* - private static final SteerFeedbackType kSteerFeedbackType = SteerFeedbackType.FusedCANcoder; - - // The stator current at which the wheels start to slip; - // This needs to be tuned to your individual robot - private static final Current kSlipCurrent = Amps.of(120.0); - - // Initial configs for the drive and steer motors and the azimuth encoder; these cannot be null. - // Some configs will be overwritten; check the `with*InitialConfigs()` API documentation. - private static final TalonFXConfiguration driveInitialConfigs = new TalonFXConfiguration(); - private static final TalonFXConfiguration steerInitialConfigs = new TalonFXConfiguration() - .withCurrentLimits( - new CurrentLimitsConfigs() - // Swerve azimuth does not require much torque output, so we can set a relatively low - // stator current limit to help avoid brownouts without impacting performance. - .withStatorCurrentLimit(Amps.of(60.0)) - .withStatorCurrentLimitEnable(true) - ); - private static final CANcoderConfiguration encoderInitialConfigs = new CANcoderConfiguration(); - // Configs for the Pigeon 2; leave this null to skip applying Pigeon 2 configs - private static final Pigeon2Configuration pigeonConfigs = null; - - // CAN bus that the devices are located on; - // All swerve devices must share the same CAN bus - public static final CANBus kCANBus = new CANBus("canivore", "./logs/example.hoot"); - - // Theoretical free speed (m/s) at 12 V applied output; - // This needs to be tuned to your individual robot - public static final LinearVelocity kSpeedAt12Volts = MetersPerSecond.of(4.54); - - // Every 1 rotation of the azimuth results in kCoupleRatio drive motor turns; - // This may need to be tuned to your individual robot - private static final double kCoupleRatio = 3.8181818181818183; - - private static final double kDriveGearRatio = 7.363636363636365; - private static final double kSteerGearRatio = 15.42857142857143; - private static final Distance kWheelRadius = Inches.of(2.167); - - private static final boolean kInvertLeftSide = false; - private static final boolean kInvertRightSide = true; - - private static final int kPigeonId = 1; - - // These are only used for simulation - private static final MomentOfInertia kSteerInertia = KilogramSquareMeters.of(0.01); - private static final MomentOfInertia kDriveInertia = KilogramSquareMeters.of(0.01); - // Simulated voltage necessary to overcome friction - private static final Voltage kSteerFrictionVoltage = Volts.of(0.2); - private static final Voltage kDriveFrictionVoltage = Volts.of(0.2); - - public static final SwerveDrivetrainConstants DrivetrainConstants = new SwerveDrivetrainConstants() - .withCANBusName(kCANBus.getName()) - .withPigeon2Id(kPigeonId) - .withPigeon2Configs(pigeonConfigs); - - private static final SwerveModuleConstantsFactory ConstantCreator = - new SwerveModuleConstantsFactory() - .withDriveMotorGearRatio(kDriveGearRatio) - .withSteerMotorGearRatio(kSteerGearRatio) - .withCouplingGearRatio(kCoupleRatio) - .withWheelRadius(kWheelRadius) - .withSteerMotorGains(steerGains) - .withDriveMotorGains(driveGains) - .withSteerMotorClosedLoopOutput(kSteerClosedLoopOutput) - .withDriveMotorClosedLoopOutput(kDriveClosedLoopOutput) - .withSlipCurrent(kSlipCurrent) - .withSpeedAt12Volts(kSpeedAt12Volts) - .withDriveMotorType(kDriveMotorType) - .withSteerMotorType(kSteerMotorType) - .withFeedbackSource(kSteerFeedbackType) - .withDriveMotorInitialConfigs(driveInitialConfigs) - .withSteerMotorInitialConfigs(steerInitialConfigs) - .withEncoderInitialConfigs(encoderInitialConfigs) - .withSteerInertia(kSteerInertia) - .withDriveInertia(kDriveInertia) - .withSteerFrictionVoltage(kSteerFrictionVoltage) - .withDriveFrictionVoltage(kDriveFrictionVoltage); - - - // Front Left - private static final int kFrontLeftDriveMotorId = 3; - private static final int kFrontLeftSteerMotorId = 2; - private static final int kFrontLeftEncoderId = 1; - private static final Angle kFrontLeftEncoderOffset = Rotations.of(0.15234375); - private static final boolean kFrontLeftSteerMotorInverted = true; - private static final boolean kFrontLeftEncoderInverted = false; - - private static final Distance kFrontLeftXPos = Inches.of(10); - private static final Distance kFrontLeftYPos = Inches.of(10); - - // Front Right - private static final int kFrontRightDriveMotorId = 1; - private static final int kFrontRightSteerMotorId = 0; - private static final int kFrontRightEncoderId = 0; - private static final Angle kFrontRightEncoderOffset = Rotations.of(-0.4873046875); - private static final boolean kFrontRightSteerMotorInverted = true; - private static final boolean kFrontRightEncoderInverted = false; - - private static final Distance kFrontRightXPos = Inches.of(10); - private static final Distance kFrontRightYPos = Inches.of(-10); - - // Back Left - private static final int kBackLeftDriveMotorId = 7; - private static final int kBackLeftSteerMotorId = 6; - private static final int kBackLeftEncoderId = 3; - private static final Angle kBackLeftEncoderOffset = Rotations.of(-0.219482421875); - private static final boolean kBackLeftSteerMotorInverted = true; - private static final boolean kBackLeftEncoderInverted = false; - - private static final Distance kBackLeftXPos = Inches.of(-10); - private static final Distance kBackLeftYPos = Inches.of(10); - - // Back Right - private static final int kBackRightDriveMotorId = 5; - private static final int kBackRightSteerMotorId = 4; - private static final int kBackRightEncoderId = 2; - private static final Angle kBackRightEncoderOffset = Rotations.of(0.17236328125); - private static final boolean kBackRightSteerMotorInverted = true; - private static final boolean kBackRightEncoderInverted = false; - - private static final Distance kBackRightXPos = Inches.of(-10); - private static final Distance kBackRightYPos = Inches.of(-10); - - - public static final SwerveModuleConstants FrontLeft = - ConstantCreator.createModuleConstants( - kFrontLeftSteerMotorId, kFrontLeftDriveMotorId, kFrontLeftEncoderId, kFrontLeftEncoderOffset, - kFrontLeftXPos, kFrontLeftYPos, kInvertLeftSide, kFrontLeftSteerMotorInverted, kFrontLeftEncoderInverted - ); - public static final SwerveModuleConstants FrontRight = - ConstantCreator.createModuleConstants( - kFrontRightSteerMotorId, kFrontRightDriveMotorId, kFrontRightEncoderId, kFrontRightEncoderOffset, - kFrontRightXPos, kFrontRightYPos, kInvertRightSide, kFrontRightSteerMotorInverted, kFrontRightEncoderInverted - ); - public static final SwerveModuleConstants BackLeft = - ConstantCreator.createModuleConstants( - kBackLeftSteerMotorId, kBackLeftDriveMotorId, kBackLeftEncoderId, kBackLeftEncoderOffset, - kBackLeftXPos, kBackLeftYPos, kInvertLeftSide, kBackLeftSteerMotorInverted, kBackLeftEncoderInverted - ); - public static final SwerveModuleConstants BackRight = - ConstantCreator.createModuleConstants( - kBackRightSteerMotorId, kBackRightDriveMotorId, kBackRightEncoderId, kBackRightEncoderOffset, - kBackRightXPos, kBackRightYPos, kInvertRightSide, kBackRightSteerMotorInverted, kBackRightEncoderInverted - ); - - /** - * Creates a CommandSwerveDrivetrain instance. - * This should only be called once in your robot program,. - */ - public static CommandSwerveDrivetrain createDrivetrain() { - return new CommandSwerveDrivetrain( - DrivetrainConstants, FrontLeft, FrontRight, BackLeft, BackRight - ); - } - - - /** - * Swerve Drive class utilizing CTR Electronics' Phoenix 6 API with the selected device types. - */ - public static class TunerSwerveDrivetrain extends SwerveDrivetrain { - /** - * Constructs a CTRE SwerveDrivetrain using the specified constants. - *

- * This constructs the underlying hardware devices, so users should not construct - * the devices themselves. If they need the devices, they can access them through - * getters in the classes. - * - * @param drivetrainConstants Drivetrain-wide constants for the swerve drive - * @param modules Constants for each specific module - */ - public TunerSwerveDrivetrain( - SwerveDrivetrainConstants drivetrainConstants, - SwerveModuleConstants... modules - ) { - super( - TalonFX::new, TalonFX::new, CANcoder::new, - drivetrainConstants, modules - ); - } - - /** - * Constructs a CTRE SwerveDrivetrain using the specified constants. - *

- * This constructs the underlying hardware devices, so users should not construct - * the devices themselves. If they need the devices, they can access them through - * getters in the classes. - * - * @param drivetrainConstants Drivetrain-wide constants for the swerve drive - * @param odometryUpdateFrequency The frequency to run the odometry loop. If - * unspecified or set to 0 Hz, this is 250 Hz on - * CAN FD, and 100 Hz on CAN 2.0. - * @param modules Constants for each specific module - */ - public TunerSwerveDrivetrain( - SwerveDrivetrainConstants drivetrainConstants, - double odometryUpdateFrequency, - SwerveModuleConstants... modules - ) { - super( - TalonFX::new, TalonFX::new, CANcoder::new, - drivetrainConstants, odometryUpdateFrequency, modules - ); - } - - /** - * Constructs a CTRE SwerveDrivetrain using the specified constants. - *

- * This constructs the underlying hardware devices, so users should not construct - * the devices themselves. If they need the devices, they can access them through - * getters in the classes. - * - * @param drivetrainConstants Drivetrain-wide constants for the swerve drive - * @param odometryUpdateFrequency The frequency to run the odometry loop. If - * unspecified or set to 0 Hz, this is 250 Hz on - * CAN FD, and 100 Hz on CAN 2.0. - * @param odometryStandardDeviation The standard deviation for odometry calculation - * in the form [x, y, theta]ᵀ, with units in meters - * and radians - * @param visionStandardDeviation The standard deviation for vision calculation - * in the form [x, y, theta]ᵀ, with units in meters - * and radians - * @param modules Constants for each specific module - */ - public TunerSwerveDrivetrain( - SwerveDrivetrainConstants drivetrainConstants, - double odometryUpdateFrequency, - Matrix odometryStandardDeviation, - Matrix visionStandardDeviation, - SwerveModuleConstants... modules - ) { - super( - TalonFX::new, TalonFX::new, CANcoder::new, - drivetrainConstants, odometryUpdateFrequency, - odometryStandardDeviation, visionStandardDeviation, modules - ); - } - } -} +package frc.robot.generated; + +import static edu.wpi.first.units.Units.*; + +import com.ctre.phoenix6.CANBus; +import com.ctre.phoenix6.configs.*; +import com.ctre.phoenix6.hardware.*; +import com.ctre.phoenix6.signals.*; +import com.ctre.phoenix6.swerve.*; +import com.ctre.phoenix6.swerve.SwerveModuleConstants.*; + +import edu.wpi.first.math.Matrix; +import edu.wpi.first.math.numbers.N1; +import edu.wpi.first.math.numbers.N3; +import edu.wpi.first.units.measure.*; + +import frc.robot.subsystems.CommandSwerveDrivetrain; + +// Generated by the 2026 Tuner X Swerve Project Generator +// https://v6.docs.ctr-electronics.com/en/stable/docs/tuner/tuner-swerve/index.html +public class TunerConstants { + // Both sets of gains need to be tuned to your individual robot. + + // The steer motor uses any SwerveModule.SteerRequestType control request with the + // output type specified by SwerveModuleConstants.SteerMotorClosedLoopOutput + private static final Slot0Configs steerGains = new Slot0Configs() + .withKP(100).withKI(0).withKD(0.5) + .withKS(0.1).withKV(1.91).withKA(0) + .withStaticFeedforwardSign(StaticFeedforwardSignValue.UseClosedLoopSign); + // When using closed-loop control, the drive motor uses the control + // output type specified by SwerveModuleConstants.DriveMotorClosedLoopOutput + private static final Slot0Configs driveGains = new Slot0Configs() + .withKP(0.1).withKI(0).withKD(0) + .withKS(0).withKV(0.124); + + // The closed-loop output type to use for the steer motors; + // This affects the PID/FF gains for the steer motors + private static final ClosedLoopOutputType kSteerClosedLoopOutput = ClosedLoopOutputType.Voltage; + // The closed-loop output type to use for the drive motors; + // This affects the PID/FF gains for the drive motors + private static final ClosedLoopOutputType kDriveClosedLoopOutput = ClosedLoopOutputType.Voltage; + + // The type of motor used for the drive motor + private static final DriveMotorArrangement kDriveMotorType = DriveMotorArrangement.TalonFX_Integrated; + // The type of motor used for the drive motor + private static final SteerMotorArrangement kSteerMotorType = SteerMotorArrangement.TalonFX_Integrated; + + // The remote sensor feedback type to use for the steer motors; + // When not Pro-licensed, Fused*/Sync* automatically fall back to Remote* + private static final SteerFeedbackType kSteerFeedbackType = SteerFeedbackType.FusedCANcoder; + + // The stator current at which the wheels start to slip; + // This needs to be tuned to your individual robot + private static final Current kSlipCurrent = Amps.of(120); + + // Initial configs for the drive and steer motors and the azimuth encoder; these cannot be null. + // Some configs will be overwritten; check the `with*InitialConfigs()` API documentation. + private static final TalonFXConfiguration driveInitialConfigs = new TalonFXConfiguration(); + private static final TalonFXConfiguration steerInitialConfigs = new TalonFXConfiguration() + .withCurrentLimits( + new CurrentLimitsConfigs() + // Swerve azimuth does not require much torque output, so we can set a relatively low + // stator current limit to help avoid brownouts without impacting performance. + .withStatorCurrentLimit(Amps.of(60)) + .withStatorCurrentLimitEnable(true) + ); + private static final CANcoderConfiguration encoderInitialConfigs = new CANcoderConfiguration(); + // Configs for the Pigeon 2; leave this null to skip applying Pigeon 2 configs + private static final Pigeon2Configuration pigeonConfigs = null; + + // CAN bus that the devices are located on; + // All swerve devices must share the same CAN bus + public static final CANBus kCANBus = new CANBus("canivore", "./logs/example.hoot"); + + // Theoretical free speed (m/s) at 12 V applied output; + // This needs to be tuned to your individual robot + public static final LinearVelocity kSpeedAt12Volts = MetersPerSecond.of(4.54); + + // Every 1 rotation of the azimuth results in kCoupleRatio drive motor turns; + // This may need to be tuned to your individual robot + private static final double kCoupleRatio = 3.8181818181818183; + + private static final double kDriveGearRatio = 7.363636363636365; + private static final double kSteerGearRatio = 15.42857142857143; + private static final Distance kWheelRadius = Inches.of(2.167); + + private static final boolean kInvertLeftSide = false; + private static final boolean kInvertRightSide = true; + + private static final int kPigeonId = 1; + + // These are only used for simulation + private static final MomentOfInertia kSteerInertia = KilogramSquareMeters.of(0.01); + private static final MomentOfInertia kDriveInertia = KilogramSquareMeters.of(0.01); + // Simulated voltage necessary to overcome friction + private static final Voltage kSteerFrictionVoltage = Volts.of(0.2); + private static final Voltage kDriveFrictionVoltage = Volts.of(0.2); + + public static final SwerveDrivetrainConstants DrivetrainConstants = new SwerveDrivetrainConstants() + .withCANBusName(kCANBus.getName()) + .withPigeon2Id(kPigeonId) + .withPigeon2Configs(pigeonConfigs); + + private static final SwerveModuleConstantsFactory ConstantCreator = + new SwerveModuleConstantsFactory() + .withDriveMotorGearRatio(kDriveGearRatio) + .withSteerMotorGearRatio(kSteerGearRatio) + .withCouplingGearRatio(kCoupleRatio) + .withWheelRadius(kWheelRadius) + .withSteerMotorGains(steerGains) + .withDriveMotorGains(driveGains) + .withSteerMotorClosedLoopOutput(kSteerClosedLoopOutput) + .withDriveMotorClosedLoopOutput(kDriveClosedLoopOutput) + .withSlipCurrent(kSlipCurrent) + .withSpeedAt12Volts(kSpeedAt12Volts) + .withDriveMotorType(kDriveMotorType) + .withSteerMotorType(kSteerMotorType) + .withFeedbackSource(kSteerFeedbackType) + .withDriveMotorInitialConfigs(driveInitialConfigs) + .withSteerMotorInitialConfigs(steerInitialConfigs) + .withEncoderInitialConfigs(encoderInitialConfigs) + .withSteerInertia(kSteerInertia) + .withDriveInertia(kDriveInertia) + .withSteerFrictionVoltage(kSteerFrictionVoltage) + .withDriveFrictionVoltage(kDriveFrictionVoltage); + + + // Front Left + private static final int kFrontLeftDriveMotorId = 3; + private static final int kFrontLeftSteerMotorId = 2; + private static final int kFrontLeftEncoderId = 1; + private static final Angle kFrontLeftEncoderOffset = Rotations.of(0.15234375); + private static final boolean kFrontLeftSteerMotorInverted = true; + private static final boolean kFrontLeftEncoderInverted = false; + + private static final Distance kFrontLeftXPos = Inches.of(10); + private static final Distance kFrontLeftYPos = Inches.of(10); + + // Front Right + private static final int kFrontRightDriveMotorId = 1; + private static final int kFrontRightSteerMotorId = 0; + private static final int kFrontRightEncoderId = 0; + private static final Angle kFrontRightEncoderOffset = Rotations.of(-0.4873046875); + private static final boolean kFrontRightSteerMotorInverted = true; + private static final boolean kFrontRightEncoderInverted = false; + + private static final Distance kFrontRightXPos = Inches.of(10); + private static final Distance kFrontRightYPos = Inches.of(-10); + + // Back Left + private static final int kBackLeftDriveMotorId = 7; + private static final int kBackLeftSteerMotorId = 6; + private static final int kBackLeftEncoderId = 3; + private static final Angle kBackLeftEncoderOffset = Rotations.of(-0.219482421875); + private static final boolean kBackLeftSteerMotorInverted = true; + private static final boolean kBackLeftEncoderInverted = false; + + private static final Distance kBackLeftXPos = Inches.of(-10); + private static final Distance kBackLeftYPos = Inches.of(10); + + // Back Right + private static final int kBackRightDriveMotorId = 5; + private static final int kBackRightSteerMotorId = 4; + private static final int kBackRightEncoderId = 2; + private static final Angle kBackRightEncoderOffset = Rotations.of(0.17236328125); + private static final boolean kBackRightSteerMotorInverted = true; + private static final boolean kBackRightEncoderInverted = false; + + private static final Distance kBackRightXPos = Inches.of(-10); + private static final Distance kBackRightYPos = Inches.of(-10); + + + public static final SwerveModuleConstants FrontLeft = + ConstantCreator.createModuleConstants( + kFrontLeftSteerMotorId, kFrontLeftDriveMotorId, kFrontLeftEncoderId, kFrontLeftEncoderOffset, + kFrontLeftXPos, kFrontLeftYPos, kInvertLeftSide, kFrontLeftSteerMotorInverted, kFrontLeftEncoderInverted + ); + public static final SwerveModuleConstants FrontRight = + ConstantCreator.createModuleConstants( + kFrontRightSteerMotorId, kFrontRightDriveMotorId, kFrontRightEncoderId, kFrontRightEncoderOffset, + kFrontRightXPos, kFrontRightYPos, kInvertRightSide, kFrontRightSteerMotorInverted, kFrontRightEncoderInverted + ); + public static final SwerveModuleConstants BackLeft = + ConstantCreator.createModuleConstants( + kBackLeftSteerMotorId, kBackLeftDriveMotorId, kBackLeftEncoderId, kBackLeftEncoderOffset, + kBackLeftXPos, kBackLeftYPos, kInvertLeftSide, kBackLeftSteerMotorInverted, kBackLeftEncoderInverted + ); + public static final SwerveModuleConstants BackRight = + ConstantCreator.createModuleConstants( + kBackRightSteerMotorId, kBackRightDriveMotorId, kBackRightEncoderId, kBackRightEncoderOffset, + kBackRightXPos, kBackRightYPos, kInvertRightSide, kBackRightSteerMotorInverted, kBackRightEncoderInverted + ); + + /** + * Creates a CommandSwerveDrivetrain instance. + * This should only be called once in your robot program,. + */ + public static CommandSwerveDrivetrain createDrivetrain() { + return new CommandSwerveDrivetrain( + DrivetrainConstants, FrontLeft, FrontRight, BackLeft, BackRight + ); + } + + + /** + * Swerve Drive class utilizing CTR Electronics' Phoenix 6 API with the selected device types. + */ + public static class TunerSwerveDrivetrain extends SwerveDrivetrain { + /** + * Constructs a CTRE SwerveDrivetrain using the specified constants. + *

+ * This constructs the underlying hardware devices, so users should not construct + * the devices themselves. If they need the devices, they can access them through + * getters in the classes. + * + * @param drivetrainConstants Drivetrain-wide constants for the swerve drive + * @param modules Constants for each specific module + */ + public TunerSwerveDrivetrain( + SwerveDrivetrainConstants drivetrainConstants, + SwerveModuleConstants... modules + ) { + super( + TalonFX::new, TalonFX::new, CANcoder::new, + drivetrainConstants, modules + ); + } + + /** + * Constructs a CTRE SwerveDrivetrain using the specified constants. + *

+ * This constructs the underlying hardware devices, so users should not construct + * the devices themselves. If they need the devices, they can access them through + * getters in the classes. + * + * @param drivetrainConstants Drivetrain-wide constants for the swerve drive + * @param odometryUpdateFrequency The frequency to run the odometry loop. If + * unspecified or set to 0 Hz, this is 250 Hz on + * CAN FD, and 100 Hz on CAN 2.0. + * @param modules Constants for each specific module + */ + public TunerSwerveDrivetrain( + SwerveDrivetrainConstants drivetrainConstants, + double odometryUpdateFrequency, + SwerveModuleConstants... modules + ) { + super( + TalonFX::new, TalonFX::new, CANcoder::new, + drivetrainConstants, odometryUpdateFrequency, modules + ); + } + + /** + * Constructs a CTRE SwerveDrivetrain using the specified constants. + *

+ * This constructs the underlying hardware devices, so users should not construct + * the devices themselves. If they need the devices, they can access them through + * getters in the classes. + * + * @param drivetrainConstants Drivetrain-wide constants for the swerve drive + * @param odometryUpdateFrequency The frequency to run the odometry loop. If + * unspecified or set to 0 Hz, this is 250 Hz on + * CAN FD, and 100 Hz on CAN 2.0. + * @param odometryStandardDeviation The standard deviation for odometry calculation + * in the form [x, y, theta]ᵀ, with units in meters + * and radians + * @param visionStandardDeviation The standard deviation for vision calculation + * in the form [x, y, theta]ᵀ, with units in meters + * and radians + * @param modules Constants for each specific module + */ + public TunerSwerveDrivetrain( + SwerveDrivetrainConstants drivetrainConstants, + double odometryUpdateFrequency, + Matrix odometryStandardDeviation, + Matrix visionStandardDeviation, + SwerveModuleConstants... modules + ) { + super( + TalonFX::new, TalonFX::new, CANcoder::new, + drivetrainConstants, odometryUpdateFrequency, + odometryStandardDeviation, visionStandardDeviation, modules + ); + } + } +} diff --git a/java/SwerveWithPathPlanner/src/main/java/frc/robot/subsystems/CommandSwerveDrivetrain.java b/java/SwerveWithPathPlanner/src/main/java/frc/robot/subsystems/CommandSwerveDrivetrain.java index 03d0bd8b..a9341527 100644 --- a/java/SwerveWithPathPlanner/src/main/java/frc/robot/subsystems/CommandSwerveDrivetrain.java +++ b/java/SwerveWithPathPlanner/src/main/java/frc/robot/subsystems/CommandSwerveDrivetrain.java @@ -2,6 +2,7 @@ import static edu.wpi.first.units.Units.*; +import java.util.Optional; import java.util.function.Supplier; import com.ctre.phoenix6.SignalLogger; @@ -34,9 +35,12 @@ /** * Class that extends the Phoenix 6 SwerveDrivetrain class and implements * Subsystem so it can easily be used in command-based projects. + * + * Generated by the 2026 Tuner X Swerve Project Generator + * https://v6.docs.ctr-electronics.com/en/stable/docs/tuner/tuner-swerve/index.html */ public class CommandSwerveDrivetrain extends TunerSwerveDrivetrain implements Subsystem { - private static final double kSimLoopPeriod = 0.005; // 5 ms + private static final double kSimLoopPeriod = 0.004; // 4 ms private Notifier m_simNotifier = null; private double m_lastSimTime; @@ -124,8 +128,8 @@ public class CommandSwerveDrivetrain extends TunerSwerveDrivetrain implements Su * the devices themselves. If they need the devices, they can access them through * getters in the classes. * - * @param drivetrainConstants Drivetrain-wide constants for the swerve drive - * @param modules Constants for each specific module + * @param drivetrainConstants Drivetrain-wide constants for the swerve drive + * @param modules Constants for each specific module */ public CommandSwerveDrivetrain( SwerveDrivetrainConstants drivetrainConstants, @@ -145,11 +149,11 @@ public CommandSwerveDrivetrain( * the devices themselves. If they need the devices, they can access them through * getters in the classes. * - * @param drivetrainConstants Drivetrain-wide constants for the swerve drive - * @param odometryUpdateFrequency The frequency to run the odometry loop. If - * unspecified or set to 0 Hz, this is 250 Hz on - * CAN FD, and 100 Hz on CAN 2.0. - * @param modules Constants for each specific module + * @param drivetrainConstants Drivetrain-wide constants for the swerve drive + * @param odometryUpdateFrequency The frequency to run the odometry loop. If + * unspecified or set to 0 Hz, this is 250 Hz on + * CAN FD, and 100 Hz on CAN 2.0. + * @param modules Constants for each specific module */ public CommandSwerveDrivetrain( SwerveDrivetrainConstants drivetrainConstants, @@ -170,17 +174,17 @@ public CommandSwerveDrivetrain( * the devices themselves. If they need the devices, they can access them through * getters in the classes. * - * @param drivetrainConstants Drivetrain-wide constants for the swerve drive - * @param odometryUpdateFrequency The frequency to run the odometry loop. If - * unspecified or set to 0 Hz, this is 250 Hz on - * CAN FD, and 100 Hz on CAN 2.0. - * @param odometryStandardDeviation The standard deviation for odometry calculation + * @param drivetrainConstants Drivetrain-wide constants for the swerve drive + * @param odometryUpdateFrequency The frequency to run the odometry loop. If + * unspecified or set to 0 Hz, this is 250 Hz on + * CAN FD, and 100 Hz on CAN 2.0. + * @param odometryStandardDeviation The standard deviation for odometry calculation * in the form [x, y, theta]ᵀ, with units in meters * and radians * @param visionStandardDeviation The standard deviation for vision calculation * in the form [x, y, theta]ᵀ, with units in meters * and radians - * @param modules Constants for each specific module + * @param modules Constants for each specific module */ public CommandSwerveDrivetrain( SwerveDrivetrainConstants drivetrainConstants, @@ -231,8 +235,8 @@ private void configureAutoBuilder() { * @param request Function returning the request to apply * @return Command to run */ - public Command applyRequest(Supplier requestSupplier) { - return run(() -> this.setControl(requestSupplier.get())); + public Command applyRequest(Supplier request) { + return run(() -> this.setControl(request.get())); } /** @@ -326,4 +330,15 @@ public void addVisionMeasurement( ) { super.addVisionMeasurement(visionRobotPoseMeters, Utils.fpgaToCurrentTime(timestampSeconds), visionMeasurementStdDevs); } + + /** + * Return the pose at a given timestamp, if the buffer is not empty. + * + * @param timestampSeconds The timestamp of the pose in seconds. + * @return The pose at the given timestamp (or Optional.empty() if the buffer is empty). + */ + @Override + public Optional samplePoseAt(double timestampSeconds) { + return super.samplePoseAt(Utils.fpgaToCurrentTime(timestampSeconds)); + } } diff --git a/java/TalonFXSGadgeteer/.vscode/settings.json b/java/TalonFXSGadgeteer/.vscode/settings.json index 612cdd0d..5e6ede86 100644 --- a/java/TalonFXSGadgeteer/.vscode/settings.json +++ b/java/TalonFXSGadgeteer/.vscode/settings.json @@ -56,5 +56,6 @@ "edu.wpi.first.math.proto.*", "edu.wpi.first.math.**.proto.*", "edu.wpi.first.math.**.struct.*", - ] + ], + "java.dependency.enableDependencyCheckup": false } diff --git a/java/TalonFXSGadgeteer/WPILib-License.md b/java/TalonFXSGadgeteer/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/java/TalonFXSGadgeteer/WPILib-License.md +++ b/java/TalonFXSGadgeteer/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/java/TalonFXSGadgeteer/build.gradle b/java/TalonFXSGadgeteer/build.gradle index f3438298..e9b0020a 100644 --- a/java/TalonFXSGadgeteer/build.gradle +++ b/java/TalonFXSGadgeteer/build.gradle @@ -43,7 +43,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. @@ -88,7 +89,9 @@ wpi.sim.addDriverstation() // knows where to look for our Robot Class. jar { from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } - from sourceSets.main.allSource + from('src') { into 'backup/src' } + from('vendordeps') { into 'backup/vendordeps' } + from('build.gradle') { into 'backup' } manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) duplicatesStrategy = DuplicatesStrategy.INCLUDE } diff --git a/java/TalonFXSGadgeteer/settings.gradle b/java/TalonFXSGadgeteer/settings.gradle index c493958a..25f6f6e8 100644 --- a/java/TalonFXSGadgeteer/settings.gradle +++ b/java/TalonFXSGadgeteer/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') diff --git a/java/VelocityClosedLoop/.vscode/settings.json b/java/VelocityClosedLoop/.vscode/settings.json index 612cdd0d..5e6ede86 100644 --- a/java/VelocityClosedLoop/.vscode/settings.json +++ b/java/VelocityClosedLoop/.vscode/settings.json @@ -56,5 +56,6 @@ "edu.wpi.first.math.proto.*", "edu.wpi.first.math.**.proto.*", "edu.wpi.first.math.**.struct.*", - ] + ], + "java.dependency.enableDependencyCheckup": false } diff --git a/java/VelocityClosedLoop/WPILib-License.md b/java/VelocityClosedLoop/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/java/VelocityClosedLoop/WPILib-License.md +++ b/java/VelocityClosedLoop/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/java/VelocityClosedLoop/build.gradle b/java/VelocityClosedLoop/build.gradle index f3438298..e9b0020a 100644 --- a/java/VelocityClosedLoop/build.gradle +++ b/java/VelocityClosedLoop/build.gradle @@ -43,7 +43,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. @@ -88,7 +89,9 @@ wpi.sim.addDriverstation() // knows where to look for our Robot Class. jar { from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } - from sourceSets.main.allSource + from('src') { into 'backup/src' } + from('vendordeps') { into 'backup/vendordeps' } + from('build.gradle') { into 'backup' } manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) duplicatesStrategy = DuplicatesStrategy.INCLUDE } diff --git a/java/VelocityClosedLoop/settings.gradle b/java/VelocityClosedLoop/settings.gradle index c493958a..25f6f6e8 100644 --- a/java/VelocityClosedLoop/settings.gradle +++ b/java/VelocityClosedLoop/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') diff --git a/java/WaitForAll/.vscode/settings.json b/java/WaitForAll/.vscode/settings.json index 612cdd0d..5e6ede86 100644 --- a/java/WaitForAll/.vscode/settings.json +++ b/java/WaitForAll/.vscode/settings.json @@ -56,5 +56,6 @@ "edu.wpi.first.math.proto.*", "edu.wpi.first.math.**.proto.*", "edu.wpi.first.math.**.struct.*", - ] + ], + "java.dependency.enableDependencyCheckup": false } diff --git a/java/WaitForAll/WPILib-License.md b/java/WaitForAll/WPILib-License.md index 645e5425..eb3061b0 100644 --- a/java/WaitForAll/WPILib-License.md +++ b/java/WaitForAll/WPILib-License.md @@ -1,4 +1,4 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors +Copyright (c) 2009-2026 FIRST and other WPILib contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/java/WaitForAll/build.gradle b/java/WaitForAll/build.gradle index f3438298..e9b0020a 100644 --- a/java/WaitForAll/build.gradle +++ b/java/WaitForAll/build.gradle @@ -43,7 +43,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. @@ -88,7 +89,9 @@ wpi.sim.addDriverstation() // knows where to look for our Robot Class. jar { from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } - from sourceSets.main.allSource + from('src') { into 'backup/src' } + from('vendordeps') { into 'backup/vendordeps' } + from('build.gradle') { into 'backup' } manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) duplicatesStrategy = DuplicatesStrategy.INCLUDE } diff --git a/java/WaitForAll/settings.gradle b/java/WaitForAll/settings.gradle index c493958a..25f6f6e8 100644 --- a/java/WaitForAll/settings.gradle +++ b/java/WaitForAll/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') diff --git a/python/ArcadeDrive/pyproject.toml b/python/ArcadeDrive/pyproject.toml index a4f083ae..9735d7ee 100644 --- a/python/ArcadeDrive/pyproject.toml +++ b/python/ArcadeDrive/pyproject.toml @@ -8,25 +8,25 @@ # Version of robotpy this project depends on robotpy_version = "2026.1.1b1" -# Which extra RobotPy components should be installed +# Which core WPILib components should be installed # -> equivalent to `pip install robotpy[extra1, ...] components = [ # "all", # "apriltag", "commands2", # "cscore", - # "navx", -] - -# Other pip packages to install -requires = [ - "phoenix6~=26.1.0", - # "pathplannerlib", - # "phoenix5", - # "photonvision", - # "playingwithfusion", - # "rev", # "romi", # "sim", # "xrp", ] + +# Other pip packages to install (including vendor packages) +requires = [ + "phoenix6~=26.1", + # "photonlibpy", + # "robotpy-ctre", # Phoenix 5 + # "robotpy-navx", + # "robotpy-pathplannerlib", + # "robotpy-playingwithfusion", + # "robotpy-rev", +] diff --git a/python/CANcoder/pyproject.toml b/python/CANcoder/pyproject.toml index a4f083ae..9735d7ee 100644 --- a/python/CANcoder/pyproject.toml +++ b/python/CANcoder/pyproject.toml @@ -8,25 +8,25 @@ # Version of robotpy this project depends on robotpy_version = "2026.1.1b1" -# Which extra RobotPy components should be installed +# Which core WPILib components should be installed # -> equivalent to `pip install robotpy[extra1, ...] components = [ # "all", # "apriltag", "commands2", # "cscore", - # "navx", -] - -# Other pip packages to install -requires = [ - "phoenix6~=26.1.0", - # "pathplannerlib", - # "phoenix5", - # "photonvision", - # "playingwithfusion", - # "rev", # "romi", # "sim", # "xrp", ] + +# Other pip packages to install (including vendor packages) +requires = [ + "phoenix6~=26.1", + # "photonlibpy", + # "robotpy-ctre", # Phoenix 5 + # "robotpy-navx", + # "robotpy-pathplannerlib", + # "robotpy-playingwithfusion", + # "robotpy-rev", +] diff --git a/python/CANdi/pyproject.toml b/python/CANdi/pyproject.toml index a4f083ae..9735d7ee 100644 --- a/python/CANdi/pyproject.toml +++ b/python/CANdi/pyproject.toml @@ -8,25 +8,25 @@ # Version of robotpy this project depends on robotpy_version = "2026.1.1b1" -# Which extra RobotPy components should be installed +# Which core WPILib components should be installed # -> equivalent to `pip install robotpy[extra1, ...] components = [ # "all", # "apriltag", "commands2", # "cscore", - # "navx", -] - -# Other pip packages to install -requires = [ - "phoenix6~=26.1.0", - # "pathplannerlib", - # "phoenix5", - # "photonvision", - # "playingwithfusion", - # "rev", # "romi", # "sim", # "xrp", ] + +# Other pip packages to install (including vendor packages) +requires = [ + "phoenix6~=26.1", + # "photonlibpy", + # "robotpy-ctre", # Phoenix 5 + # "robotpy-navx", + # "robotpy-pathplannerlib", + # "robotpy-playingwithfusion", + # "robotpy-rev", +] diff --git a/python/CANdle/pyproject.toml b/python/CANdle/pyproject.toml index a4f083ae..9735d7ee 100644 --- a/python/CANdle/pyproject.toml +++ b/python/CANdle/pyproject.toml @@ -8,25 +8,25 @@ # Version of robotpy this project depends on robotpy_version = "2026.1.1b1" -# Which extra RobotPy components should be installed +# Which core WPILib components should be installed # -> equivalent to `pip install robotpy[extra1, ...] components = [ # "all", # "apriltag", "commands2", # "cscore", - # "navx", -] - -# Other pip packages to install -requires = [ - "phoenix6~=26.1.0", - # "pathplannerlib", - # "phoenix5", - # "photonvision", - # "playingwithfusion", - # "rev", # "romi", # "sim", # "xrp", ] + +# Other pip packages to install (including vendor packages) +requires = [ + "phoenix6~=26.1", + # "photonlibpy", + # "robotpy-ctre", # Phoenix 5 + # "robotpy-navx", + # "robotpy-pathplannerlib", + # "robotpy-playingwithfusion", + # "robotpy-rev", +] diff --git a/python/CANrange/pyproject.toml b/python/CANrange/pyproject.toml index a4f083ae..9735d7ee 100644 --- a/python/CANrange/pyproject.toml +++ b/python/CANrange/pyproject.toml @@ -8,25 +8,25 @@ # Version of robotpy this project depends on robotpy_version = "2026.1.1b1" -# Which extra RobotPy components should be installed +# Which core WPILib components should be installed # -> equivalent to `pip install robotpy[extra1, ...] components = [ # "all", # "apriltag", "commands2", # "cscore", - # "navx", -] - -# Other pip packages to install -requires = [ - "phoenix6~=26.1.0", - # "pathplannerlib", - # "phoenix5", - # "photonvision", - # "playingwithfusion", - # "rev", # "romi", # "sim", # "xrp", ] + +# Other pip packages to install (including vendor packages) +requires = [ + "phoenix6~=26.1", + # "photonlibpy", + # "robotpy-ctre", # Phoenix 5 + # "robotpy-navx", + # "robotpy-pathplannerlib", + # "robotpy-playingwithfusion", + # "robotpy-rev", +] diff --git a/python/MotionMagic/pyproject.toml b/python/MotionMagic/pyproject.toml index a4f083ae..9735d7ee 100644 --- a/python/MotionMagic/pyproject.toml +++ b/python/MotionMagic/pyproject.toml @@ -8,25 +8,25 @@ # Version of robotpy this project depends on robotpy_version = "2026.1.1b1" -# Which extra RobotPy components should be installed +# Which core WPILib components should be installed # -> equivalent to `pip install robotpy[extra1, ...] components = [ # "all", # "apriltag", "commands2", # "cscore", - # "navx", -] - -# Other pip packages to install -requires = [ - "phoenix6~=26.1.0", - # "pathplannerlib", - # "phoenix5", - # "photonvision", - # "playingwithfusion", - # "rev", # "romi", # "sim", # "xrp", ] + +# Other pip packages to install (including vendor packages) +requires = [ + "phoenix6~=26.1", + # "photonlibpy", + # "robotpy-ctre", # Phoenix 5 + # "robotpy-navx", + # "robotpy-pathplannerlib", + # "robotpy-playingwithfusion", + # "robotpy-rev", +] diff --git a/python/PhoenixSysId/pyproject.toml b/python/PhoenixSysId/pyproject.toml index a4f083ae..9735d7ee 100644 --- a/python/PhoenixSysId/pyproject.toml +++ b/python/PhoenixSysId/pyproject.toml @@ -8,25 +8,25 @@ # Version of robotpy this project depends on robotpy_version = "2026.1.1b1" -# Which extra RobotPy components should be installed +# Which core WPILib components should be installed # -> equivalent to `pip install robotpy[extra1, ...] components = [ # "all", # "apriltag", "commands2", # "cscore", - # "navx", -] - -# Other pip packages to install -requires = [ - "phoenix6~=26.1.0", - # "pathplannerlib", - # "phoenix5", - # "photonvision", - # "playingwithfusion", - # "rev", # "romi", # "sim", # "xrp", ] + +# Other pip packages to install (including vendor packages) +requires = [ + "phoenix6~=26.1", + # "photonlibpy", + # "robotpy-ctre", # Phoenix 5 + # "robotpy-navx", + # "robotpy-pathplannerlib", + # "robotpy-playingwithfusion", + # "robotpy-rev", +] diff --git a/python/PositionClosedLoop/pyproject.toml b/python/PositionClosedLoop/pyproject.toml index a4f083ae..9735d7ee 100644 --- a/python/PositionClosedLoop/pyproject.toml +++ b/python/PositionClosedLoop/pyproject.toml @@ -8,25 +8,25 @@ # Version of robotpy this project depends on robotpy_version = "2026.1.1b1" -# Which extra RobotPy components should be installed +# Which core WPILib components should be installed # -> equivalent to `pip install robotpy[extra1, ...] components = [ # "all", # "apriltag", "commands2", # "cscore", - # "navx", -] - -# Other pip packages to install -requires = [ - "phoenix6~=26.1.0", - # "pathplannerlib", - # "phoenix5", - # "photonvision", - # "playingwithfusion", - # "rev", # "romi", # "sim", # "xrp", ] + +# Other pip packages to install (including vendor packages) +requires = [ + "phoenix6~=26.1", + # "photonlibpy", + # "robotpy-ctre", # Phoenix 5 + # "robotpy-navx", + # "robotpy-pathplannerlib", + # "robotpy-playingwithfusion", + # "robotpy-rev", +] diff --git a/python/StatusSignals/pyproject.toml b/python/StatusSignals/pyproject.toml index a4f083ae..9735d7ee 100644 --- a/python/StatusSignals/pyproject.toml +++ b/python/StatusSignals/pyproject.toml @@ -8,25 +8,25 @@ # Version of robotpy this project depends on robotpy_version = "2026.1.1b1" -# Which extra RobotPy components should be installed +# Which core WPILib components should be installed # -> equivalent to `pip install robotpy[extra1, ...] components = [ # "all", # "apriltag", "commands2", # "cscore", - # "navx", -] - -# Other pip packages to install -requires = [ - "phoenix6~=26.1.0", - # "pathplannerlib", - # "phoenix5", - # "photonvision", - # "playingwithfusion", - # "rev", # "romi", # "sim", # "xrp", ] + +# Other pip packages to install (including vendor packages) +requires = [ + "phoenix6~=26.1", + # "photonlibpy", + # "robotpy-ctre", # Phoenix 5 + # "robotpy-navx", + # "robotpy-pathplannerlib", + # "robotpy-playingwithfusion", + # "robotpy-rev", +] diff --git a/python/SwerveWithPathPlanner/generated/tuner_constants.py b/python/SwerveWithPathPlanner/generated/tuner_constants.py index b2e27fad..f6aa280e 100644 --- a/python/SwerveWithPathPlanner/generated/tuner_constants.py +++ b/python/SwerveWithPathPlanner/generated/tuner_constants.py @@ -1,11 +1,14 @@ +from typing import TYPE_CHECKING, overload from phoenix6 import CANBus, configs, hardware, signals, swerve, units -from subsystems.command_swerve_drivetrain import CommandSwerveDrivetrain from wpimath.units import inchesToMeters +if TYPE_CHECKING: + from subsystems.command_swerve_drivetrain import CommandSwerveDrivetrain + class TunerConstants: """ - Generated by the Tuner X Swerve Project Generator + Generated by the 2026 Tuner X Swerve Project Generator https://v6.docs.ctr-electronics.com/en/stable/docs/tuner/tuner-swerve/index.html """ @@ -21,7 +24,9 @@ class TunerConstants: .with_k_s(0.1) .with_k_v(1.91) .with_k_a(0) - .with_static_feedforward_sign(signals.StaticFeedforwardSignValue.USE_CLOSED_LOOP_SIGN) + .with_static_feedforward_sign( + signals.StaticFeedforwardSignValue.USE_CLOSED_LOOP_SIGN + ) ) # When using closed-loop control, the drive motor uses the control # output type specified by SwerveModuleConstants.DriveMotorClosedLoopOutput @@ -61,7 +66,8 @@ class TunerConstants: configs.CurrentLimitsConfigs() # Swerve azimuth does not require much torque output, so we can set a relatively low # stator current limit to help avoid brownouts without impacting performance. - .with_stator_current_limit(60.0).with_stator_current_limit_enable(True) + .with_stator_current_limit(60.0) + .with_stator_current_limit_enable(True) ) _encoder_initial_configs = configs.CANcoderConfiguration() # Configs for the Pigeon 2; leave this None to skip applying Pigeon 2 configs @@ -102,7 +108,11 @@ class TunerConstants: .with_pigeon2_configs(_pigeon_configs) ) - _constants_creator: swerve.SwerveModuleConstantsFactory[configs.TalonFXConfiguration, configs.TalonFXConfiguration, configs.CANcoderConfiguration] = ( + _constants_creator: swerve.SwerveModuleConstantsFactory[ + configs.TalonFXConfiguration, + configs.TalonFXConfiguration, + configs.CANcoderConfiguration, + ] = ( swerve.SwerveModuleConstantsFactory() .with_drive_motor_gear_ratio(_drive_gear_ratio) .with_steer_motor_gear_ratio(_steer_gear_ratio) @@ -218,15 +228,14 @@ class TunerConstants: ) @classmethod - def create_drivetrain(cls) -> CommandSwerveDrivetrain: + def create_drivetrain(cls) -> "CommandSwerveDrivetrain": """ Creates a CommandSwerveDrivetrain instance. This should only be called once in your robot program. """ + from subsystems.command_swerve_drivetrain import CommandSwerveDrivetrain + return CommandSwerveDrivetrain( - hardware.TalonFX, - hardware.TalonFX, - hardware.CANcoder, cls.drivetrain_constants, [ cls.front_left, @@ -235,3 +244,123 @@ def create_drivetrain(cls) -> CommandSwerveDrivetrain: cls.back_right, ], ) + + +class TunerSwerveDrivetrain( + swerve.SwerveDrivetrain[hardware.TalonFX, hardware.TalonFX, hardware.CANcoder] +): + """Swerve Drive class utilizing CTR Electronics' Phoenix 6 API with the selected device types.""" + + @overload + def __init__( + self, + drivetrain_constants: swerve.SwerveDrivetrainConstants, + modules: list[swerve.SwerveModuleConstants], + /, + ) -> None: + """ + Constructs a CTRE SwerveDrivetrain using the specified constants. + + This constructs the underlying hardware devices, so users should not construct + the devices themselves. If they need the devices, they can access them through + getters in the classes. + + :param drivetrain_constants: Drivetrain-wide constants for the swerve drive + :type drivetrain_constants: swerve.SwerveDrivetrainConstants + :param modules: Constants for each specific module + :type modules: list[swerve.SwerveModuleConstants] + """ + ... + + @overload + def __init__( + self, + drivetrain_constants: swerve.SwerveDrivetrainConstants, + odometry_update_frequency: units.hertz, + modules: list[swerve.SwerveModuleConstants], + /, + ) -> None: + """ + Constructs a CTRE SwerveDrivetrain using the specified constants. + + This constructs the underlying hardware devices, so users should not construct + the devices themselves. If they need the devices, they can access them through + getters in the classes. + + :param drivetrain_constants: Drivetrain-wide constants for the swerve drive + :type drivetrain_constants: swerve.SwerveDrivetrainConstants + :param odometry_update_frequency: The frequency to run the odometry loop. If + unspecified or set to 0 Hz, this is 250 Hz on + CAN FD, and 100 Hz on CAN 2.0. + :type odometry_update_frequency: units.hertz + :param modules: Constants for each specific module + :type modules: list[swerve.SwerveModuleConstants] + """ + ... + + @overload + def __init__( + self, + drivetrain_constants: swerve.SwerveDrivetrainConstants, + odometry_update_frequency: units.hertz, + odometry_standard_deviation: tuple[float, float, float], + vision_standard_deviation: tuple[float, float, float], + modules: list[swerve.SwerveModuleConstants], + /, + ) -> None: + """ + Constructs a CTRE SwerveDrivetrain using the specified constants. + + This constructs the underlying hardware devices, so users should not construct + the devices themselves. If they need the devices, they can access them through + getters in the classes. + + :param drivetrain_constants: Drivetrain-wide constants for the swerve drive + :type drivetrain_constants: swerve.SwerveDrivetrainConstants + :param odometry_update_frequency: The frequency to run the odometry loop. If + unspecified or set to 0 Hz, this is 250 Hz on + CAN FD, and 100 Hz on CAN 2.0. + :type odometry_update_frequency: units.hertz + :param odometry_standard_deviation: The standard deviation for odometry calculation + in the form [x, y, theta]ᵀ, with units in meters + and radians + :type odometry_standard_deviation: tuple[float, float, float] + :param vision_standard_deviation: The standard deviation for vision calculation + in the form [x, y, theta]ᵀ, with units in meters + and radians + :type vision_standard_deviation: tuple[float, float, float] + :param modules: Constants for each specific module + :type modules: list[swerve.SwerveModuleConstants] + """ + ... + + @overload + def __init__( + self, + drivetrain_constants: swerve.SwerveDrivetrainConstants, + arg0: None, + arg1: None, + arg2: None, + arg3: None, + /, + ) -> None: ... + + def __init__( + self, + drivetrain_constants: swerve.SwerveDrivetrainConstants, + arg0=None, + arg1=None, + arg2=None, + arg3=None, + ): + swerve.SwerveDrivetrain.__init__( + self, + hardware.TalonFX, + hardware.TalonFX, + hardware.CANcoder, + drivetrain_constants, + arg0, + arg1, + arg2, + arg3, + ) diff --git a/python/SwerveWithPathPlanner/pyproject.toml b/python/SwerveWithPathPlanner/pyproject.toml index a4f083ae..0184575a 100644 --- a/python/SwerveWithPathPlanner/pyproject.toml +++ b/python/SwerveWithPathPlanner/pyproject.toml @@ -8,25 +8,25 @@ # Version of robotpy this project depends on robotpy_version = "2026.1.1b1" -# Which extra RobotPy components should be installed +# Which core WPILib components should be installed # -> equivalent to `pip install robotpy[extra1, ...] components = [ # "all", # "apriltag", "commands2", # "cscore", - # "navx", -] - -# Other pip packages to install -requires = [ - "phoenix6~=26.1.0", - # "pathplannerlib", - # "phoenix5", - # "photonvision", - # "playingwithfusion", - # "rev", # "romi", # "sim", # "xrp", ] + +# Other pip packages to install (including vendor packages) +requires = [ + "phoenix6~=26.1", + # "photonlibpy", + # "robotpy-ctre", # Phoenix 5 + # "robotpy-navx", + "robotpy-pathplannerlib", + # "robotpy-playingwithfusion", + # "robotpy-rev", +] diff --git a/python/SwerveWithPathPlanner/robot.py b/python/SwerveWithPathPlanner/robot.py index 7d0b41a6..aae35829 100644 --- a/python/SwerveWithPathPlanner/robot.py +++ b/python/SwerveWithPathPlanner/robot.py @@ -11,6 +11,8 @@ from robotcontainer import RobotContainer +from phoenix6 import HootAutoReplay + class MyRobot(commands2.TimedCommandRobot): """ @@ -30,6 +32,13 @@ def robotInit(self) -> None: # autonomous chooser on the dashboard. self.container = RobotContainer() + # log and replay timestamp and joystick data + self._time_and_joystick_replay = ( + HootAutoReplay() + .with_timestamp_replay() + .with_joystick_replay() + ) + def robotPeriodic(self) -> None: """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. @@ -37,6 +46,7 @@ def robotPeriodic(self) -> None: This runs after the mode specific periodic functions, but before LiveWindow and SmartDashboard integrated updating.""" + self._time_and_joystick_replay.update() # 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 @@ -56,7 +66,7 @@ def autonomousInit(self) -> None: self.autonomousCommand = self.container.getAutonomousCommand() if self.autonomousCommand: - self.autonomousCommand.schedule() + commands2.CommandScheduler.getInstance().schedule(self.autonomousCommand) def autonomousPeriodic(self) -> None: """This function is called periodically during autonomous""" @@ -68,7 +78,7 @@ def teleopInit(self) -> None: # continue until interrupted by another command, remove # this line or comment it out. if self.autonomousCommand: - self.autonomousCommand.cancel() + commands2.CommandScheduler.getInstance().cancel(self.autonomousCommand) def teleopPeriodic(self) -> None: """This function is called periodically during operator control""" diff --git a/python/SwerveWithPathPlanner/robotcontainer.py b/python/SwerveWithPathPlanner/robotcontainer.py index ab189851..d5c517d9 100644 --- a/python/SwerveWithPathPlanner/robotcontainer.py +++ b/python/SwerveWithPathPlanner/robotcontainer.py @@ -5,7 +5,7 @@ # import commands2 -import commands2.cmd +from commands2 import cmd from commands2.button import CommandXboxController, Trigger from commands2.sysid import SysIdRoutine @@ -29,7 +29,7 @@ class RobotContainer: def __init__(self) -> None: self._max_speed = ( - TunerConstants.speed_at_12_volts + 1.0 * TunerConstants.speed_at_12_volts ) # speed_at_12_volts desired top speed self._max_angular_rate = rotationsToRadians( 0.75 @@ -110,12 +110,12 @@ def configureButtonBindings(self) -> None: ) ) - self._joystick.pov(0).whileTrue( + self._joystick.povUp().whileTrue( self.drivetrain.apply_request( lambda: self._forward_straight.with_velocity_x(0.5).with_velocity_y(0) ) ) - self._joystick.pov(180).whileTrue( + self._joystick.povDown().whileTrue( self.drivetrain.apply_request( lambda: self._forward_straight.with_velocity_x(-0.5).with_velocity_y(0) ) @@ -138,7 +138,7 @@ def configureButtonBindings(self) -> None: # reset the field-centric heading on left bumper press self._joystick.leftBumper().onTrue( - self.drivetrain.runOnce(lambda: self.drivetrain.seed_field_centric()) + self.drivetrain.runOnce(self.drivetrain.seed_field_centric) ) self.drivetrain.register_telemetry( @@ -146,7 +146,8 @@ def configureButtonBindings(self) -> None: ) def getAutonomousCommand(self) -> commands2.Command: - """Use this to pass the autonomous command to the main {@link Robot} class. + """ + Use this to pass the autonomous command to the main {@link Robot} class. :returns: the command to run in autonomous """ diff --git a/python/SwerveWithPathPlanner/subsystems/command_swerve_drivetrain.py b/python/SwerveWithPathPlanner/subsystems/command_swerve_drivetrain.py index 4000fe8c..c531cab9 100644 --- a/python/SwerveWithPathPlanner/subsystems/command_swerve_drivetrain.py +++ b/python/SwerveWithPathPlanner/subsystems/command_swerve_drivetrain.py @@ -10,14 +10,19 @@ from wpimath.geometry import Pose2d, Rotation2d from wpimath.kinematics import ChassisSpeeds +from generated.tuner_constants import TunerSwerveDrivetrain -class CommandSwerveDrivetrain(Subsystem, swerve.SwerveDrivetrain): + +class CommandSwerveDrivetrain(Subsystem, TunerSwerveDrivetrain): """ Class that extends the Phoenix 6 SwerveDrivetrain class and implements Subsystem so it can easily be used in command-based projects. + + Generated by the 2026 Tuner X Swerve Project Generator + https://v6.docs.ctr-electronics.com/en/stable/docs/tuner/tuner-swerve/index.html """ - _SIM_LOOP_PERIOD: units.second = 0.005 + _SIM_LOOP_PERIOD: units.second = 0.004 # 4 ms _BLUE_ALLIANCE_PERSPECTIVE_ROTATION = Rotation2d.fromDegrees(0) """Blue alliance sees forward as 0 degrees (toward red alliance wall)""" @@ -27,11 +32,9 @@ class CommandSwerveDrivetrain(Subsystem, swerve.SwerveDrivetrain): @overload def __init__( self, - drive_motor_type: type, - steer_motor_type: type, - encoder_type: type, drivetrain_constants: swerve.SwerveDrivetrainConstants, modules: list[swerve.SwerveModuleConstants], + /, ) -> None: """ Constructs a CTRE SwerveDrivetrain using the specified constants. @@ -40,12 +43,6 @@ def __init__( the devices themselves. If they need the devices, they can access them through getters in the classes. - :param drive_motor_type: Type of the drive motor - :type drive_motor_type: type - :param steer_motor_type: Type of the steer motor - :type steer_motor_type: type - :param encoder_type: Type of the azimuth encoder - :type encoder_type: type :param drivetrain_constants: Drivetrain-wide constants for the swerve drive :type drivetrain_constants: swerve.SwerveDrivetrainConstants :param modules: Constants for each specific module @@ -56,12 +53,10 @@ def __init__( @overload def __init__( self, - drive_motor_type: type, - steer_motor_type: type, - encoder_type: type, drivetrain_constants: swerve.SwerveDrivetrainConstants, odometry_update_frequency: units.hertz, modules: list[swerve.SwerveModuleConstants], + /, ) -> None: """ Constructs a CTRE SwerveDrivetrain using the specified constants. @@ -70,12 +65,6 @@ def __init__( the devices themselves. If they need the devices, they can access them through getters in the classes. - :param drive_motor_type: Type of the drive motor - :type drive_motor_type: type - :param steer_motor_type: Type of the steer motor - :type steer_motor_type: type - :param encoder_type: Type of the azimuth encoder - :type encoder_type: type :param drivetrain_constants: Drivetrain-wide constants for the swerve drive :type drivetrain_constants: swerve.SwerveDrivetrainConstants :param odometry_update_frequency: The frequency to run the odometry loop. If @@ -90,14 +79,12 @@ def __init__( @overload def __init__( self, - drive_motor_type: type, - steer_motor_type: type, - encoder_type: type, drivetrain_constants: swerve.SwerveDrivetrainConstants, odometry_update_frequency: units.hertz, odometry_standard_deviation: tuple[float, float, float], vision_standard_deviation: tuple[float, float, float], modules: list[swerve.SwerveModuleConstants], + /, ) -> None: """ Constructs a CTRE SwerveDrivetrain using the specified constants. @@ -106,12 +93,6 @@ def __init__( the devices themselves. If they need the devices, they can access them through getters in the classes. - :param drive_motor_type: Type of the drive motor - :type drive_motor_type: type - :param steer_motor_type: Type of the steer motor - :type steer_motor_type: type - :param encoder_type: Type of the azimuth encoder - :type encoder_type: type :param drivetrain_constants: Drivetrain-wide constants for the swerve drive :type drivetrain_constants: swerve.SwerveDrivetrainConstants :param odometry_update_frequency: The frequency to run the odometry loop. If @@ -131,11 +112,19 @@ def __init__( """ ... + @overload + def __init__( + self, + drivetrain_constants: swerve.SwerveDrivetrainConstants, + arg0: None, + arg1: None, + arg2: None, + arg3: None, + /, + ) -> None: ... + def __init__( self, - drive_motor_type: type, - steer_motor_type: type, - encoder_type: type, drivetrain_constants: swerve.SwerveDrivetrainConstants, arg0=None, arg1=None, @@ -143,9 +132,8 @@ def __init__( arg3=None, ): Subsystem.__init__(self) - swerve.SwerveDrivetrain.__init__( - self, drive_motor_type, steer_motor_type, encoder_type, - drivetrain_constants, arg0, arg1, arg2, arg3 + TunerSwerveDrivetrain.__init__( + self, drivetrain_constants, arg0, arg1, arg2, arg3 ) self._sim_notifier: Notifier | None = None @@ -170,7 +158,8 @@ def __init__( # Log state with SignalLogger class recordState=lambda state: SignalLogger.write_string( "SysIdTranslation_State", SysIdRoutineLog.stateEnumToString(state) - ), + ) + and None, ), SysIdRoutine.Mechanism( lambda output: self.set_control( @@ -190,7 +179,8 @@ def __init__( # Log state with SignalLogger class recordState=lambda state: SignalLogger.write_string( "SysIdSteer_State", SysIdRoutineLog.stateEnumToString(state) - ), + ) + and None, ), SysIdRoutine.Mechanism( lambda output: self.set_control( @@ -212,7 +202,8 @@ def __init__( # Log state with SignalLogger class recordState=lambda state: SignalLogger.write_string( "SysIdSteer_State", SysIdRoutineLog.stateEnumToString(state) - ), + ) + and None, ), SysIdRoutine.Mechanism( lambda output: ( @@ -222,7 +213,8 @@ def __init__( ), # also log the requested output for SysId SignalLogger.write_double("Rotational_Rate", output), - ), + ) + and None, lambda log: None, self, ), @@ -327,11 +319,17 @@ def _sim_periodic(): # use the measured time delta, get battery voltage from WPILib self.update_sim_state(delta_time, RobotController.getBatteryVoltage()) + # Run simulation at a faster rate so PID gains behave more reasonably self._last_sim_time = utils.get_current_time_seconds() self._sim_notifier = Notifier(_sim_periodic) self._sim_notifier.startPeriodic(self._SIM_LOOP_PERIOD) - def add_vision_measurement(self, vision_robot_pose: Pose2d, timestamp: units.second, vision_measurement_std_devs: tuple[float, float, float] | None = None): + def add_vision_measurement( + self, + vision_robot_pose: Pose2d, + timestamp: units.second, + vision_measurement_std_devs: tuple[float, float, float] | None = None, + ): """ Adds a vision measurement to the Kalman Filter. This will correct the odometry pose estimate while still accounting for measurement noise. @@ -349,4 +347,20 @@ def add_vision_measurement(self, vision_robot_pose: Pose2d, timestamp: units.sec and radians. :type vision_measurement_std_devs: tuple[float, float, float] | None """ - swerve.SwerveDrivetrain.add_vision_measurement(self, vision_robot_pose, utils.fpga_to_current_time(timestamp), vision_measurement_std_devs) + TunerSwerveDrivetrain.add_vision_measurement( + self, + vision_robot_pose, + utils.fpga_to_current_time(timestamp), + vision_measurement_std_devs + ) + + def sample_pose_at(self, timestamp: units.second) -> Pose2d | None: + """ + Return the pose at a given timestamp, if the buffer is not empty. + + :param timestamp: The timestamp of the pose in seconds. + :type timestamp: second + :returns: The pose at the given timestamp (or None if the buffer is empty). + :rtype: Pose2d | None + """ + return TunerSwerveDrivetrain.sample_pose_at(self, utils.fpga_to_current_time(timestamp)) diff --git a/python/SwerveWithPathPlanner/telemetry.py b/python/SwerveWithPathPlanner/telemetry.py index b705d661..bd916b76 100644 --- a/python/SwerveWithPathPlanner/telemetry.py +++ b/python/SwerveWithPathPlanner/telemetry.py @@ -4,6 +4,7 @@ from wpimath.geometry import Pose2d from wpimath.kinematics import ChassisSpeeds, SwerveModulePosition, SwerveModuleState + class Telemetry: def __init__(self, max_speed: units.meters_per_second): """ @@ -71,6 +72,10 @@ def __init__(self, max_speed: units.meters_per_second): .appendLigament("Direction", 0.1, 0, 0, Color8Bit(Color.kWhite)), ] + # Set up the module state Mechanism2d telemetry + for i, module_mechanism in enumerate(self._module_mechanisms): + SmartDashboard.putData(f"Module {i}", module_mechanism) + def telemeterize(self, state: swerve.SwerveDrivetrain.SwerveDriveState): """ Accept the swerve drive state and telemeterize it to SmartDashboard and SignalLogger. @@ -85,19 +90,16 @@ def telemeterize(self, state: swerve.SwerveDrivetrain.SwerveDriveState): self._drive_odometry_frequency.set(1.0 / state.odometry_period) # Also write to log file - pose_array = [state.pose.x, state.pose.y, state.pose.rotation().degrees()] - module_states_array = [] - module_targets_array = [] - for i in range(4): - module_states_array.append(state.module_states[i].angle.radians()) - module_states_array.append(state.module_states[i].speed) - module_targets_array.append(state.module_targets[i].angle.radians()) - module_targets_array.append(state.module_targets[i].speed) - - SignalLogger.write_double_array("DriveState/Pose", pose_array) - SignalLogger.write_double_array("DriveState/ModuleStates", module_states_array) - SignalLogger.write_double_array( - "DriveState/ModuleTargets", module_targets_array + SignalLogger.write_struct("DriveState/Pose", Pose2d, state.pose) + SignalLogger.write_struct("DriveState/Speeds", ChassisSpeeds, state.speeds) + SignalLogger.write_struct_array( + "DriveState/ModuleStates", SwerveModuleState, state.module_states + ) + SignalLogger.write_struct_array( + "DriveState/ModuleTargets", SwerveModuleState, state.module_targets + ) + SignalLogger.write_struct_array( + "DriveState/ModulePositions", SwerveModulePosition, state.module_positions ) SignalLogger.write_double( "DriveState/OdometryPeriod", state.odometry_period, "seconds" @@ -105,12 +107,12 @@ def telemeterize(self, state: swerve.SwerveDrivetrain.SwerveDriveState): # Telemeterize the pose to a Field2d self._field_type_pub.set("Field2d") + + pose_array = [state.pose.x, state.pose.y, state.pose.rotation().degrees()] self._field_pub.set(pose_array) - # Telemeterize the module states to a Mechanism2d + # Telemeterize each module state to a Mechanism2d for i, module_state in enumerate(state.module_states): self._module_speeds[i].setAngle(module_state.angle.degrees()) self._module_directions[i].setAngle(module_state.angle.degrees()) self._module_speeds[i].setLength(module_state.speed / (2 * self._max_speed)) - - SmartDashboard.putData(f"Module {i}", self._module_mechanisms[i]) diff --git a/python/TalonFX/pyproject.toml b/python/TalonFX/pyproject.toml index a4f083ae..9735d7ee 100644 --- a/python/TalonFX/pyproject.toml +++ b/python/TalonFX/pyproject.toml @@ -8,25 +8,25 @@ # Version of robotpy this project depends on robotpy_version = "2026.1.1b1" -# Which extra RobotPy components should be installed +# Which core WPILib components should be installed # -> equivalent to `pip install robotpy[extra1, ...] components = [ # "all", # "apriltag", "commands2", # "cscore", - # "navx", -] - -# Other pip packages to install -requires = [ - "phoenix6~=26.1.0", - # "pathplannerlib", - # "phoenix5", - # "photonvision", - # "playingwithfusion", - # "rev", # "romi", # "sim", # "xrp", ] + +# Other pip packages to install (including vendor packages) +requires = [ + "phoenix6~=26.1", + # "photonlibpy", + # "robotpy-ctre", # Phoenix 5 + # "robotpy-navx", + # "robotpy-pathplannerlib", + # "robotpy-playingwithfusion", + # "robotpy-rev", +] diff --git a/python/VelocityClosedLoop/pyproject.toml b/python/VelocityClosedLoop/pyproject.toml index a4f083ae..9735d7ee 100644 --- a/python/VelocityClosedLoop/pyproject.toml +++ b/python/VelocityClosedLoop/pyproject.toml @@ -8,25 +8,25 @@ # Version of robotpy this project depends on robotpy_version = "2026.1.1b1" -# Which extra RobotPy components should be installed +# Which core WPILib components should be installed # -> equivalent to `pip install robotpy[extra1, ...] components = [ # "all", # "apriltag", "commands2", # "cscore", - # "navx", -] - -# Other pip packages to install -requires = [ - "phoenix6~=26.1.0", - # "pathplannerlib", - # "phoenix5", - # "photonvision", - # "playingwithfusion", - # "rev", # "romi", # "sim", # "xrp", ] + +# Other pip packages to install (including vendor packages) +requires = [ + "phoenix6~=26.1", + # "photonlibpy", + # "robotpy-ctre", # Phoenix 5 + # "robotpy-navx", + # "robotpy-pathplannerlib", + # "robotpy-playingwithfusion", + # "robotpy-rev", +]