Author SHA1 Message Date
Bradley d29acde2df Merge branch 'main' of https://git.coldlightalchemist.com/Team_2648/2026-Robot-Code 2026-03-17 19:02:03 -04:00
Bradley 048c7158ee Auto Align, Auto Hood Angle for 3000 RPM, Camera Poses Working 2026-03-17 19:01:02 -04:00
Tyler-J42 a8833aaf5b after portland changes 2026-03-14 19:11:29 -04:00
Tyler-J42 47606ade0f pose localization trouble 2026-03-14 15:56:08 -04:00
Bradley a6dca0925f Intake Roller Changes 2026-03-14 13:14:19 -04:00
Tylr-J42 72a07b3d7a second intake motor 2026-03-14 09:46:49 -04:00
Tyler-J42 5e1eadf887 end of pine tree 2 2026-03-08 19:24:00 -04:00
Tyler-J42 21c0421a88 end of pine tree 2026-03-08 19:20:07 -04:00
Tyler-J42 81d6c36436 drive train testing 2026-03-06 00:39:39 -05:00
Bradley f1f523de73 Changes from 3/5 meeting 2026-03-05 19:05:09 -05:00
Bradley 10fb8d4aa5 Putting the Auto Chooser somewhere in networktables 2026-03-05 17:07:19 -05:00
Tyler-J42 77f2c54a90 more bindings n stuff 2026-03-05 00:28:37 -05:00
Tylr-J42 4171da889f button bindings 2026-03-04 13:31:23 -05:00
Bradley 918876923f Changes from build session 3/3/26 2026-03-04 10:05:46 -05:00
Tylr-J42 208cfa3ce4 outpost paths 2026-03-03 14:11:12 -05:00
Tyler-J42 fb937d86dc good flywheel and hood control 2026-03-01 19:15:36 -05:00
Bradley db443cfe63 Merge branch 'tuning' of https://git.coldlightalchemist.com/Team_2648/2026-Robot-Code into tuning 2026-03-01 16:38:07 -05:00
Bradley cbcfc9cab0 Placement of where a value was set was wrong 2026-03-01 16:36:06 -05:00
Tyler-J42 96fb68cb32 one shooter good 2026-03-01 15:56:55 -05:00
Tyler-J42 80ef3a3431 encoder weird 2026-03-01 14:50:55 -05:00
Tyler-J42 866e6b99df shooter units off 2026-03-01 13:58:39 -05:00
Bradley 3791333f56 Work from build 2/28 2026-02-28 17:42:37 -05:00
Tylr-J42 7621cfd009 added values from calculations and cad. 2026-02-26 08:18:07 -05:00
Bradley e2c2eaafc9 A little bit more hood stuff, adding a command to trigger the rezero functionality 2026-02-22 13:40:29 -05:00
Bradley acf78b8ccd A little bit more hood stuff, adding a command to trigger the rezero functionality 2026-02-22 13:40:14 -05:00
Bradley 678ff1a198 Adjustments to the hood now that I know we're going with relative not absolute encoders 2026-02-22 12:03:37 -05:00
Bradley 206abe5816 Beginnings of a climber subsystem 2026-02-19 12:08:36 -05:00
Bradley 8762e82078 More testing stuff 2026-02-18 18:27:26 -05:00
Bradley 958bc92ca0 Some additional PhotonVision/Drivetrain work, and a terrible auto path 2026-02-18 17:57:06 -05:00
Bradley 88c021f05e A bit of work setting up bindings for testing robot features prior to deciding on final controls 2026-02-15 21:16:32 -05:00
Bradley 01b7e1b878 Removing an unnecessary todo 2026-02-15 14:51:54 -05:00
Bradley 701fbfc43e Some minor changes, either reducing duplicate code, or generalizing code 2026-02-15 14:46:19 -05:00
Bradley 7f291e42a1 More PhotonVision work, a bunch of comments/docstrings 2026-02-14 22:05:29 -05:00
Bradley 91a5281202 A bunch of changes, mostly related to shooting balls at the hub dynamically, still need a means of doing this based on a single apriltag, in the event the robot pose is unreliable 2026-02-12 16:02:08 -05:00
Bradley f8429dc899 Working on various auto lock on and some Auto stuff 2026-02-11 14:59:31 -05:00
Bradley 9549c5343d Final commit before merging to main to continue progress 2026-02-11 09:50:40 -05:00
Bradley cdccc8ae84 Merge branch 'main' into photonvision_as_a_resource 2026-02-10 17:20:00 -05:00
Bradley faec33984d Preliminary Hood Subsystem 2026-02-10 17:19:17 -05:00
Bradley e70e681366 Intermediary change 2026-02-10 16:12:50 -05:00
Bradley 9fa09a354a Merge branch 'main' into photonvision_as_a_resource 2026-02-08 12:39:25 -05:00
Bradley 415a5b02c4 Minor Spindexer additions 2026-02-08 11:47:29 -05:00
Bradley d0945f5e23 Fixing a commit problem 2026-02-08 11:24:41 -05:00
Bradley ee4955485c Beginnings of a different solution for the PhotonVision cameras 2026-02-08 11:23:27 -05:00
Bradley b68d7b7399 IntakePivot and Shooter changes to make me hate them less, other minor fixes 2026-02-07 07:17:55 -05:00
Bradley faff80fb9a Adding a few subsystems, not sure I like the use of periodic for the shooter and intake pivot subsystems 2026-02-06 21:07:38 -05:00
Bradley ffc1c0cd8b Adding module zeroing constants and a few other minor changes from 2/3 build session 2026-02-03 18:32:32 -05:00
Bradley e4a58f00df Adding preliminary shooter subsystem 2026-02-01 14:17:01 -05:00
Bradley 66049f1357 FINALLY FIXED SWERVE 2026-01-31 17:03:35 -05:00
Bradley 95108b7da7 Final final push, adding setX as evidence of a symptom 2026-01-31 14:10:15 -05:00
Bradley 22c7ec79e2 Final change before Chief Post 2026-01-31 13:57:05 -05:00
Bradley c5df269a49 Add module position sanity checks 2026-01-31 13:54:12 -05:00
Bradley 359a9a6bbb Minor change to remove something that didn't make any difference 2026-01-31 13:31:45 -05:00
Bradley 4666a74877 Pushing up changes that are related to us trying to fix rotation 2026-01-31 13:29:11 -05:00
Bradley 4296e2f27f Partially adjusting drivetrain code to resolve an obvious error 2026-01-28 20:32:10 -05:00
Bradley 436667d0e4 Pushing up the little bit of work from 1/27 build session 2026-01-27 18:34:34 -05:00
Bradley dae39c30a0 Build Session 1/24, swerve work, need to revalidate individual module CAN IDs 2026-01-24 18:02:05 -05:00
Bradley c6cc0c6b60 Adding a preliminary mechanism for auto rezeroing the turning encoder from the absolute encoder when it's not moving 2026-01-22 17:03:24 -05:00
Bradley 7c4a381f2b Adding some shot utilities. Needs review 2026-01-22 16:34:03 -05:00
Bradley c2cb06748c Adding a mechanism for a 'shift display' in Elastic 2026-01-22 16:03:46 -05:00
wildercayden e531c8e191 made the 'Utlities.java' file and started work on the alliance hub switch 2026-01-21 21:17:01 -05:00
wildercayden 6a59518ad8 made the 'Utlities.java' file and started work on the alliance hub switch 2026-01-21 21:13:30 -05:00
Bradley 7f9214ae58 Adding a mechanism to zero the modules without an absolute encoder 2026-01-21 17:52:25 -05:00
Bradley 929dd81329 Update to 2026.2.1, more auto code, more tag tracking code, pondering on the fly path generation 2026-01-18 23:01:17 -05:00
Bradley e05415452c Fixing a bad package name, something I didn't spell correctly, computer crash seems to have messed up the world here 2026-01-14 21:18:22 -05:00
Bradley 47f0de2ebb Merge branch 'main' of https://git.coldlightalchemist.com/Team_2648/2026-Robot-Code 2026-01-14 21:15:41 -05:00
Bradley 95e15ed75e A number of incomplete changes, and fixing OI constants which didn't get properly saved 2026-01-14 21:15:21 -05:00
Bradley 9e247389e8 Merge pull request 'Bringing in basic drivetrain stuff' (#1) from brads-tinkering into main
Reviewed-on: #1
2026-01-13 16:13:59 -05:00
Bradley 58a6971704 First tinkering iteration, missing some stuff 2026-01-12 23:25:11 -05:00
Bradley ec73c42cfb Initial Commit 2026-01-10 12:04:38 -05:00
70 changed files with 2472 additions and 846 deletions

No files matched your search

+1 -1
View File
@@ -13,7 +13,7 @@
},
{
"type": "wpilib",
"name": "WPILib Systemcore Debug",
"name": "WPILib roboRIO Debug",
"request": "launch",
"desktop": false,
}
+4 -5
View File
@@ -37,7 +37,7 @@
"org.mockito.Mockito.*",
"org.mockito.ArgumentMatchers.*",
"org.mockito.Answers.*",
"org.wpilib.units.Units.*"
"edu.wpi.first.units.Units.*"
],
"java.completion.filteredTypes": [
"java.awt.*",
@@ -53,10 +53,9 @@
"javax.swing.*",
"javax.management.*",
"javax.smartcardio.*",
"org.wpilib.math.proto.*",
"org.wpilib.math.**.proto.*",
"org.wpilib.math.**.struct.*",
"edu.wpi.first.math.proto.*",
"edu.wpi.first.math.**.proto.*",
"edu.wpi.first.math.**.struct.*",
],
"java.debug.settings.enableRunDebugCodeLens": false,
"java.dependency.enableDependencyCheckup": false
}
+2 -2
View File
@@ -1,6 +1,6 @@
{
"enableCppIntellisense": false,
"currentLanguage": "java",
"projectYear": "2027_alpha7",
"teamNumber": 9999
"projectYear": "2026",
"teamNumber": 2648
}
+39 -31
View File
@@ -1,45 +1,39 @@
plugins {
id "java"
id "application"
id "org.wpilib.GradleRIO" version "2027.0.0-alpha-7"
id "edu.wpi.first.GradleRIO" version "2026.2.1"
}
java {
sourceCompatibility = JavaVersion.VERSION_25
targetCompatibility = JavaVersion.VERSION_25
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
def ROBOT_MAIN_CLASS = "first.Main"
def ROBOT_MAIN_CLASS = "frc.robot.Main"
// Define my targets (SystemCore) and artifacts (deployable files)
// Define my targets (RoboRIO) and artifacts (deployable files)
// This is added by GradleRIO's backing project DeployUtils.
deploy {
targets {
systemcore(getTargetTypeClass('SystemCore')) {
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.wpilib.getTeamNumber()
// Use the default systemcore host name. This must be called after setting team
// as happens on the line above
useDefaultSystemcoreHostName()
debug = project.wpilib.getDebugOrDefault(false)
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
wpilibJava(getArtifactTypeClass('WPILibJavaArtifact')) {
// Set to true to use debug including JNI, which will drastically impact performance.
debugJni = false
frcJava(getArtifactTypeClass('FRCJavaArtifact')) {
}
// Static files artifact
wpilibStaticFileDeploy(getArtifactTypeClass('FileTreeArtifact')) {
frcStaticFileDeploy(getArtifactTypeClass('FileTreeArtifact')) {
files = project.fileTree('src/main/deploy')
directory = '/home/systemcore/deploy'
deleteOldFiles = false // Change to true to delete files on systemcore that no
directory = '/home/lvuser/deploy'
deleteOldFiles = false // Change to true to delete files on roboRIO that no
// longer exist in deploy directory of this project
}
}
@@ -47,14 +41,20 @@ deploy {
}
}
def deployArtifact = deploy.targets.systemcore.artifacts.wpilibJava
def deployArtifact = deploy.targets.roborio.artifacts.frcJava
// Set to true to use debug for simulation including JNI
wpi.java.runSimWithDebugJni = false
// 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
task(replayWatch, type: JavaExec) {
mainClass = "org.littletonrobotics.junction.ReplayWatch"
classpath = sourceSets.main.runtimeClasspath
}
// Defining my dependencies. In this case, WPILib (+ friends), and vendor libraries.
// Also defines JUnit 5.
dependencies {
@@ -62,11 +62,11 @@ dependencies {
implementation wpi.java.deps.wpilib()
implementation wpi.java.vendor.java()
systemcoreDebug wpi.java.deps.wpilibJniDebug(wpi.platforms.systemcore)
systemcoreDebug wpi.java.vendor.jniDebug(wpi.platforms.systemcore)
roborioDebug wpi.java.deps.wpilibJniDebug(wpi.platforms.roborio)
roborioDebug wpi.java.vendor.jniDebug(wpi.platforms.roborio)
systemcoreRelease wpi.java.deps.wpilibJniRelease(wpi.platforms.systemcore)
systemcoreRelease wpi.java.vendor.jniRelease(wpi.platforms.systemcore)
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)
@@ -78,6 +78,9 @@ dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.1'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
def akitJson = new groovy.json.JsonSlurper().parseText(new File(projectDir.getAbsolutePath() + "/vendordeps/AdvantageKit.json").text)
annotationProcessor "org.littletonrobotics.akit:akit-autolog:$akitJson.version"
}
test {
@@ -89,18 +92,23 @@ test {
wpi.sim.addGui().defaultEnabled = true
wpi.sim.addDriverstation()
application.mainClass = ROBOT_MAIN_CLASS
deployArtifact.configureApplication(application)
wpi.java.configureApplication(application)
wpi.java.configureTestTasks(test)
// 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'
Binary file not shown.
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=permwrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Vendored
+9 -5
View File
@@ -1,7 +1,7 @@
#!/bin/sh
#
# Copyright © 2015 the original authors.
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -57,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/2d6327017519d23b96af35865dc997fcb544fb40/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -86,7 +86,8 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -114,6 +115,7 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
@@ -171,6 +173,7 @@ fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
@@ -203,14 +206,15 @@ fi
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
Vendored
+2 -1
View File
@@ -70,10 +70,11 @@ 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%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
"%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
+11 -19
View File
@@ -2,35 +2,27 @@ import org.gradle.internal.os.OperatingSystem
pluginManagement {
repositories {
String wpilibYear = '2027_alpha7'
File wpilibHome
def os = OperatingSystem.current()
if (os.isWindows()) {
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")
wpilibHome = new File(homeRoot, wpilibYear)
} else if (os.isLinux()) {
String xdgDataHome = System.getenv('XDG_DATA_HOME')
if (xdgDataHome == null || xdgDataHome.trim().isEmpty() || !new File(xdgDataHome).isAbsolute()) {
xdgDataHome = new File(System.getProperty("user.home"), ".local/share").getPath()
}
def homeRoot = new File(xdgDataHome, "wpilib")
wpilibHome = new File(homeRoot, wpilibYear)
frcHome = new File(homeRoot, frcYear)
} else {
def userFolder = System.getProperty("user.home")
def homeRoot = new File(userFolder, ".wpilib")
wpilibHome = new File(homeRoot, wpilibYear)
def homeRoot = new File(userFolder, "wpilib")
frcHome = new File(homeRoot, frcYear)
}
def wpilibHomeMaven = new File(wpilibHome, 'maven')
def frcHomeMaven = new File(frcHome, 'maven')
maven {
name = 'wpilibHome'
url = wpilibHomeMaven
name = 'frcHome'
url = frcHomeMaven
}
mavenLocal()
gradlePluginPortal()
}
}
+1 -1
View File
@@ -1,3 +1,3 @@
Files placed in this directory will be deployed to the Systemcore into the
Files placed in this directory will be deployed to the RoboRIO into the
'deploy' directory in the home folder. Use the 'Filesystem.getDeployDirectory' wpilib function
to get a proper path relative to the deploy directory.
@@ -0,0 +1,37 @@
{
"version": "2025.0",
"command": {
"type": "sequential",
"data": {
"commands": [
{
"type": "named",
"data": {
"name": "intake down"
}
},
{
"type": "named",
"data": {
"name": "spinup"
}
},
{
"type": "path",
"data": {
"pathName": "Center to Shoot"
}
},
{
"type": "named",
"data": {
"name": "shoot close"
}
}
]
}
},
"resetOdom": true,
"folder": null,
"choreoAuto": false
}
@@ -0,0 +1,67 @@
{
"version": "2025.0",
"command": {
"type": "sequential",
"data": {
"commands": [
{
"type": "named",
"data": {
"name": "intake down"
}
},
{
"type": "named",
"data": {
"name": "spinup"
}
},
{
"type": "path",
"data": {
"pathName": "start to score left"
}
},
{
"type": "named",
"data": {
"name": "shoot close"
}
},
{
"type": "path",
"data": {
"pathName": "Left to Outpost"
}
},
{
"type": "named",
"data": {
"name": "stop spindexer"
}
},
{
"type": "path",
"data": {
"pathName": "trough to shot"
}
},
{
"type": "named",
"data": {
"name": "spinup"
}
},
{
"type": "named",
"data": {
"name": "shoot N jimmy"
}
}
]
}
},
"resetOdom": true,
"folder": null,
"choreoAuto": false
}
@@ -0,0 +1,31 @@
{
"version": "2025.0",
"command": {
"type": "sequential",
"data": {
"commands": [
{
"type": "path",
"data": {
"pathName": "Start to outpost"
}
},
{
"type": "path",
"data": {
"pathName": "Outpost to Ranged Shot"
}
},
{
"type": "named",
"data": {
"name": "Auto Shoot"
}
}
]
}
},
"resetOdom": true,
"folder": null,
"choreoAuto": false
}
@@ -0,0 +1,25 @@
{
"version": "2025.0",
"command": {
"type": "sequential",
"data": {
"commands": [
{
"type": "named",
"data": {
"name": "intake down"
}
},
{
"type": "path",
"data": {
"pathName": "left start to center"
}
}
]
}
},
"resetOdom": true,
"folder": null,
"choreoAuto": false
}
+1
View File
@@ -0,0 +1 @@
{"field_size":{"x":16.54,"y":8.07},"nodeSizeMeters":0.3,"grid":[[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,true],[true,true,false,false,false,false,false,false,false,false,false,false,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,true,true],[true,true,false,false,false,false,false,false,false,false,false,false,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,true,true,true],[true,true,false,false,false,false,false,false,false,false,false,false,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,true,true,true,true],[true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,true,true,true],[true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,true,true,true],[true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,true,true,true],[true,true,true,true,true,false,false,false,false,false,false,false,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,true,true,true],[true,true,true,true,true,true,false,false,false,false,false,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,true,true],[true,true,true,true,true,true,false,false,false,false,false,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,true,true,true,true,true],[true,true,true,true,true,true,false,false,false,false,false,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,true,true,true,true,true,true,true,false,false,false,false,false,false,true,true,true,true,true,true],[true,true,true,true,true,true,false,false,false,false,false,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,true,true,true,true,true,true,true,false,false,false,false,false,false,true,true,true,true,true,true],[true,true,true,true,true,true,false,false,false,false,false,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,true,true,true,true,true,true,true,false,false,false,false,false,false,true,true,true,true,true,true],[true,true,true,true,true,false,false,false,false,false,false,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,true,tLine truncated
@@ -0,0 +1,54 @@
{
"version": "2025.0",
"waypoints": [
{
"anchor": {
"x": 3.622028469750891,
"y": 4.008102016607354
},
"prevControl": null,
"nextControl": {
"x": 3.266975088967973,
"y": 4.0403795966785285
},
"isLocked": false,
"linkedName": null
},
{
"anchor": {
"x": 3.1271055753262162,
"y": 4.008102016607354
},
"prevControl": {
"x": 4.0416370106761565,
"y": 4.0403795966785285
},
"nextControl": null,
"isLocked": false,
"linkedName": null
}
],
"rotationTargets": [],
"constraintZones": [],
"pointTowardsZones": [],
"eventMarkers": [],
"globalConstraints": {
"maxVelocity": 2.0,
"maxAcceleration": 1.5,
"maxAngularVelocity": 540.0,
"maxAngularAcceleration": 720.0,
"nominalVoltage": 12.0,
"unlimited": false
},
"goalEndState": {
"velocity": 0,
"rotation": 0.0
},
"reversed": false,
"folder": null,
"idealStartingState": {
"velocity": 0,
"rotation": 0.0
},
"useDefaultConstraints": true
}
@@ -0,0 +1,54 @@
{
"version": "2025.0",
"waypoints": [
{
"anchor": {
"x": 2.0,
"y": 7.0
},
"prevControl": null,
"nextControl": {
"x": 3.0,
"y": 7.0
},
"isLocked": false,
"linkedName": null
},
{
"anchor": {
"x": 4.0,
"y": 6.0
},
"prevControl": {
"x": 3.0,
"y": 6.0
},
"nextControl": null,
"isLocked": false,
"linkedName": null
}
],
"rotationTargets": [],
"constraintZones": [],
"pointTowardsZones": [],
"eventMarkers": [],
"globalConstraints": {
"maxVelocity": 2.0,
"maxAcceleration": 1.5,
"maxAngularVelocity": 540.0,
"maxAngularAcceleration": 720.0,
"nominalVoltage": 12.0,
"unlimited": false
},
"goalEndState": {
"velocity": 0,
"rotation": 0.0
},
"reversed": false,
"folder": null,
"idealStartingState": {
"velocity": 0,
"rotation": 0.0
},
"useDefaultConstraints": true
}
@@ -0,0 +1,80 @@
{
"version": "2025.0",
"waypoints": [
{
"anchor": {
"x": 3.2515736040609142,
"y": 4.914375634517767
},
"prevControl": null,
"nextControl": {
"x": 2.4338749089244973,
"y": 5.333984175443034
},
"isLocked": false,
"linkedName": "left close"
},
{
"anchor": {
"x": 0.77458883248731,
"y": 5.927269035532995
},
"prevControl": {
"x": 2.3777086426889733,
"y": 6.110175322602984
},
"nextControl": null,
"isLocked": false,
"linkedName": "trough"
}
],
"rotationTargets": [
{
"waypointRelativePos": 0.5,
"rotationDegrees": 180.0
}
],
"constraintZones": [
{
"name": "Constraints Zone",
"minWaypointRelativePos": 0.3963599595551063,
"maxWaypointRelativePos": 1.0,
"constraints": {
"maxVelocity": 3.0,
"maxAcceleration": 4.0,
"maxAngularVelocity": 540.0,
"maxAngularAcceleration": 720.0,
"nominalVoltage": 12.0,
"unlimited": false
}
}
],
"pointTowardsZones": [],
"eventMarkers": [
{
"name": "Intake Start",
"waypointRelativePos": 0.09706774519716882,
"endWaypointRelativePos": null,
"command": null
}
],
"globalConstraints": {
"maxVelocity": 2.0,
"maxAcceleration": 1.5,
"maxAngularVelocity": 540.0,
"maxAngularAcceleration": 720.0,
"nominalVoltage": 12.0,
"unlimited": false
},
"goalEndState": {
"velocity": 0,
"rotation": 178.80651057601818
},
"reversed": false,
"folder": null,
"idealStartingState": {
"velocity": 0,
"rotation": -31.15930450834445
},
"useDefaultConstraints": true
}
@@ -0,0 +1,151 @@
{
"version": "2025.0",
"waypoints": [
{
"anchor": {
"x": 2.0,
"y": 4.0
},
"prevControl": null,
"nextControl": {
"x": 2.572076308784383,
"y": 3.3951907719609573
},
"isLocked": false,
"linkedName": null
},
{
"anchor": {
"x": 3.1112866015971603,
"y": 2.6628305235137533
},
"prevControl": {
"x": 2.8612866015971603,
"y": 2.6628305235137533
},
"nextControl": {
"x": 3.3612866015971603,
"y": 2.6628305235137533
},
"isLocked": false,
"linkedName": null
},
{
"anchor": {
"x": 5.839529724933453,
"y": 2.357009760425909
},
"prevControl": {
"x": 5.055196983507387,
"y": 2.7986728575396165
},
"nextControl": {
"x": 6.668464951197871,
"y": 1.890230700976042
},
"isLocked": false,
"linkedName": null
},
{
"anchor": {
"x": 6.612129547471162,
"y": 0.8279059449866895
},
"prevControl": {
"x": 6.3623142538133335,
"y": 0.8182976644613882
},
"nextControl": {
"x": 7.030621118012423,
"y": 0.844001774622892
},
"isLocked": false,
"linkedName": null
},
{
"anchor": {
"x": 8.189520851818989,
"y": 0.8279059449866895
},
"prevControl": {
"x": 8.08578683847011,
"y": 0.4907704016028374
},
"nextControl": {
"x": 8.318287488908608,
"y": 1.246397515527949
},
"isLocked": false,
"linkedName": null
},
{
"anchor": {
"x": 8.189520851818989,
"y": 7.111241666666667
},
"prevControl": {
"x": 8.36001268105017,
"y": 7.294087328812116
},
"nextControl": {
"x": 6.244366666666667,
"y": 5.025141666666666
},
"isLocked": false,
"linkedName": null
},
{
"anchor": {
"x": 2.518108333333333,
"y": 5.592016666666666
},
"prevControl": {
"x": 3.205916666666667,
"y": 5.644925000000001
},
"nextControl": null,
"isLocked": false,
"linkedName": null
}
],
"rotationTargets": [
{
"waypointRelativePos": 1,
"rotationDegrees": 45.0
},
{
"waypointRelativePos": 2,
"rotationDegrees": 45.0
},
{
"waypointRelativePos": 3,
"rotationDegrees": -135.0
},
{
"waypointRelativePos": 5,
"rotationDegrees": -135.0
}
],
"constraintZones": [],
"pointTowardsZones": [],
"eventMarkers": [],
"globalConstraints": {
"maxVelocity": 2.0,
"maxAcceleration": 1.5,
"maxAngularVelocity": 540.0,
"maxAngularAcceleration": 720.0,
"nominalVoltage": 12.0,
"unlimited": false
},
"goalEndState": {
"velocity": 0,
"rotation": -133.87669728592465
},
"reversed": false,
"folder": null,
"idealStartingState": {
"velocity": 0,
"rotation": 0.0
},
"useDefaultConstraints": true
}
@@ -0,0 +1,54 @@
{
"version": "2025.0",
"waypoints": [
{
"anchor": {
"x": 0.7089624329216013,
"y": 0.668228980317108
},
"prevControl": null,
"nextControl": {
"x": 2.1043470483005366,
"y": 0.7169051878354196
},
"isLocked": false,
"linkedName": "Outpost"
},
{
"anchor": {
"x": 2.3639534883720925,
"y": 2.9722361359570666
},
"prevControl": {
"x": 2.234150268336314,
"y": 2.5666010733452596
},
"nextControl": null,
"isLocked": false,
"linkedName": null
}
],
"rotationTargets": [],
"constraintZones": [],
"pointTowardsZones": [],
"eventMarkers": [],
"globalConstraints": {
"maxVelocity": 2.0,
"maxAcceleration": 1.5,
"maxAngularVelocity": 540.0,
"maxAngularAcceleration": 720.0,
"nominalVoltage": 12.0,
"unlimited": false
},
"goalEndState": {
"velocity": 0,
"rotation": 24.304549265936608
},
"reversed": false,
"folder": "Right Outpost",
"idealStartingState": {
"velocity": 0,
"rotation": 180.0
},
"useDefaultConstraints": true
}
@@ -0,0 +1,66 @@
{
"version": "2025.0",
"waypoints": [
{
"anchor": {
"x": 3.6619856887266913,
"y": 2.2583184257605784
},
"prevControl": null,
"nextControl": {
"x": 2.4937567084046877,
"y": 1.3172450805011864
},
"isLocked": false,
"linkedName": null
},
{
"anchor": {
"x": 0.7089624329216013,
"y": 0.668228980317108
},
"prevControl": {
"x": 1.6987119856944104,
"y": 1.0414132379199703
},
"nextControl": null,
"isLocked": false,
"linkedName": "Outpost"
}
],
"rotationTargets": [
{
"waypointRelativePos": 0.7234468937875753,
"rotationDegrees": 180.0
}
],
"constraintZones": [],
"pointTowardsZones": [],
"eventMarkers": [
{
"name": "Intake Start",
"waypointRelativePos": 0.4500000000000002,
"endWaypointRelativePos": null,
"command": null
}
],
"globalConstraints": {
"maxVelocity": 2.0,
"maxAcceleration": 1.5,
"maxAngularVelocity": 540.0,
"maxAngularAcceleration": 720.0,
"nominalVoltage": 12.0,
"unlimited": false
},
"goalEndState": {
"velocity": 0,
"rotation": 180.0
},
"reversed": false,
"folder": "Right Outpost",
"idealStartingState": {
"velocity": 0,
"rotation": 180.0
},
"useDefaultConstraints": true
}
@@ -0,0 +1,132 @@
{
"version": "2025.0",
"waypoints": [
{
"anchor": {
"x": 3.573857868020305,
"y": 6.3692588832487305
},
"prevControl": null,
"nextControl": {
"x": 3.1594923857868027,
"y": 6.424507614213196
},
"isLocked": false,
"linkedName": "start left"
},
{
"anchor": {
"x": 2.634629441624366,
"y": 5.558944162436549
},
"prevControl": {
"x": 2.4136345177664977,
"y": 5.908852791878173
},
"nextControl": {
"x": 2.895419769065523,
"y": 5.146026143988051
},
"isLocked": false,
"linkedName": null
},
{
"anchor": {
"x": 4.522294416243654,
"y": 5.558944162436549
},
"prevControl": {
"x": 3.5095162657293457,
"y": 5.533304209258972
},
"nextControl": {
"x": 6.704619289340102,
"y": 5.614192893401015
},
"isLocked": false,
"linkedName": null
},
{
"anchor": {
"x": 7.478101522849547,
"y": 7.244030456855094
},
"prevControl": {
"x": 6.765542310662505,
"y": 7.465169522706244
},
"nextControl": {
"x": 8.012172588839395,
"y": 7.078284263961693
},
"isLocked": false,
"linkedName": null
},
{
"anchor": {
"x": 7.671472081218274,
"y": 4.7670456852791885
},
"prevControl": {
"x": 7.726720812182741,
"y": 7.639979695431472
},
"nextControl": null,
"isLocked": false,
"linkedName": null
}
],
"rotationTargets": [
{
"waypointRelativePos": 1.5636363636363326,
"rotationDegrees": -45.0
},
{
"waypointRelativePos": 3.0318181818182266,
"rotationDegrees": -90.0
}
],
"constraintZones": [
{
"name": "Constraints Zone",
"minWaypointRelativePos": 2.6208291203235685,
"maxWaypointRelativePos": 4.0,
"constraints": {
"maxVelocity": 1.0,
"maxAcceleration": 1.5,
"maxAngularVelocity": 540.0,
"maxAngularAcceleration": 720.0,
"nominalVoltage": 12.0,
"unlimited": false
}
}
],
"pointTowardsZones": [],
"eventMarkers": [
{
"name": "Intake Start",
"waypointRelativePos": 0,
"endWaypointRelativePos": null,
"command": null
}
],
"globalConstraints": {
"maxVelocity": 2.0,
"maxAcceleration": 1.5,
"maxAngularVelocity": 540.0,
"maxAngularAcceleration": 720.0,
"nominalVoltage": 12.0,
"unlimited": false
},
"goalEndState": {
"velocity": 0,
"rotation": -89.09061955080092
},
"reversed": false,
"folder": null,
"idealStartingState": {
"velocity": 0,
"rotation": -90.0
},
"useDefaultConstraints": true
}
@@ -0,0 +1,54 @@
{
"version": "2025.0",
"waypoints": [
{
"anchor": {
"x": 3.573857868020305,
"y": 6.3692588832487305
},
"prevControl": null,
"nextControl": {
"x": 2.7991959463121194,
"y": 6.260219737341258
},
"isLocked": false,
"linkedName": "start left"
},
{
"anchor": {
"x": 3.2515736040609142,
"y": 4.914375634517767
},
"prevControl": {
"x": 3.44523908448796,
"y": 5.430816915656558
},
"nextControl": null,
"isLocked": false,
"linkedName": "left close"
}
],
"rotationTargets": [],
"constraintZones": [],
"pointTowardsZones": [],
"eventMarkers": [],
"globalConstraints": {
"maxVelocity": 2.0,
"maxAcceleration": 1.5,
"maxAngularVelocity": 540.0,
"maxAngularAcceleration": 720.0,
"nominalVoltage": 12.0,
"unlimited": false
},
"goalEndState": {
"velocity": 0,
"rotation": -31.15930450834445
},
"reversed": false,
"folder": null,
"idealStartingState": {
"velocity": 0,
"rotation": -90.0
},
"useDefaultConstraints": true
}
@@ -0,0 +1,54 @@
{
"version": "2025.0",
"waypoints": [
{
"anchor": {
"x": 0.77458883248731,
"y": 5.927269035532995
},
"prevControl": null,
"nextControl": {
"x": 1.7745888324873098,
"y": 5.927269035532995
},
"isLocked": false,
"linkedName": "trough"
},
{
"anchor": {
"x": 3.2515736040609142,
"y": 4.914375634517767
},
"prevControl": {
"x": 2.6254213197969554,
"y": 5.420822335025381
},
"nextControl": null,
"isLocked": false,
"linkedName": "left close"
}
],
"rotationTargets": [],
"constraintZones": [],
"pointTowardsZones": [],
"eventMarkers": [],
"globalConstraints": {
"maxVelocity": 2.0,
"maxAcceleration": 1.5,
"maxAngularVelocity": 540.0,
"maxAngularAcceleration": 720.0,
"nominalVoltage": 12.0,
"unlimited": false
},
"goalEndState": {
"velocity": 0,
"rotation": -31.15930450834445
},
"reversed": false,
"folder": null,
"idealStartingState": {
"velocity": 0,
"rotation": 178.80651057601818
},
"useDefaultConstraints": true
}
+36
View File
@@ -0,0 +1,36 @@
{
"robotWidth": 0.921,
"robotLength": 0.787,
"holonomicMode": true,
"pathFolders": [
"Right Outpost"
],
"autoFolders": [],
"defaultMaxVel": 2.0,
"defaultMaxAccel": 1.5,
"defaultMaxAngVel": 540.0,
"defaultMaxAngAccel": 720.0,
"defaultNominalVoltage": 12.0,
"robotMass": 64.864,
"robotMOI": 37.809,
"robotTrackwidth": 0.546,
"driveWheelRadius": 0.051,
"driveGearing": 6.122,
"maxDriveSpeed": 4.66,
"driveMotorType": "krakenX60",
"driveCurrentLimit": 65.0,
"wheelCOF": 1.2,
"flModuleX": 0.238,
"flModuleY": 0.3015,
"frModuleX": 0.238,
"frModuleY": -0.3015,
"blModuleX": -0.238,
"blModuleY": 0.3015,
"brModuleX": -0.238,
"brModuleY": -0.3015,
"bumperOffsetX": 0.0,
"bumperOffsetY": 0.0,
"robotFeatures": [
"{\"name\":\"Rectangle\",\"type\":\"rounded_rect\",\"data\":{\"center\":{\"x\":0.55,\"y\":0.0},\"size\":{\"width\":0.921,\"length\":0.305},\"borderRadius\":0.05,\"strokeWidth\":0.02,\"filled\":false}}"
]
}
-25
View File
@@ -1,25 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package first;
import org.wpilib.framework.RobotBase;
/**
* Do NOT add any static variables to this class, or any initialization at all. Unless you know what
* you are doing, do not modify this file except to change the parameter class to the startRobot
* call.
*/
public final class Main {
private Main() {}
/**
* Main initialization function. Do not perform any initialization here.
*
* <p>If you change your main robot class, change the parameter type.
*/
public static void main(String... args) {
RobotBase.startRobot(first.robot.Robot::new);
}
}
-76
View File
@@ -1,76 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package first.robot;
import org.wpilib.command2.Command;
import org.wpilib.command2.CommandScheduler;
import org.wpilib.epilogue.Epilogue;
import org.wpilib.epilogue.Logged;
import org.wpilib.framework.TimedRobot;
@Logged
public class Robot extends TimedRobot {
private Command autonomousCommand;
private final RobotContainer robotContainer;
public Robot() {
robotContainer = new RobotContainer();
}
@Override
public void robotPeriodic() {
CommandScheduler.getInstance().run();
Epilogue.update(this);
}
@Override
public void disabledInit() {}
@Override
public void disabledPeriodic() {}
@Override
public void disabledExit() {}
@Override
public void autonomousInit() {
autonomousCommand = robotContainer.getAutonomousCommand();
if (autonomousCommand != null) {
CommandScheduler.getInstance().schedule(autonomousCommand);
}
}
@Override
public void autonomousPeriodic() {}
@Override
public void autonomousExit() {
if (autonomousCommand != null) {
autonomousCommand.cancel();
}
}
@Override
public void teleopInit() {}
@Override
public void teleopPeriodic() {}
@Override
public void teleopExit() {}
@Override
public void utilityInit() {
CommandScheduler.getInstance().cancelAll();
}
@Override
public void utilityPeriodic() {}
@Override
public void utilityExit() {}
}
@@ -1,22 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package first.robot;
import org.wpilib.command2.Command;
import org.wpilib.command2.Commands;
import org.wpilib.epilogue.Logged;
@Logged
public class RobotContainer {
public RobotContainer() {
configureBindings();
}
private void configureBindings() {}
public Command getAutonomousCommand() {
return Commands.print("No autonomous command configured");
}
}
@@ -1,28 +0,0 @@
package first.robot.constants;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
import com.revrobotics.spark.config.SparkMaxConfig;
public class RollerIndexerConstants {
public static final int kMotor1CANID = 50;
public static final int kMotor2CANID = 4;
public static final int kCurrentLimit = 40;
public static final double kMotorSpeed = 1;
public static final boolean kMotorInverted = true;
public static final IdleMode kIdleMode = IdleMode.kBrake;
// YOU SHOULDN'T NEED TO CHANGE ANYTHING BELOW THIS LINE UNLESS YOU'RE ADDING A CONFIGURATION ITEM
public static final SparkMaxConfig kMotorConfig = new SparkMaxConfig();
static {
kMotorConfig
.inverted(kMotorInverted)
.smartCurrentLimit(kCurrentLimit)
.idleMode(kIdleMode);
}
}
@@ -1,7 +0,0 @@
package first.robot.constants;
import org.wpilib.hardware.imu.OnboardIMU.MountOrientation;
public class SystemCoreConstants {
public static final MountOrientation kSystemCoreMountOrientation = MountOrientation.FLAT;
}
@@ -1,13 +0,0 @@
package first.robot.interfaces;
import java.util.function.DoubleSupplier;
import org.wpilib.command2.Command;
public interface IIndexer {
public Command spinToShooter();
public Command spinToShooter(DoubleSupplier shooterSpeedRPM, double cutOffRPM);
public Command spinToIntake();
public Command stop();
public Command instantaneousStop();
}
+15
View File
@@ -0,0 +1,15 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package frc.robot;
import edu.wpi.first.wpilibj.RobotBase;
public final class Main {
private Main() {}
public static void main(String... args) {
RobotBase.startRobot(Robot::new);
}
}
+101
View File
@@ -0,0 +1,101 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package frc.robot;
import org.littletonrobotics.junction.LogFileUtil;
import org.littletonrobotics.junction.LoggedRobot;
import org.littletonrobotics.junction.Logger;
import org.littletonrobotics.junction.networktables.NT4Publisher;
import org.littletonrobotics.junction.wpilog.WPILOGReader;
import org.littletonrobotics.junction.wpilog.WPILOGWriter;
import edu.wpi.first.wpilibj.PowerDistribution;
import edu.wpi.first.wpilibj.PowerDistribution.ModuleType;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.CommandScheduler;
import frc.robot.constants.CompetitionConstants;
public class Robot extends LoggedRobot {
private Command m_autonomousCommand;
private final RobotContainer m_robotContainer;
@SuppressWarnings("resource")
public Robot() {
Logger.recordMetadata("ProjectName", "2026_Robot_Code");
if(isReal()) {
if(CompetitionConstants.kLogToNetworkTables) {
Logger.addDataReceiver(new NT4Publisher());
}
Logger.addDataReceiver(new WPILOGWriter());
new PowerDistribution(1, ModuleType.kRev);
} else {
setUseTiming(false);
String logPath = LogFileUtil.findReplayLog();
Logger.setReplaySource(new WPILOGReader(logPath));
Logger.addDataReceiver(new WPILOGWriter(LogFileUtil.addPathSuffix(logPath, "_sim")));
}
Logger.start();
m_robotContainer = new RobotContainer();
}
@Override
public void robotPeriodic() {
CommandScheduler.getInstance().run();
}
@Override
public void disabledInit() {}
@Override
public void disabledPeriodic() {}
@Override
public void disabledExit() {}
@Override
public void autonomousInit() {
m_autonomousCommand = m_robotContainer.getAutonomousCommand();
if (m_autonomousCommand != null) {
CommandScheduler.getInstance().schedule(m_autonomousCommand);
}
}
@Override
public void autonomousPeriodic() {}
@Override
public void autonomousExit() {}
@Override
public void teleopInit() {
if (m_autonomousCommand != null) {
m_autonomousCommand.cancel();
}
}
@Override
public void teleopPeriodic() {}
@Override
public void teleopExit() {}
@Override
public void testInit() {
CommandScheduler.getInstance().cancelAll();
}
@Override
public void testPeriodic() {}
@Override
public void testExit() {}
}
+475
View File
@@ -0,0 +1,475 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package frc.robot;
import edu.wpi.first.wpilibj.DriverStation.Alliance;
import java.util.Optional;
import java.util.OptionalDouble;
import org.littletonrobotics.junction.Logger;
import com.pathplanner.lib.auto.AutoBuilder;
import com.pathplanner.lib.auto.NamedCommands;
import com.pathplanner.lib.events.EventTrigger;
import com.pathplanner.lib.path.EventMarker;
import edu.wpi.first.math.MathUtil;
import edu.wpi.first.math.geometry.Pose2d;
import edu.wpi.first.math.interpolation.InterpolatingDoubleTreeMap;
import edu.wpi.first.math.util.Units;
import edu.wpi.first.util.sendable.Sendable;
import edu.wpi.first.util.sendable.SendableBuilder;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.smartdashboard.SendableChooser;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.Commands;
import edu.wpi.first.wpilibj2.command.InstantCommand;
import edu.wpi.first.wpilibj2.command.PrintCommand;
import edu.wpi.first.wpilibj2.command.button.CommandXboxController;
import edu.wpi.first.wpilibj2.command.button.RobotModeTriggers;
import edu.wpi.first.wpilibj2.command.button.Trigger;
import frc.robot.constants.AutoConstants;
import frc.robot.constants.CompetitionConstants;
import frc.robot.constants.HoodConstants;
import frc.robot.constants.OIConstants;
import frc.robot.constants.ShooterConstants;
import frc.robot.constants.IntakePivotConstants.IntakePivotPosition;
import frc.robot.constants.ShooterConstants.ShooterSpeeds;
import frc.robot.subsystems.Climber;
import frc.robot.subsystems.Drivetrain;
import frc.robot.subsystems.Hood;
import frc.robot.subsystems.IntakePivot;
import frc.robot.subsystems.IntakeRoller;
import frc.robot.subsystems.PhotonVision;
import frc.robot.subsystems.Shooter;
import frc.robot.subsystems.Spindexer;
import frc.robot.utilities.Elastic;
import frc.robot.utilities.Utilities;
public class RobotContainer {
private PhotonVision vision;
private Drivetrain drivetrain;
private Hood hood;
private Shooter shooter;
private IntakePivot intakePivot;
private IntakeRoller intakeRoller;
private Spindexer spindexer;
//private Climber climber;
private CommandXboxController driver;
private CommandXboxController secondary;
private SendableChooser<Command> autoChooser;
private Timer shiftTimer;
private boolean resetOdometryToVisualPose;
public RobotContainer() {
vision = new PhotonVision();
drivetrain = new Drivetrain(null);
hood = new Hood();
shooter = new Shooter();
intakePivot = new IntakePivot();
intakeRoller = new IntakeRoller();
spindexer = new Spindexer();
//climber = new Climber();
configureNamedCommands();
resetOdometryToVisualPose = false;
//vision.addPoseEstimateConsumer(drivetrain::consumeVisualPose);
vision.addPoseEstimateConsumer((vp) -> {
Logger.recordOutput(
"Vision/" + vp.cameraName() + "/Pose",
vp.visualPose()
);
});
vision.addPoseEstimateConsumer((vp) -> {
if(resetOdometryToVisualPose) {
drivetrain.resetOdometry(vp.visualPose());
resetOdometryToVisualPose = false;
}
});
driver = new CommandXboxController(OIConstants.kDriverControllerPort);
secondary = new CommandXboxController(OIConstants.kOperatorControllerPort);
shiftTimer = new Timer();
shiftTimer.reset();
configureBindings();
//testConfigureBindings();
configureShiftDisplay();
if(AutoConstants.kAutoConfigOk) {
autoChooser = AutoBuilder.buildAutoChooser();
SmartDashboard.putData("Auto Chooser", autoChooser);
}
}
/**
* Before you @ mention me for terrible match controls, these are <i>TEST BINDINGS</i>
*
* The are configured in such a way to make testing of multiple systems possible without
* having to constantly change bindings.
*
* Most of the configurations here won't make sense for actual competition play. See
* {@link #configureBindings()} for actual competition play
*
* The intent of each binding is outlined by comments above each binding.
*/
private void testConfigureBindings() {
// This should just work, if it doesn't it's likely modules aren't assigned the right IDs
// after the electronics rebuild. For testing normal operation nothing about the Drivetrain
// class should need to change
//drivetrain.setDefaultCommand(drivetrain.drive(() -> 0, () -> 0, () -> 0, () -> true));
drivetrain.setDefaultCommand(
drivetrain.drive(
driver::getLeftY,
driver::getLeftX,
driver::getRightX,
() -> true
)
);
driver.y().whileTrue(drivetrain.zeroHeading());
/*
// This needs to be tested after a prolonged amount of driving around <i>aggressively</i>.
// Do things like going over the bump repeatedly, spin around a bunch, etc.
// If this works well over time, then this is likely all we need
driver.a().whileTrue(
drivetrain.lockRotationToHub(
driver::getLeftY,
driver::getLeftX,
false
)
);
// This can be tested as an alternative to the above, it's less dynamic, but is a simpler
// alternative.
driver.b().whileTrue(
drivetrain.lockToYaw(
() -> {
OptionalDouble maybeYaw = vision.getBestYawForTag(Utilities.getHubCenterAprilTagID());
return maybeYaw.isEmpty() ? 0 : maybeYaw.getAsDouble();
},
driver::getLeftY,
driver::getLeftX
)
);*/
// Stop everything by default other than the drivetrain
shooter.setDefaultCommand(shooter.stop());
intakePivot.setDefaultCommand(intakePivot.stop());
intakeRoller.setDefaultCommand(intakeRoller.stop());
hood.setDefaultCommand(hood.stop());
spindexer.setDefaultCommand(spindexer.stop());
//climber.setDefaultCommand(climber.stop());
// While holding POV up of the driver controller, the climber
// should move such that its motor moves the climber down with the left
// driver controller trigger axis, and up with the right driver controller
// trigger axis.
// DO NOT INVERT MOTION WITH UNARY MINUS (-). Every motor can be inverted
// from the constants file for the subsystem having the problem.
//driver.povUp().whileTrue(climber.manualSpeed(() -> {
// return driver.getLeftTriggerAxis() * -1 + driver.getRightTriggerAxis();
//}));
// While holding the right bumper of the driver controller, the intake rollers
// and the spindexer and feeder should move such that all motors are moving in such a way
// that it would draw balls from the floor, through the spindexer, and into the
// feeder.
// DO NOT INVERT MOTION WITH UNARY MINUS (-). Every motor can be inverted from the
// constants file for the subsystem having the problem
driver.rightBumper().whileTrue(
spindexer.spinToShooter()
);
// While holding the left bumper of the driver controller, the intake rollers
// and the spindexer and feeder should move such that all motors are moving in such a way
// that it would try to eject balls through the intake.
// DO NOT INVERT MOTION WITH UNARY MINUS (-). Every motor can be inverted from the
// constants file for the subsystem having the problem
driver.leftBumper().whileTrue(
intakeRoller.runIn()
//intakeRoller.runOut().alongWith(spindexer.spinToIntake())
);
// While holding D-Pad up on the secondary controller, the shooter should spin
// while holding down the secondary controllers right trigger some amount.
// DO NOT INVERT MOTION WITH UNARY MINUS (-). Every motor can be inverted from the
// constants file for the subsystem having the problem
secondary.povUp().whileTrue(
shooter.manualSpeed(secondary::getRightTriggerAxis)
);
// While holding D-Pad down on the seconadry controller, the intakePivot should move
// such that left trigger on the secondary controller moves the pivot down, and
// right trigger on the secondary controller moves the pivot up.
// DO NOT INVERT MOTION WITH UNARY MINUS (-). Every motor can be inverted from the
// constants file for the subsystem having the problem
secondary.povDown().whileTrue(
intakePivot.manualSpeed(() -> {
return secondary.getLeftTriggerAxis() * -1 + secondary.getRightTriggerAxis();
})
);
// While holding D-Pad left on the secondary controller, the hood should move
// such that the left trigger on the secondary controller moves the hood down, and
// right trigger on the secondary controller moves the hood up.
// DO NOT INVERT MOTION WITH UNARY MINUS (-). Every motor can be inverted from the
// constants file for the subsystem having the problem
secondary.povLeft().whileTrue(
hood.manualSpeed(() -> {
return secondary.getLeftTriggerAxis() * -1 + secondary.getRightTriggerAxis();
})
);
// STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP
// Don't proceed unless you've verified by hand or with the above bindings, that sensing
// systems are providing correct values in the correct direction of rotation.
// Useful for testing PID and FF responses of the shooter
// You need to have graphs up of the logged data to make sure the response is correct
secondary.a().whileTrue(shooter.maintainSpeed(ShooterSpeeds.kHubSpeed));
secondary.b().whileTrue(shooter.maintainSpeed(ShooterSpeeds.kFeedSpeed));
// Useful for testing PID and FF responses of the intake pivot
// You need to have graphs up of the logged data to make sure the response is correct
secondary.x().whileTrue(intakePivot.maintainPosition(IntakePivotPosition.kDown));
secondary.y().whileTrue(intakePivot.maintainPosition(IntakePivotPosition.kUp));
secondary.povUp().whileTrue(hood.trackToAngle(() -> Math.toRadians(40.0)));
secondary.povDown().whileTrue(hood.trackToAngle(() -> Math.toRadians(0.0)));
// TODO Some means of testing hood PIDF
// TODO Some means of testing climber PIDF
}
private void configureBindings() {
drivetrain.setDefaultCommand(
drivetrain.drive(
driver::getLeftY,
driver::getLeftX,
driver::getRightX,
() -> true
)
);
shooter.setDefaultCommand(shooter.stop());
intakeRoller.setDefaultCommand(intakeRoller.stop());
spindexer.setDefaultCommand(spindexer.stop());
intakePivot.setDefaultCommand(intakePivot.manualSpeed(() -> secondary.getLeftY()));
driver.a().onTrue(new InstantCommand(() -> resetOdometryToVisualPose = true));
driver.y().whileTrue(drivetrain.zeroHeading());
driver.leftTrigger().whileTrue(
drivetrain.lockRotationToHub(
driver::getLeftY,
driver::getLeftX,
false
)
);
driver.leftBumper().whileTrue(intakeRoller.runOut());
driver.rightBumper().whileTrue(intakeRoller.runIn());
driver.rightTrigger().whileTrue(spindexer.spinToShooter());
driver.b().whileTrue(spindexer.spinToIntake());
/* driver.b().whileTrue(
drivetrain.lockToYaw(
() -> {
OptionalDouble maybeYaw = vision.getBestYawForTag(Utilities.getHubCenterAprilTagID());
return maybeYaw.isEmpty() ? 0 : maybeYaw.getAsDouble();
},
driver::getLeftY,
driver::getLeftX
)
);*/
secondary.a().toggleOnTrue(shooter.maintainSpeed(ShooterSpeeds.kHubSpeed));
secondary.x().toggleOnTrue(shooter.maintainSpeed(ShooterSpeeds.kFeedSpeed));
//hood.setDefaultCommand(hood.trackToAngle(() -> Units.degreesToRadians(MathUtil.clamp(hoodAngle, 0, 40))));
//secondary.y().onTrue(hood.trackToAngle(() -> Units.degreesToRadians(40)));
//40 good for feeding
//secondary.b().onTrue(hood.trackToAngle(() -> Units.degreesToRadians(30)));
//30 degrees good for shooter far near outpost
secondary.rightBumper().onTrue(hood.trackToAngle(() -> Units.degreesToRadians(10)));
//10 degrees good for shooting ~33in away from hub
hood.setDefaultCommand(hood.trackToAngle(() -> {
Pose2d drivetrainPose = drivetrain.getPose();
Pose2d hubPose = Utilities.getHubPose();
double distance = drivetrainPose.getTranslation()
.getDistance(hubPose.getTranslation());
Logger.recordOutput("Hood/DistanceToHub", distance);
Optional<ShooterSpeeds> currentSpeeds = shooter.getTargetSpeeds();
if(currentSpeeds.isPresent()) {
InterpolatingDoubleTreeMap map = HoodConstants.kHoodInterpolators.get(currentSpeeds.get());
if(map != null) {
return MathUtil.clamp(map.get(distance), 0, 40);
} else {
return 0;
}
} else {
return 0;
}
}));
}
private void configureNamedCommands() {
NamedCommands.registerCommand(
"Drivetrain Set X",
drivetrain.setX()
);
NamedCommands.registerCommand(
"Drivetrain Face Hub",
drivetrain.rotateToPose(
Utilities.getHubPose(),
false // TODO Should this be true by default?
)
);
NamedCommands.registerCommand(
"intake down",
intakePivot.manualSpeed(()->0.75)
.withTimeout(1)
);
NamedCommands.registerCommand("spinup",
shooter.maintainSpeed(ShooterSpeeds.kHubSpeed)
.withTimeout(3));
NamedCommands.registerCommand("shoot close",
spindexer.spinToShooter()
.alongWith(shooter.maintainSpeed(ShooterSpeeds.kHubSpeed))
.alongWith(hood.trackToAngle(() -> Units.degreesToRadians(10)))
.withTimeout(3).andThen(spindexer.instantaneousStop()));
// NamedCommands.registerCommand("Intake Start", intakeRoller.runIn());
new EventTrigger("Intake Start")
.onTrue(intakeRoller.runIn());
NamedCommands.registerCommand("stop spindexer", spindexer.instantaneousStop());
NamedCommands.registerCommand("jimmy",
Commands.repeatingSequence(
intakePivot.manualSpeed(() -> -0.75).withTimeout(0.2)
.andThen(intakePivot.manualSpeed(() -> 0.75).withTimeout(0.2))
)
);
NamedCommands.registerCommand("shoot N jimmy",
Commands.parallel(
Commands.repeatingSequence(
intakePivot.manualSpeed(() -> -0.75).withTimeout(0.5),
intakePivot.manualSpeed(() -> 0.75).withTimeout(0.5)
),
spindexer.spinToShooter()
.alongWith(shooter.maintainSpeed(ShooterSpeeds.kHubSpeed),
hood.trackToAngle(() -> Units.degreesToRadians(10)))
).withTimeout(3).andThen(spindexer.instantaneousStop()));
}
public Command getAutonomousCommand() {
return autoChooser.getSelected();
}
/**
* The "shift display" relies on Elastic's ability to show 1 or more colors
* in a box on the dashboard.
*
* Using the RobotModeTriggers and a Timer based on the FPGA, a reasonably
* accurate "shift display" can be created to indicate whose hub is active
* and when.
*
* During autonomous, and the first 10 seconds of teleop, the shift display
* will display a gradient of both red and blue, indicating the fact that
* both hubs are active.
*
* For the rest of teleop, with the exception of the endgame, the display
* will present either the color red, or the color blue, based on the returned
* value of Utilities.whoHasFirstShift(). Because shifts change on a known cycle,
* we can use the known state of who has first shift, to determine the remaining three shifts
* that come after.
*
* For the endgame portion of teleop, the shift display returns to the gradient
* of both red and blue.
*
* Because this relies on the RobotModeTriggers and an FPGA timer, it should be
* <i>reasonably</i> accurate, it's unlikely to be perfect relative to field time
* but it will be very very very (likely unnoticably) close.
*/
private void configureShiftDisplay() {
SmartDashboard.putStringArray(OIConstants.kCurrentActiveHub, OIConstants.kRedBlueDisplay);
RobotModeTriggers.autonomous().onTrue(new InstantCommand(() -> {
shiftTimer.stop();
SmartDashboard.putStringArray(OIConstants.kCurrentActiveHub, OIConstants.kRedBlueDisplay);
}));
RobotModeTriggers.teleop().onTrue(new InstantCommand(() -> {
Elastic.selectTab(OIConstants.kTeleopTab);
shiftTimer.reset();
shiftTimer.start();
}));
new Trigger(() -> shiftTimer.get() <= 10).onTrue(new InstantCommand(() -> {
SmartDashboard.putStringArray(OIConstants.kCurrentActiveHub, OIConstants.kRedBlueDisplay);
}));
new Trigger(() -> shiftTimer.get() > 10 && shiftTimer.get() <= 35).onTrue(new InstantCommand(() -> {
SmartDashboard.putStringArray(
OIConstants.kCurrentActiveHub,
Utilities.whoHasFirstShift() == Alliance.Red ? OIConstants.kRedDisplay : OIConstants.kBlueDisplay
);
}));
new Trigger(() -> shiftTimer.get() > 35 && shiftTimer.get() <= 60).onTrue(new InstantCommand(() -> {
SmartDashboard.putStringArray(
OIConstants.kCurrentActiveHub,
Utilities.whoHasFirstShift() == Alliance.Red ? OIConstants.kBlueDisplay : OIConstants.kRedDisplay
);
}));
new Trigger(() -> shiftTimer.get() > 60 && shiftTimer.get() <= 85).onTrue(new InstantCommand(() -> {
SmartDashboard.putStringArray(
OIConstants.kCurrentActiveHub,
Utilities.whoHasFirstShift() == Alliance.Red ? OIConstants.kRedDisplay : OIConstants.kBlueDisplay
);
}));
new Trigger(() -> shiftTimer.get() > 85 && shiftTimer.get() <= 110).onTrue(new InstantCommand(() -> {
SmartDashboard.putStringArray(
OIConstants.kCurrentActiveHub,
Utilities.whoHasFirstShift() == Alliance.Red ? OIConstants.kBlueDisplay : OIConstants.kRedDisplay
);
}));
new Trigger(() -> shiftTimer.get() > 110).onTrue(new InstantCommand(() -> {
SmartDashboard.putStringArray(OIConstants.kCurrentActiveHub, OIConstants.kRedBlueDisplay);
}));
}
}
@@ -1,15 +1,18 @@
package first.robot.constants;
package frc.robot.constants;
import java.io.IOException;
import org.json.simple.parser.ParseException;
import org.wpilib.math.trajectory.TrapezoidProfile;
import com.pathplanner.lib.config.PIDConstants;
import com.pathplanner.lib.config.RobotConfig;
import com.pathplanner.lib.controllers.PPHolonomicDriveController;
import com.pathplanner.lib.path.PathConstraints;
import edu.wpi.first.math.trajectory.TrapezoidProfile;
import edu.wpi.first.math.util.Units;
// TODO This is all hold over from 2025, does any of it need to change?
public class AutoConstants {
public static final double kMaxSpeedMetersPerSecond = 4;
public static final double kMaxAccelerationMetersPerSecondSquared = 4;
@@ -57,4 +60,4 @@ public class AutoConstants {
kAutoConfigOk = false;
}
}
}
}
@@ -1,10 +1,8 @@
package first.robot.constants;
import org.wpilib.hardware.bus.CANPort;
package frc.robot.constants;
import com.revrobotics.spark.FeedbackSensor;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
import com.revrobotics.spark.config.SparkMaxConfig;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
public class ClimberConstants {
// TODO Real values
@@ -24,8 +22,6 @@ public class ClimberConstants {
}
}
public static final CANPort kCANPort = CANPort.CAN_S0;
public static final int kMotorCANID = 0;
public static final double kConversionFactor = 0;
@@ -53,9 +49,6 @@ public class ClimberConstants {
.smartCurrentLimit(kCurrentLimit)
.idleMode(kIdleMode);
kMotorConfig.encoder
// Ignoring the red here for now. REVLib 2027alpha8 is entirely missing
// a solution for this. Issue is open and pending
// https://github.com/wpilibsuite/SystemcoreTesting/issues/401
.positionConversionFactor(kConversionFactor)
.velocityConversionFactor(kConversionFactor / 60);
kMotorConfig.closedLoop
@@ -1,14 +1,19 @@
package first.robot.constants;
package frc.robot.constants;
import org.wpilib.fields.Field;
import org.wpilib.fields.Fields;
import org.wpilib.math.geometry.Pose2d;
import org.wpilib.math.geometry.Rotation2d;
import org.wpilib.math.geometry.Transform3d;
import org.wpilib.math.util.Units;
import edu.wpi.first.apriltag.AprilTagFieldLayout;
import edu.wpi.first.apriltag.AprilTagFields;
import edu.wpi.first.math.geometry.Pose2d;
import edu.wpi.first.math.geometry.Rotation2d;
import edu.wpi.first.math.geometry.Transform3d;
import edu.wpi.first.math.util.Units;
public class CompetitionConstants {
public static final Field kField = Fields.FRC_2026_REBUILT_ANDY_MARK.loadField();
// THIS SHOULD BE FALSE DURING COMPETITION PLAY
public static final boolean kLogToNetworkTables = true;
public static final AprilTagFieldLayout kTagLayout = AprilTagFieldLayout.loadField(
AprilTagFields.kDefaultField
);
public static final double kHubGoalHeightMeters = Units.inchesToMeters(72);
@@ -1,13 +1,12 @@
package first.robot.constants;
package frc.robot.constants;
import org.wpilib.hardware.bus.CANPort;
import org.wpilib.math.geometry.Translation2d;
import org.wpilib.math.kinematics.SwerveDriveKinematics;
import org.wpilib.math.linalg.Matrix;
import org.wpilib.math.linalg.VecBuilder;
import org.wpilib.math.numbers.N1;
import org.wpilib.math.numbers.N3;
import org.wpilib.math.util.Units;
import edu.wpi.first.math.Matrix;
import edu.wpi.first.math.VecBuilder;
import edu.wpi.first.math.geometry.Translation2d;
import edu.wpi.first.math.kinematics.SwerveDriveKinematics;
import edu.wpi.first.math.numbers.N1;
import edu.wpi.first.math.numbers.N3;
import edu.wpi.first.math.util.Units;
public class DrivetrainConstants {
public static final double kMaxSpeedMetersPerSecond = 4.663;
@@ -21,8 +20,6 @@ public class DrivetrainConstants {
public static final double kRearLeftMagEncoderOffset = 3.761;
public static final double kRearRightMagEncoderOffset = 2.573;
public static final CANPort kCANPort = CANPort.CAN_S0;
public static final int kFrontLeftDrivingCANID = 4;
public static final int kFrontRightDrivingCANID = 3;
public static final int kRearLeftDrivingCANID = 1;
@@ -49,7 +46,7 @@ public class DrivetrainConstants {
// TODO How much do we trust gyro and encoders vs vision estimates.
// NOTE: Bigger values indicate LESS trust. Generally all three values for a given matrix should be the same
public static final Matrix<N3, N1> kSensorFusionOdometryStdDevs = VecBuilder.fill(0.1, 0.1, 0.1);
public static final Matrix<N3, N1> kVisionOdometryStdDevs = VecBuilder.fill(0.3, 0.3, 0.3);
public static final Matrix<N3, N1> kVisionOdometryStdDevs = VecBuilder.fill(0.9, 0.9, 0.9);
// YOU SHOULDN'T NEED TO CHANGE ANYTHING BELOW THIS LINE UNLESS YOU'RE ADDING A NEW CONFIGURATION ITEM
public static final SwerveDriveKinematics kDriveKinematics = new SwerveDriveKinematics(
@@ -1,22 +1,24 @@
package first.robot.constants;
package frc.robot.constants;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Map;
import org.wpilib.hardware.bus.CANPort;
import org.wpilib.math.interpolation.InterpolatingDoubleTreeMap;
import org.wpilib.math.util.Units;
import com.revrobotics.spark.ClosedLoopSlot;
import com.revrobotics.spark.FeedbackSensor;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
import com.revrobotics.spark.config.SparkMaxConfig;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
import first.robot.constants.ShooterConstants.ShooterSpeeds;
import edu.wpi.first.math.interpolation.InterpolatingDoubleTreeMap;
import edu.wpi.first.math.util.Units;
import edu.wpi.first.wpilibj.Filesystem;
import frc.robot.constants.ShooterConstants.ShooterSpeeds;
public class HoodConstants {
// TODO Real Values
public static final CANPort kCANPort = CANPort.CAN_S0;
public static final int kMotorCANID = 12;
public static final double kConversionFactor = (1.0/3.0)*(8.0/147.0)*2*Math.PI;
@@ -57,9 +59,6 @@ public class HoodConstants {
.inverted(kInverted)
.smartCurrentLimit(kCurrentLimit);
kConfig.encoder
// Ignoring the red here for now. REVLib 2027alpha8 is entirely missing
// a solution for this. Issue is open and pending
// https://github.com/wpilibsuite/SystemcoreTesting/issues/401
.positionConversionFactor(kConversionFactor)
.velocityConversionFactor(kConversionFactor / 60);
kConfig.closedLoop
@@ -72,22 +71,22 @@ public class HoodConstants {
kHoodInterpolators.get(ShooterSpeeds.kHubSpeed).put(
Double.valueOf(Units.inchesToMeters(22.2 + 40)),
Double.valueOf(Units.degreesToRadians(9.5)));
Double.valueOf(Units.degreesToRadians(10)));
kHoodInterpolators.get(ShooterSpeeds.kHubSpeed).put(
Double.valueOf(Units.inchesToMeters(22.2 + 60)),
Double.valueOf(Units.degreesToRadians(12.5)));
Double.valueOf(Units.degreesToRadians(13)));
kHoodInterpolators.get(ShooterSpeeds.kHubSpeed).put(
Double.valueOf(Units.inchesToMeters(22.2 + 80)),
Double.valueOf(Units.degreesToRadians(16.25)));
Double.valueOf(Units.degreesToRadians(17)));
kHoodInterpolators.get(ShooterSpeeds.kHubSpeed).put(
Double.valueOf(Units.inchesToMeters(22.2 + 100)),
Double.valueOf(Units.degreesToRadians(20.5)));
Double.valueOf(Units.degreesToRadians(21)));
kHoodInterpolators.get(ShooterSpeeds.kHubSpeed).put(
Double.valueOf(Units.inchesToMeters(22.2 + 120)),
Double.valueOf(Units.degreesToRadians(23.5)));
Double.valueOf(Units.degreesToRadians(24)));
}
}
@@ -1,35 +1,25 @@
package first.robot.constants;
import org.wpilib.hardware.bus.CANPort;
package frc.robot.constants;
import com.revrobotics.spark.FeedbackSensor;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
import com.revrobotics.spark.config.SparkMaxConfig;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
public class IntakePivotConstants {
// TODO Real values
public enum IntakePivotPosition {
kUp(Math.toRadians(116.0)),
kDown(Math.toRadians(0.0));
private double positionRadians;
private double positionRotations;
private IntakePivotPosition(double positionRadians) {
this.positionRadians = positionRadians;
this.positionRotations = positionRadians / kConversionFactor;
}
public double getPositionRadians() {
return positionRadians;
}
public double getPositionRotations() {
return positionRotations;
}
}
public static final CANPort kCANPort = CANPort.CAN_S0;
public static final int kLeftMotorCANID = 16;
public static final int kRightMotorCANID = 9;
@@ -63,9 +53,6 @@ public class IntakePivotConstants {
.smartCurrentLimit(kCurrentLimit)
.inverted(false);
KLeftMotorConfig.encoder
// Ignoring the red here for now. REVLib 2027alpha8 is entirely missing
// a solution for this. Issue is open and pending
// https://github.com/wpilibsuite/SystemcoreTesting/issues/401
.positionConversionFactor(kConversionFactor)
.velocityConversionFactor(kConversionFactor / 60);
KLeftMotorConfig.closedLoop
@@ -73,9 +60,6 @@ public class IntakePivotConstants {
.pid(kP, kI, kD)
.outputRange(-1, 1)
.positionWrappingEnabled(true)
// Ignoring the red here for now. REVLib 2027alpha8 is entirely missing
// a solution for this. Issue is open and pending
// https://github.com/wpilibsuite/SystemcoreTesting/issues/401
.positionWrappingInputRange(0, 2 * Math.PI)
.feedForward
.svag(kS, kV, kA, kG);
@@ -1,14 +1,10 @@
package first.robot.constants;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
import org.wpilib.hardware.bus.CANPort;
package frc.robot.constants;
import com.revrobotics.spark.config.SparkMaxConfig;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
public class IntakeRollerConstants {
public static final CANPort kCANPort = CANPort.CAN_S0;
// TODO Real values
public static final int kRightMotorCANID = 20;
public static final int kLeftMotorCANID = 1;
@@ -17,8 +13,7 @@ public class IntakeRollerConstants {
public static final boolean kInvertLeftMotor = false;
public static final boolean kInvertRightMotor = true;
public static final double kIntakeInSpeed = .9;
public static final double kIntakeOutSpeed = 1;
public static final double kSpeed = 1;
public static final IdleMode kIdleMode = IdleMode.kCoast;
@@ -1,5 +1,5 @@
package first.robot.constants;
package frc.robot.constants;
public class KrakenMotorConstants {
public static final double kFreeSpeedRPM = 6000;
}
}
@@ -1,7 +1,4 @@
package first.robot.constants;
import org.wpilib.hardware.bus.CANPort;
import org.wpilib.math.util.Units;
package frc.robot.constants;
import com.ctre.phoenix6.configs.AudioConfigs;
import com.ctre.phoenix6.configs.ClosedLoopRampsConfigs;
@@ -13,8 +10,10 @@ import com.ctre.phoenix6.signals.InvertedValue;
import com.ctre.phoenix6.signals.NeutralModeValue;
import com.revrobotics.spark.ClosedLoopSlot;
import com.revrobotics.spark.FeedbackSensor;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
import com.revrobotics.spark.config.SparkMaxConfig;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
import edu.wpi.first.math.util.Units;
public class ModuleConstants {
public enum ModuleName {
@@ -30,7 +29,7 @@ public class ModuleConstants {
}
public String getLoggableName() {
return loggableName;
return "Drivetrain/Modules/" + loggableName;
}
}
@@ -57,7 +56,7 @@ public class ModuleConstants {
// TODO Hold over from 2025, adjust?
public static final int kDriveMotorStatorCurrentLimit = 90;
public static final int kDriveMotorSupplyCurrentLimit = 40;
public static final int kDriveMotorSupplyCurrentLimit = 55;
// TODO Hold over from 2025, adjust?
public static final InvertedValue kDriveInversionState = InvertedValue.Clockwise_Positive;
@@ -120,9 +119,7 @@ public class ModuleConstants {
.smartCurrentLimit(kTurnMotorCurrentLimit)
.inverted(true);
turningConfig.encoder
// Ignoring the red here for now. REVLib 2027alpha8 is entirely missing
// a solution for this. Issue is open and pending
// https://github.com/wpilibsuite/SystemcoreTesting/issues/401
//.inverted(true)
.positionConversionFactor(kTurningFactor)
.velocityConversionFactor(kTurningFactor / 60.0);
turningConfig.closedLoop
@@ -131,9 +128,6 @@ public class ModuleConstants {
.outputRange(-1, 1)
.allowedClosedLoopError(kTurnTolerance, ClosedLoopSlot.kSlot0)
.positionWrappingEnabled(true)
// Ignoring the red here for now. REVLib 2027alpha8 is entirely missing
// a solution for this. Issue is open and pending
// https://github.com/wpilibsuite/SystemcoreTesting/issues/401
.positionWrappingInputRange(0, 2 * Math.PI);
}
@@ -1,6 +1,6 @@
package first.robot.constants;
package frc.robot.constants;
import org.wpilib.util.Color;
import edu.wpi.first.wpilibj.util.Color;
public class OIConstants {
public static final int kDriverControllerPort = 0;
@@ -15,15 +15,15 @@ public class OIConstants {
public static final String kCurrentActiveHub = "Alliance Hub Currently Active";
public static final String[] kRedBlueDisplay = {
Color.RED.toHexString(),
Color.BLUE.toHexString()
Color.kRed.toHexString(),
Color.kBlue.toHexString()
};
public static final String[] kRedDisplay = {
Color.RED.toHexString()
Color.kRed.toHexString()
};
public static final String[] kBlueDisplay = {
Color.BLUE.toHexString()
Color.kBlue.toHexString()
};
}
@@ -1,12 +1,11 @@
package first.robot.constants;
package frc.robot.constants;
import java.util.List;
import org.wpilib.math.geometry.Rotation3d;
import org.wpilib.math.geometry.Transform3d;
import org.wpilib.math.util.Units;
import first.robot.utilities.PhotonVisionConfig;
import edu.wpi.first.math.geometry.Rotation3d;
import edu.wpi.first.math.geometry.Transform3d;
import edu.wpi.first.math.util.Units;
import frc.robot.utilities.PhotonVisionConfig;
public class PhotonConstants {
public static final String kCamera1Name = "CameraPV1";
@@ -45,4 +44,4 @@ public class PhotonConstants {
new PhotonVisionConfig(kCamera1Name, kCamera1RobotToCam, kCamera1HeightMeters, kCamera1PitchRadians),
new PhotonVisionConfig(kCamera2Name, kCamera2RobotToCam, kCamera2HeightMeters, kCamera2PitchRadians)
);
}
}
@@ -1,11 +1,10 @@
package first.robot.constants;
package frc.robot.constants;
import org.wpilib.math.util.Units;
import com.revrobotics.spark.ClosedLoopSlot;
import com.revrobotics.spark.FeedbackSensor;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
import com.revrobotics.spark.config.SparkMaxConfig;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
import edu.wpi.first.math.util.Units;
public class ShooterConstants {
public enum ShooterSpeeds {
@@ -41,18 +40,18 @@ public class ShooterConstants {
public static final boolean kLeftShooterMotorInverted = true;
public static final boolean kRightShooterMotorInverted = false;
public static final double kLeftP = 0.75;//0.01;//0.001;
public static final double kLeftP = 0.001;
public static final double kLeftI = 0;
public static final double kLeftD = 0;//0.1;//1.8;
public static final double kLeftD = 0;
public static final double kLeftS = 0;
public static final double kLeftV = 0.00129;
public static final double kLeftV = 0.0013;
public static final double kLeftA = 0;
public static final double kRightP = 0.75;//0.001;//0.001;
public static final double kRightP = 0.001;
public static final double kRightI = 0;
public static final double kRightD = 0;//0.1;
public static final double kRightD = 0.000;
public static final double kRightS = 0;
public static final double kRightV = 0.00125;
public static final double kRightV = 0.00121;
public static final double kRightA = 0;
public static final double kMaxManualSpeedMultiplier = 1;
@@ -69,44 +68,35 @@ public class ShooterConstants {
public static final SparkMaxConfig kLeftMotorConfig = new SparkMaxConfig();
public static final SparkMaxConfig kRightMotorConfig = new SparkMaxConfig();
static {
kLeftMotorConfig
.idleMode(kShooterIdleMode)
.smartCurrentLimit(kCurrentLimit)
.inverted(kLeftShooterMotorInverted);
kLeftMotorConfig.absoluteEncoder
// Ignoring the red here for now. REVLib 2027alpha8 is entirely missing
// a solution for this. Issue is open and pending
// https://github.com/wpilibsuite/SystemcoreTesting/issues/401
.positionConversionFactor(1)
.velocityConversionFactor(60)
.averageDepth(8); // VERY IMPORTANT FOR RESPONSE OF FLYWHEEL DEFAULTS ARE DOGWATER
.velocityConversionFactor(60);
kLeftMotorConfig.closedLoop
.feedbackSensor(FeedbackSensor.kAbsoluteEncoder)
.pid(kLeftP, kLeftI, kLeftD, ClosedLoopSlot.kSlot0)
.pid(kLeftP, kLeftI, kLeftD)
.outputRange(-1, 1)
.allowedClosedLoopError(25.0, ClosedLoopSlot.kSlot0)
.feedForward
.sva(kLeftS, kLeftV, kLeftA, ClosedLoopSlot.kSlot0);
.sva(kLeftS, kLeftV, kLeftA);
kRightMotorConfig
.idleMode(kShooterIdleMode)
.smartCurrentLimit(kCurrentLimit)
.inverted(kRightShooterMotorInverted);
kRightMotorConfig.absoluteEncoder
// Ignoring the red here for now. REVLib 2027alpha8 is entirely missing
// a solution for this. Issue is open and pending
// https://github.com/wpilibsuite/SystemcoreTesting/issues/401
.positionConversionFactor(1)
.velocityConversionFactor(60)
.averageDepth(8)// VERY IMPORTANT FOR RESPONSE OF FLYWHEEL DEFAULTS ARE DOGWATER
.inverted(true);
kRightMotorConfig.closedLoop
.feedbackSensor(FeedbackSensor.kAbsoluteEncoder)
.pid(kRightP, kRightI, kRightD)
.outputRange(-1, 1)
.allowedClosedLoopError(25.0, ClosedLoopSlot.kSlot0)
.feedForward
.sva(kRightS, kRightV, kRightA, ClosedLoopSlot.kSlot0);
.sva(kRightS, kRightV, kRightA);
}
}
@@ -1,11 +1,11 @@
package first.robot.constants;
package frc.robot.constants;
import com.ctre.phoenix6.configs.CurrentLimitsConfigs;
import com.ctre.phoenix6.configs.MotorOutputConfigs;
import com.ctre.phoenix6.signals.InvertedValue;
import com.ctre.phoenix6.signals.NeutralModeValue;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
import com.revrobotics.spark.config.SparkMaxConfig;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
public class SpindexerConstants {
// TODO Real values
@@ -1,23 +1,22 @@
package first.robot.subsystems;
package frc.robot.subsystems;
import java.util.function.DoubleSupplier;
import org.wpilib.command2.Command;
import org.wpilib.command2.SubsystemBase;
import org.wpilib.epilogue.Logged;
import org.littletonrobotics.junction.Logger;
import com.revrobotics.PersistMode;
import com.revrobotics.RelativeEncoder;
import com.revrobotics.ResetMode;
import com.revrobotics.spark.SparkClosedLoopController;
import com.revrobotics.spark.SparkLowLevel.ControlType;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import com.revrobotics.spark.SparkMax;
import com.revrobotics.spark.SparkBase.ControlType;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import first.robot.constants.ClimberConstants;
import first.robot.constants.ClimberConstants.ClimberPositions;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
import frc.robot.constants.ClimberConstants;
import frc.robot.constants.ClimberConstants.ClimberPositions;
@Logged
public class Climber extends SubsystemBase {
private SparkMax motor;
@@ -28,11 +27,7 @@ public class Climber extends SubsystemBase {
private ClimberPositions targetPosition;
public Climber() {
motor = new SparkMax(
ClimberConstants.kCANPort,
ClimberConstants.kMotorCANID,
MotorType.kBrushless
);
motor = new SparkMax(ClimberConstants.kMotorCANID, MotorType.kBrushless);
motor.configure(
ClimberConstants.kMotorConfig,
@@ -47,20 +42,11 @@ public class Climber extends SubsystemBase {
targetPosition = null;
}
public double getTargetPositionMeters() {
if (targetPosition == null) {
return -1;
} else {
return targetPosition.getPositionMeters();
}
}
public double getCurrentPositionMeters() {
return encoder.getPosition().get();
}
public boolean isAtSetpoint() {
return controller.isAtSetpoint().get();
@Override
public void periodic() {
Logger.recordOutput("Climber/TargetPositionMeters", targetPosition == null ? -1 : targetPosition.getPositionMeters());
Logger.recordOutput("Climber/CurrentPositionMeters", encoder.getPosition());
Logger.recordOutput("Climber/AtSetpoint", controller.isAtSetpoint());
}
public Command maintainPosition(ClimberPositions position) {
@@ -78,7 +64,7 @@ public class Climber extends SubsystemBase {
return run(() -> {
targetPosition = null;
motor.setThrottle(speed.getAsDouble());
motor.set(speed.getAsDouble());
});
}
@@ -1,4 +1,4 @@
package first.robot.subsystems;
package frc.robot.subsystems;
import java.util.List;
import java.util.Optional;
@@ -6,35 +6,33 @@ import java.util.function.BooleanSupplier;
import java.util.function.DoubleSupplier;
import java.util.function.Supplier;
import org.wpilib.command2.Command;
import org.wpilib.command2.PrintCommand;
import org.wpilib.command2.SubsystemBase;
import org.wpilib.driverstation.Alliance;
import org.wpilib.driverstation.DriverStation;
import org.wpilib.driverstation.MatchState;
import org.wpilib.hardware.imu.OnboardIMU;
import org.wpilib.hardware.imu.OnboardIMU.MountOrientation;
import org.wpilib.math.controller.PIDController;
import org.wpilib.math.estimator.SwerveDrivePoseEstimator;
import org.wpilib.math.geometry.Pose2d;
import org.wpilib.math.geometry.Rotation2d;
import org.wpilib.math.kinematics.ChassisVelocities;
import org.wpilib.math.kinematics.SwerveDriveKinematics;
import org.wpilib.math.kinematics.SwerveModulePosition;
import org.wpilib.math.kinematics.SwerveModuleVelocity;
import org.wpilib.math.util.MathUtil;
import org.littletonrobotics.junction.Logger;
import com.pathplanner.lib.auto.AutoBuilder;
import com.pathplanner.lib.path.PathPlannerPath;
import com.studica.frc.AHRS;
import com.studica.frc.AHRS.NavXComType;
import first.robot.constants.AutoConstants;
import first.robot.constants.DrivetrainConstants;
import first.robot.constants.ModuleConstants.ModuleName;
import first.robot.constants.OIConstants;
import first.robot.constants.SystemCoreConstants;
import first.robot.utilities.SwerveModule;
import first.robot.utilities.Utilities;
import first.robot.utilities.VisualPose;
import edu.wpi.first.math.MathUtil;
import edu.wpi.first.math.controller.PIDController;
import edu.wpi.first.math.estimator.SwerveDrivePoseEstimator;
import edu.wpi.first.math.geometry.Pose2d;
import edu.wpi.first.math.geometry.Rotation2d;
import edu.wpi.first.math.kinematics.ChassisSpeeds;
import edu.wpi.first.math.kinematics.SwerveDriveKinematics;
import edu.wpi.first.math.kinematics.SwerveModulePosition;
import edu.wpi.first.math.kinematics.SwerveModuleState;
import edu.wpi.first.wpilibj.DriverStation;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.PrintCommand;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
import frc.robot.constants.AutoConstants;
import frc.robot.constants.DrivetrainConstants;
import frc.robot.constants.OIConstants;
import frc.robot.constants.ModuleConstants.ModuleName;
import frc.robot.utilities.SwerveModule;
import frc.robot.utilities.Utilities;
import frc.robot.utilities.VisualPose;
public class Drivetrain extends SubsystemBase {
private SwerveModule frontLeft;
@@ -42,7 +40,7 @@ public class Drivetrain extends SubsystemBase {
private SwerveModule rearLeft;
private SwerveModule rearRight;
private OnboardIMU imu;
private AHRS gyro;
private SwerveDrivePoseEstimator estimator;
@@ -50,7 +48,6 @@ public class Drivetrain extends SubsystemBase {
public Drivetrain(Pose2d startupPose) {
frontLeft = new SwerveModule(
DrivetrainConstants.kCANPort,
ModuleName.kFrontLeft,
DrivetrainConstants.kFrontLeftDrivingCANID,
DrivetrainConstants.kFrontLeftTurningCANID,
@@ -59,7 +56,6 @@ public class Drivetrain extends SubsystemBase {
);
frontRight = new SwerveModule(
DrivetrainConstants.kCANPort,
ModuleName.kFrontRight,
DrivetrainConstants.kFrontRightDrivingCANID,
DrivetrainConstants.kFrontRightTurningCANID,
@@ -68,7 +64,6 @@ public class Drivetrain extends SubsystemBase {
);
rearLeft = new SwerveModule(
DrivetrainConstants.kCANPort,
ModuleName.kRearLeft,
DrivetrainConstants.kRearLeftDrivingCANID,
DrivetrainConstants.kRearLeftTurningCANID,
@@ -77,7 +72,6 @@ public class Drivetrain extends SubsystemBase {
);
rearRight = new SwerveModule(
DrivetrainConstants.kCANPort,
ModuleName.kRearRight,
DrivetrainConstants.kRearRightDrivingCANID,
DrivetrainConstants.kRearRightTurningCANID,
@@ -85,7 +79,7 @@ public class Drivetrain extends SubsystemBase {
DrivetrainConstants.kRearRightMagEncoderOffset
);
imu = new OnboardIMU(SystemCoreConstants.kSystemCoreMountOrientation);
gyro = new AHRS(NavXComType.kMXP_SPI);
yawRotationController = new PIDController(
DrivetrainConstants.kHeadingP,
@@ -119,9 +113,9 @@ public class Drivetrain extends SubsystemBase {
AutoConstants.kPPDriveController,
AutoConstants.kRobotConfig,
() -> {
Optional<Alliance> alliance = MatchState.getAlliance();
Optional<DriverStation.Alliance> alliance = DriverStation.getAlliance();
if (alliance.isPresent()) {
return alliance.get() == Alliance.RED;
return alliance.get() == DriverStation.Alliance.Red;
}
return false;
},
@@ -175,7 +169,7 @@ public class Drivetrain extends SubsystemBase {
.get();
return run(() -> {
module.setDesiredState(new SwerveModuleVelocity(
module.setDesiredState(new SwerveModuleState(
staticSpeed,
Rotation2d.fromDegrees(staticAngleDegrees)
));
@@ -330,16 +324,16 @@ public class Drivetrain extends SubsystemBase {
public Command setX() {
return run(() -> {
frontLeft.setDesiredState(new SwerveModuleVelocity(0, Rotation2d.fromDegrees(45)));
frontRight.setDesiredState(new SwerveModuleVelocity(0, Rotation2d.fromDegrees(-45)));
rearLeft.setDesiredState(new SwerveModuleVelocity(0, Rotation2d.fromDegrees(-45)));
rearRight.setDesiredState(new SwerveModuleVelocity(0, Rotation2d.fromDegrees(45)));
frontLeft.setDesiredState(new SwerveModuleState(0, Rotation2d.fromDegrees(45)));
frontRight.setDesiredState(new SwerveModuleState(0, Rotation2d.fromDegrees(-45)));
rearLeft.setDesiredState(new SwerveModuleState(0, Rotation2d.fromDegrees(-45)));
rearRight.setDesiredState(new SwerveModuleState(0, Rotation2d.fromDegrees(45)));
});
}
public Command zeroHeading() {
return run(() -> {
imu.resetYaw();;
gyro.reset();
estimator.resetRotation(new Rotation2d(0));
});
}
@@ -390,25 +384,26 @@ public class Drivetrain extends SubsystemBase {
double rotationDelivered = rotation * DrivetrainConstants.kMaxAngularSpeed;
ChassisVelocities velocities = new ChassisVelocities(xSpeedDelivered, ySpeedDelivered, rotationDelivered);
SwerveModuleVelocity[] swerveModuleStates = DrivetrainConstants.kDriveKinematics.toSwerveModuleVelocities(
SwerveModuleState[] swerveModuleStates = DrivetrainConstants.kDriveKinematics.toSwerveModuleStates(
fieldRelative ?
velocities.toFieldRelative(Rotation2d.fromDegrees(getGyroValue())) : velocities
ChassisSpeeds.fromFieldRelativeSpeeds(xSpeedDelivered, ySpeedDelivered, rotationDelivered,
//estimator.getEstimatedPosition().getRotation()) :
Rotation2d.fromDegrees(getGyroValue())) :
new ChassisSpeeds(xSpeedDelivered, ySpeedDelivered, rotationDelivered)
);
setModuleStates(swerveModuleStates);
}
public void driveWithChassisSpeeds(ChassisVelocities speeds) {
ChassisVelocities discreteSpeeds = speeds.discretize(0.2);
SwerveModuleVelocity[] newStates = DrivetrainConstants.kDriveKinematics.toSwerveModuleVelocities(discreteSpeeds);
public void driveWithChassisSpeeds(ChassisSpeeds speeds) {
ChassisSpeeds discreteSpeeds = ChassisSpeeds.discretize(speeds, 0.2);
SwerveModuleState[] newStates = DrivetrainConstants.kDriveKinematics.toSwerveModuleStates(discreteSpeeds);
setModuleStates(newStates);
}
public void setModuleStates(SwerveModuleVelocity[] desiredStates) {
SwerveDriveKinematics.desaturateWheelVelocities(
public void setModuleStates(SwerveModuleState[] desiredStates) {
SwerveDriveKinematics.desaturateWheelSpeeds(
desiredStates, DrivetrainConstants.kMaxSpeedMetersPerSecond);
frontLeft.setDesiredState(desiredStates[0]);
frontRight.setDesiredState(desiredStates[1]);
@@ -416,8 +411,8 @@ public class Drivetrain extends SubsystemBase {
rearRight.setDesiredState(desiredStates[3]);
}
public ChassisVelocities getCurrentChassisSpeeds() {
return DrivetrainConstants.kDriveKinematics.toChassisVelocities(
public ChassisSpeeds getCurrentChassisSpeeds() {
return DrivetrainConstants.kDriveKinematics.toChassisSpeeds(
frontLeft.getState(),
frontRight.getState(),
rearLeft.getState(),
@@ -430,7 +425,7 @@ public class Drivetrain extends SubsystemBase {
}
public double getGyroValue() {
return imu.getYawRadians() * (DrivetrainConstants.kGyroReversed ? -1 : 1);
return gyro.getAngle() * (DrivetrainConstants.kGyroReversed ? -1 : 1);
}
public Rotation2d getHeading() {
@@ -441,4 +436,3 @@ public class Drivetrain extends SubsystemBase {
return estimator.getEstimatedPosition().getRotation().getDegrees();
}
}
@@ -1,25 +1,23 @@
package first.robot.subsystems;
package frc.robot.subsystems;
import java.util.Optional;
import java.util.function.DoubleSupplier;
import org.wpilib.command2.Command;
import org.wpilib.command2.SubsystemBase;
import org.wpilib.math.geometry.Pose2d;
import org.wpilib.math.interpolation.InterpolatingDoubleTreeMap;
import org.wpilib.math.util.MathUtil;
import org.littletonrobotics.junction.Logger;
import com.revrobotics.PersistMode;
import com.revrobotics.RelativeEncoder;
import com.revrobotics.ResetMode;
import com.revrobotics.spark.SparkClosedLoopController;
import com.revrobotics.spark.SparkLowLevel.ControlType;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import com.revrobotics.spark.SparkMax;
import com.revrobotics.spark.SparkBase.ControlType;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import first.robot.constants.HoodConstants;
import first.robot.constants.ShooterConstants.ShooterSpeeds;
import first.robot.utilities.Utilities;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.InstantCommand;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
import edu.wpi.first.wpilibj2.command.button.Trigger;
import frc.robot.constants.HoodConstants;
public class Hood extends SubsystemBase {
private SparkMax motor;
@@ -36,11 +34,7 @@ public class Hood extends SubsystemBase {
private double currentTargetDegrees;
public Hood() {
motor = new SparkMax(
HoodConstants.kCANPort,
HoodConstants.kMotorCANID,
MotorType.kBrushless
);
motor = new SparkMax(HoodConstants.kMotorCANID, MotorType.kBrushless);
motor.configure(
HoodConstants.kConfig,
@@ -74,21 +68,6 @@ public class Hood extends SubsystemBase {
@Override
public void periodic() {
SmartDashboard.putNumber(
"HoodTargetDegrees",
Math.toDegrees(currentTargetDegrees)
);
SmartDashboard.putNumber(
"HoodCurrentAngle",
Math.toDegrees(encoder.getPosition())
);
SmartDashboard.putBoolean(
"HoodAtSetpoint",
controller.isAtSetpoint()
);
Logger.recordOutput("Hood/OutputCurrent", motor.getOutputCurrent());
Logger.recordOutput("Hood/CurrentTarget", Math.toDegrees(currentTargetDegrees));
Logger.recordOutput("Hood/CurrentAngle", Math.toDegrees(encoder.getPosition()));
@@ -96,32 +75,6 @@ public class Hood extends SubsystemBase {
Logger.recordOutput("Hood/VoltageOut", motor.getAppliedOutput()*motor.getBusVoltage());
}
public Command trackToAnglePoseBased(Drivetrain drivetrain, Shooter shooter) {
return trackToAngle(() -> {
Pose2d drivetrainPose = drivetrain.getPose();
Pose2d hubPose = Utilities.getHubPose();
double distance = drivetrainPose.getTranslation()
.getDistance(hubPose.getTranslation());
Logger.recordOutput("Hood/DistanceToHub", distance);
Optional<ShooterSpeeds> currentSpeeds = shooter.getTargetSpeeds();
if(currentSpeeds.isPresent()) {
InterpolatingDoubleTreeMap map = HoodConstants.kHoodInterpolators.get(currentSpeeds.get());
if(map != null) {
return MathUtil.clamp(map.get(distance), 0, 40);
} else {
return 0;
}
} else {
return 0;
}
});
}
public Command trackToAngle(DoubleSupplier degreeAngleSupplier) {
return run(() -> {
currentTargetDegrees = degreeAngleSupplier.getAsDouble();
@@ -169,7 +122,7 @@ public class Hood extends SubsystemBase {
currentTargetDegrees = 0;
return run(() -> {
motor.setThrottle(speed.getAsDouble() * HoodConstants.kMaxManualSpeedMultiplier);
motor.set(speed.getAsDouble() * HoodConstants.kMaxManualSpeedMultiplier);
});
}
@@ -1,22 +1,22 @@
package first.robot.subsystems;
package frc.robot.subsystems;
import java.util.Optional;
import java.util.function.DoubleSupplier;
import org.wpilib.command2.Command;
import org.wpilib.command2.Commands;
import org.wpilib.command2.SubsystemBase;
import org.littletonrobotics.junction.Logger;
import com.revrobotics.PersistMode;
import com.revrobotics.RelativeEncoder;
import com.revrobotics.ResetMode;
import com.revrobotics.spark.SparkClosedLoopController;
import com.revrobotics.spark.SparkLowLevel.ControlType;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import com.revrobotics.spark.SparkMax;
import com.revrobotics.spark.SparkBase.ControlType;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import first.robot.constants.IntakePivotConstants;
import first.robot.constants.IntakePivotConstants.IntakePivotPosition;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
import frc.robot.constants.IntakePivotConstants;
import frc.robot.constants.IntakePivotConstants.IntakePivotPosition;
public class IntakePivot extends SubsystemBase {
private SparkMax leftMotor;
@@ -29,16 +29,8 @@ public class IntakePivot extends SubsystemBase {
private IntakePivotPosition currentTargetPosition;
public IntakePivot() {
leftMotor = new SparkMax(
IntakePivotConstants.kCANPort,
IntakePivotConstants.kLeftMotorCANID,
MotorType.kBrushless
);
rightMotor = new SparkMax(
IntakePivotConstants.kCANPort,
IntakePivotConstants.kRightMotorCANID,
MotorType.kBrushless
);
leftMotor = new SparkMax(IntakePivotConstants.kLeftMotorCANID, MotorType.kBrushless);
rightMotor = new SparkMax(IntakePivotConstants.kRightMotorCANID, MotorType.kBrushless);
leftMotor.configure(
IntakePivotConstants.KLeftMotorConfig,
@@ -83,36 +75,17 @@ public class IntakePivot extends SubsystemBase {
return run(() -> {
currentTargetPosition = null;
leftMotor.setThrottle(speed.getAsDouble() * IntakePivotConstants.kMaxManualSpeedMultiplier);
rightMotor.setThrottle(speed.getAsDouble() * IntakePivotConstants.kMaxManualSpeedMultiplier);
leftMotor.set(speed.getAsDouble() * IntakePivotConstants.kMaxManualSpeedMultiplier);
rightMotor.set(speed.getAsDouble() * IntakePivotConstants.kMaxManualSpeedMultiplier);
});
}
/**
* Repeatedly moves the intake up and down. AKA "Jimmying" the intake
*
* @param time How long the intake will go both ways for (seconds)
* @return Command that repeatedly Jimmys the intake
*/
public Command jimmy(double time){
return Commands.repeatingSequence(
manualSpeed(() -> -0.75).withTimeout(time),
manualSpeed(() -> 0.75).withTimeout(time)
);
}
/**
* Repeatedly moves the intake up and down. AKA "Jimmying" the intake
*
* @param time How long the intake will go both ways for (seconds)
* @return Command that repeatedly Jimmys the intake
*/
public Command jimmy(DoubleSupplier time) {
return Commands.repeatingSequence(
manualSpeed(() -> -0.75).withTimeout(time.getAsDouble()),
manualSpeed(() -> 0.75).withTimeout(time.getAsDouble())
);
}
// public Command jimmy(){
// return run(() -> {
// leftMotor.set(0.5 * IntakePivotConstants.kMaxManualSpeedMultiplier);
// rightMotor.set(0.5 * IntakePivotConstants.kMaxManualSpeedMultiplier);
// })
// }
public Command stop() {
return manualSpeed(() -> 0);
@@ -122,4 +95,3 @@ public class IntakePivot extends SubsystemBase {
return Optional.ofNullable(currentTargetPosition);
}
}
@@ -1,31 +1,21 @@
package first.robot.subsystems;
import org.wpilib.command2.Command;
import org.wpilib.command2.SubsystemBase;
package frc.robot.subsystems;
import com.revrobotics.PersistMode;
import com.revrobotics.ResetMode;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import com.revrobotics.spark.SparkMax;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import first.robot.constants.IntakeRollerConstants;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
import frc.robot.constants.IntakeRollerConstants;
public class IntakeRoller extends SubsystemBase {
private SparkMax leftMotor;
private SparkMax rightMotor;
public IntakeRoller() {
leftMotor = new SparkMax(
IntakeRollerConstants.kCANPort,
IntakeRollerConstants.kLeftMotorCANID,
MotorType.kBrushless
);
rightMotor = new SparkMax(
IntakeRollerConstants.kCANPort,
IntakeRollerConstants.kRightMotorCANID,
MotorType.kBrushless
);
leftMotor = new SparkMax(IntakeRollerConstants.kLeftMotorCANID, MotorType.kBrushless);
rightMotor = new SparkMax(IntakeRollerConstants.kRightMotorCANID, MotorType.kBrushless);
leftMotor.configure(
IntakeRollerConstants.leftMotorConfig,
@@ -42,22 +32,22 @@ public class IntakeRoller extends SubsystemBase {
public Command runIn() {
return run(() -> {
leftMotor.setThrottle(IntakeRollerConstants.kIntakeInSpeed);
rightMotor.setThrottle(IntakeRollerConstants.kIntakeInSpeed);
leftMotor.set(IntakeRollerConstants.kSpeed*0.8);
rightMotor.set(IntakeRollerConstants.kSpeed*0.8);
});
}
public Command runOut() {
return run(() -> {
leftMotor.setThrottle(-IntakeRollerConstants.kIntakeOutSpeed);
rightMotor.setThrottle(-IntakeRollerConstants.kIntakeOutSpeed);
leftMotor.set(-IntakeRollerConstants.kSpeed);
rightMotor.set(-IntakeRollerConstants.kSpeed);
});
}
public Command stop() {
return run(() -> {
leftMotor.setThrottle(0);
rightMotor.setThrottle(0);
leftMotor.set(0);
rightMotor.set(0);
});
}
@@ -1,4 +1,4 @@
package first.robot.subsystems;
package frc.robot.subsystems;
import java.util.ArrayList;
import java.util.List;
@@ -9,16 +9,18 @@ import java.util.function.Consumer;
import org.photonvision.EstimatedRobotPose;
import org.photonvision.PhotonCamera;
import org.photonvision.PhotonPoseEstimator;
import org.photonvision.PhotonPoseEstimator.PoseStrategy;
import org.photonvision.targeting.PhotonPipelineResult;
import org.photonvision.targeting.PhotonTrackedTarget;
import org.wpilib.command2.SubsystemBase;
import org.wpilib.math.geometry.Pose3d;
import org.wpilib.math.geometry.Transform3d;
import first.robot.constants.CompetitionConstants;
import first.robot.constants.PhotonConstants;
import first.robot.utilities.PhotonVisionConfig;
import first.robot.utilities.VisualPose;
import edu.wpi.first.math.geometry.Pose2d;
import edu.wpi.first.math.geometry.Pose3d;
import edu.wpi.first.math.geometry.Transform3d;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
import frc.robot.constants.CompetitionConstants;
import frc.robot.constants.PhotonConstants;
import frc.robot.utilities.PhotonVisionConfig;
import frc.robot.utilities.VisualPose;
/**
* This "Subsystem" is not actually a Subsystem. The intent is for this to be treated as
@@ -57,7 +59,8 @@ public class PhotonVision extends SubsystemBase {
for(int i = 0; i < PhotonConstants.configs.size(); i++) {
cameras[i] = new PhotonCamera(PhotonConstants.configs.get(i).cameraName());
estimators[i] = new PhotonPoseEstimator(
CompetitionConstants.kField,
CompetitionConstants.kTagLayout,
PoseStrategy.MULTI_TAG_PNP_ON_COPROCESSOR,
PhotonConstants.configs.get(i).robotToCamera()
);
latestResults.add(null);
@@ -74,7 +77,7 @@ public class PhotonVision extends SubsystemBase {
if(!results.isEmpty()) {
latestResults.set(i, results.get(results.size() - 1));
Optional<EstimatedRobotPose> pose = estimators[i].estimateCoprocMultiTagPose(latestResults.get(i));
Optional<EstimatedRobotPose> pose = estimators[i].update(latestResults.get(i));
if(!pose.isEmpty()) {
VisualPose visualPose = new VisualPose(
@@ -134,9 +137,9 @@ public class PhotonVision extends SubsystemBase {
// See PhotonPoseEstimator.multiTagOnCoprocStrategy
// TODO This doesn't currently account for the offset of the tag relative to say the hub
// unclear if that offset amount will be important or not
return Optional.of(Pose3d.ZERO
return Optional.of(Pose3d.kZero
.plus(bestCameraToTarget.inverse())
.relativeTo(CompetitionConstants.kField.getOrigin())
.relativeTo(CompetitionConstants.kTagLayout.getOrigin())
.plus(config.robotToCamera().inverse()));
}
@@ -201,4 +204,3 @@ public class PhotonVision extends SubsystemBase {
poseEstimateConsumers.add(consumer);
}
}
@@ -0,0 +1,123 @@
package frc.robot.subsystems;
import java.util.Optional;
import java.util.function.DoubleSupplier;
import org.littletonrobotics.junction.Logger;
import com.revrobotics.AbsoluteEncoder;
import com.revrobotics.PersistMode;
import com.revrobotics.RelativeEncoder;
import com.revrobotics.ResetMode;
import com.revrobotics.spark.SparkClosedLoopController;
import com.revrobotics.spark.SparkMax;
import com.revrobotics.spark.SparkBase.ControlType;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
import frc.robot.constants.ShooterConstants;
import frc.robot.constants.ShooterConstants.ShooterSpeeds;
public class Shooter extends SubsystemBase {
private SparkMax leftMotor;
private SparkMax rightMotor;
private AbsoluteEncoder leftEncoder;
private AbsoluteEncoder rightEncoder;
private RelativeEncoder rightRelative;
private SparkClosedLoopController leftClosedLoopController;
private SparkClosedLoopController rightClosedLoopController;
private ShooterSpeeds targetSpeeds;
public Shooter() {
leftMotor = new SparkMax(ShooterConstants.kLeftShooterMotorCANID, MotorType.kBrushless);
rightMotor = new SparkMax(ShooterConstants.kRightShooterMotorCANID, MotorType.kBrushless);
leftMotor.configure(
ShooterConstants.kLeftMotorConfig,
ResetMode.kResetSafeParameters,
PersistMode.kPersistParameters
);
rightMotor.configure(
ShooterConstants.kRightMotorConfig,
ResetMode.kResetSafeParameters,
PersistMode.kPersistParameters
);
leftEncoder = leftMotor.getAbsoluteEncoder();
rightEncoder = rightMotor.getAbsoluteEncoder();
leftClosedLoopController = leftMotor.getClosedLoopController();
rightClosedLoopController = rightMotor.getClosedLoopController();
// TODO Set this to the initial startup speed
targetSpeeds = null;
rightRelative = rightMotor.getEncoder();
}
@Override
public void periodic() {
Logger.recordOutput(
"Shooter/TargetRPM",
targetSpeeds == null ? 0 : targetSpeeds.getSpeedRPM()
);
Logger.recordOutput("Shooter/LeftRollers/CurrentRPM", leftEncoder.getVelocity());
Logger.recordOutput("Shooter/RightRollers/CurrentRPM", rightEncoder.getVelocity());
Logger.recordOutput("Shooter/RightRollers/rightmotor", rightRelative.getVelocity());
// TODO How does the SparkMAX controller determine "at setpoint"? Is there any tolerance?
Logger.recordOutput("Shooter/LeftRollers/AtSetpoint", leftClosedLoopController.isAtSetpoint());
Logger.recordOutput("Shooter/RightRollers/AtSetpoint", rightClosedLoopController.isAtSetpoint());
}
public Command maintainSpeed(ShooterSpeeds speeds) {
return run(() -> {
targetSpeeds = speeds;
if(targetSpeeds == null) {
leftMotor.disable();
rightMotor.disable();
} else {
leftClosedLoopController.setSetpoint(
targetSpeeds.getSpeedRPM(),
ControlType.kVelocity
);
rightClosedLoopController.setSetpoint(
targetSpeeds.getSpeedRPM(),
ControlType.kVelocity
);
}
});
}
public Command manualSpeed(DoubleSupplier speed) {
return run(() -> {
targetSpeeds = null;
leftMotor.set(speed.getAsDouble() * ShooterConstants.kMaxManualSpeedMultiplier);
rightMotor.set(speed.getAsDouble() * ShooterConstants.kMaxManualSpeedMultiplier);
});
}
public Command stop() {
return manualSpeed(() -> 0);
}
public double getAverageActualSpeeds() {
return (leftEncoder.getVelocity() + rightEncoder.getVelocity()) / 2;
}
public Optional<ShooterSpeeds> getTargetSpeeds() {
return Optional.ofNullable(targetSpeeds);
}
}
@@ -0,0 +1,70 @@
package frc.robot.subsystems;
import com.ctre.phoenix6.controls.DutyCycleOut;
import com.ctre.phoenix6.hardware.TalonFX;
import com.revrobotics.PersistMode;
import com.revrobotics.ResetMode;
import com.revrobotics.spark.SparkMax;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
import frc.robot.constants.SpindexerConstants;
public class Spindexer extends SubsystemBase {
private TalonFX spindexerMotor;
private SparkMax feederMotor;
private DutyCycleOut spindexerMotorOutput;
public Spindexer() {
spindexerMotor = new TalonFX(SpindexerConstants.kSpindexerMotorCANID);
feederMotor = new SparkMax(SpindexerConstants.kFeederMotorCANID, MotorType.kBrushless);
spindexerMotor.getConfigurator().apply(SpindexerConstants.kSpindexerCurrentLimitConfig);
spindexerMotor.getConfigurator().apply(SpindexerConstants.kSpindexerMotorConfig);
feederMotor.configure(
SpindexerConstants.kFeederConfig,
ResetMode.kResetSafeParameters,
PersistMode.kPersistParameters
);
spindexerMotorOutput = new DutyCycleOut(0);
}
public Command spinToShooter() {
return run(() -> {
spindexerMotor.setControl(
spindexerMotorOutput.withOutput(SpindexerConstants.kSpindexerSpeed)
);
feederMotor.set(SpindexerConstants.kFeederSpeed);
});
}
public Command spinToIntake() {
return run(() -> {
spindexerMotor.setControl(
spindexerMotorOutput.withOutput(-SpindexerConstants.kSpindexerSpeed)
);
feederMotor.set(-SpindexerConstants.kFeederSpeed);
});
}
public Command stop() {
return run(() -> {
spindexerMotor.setControl(spindexerMotorOutput.withOutput(0));
feederMotor.set(0);
});
}
public Command instantaneousStop() {
return runOnce(() -> {
spindexerMotor.setControl(spindexerMotorOutput.withOutput(0));
feederMotor.set(0);
});
}
}
@@ -1,27 +1,28 @@
package first.robot.utilities;
// Copyright (c) 2023-2026 Gold87 and other Elastic contributors
// This software can be modified and/or shared under the terms
// defined by the Elastic license:
// https://github.com/Gold872/elastic_dashboard/blob/main/LICENSE
import org.wpilib.networktables.NetworkTableInstance;
import org.wpilib.networktables.PubSubOption;
import org.wpilib.networktables.StringPublisher;
import org.wpilib.networktables.StringTopic;
package frc.robot.utilities;
import io.avaje.json.JsonException;
import io.avaje.jsonb.Json;
import io.avaje.jsonb.JsonType;
import io.avaje.jsonb.Jsonb;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import edu.wpi.first.networktables.NetworkTableInstance;
import edu.wpi.first.networktables.PubSubOption;
import edu.wpi.first.networktables.StringPublisher;
import edu.wpi.first.networktables.StringTopic;
public final class Elastic {
private static final StringTopic notificationTopic =
NetworkTableInstance.getDefault().getStringTopic("/Elastic/RobotNotifications");
private static final StringPublisher notificationPublisher =
notificationTopic.publish(PubSubOption.SEND_ALL, PubSubOption.KEEP_DUPLICATES);
notificationTopic.publish(PubSubOption.sendAll(true), PubSubOption.keepDuplicates(true));
private static final StringTopic selectedTabTopic =
NetworkTableInstance.getDefault().getStringTopic("/Elastic/SelectedTab");
private static final StringPublisher selectedTabPublisher =
selectedTabTopic.publish(PubSubOption.KEEP_DUPLICATES);
private static final Jsonb jsonb = Jsonb.builder().build();
private static final JsonType<Notification> notificationJsonType =
jsonb.type(Notification.class);
selectedTabTopic.publish(PubSubOption.keepDuplicates(true));
private static final ObjectMapper objectMapper = new ObjectMapper();
/**
* Represents the possible levels of notifications for the Elastic dashboard. These levels are
@@ -44,8 +45,8 @@ public final class Elastic {
*/
public static void sendNotification(Notification notification) {
try {
notificationPublisher.set(notificationJsonType.toJson(notification));
} catch (JsonException e) {
notificationPublisher.set(objectMapper.writeValueAsString(notification));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
@@ -78,24 +79,23 @@ public final class Elastic {
* properties such as level, title, description, display time, and dimensions to control how the
* notification is displayed on the dashboard.
*/
@Json
public static class Notification {
@Json.Property("level")
@JsonProperty("level")
private NotificationLevel level;
@Json.Property("title")
@JsonProperty("title")
private String title;
@Json.Property("description")
@JsonProperty("description")
private String description;
@Json.Property("displayTime")
@JsonProperty("displayTime")
private int displayTimeMillis;
@Json.Property("width")
@JsonProperty("width")
private double width;
@Json.Property("height")
@JsonProperty("height")
private double height;
/**
@@ -1,6 +1,6 @@
package first.robot.utilities;
package frc.robot.utilities;
import org.wpilib.math.geometry.Transform3d;
import edu.wpi.first.math.geometry.Transform3d;
public record PhotonVisionConfig (
String cameraName,
@@ -1,13 +1,12 @@
package first.robot.utilities;
package frc.robot.utilities;
import java.util.function.DoubleSupplier;
import org.wpilib.command2.Command;
import org.wpilib.command2.SubsystemBase;
import org.wpilib.hardware.bus.CANPort;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import com.revrobotics.spark.SparkMax;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
/**
* A simple subsystem that can be used to test a single SparkMax and associated NEO motor
@@ -20,8 +19,8 @@ public class SparkMAXTester extends SubsystemBase {
*
* @param deviceID The CAN ID of the SparkMAX that needs testing
*/
public SparkMAXTester(CANPort canPort, int deviceID) {
spark = new SparkMax(canPort, deviceID, MotorType.kBrushless);
public SparkMAXTester(int deviceID) {
spark = new SparkMax(deviceID, MotorType.kBrushless);
}
/**
@@ -32,7 +31,7 @@ public class SparkMAXTester extends SubsystemBase {
*/
public Command setSpeed(DoubleSupplier speed) {
return run(() -> {
spark.setThrottle(speed.getAsDouble());
spark.set(speed.getAsDouble());
});
}
}
@@ -1,24 +1,23 @@
package first.robot.utilities;
package frc.robot.utilities;
import org.wpilib.hardware.bus.CANPort;
import org.wpilib.hardware.rotation.AnalogEncoder;
import org.wpilib.math.geometry.Rotation2d;
import org.wpilib.math.kinematics.SwerveModulePosition;
import org.wpilib.math.kinematics.SwerveModuleVelocity;
import org.littletonrobotics.junction.Logger;
import com.ctre.phoenix6.CANBus;
import com.ctre.phoenix6.controls.VelocityVoltage;
import com.ctre.phoenix6.hardware.TalonFX;
import com.revrobotics.PersistMode;
import com.revrobotics.RelativeEncoder;
import com.revrobotics.ResetMode;
import com.revrobotics.spark.SparkClosedLoopController;
import com.revrobotics.spark.SparkLowLevel.ControlType;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import com.revrobotics.spark.SparkMax;
import com.revrobotics.spark.SparkBase.ControlType;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import first.robot.constants.ModuleConstants;
import first.robot.constants.ModuleConstants.ModuleName;
import edu.wpi.first.math.geometry.Rotation2d;
import edu.wpi.first.math.kinematics.SwerveModulePosition;
import edu.wpi.first.math.kinematics.SwerveModuleState;
import edu.wpi.first.wpilibj.AnalogEncoder;
import frc.robot.constants.ModuleConstants;
import frc.robot.constants.ModuleConstants.ModuleName;
/*
* This thread
@@ -45,8 +44,8 @@ public class SwerveModule {
private VelocityVoltage driveVelocityRequest;
private SwerveModuleVelocity lastTargetState;
private SwerveModuleVelocity lastTargetStateOptimized;
private SwerveModuleState lastTargetState;
private SwerveModuleState lastTargetStateOptimized;
private boolean isAbsoluteEncoderDisabled;
private boolean turningEncoderAutoRezeroEnabled;
@@ -57,35 +56,32 @@ public class SwerveModule {
* This constructor assumes you zeroed the swerve modules (faced all the bevel gears to the left)
* before booting up the robot.
*
* @param canPort The CANPort enumeration that represents the CAN bus that the motors for this module live on
* @param moduleName The module name, Front Left, Front Right, etc.
* @param drivingCANID The CAN ID of the Kraken used to drive the module wheel
* @param turningCANID The CAN ID of the Spark MAX used to turn the module wheel
*/
public SwerveModule(CANPort canPort, ModuleName moduleName, int drivingCANID, int turningCANID) {
this(canPort, moduleName, drivingCANID, turningCANID, -1, -1);
public SwerveModule(ModuleName moduleName, int drivingCANID, int turningCANID) {
this(moduleName, drivingCANID, turningCANID, -1, -1);
}
/**
* Builds the swerve module with the normal features, disables automatic rezeroing of the turning encoder
* from the absolute encoder.
*
* @param canPort The CANPort enumeration that represents the CAN bus that the motors for this module live on
* @param moduleName The module name, Front Left, Front Right, etc.
* @param drivingCANID The CAN ID of the Kraken used to drive the module wheel
* @param turningCANID The CAN ID of the Spark MAX used to turn the module wheel
* @param analogEncoderID The Analog In port ID for the Thrify Absolute Encoder
* @param analogEncoderOffset The angular offset for the absolute encoder to achieve 0 position on the module
*/
public SwerveModule(CANPort canPort, ModuleName moduleName, int drivingCANID, int turningCANID, int analogEncoderID, double analogEncoderOffset) {
this(canPort, moduleName, drivingCANID, turningCANID, analogEncoderID, analogEncoderOffset, false);
public SwerveModule(ModuleName moduleName, int drivingCANID, int turningCANID, int analogEncoderID, double analogEncoderOffset) {
this(moduleName, drivingCANID, turningCANID, analogEncoderID, analogEncoderOffset, false);
}
/**
* Builds the swerve module with the normal features, and gives the option to enable automatic turning encoder rezeroing
* when the turning motor is not moving
*
* @param canPort The CANPort enumeration that represents the CAN bus that the motors for this module live on
* @param moduleName The module name, Front Left, Front Right, etc.
* @param drivingCANID The CAN ID of the Kraken used to drive the module wheel
* @param turningCANID The CAN ID of the Spark MAX used to turn the module wheel
@@ -93,12 +89,12 @@ public class SwerveModule {
* @param analogEncoderOffset The angular offset for the absolute encoder to achieve 0 position on the module
* @param turningEncoderAutoRezeroEnabled Should the turning encoder in the NEO automatically rezero from the absolute encoder
*/
public SwerveModule(CANPort canPort, ModuleName moduleName, int drivingCANID, int turningCANID,
public SwerveModule(ModuleName moduleName, int drivingCANID, int turningCANID,
int analogEncoderID, double analogEncoderOffset, boolean turningEncoderAutoRezeroEnabled) {
isAbsoluteEncoderDisabled = (analogEncoderID == -1) || (analogEncoderOffset < 0);
drive = new TalonFX(drivingCANID, new CANBus(canPort));
turning = new SparkMax(canPort, turningCANID, MotorType.kBrushless);
drive = new TalonFX(drivingCANID);
turning = new SparkMax(turningCANID, MotorType.kBrushless);
turningRelativeEncoder = turning.getEncoder();
@@ -165,8 +161,8 @@ public class SwerveModule {
return moduleName;
}
public SwerveModuleVelocity getState() {
return new SwerveModuleVelocity(
public SwerveModuleState getState() {
return new SwerveModuleState(
drive.getVelocity().getValueAsDouble() * ModuleConstants.kWheelCircumferenceMeters,
new Rotation2d(getTurningEncoderPosition())
);
@@ -184,8 +180,8 @@ public class SwerveModule {
turning.disable();
}
public void setDesiredState(SwerveModuleVelocity desiredState) {
lastTargetState = new SwerveModuleVelocity(desiredState.velocity, desiredState.angle);
public void setDesiredState(SwerveModuleState desiredState) {
lastTargetState = new SwerveModuleState(desiredState.speedMetersPerSecond, desiredState.angle);
desiredState.optimize(new Rotation2d(getTurningEncoderPosition()));
@@ -193,9 +189,9 @@ public class SwerveModule {
drive.setControl(
driveVelocityRequest.withVelocity(
desiredState.velocity / ModuleConstants.kWheelCircumferenceMeters
desiredState.speedMetersPerSecond / ModuleConstants.kWheelCircumferenceMeters
).withFeedForward(
desiredState.velocity / ModuleConstants.kWheelCircumferenceMeters
desiredState.speedMetersPerSecond / ModuleConstants.kWheelCircumferenceMeters
)
);
@@ -206,7 +202,7 @@ public class SwerveModule {
}
public double getTurningEncoderPosition() {
return turningRelativeEncoder.getPosition().get() * (ModuleConstants.kIsEncoderInverted ? -1 : 1);
return turningRelativeEncoder.getPosition() * (ModuleConstants.kIsEncoderInverted ? -1 : 1);
}
public void resetEncoders() {
@@ -223,4 +219,3 @@ public class SwerveModule {
}
}
}
@@ -1,12 +1,11 @@
package first.robot.utilities;
package frc.robot.utilities;
import java.util.Optional;
import org.wpilib.driverstation.Alliance;
import org.wpilib.driverstation.MatchState;
import org.wpilib.math.geometry.Pose2d;
import first.robot.constants.CompetitionConstants;
import edu.wpi.first.math.geometry.Pose2d;
import edu.wpi.first.wpilibj.DriverStation;
import edu.wpi.first.wpilibj.DriverStation.Alliance;
import frc.robot.constants.CompetitionConstants;
public class Utilities {
public static final double kG = -9.81;
@@ -19,22 +18,19 @@ public class Utilities {
* is not present
*/
public static Alliance whoHasFirstShift() {
Optional<String> gameData = MatchState.getGameData();
String gameData = DriverStation.getGameSpecificMessage();
if(gameData.isPresent()) {
String gameDataString = gameData.get();
if(gameDataString.length() > 0) {
switch (gameDataString.charAt(0)) {
case 'B':
return Alliance.RED;
case 'R':
return Alliance.BLUE;
default:
return null;
}
if(gameData.length() > 0) {
switch (gameData.charAt(0)) {
case 'B':
return Alliance.Red;
case 'R':
return Alliance.Blue;
default:
return null;
}
}
return null;
}
@@ -46,9 +42,9 @@ public class Utilities {
* @return The Pose2d object which represents the appropriate pose of the Hub
*/
public static Pose2d getHubPose() {
Optional<Alliance> alliance = MatchState.getAlliance();
Optional<Alliance> alliance = DriverStation.getAlliance();
if(alliance.isEmpty() || alliance.get() == Alliance.BLUE) {
if(alliance.isEmpty() || alliance.get() == Alliance.Blue) {
return CompetitionConstants.kBlueHubLocation;
} else {
return CompetitionConstants.kRedHubLocation;
@@ -63,9 +59,9 @@ public class Utilities {
* @return The tag ID that is in the center of the assigned alliance's hub
*/
public static int getHubCenterAprilTagID() {
Optional<Alliance> alliance = MatchState.getAlliance();
Optional<Alliance> alliance = DriverStation.getAlliance();
if(alliance.isEmpty() || alliance.get() == Alliance.BLUE) {
if(alliance.isEmpty() || alliance.get() == Alliance.Blue) {
return 26;
} else {
return 10;
@@ -1,6 +1,6 @@
package first.robot.utilities;
package frc.robot.utilities;
import org.wpilib.math.geometry.Pose2d;
import edu.wpi.first.math.geometry.Pose2d;
/**
* A record class which represents the source of a visual pose, the pose itself
+35
View File
@@ -0,0 +1,35 @@
{
"fileName": "AdvantageKit.json",
"name": "AdvantageKit",
"version": "26.0.0",
"uuid": "d820cc26-74e3-11ec-90d6-0242ac120003",
"frcYear": "2026",
"mavenUrls": [
"https://frcmaven.wpi.edu/artifactory/littletonrobotics-mvn-release/"
],
"jsonUrl": "https://github.com/Mechanical-Advantage/AdvantageKit/releases/latest/download/AdvantageKit.json",
"javaDependencies": [
{
"groupId": "org.littletonrobotics.akit",
"artifactId": "akit-java",
"version": "26.0.0"
}
],
"jniDependencies": [
{
"groupId": "org.littletonrobotics.akit",
"artifactId": "akit-wpilibio",
"version": "26.0.0",
"skipInvalidPlatforms": false,
"isJar": false,
"validPlatforms": [
"linuxathena",
"linuxx86-64",
"linuxarm64",
"osxuniversal",
"windowsx86-64"
]
}
],
"cppDependencies": []
}
@@ -1,18 +1,18 @@
{
"fileName": "PathplannerLibSystemCoreAlpha.json",
"fileName": "PathplannerLib-2026.1.2.json",
"name": "PathplannerLib",
"version": "2027.0.0-alpha-4.1",
"version": "2026.1.2",
"uuid": "1b42324f-17c6-4875-8e77-1c312bc8c786",
"wpilibYear": "2027_alpha7",
"frcYear": "2026",
"mavenUrls": [
"https://3015rangerrobotics.github.io/pathplannerlib/repo"
],
"jsonUrl": "https://3015rangerrobotics.github.io/pathplannerlib/PathplannerLibSystemCoreAlpha.json",
"jsonUrl": "https://3015rangerrobotics.github.io/pathplannerlib/PathplannerLib.json",
"javaDependencies": [
{
"groupId": "com.pathplanner.lib",
"artifactId": "PathplannerLib-java",
"version": "2027.0.0-alpha-4.1"
"version": "2026.1.2"
}
],
"jniDependencies": [],
@@ -20,7 +20,7 @@
{
"groupId": "com.pathplanner.lib",
"artifactId": "PathplannerLib-cpp",
"version": "2027.0.0-alpha-4.1",
"version": "2026.1.2",
"libName": "PathplannerLib",
"headerClassifier": "headers",
"sharedLibrary": false,
@@ -29,7 +29,8 @@
"windowsx86-64",
"linuxx86-64",
"osxuniversal",
"linuxsystemcore",
"linuxathena",
"linuxarm32",
"linuxarm64"
]
}
+171
View File
@@ -0,0 +1,171 @@
{
"fileName": "Phoenix5-5.36.0.json",
"name": "CTRE-Phoenix (v5)",
"version": "5.36.0",
"frcYear": "2026",
"uuid": "ab676553-b602-441f-a38d-f1296eff6537",
"mavenUrls": [
"https://maven.ctr-electronics.com/release/"
],
"jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-frc2026-latest.json",
"requires": [
{
"uuid": "e995de00-2c64-4df5-8831-c1441420ff19",
"errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.",
"offlineFileName": "Phoenix6-frc2026-latest.json",
"onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2026-latest.json"
}
],
"conflictsWith": [
{
"uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af",
"errorMessage": "Users must use the Phoenix 5 replay vendordep when using the Phoenix 6 replay vendordep.",
"offlineFileName": "Phoenix6-replay-frc2026-latest.json"
},
{
"uuid": "fbc886a4-2cec-40c0-9835-71086a8cc3df",
"errorMessage": "Users cannot have both the replay and regular Phoenix 5 vendordeps in their robot program.",
"offlineFileName": "Phoenix5-replay-frc2026-latest.json"
}
],
"javaDependencies": [
{
"groupId": "com.ctre.phoenix",
"artifactId": "api-java",
"version": "5.36.0"
},
{
"groupId": "com.ctre.phoenix",
"artifactId": "wpiapi-java",
"version": "5.36.0"
}
],
"jniDependencies": [
{
"groupId": "com.ctre.phoenix",
"artifactId": "cci",
"version": "5.36.0",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
"windowsx86-64",
"linuxx86-64",
"linuxarm64",
"linuxathena"
],
"simMode": "hwsim"
},
{
"groupId": "com.ctre.phoenix.sim",
"artifactId": "cci-sim",
"version": "5.36.0",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
"windowsx86-64",
"linuxx86-64",
"linuxarm64",
"osxuniversal"
],
"simMode": "swsim"
}
],
"cppDependencies": [
{
"groupId": "com.ctre.phoenix",
"artifactId": "wpiapi-cpp",
"version": "5.36.0",
"libName": "CTRE_Phoenix_WPI",
"headerClassifier": "headers",
"sharedLibrary": true,
"skipInvalidPlatforms": true,
"binaryPlatforms": [
"windowsx86-64",
"linuxx86-64",
"linuxarm64",
"linuxathena"
],
"simMode": "hwsim"
},
{
"groupId": "com.ctre.phoenix",
"artifactId": "api-cpp",
"version": "5.36.0",
"libName": "CTRE_Phoenix",
"headerClassifier": "headers",
"sharedLibrary": true,
"skipInvalidPlatforms": true,
"binaryPlatforms": [
"windowsx86-64",
"linuxx86-64",
"linuxarm64",
"linuxathena"
],
"simMode": "hwsim"
},
{
"groupId": "com.ctre.phoenix",
"artifactId": "cci",
"version": "5.36.0",
"libName": "CTRE_PhoenixCCI",
"headerClassifier": "headers",
"sharedLibrary": true,
"skipInvalidPlatforms": true,
"binaryPlatforms": [
"windowsx86-64",
"linuxx86-64",
"linuxarm64",
"linuxathena"
],
"simMode": "hwsim"
},
{
"groupId": "com.ctre.phoenix.sim",
"artifactId": "wpiapi-cpp-sim",
"version": "5.36.0",
"libName": "CTRE_Phoenix_WPISim",
"headerClassifier": "headers",
"sharedLibrary": true,
"skipInvalidPlatforms": true,
"binaryPlatforms": [
"windowsx86-64",
"linuxx86-64",
"linuxarm64",
"osxuniversal"
],
"simMode": "swsim"
},
{
"groupId": "com.ctre.phoenix.sim",
"artifactId": "api-cpp-sim",
"version": "5.36.0",
"libName": "CTRE_PhoenixSim",
"headerClassifier": "headers",
"sharedLibrary": true,
"skipInvalidPlatforms": true,
"binaryPlatforms": [
"windowsx86-64",
"linuxx86-64",
"linuxarm64",
"osxuniversal"
],
"simMode": "swsim"
},
{
"groupId": "com.ctre.phoenix.sim",
"artifactId": "cci-sim",
"version": "5.36.0",
"libName": "CTRE_PhoenixCCISim",
"headerClassifier": "headers",
"sharedLibrary": true,
"skipInvalidPlatforms": true,
"binaryPlatforms": [
"windowsx86-64",
"linuxx86-64",
"linuxarm64",
"osxuniversal"
],
"simMode": "swsim"
}
]
}
@@ -1,60 +1,60 @@
{
"fileName": "Phoenix6-26.70.0-alpha-2.json",
"fileName": "Phoenix6-26.1.0.json",
"name": "CTRE-Phoenix (v6)",
"version": "26.70.0-alpha-2",
"wpilibYear": "2027_alpha7",
"version": "26.1.0",
"frcYear": "2026",
"uuid": "e995de00-2c64-4df5-8831-c1441420ff19",
"mavenUrls": [
"https://maven.ctr-electronics.com/release/"
],
"jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2027-latest.json",
"jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2026-latest.json",
"conflictsWith": [
{
"uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af",
"errorMessage": "Users cannot have both the replay and regular Phoenix 6 vendordeps in their robot program.",
"offlineFileName": "Phoenix6-replay-frc2027-latest.json"
"errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.",
"offlineFileName": "Phoenix6-replay-frc2026-latest.json"
}
],
"javaDependencies": [
{
"groupId": "com.ctre.phoenix6",
"artifactId": "wpiapi-java",
"version": "26.70.0-alpha-2"
"version": "26.1.0"
}
],
"jniDependencies": [
{
"groupId": "com.ctre.phoenix6",
"artifactId": "api-cpp",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
"windowsx86-64",
"linuxx86-64",
"linuxarm64",
"linuxsystemcore"
"linuxathena"
],
"simMode": "hwsim"
},
{
"groupId": "com.ctre.phoenix6",
"artifactId": "tools",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
"windowsx86-64",
"linuxx86-64",
"linuxarm64",
"linuxsystemcore"
"linuxathena"
],
"simMode": "hwsim"
},
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "api-cpp-sim",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -68,7 +68,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "tools-sim",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -82,7 +82,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simTalonSRX",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -96,7 +96,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simVictorSPX",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -110,7 +110,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simPigeonIMU",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -124,7 +124,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProTalonFX",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -138,7 +138,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProTalonFXS",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -152,7 +152,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProCANcoder",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -166,7 +166,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProPigeon2",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -180,7 +180,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProCANrange",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -194,7 +194,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProCANdi",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -208,7 +208,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProCANdle",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -224,7 +224,7 @@
{
"groupId": "com.ctre.phoenix6",
"artifactId": "wpiapi-cpp",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"libName": "CTRE_Phoenix6_WPI",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -233,14 +233,14 @@
"windowsx86-64",
"linuxx86-64",
"linuxarm64",
"linuxsystemcore"
"linuxathena"
],
"simMode": "hwsim"
},
{
"groupId": "com.ctre.phoenix6",
"artifactId": "tools",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"libName": "CTRE_PhoenixTools",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -249,14 +249,14 @@
"windowsx86-64",
"linuxx86-64",
"linuxarm64",
"linuxsystemcore"
"linuxathena"
],
"simMode": "hwsim"
},
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "wpiapi-cpp-sim",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"libName": "CTRE_Phoenix6_WPISim",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -272,7 +272,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "tools-sim",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"libName": "CTRE_PhoenixTools_Sim",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -288,7 +288,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simTalonSRX",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"libName": "CTRE_SimTalonSRX",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -304,7 +304,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simVictorSPX",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"libName": "CTRE_SimVictorSPX",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -320,7 +320,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simPigeonIMU",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"libName": "CTRE_SimPigeonIMU",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -336,7 +336,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProTalonFX",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"libName": "CTRE_SimProTalonFX",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -352,7 +352,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProTalonFXS",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"libName": "CTRE_SimProTalonFXS",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -368,7 +368,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProCANcoder",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"libName": "CTRE_SimProCANcoder",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -384,7 +384,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProPigeon2",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"libName": "CTRE_SimProPigeon2",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -400,7 +400,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProCANrange",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"libName": "CTRE_SimProCANrange",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -416,7 +416,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProCANdi",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"libName": "CTRE_SimProCANdi",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -432,7 +432,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProCANdle",
"version": "26.70.0-alpha-2",
"version": "26.1.0",
"libName": "CTRE_SimProCANdle",
"headerClassifier": "headers",
"sharedLibrary": true,
+25 -18
View File
@@ -1,60 +1,63 @@
{
"fileName": "REVLib.json",
"name": "REVLib",
"version": "2027.0.0-alpha-8",
"wpilibYear": "2027_alpha7",
"version": "2026.0.0",
"frcYear": "2026",
"uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb",
"mavenUrls": [
"https://maven.revrobotics.com/"
],
"jsonUrl": "https://software-metadata.revrobotics.com/REVLib-2027.json",
"jsonUrl": "https://software-metadata.revrobotics.com/REVLib-2026.json",
"javaDependencies": [
{
"groupId": "com.revrobotics.frc",
"artifactId": "REVLib-java",
"version": "2027.0.0-alpha-8"
"version": "2026.0.0"
}
],
"jniDependencies": [
{
"groupId": "com.revrobotics.frc",
"artifactId": "REVLib-driver",
"version": "2027.0.0-alpha-8",
"version": "2026.0.0",
"skipInvalidPlatforms": true,
"isJar": false,
"validPlatforms": [
"windowsx86-64",
"linuxarm64",
"linuxx86-64",
"linuxsystemcore",
"linuxathena",
"linuxarm32",
"osxuniversal"
]
},
{
"groupId": "com.revrobotics.frc",
"artifactId": "RevLibBackendDriver",
"version": "2027.0.0-alpha-8",
"version": "2026.0.0",
"skipInvalidPlatforms": true,
"isJar": false,
"validPlatforms": [
"windowsx86-64",
"linuxarm64",
"linuxx86-64",
"linuxsystemcore",
"linuxathena",
"linuxarm32",
"osxuniversal"
]
},
{
"groupId": "com.revrobotics.frc",
"artifactId": "RevLibWpiBackendDriver",
"version": "2027.0.0-alpha-8",
"version": "2026.0.0",
"skipInvalidPlatforms": true,
"isJar": false,
"validPlatforms": [
"windowsx86-64",
"linuxarm64",
"linuxx86-64",
"linuxsystemcore",
"linuxathena",
"linuxarm32",
"osxuniversal"
]
}
@@ -63,7 +66,7 @@
{
"groupId": "com.revrobotics.frc",
"artifactId": "REVLib-cpp",
"version": "2027.0.0-alpha-8",
"version": "2026.0.0",
"libName": "REVLib",
"headerClassifier": "headers",
"sharedLibrary": false,
@@ -72,14 +75,15 @@
"windowsx86-64",
"linuxarm64",
"linuxx86-64",
"linuxsystemcore",
"linuxathena",
"linuxarm32",
"osxuniversal"
]
},
{
"groupId": "com.revrobotics.frc",
"artifactId": "REVLib-driver",
"version": "2027.0.0-alpha-8",
"version": "2026.0.0",
"libName": "REVLibDriver",
"headerClassifier": "headers",
"sharedLibrary": false,
@@ -88,14 +92,15 @@
"windowsx86-64",
"linuxarm64",
"linuxx86-64",
"linuxsystemcore",
"linuxathena",
"linuxarm32",
"osxuniversal"
]
},
{
"groupId": "com.revrobotics.frc",
"artifactId": "RevLibBackendDriver",
"version": "2027.0.0-alpha-8",
"version": "2026.0.0",
"libName": "BackendDriver",
"sharedLibrary": true,
"skipInvalidPlatforms": true,
@@ -103,14 +108,15 @@
"windowsx86-64",
"linuxarm64",
"linuxx86-64",
"linuxsystemcore",
"linuxathena",
"linuxarm32",
"osxuniversal"
]
},
{
"groupId": "com.revrobotics.frc",
"artifactId": "RevLibWpiBackendDriver",
"version": "2027.0.0-alpha-8",
"version": "2026.0.0",
"libName": "REVLibWpi",
"sharedLibrary": true,
"skipInvalidPlatforms": true,
@@ -118,7 +124,8 @@
"windowsx86-64",
"linuxarm64",
"linuxx86-64",
"linuxsystemcore",
"linuxathena",
"linuxarm32",
"osxuniversal"
]
}
+71
View File
@@ -0,0 +1,71 @@
{
"fileName": "Studica.json",
"name": "Studica",
"version": "2026.0.0",
"frcYear": "2026",
"uuid": "cb311d09-36e9-4143-a032-55bb2b94443b",
"mavenUrls": [
"https://dev.studica.com/maven/release/2026/"
],
"jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0.json",
"javaDependencies": [
{
"groupId": "com.studica.frc",
"artifactId": "Studica-java",
"version": "2026.0.0"
}
],
"jniDependencies": [
{
"groupId": "com.studica.frc",
"artifactId": "Studica-driver",
"version": "2026.0.0",
"skipInvalidPlatforms": true,
"isJar": false,
"validPlatforms": [
"windowsx86-64",
"linuxarm64",
"linuxx86-64",
"linuxathena",
"linuxarm32",
"osxuniversal"
]
}
],
"cppDependencies": [
{
"groupId": "com.studica.frc",
"artifactId": "Studica-cpp",
"version": "2026.0.0",
"libName": "Studica",
"headerClassifier": "headers",
"sharedLibrary": false,
"skipInvalidPlatforms": true,
"binaryPlatforms": [
"windowsx86-64",
"linuxarm64",
"linuxx86-64",
"linuxathena",
"linuxarm32",
"osxuniversal"
]
},
{
"groupId": "com.studica.frc",
"artifactId": "Studica-driver",
"version": "2026.0.0",
"libName": "StudicaDriver",
"headerClassifier": "headers",
"sharedLibrary": false,
"skipInvalidPlatforms": true,
"binaryPlatforms": [
"windowsx86-64",
"linuxarm64",
"linuxx86-64",
"linuxathena",
"linuxarm32",
"osxuniversal"
]
}
]
}
@@ -1,41 +1,36 @@
{
"fileName": "CommandsV2.json",
"name": "Commands V2",
"fileName": "WPILibNewCommands.json",
"name": "WPILib-New-Commands",
"version": "1.0.0",
"uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266",
"wpilibYear": "2027_alpha7",
"frcYear": "2026",
"mavenUrls": [],
"jsonUrl": "",
"conflictsWith": [
{
"uuid": "4decdc05-a056-46cf-9561-39449bbb01306",
"errorMessage": "Users can not have both Commands v2 and Commands v3 vendordeps in their robot program.",
"offlineFileName": "CommandsV3.json"
}
],
"javaDependencies": [
{
"groupId": "org.wpilib.commandsv2",
"artifactId": "commandsv2-java",
"groupId": "edu.wpi.first.wpilibNewCommands",
"artifactId": "wpilibNewCommands-java",
"version": "wpilib"
}
],
"jniDependencies": [],
"cppDependencies": [
{
"groupId": "org.wpilib.commandsv2",
"artifactId": "commandsv2-cpp",
"groupId": "edu.wpi.first.wpilibNewCommands",
"artifactId": "wpilibNewCommands-cpp",
"version": "wpilib",
"libName": "commandsv2",
"libName": "wpilibNewCommands",
"headerClassifier": "headers",
"sourcesClassifier": "sources",
"sharedLibrary": true,
"skipInvalidPlatforms": true,
"binaryPlatforms": [
"linuxsystemcore",
"linuxathena",
"linuxarm32",
"linuxarm64",
"windowsx86-64",
"windowsarm64",
"windowsx86",
"linuxx86-64",
"osxuniversal"
]
@@ -1,84 +0,0 @@
{
"fileName": "photonlib.json",
"name": "photonlib",
"version": "dev-v2027.0.0-alpha-2-81-g5b5b7870",
"uuid": "515fe07e-bfc6-11fa-b3de-0242ac130004",
"wpilibYear": "2027_alpha7",
"mavenUrls": [
"https://maven.photonvision.org/repository/internal",
"https://maven.photonvision.org/repository/snapshots"
],
"jsonUrl": "https://maven.photonvision.org/repository/internal/org/photonvision/photonlib-json/1.0/photonlib-json-1.0.json",
"jniDependencies": [
{
"groupId": "org.photonvision",
"artifactId": "photontargeting-cpp",
"version": "dev-v2027.0.0-alpha-2-81-g5b5b7870",
"skipInvalidPlatforms": true,
"isJar": false,
"validPlatforms": [
"windowsx86-64",
"linuxsystemcore",
"linuxx86-64",
"osxuniversal"
]
},
{
"groupId": "org.wpilib.fields",
"artifactId": "fields-cpp",
"version": "wpilib",
"skipInvalidPlatforms": true,
"isJar": false,
"validPlatforms": [
"windowsx86-64",
"linuxsystemcore",
"linuxx86-64",
"osxuniversal"
]
}
],
"cppDependencies": [
{
"groupId": "org.photonvision",
"artifactId": "photonlib-cpp",
"version": "dev-v2027.0.0-alpha-2-81-g5b5b7870",
"libName": "photonlib",
"headerClassifier": "headers",
"sharedLibrary": true,
"skipInvalidPlatforms": true,
"binaryPlatforms": [
"windowsx86-64",
"linuxsystemcore",
"linuxx86-64",
"osxuniversal"
]
},
{
"groupId": "org.photonvision",
"artifactId": "photontargeting-cpp",
"version": "dev-v2027.0.0-alpha-2-81-g5b5b7870",
"libName": "photontargeting",
"headerClassifier": "headers",
"sharedLibrary": true,
"skipInvalidPlatforms": true,
"binaryPlatforms": [
"windowsx86-64",
"linuxsystemcore",
"linuxx86-64",
"osxuniversal"
]
}
],
"javaDependencies": [
{
"groupId": "org.photonvision",
"artifactId": "photonlib-java",
"version": "dev-v2027.0.0-alpha-2-81-g5b5b7870"
},
{
"groupId": "org.photonvision",
"artifactId": "photontargeting-java",
"version": "dev-v2027.0.0-alpha-2-81-g5b5b7870"
}
]
}
+71
View File
@@ -0,0 +1,71 @@
{
"fileName": "photonlib.json",
"name": "photonlib",
"version": "v2026.0.1-beta",
"uuid": "515fe07e-bfc6-11fa-b3de-0242ac130004",
"frcYear": "2026",
"mavenUrls": [
"https://maven.photonvision.org/repository/internal",
"https://maven.photonvision.org/repository/snapshots"
],
"jsonUrl": "https://maven.photonvision.org/repository/internal/org/photonvision/photonlib-json/1.0/photonlib-json-1.0.json",
"jniDependencies": [
{
"groupId": "org.photonvision",
"artifactId": "photontargeting-cpp",
"version": "v2026.0.1-beta",
"skipInvalidPlatforms": true,
"isJar": false,
"validPlatforms": [
"windowsx86-64",
"linuxathena",
"linuxx86-64",
"osxuniversal"
]
}
],
"cppDependencies": [
{
"groupId": "org.photonvision",
"artifactId": "photonlib-cpp",
"version": "v2026.0.1-beta",
"libName": "photonlib",
"headerClassifier": "headers",
"sharedLibrary": true,
"skipInvalidPlatforms": true,
"binaryPlatforms": [
"windowsx86-64",
"linuxathena",
"linuxx86-64",
"osxuniversal"
]
},
{
"groupId": "org.photonvision",
"artifactId": "photontargeting-cpp",
"version": "v2026.0.1-beta",
"libName": "photontargeting",
"headerClassifier": "headers",
"sharedLibrary": true,
"skipInvalidPlatforms": true,
"binaryPlatforms": [
"windowsx86-64",
"linuxathena",
"linuxx86-64",
"osxuniversal"
]
}
],
"javaDependencies": [
{
"groupId": "org.photonvision",
"artifactId": "photonlib-java",
"version": "v2026.0.1-beta"
},
{
"groupId": "org.photonvision",
"artifactId": "photontargeting-java",
"version": "v2026.0.1-beta"
}
]
}