72 changed files with 758 additions and 2686 deletions

No files matched your search

+1 -1
View File
@@ -13,7 +13,7 @@
},
{
"type": "wpilib",
"name": "WPILib roboRIO Debug",
"name": "WPILib Systemcore Debug",
"request": "launch",
"desktop": false,
}
+5 -4
View File
@@ -37,7 +37,7 @@
"org.mockito.Mockito.*",
"org.mockito.ArgumentMatchers.*",
"org.mockito.Answers.*",
"edu.wpi.first.units.Units.*"
"org.wpilib.units.Units.*"
],
"java.completion.filteredTypes": [
"java.awt.*",
@@ -53,9 +53,10 @@
"javax.swing.*",
"javax.management.*",
"javax.smartcardio.*",
"edu.wpi.first.math.proto.*",
"edu.wpi.first.math.**.proto.*",
"edu.wpi.first.math.**.struct.*",
"org.wpilib.math.proto.*",
"org.wpilib.math.**.proto.*",
"org.wpilib.math.**.struct.*",
],
"java.debug.settings.enableRunDebugCodeLens": false,
"java.dependency.enableDependencyCheckup": false
}
+2 -2
View File
@@ -1,6 +1,6 @@
{
"enableCppIntellisense": false,
"currentLanguage": "java",
"projectYear": "2026",
"teamNumber": 2648
"projectYear": "2027_alpha7",
"teamNumber": 9999
}
+31 -39
View File
@@ -1,39 +1,45 @@
plugins {
id "java"
id "edu.wpi.first.GradleRIO" version "2026.2.1"
id "application"
id "org.wpilib.GradleRIO" version "2027.0.0-alpha-7"
}
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
sourceCompatibility = JavaVersion.VERSION_25
targetCompatibility = JavaVersion.VERSION_25
}
def ROBOT_MAIN_CLASS = "frc.robot.Main"
def ROBOT_MAIN_CLASS = "first.Main"
// Define my targets (RoboRIO) and artifacts (deployable files)
// Define my targets (SystemCore) and artifacts (deployable files)
// This is added by GradleRIO's backing project DeployUtils.
deploy {
targets {
roborio(getTargetTypeClass('RoboRIO')) {
systemcore(getTargetTypeClass('SystemCore')) {
// Team number is loaded either from the .wpilib/wpilib_preferences.json
// or from command line. If not found an exception will be thrown.
// You can use getTeamOrDefault(team) instead of getTeamNumber if you
// want to store a team number in this file.
team = project.frc.getTeamNumber()
debug = project.frc.getDebugOrDefault(false)
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)
artifacts {
// First part is artifact name, 2nd is artifact type
// getTargetTypeClass is a shortcut to get the class type using a string
frcJava(getArtifactTypeClass('FRCJavaArtifact')) {
wpilibJava(getArtifactTypeClass('WPILibJavaArtifact')) {
// Set to true to use debug including JNI, which will drastically impact performance.
debugJni = false
}
// Static files artifact
frcStaticFileDeploy(getArtifactTypeClass('FileTreeArtifact')) {
wpilibStaticFileDeploy(getArtifactTypeClass('FileTreeArtifact')) {
files = project.fileTree('src/main/deploy')
directory = '/home/lvuser/deploy'
deleteOldFiles = false // Change to true to delete files on roboRIO that no
directory = '/home/systemcore/deploy'
deleteOldFiles = false // Change to true to delete files on systemcore that no
// longer exist in deploy directory of this project
}
}
@@ -41,20 +47,14 @@ deploy {
}
}
def deployArtifact = deploy.targets.roborio.artifacts.frcJava
def deployArtifact = deploy.targets.systemcore.artifacts.wpilibJava
// Set to true to use debug for all targets including JNI, which will drastically impact
// performance.
wpi.java.debugJni = false
// Set to true to use debug for simulation including JNI
wpi.java.runSimWithDebugJni = 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()
roborioDebug wpi.java.deps.wpilibJniDebug(wpi.platforms.roborio)
roborioDebug wpi.java.vendor.jniDebug(wpi.platforms.roborio)
systemcoreDebug wpi.java.deps.wpilibJniDebug(wpi.platforms.systemcore)
systemcoreDebug wpi.java.vendor.jniDebug(wpi.platforms.systemcore)
roborioRelease wpi.java.deps.wpilibJniRelease(wpi.platforms.roborio)
roborioRelease wpi.java.vendor.jniRelease(wpi.platforms.roborio)
systemcoreRelease wpi.java.deps.wpilibJniRelease(wpi.platforms.systemcore)
systemcoreRelease wpi.java.vendor.jniRelease(wpi.platforms.systemcore)
nativeDebug wpi.java.deps.wpilibJniDebug(wpi.platforms.desktop)
nativeDebug wpi.java.vendor.jniDebug(wpi.platforms.desktop)
@@ -78,9 +78,6 @@ 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 {
@@ -92,23 +89,18 @@ test {
wpi.sim.addGui().defaultEnabled = true
wpi.sim.addDriverstation()
// Setting up my Jar File. In this case, adding all libraries into the main jar ('fat jar')
// in order to make them all available at runtime. Also adding the manifest so WPILib
// knows where to look for our Robot Class.
application.mainClass = ROBOT_MAIN_CLASS
deployArtifact.configureApplication(application)
wpi.java.configureApplication(application)
wpi.java.configureTestTasks(test)
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-8.11-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Vendored
+5 -9
View File
@@ -1,7 +1,7 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
# Copyright © 2015 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/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/2d6327017519d23b96af35865dc997fcb544fb40/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,8 +86,7 @@ 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
' "$PWD" ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -115,7 +114,6 @@ 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.
@@ -173,7 +171,6 @@ 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" )
@@ -206,15 +203,14 @@ fi
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.
Vendored
+1 -2
View File
@@ -70,11 +70,10 @@ goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell
+19 -11
View File
@@ -2,27 +2,35 @@ import org.gradle.internal.os.OperatingSystem
pluginManagement {
repositories {
mavenLocal()
gradlePluginPortal()
String frcYear = '2026'
File frcHome
if (OperatingSystem.current().isWindows()) {
String wpilibYear = '2027_alpha7'
File wpilibHome
def os = OperatingSystem.current()
if (os.isWindows()) {
String publicFolder = System.getenv('PUBLIC')
if (publicFolder == null) {
publicFolder = "C:\\Users\\Public"
}
def homeRoot = new File(publicFolder, "wpilib")
frcHome = new File(homeRoot, frcYear)
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)
} else {
def userFolder = System.getProperty("user.home")
def homeRoot = new File(userFolder, "wpilib")
frcHome = new File(homeRoot, frcYear)
def homeRoot = new File(userFolder, ".wpilib")
wpilibHome = new File(homeRoot, wpilibYear)
}
def frcHomeMaven = new File(frcHome, 'maven')
def wpilibHomeMaven = new File(wpilibHome, 'maven')
maven {
name = 'frcHome'
url = frcHomeMaven
name = 'wpilibHome'
url = wpilibHomeMaven
}
mavenLocal()
gradlePluginPortal()
}
}
+1 -1
View File
@@ -1,3 +1,3 @@
Files placed in this directory will be deployed to the RoboRIO into the
Files placed in this directory will be deployed to the Systemcore into the
'deploy' directory in the home folder. Use the 'Filesystem.getDeployDirectory' wpilib function
to get a proper path relative to the deploy directory.
@@ -1,37 +0,0 @@
{
"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
}
@@ -1,67 +0,0 @@
{
"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
}
@@ -1,31 +0,0 @@
{
"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
}
@@ -1,43 +0,0 @@
{
"version": "2025.0",
"command": {
"type": "sequential",
"data": {
"commands": [
{
"type": "named",
"data": {
"name": "intake down"
}
},
{
"type": "path",
"data": {
"pathName": "left start to center"
}
},
{
"type": "path",
"data": {
"pathName": "over bump to pile"
}
},
{
"type": "path",
"data": {
"pathName": "back from center"
}
},
{
"type": "named",
"data": {
"name": "auto shoot"
}
}
]
}
},
"resetOdom": true,
"folder": null,
"choreoAuto": false
}
-1
View File
@@ -1 +0,0 @@
{"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
@@ -1,54 +0,0 @@
{
"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
}
@@ -1,54 +0,0 @@
{
"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
}
@@ -1,80 +0,0 @@
{
"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
}
@@ -1,151 +0,0 @@
{
"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
}
@@ -1,54 +0,0 @@
{
"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
}
@@ -1,66 +0,0 @@
{
"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
}
@@ -1,63 +0,0 @@
{
"version": "2025.0",
"waypoints": [
{
"anchor": {
"x": 6.050842639593909,
"y": 5.715482233502538
},
"prevControl": null,
"nextControl": {
"x": 5.130030456852792,
"y": 5.7523147208121825
},
"isLocked": false,
"linkedName": "over bump"
},
{
"anchor": {
"x": 3.002954314720812,
"y": 5.310324873096447
},
"prevControl": {
"x": 4.052680203045686,
"y": 5.9825177664974625
},
"nextControl": null,
"isLocked": false,
"linkedName": null
}
],
"rotationTargets": [
{
"waypointRelativePos": 0.10454545454545605,
"rotationDegrees": -115.0
},
{
"waypointRelativePos": 0.7931818181818296,
"rotationDegrees": -115.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": -36.158185439808385
},
"reversed": false,
"folder": null,
"idealStartingState": {
"velocity": 0,
"rotation": -123.34070734647689
},
"useDefaultConstraints": true
}
@@ -1,98 +0,0 @@
{
"version": "2025.0",
"waypoints": [
{
"anchor": {
"x": 3.573857868020305,
"y": 6.3692588832487305
},
"prevControl": null,
"nextControl": {
"x": 2.9108730964467004,
"y": 6.498172588832488
},
"isLocked": false,
"linkedName": "start left"
},
{
"anchor": {
"x": 2.5885888324873094,
"y": 5.936477157360406
},
"prevControl": {
"x": 2.3675939086294413,
"y": 6.28638578680203
},
"nextControl": {
"x": 2.8493791599284664,
"y": 5.523559138911907
},
"isLocked": false,
"linkedName": null
},
{
"anchor": {
"x": 4.577543147208122,
"y": 5.715482233502538
},
"prevControl": {
"x": 3.565840773084476,
"y": 5.768729726877464
},
"nextControl": {
"x": 5.102406091370558,
"y": 5.687857868020306
},
"isLocked": false,
"linkedName": null
},
{
"anchor": {
"x": 6.050842639593909,
"y": 5.715482233502538
},
"prevControl": {
"x": 5.525979695431473,
"y": 5.807563451776649
},
"nextControl": null,
"isLocked": false,
"linkedName": "over bump"
}
],
"rotationTargets": [
{
"waypointRelativePos": 1.62272727272727,
"rotationDegrees": -135.0
}
],
"constraintZones": [],
"pointTowardsZones": [],
"eventMarkers": [
{
"name": "Intake Start",
"waypointRelativePos": 2.1,
"endWaypointRelativePos": null,
"command": null
}
],
"globalConstraints": {
"maxVelocity": 3.0,
"maxAcceleration": 2.0,
"maxAngularVelocity": 540.0,
"maxAngularAcceleration": 720.0,
"nominalVoltage": 12.0,
"unlimited": false
},
"goalEndState": {
"velocity": 0,
"rotation": -123.34070734647689
},
"reversed": false,
"folder": null,
"idealStartingState": {
"velocity": 0,
"rotation": -90.0
},
"useDefaultConstraints": false
}
@@ -1,112 +0,0 @@
{
"version": "2025.0",
"waypoints": [
{
"anchor": {
"x": 6.050842639593909,
"y": 5.715482233502538
},
"prevControl": null,
"nextControl": {
"x": 6.520456852791878,
"y": 6.406091370558377
},
"isLocked": false,
"linkedName": "over bump"
},
{
"anchor": {
"x": 7.017695431472081,
"y": 7.216406091370559
},
"prevControl": {
"x": 6.017695431472081,
"y": 7.216406091370559
},
"nextControl": {
"x": 8.017695431472081,
"y": 7.216406091370559
},
"isLocked": false,
"linkedName": null
},
{
"anchor": {
"x": 7.883258883248731,
"y": 4.831502538071066
},
"prevControl": {
"x": 7.941269035532995,
"y": 6.042370558375635
},
"nextControl": {
"x": 7.825248730964466,
"y": 3.620634517766498
},
"isLocked": false,
"linkedName": null
},
{
"anchor": {
"x": 6.050842639593909,
"y": 5.715482233502538
},
"prevControl": {
"x": 6.99789847715736,
"y": 5.183713197969544
},
"nextControl": null,
"isLocked": false,
"linkedName": null
}
],
"rotationTargets": [
{
"waypointRelativePos": 1.0045454545454569,
"rotationDegrees": -115.0
}
],
"constraintZones": [
{
"name": "Constraints Zone",
"minWaypointRelativePos": 1.1243680485338854,
"maxWaypointRelativePos": 2.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.7886754297269942,
"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": -120.34324888423971
},
"reversed": false,
"folder": null,
"idealStartingState": {
"velocity": 0,
"rotation": -123.34070734647689
},
"useDefaultConstraints": true
}
@@ -1,54 +0,0 @@
{
"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
}
@@ -1,54 +0,0 @@
{
"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
@@ -1,36 +0,0 @@
{
"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
@@ -0,0 +1,25 @@
// 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
@@ -0,0 +1,76 @@
// 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() {}
}
@@ -0,0 +1,22 @@
// 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,18 +1,15 @@
package frc.robot.constants;
package first.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;
@@ -1,8 +1,10 @@
package frc.robot.constants;
package first.robot.constants;
import org.wpilib.hardware.bus.CANPort;
import com.revrobotics.spark.FeedbackSensor;
import com.revrobotics.spark.config.SparkMaxConfig;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
import com.revrobotics.spark.config.SparkMaxConfig;
public class ClimberConstants {
// TODO Real values
@@ -22,6 +24,8 @@ public class ClimberConstants {
}
}
public static final CANPort kCANPort = CANPort.CAN_S0;
public static final int kMotorCANID = 0;
public static final double kConversionFactor = 0;
@@ -49,6 +53,9 @@ 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,19 +1,14 @@
package frc.robot.constants;
package first.robot.constants;
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;
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;
public class CompetitionConstants {
// 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 Field kField = Fields.FRC_2026_REBUILT_ANDY_MARK.loadField();
public static final double kHubGoalHeightMeters = Units.inchesToMeters(72);
@@ -1,12 +1,13 @@
package frc.robot.constants;
package first.robot.constants;
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;
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;
public class DrivetrainConstants {
public static final double kMaxSpeedMetersPerSecond = 4.663;
@@ -20,6 +21,8 @@ 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;
@@ -46,7 +49,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.9, 0.9, 0.9);
public static final Matrix<N3, N1> kVisionOdometryStdDevs = VecBuilder.fill(0.3, 0.3, 0.3);
// 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,24 +1,22 @@
package frc.robot.constants;
package first.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.SparkMaxConfig;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
import com.revrobotics.spark.config.SparkMaxConfig;
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;
import first.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;
@@ -59,6 +57,9 @@ 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
@@ -1,25 +1,35 @@
package frc.robot.constants;
package first.robot.constants;
import org.wpilib.hardware.bus.CANPort;
import com.revrobotics.spark.FeedbackSensor;
import com.revrobotics.spark.config.SparkMaxConfig;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
import com.revrobotics.spark.config.SparkMaxConfig;
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;
@@ -53,6 +63,9 @@ 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
@@ -60,6 +73,9 @@ 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,10 +1,14 @@
package frc.robot.constants;
package first.robot.constants;
import com.revrobotics.spark.config.SparkMaxConfig;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
import org.wpilib.hardware.bus.CANPort;
import com.revrobotics.spark.config.SparkMaxConfig;
public class IntakeRollerConstants {
// TODO Real values
public static final CANPort kCANPort = CANPort.CAN_S0;
public static final int kRightMotorCANID = 20;
public static final int kLeftMotorCANID = 1;
@@ -13,7 +17,8 @@ public class IntakeRollerConstants {
public static final boolean kInvertLeftMotor = false;
public static final boolean kInvertRightMotor = true;
public static final double kSpeed = 1;
public static final double kIntakeInSpeed = .9;
public static final double kIntakeOutSpeed = 1;
public static final IdleMode kIdleMode = IdleMode.kCoast;
@@ -1,4 +1,4 @@
package frc.robot.constants;
package first.robot.constants;
public class KrakenMotorConstants {
public static final double kFreeSpeedRPM = 6000;
@@ -1,4 +1,7 @@
package frc.robot.constants;
package first.robot.constants;
import org.wpilib.hardware.bus.CANPort;
import org.wpilib.math.util.Units;
import com.ctre.phoenix6.configs.AudioConfigs;
import com.ctre.phoenix6.configs.ClosedLoopRampsConfigs;
@@ -10,10 +13,8 @@ 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.SparkMaxConfig;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
import edu.wpi.first.math.util.Units;
import com.revrobotics.spark.config.SparkMaxConfig;
public class ModuleConstants {
public enum ModuleName {
@@ -29,7 +30,7 @@ public class ModuleConstants {
}
public String getLoggableName() {
return "Drivetrain/Modules/" + loggableName;
return loggableName;
}
}
@@ -56,7 +57,7 @@ public class ModuleConstants {
// TODO Hold over from 2025, adjust?
public static final int kDriveMotorStatorCurrentLimit = 90;
public static final int kDriveMotorSupplyCurrentLimit = 55;
public static final int kDriveMotorSupplyCurrentLimit = 40;
// TODO Hold over from 2025, adjust?
public static final InvertedValue kDriveInversionState = InvertedValue.Clockwise_Positive;
@@ -119,7 +120,9 @@ public class ModuleConstants {
.smartCurrentLimit(kTurnMotorCurrentLimit)
.inverted(true);
turningConfig.encoder
//.inverted(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
.positionConversionFactor(kTurningFactor)
.velocityConversionFactor(kTurningFactor / 60.0);
turningConfig.closedLoop
@@ -128,6 +131,9 @@ 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 frc.robot.constants;
package first.robot.constants;
import edu.wpi.first.wpilibj.util.Color;
import org.wpilib.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.kRed.toHexString(),
Color.kBlue.toHexString()
Color.RED.toHexString(),
Color.BLUE.toHexString()
};
public static final String[] kRedDisplay = {
Color.kRed.toHexString()
Color.RED.toHexString()
};
public static final String[] kBlueDisplay = {
Color.kBlue.toHexString()
Color.BLUE.toHexString()
};
}
@@ -1,11 +1,12 @@
package frc.robot.constants;
package first.robot.constants;
import java.util.List;
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;
import org.wpilib.math.geometry.Rotation3d;
import org.wpilib.math.geometry.Transform3d;
import org.wpilib.math.util.Units;
import first.robot.utilities.PhotonVisionConfig;
public class PhotonConstants {
public static final String kCamera1Name = "CameraPV1";
@@ -0,0 +1,28 @@
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,13 +1,11 @@
package frc.robot.constants;
package first.robot.constants;
import org.wpilib.math.util.Units;
import com.revrobotics.spark.ClosedLoopSlot;
import com.revrobotics.spark.FeedbackSensor;
import com.revrobotics.spark.config.SparkMaxConfig;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
import edu.wpi.first.math.controller.SimpleMotorFeedforward;
import edu.wpi.first.math.util.Units;
import com.revrobotics.spark.config.SparkMaxConfig;
public class ShooterConstants {
public enum ShooterSpeeds {
@@ -43,14 +41,14 @@ public class ShooterConstants {
public static final boolean kLeftShooterMotorInverted = true;
public static final boolean kRightShooterMotorInverted = false;
public static final double kLeftP = 0.1;//0.01;//0.001;
public static final double kLeftP = 0.75;//0.01;//0.001;
public static final double kLeftI = 0;
public static final double kLeftD = 0;//0.1;//1.8;
public static final double kLeftS = 0;
public static final double kLeftV = 0.00129;
public static final double kLeftA = 0;
public static final double kRightP = 0.1;//0.001;//0.001;
public static final double kRightP = 0.75;//0.001;//0.001;
public static final double kRightI = 0;
public static final double kRightD = 0;//0.1;
public static final double kRightS = 0;
@@ -71,13 +69,15 @@ 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
@@ -94,6 +94,9 @@ public class ShooterConstants {
.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
@@ -1,11 +1,11 @@
package frc.robot.constants;
package first.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.SparkMaxConfig;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
import com.revrobotics.spark.config.SparkMaxConfig;
public class SpindexerConstants {
// TODO Real values
@@ -0,0 +1,7 @@
package first.robot.constants;
import org.wpilib.hardware.imu.OnboardIMU.MountOrientation;
public class SystemCoreConstants {
public static final MountOrientation kSystemCoreMountOrientation = MountOrientation.FLAT;
}
@@ -0,0 +1,13 @@
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();
}
@@ -1,22 +1,23 @@
package frc.robot.subsystems;
package first.robot.subsystems;
import java.util.function.DoubleSupplier;
import org.littletonrobotics.junction.Logger;
import org.wpilib.command2.Command;
import org.wpilib.command2.SubsystemBase;
import org.wpilib.epilogue.Logged;
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.ControlType;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import com.revrobotics.spark.SparkMax;
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;
import first.robot.constants.ClimberConstants;
import first.robot.constants.ClimberConstants.ClimberPositions;
@Logged
public class Climber extends SubsystemBase {
private SparkMax motor;
@@ -27,7 +28,11 @@ public class Climber extends SubsystemBase {
private ClimberPositions targetPosition;
public Climber() {
motor = new SparkMax(ClimberConstants.kMotorCANID, MotorType.kBrushless);
motor = new SparkMax(
ClimberConstants.kCANPort,
ClimberConstants.kMotorCANID,
MotorType.kBrushless
);
motor.configure(
ClimberConstants.kMotorConfig,
@@ -42,11 +47,20 @@ public class Climber extends SubsystemBase {
targetPosition = null;
}
@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 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();
}
public Command maintainPosition(ClimberPositions position) {
@@ -64,7 +78,7 @@ public class Climber extends SubsystemBase {
return run(() -> {
targetPosition = null;
motor.set(speed.getAsDouble());
motor.setThrottle(speed.getAsDouble());
});
}
@@ -1,4 +1,4 @@
package frc.robot.subsystems;
package first.robot.subsystems;
import java.util.List;
import java.util.Optional;
@@ -6,33 +6,35 @@ import java.util.function.BooleanSupplier;
import java.util.function.DoubleSupplier;
import java.util.function.Supplier;
import org.littletonrobotics.junction.Logger;
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 com.pathplanner.lib.auto.AutoBuilder;
import com.pathplanner.lib.path.PathPlannerPath;
import com.studica.frc.AHRS;
import com.studica.frc.AHRS.NavXComType;
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;
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;
public class Drivetrain extends SubsystemBase {
private SwerveModule frontLeft;
@@ -40,7 +42,7 @@ public class Drivetrain extends SubsystemBase {
private SwerveModule rearLeft;
private SwerveModule rearRight;
private AHRS gyro;
private OnboardIMU imu;
private SwerveDrivePoseEstimator estimator;
@@ -48,6 +50,7 @@ public class Drivetrain extends SubsystemBase {
public Drivetrain(Pose2d startupPose) {
frontLeft = new SwerveModule(
DrivetrainConstants.kCANPort,
ModuleName.kFrontLeft,
DrivetrainConstants.kFrontLeftDrivingCANID,
DrivetrainConstants.kFrontLeftTurningCANID,
@@ -56,6 +59,7 @@ public class Drivetrain extends SubsystemBase {
);
frontRight = new SwerveModule(
DrivetrainConstants.kCANPort,
ModuleName.kFrontRight,
DrivetrainConstants.kFrontRightDrivingCANID,
DrivetrainConstants.kFrontRightTurningCANID,
@@ -64,6 +68,7 @@ public class Drivetrain extends SubsystemBase {
);
rearLeft = new SwerveModule(
DrivetrainConstants.kCANPort,
ModuleName.kRearLeft,
DrivetrainConstants.kRearLeftDrivingCANID,
DrivetrainConstants.kRearLeftTurningCANID,
@@ -72,6 +77,7 @@ public class Drivetrain extends SubsystemBase {
);
rearRight = new SwerveModule(
DrivetrainConstants.kCANPort,
ModuleName.kRearRight,
DrivetrainConstants.kRearRightDrivingCANID,
DrivetrainConstants.kRearRightTurningCANID,
@@ -79,7 +85,7 @@ public class Drivetrain extends SubsystemBase {
DrivetrainConstants.kRearRightMagEncoderOffset
);
gyro = new AHRS(NavXComType.kMXP_SPI);
imu = new OnboardIMU(SystemCoreConstants.kSystemCoreMountOrientation);
yawRotationController = new PIDController(
DrivetrainConstants.kHeadingP,
@@ -113,9 +119,9 @@ public class Drivetrain extends SubsystemBase {
AutoConstants.kPPDriveController,
AutoConstants.kRobotConfig,
() -> {
Optional<DriverStation.Alliance> alliance = DriverStation.getAlliance();
Optional<Alliance> alliance = MatchState.getAlliance();
if (alliance.isPresent()) {
return alliance.get() == DriverStation.Alliance.Red;
return alliance.get() == Alliance.RED;
}
return false;
},
@@ -169,7 +175,7 @@ public class Drivetrain extends SubsystemBase {
.get();
return run(() -> {
module.setDesiredState(new SwerveModuleState(
module.setDesiredState(new SwerveModuleVelocity(
staticSpeed,
Rotation2d.fromDegrees(staticAngleDegrees)
));
@@ -324,16 +330,16 @@ public class Drivetrain extends SubsystemBase {
public Command setX() {
return run(() -> {
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)));
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)));
});
}
public Command zeroHeading() {
return run(() -> {
gyro.reset();
imu.resetYaw();;
estimator.resetRotation(new Rotation2d(0));
});
}
@@ -384,26 +390,25 @@ public class Drivetrain extends SubsystemBase {
double rotationDelivered = rotation * DrivetrainConstants.kMaxAngularSpeed;
SwerveModuleState[] swerveModuleStates = DrivetrainConstants.kDriveKinematics.toSwerveModuleStates(
ChassisVelocities velocities = new ChassisVelocities(xSpeedDelivered, ySpeedDelivered, rotationDelivered);
SwerveModuleVelocity[] swerveModuleStates = DrivetrainConstants.kDriveKinematics.toSwerveModuleVelocities(
fieldRelative ?
ChassisSpeeds.fromFieldRelativeSpeeds(xSpeedDelivered, ySpeedDelivered, rotationDelivered,
//estimator.getEstimatedPosition().getRotation()) :
Rotation2d.fromDegrees(getGyroValue())) :
new ChassisSpeeds(xSpeedDelivered, ySpeedDelivered, rotationDelivered)
velocities.toFieldRelative(Rotation2d.fromDegrees(getGyroValue())) : velocities
);
setModuleStates(swerveModuleStates);
}
public void driveWithChassisSpeeds(ChassisSpeeds speeds) {
ChassisSpeeds discreteSpeeds = ChassisSpeeds.discretize(speeds, 0.2);
SwerveModuleState[] newStates = DrivetrainConstants.kDriveKinematics.toSwerveModuleStates(discreteSpeeds);
public void driveWithChassisSpeeds(ChassisVelocities speeds) {
ChassisVelocities discreteSpeeds = speeds.discretize(0.2);
SwerveModuleVelocity[] newStates = DrivetrainConstants.kDriveKinematics.toSwerveModuleVelocities(discreteSpeeds);
setModuleStates(newStates);
}
public void setModuleStates(SwerveModuleState[] desiredStates) {
SwerveDriveKinematics.desaturateWheelSpeeds(
public void setModuleStates(SwerveModuleVelocity[] desiredStates) {
SwerveDriveKinematics.desaturateWheelVelocities(
desiredStates, DrivetrainConstants.kMaxSpeedMetersPerSecond);
frontLeft.setDesiredState(desiredStates[0]);
frontRight.setDesiredState(desiredStates[1]);
@@ -411,8 +416,8 @@ public class Drivetrain extends SubsystemBase {
rearRight.setDesiredState(desiredStates[3]);
}
public ChassisSpeeds getCurrentChassisSpeeds() {
return DrivetrainConstants.kDriveKinematics.toChassisSpeeds(
public ChassisVelocities getCurrentChassisSpeeds() {
return DrivetrainConstants.kDriveKinematics.toChassisVelocities(
frontLeft.getState(),
frontRight.getState(),
rearLeft.getState(),
@@ -425,7 +430,7 @@ public class Drivetrain extends SubsystemBase {
}
public double getGyroValue() {
return gyro.getAngle() * (DrivetrainConstants.kGyroReversed ? -1 : 1);
return imu.getYawRadians() * (DrivetrainConstants.kGyroReversed ? -1 : 1);
}
public Rotation2d getHeading() {
@@ -436,3 +441,4 @@ public class Drivetrain extends SubsystemBase {
return estimator.getEstimatedPosition().getRotation().getDegrees();
}
}
@@ -1,30 +1,25 @@
package frc.robot.subsystems;
package first.robot.subsystems;
import java.util.Optional;
import java.util.function.DoubleSupplier;
import org.littletonrobotics.junction.Logger;
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 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.ControlType;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import com.revrobotics.spark.SparkMax;
import edu.wpi.first.math.MathUtil;
import edu.wpi.first.math.geometry.Pose2d;
import edu.wpi.first.math.interpolation.InterpolatingDoubleTreeMap;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.InstantCommand;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
import edu.wpi.first.wpilibj2.command.button.Trigger;
import frc.robot.constants.HoodConstants;
import frc.robot.constants.ShooterConstants.ShooterSpeeds;
import frc.robot.utilities.Utilities;
import first.robot.constants.HoodConstants;
import first.robot.constants.ShooterConstants.ShooterSpeeds;
import first.robot.utilities.Utilities;
public class Hood extends SubsystemBase {
private SparkMax motor;
@@ -41,7 +36,11 @@ public class Hood extends SubsystemBase {
private double currentTargetDegrees;
public Hood() {
motor = new SparkMax(HoodConstants.kMotorCANID, MotorType.kBrushless);
motor = new SparkMax(
HoodConstants.kCANPort,
HoodConstants.kMotorCANID,
MotorType.kBrushless
);
motor.configure(
HoodConstants.kConfig,
@@ -170,7 +169,7 @@ public class Hood extends SubsystemBase {
currentTargetDegrees = 0;
return run(() -> {
motor.set(speed.getAsDouble() * HoodConstants.kMaxManualSpeedMultiplier);
motor.setThrottle(speed.getAsDouble() * HoodConstants.kMaxManualSpeedMultiplier);
});
}
@@ -1,23 +1,22 @@
package frc.robot.subsystems;
package first.robot.subsystems;
import java.util.Optional;
import java.util.function.DoubleSupplier;
import org.littletonrobotics.junction.Logger;
import org.wpilib.command2.Command;
import org.wpilib.command2.Commands;
import org.wpilib.command2.SubsystemBase;
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.ControlType;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import com.revrobotics.spark.SparkMax;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.Commands;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
import frc.robot.constants.IntakePivotConstants;
import frc.robot.constants.IntakePivotConstants.IntakePivotPosition;
import first.robot.constants.IntakePivotConstants;
import first.robot.constants.IntakePivotConstants.IntakePivotPosition;
public class IntakePivot extends SubsystemBase {
private SparkMax leftMotor;
@@ -30,8 +29,16 @@ public class IntakePivot extends SubsystemBase {
private IntakePivotPosition currentTargetPosition;
public IntakePivot() {
leftMotor = new SparkMax(IntakePivotConstants.kLeftMotorCANID, MotorType.kBrushless);
rightMotor = new SparkMax(IntakePivotConstants.kRightMotorCANID, MotorType.kBrushless);
leftMotor = new SparkMax(
IntakePivotConstants.kCANPort,
IntakePivotConstants.kLeftMotorCANID,
MotorType.kBrushless
);
rightMotor = new SparkMax(
IntakePivotConstants.kCANPort,
IntakePivotConstants.kRightMotorCANID,
MotorType.kBrushless
);
leftMotor.configure(
IntakePivotConstants.KLeftMotorConfig,
@@ -76,8 +83,8 @@ public class IntakePivot extends SubsystemBase {
return run(() -> {
currentTargetPosition = null;
leftMotor.set(speed.getAsDouble() * IntakePivotConstants.kMaxManualSpeedMultiplier);
rightMotor.set(speed.getAsDouble() * IntakePivotConstants.kMaxManualSpeedMultiplier);
leftMotor.setThrottle(speed.getAsDouble() * IntakePivotConstants.kMaxManualSpeedMultiplier);
rightMotor.setThrottle(speed.getAsDouble() * IntakePivotConstants.kMaxManualSpeedMultiplier);
});
}
@@ -115,3 +122,4 @@ public class IntakePivot extends SubsystemBase {
return Optional.ofNullable(currentTargetPosition);
}
}
@@ -1,21 +1,31 @@
package frc.robot.subsystems;
package first.robot.subsystems;
import org.wpilib.command2.Command;
import org.wpilib.command2.SubsystemBase;
import com.revrobotics.PersistMode;
import com.revrobotics.ResetMode;
import com.revrobotics.spark.SparkMax;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import com.revrobotics.spark.SparkMax;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
import frc.robot.constants.IntakeRollerConstants;
import first.robot.constants.IntakeRollerConstants;
public class IntakeRoller extends SubsystemBase {
private SparkMax leftMotor;
private SparkMax rightMotor;
public IntakeRoller() {
leftMotor = new SparkMax(IntakeRollerConstants.kLeftMotorCANID, MotorType.kBrushless);
rightMotor = new SparkMax(IntakeRollerConstants.kRightMotorCANID, MotorType.kBrushless);
leftMotor = new SparkMax(
IntakeRollerConstants.kCANPort,
IntakeRollerConstants.kLeftMotorCANID,
MotorType.kBrushless
);
rightMotor = new SparkMax(
IntakeRollerConstants.kCANPort,
IntakeRollerConstants.kRightMotorCANID,
MotorType.kBrushless
);
leftMotor.configure(
IntakeRollerConstants.leftMotorConfig,
@@ -32,22 +42,22 @@ public class IntakeRoller extends SubsystemBase {
public Command runIn() {
return run(() -> {
leftMotor.set(IntakeRollerConstants.kSpeed*0.8);
rightMotor.set(IntakeRollerConstants.kSpeed*0.8);
leftMotor.setThrottle(IntakeRollerConstants.kIntakeInSpeed);
rightMotor.setThrottle(IntakeRollerConstants.kIntakeInSpeed);
});
}
public Command runOut() {
return run(() -> {
leftMotor.set(-IntakeRollerConstants.kSpeed);
rightMotor.set(-IntakeRollerConstants.kSpeed);
leftMotor.setThrottle(-IntakeRollerConstants.kIntakeOutSpeed);
rightMotor.setThrottle(-IntakeRollerConstants.kIntakeOutSpeed);
});
}
public Command stop() {
return run(() -> {
leftMotor.set(0);
rightMotor.set(0);
leftMotor.setThrottle(0);
rightMotor.setThrottle(0);
});
}
@@ -1,4 +1,4 @@
package frc.robot.subsystems;
package first.robot.subsystems;
import java.util.ArrayList;
import java.util.List;
@@ -9,18 +9,16 @@ 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 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;
import first.robot.constants.CompetitionConstants;
import first.robot.constants.PhotonConstants;
import first.robot.utilities.PhotonVisionConfig;
import first.robot.utilities.VisualPose;
/**
* This "Subsystem" is not actually a Subsystem. The intent is for this to be treated as
@@ -59,8 +57,7 @@ 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.kTagLayout,
PoseStrategy.MULTI_TAG_PNP_ON_COPROCESSOR,
CompetitionConstants.kField,
PhotonConstants.configs.get(i).robotToCamera()
);
latestResults.add(null);
@@ -77,7 +74,7 @@ public class PhotonVision extends SubsystemBase {
if(!results.isEmpty()) {
latestResults.set(i, results.get(results.size() - 1));
Optional<EstimatedRobotPose> pose = estimators[i].update(latestResults.get(i));
Optional<EstimatedRobotPose> pose = estimators[i].estimateCoprocMultiTagPose(latestResults.get(i));
if(!pose.isEmpty()) {
VisualPose visualPose = new VisualPose(
@@ -137,9 +134,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.kZero
return Optional.of(Pose3d.ZERO
.plus(bestCameraToTarget.inverse())
.relativeTo(CompetitionConstants.kTagLayout.getOrigin())
.relativeTo(CompetitionConstants.kField.getOrigin())
.plus(config.robotToCamera().inverse()));
}
@@ -204,3 +201,4 @@ public class PhotonVision extends SubsystemBase {
poseEstimateConsumers.add(consumer);
}
}
@@ -1,28 +1,27 @@
// 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
package first.robot.utilities;
package frc.robot.utilities;
import org.wpilib.networktables.NetworkTableInstance;
import org.wpilib.networktables.PubSubOption;
import org.wpilib.networktables.StringPublisher;
import org.wpilib.networktables.StringTopic;
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;
import io.avaje.json.JsonException;
import io.avaje.jsonb.Json;
import io.avaje.jsonb.JsonType;
import io.avaje.jsonb.Jsonb;
public final class Elastic {
private static final StringTopic notificationTopic =
NetworkTableInstance.getDefault().getStringTopic("/Elastic/RobotNotifications");
private static final StringPublisher notificationPublisher =
notificationTopic.publish(PubSubOption.sendAll(true), PubSubOption.keepDuplicates(true));
notificationTopic.publish(PubSubOption.SEND_ALL, PubSubOption.KEEP_DUPLICATES);
private static final StringTopic selectedTabTopic =
NetworkTableInstance.getDefault().getStringTopic("/Elastic/SelectedTab");
private static final StringPublisher selectedTabPublisher =
selectedTabTopic.publish(PubSubOption.keepDuplicates(true));
private static final ObjectMapper objectMapper = new ObjectMapper();
selectedTabTopic.publish(PubSubOption.KEEP_DUPLICATES);
private static final Jsonb jsonb = Jsonb.builder().build();
private static final JsonType<Notification> notificationJsonType =
jsonb.type(Notification.class);
/**
* Represents the possible levels of notifications for the Elastic dashboard. These levels are
@@ -45,8 +44,8 @@ public final class Elastic {
*/
public static void sendNotification(Notification notification) {
try {
notificationPublisher.set(objectMapper.writeValueAsString(notification));
} catch (JsonProcessingException e) {
notificationPublisher.set(notificationJsonType.toJson(notification));
} catch (JsonException e) {
e.printStackTrace();
}
}
@@ -79,23 +78,24 @@ 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 {
@JsonProperty("level")
@Json.Property("level")
private NotificationLevel level;
@JsonProperty("title")
@Json.Property("title")
private String title;
@JsonProperty("description")
@Json.Property("description")
private String description;
@JsonProperty("displayTime")
@Json.Property("displayTime")
private int displayTimeMillis;
@JsonProperty("width")
@Json.Property("width")
private double width;
@JsonProperty("height")
@Json.Property("height")
private double height;
/**
@@ -1,6 +1,6 @@
package frc.robot.utilities;
package first.robot.utilities;
import edu.wpi.first.math.geometry.Transform3d;
import org.wpilib.math.geometry.Transform3d;
public record PhotonVisionConfig (
String cameraName,
@@ -1,12 +1,13 @@
package frc.robot.utilities;
package first.robot.utilities;
import java.util.function.DoubleSupplier;
import com.revrobotics.spark.SparkMax;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import org.wpilib.command2.Command;
import org.wpilib.command2.SubsystemBase;
import org.wpilib.hardware.bus.CANPort;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import com.revrobotics.spark.SparkMax;
/**
* A simple subsystem that can be used to test a single SparkMax and associated NEO motor
@@ -19,8 +20,8 @@ public class SparkMAXTester extends SubsystemBase {
*
* @param deviceID The CAN ID of the SparkMAX that needs testing
*/
public SparkMAXTester(int deviceID) {
spark = new SparkMax(deviceID, MotorType.kBrushless);
public SparkMAXTester(CANPort canPort, int deviceID) {
spark = new SparkMax(canPort, deviceID, MotorType.kBrushless);
}
/**
@@ -31,7 +32,7 @@ public class SparkMAXTester extends SubsystemBase {
*/
public Command setSpeed(DoubleSupplier speed) {
return run(() -> {
spark.set(speed.getAsDouble());
spark.setThrottle(speed.getAsDouble());
});
}
}
@@ -1,23 +1,24 @@
package frc.robot.utilities;
package first.robot.utilities;
import org.littletonrobotics.junction.Logger;
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 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.SparkMax;
import com.revrobotics.spark.SparkBase.ControlType;
import com.revrobotics.spark.SparkLowLevel.ControlType;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import com.revrobotics.spark.SparkMax;
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;
import first.robot.constants.ModuleConstants;
import first.robot.constants.ModuleConstants.ModuleName;
/*
* This thread
@@ -44,8 +45,8 @@ public class SwerveModule {
private VelocityVoltage driveVelocityRequest;
private SwerveModuleState lastTargetState;
private SwerveModuleState lastTargetStateOptimized;
private SwerveModuleVelocity lastTargetState;
private SwerveModuleVelocity lastTargetStateOptimized;
private boolean isAbsoluteEncoderDisabled;
private boolean turningEncoderAutoRezeroEnabled;
@@ -56,32 +57,35 @@ 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(ModuleName moduleName, int drivingCANID, int turningCANID) {
this(moduleName, drivingCANID, turningCANID, -1, -1);
public SwerveModule(CANPort canPort, ModuleName moduleName, int drivingCANID, int turningCANID) {
this(canPort, 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(ModuleName moduleName, int drivingCANID, int turningCANID, int analogEncoderID, double analogEncoderOffset) {
this(moduleName, drivingCANID, turningCANID, analogEncoderID, analogEncoderOffset, false);
public SwerveModule(CANPort canPort, ModuleName moduleName, int drivingCANID, int turningCANID, int analogEncoderID, double analogEncoderOffset) {
this(canPort, 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
@@ -89,12 +93,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(ModuleName moduleName, int drivingCANID, int turningCANID,
public SwerveModule(CANPort canPort, ModuleName moduleName, int drivingCANID, int turningCANID,
int analogEncoderID, double analogEncoderOffset, boolean turningEncoderAutoRezeroEnabled) {
isAbsoluteEncoderDisabled = (analogEncoderID == -1) || (analogEncoderOffset < 0);
drive = new TalonFX(drivingCANID);
turning = new SparkMax(turningCANID, MotorType.kBrushless);
drive = new TalonFX(drivingCANID, new CANBus(canPort));
turning = new SparkMax(canPort, turningCANID, MotorType.kBrushless);
turningRelativeEncoder = turning.getEncoder();
@@ -161,8 +165,8 @@ public class SwerveModule {
return moduleName;
}
public SwerveModuleState getState() {
return new SwerveModuleState(
public SwerveModuleVelocity getState() {
return new SwerveModuleVelocity(
drive.getVelocity().getValueAsDouble() * ModuleConstants.kWheelCircumferenceMeters,
new Rotation2d(getTurningEncoderPosition())
);
@@ -180,8 +184,8 @@ public class SwerveModule {
turning.disable();
}
public void setDesiredState(SwerveModuleState desiredState) {
lastTargetState = new SwerveModuleState(desiredState.speedMetersPerSecond, desiredState.angle);
public void setDesiredState(SwerveModuleVelocity desiredState) {
lastTargetState = new SwerveModuleVelocity(desiredState.velocity, desiredState.angle);
desiredState.optimize(new Rotation2d(getTurningEncoderPosition()));
@@ -189,9 +193,9 @@ public class SwerveModule {
drive.setControl(
driveVelocityRequest.withVelocity(
desiredState.speedMetersPerSecond / ModuleConstants.kWheelCircumferenceMeters
desiredState.velocity / ModuleConstants.kWheelCircumferenceMeters
).withFeedForward(
desiredState.speedMetersPerSecond / ModuleConstants.kWheelCircumferenceMeters
desiredState.velocity / ModuleConstants.kWheelCircumferenceMeters
)
);
@@ -202,7 +206,7 @@ public class SwerveModule {
}
public double getTurningEncoderPosition() {
return turningRelativeEncoder.getPosition() * (ModuleConstants.kIsEncoderInverted ? -1 : 1);
return turningRelativeEncoder.getPosition().get() * (ModuleConstants.kIsEncoderInverted ? -1 : 1);
}
public void resetEncoders() {
@@ -219,3 +223,4 @@ public class SwerveModule {
}
}
}
@@ -1,11 +1,12 @@
package frc.robot.utilities;
package first.robot.utilities;
import java.util.Optional;
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;
import org.wpilib.driverstation.Alliance;
import org.wpilib.driverstation.MatchState;
import org.wpilib.math.geometry.Pose2d;
import first.robot.constants.CompetitionConstants;
public class Utilities {
public static final double kG = -9.81;
@@ -18,19 +19,22 @@ public class Utilities {
* is not present
*/
public static Alliance whoHasFirstShift() {
String gameData = DriverStation.getGameSpecificMessage();
Optional<String> gameData = MatchState.getGameData();
if(gameData.length() > 0) {
switch (gameData.charAt(0)) {
case 'B':
return Alliance.Red;
case 'R':
return Alliance.Blue;
default:
return null;
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;
}
}
}
return null;
}
@@ -42,9 +46,9 @@ public class Utilities {
* @return The Pose2d object which represents the appropriate pose of the Hub
*/
public static Pose2d getHubPose() {
Optional<Alliance> alliance = DriverStation.getAlliance();
Optional<Alliance> alliance = MatchState.getAlliance();
if(alliance.isEmpty() || alliance.get() == Alliance.Blue) {
if(alliance.isEmpty() || alliance.get() == Alliance.BLUE) {
return CompetitionConstants.kBlueHubLocation;
} else {
return CompetitionConstants.kRedHubLocation;
@@ -59,9 +63,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 = DriverStation.getAlliance();
Optional<Alliance> alliance = MatchState.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 frc.robot.utilities;
package first.robot.utilities;
import edu.wpi.first.math.geometry.Pose2d;
import org.wpilib.math.geometry.Pose2d;
/**
* A record class which represents the source of a visual pose, the pose itself
-15
View File
@@ -1,15 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package frc.robot;
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
@@ -1,101 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package frc.robot;
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() {}
}
-505
View File
@@ -1,505 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package frc.robot;
import edu.wpi.first.wpilibj.DriverStation.Alliance;
import edu.wpi.first.wpilibj.GenericHID.RumbleType;
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.FunctionalCommand;
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();
configureShiftDisplay();
//testConfigureBindings();
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.x().whileTrue(drivetrain.setX());
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().alongWith(
intakeRoller.runIn(),
intakePivot.jimmy(.5)
)
);
driver.rightTrigger().onFalse(
intakePivot.manualSpeed(() -> 0.75).withTimeout(0.5)
);
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().whileTrue(hood.trackToAngle(() -> Units.degreesToRadians(10)));
//10 degrees good for shooting ~33in away from hub
hood.setDefaultCommand(hood.trackToAnglePoseBased(drivetrain, shooter));
/*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;
}
}));*/
new Trigger(() -> MathUtil.isNear(
shooter.getTargetSpeeds().isEmpty() ? 0 : shooter.getTargetSpeeds().get().getSpeedRPM(),
shooter.getAverageActualSpeeds(),
150)).onTrue(
new FunctionalCommand(
() -> {},
() -> {
driver.setRumble(RumbleType.kBothRumble, .75);
secondary.setRumble(RumbleType.kBothRumble, .75);
},
(b) -> {
driver.setRumble(RumbleType.kBothRumble, 0);
secondary.setRumble(RumbleType.kBothRumble, 0);
},
() -> false
).withTimeout(1)
);
}
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",
intakePivot.jimmy(0.2)
);
NamedCommands.registerCommand("shoot N jimmy",
Commands.parallel(
intakePivot.jimmy(0.5),
spindexer.spinToShooter()
.alongWith(shooter.maintainSpeed(ShooterSpeeds.kHubSpeed),
hood.trackToAngle(() -> Units.degreesToRadians(10)))
).withTimeout(3).andThen(spindexer.instantaneousStop()));
NamedCommands.registerCommand("auto shoot", hood.trackToAnglePoseBased(drivetrain, shooter));
}
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,161 +0,0 @@
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.ClosedLoopSlot;
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.math.controller.SimpleMotorFeedforward;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
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;
private SimpleMotorFeedforward shooterFFLeft;
private SimpleMotorFeedforward shooterFFRight;
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();
shooterFFLeft = new SimpleMotorFeedforward(ShooterConstants.kLeftS, ShooterConstants.kLeftV, ShooterConstants.kLeftA);
shooterFFRight = new SimpleMotorFeedforward(ShooterConstants.kRightS, ShooterConstants.kRightV, ShooterConstants.kRightA);
}
@Override
public void periodic() {
SmartDashboard.putNumber(
"ShooterTargetRPM",
targetSpeeds == null ? 0 : targetSpeeds.getSpeedRPM());
SmartDashboard.putNumber(
"ShooterLeftSideRPM",
leftEncoder.getVelocity()
);
SmartDashboard.putNumber(
"ShooterRightSideRPM",
rightEncoder.getVelocity()
);
SmartDashboard.putBoolean(
"ShooterLeftSideAtSetpoint",
leftClosedLoopController.isAtSetpoint()
);
SmartDashboard.putBoolean(
"ShooterRightSideAtSetpoint",
rightClosedLoopController.isAtSetpoint()
);
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());
Logger.recordOutput("Shooter/LeftRollers/OutputVoltage", leftMotor.getAppliedOutput() * leftMotor.getBusVoltage());
Logger.recordOutput("Shooter/RightRollers/OutputVoltage", rightMotor.getAppliedOutput() * rightMotor.getBusVoltage());
// 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,
ClosedLoopSlot.kSlot0,
shooterFFLeft.calculate(targetSpeeds.getSpeedRPM())
);
rightClosedLoopController.setSetpoint(
targetSpeeds.getSpeedRPM(),
ControlType.kVelocity,
ClosedLoopSlot.kSlot0,
shooterFFRight.calculate(targetSpeeds.getSpeedRPM())
);
}
});
}
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);
}
}
@@ -1,70 +0,0 @@
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);
});
}
}
-35
View File
@@ -1,35 +0,0 @@
{
"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,36 +1,41 @@
{
"fileName": "WPILibNewCommands.json",
"name": "WPILib-New-Commands",
"fileName": "CommandsV2.json",
"name": "Commands V2",
"version": "1.0.0",
"uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266",
"frcYear": "2026",
"wpilibYear": "2027_alpha7",
"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": "edu.wpi.first.wpilibNewCommands",
"artifactId": "wpilibNewCommands-java",
"groupId": "org.wpilib.commandsv2",
"artifactId": "commandsv2-java",
"version": "wpilib"
}
],
"jniDependencies": [],
"cppDependencies": [
{
"groupId": "edu.wpi.first.wpilibNewCommands",
"artifactId": "wpilibNewCommands-cpp",
"groupId": "org.wpilib.commandsv2",
"artifactId": "commandsv2-cpp",
"version": "wpilib",
"libName": "wpilibNewCommands",
"libName": "commandsv2",
"headerClassifier": "headers",
"sourcesClassifier": "sources",
"sharedLibrary": true,
"skipInvalidPlatforms": true,
"binaryPlatforms": [
"linuxsystemcore",
"linuxathena",
"linuxarm32",
"linuxarm64",
"windowsx86-64",
"windowsx86",
"windowsarm64",
"linuxx86-64",
"osxuniversal"
]
@@ -1,18 +1,18 @@
{
"fileName": "PathplannerLib-2026.1.2.json",
"fileName": "PathplannerLibSystemCoreAlpha.json",
"name": "PathplannerLib",
"version": "2026.1.2",
"version": "2027.0.0-alpha-4.1",
"uuid": "1b42324f-17c6-4875-8e77-1c312bc8c786",
"frcYear": "2026",
"wpilibYear": "2027_alpha7",
"mavenUrls": [
"https://3015rangerrobotics.github.io/pathplannerlib/repo"
],
"jsonUrl": "https://3015rangerrobotics.github.io/pathplannerlib/PathplannerLib.json",
"jsonUrl": "https://3015rangerrobotics.github.io/pathplannerlib/PathplannerLibSystemCoreAlpha.json",
"javaDependencies": [
{
"groupId": "com.pathplanner.lib",
"artifactId": "PathplannerLib-java",
"version": "2026.1.2"
"version": "2027.0.0-alpha-4.1"
}
],
"jniDependencies": [],
@@ -20,7 +20,7 @@
{
"groupId": "com.pathplanner.lib",
"artifactId": "PathplannerLib-cpp",
"version": "2026.1.2",
"version": "2027.0.0-alpha-4.1",
"libName": "PathplannerLib",
"headerClassifier": "headers",
"sharedLibrary": false,
@@ -29,8 +29,7 @@
"windowsx86-64",
"linuxx86-64",
"osxuniversal",
"linuxathena",
"linuxarm32",
"linuxsystemcore",
"linuxarm64"
]
}
-171
View File
@@ -1,171 +0,0 @@
{
"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.1.0.json",
"fileName": "Phoenix6-26.70.0-alpha-2.json",
"name": "CTRE-Phoenix (v6)",
"version": "26.1.0",
"frcYear": "2026",
"version": "26.70.0-alpha-2",
"wpilibYear": "2027_alpha7",
"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-frc2026-latest.json",
"jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2027-latest.json",
"conflictsWith": [
{
"uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af",
"errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.",
"offlineFileName": "Phoenix6-replay-frc2026-latest.json"
"errorMessage": "Users cannot have both the replay and regular Phoenix 6 vendordeps in their robot program.",
"offlineFileName": "Phoenix6-replay-frc2027-latest.json"
}
],
"javaDependencies": [
{
"groupId": "com.ctre.phoenix6",
"artifactId": "wpiapi-java",
"version": "26.1.0"
"version": "26.70.0-alpha-2"
}
],
"jniDependencies": [
{
"groupId": "com.ctre.phoenix6",
"artifactId": "api-cpp",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
"windowsx86-64",
"linuxx86-64",
"linuxarm64",
"linuxathena"
"linuxsystemcore"
],
"simMode": "hwsim"
},
{
"groupId": "com.ctre.phoenix6",
"artifactId": "tools",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
"windowsx86-64",
"linuxx86-64",
"linuxarm64",
"linuxathena"
"linuxsystemcore"
],
"simMode": "hwsim"
},
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "api-cpp-sim",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -68,7 +68,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "tools-sim",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -82,7 +82,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simTalonSRX",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -96,7 +96,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simVictorSPX",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -110,7 +110,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simPigeonIMU",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -124,7 +124,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProTalonFX",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -138,7 +138,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProTalonFXS",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -152,7 +152,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProCANcoder",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -166,7 +166,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProPigeon2",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -180,7 +180,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProCANrange",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -194,7 +194,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProCANdi",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -208,7 +208,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProCANdle",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
@@ -224,7 +224,7 @@
{
"groupId": "com.ctre.phoenix6",
"artifactId": "wpiapi-cpp",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"libName": "CTRE_Phoenix6_WPI",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -233,14 +233,14 @@
"windowsx86-64",
"linuxx86-64",
"linuxarm64",
"linuxathena"
"linuxsystemcore"
],
"simMode": "hwsim"
},
{
"groupId": "com.ctre.phoenix6",
"artifactId": "tools",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"libName": "CTRE_PhoenixTools",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -249,14 +249,14 @@
"windowsx86-64",
"linuxx86-64",
"linuxarm64",
"linuxathena"
"linuxsystemcore"
],
"simMode": "hwsim"
},
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "wpiapi-cpp-sim",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"libName": "CTRE_Phoenix6_WPISim",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -272,7 +272,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "tools-sim",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"libName": "CTRE_PhoenixTools_Sim",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -288,7 +288,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simTalonSRX",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"libName": "CTRE_SimTalonSRX",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -304,7 +304,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simVictorSPX",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"libName": "CTRE_SimVictorSPX",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -320,7 +320,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simPigeonIMU",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"libName": "CTRE_SimPigeonIMU",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -336,7 +336,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProTalonFX",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"libName": "CTRE_SimProTalonFX",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -352,7 +352,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProTalonFXS",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"libName": "CTRE_SimProTalonFXS",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -368,7 +368,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProCANcoder",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"libName": "CTRE_SimProCANcoder",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -384,7 +384,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProPigeon2",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"libName": "CTRE_SimProPigeon2",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -400,7 +400,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProCANrange",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"libName": "CTRE_SimProCANrange",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -416,7 +416,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProCANdi",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"libName": "CTRE_SimProCANdi",
"headerClassifier": "headers",
"sharedLibrary": true,
@@ -432,7 +432,7 @@
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProCANdle",
"version": "26.1.0",
"version": "26.70.0-alpha-2",
"libName": "CTRE_SimProCANdle",
"headerClassifier": "headers",
"sharedLibrary": true,
+18 -25
View File
@@ -1,63 +1,60 @@
{
"fileName": "REVLib.json",
"name": "REVLib",
"version": "2026.0.0",
"frcYear": "2026",
"version": "2027.0.0-alpha-8",
"wpilibYear": "2027_alpha7",
"uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb",
"mavenUrls": [
"https://maven.revrobotics.com/"
],
"jsonUrl": "https://software-metadata.revrobotics.com/REVLib-2026.json",
"jsonUrl": "https://software-metadata.revrobotics.com/REVLib-2027.json",
"javaDependencies": [
{
"groupId": "com.revrobotics.frc",
"artifactId": "REVLib-java",
"version": "2026.0.0"
"version": "2027.0.0-alpha-8"
}
],
"jniDependencies": [
{
"groupId": "com.revrobotics.frc",
"artifactId": "REVLib-driver",
"version": "2026.0.0",
"version": "2027.0.0-alpha-8",
"skipInvalidPlatforms": true,
"isJar": false,
"validPlatforms": [
"windowsx86-64",
"linuxarm64",
"linuxx86-64",
"linuxathena",
"linuxarm32",
"linuxsystemcore",
"osxuniversal"
]
},
{
"groupId": "com.revrobotics.frc",
"artifactId": "RevLibBackendDriver",
"version": "2026.0.0",
"version": "2027.0.0-alpha-8",
"skipInvalidPlatforms": true,
"isJar": false,
"validPlatforms": [
"windowsx86-64",
"linuxarm64",
"linuxx86-64",
"linuxathena",
"linuxarm32",
"linuxsystemcore",
"osxuniversal"
]
},
{
"groupId": "com.revrobotics.frc",
"artifactId": "RevLibWpiBackendDriver",
"version": "2026.0.0",
"version": "2027.0.0-alpha-8",
"skipInvalidPlatforms": true,
"isJar": false,
"validPlatforms": [
"windowsx86-64",
"linuxarm64",
"linuxx86-64",
"linuxathena",
"linuxarm32",
"linuxsystemcore",
"osxuniversal"
]
}
@@ -66,7 +63,7 @@
{
"groupId": "com.revrobotics.frc",
"artifactId": "REVLib-cpp",
"version": "2026.0.0",
"version": "2027.0.0-alpha-8",
"libName": "REVLib",
"headerClassifier": "headers",
"sharedLibrary": false,
@@ -75,15 +72,14 @@
"windowsx86-64",
"linuxarm64",
"linuxx86-64",
"linuxathena",
"linuxarm32",
"linuxsystemcore",
"osxuniversal"
]
},
{
"groupId": "com.revrobotics.frc",
"artifactId": "REVLib-driver",
"version": "2026.0.0",
"version": "2027.0.0-alpha-8",
"libName": "REVLibDriver",
"headerClassifier": "headers",
"sharedLibrary": false,
@@ -92,15 +88,14 @@
"windowsx86-64",
"linuxarm64",
"linuxx86-64",
"linuxathena",
"linuxarm32",
"linuxsystemcore",
"osxuniversal"
]
},
{
"groupId": "com.revrobotics.frc",
"artifactId": "RevLibBackendDriver",
"version": "2026.0.0",
"version": "2027.0.0-alpha-8",
"libName": "BackendDriver",
"sharedLibrary": true,
"skipInvalidPlatforms": true,
@@ -108,15 +103,14 @@
"windowsx86-64",
"linuxarm64",
"linuxx86-64",
"linuxathena",
"linuxarm32",
"linuxsystemcore",
"osxuniversal"
]
},
{
"groupId": "com.revrobotics.frc",
"artifactId": "RevLibWpiBackendDriver",
"version": "2026.0.0",
"version": "2027.0.0-alpha-8",
"libName": "REVLibWpi",
"sharedLibrary": true,
"skipInvalidPlatforms": true,
@@ -124,8 +118,7 @@
"windowsx86-64",
"linuxarm64",
"linuxx86-64",
"linuxathena",
"linuxarm32",
"linuxsystemcore",
"osxuniversal"
]
}
-71
View File
@@ -1,71 +0,0 @@
{
"fileName": "Studica.json",
"name": "Studica",
"version": "2026.0.0",
"frcYear": "2026",
"uuid": "cb311d09-36e9-4143-a032-55bb2b94443b",
"mavenUrls": [
"https://dev.studica.com/maven/release/2026/"
],
"jsonUrl": "https://dev.studica.com/maven/release/2026/json/Studica-2026.0.0.json",
"javaDependencies": [
{
"groupId": "com.studica.frc",
"artifactId": "Studica-java",
"version": "2026.0.0"
}
],
"jniDependencies": [
{
"groupId": "com.studica.frc",
"artifactId": "Studica-driver",
"version": "2026.0.0",
"skipInvalidPlatforms": true,
"isJar": false,
"validPlatforms": [
"windowsx86-64",
"linuxarm64",
"linuxx86-64",
"linuxathena",
"linuxarm32",
"osxuniversal"
]
}
],
"cppDependencies": [
{
"groupId": "com.studica.frc",
"artifactId": "Studica-cpp",
"version": "2026.0.0",
"libName": "Studica",
"headerClassifier": "headers",
"sharedLibrary": false,
"skipInvalidPlatforms": true,
"binaryPlatforms": [
"windowsx86-64",
"linuxarm64",
"linuxx86-64",
"linuxathena",
"linuxarm32",
"osxuniversal"
]
},
{
"groupId": "com.studica.frc",
"artifactId": "Studica-driver",
"version": "2026.0.0",
"libName": "StudicaDriver",
"headerClassifier": "headers",
"sharedLibrary": false,
"skipInvalidPlatforms": true,
"binaryPlatforms": [
"windowsx86-64",
"linuxarm64",
"linuxx86-64",
"linuxathena",
"linuxarm32",
"osxuniversal"
]
}
]
}
@@ -0,0 +1,84 @@
{
"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
@@ -1,71 +0,0 @@
{
"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"
}
]
}