Merge pull request #44 from Team4388/formalise

Formalize errors, update to 2025
This commit is contained in:
C4llSqin
2025-01-04 16:08:04 -07:00
committed by GitHub
41 changed files with 1171 additions and 1304 deletions
+9 -2
View File
@@ -169,6 +169,8 @@ out/
.fleet .fleet
# Simulation GUI and other tools window save file # Simulation GUI and other tools window save file
networktables.json
simgui.json
*-window.json *-window.json
# Simulation data log directory # Simulation data log directory
@@ -176,5 +178,10 @@ logs/
# Folder that has CTRE Phoenix Sim device config storage # Folder that has CTRE Phoenix Sim device config storage
ctre_sim/ ctre_sim/
simgui.json
simgui-ds.json # clangd
/.cache
compile_commands.json
# Eclipse generated file for annotation processors
.factorypath
-3
View File
@@ -1,3 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
-17
View File
@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="temurin-11" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>
-4
View File
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
</project>
Generated
-6
View File
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
-40
View File
@@ -1,40 +0,0 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package frc4388.robot.commands;
import edu.wpi.first.wpilibj2.command.*;
import frc4388.robot.subsystems.*;
import org.junit.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
public class CommandTest {
private CommandScheduler scheduler = null;
@Before
public void setup() {
scheduler = CommandScheduler.getInstance();
}
// TODO: Update this to use an actual command. Won't work with inline commands for some reason
@Test
public void testExample() {
// Arrange
Drive drive = mock(Drive.class);
RunCommand command = new RunCommand(() -> drive.driveWithInput(0, 0), drive);
// Act
scheduler.schedule(command);
scheduler.run();
// Assert
verify(drive).driveWithInput(0, 0);
}
}
-59
View File
@@ -1,59 +0,0 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2018-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package frc4388.robot.subsystems;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import org.junit.*;
import edu.wpi.first.wpilibj.Spark;
import frc4388.robot.Constants.LEDConstants;
import frc4388.utility.LEDPatterns;
/**
* Based off the LEDSubsystemTest class
*/
public class SubsystemTest {
@Test
public void testConstructor() {
// Arrange
Spark ledController = mock(Spark.class);
// Act
LED led = new LED(ledController);
// Assert
assertEquals(LEDConstants.DEFAULT_PATTERN.getValue(), led.getPattern().getValue(), 0.0001);
}
@Test
public void testPatterns() {
// Arrange
Spark ledController = mock(Spark.class);
LED led = new LED(ledController);
// Act
led.setPattern(LEDPatterns.RAINBOW_RAINBOW);
// Assert
assertEquals(LEDPatterns.RAINBOW_RAINBOW.getValue(), led.getPattern().getValue(), 0.0001);
// Act
led.setPattern(LEDPatterns.BLUE_BREATH);
// Assert
assertEquals(LEDPatterns.BLUE_BREATH.getValue(), led.getPattern().getValue(), 0.0001);
// Act
led.setPattern(LEDPatterns.SOLID_BLACK);
// Assert
assertEquals(LEDPatterns.SOLID_BLACK.getValue(), led.getPattern().getValue(), 0.0001);
}
}
-61
View File
@@ -1,61 +0,0 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2018-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package frc4388.utility;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import com.kauailabs.navx.frc.AHRS;
import org.junit.*;
import frc4388.mocks.MockPigeonIMU;
import frc4388.robot.Constants.DriveConstants;
/**
* Based on the RobotGyroUtilityTest class
*/
public class UtilityTest {
private RobotGyro gyroPigeon;
private RobotGyro gyroNavX;
@Test
public void testConstructor() {
// Arrange
MockPigeonIMU pigeon = new MockPigeonIMU(DriveConstants.DRIVE_PIGEON_ID);
AHRS navX = mock(AHRS.class);
gyroPigeon = new RobotGyro(pigeon);
gyroNavX = new RobotGyro(navX);
// Assert
assertEquals(true, gyroPigeon.m_isGyroAPigeon);
assertEquals(pigeon, gyroPigeon.getPigeon());
assertEquals(null, gyroPigeon.getNavX());
assertEquals(false, gyroNavX.m_isGyroAPigeon);
assertEquals(navX, gyroNavX.getNavX());
assertEquals(null, gyroNavX.getPigeon());
}
@Test
public void testHeadingPigeon() {
// Arrange
MockPigeonIMU pigeon = new MockPigeonIMU(DriveConstants.DRIVE_PIGEON_ID);
gyroPigeon = new RobotGyro(pigeon);
// Act & Assert
assertEquals(-90, gyroPigeon.getHeading(270), 0.0001);
assertEquals(-45, gyroPigeon.getHeading(315), 0.0001);
assertEquals(-60, gyroPigeon.getHeading(-60), 0.0001);
assertEquals(30, gyroPigeon.getHeading(30), 0.0001);
assertEquals(0, gyroPigeon.getHeading(0), 0.0001);
assertEquals(180, gyroPigeon.getHeading(180), 0.0001);
assertEquals(-180, gyroPigeon.getHeading(-180), 0.0001);
assertEquals(97, gyroPigeon.getHeading(1537), 0.0001);
assertEquals(99, gyroPigeon.getHeading(-2781), 0.0001);
}
}
+32 -1
View File
@@ -25,5 +25,36 @@
} }
}, },
], ],
"java.test.defaultConfig": "WPIlibUnitTests" "java.test.defaultConfig": "WPIlibUnitTests",
"java.import.gradle.annotationProcessing.enabled": false,
"java.completion.favoriteStaticMembers": [
"org.junit.Assert.*",
"org.junit.Assume.*",
"org.junit.jupiter.api.Assertions.*",
"org.junit.jupiter.api.Assumptions.*",
"org.junit.jupiter.api.DynamicContainer.*",
"org.junit.jupiter.api.DynamicTest.*",
"org.mockito.Mockito.*",
"org.mockito.ArgumentMatchers.*",
"org.mockito.Answers.*",
"edu.wpi.first.units.Units.*"
],
"java.completion.filteredTypes": [
"java.awt.*",
"com.sun.*",
"sun.*",
"jdk.*",
"org.graalvm.*",
"io.micrometer.shaded.*",
"java.beans.*",
"java.util.Base64.*",
"java.util.Timer",
"java.sql.*",
"javax.swing.*",
"javax.management.*",
"javax.smartcardio.*",
"edu.wpi.first.math.proto.*",
"edu.wpi.first.math.**.proto.*",
"edu.wpi.first.math.**.struct.*",
]
} }
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"enableCppIntellisense": false, "enableCppIntellisense": false,
"currentLanguage": "java", "currentLanguage": "java",
"projectYear": "2024", "projectYear": "2025",
"teamNumber": 4388 "teamNumber": 4388
} }
-24
View File
@@ -1,24 +0,0 @@
Copyright (c) 2009-2024 FIRST
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the FIRST nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY FIRST AND CONTRIBUTORS``AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY NONINFRINGEMENT AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FIRST OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 2009-2023 FIRST and other WPILib contributors Copyright (c) 2009-2024 FIRST and other WPILib contributors
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
+10 -7
View File
@@ -1,6 +1,6 @@
plugins { plugins {
id "java" id "java"
id "edu.wpi.first.GradleRIO" version "2024.3.2" id "edu.wpi.first.GradleRIO" version "2025.1.1"
} }
java { java {
@@ -33,6 +33,8 @@ deploy {
frcStaticFileDeploy(getArtifactTypeClass('FileTreeArtifact')) { frcStaticFileDeploy(getArtifactTypeClass('FileTreeArtifact')) {
files = project.fileTree('src/main/deploy') files = project.fileTree('src/main/deploy')
directory = '/home/lvuser/deploy' directory = '/home/lvuser/deploy'
deleteOldFiles = false // Change to true to delete files on roboRIO that no
// longer exist in deploy directory of this project
} }
} }
} }
@@ -50,6 +52,7 @@ def includeDesktopSupport = false
// Defining my dependencies. In this case, WPILib (+ friends), and vendor libraries. // Defining my dependencies. In this case, WPILib (+ friends), and vendor libraries.
// Also defines JUnit 5. // Also defines JUnit 5.
dependencies { dependencies {
annotationProcessor wpi.java.deps.wpilibAnnotations()
implementation wpi.java.deps.wpilib() implementation wpi.java.deps.wpilib()
implementation wpi.java.vendor.java() implementation wpi.java.vendor.java()
@@ -67,14 +70,14 @@ dependencies {
nativeRelease wpi.java.vendor.jniRelease(wpi.platforms.desktop) nativeRelease wpi.java.vendor.jniRelease(wpi.platforms.desktop)
simulationRelease wpi.sim.enableRelease() simulationRelease wpi.sim.enableRelease()
//testImplementation 'org.junit.jupiter:junit-jupiter:5.10.1' testImplementation 'org.junit.jupiter:junit-jupiter:5.10.1'
//testRuntimeOnly 'org.junit.platform:junit-platform-launcher' testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
} }
// test { test {
// useJUnitPlatform() useJUnitPlatform()
// systemProperty 'junit.jupiter.extensions.autodetection.enabled', 'true' systemProperty 'junit.jupiter.extensions.autodetection.enabled', 'true'
//} }
// Simulation configuration (e.g. environment variables). // Simulation configuration (e.g. environment variables).
wpi.sim.addGui().defaultEnabled = true wpi.sim.addGui().defaultEnabled = true
Binary file not shown.
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=permwrapper/dists distributionPath=permwrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
Vendored Regular → Executable
+5 -2
View File
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# #
# SPDX-License-Identifier: Apache-2.0
#
############################################################################## ##############################################################################
# #
@@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.
@@ -84,7 +86,8 @@ done
# shellcheck disable=SC2034 # shellcheck disable=SC2034
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum
Vendored
+12 -10
View File
@@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and @rem See the License for the specific language governing permissions and
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off @if "%DEBUG%"=="" @echo off
@rem ########################################################################## @rem ##########################################################################
@@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute if %ERRORLEVEL% equ 0 goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail
@@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute if exist "%JAVA_EXE%" goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail
+1 -1
View File
@@ -4,7 +4,7 @@ pluginManagement {
repositories { repositories {
mavenLocal() mavenLocal()
gradlePluginPortal() gradlePluginPortal()
String frcYear = '2024' String frcYear = '2025'
File frcHome File frcHome
if (OperatingSystem.current().isWindows()) { if (OperatingSystem.current().isWindows()) {
String publicFolder = System.getenv('PUBLIC') String publicFolder = System.getenv('PUBLIC')
+92
View File
@@ -0,0 +1,92 @@
{
"keyboardJoysticks": [
{
"axisConfig": [
{
"decKey": 65,
"incKey": 68
},
{
"decKey": 87,
"incKey": 83
},
{
"decKey": 69,
"decayRate": 0.0,
"incKey": 82,
"keyRate": 0.009999999776482582
}
],
"axisCount": 3,
"buttonCount": 4,
"buttonKeys": [
90,
88,
67,
86
],
"povConfig": [
{
"key0": 328,
"key135": 323,
"key180": 322,
"key225": 321,
"key270": 324,
"key315": 327,
"key45": 329,
"key90": 326
}
],
"povCount": 1
},
{
"axisConfig": [
{
"decKey": 74,
"incKey": 76
},
{
"decKey": 73,
"incKey": 75
}
],
"axisCount": 2,
"buttonCount": 4,
"buttonKeys": [
77,
44,
46,
47
],
"povCount": 0
},
{
"axisConfig": [
{
"decKey": 263,
"incKey": 262
},
{
"decKey": 265,
"incKey": 264
}
],
"axisCount": 2,
"buttonCount": 6,
"buttonKeys": [
260,
268,
266,
261,
269,
267
],
"povCount": 0
},
{
"axisCount": 0,
"buttonCount": 0,
"povCount": 0
}
]
}
+22 -15
View File
@@ -7,7 +7,11 @@
package frc4388.robot; package frc4388.robot;
import java.util.ArrayList;
import java.util.List;
import edu.wpi.first.math.trajectory.TrapezoidProfile; import edu.wpi.first.math.trajectory.TrapezoidProfile;
import frc4388.utility.CanDevice;
import frc4388.utility.Gains; import frc4388.utility.Gains;
import frc4388.utility.LEDPatterns; import frc4388.utility.LEDPatterns;
@@ -20,6 +24,8 @@ import frc4388.utility.LEDPatterns;
* constants are needed, to reduce verbosity. * constants are needed, to reduce verbosity.
*/ */
public final class Constants { public final class Constants {
public static final String CANBUS_NAME = "rio";
public static final class SwerveDriveConstants { public static final class SwerveDriveConstants {
public static final double MAX_ROT_SPEED = 3.5; public static final double MAX_ROT_SPEED = 3.5;
@@ -29,8 +35,6 @@ public final class Constants {
public static double PLAYBACK_ROTATION_SPEED = AUTO_MAX_ROT_SPEED; public static double PLAYBACK_ROTATION_SPEED = AUTO_MAX_ROT_SPEED;
public static double ROT_CORRECTION_SPEED = 10; // MIN_ROT_SPEED; public static double ROT_CORRECTION_SPEED = 10; // MIN_ROT_SPEED;
public static final String CANBUS_NAME = "IDK";
public static final double CORRECTION_MIN = 10; public static final double CORRECTION_MIN = 10;
public static final double CORRECTION_MAX = 50; public static final double CORRECTION_MAX = 50;
@@ -40,6 +44,8 @@ public final class Constants {
public static final double FAST_SPEED = 0.5; public static final double FAST_SPEED = 0.5;
public static final double TURBO_SPEED = 1.0; public static final double TURBO_SPEED = 1.0;
// public static List<CanDevice> CAN_DEVICES = new ArrayList<>();
public static final class DefaultSwerveRotOffsets { public static final class DefaultSwerveRotOffsets {
public static final double FRONT_LEFT_ROT_OFFSET = 0.0; //TODO: per robot swerve module offsets. public static final double FRONT_LEFT_ROT_OFFSET = 0.0; //TODO: per robot swerve module offsets.
public static final double FRONT_RIGHT_ROT_OFFSET = 0.0; //TODO: per robot swerve module offsets. public static final double FRONT_RIGHT_ROT_OFFSET = 0.0; //TODO: per robot swerve module offsets.
@@ -48,23 +54,24 @@ public final class Constants {
} }
public static final class IDs { public static final class IDs {
public static final int RIGHT_FRONT_WHEEL_ID = 2; public static final CanDevice RIGHT_FRONT_WHEEL = new CanDevice("RIGHT_FRONT_WHEEL", 2);
public static final int RIGHT_FRONT_STEER_ID = 3; public static final CanDevice RIGHT_FRONT_STEER = new CanDevice("RIGHT_FRONT_STEER", 3);
public static final int RIGHT_FRONT_ENCODER_ID = 10; public static final CanDevice RIGHT_FRONT_ENCODER = new CanDevice("RIGHT_FRONT_ENCODER", 10);
public static final int LEFT_FRONT_WHEEL_ID = 4; public static final CanDevice LEFT_FRONT_WHEEL = new CanDevice("LEFT_FRONT_WHEEL", 4);
public static final int LEFT_FRONT_STEER_ID = 5; public static final CanDevice LEFT_FRONT_STEER = new CanDevice("LEFT_FRONT_STEER", 5);
public static final int LEFT_FRONT_ENCODER_ID = 11; public static final CanDevice LEFT_FRONT_ENCODER = new CanDevice("LEFT_FRONT_ENCODER", 11);
public static final int LEFT_BACK_WHEEL_ID = 6; public static final CanDevice LEFT_BACK_WHEEL = new CanDevice("LEFT_BACK_WHEEL", 6);
public static final int LEFT_BACK_STEER_ID = 7; public static final CanDevice LEFT_BACK_STEER = new CanDevice("LEFT_BACK_STEER", 7);
public static final int LEFT_BACK_ENCODER_ID = 12; public static final CanDevice LEFT_BACK_ENCODER = new CanDevice("LEFT_BACK_ENCODER", 12);
public static final int RIGHT_BACK_WHEEL_ID = 8; public static final CanDevice RIGHT_BACK_WHEEL = new CanDevice("RIGHT_BACK_WHEEL", 8);
public static final int RIGHT_BACK_STEER_ID = 9; public static final CanDevice RIGHT_BACK_STEER = new CanDevice("RIGHT_BACK_STEER", 9);
public static final int RIGHT_BACK_ENCODER_ID = 13; public static final CanDevice RIGHT_BACK_ENCODER = new CanDevice("RIGHT_BACK_ENCODER", 13);
public static final int DRIVE_PIGEON_ID = 14; public static final CanDevice DRIVE_PIGEON = new CanDevice("DRIVE_PIGEON", 4);
public static final CanDevice e = new CanDevice("NONEXISTANT_CAN", 50);
} }
public static final class PIDConstants { public static final class PIDConstants {
+101 -4
View File
@@ -7,11 +7,26 @@
package frc4388.robot; package frc4388.robot;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.logging.Level;
import com.ctre.phoenix6.CANBus;
import com.ctre.phoenix6.CANBus.CANBusStatus;
import edu.wpi.first.util.sendable.Sendable;
import edu.wpi.first.wpilibj.TimedRobot; import edu.wpi.first.wpilibj.TimedRobot;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import edu.wpi.first.wpilibj2.command.Command; import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.CommandScheduler; import edu.wpi.first.wpilibj2.command.CommandScheduler;
import frc4388.utility.CanDevice;
import frc4388.utility.DeferredBlock; import frc4388.utility.DeferredBlock;
import frc4388.utility.RobotTime; import frc4388.utility.RobotTime;
import frc4388.utility.Status;
import frc4388.utility.Subsystem;
import frc4388.utility.Status.Report;
import frc4388.utility.Status.ReportLevel;
//import frc4388.robot.subsystems.LED; //import frc4388.robot.subsystems.LED;
/** /**
* The VM is configured to automatically run this class, and to call the * The VM is configured to automatically run this class, and to call the
@@ -36,6 +51,26 @@ public class Robot extends TimedRobot {
// Instantiate our RobotContainer. This will perform all our button bindings, and put our // Instantiate our RobotContainer. This will perform all our button bindings, and put our
// autonomous chooser on the dashboard. // autonomous chooser on the dashboard.
m_robotContainer = new RobotContainer(); m_robotContainer = new RobotContainer();
new Thread() {
public void run() {
try{
while(!this.isInterrupted() && this.isAlive()){
Thread.sleep(500);
for(int i=0;i<Subsystem.subsystems.size(); i++){
Subsystem.subsystems.get(i).queryStatus();
}
System.out.println("Updated statuses!");
}
}catch(Exception e){
e.printStackTrace();
}
}
}.start();
} }
/** /**
@@ -125,10 +160,72 @@ public class Robot extends TimedRobot {
// m_robotContainer.m_robotMap.rightFront.go(m_robotContainer.getDeadbandedDriverController().getLeft()); // m_robotContainer.m_robotMap.rightFront.go(m_robotContainer.getDeadbandedDriverController().getLeft());
} }
/**
* This function is called periodically during test mode.
*/
@Override @Override
public void testPeriodic() { public void testInit() {
List<String> errors = new ArrayList<>();
// Subsystems header
System.out.println(new String(Base64.getDecoder().decode("IOKWl+KWhOKWhOKWluKWl+KWliDilpfilpbilpfiloTiloTilpYgIOKWl+KWhOKWhOKWluKWl+KWliAg4paX4paW4paX4paE4paE4paW4paX4paE4paE4paE4paW4paX4paE4paE4paE4paW4paX4paWICDilpfilpYg4paX4paE4paE4paWCuKWkOKWjCAgIOKWkOKWjCDilpDilozilpDilowg4paQ4paM4paQ4paMICAgIOKWneKWmuKWnuKWmOKWkOKWjCAgICAg4paIICDilpDilowgICDilpDilpvilprilp7ilpzilozilpDilowgICAKIOKWneKWgOKWmuKWluKWkOKWjCDilpDilozilpDilpviloDilprilpYg4pad4paA4paa4paWICDilpDilowgIOKWneKWgOKWmuKWliAg4paIICDilpDilpviloDiloDilpjilpDilowgIOKWkOKWjCDilp3iloDilprilpYK4paX4paE4paE4pae4paY4pad4paa4paE4pae4paY4paQ4paZ4paE4pae4paY4paX4paE4paE4pae4paYICDilpDilowg4paX4paE4paE4pae4paYICDiloggIOKWkOKWmeKWhOKWhOKWluKWkOKWjCAg4paQ4paM4paX4paE4paE4pae4paY")));
for(int i=0;i< Subsystem.subsystems.size();i++){
Subsystem subsystem = Subsystem.subsystems.get(i);
System.out.println("** Subsystem diagnostic report for " + subsystem.getName() + ":");
Status status = subsystem.diagnosticStatus();
for(int a=0;a<status.reports.size();a++){
Report r = status.reports.get(a);
if(r.reportLevel == ReportLevel.ERROR)
errors.add(subsystem.getName() + " - " + r.toString());
subsystem.Log(r.toString());
}
}
// CAN header
System.out.println(new String(Base64.getDecoder().decode("IOKWl+KWhOKWhOKWliDilpfiloTilpYg4paX4paWICDilpfilpYK4paQ4paMICAg4paQ4paMIOKWkOKWjOKWkOKWm+KWmuKWluKWkOKWjArilpDilowgICDilpDilpviloDilpzilozilpDilowg4pad4pac4paMCuKWneKWmuKWhOKWhOKWluKWkOKWjCDilpDilozilpDilowgIOKWkOKWjCh0KQ==")));
CANBus canBus = new CANBus(Constants.CANBUS_NAME);
CANBusStatus canInfo = canBus.getStatus();
System.out.println("CANInfo BusOffCount - " + canInfo.BusOffCount);
System.out.println("CANInfo BusUtilization - " + canInfo.BusUtilization);
System.out.println("CANInfo RX Errors count - " + canInfo.REC);
System.out.println("CANInfo TX Errors count - " + canInfo.TEC);
System.out.println("CANInfo Transmit buffer full count - " + canInfo.TxFullCount);
// Broken turniary operator
ReportLevel canReportLevel = canInfo.Status.isOK() ? (canInfo.Status.isWarning() ? ReportLevel.WARNING : ReportLevel.ERROR) : ReportLevel.INFO;
String canStatus = "CAN " + canReportLevel.name() + " - " + canInfo.Status.getName() + " (" + canInfo.Status.getDescription() + ")";
if(canReportLevel == ReportLevel.ERROR) {
errors.add(canStatus);
}
System.out.println(canStatus);
for(int i=0;i<CanDevice.devices.size();i++){
CanDevice device = CanDevice.devices.get(i);
System.out.println("** CAN diagnostic report for " + device.name + ":");
Status status = device.diagnosticStatus();
for(int a=0;a<status.reports.size();a++){
Report r = status.reports.get(a);
if(r.reportLevel == ReportLevel.ERROR)
errors.add(device.getName() + " - " + r.toString());
device.Log(r.toString());
}
}
// System.out.println("Found CAN devices: " + new DeviceFinder().Find());
if(errors.size() > 0) {
// Errors header
System.out.println(new String(Base64.getDecoder().decode("4paX4paE4paE4paE4paW4paX4paE4paE4paWIOKWl+KWhOKWhOKWliAg4paX4paE4paWIOKWl+KWhOKWhOKWliAg4paX4paE4paE4paWCuKWkOKWjCAgIOKWkOKWjCDilpDilozilpDilowg4paQ4paM4paQ4paMIOKWkOKWjOKWkOKWjCDilpDilozilpDilowgICAK4paQ4pab4paA4paA4paY4paQ4pab4paA4paa4paW4paQ4pab4paA4paa4paW4paQ4paMIOKWkOKWjOKWkOKWm+KWgOKWmuKWliDilp3iloDilprilpYK4paQ4paZ4paE4paE4paW4paQ4paMIOKWkOKWjOKWkOKWjCDilpDilozilp3ilpriloTilp7ilpjilpDilowg4paQ4paM4paX4paE4paE4pae4paY")));
for(int i=0;i<errors.size(); i++){
System.out.println(errors.get(i));
}
}
} }
} }
@@ -9,6 +9,10 @@ package frc4388.robot;
// Drive Systems // Drive Systems
import edu.wpi.first.wpilibj.DriverStation; import edu.wpi.first.wpilibj.DriverStation;
import java.util.ArrayList;
import java.util.List;
import edu.wpi.first.cameraserver.CameraServer; import edu.wpi.first.cameraserver.CameraServer;
import edu.wpi.first.wpilibj.GenericHID; import edu.wpi.first.wpilibj.GenericHID;
import frc4388.utility.controller.XboxController; import frc4388.utility.controller.XboxController;
@@ -33,6 +37,7 @@ import frc4388.robot.subsystems.SwerveDrive;
// Utilites // Utilites
import frc4388.utility.DeferredBlock; import frc4388.utility.DeferredBlock;
import frc4388.utility.Subsystem;
import frc4388.utility.configurable.ConfigurableString; import frc4388.utility.configurable.ConfigurableString;
/** /**
@@ -65,6 +70,8 @@ public class RobotContainer {
private final VirtualController m_virtualDriver = new VirtualController(0); private final VirtualController m_virtualDriver = new VirtualController(0);
private final VirtualController m_virtualOperator = new VirtualController(1); private final VirtualController m_virtualOperator = new VirtualController(1);
// public List<Subsystem> subsystems = new ArrayList<>();
// ! Teleop Commands // ! Teleop Commands
// ! /* Autos */ // ! /* Autos */
@@ -96,6 +103,12 @@ public class RobotContainer {
.withName("SwerveDrive DefaultCommand")); .withName("SwerveDrive DefaultCommand"));
m_robotSwerveDrive.setToSlow(); m_robotSwerveDrive.setToSlow();
// this.subsystems.add(m_robotSwerveDrive);
// this.subsystems.add(m_robotMap.leftFront);
// this.subsystems.add(m_robotMap.rightFront);
// this.subsystems.add(m_robotMap.rightBack);
// this.subsystems.add(m_robotMap.leftBack);
// ! Swerve Drive One Module Test // ! Swerve Drive One Module Test
// m_robotSwerveDrive.setDefaultCommand(new RunCommand(() -> { // m_robotSwerveDrive.setDefaultCommand(new RunCommand(() -> {
// m_robotMap.rightFront.go(getDeadbandedDriverController().getLeft()); // m_robotMap.rightFront.go(getDeadbandedDriverController().getLeft());
+17 -17
View File
@@ -22,7 +22,7 @@ import frc4388.utility.RobotGyro;
* testing and modularization. * testing and modularization.
*/ */
public class RobotMap { public class RobotMap {
private Pigeon2 m_pigeon2 = new Pigeon2(SwerveDriveConstants.IDs.DRIVE_PIGEON_ID); private Pigeon2 m_pigeon2 = new Pigeon2(SwerveDriveConstants.IDs.DRIVE_PIGEON.id);
public RobotGyro gyro = new RobotGyro(m_pigeon2); public RobotGyro gyro = new RobotGyro(m_pigeon2);
public SwerveModule leftFront; public SwerveModule leftFront;
@@ -38,28 +38,28 @@ public class RobotMap {
// public final Spark LEDController = new Spark(LEDConstants.LED_SPARK_ID); // public final Spark LEDController = new Spark(LEDConstants.LED_SPARK_ID);
/* Swreve Drive Subsystem */ /* Swreve Drive Subsystem */
public final TalonFX leftFrontWheel = new TalonFX(SwerveDriveConstants.IDs.LEFT_FRONT_WHEEL_ID); public final TalonFX leftFrontWheel = new TalonFX(SwerveDriveConstants.IDs.LEFT_FRONT_WHEEL.id);
public final TalonFX leftFrontSteer = new TalonFX(SwerveDriveConstants.IDs.LEFT_FRONT_STEER_ID); public final TalonFX leftFrontSteer = new TalonFX(SwerveDriveConstants.IDs.LEFT_FRONT_STEER.id);
public final CANcoder leftFrontEncoder = new CANcoder(SwerveDriveConstants.IDs.LEFT_FRONT_ENCODER_ID); public final CANcoder leftFrontEncoder = new CANcoder(SwerveDriveConstants.IDs.LEFT_FRONT_ENCODER.id);
public final TalonFX rightFrontWheel = new TalonFX(SwerveDriveConstants.IDs.RIGHT_FRONT_WHEEL_ID); public final TalonFX rightFrontWheel = new TalonFX(SwerveDriveConstants.IDs.RIGHT_FRONT_WHEEL.id);
public final TalonFX rightFrontSteer = new TalonFX(SwerveDriveConstants.IDs.RIGHT_FRONT_STEER_ID); public final TalonFX rightFrontSteer = new TalonFX(SwerveDriveConstants.IDs.RIGHT_FRONT_STEER.id);
public final CANcoder rightFrontEncoder = new CANcoder(SwerveDriveConstants.IDs.RIGHT_FRONT_ENCODER_ID); public final CANcoder rightFrontEncoder = new CANcoder(SwerveDriveConstants.IDs.RIGHT_FRONT_ENCODER.id);
public final TalonFX leftBackWheel = new TalonFX(SwerveDriveConstants.IDs.LEFT_BACK_WHEEL_ID); public final TalonFX leftBackWheel = new TalonFX(SwerveDriveConstants.IDs.LEFT_BACK_WHEEL.id);
public final TalonFX leftBackSteer = new TalonFX(SwerveDriveConstants.IDs.LEFT_BACK_STEER_ID); public final TalonFX leftBackSteer = new TalonFX(SwerveDriveConstants.IDs.LEFT_BACK_STEER.id);
public final CANcoder leftBackEncoder = new CANcoder(SwerveDriveConstants.IDs.LEFT_BACK_ENCODER_ID); public final CANcoder leftBackEncoder = new CANcoder(SwerveDriveConstants.IDs.LEFT_BACK_ENCODER.id);
public final TalonFX rightBackWheel = new TalonFX(SwerveDriveConstants.IDs.RIGHT_BACK_WHEEL_ID); public final TalonFX rightBackWheel = new TalonFX(SwerveDriveConstants.IDs.RIGHT_BACK_WHEEL.id);
public final TalonFX rightBackSteer = new TalonFX(SwerveDriveConstants.IDs.RIGHT_BACK_STEER_ID); public final TalonFX rightBackSteer = new TalonFX(SwerveDriveConstants.IDs.RIGHT_BACK_STEER.id);
public final CANcoder rightBackEncoder = new CANcoder(SwerveDriveConstants.IDs.RIGHT_BACK_ENCODER_ID); public final CANcoder rightBackEncoder = new CANcoder(SwerveDriveConstants.IDs.RIGHT_BACK_ENCODER.id);
void configureDriveMotorControllers() { void configureDriveMotorControllers() {
// initialize SwerveModules // initialize SwerveModules
this.rightFront = new SwerveModule(rightFrontWheel, rightFrontSteer, rightFrontEncoder, SwerveDriveConstants.DefaultSwerveRotOffsets.FRONT_RIGHT_ROT_OFFSET); this.rightFront = new SwerveModule("Right Front Swerve Module", rightFrontWheel, rightFrontSteer, rightFrontEncoder, SwerveDriveConstants.DefaultSwerveRotOffsets.FRONT_RIGHT_ROT_OFFSET);
this.leftFront = new SwerveModule(leftFrontWheel, leftFrontSteer, leftFrontEncoder, SwerveDriveConstants.DefaultSwerveRotOffsets.FRONT_LEFT_ROT_OFFSET); this.leftFront = new SwerveModule("Left Front Swerve Module", leftFrontWheel, leftFrontSteer, leftFrontEncoder, SwerveDriveConstants.DefaultSwerveRotOffsets.FRONT_LEFT_ROT_OFFSET);
this.leftBack = new SwerveModule(leftBackWheel, leftBackSteer, leftBackEncoder, SwerveDriveConstants.DefaultSwerveRotOffsets.BACK_LEFT_ROT_OFFSET); this.leftBack = new SwerveModule("Left Back Swerve Module", leftBackWheel, leftBackSteer, leftBackEncoder, SwerveDriveConstants.DefaultSwerveRotOffsets.BACK_LEFT_ROT_OFFSET);
this.rightBack = new SwerveModule(rightBackWheel, rightBackSteer, rightBackEncoder, SwerveDriveConstants.DefaultSwerveRotOffsets.BACK_RIGHT_ROT_OFFSET); this.rightBack = new SwerveModule("Right Back Swerve Module", rightBackWheel, rightBackSteer, rightBackEncoder, SwerveDriveConstants.DefaultSwerveRotOffsets.BACK_RIGHT_ROT_OFFSET);
} }
} }
@@ -1,98 +0,0 @@
package frc4388.robot.commands.Autos;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import edu.wpi.first.wpilibj.shuffleboard.BuiltInWidgets;
import edu.wpi.first.wpilibj.shuffleboard.ComplexWidget;
import edu.wpi.first.wpilibj.shuffleboard.Shuffleboard;
import edu.wpi.first.wpilibj.smartdashboard.SendableChooser;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.InstantCommand;
import frc4388.robot.commands.Swerve.JoystickPlayback;
import frc4388.robot.subsystems.SwerveDrive;
public class PlaybackChooser {
private final ArrayList<SendableChooser<Command>> m_choosers = new ArrayList<>();
private SendableChooser<Command> m_playback = null;
private final ArrayList<ComplexWidget> m_widgets = new ArrayList<>();
private final HashMap<String, Command> m_commandPool = new HashMap<>();
private final File m_dir = new File("/home/lvuser/autos/");
private int m_cmdNum = 0;
private final SwerveDrive m_swerve;
// commands
private Command m_noAuto = new InstantCommand();
public PlaybackChooser(SwerveDrive swerve, Object... pool) {
m_swerve = swerve;
}
public PlaybackChooser addOption(String name, Command option) {
m_commandPool.put(name, option);
return this;
}
public PlaybackChooser buildDisplay() {
for (int i = 0; i < 10; i++) {
appendCommand();
}
m_playback = m_choosers.get(0);
nextChooser();
// ! This does not work, why?
Shuffleboard.getTab("Auto Chooser")
.add("Add Sequence", new InstantCommand(() -> nextChooser()))
.withPosition(4, 0);
return this;
}
// This will be bound to a button for the time being
public void appendCommand() {
var chooser = new SendableChooser<Command>();
chooser.setDefaultOption("No Auto", m_noAuto);
m_choosers.add(chooser);
ComplexWidget widget = Shuffleboard.getTab("Auto Chooser")
.add("Command: " + m_choosers.size(), chooser)
.withSize(4, 1)
.withPosition(0, m_choosers.size() - 1)
.withWidget(BuiltInWidgets.kSplitButtonChooser);
m_widgets.add(widget);
}
public void nextChooser() {
SendableChooser<Command> chooser = m_choosers.get(m_cmdNum++);
String[] dirs = m_dir.list();
if(dirs != null){ // Fix funny error
for (String auto : dirs) {
chooser.addOption(auto, new JoystickPlayback(m_swerve, auto));
}
}
for (var cmd_name : m_commandPool.keySet()) {
chooser.addOption(cmd_name, m_commandPool.get(cmd_name));
}
}
public Command getCommand() {
Command command = m_playback.getSelected();
command = command == null ? m_noAuto : command.asProxy();
Command[] commands = new Command[m_cmdNum - 1];
for (int i = 0; i < m_cmdNum - 1; i++) {
Command command2 = m_choosers.get(i + 1).getSelected();
command2 = command2 == null ? m_noAuto : command2.asProxy();
commands[i] = command2.asProxy();
}
return command.andThen(commands);
}
}
@@ -1,145 +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 frc4388.robot.commands.Swerve;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
import edu.wpi.first.math.geometry.Translation2d;
import edu.wpi.first.wpilibj2.command.Command;
import frc4388.robot.subsystems.SwerveDrive;
import frc4388.utility.UtilityStructs.TimedOutput;
public class JoystickPlayback extends Command {
private final SwerveDrive swerve;
private String filename;
private int mult = 1;
private Scanner input;
private final ArrayList<TimedOutput> outputs = new ArrayList<>();
private int counter = 0;
private long startTime = 0;
private long playbackTime = 0;
private int lastIndex;
private boolean m_finished = false; // ! find a better way
/** Creates a new JoystickPlayback. */
public JoystickPlayback(SwerveDrive swerve, String filename, int mult) {
this.swerve = swerve;
this.filename = filename;
this.mult = mult;
addRequirements(this.swerve);
}
/** Creates a new JoystickPlayback. */
public JoystickPlayback(SwerveDrive swerve, String filename) {
this(swerve, filename, 1);
}
// Called when the command is initially scheduled.
@Override
public void initialize() {
outputs.clear();
m_finished = false;
startTime = System.currentTimeMillis();
playbackTime = 0;
lastIndex = 0;
try {
input = new Scanner(new File("/home/lvuser/autos/" + filename));
String line = "";
while (input.hasNextLine()) {
line = input.nextLine();
if (line.isEmpty() || line.isBlank() || line.equals("\n")) {
continue;
}
String[] values = line.split(",");
System.out.println("values: " + values[0] + " " + values[1] + " " + values[2] + " " + values[3]);
var out = new TimedOutput();
out.leftX = Double.parseDouble(values[0]) * mult;
out.leftY = Double.parseDouble(values[1]);
out.rightX = Double.parseDouble(values[2]);
out.rightY = Double.parseDouble(values[3]);
out.timedOffset = Long.parseLong(values[4]);
outputs.add(out);
}
input.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
// Called every time the scheduler runs while the command is scheduled.
@Override
public void execute() {
if (counter == 0) {
startTime = System.currentTimeMillis();
playbackTime = 0;
} else {
playbackTime = System.currentTimeMillis() - startTime;
}
// skip to reasonable time frame
// too tired to write comment: ask daniel thomas; it goes to the thing until it's bigger than the other thing
{
int i = lastIndex == 0 ? 1 : lastIndex;
while (i < outputs.size() && outputs.get(i).timedOffset < playbackTime) {
i++;
}
if (i >= outputs.size()) {
m_finished = true; // ! kind of a hack
return;
}
lastIndex = i;
}
TimedOutput lastOut = outputs.get(lastIndex - 1);
TimedOutput out = outputs.get(lastIndex);
double deltaTime = out.timedOffset - lastOut.timedOffset;
double playbackDelta = playbackTime - lastOut.timedOffset;
double lerpLX = lastOut.leftX + (out.leftX - lastOut.leftX) * (playbackDelta / deltaTime);
double lerpLY = lastOut.leftY + (out.leftY - lastOut.leftY) * (playbackDelta / deltaTime);
double lerpRX = lastOut.rightX + (out.rightX - lastOut.rightX) * (playbackDelta / deltaTime);
double lerpRY = lastOut.rightY + (out.rightY - lastOut.rightY) * (playbackDelta / deltaTime);
// this.swerve.driveWithInput(new Translation2d(out.leftX, out.leftY),
// new Translation2d(out.rightX, out.rightY),
// true);
// this.swerve.driveWithInput( new Translation2d(lerpLX, lerpLY),
// new Translation2d(lerpRX, lerpRY),
// true);
this.swerve.playbackDriveWithInput( new Translation2d(lerpLX, lerpLY),
new Translation2d(lerpRX, lerpRY),
true);
counter++;
}
// Called once the command ends or is interrupted.
@Override
public void end(boolean interrupted) {
input.close();
swerve.stopModules();
}
// Returns true when the command should end.
@Override
public boolean isFinished() {
return m_finished;
}
}
@@ -1,97 +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 frc4388.robot.commands.Swerve;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.function.Supplier;
import edu.wpi.first.math.geometry.Translation2d;
import edu.wpi.first.wpilibj2.command.Command;
import frc4388.robot.subsystems.SwerveDrive;
import frc4388.utility.UtilityStructs.TimedOutput;
public class JoystickRecorder extends Command {
public final SwerveDrive swerve;
public final Supplier<Double> leftX;
public final Supplier<Double> leftY;
public final Supplier<Double> rightX;
public final Supplier<Double> rightY;
private String filename;
public final ArrayList<TimedOutput> outputs = new ArrayList<>();
private long startTime = -1;
/** Creates a new JoystickRecorder. */
public JoystickRecorder(SwerveDrive swerve, Supplier<Double> leftX, Supplier<Double> leftY,
Supplier<Double> rightX, Supplier<Double> rightY,
String filename)
{
this.swerve = swerve;
this.leftX = leftX;
this.leftY = leftY;
this.rightX = rightX;
this.rightY = rightY;
this.filename = filename;
addRequirements(this.swerve);
}
// Called when the command is initially scheduled.
@Override
public void initialize() {
outputs.clear();
this.startTime = System.currentTimeMillis();
outputs.add(new TimedOutput());
}
// Called every time the scheduler runs while the command is scheduled.
@Override
public void execute() {
var inputs = new TimedOutput();
inputs.leftX = leftX.get();
inputs.leftY = leftY.get();
inputs.rightX = rightX.get();
inputs.rightY = rightY.get();
inputs.timedOffset = System.currentTimeMillis() - startTime;
outputs.add(inputs);
swerve.playbackDriveWithInput(new Translation2d(inputs.leftX, inputs.leftY),
new Translation2d(inputs.rightX, inputs.rightY),
true);
//System.out.println("RECORDING");
}
// Called once the command ends or is interrupted.
@Override
public void end(boolean interrupted) {
File output = new File("/home/lvuser/autos/" + filename);
try (PrintWriter writer = new PrintWriter(output)) {
for (var input : outputs) {
writer.println( input.leftX + "," + input.leftY + "," +
input.rightX + "," + input.rightY + "," +
input.timedOffset);
}
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// Returns true when the command should end.
@Override
public boolean isFinished() {
return false;
}
}
@@ -1,36 +0,0 @@
package frc4388.robot.subsystems;
//import edu.wpi.first.apriltag.AprilTag;
//import edu.wpi.first.math.geometry.Pose3d;
//import edu.wpi.first.math.geometry.Rotation3d;
//import edu.wpi.first.networktables.NetworkTable;
//import edu.wpi.first.networktables.NetworkTableEntry;
import edu.wpi.first.networktables.NetworkTableInstance;
public class Apriltags {
public static class Tag {
public boolean visible = true;
public double x, y, z = 0;
public double ry, rp, rr = 0;
}
public Tag getTagPosRot() {
final var tagTable = NetworkTableInstance.getDefault().getTable("apriltag");
final Tag tag = new Tag();
tag.visible = isAprilTag();
tag.x = tagTable.getEntry("TagPosX").getDouble(0);
tag.y = tagTable.getEntry("TagPosY").getDouble(0);
tag.z = tagTable.getEntry("TagPosZ").getDouble(0);
tag.ry = tagTable.getEntry("TagRotY").getDouble(0);
tag.rp = tagTable.getEntry("TagRotP").getDouble(0);
tag.rr = tagTable.getEntry("TagRotR").getDouble(0);
return tag;
}
public boolean isAprilTag() {
final var tagTable = NetworkTableInstance.getDefault().getTable("apriltag");
return tagTable.getEntry("IsTag").getBoolean(false);
}
}
@@ -7,6 +7,8 @@
package frc4388.robot.subsystems; package frc4388.robot.subsystems;
import java.util.logging.Level;
import com.ctre.phoenix6.controls.Follower; import com.ctre.phoenix6.controls.Follower;
import com.ctre.phoenix6.hardware.TalonFX; import com.ctre.phoenix6.hardware.TalonFX;
@@ -17,11 +19,14 @@ import edu.wpi.first.wpilibj2.command.SubsystemBase;
import frc4388.robot.Constants.DriveConstants; import frc4388.robot.Constants.DriveConstants;
import frc4388.utility.RobotGyro; import frc4388.utility.RobotGyro;
import frc4388.utility.RobotTime; import frc4388.utility.RobotTime;
import frc4388.utility.Status;
import frc4388.utility.Subsystem;
import frc4388.utility.Status.ReportLevel;
/** /**
* Add your docs here. * Add your docs here.
*/ */
public class DiffDrive extends SubsystemBase { public class DiffDrive extends Subsystem {
// Put methods for controlling this subsystem // Put methods for controlling this subsystem
// here. Call these from Commands. // here. Call these from Commands.
@@ -40,6 +45,8 @@ public class DiffDrive extends SubsystemBase {
public DiffDrive(TalonFX leftFrontMotor, TalonFX rightFrontMotor, TalonFX leftBackMotor, public DiffDrive(TalonFX leftFrontMotor, TalonFX rightFrontMotor, TalonFX leftBackMotor,
TalonFX rightBackMotor, DifferentialDrive driveTrain, RobotGyro gyro) { TalonFX rightBackMotor, DifferentialDrive driveTrain, RobotGyro gyro) {
super();
m_leftFrontMotor = leftFrontMotor; m_leftFrontMotor = leftFrontMotor;
m_rightFrontMotor = rightFrontMotor; m_rightFrontMotor = rightFrontMotor;
m_leftBackMotor = leftBackMotor; m_leftBackMotor = leftBackMotor;
@@ -85,4 +92,21 @@ public class DiffDrive extends SubsystemBase {
SmartDashboard.putNumber("Gyro Pitch", m_gyro.getPitch()); SmartDashboard.putNumber("Gyro Pitch", m_gyro.getPitch());
//SmartDashboard.putData(m_gyro); //SmartDashboard.putData(m_gyro);
} }
@Override
public String getSubsystemName() {
return "Diff Drive";
}
@Override
public void queryStatus() {
// TODO: Add Stuff
}
@Override
public Status diagnosticStatus() {
Log("Diagnostic info for this has not been inplemented!"); //TODO
return new Status();
}
} }
@@ -4,6 +4,8 @@
package frc4388.robot.subsystems; package frc4388.robot.subsystems;
import java.util.logging.Level;
import edu.wpi.first.math.geometry.Rotation2d; import edu.wpi.first.math.geometry.Rotation2d;
import edu.wpi.first.math.geometry.Translation2d; import edu.wpi.first.math.geometry.Translation2d;
import edu.wpi.first.math.kinematics.ChassisSpeeds; import edu.wpi.first.math.kinematics.ChassisSpeeds;
@@ -17,8 +19,12 @@ import frc4388.robot.Constants.SwerveDriveConstants;
import frc4388.robot.Constants.SwerveDriveConstants.Conversions; import frc4388.robot.Constants.SwerveDriveConstants.Conversions;
import frc4388.utility.RobotGyro; import frc4388.utility.RobotGyro;
import frc4388.utility.RobotUnits; import frc4388.utility.RobotUnits;
import frc4388.utility.Status;
import frc4388.utility.Subsystem;
import frc4388.utility.Status.Report;
import frc4388.utility.Status.ReportLevel;
public class SwerveDrive extends SubsystemBase { public class SwerveDrive extends Subsystem {
private SwerveModule leftFront; private SwerveModule leftFront;
private SwerveModule rightFront; private SwerveModule rightFront;
@@ -49,6 +55,7 @@ public class SwerveDrive extends SubsystemBase {
/** Creates a new SwerveDrive. */ /** Creates a new SwerveDrive. */
public SwerveDrive(SwerveModule leftFront, SwerveModule rightFront, SwerveModule leftBack, SwerveModule rightBack, RobotGyro gyro) { public SwerveDrive(SwerveModule leftFront, SwerveModule rightFront, SwerveModule leftBack, SwerveModule rightBack, RobotGyro gyro) {
super();
this.leftFront = leftFront; this.leftFront = leftFront;
this.rightFront = rightFront; this.rightFront = rightFront;
this.leftBack = leftBack; this.leftBack = leftBack;
@@ -285,29 +292,23 @@ public class SwerveDrive extends SubsystemBase {
public void setToSlow() { public void setToSlow() {
this.speedAdjust = Conversions.JOYSTICK_TO_METERS_PER_SECOND_FAST * SwerveDriveConstants.SLOW_SPEED; this.speedAdjust = Conversions.JOYSTICK_TO_METERS_PER_SECOND_FAST * SwerveDriveConstants.SLOW_SPEED;
System.out.println("SLOW"); for(int i=0;i<5;i++){
System.out.println("SLOW"); Log("SLOW");
System.out.println("SLOW"); }
System.out.println("SLOW");
System.out.println("SLOW");
} }
public void setToFast() { public void setToFast() {
this.speedAdjust = Conversions.JOYSTICK_TO_METERS_PER_SECOND_FAST * SwerveDriveConstants.FAST_SPEED; this.speedAdjust = Conversions.JOYSTICK_TO_METERS_PER_SECOND_FAST * SwerveDriveConstants.FAST_SPEED;
System.out.println("FAST"); for(int i=0;i<5;i++){
System.out.println("FAST"); Log("FAST");
System.out.println("FAST"); }
System.out.println("FAST");
System.out.println("FAST");
} }
public void setToTurbo() { public void setToTurbo() {
this.speedAdjust = Conversions.JOYSTICK_TO_METERS_PER_SECOND_FAST * SwerveDriveConstants.TURBO_SPEED; this.speedAdjust = Conversions.JOYSTICK_TO_METERS_PER_SECOND_FAST * SwerveDriveConstants.TURBO_SPEED;
System.out.println("TURBO"); for(int i=0;i<5;i++){
System.out.println("TURBO"); Log("TURBO");
System.out.println("TURBO"); }
System.out.println("TURBO");
System.out.println("TURBO");
} }
public void toggleGear(double angle) { public void toggleGear(double angle) {
@@ -328,6 +329,36 @@ public class SwerveDrive extends SubsystemBase {
rotSpeedAdjust = SwerveDriveConstants.MIN_ROT_SPEED; rotSpeedAdjust = SwerveDriveConstants.MIN_ROT_SPEED;
} }
@Override
public String getSubsystemName() {
return "Swerve Drive Controller";
}
@Override
public void queryStatus() {
SmartDashboard.putNumber("[" + getSubsystemName() + "] Gyro angle", this.gyro.getAngle());
SmartDashboard.putNumber("[" + getSubsystemName() + "] Shift State", this.speedAdjust);
// this.leftFront.queryStatus();
// this.leftBack.queryStatus();
// this.rightFront.queryStatus();
// this.rightBack.queryStatus();
//TODO: Add more status things
}
@Override
public Status diagnosticStatus() {
Status status = new Status();
for (SwerveModule module : modules) {
for (Report moduleDignostic : module.diagnosticStatus().reports) {
status.addReport(moduleDignostic.reportLevel, "[" + module.getSubsystemName() + "] " + moduleDignostic.description);
}
}
status.diagnoseHardwareCTRE("Swerve Gyro", gyro.getPigeon());
return status;
}
} }
@@ -4,6 +4,8 @@
package frc4388.robot.subsystems; package frc4388.robot.subsystems;
import java.util.logging.Level;
import com.ctre.phoenix6.StatusSignal; import com.ctre.phoenix6.StatusSignal;
import com.ctre.phoenix6.Utils; import com.ctre.phoenix6.Utils;
import com.ctre.phoenix6.configs.CANcoderConfiguration; import com.ctre.phoenix6.configs.CANcoderConfiguration;
@@ -14,12 +16,14 @@ import com.ctre.phoenix6.configs.MotorOutputConfigs;
import com.ctre.phoenix6.configs.OpenLoopRampsConfigs; import com.ctre.phoenix6.configs.OpenLoopRampsConfigs;
import com.ctre.phoenix6.configs.Slot0Configs; import com.ctre.phoenix6.configs.Slot0Configs;
import com.ctre.phoenix6.configs.TalonFXConfiguration; import com.ctre.phoenix6.configs.TalonFXConfiguration;
import com.ctre.phoenix6.controls.ControlRequest;
import com.ctre.phoenix6.controls.DutyCycleOut; import com.ctre.phoenix6.controls.DutyCycleOut;
import com.ctre.phoenix6.controls.Follower; import com.ctre.phoenix6.controls.Follower;
import com.ctre.phoenix6.controls.PositionVoltage; import com.ctre.phoenix6.controls.PositionVoltage;
import com.ctre.phoenix6.hardware.TalonFX; import com.ctre.phoenix6.hardware.TalonFX;
import com.ctre.phoenix6.signals.FeedbackSensorSourceValue; import com.ctre.phoenix6.signals.FeedbackSensorSourceValue;
import com.ctre.phoenix6.signals.InvertedValue; import com.ctre.phoenix6.signals.InvertedValue;
import com.ctre.phoenix6.signals.MagnetHealthValue;
import com.ctre.phoenix6.signals.NeutralModeValue; import com.ctre.phoenix6.signals.NeutralModeValue;
import com.ctre.phoenix6.signals.SensorDirectionValue; import com.ctre.phoenix6.signals.SensorDirectionValue;
import com.ctre.phoenix6.hardware.CANcoder; import com.ctre.phoenix6.hardware.CANcoder;
@@ -29,12 +33,17 @@ import edu.wpi.first.math.geometry.Rotation2d;
import edu.wpi.first.math.kinematics.SwerveModulePosition; import edu.wpi.first.math.kinematics.SwerveModulePosition;
import edu.wpi.first.math.kinematics.SwerveModuleState; import edu.wpi.first.math.kinematics.SwerveModuleState;
import edu.wpi.first.math.util.Units; import edu.wpi.first.math.util.Units;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
// import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; // import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import edu.wpi.first.wpilibj2.command.SubsystemBase; import edu.wpi.first.wpilibj2.command.SubsystemBase;
import frc4388.robot.Constants.SwerveDriveConstants; import frc4388.robot.Constants.SwerveDriveConstants;
import frc4388.utility.Gains; import frc4388.utility.Gains;
import frc4388.utility.Status;
import frc4388.utility.Subsystem;
import frc4388.utility.Status.ReportLevel;
public class SwerveModule extends SubsystemBase { public class SwerveModule extends Subsystem {
private String name = "Null";
private TalonFX driveMotor; private TalonFX driveMotor;
private TalonFX angleMotor; private TalonFX angleMotor;
private CANcoder encoder; private CANcoder encoder;
@@ -47,7 +56,9 @@ public class SwerveModule extends SubsystemBase {
/** Creates a new SwerveModule. */ /** Creates a new SwerveModule. */
public SwerveModule(TalonFX driveMotor, TalonFX angleMotor, CANcoder encoder, double offset) { public SwerveModule(String name, TalonFX driveMotor, TalonFX angleMotor, CANcoder encoder, double offset) {
super();
this.name = name;
this.driveMotor = driveMotor; this.driveMotor = driveMotor;
this.angleMotor = angleMotor; this.angleMotor = angleMotor;
this.encoder = encoder; this.encoder = encoder;
@@ -150,7 +161,7 @@ public class SwerveModule extends SubsystemBase {
public Rotation2d getAngle() { public Rotation2d getAngle() {
// * Note: This assumes that the CANCoders are setup with the default feedback coefficient and the sensor value reports degrees. // * Note: This assumes that the CANCoders are setup with the default feedback coefficient and the sensor value reports degrees.
// return Rotation2d.fromDegrees(encoder.getAbsolutePosition()); // return Rotation2d.fromDegrees(encoder.getAbsolutePosition());
return Rotation2d.fromRotations(encoder.getPosition().getValue()); return Rotation2d.fromRotations(encoder.getPosition().getValue().baseUnitMagnitude());
} }
public double getAngularVel() { public double getAngularVel() {
@@ -184,7 +195,7 @@ public class SwerveModule extends SubsystemBase {
*/ */
public SwerveModuleState getState() { public SwerveModuleState getState() {
return new SwerveModuleState( return new SwerveModuleState(
Units.inchesToMeters(driveMotor.getVelocity().getValue() * Units.inchesToMeters(driveMotor.getVelocity().getValue().baseUnitMagnitude() *
SwerveDriveConstants.Conversions.INCHES_PER_WHEEL_REV * SwerveDriveConstants.Conversions.INCHES_PER_WHEEL_REV *
SwerveDriveConstants.Conversions.WHEEL_REV_PER_MOTOR_REV), SwerveDriveConstants.Conversions.WHEEL_REV_PER_MOTOR_REV),
getAngle() getAngle()
@@ -208,10 +219,10 @@ public class SwerveModule extends SubsystemBase {
* Set the speed and rotation of the SwerveModule from a SwerveModuleState object * Set the speed and rotation of the SwerveModule from a SwerveModuleState object
* @param desiredState a SwerveModuleState representing the desired new state of the module * @param desiredState a SwerveModuleState representing the desired new state of the module
// */ // */
public void setDesiredState(SwerveModuleState desiredState) { public void setDesiredState(SwerveModuleState state) {
Rotation2d currentRotation = this.getAngle(); Rotation2d currentRotation = this.getAngle();
SwerveModuleState state = SwerveModuleState.optimize(desiredState, currentRotation); state.optimize(currentRotation);//SwerveModuleState.optimize(desiredState, currentRotation);
// calculate the difference between our current rotational position and our new rotational position // calculate the difference between our current rotational position and our new rotational position
Rotation2d rotationDelta = state.angle.minus(currentRotation); Rotation2d rotationDelta = state.angle.minus(currentRotation);
@@ -227,6 +238,33 @@ public class SwerveModule extends SubsystemBase {
// encoder.setPosition(0); // encoder.setPosition(0);
} }
@Override
public String getSubsystemName() {
return this.name;
}
@Override
public void queryStatus() {
SmartDashboard.putNumber("[" + getSubsystemName() + "] Drive motor speed", this.driveMotor.get());
SmartDashboard.putNumber("[" + getSubsystemName() + "] Angle motor angle", this.angleMotor.getRotorPosition().getValueAsDouble());
//TODO: Add more status things
}
public boolean motorsAlive() {
return this.driveMotor.isAlive() && this.angleMotor.isAlive();
}
@Override
public Status diagnosticStatus() {
Status status = new Status();
status.diagnoseHardwareCTRE("Drive", this.driveMotor);
status.diagnoseHardwareCTRE("Angle", this.angleMotor);
status.diagnoseHardwareCTRE("Steer", this.encoder);
return status;
}
// public double getCurrent() { // public double getCurrent() {
// return angleMotor.getSupplyCurrent() + driveMotor.getSupplyCurrent(); // return angleMotor.getSupplyCurrent() + driveMotor.getSupplyCurrent();
// } // }
@@ -1,38 +0,0 @@
package frc4388.robot.subsystems;
import edu.wpi.first.apriltag.AprilTag;
import edu.wpi.first.math.geometry.Pose3d;
import edu.wpi.first.math.geometry.Rotation3d;
import edu.wpi.first.networktables.NetworkTableEntry;
import edu.wpi.first.networktables.NetworkTableInstance;
public class Vision {
private final NetworkTableEntry m_isTags;
private final NetworkTableEntry m_xPoses;
private final NetworkTableEntry m_yPoses;
private final NetworkTableEntry m_zPoses;
public Vision() {
final var tagTable = NetworkTableInstance.getDefault().getTable("apriltag");
m_isTags = tagTable.getEntry("IsTag");
m_xPoses = tagTable.getEntry("TagPosX");
m_yPoses = tagTable.getEntry("TagPosY");
m_zPoses = tagTable.getEntry("TagPosZ");
}
public AprilTag[] getAprilTags() {
if (!m_isTags.getBoolean(false)) return new AprilTag[0];
double xarr[] = m_xPoses.getDoubleArray(new double[] {});
double yarr[] = m_yPoses.getDoubleArray(new double[] {});
double zarr[] = m_zPoses.getDoubleArray(new double[] {});
AprilTag tags[] = new AprilTag[xarr.length];
for (int i = 0; i < tags.length; i++) {
tags[i] = new AprilTag(0, new Pose3d(xarr[i], yarr[i], zarr[i], new Rotation3d()));
}
return tags;
}
}
@@ -0,0 +1,57 @@
package frc4388.utility;
import java.util.ArrayList;
import java.util.List;
import edu.wpi.first.hal.CANData;
import edu.wpi.first.hal.can.CANJNI;
import edu.wpi.first.wpilibj.CAN;
import frc4388.utility.Status.Report;
import frc4388.utility.Status.ReportLevel;
public class CanDevice {
public static List<CanDevice> devices = new ArrayList<>();
public String name;
public int id;
public CanDevice(String name, int id) {
this.name = name;
this.id = id;
devices.add(this);
}
private boolean isAlive() {
return true; //TODO: Link this with Device Finder
}
public String getName() {
return "CAN ID " + this.id + " ( " + this.name + " ) ";
}
public void Log(String str){
System.out.println(getName() + " - " + str);
}
public Status queryStatus() {
Status s = new Status();
s.addReport(ReportLevel.INFO, "TODO");
return s;
}
public Status diagnosticStatus() {
Status s = new Status();
//TODO
s.addReport(ReportLevel.INFO, "Add CAN magic here");
boolean isAlive = isAlive();
s.addReport(isAlive ? ReportLevel.INFO : ReportLevel.ERROR, "Is Alive: " + isAlive);
return s;
}
}
+1 -1
View File
@@ -181,7 +181,7 @@ public class RobotGyro {
* Roll is within [-90,+90] degrees. * Roll is within [-90,+90] degrees.
*/ */
private double[] getPigeonAngles() { private double[] getPigeonAngles() {
m_pigeon.getAngle(); //m_pigeon.getAngle(); // This appeared to not do anything?
var rotation = m_pigeon.getRotation3d(); var rotation = m_pigeon.getRotation3d();
return new double[] {RobotUnits.radiansToDegrees(rotation.getX() - rollZero), RobotUnits.radiansToDegrees(rotation.getY() - pitchZero), RobotUnits.radiansToDegrees(rotation.getZ())}; return new double[] {RobotUnits.radiansToDegrees(rotation.getX() - rollZero), RobotUnits.radiansToDegrees(rotation.getY() - pitchZero), RobotUnits.radiansToDegrees(rotation.getZ())};
+81
View File
@@ -0,0 +1,81 @@
package frc4388.utility;
import java.util.ArrayList;
import java.util.List;
import com.ctre.phoenix6.StatusCode;
import com.ctre.phoenix6.controls.EmptyControl;
import com.ctre.phoenix6.hardware.CANcoder;
import com.ctre.phoenix6.hardware.Pigeon2;
import com.ctre.phoenix6.hardware.TalonFX;
public class Status {
public enum ReportLevel {
INFO,
WARNING,
ERROR
}
public class Report {
public ReportLevel reportLevel;
public String description;
@Override
public String toString() {
return this.reportLevel.name() + ": " + this.description;
}
}
public List<Report> reports;
public Status() {
this.reports = new ArrayList<>();
}
public void addReport(ReportLevel level, String description) {
Report r = new Report();
r.reportLevel = level;
r.description = description;
this.reports.add(r);
}
private String printStatusCode(StatusCode status){
return status.getName() + " (" + status.value + ")";
}
public void diagnoseHardwareCTRE(String deviceName, TalonFX motor) {
if (motor.isAlive()) addReport(ReportLevel.INFO, deviceName + " Motor (TalonFX) Alive?: Alive.");
else addReport(ReportLevel.ERROR, deviceName + " Motor (TalonFX) Alive?: Dead!");
}
public void diagnoseHardwareCTRE(String deviceName, CANcoder coder) {
// Because the Cancoder has no method to check its alive, we send it a empty control which it should return a zero when it gets the control.
// If its not zero, that means that most likely that it had some communication error, I.e. It actually is powered off or not connected at all.
// TODO: validate that a CANCoder can actually do `EmptyControl`s
StatusCode status = coder.setControl(new EmptyControl());
if (status.value == 0) addReport(ReportLevel.INFO, deviceName + " Cancoder Alive?: Alive. " + printStatusCode(status));
else addReport(ReportLevel.ERROR, deviceName + " Cancoder Alive?: Dead! " + printStatusCode(status));
// StatusSignal<MagnetHealthValue> -> MagnetHealthValue -> int
int coderMagHealth = coder.getMagnetHealth().getValue().value;
if (coderMagHealth == 3) addReport(ReportLevel.INFO, deviceName + " Cancoder Magnet Strength?: Ideal."); // why is 3 the 'good value'?
if (coderMagHealth == 2) addReport(ReportLevel.WARNING, deviceName + " Cancoder Magnet Strength?: Subpar.");
if (coderMagHealth == 1) addReport(ReportLevel.ERROR, deviceName + " Cancoder Magnet Strength?: Too Close or Far!");
if (coderMagHealth == 0) addReport(ReportLevel.ERROR, deviceName + " Cancoder Magnet Strength?: Unkown!");
}
public void diagnoseHardwareCTRE(String deviceName, Pigeon2 pigeon) {
// Because the Pigeon has no method to check its alive, we send it a empty control which it should return a zero when it gets the control.
// If its not zero, that means that most likely that it had some communication error, I.e. It actually is powered off or not connected at all.
// TODO: validate that a Pigeon2 can actually do `EmptyControl`s
StatusCode status = pigeon.setControl(new EmptyControl());
if (status.value == 0) addReport(ReportLevel.INFO, deviceName + " Pigeon2 Alive?: Alive. " + printStatusCode(status));
else addReport(ReportLevel.ERROR, deviceName + " Pigeon2 Alive?: Dead! " + printStatusCode(status));
}
public boolean hasReport() {
return reports.size() == 0;
}
}
@@ -0,0 +1,25 @@
package frc4388.utility;
import java.util.ArrayList;
import java.util.List;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
public abstract class Subsystem extends SubsystemBase {
public static List<Subsystem> subsystems = new ArrayList<>();
public Subsystem(){
subsystems.add(this);
}
public void Log(String str) {
System.out.println(getSubsystemName() + " - " + str);
}
// Get name of subsystem, for use in log.
public abstract String getSubsystemName();
// Get what the subystem is currently doing, such as "Shooter spun up". This should post to SmartDashboard
public abstract void queryStatus();
// Proactivly search for any errors in each subsystem
public abstract Status diagnosticStatus();
}
-31
View File
@@ -1,31 +0,0 @@
/**
* This file is a configuration file generated by the `Template` extension on `vscode`
* @see https://marketplace.visualstudio.com/items?itemName=yongwoo.template
*/
module.exports = {
// You can change the template path to another path
templateRootPath: "./.templates",
// After copying the template file the `replaceFileTextFn` function is executed
replaceFileTextFn: (fileText, templateName, utils) => {
// @see https://www.npmjs.com/package/change-case
const { changeCase } = utils;
// You can change the text in the file
return fileText
.replace(/__templateName__/gm, templateName)
.replace(
/__templateNameToPascalCase__/gm,
changeCase.pascalCase(templateName)
)
.replace(
/__templateNameToParamCase__/gm,
changeCase.paramCase(templateName)
);
},
replaceFileNameFn: (fileName, templateName, utils) => {
const { path } = utils;
// @see https://nodejs.org/api/path.html#path_path_parse_path
const { base } = path.parse(fileName);
// You can change the file name
return base;
}
};
+1 -1
View File
@@ -3,7 +3,7 @@
"name": "NavX", "name": "NavX",
"version": "2024.1.0", "version": "2024.1.0",
"uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b",
"frcYear": "2024", "frcYear": "2025",
"mavenUrls": [ "mavenUrls": [
"https://dev.studica.com/maven/release/2024/" "https://dev.studica.com/maven/release/2024/"
], ],
@@ -1,50 +1,80 @@
{ {
"fileName": "Phoenix6.json", "fileName": "Phoenix6-25.1.0.json",
"name": "CTRE-Phoenix (v6)", "name": "CTRE-Phoenix (v6)",
"version": "24.3.0", "version": "25.1.0",
"frcYear": 2024, "frcYear": "2025",
"uuid": "e995de00-2c64-4df5-8831-c1441420ff19", "uuid": "e995de00-2c64-4df5-8831-c1441420ff19",
"mavenUrls": [ "mavenUrls": [
"https://maven.ctr-electronics.com/release/" "https://maven.ctr-electronics.com/release/"
], ],
"jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2024-latest.json", "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-latest.json",
"conflictsWith": [ "conflictsWith": [
{ {
"uuid": "3fcf3402-e646-4fa6-971e-18afe8173b1a", "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af",
"errorMessage": "The combined Phoenix-6-And-5 vendordep is no longer supported. Please remove the vendordep and instead add both the latest Phoenix 6 vendordep and Phoenix 5 vendordep.", "errorMessage": "Users can not have both the replay and regular Phoenix 6 vendordeps in their robot program.",
"offlineFileName": "Phoenix6And5.json" "offlineFileName": "Phoenix6-replay-frc2025-latest.json"
} }
], ],
"javaDependencies": [ "javaDependencies": [
{ {
"groupId": "com.ctre.phoenix6", "groupId": "com.ctre.phoenix6",
"artifactId": "wpiapi-java", "artifactId": "wpiapi-java",
"version": "24.3.0" "version": "25.1.0"
} }
], ],
"jniDependencies": [ "jniDependencies": [
{ {
"groupId": "com.ctre.phoenix6", "groupId": "com.ctre.phoenix6",
"artifactId": "tools", "artifactId": "api-cpp",
"version": "24.3.0", "version": "25.1.0",
"isJar": false, "isJar": false,
"skipInvalidPlatforms": true, "skipInvalidPlatforms": true,
"validPlatforms": [ "validPlatforms": [
"windowsx86-64", "windowsx86-64",
"linuxx86-64", "linuxx86-64",
"linuxarm64",
"linuxathena"
],
"simMode": "hwsim"
},
{
"groupId": "com.ctre.phoenix6",
"artifactId": "tools",
"version": "25.1.0",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
"windowsx86-64",
"linuxx86-64",
"linuxarm64",
"linuxathena" "linuxathena"
], ],
"simMode": "hwsim" "simMode": "hwsim"
}, },
{ {
"groupId": "com.ctre.phoenix6.sim", "groupId": "com.ctre.phoenix6.sim",
"artifactId": "tools-sim", "artifactId": "api-cpp-sim",
"version": "24.3.0", "version": "25.1.0",
"isJar": false, "isJar": false,
"skipInvalidPlatforms": true, "skipInvalidPlatforms": true,
"validPlatforms": [ "validPlatforms": [
"windowsx86-64", "windowsx86-64",
"linuxx86-64", "linuxx86-64",
"linuxarm64",
"osxuniversal"
],
"simMode": "swsim"
},
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "tools-sim",
"version": "25.1.0",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
"windowsx86-64",
"linuxx86-64",
"linuxarm64",
"osxuniversal" "osxuniversal"
], ],
"simMode": "swsim" "simMode": "swsim"
@@ -52,25 +82,13 @@
{ {
"groupId": "com.ctre.phoenix6.sim", "groupId": "com.ctre.phoenix6.sim",
"artifactId": "simTalonSRX", "artifactId": "simTalonSRX",
"version": "24.3.0", "version": "25.1.0",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
"windowsx86-64",
"linuxx86-64",
"osxuniversal"
],
"simMode": "swsim"
},
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simTalonFX",
"version": "24.3.0",
"isJar": false, "isJar": false,
"skipInvalidPlatforms": true, "skipInvalidPlatforms": true,
"validPlatforms": [ "validPlatforms": [
"windowsx86-64", "windowsx86-64",
"linuxx86-64", "linuxx86-64",
"linuxarm64",
"osxuniversal" "osxuniversal"
], ],
"simMode": "swsim" "simMode": "swsim"
@@ -78,12 +96,13 @@
{ {
"groupId": "com.ctre.phoenix6.sim", "groupId": "com.ctre.phoenix6.sim",
"artifactId": "simVictorSPX", "artifactId": "simVictorSPX",
"version": "24.3.0", "version": "25.1.0",
"isJar": false, "isJar": false,
"skipInvalidPlatforms": true, "skipInvalidPlatforms": true,
"validPlatforms": [ "validPlatforms": [
"windowsx86-64", "windowsx86-64",
"linuxx86-64", "linuxx86-64",
"linuxarm64",
"osxuniversal" "osxuniversal"
], ],
"simMode": "swsim" "simMode": "swsim"
@@ -91,12 +110,13 @@
{ {
"groupId": "com.ctre.phoenix6.sim", "groupId": "com.ctre.phoenix6.sim",
"artifactId": "simPigeonIMU", "artifactId": "simPigeonIMU",
"version": "24.3.0", "version": "25.1.0",
"isJar": false, "isJar": false,
"skipInvalidPlatforms": true, "skipInvalidPlatforms": true,
"validPlatforms": [ "validPlatforms": [
"windowsx86-64", "windowsx86-64",
"linuxx86-64", "linuxx86-64",
"linuxarm64",
"osxuniversal" "osxuniversal"
], ],
"simMode": "swsim" "simMode": "swsim"
@@ -104,12 +124,13 @@
{ {
"groupId": "com.ctre.phoenix6.sim", "groupId": "com.ctre.phoenix6.sim",
"artifactId": "simCANCoder", "artifactId": "simCANCoder",
"version": "24.3.0", "version": "25.1.0",
"isJar": false, "isJar": false,
"skipInvalidPlatforms": true, "skipInvalidPlatforms": true,
"validPlatforms": [ "validPlatforms": [
"windowsx86-64", "windowsx86-64",
"linuxx86-64", "linuxx86-64",
"linuxarm64",
"osxuniversal" "osxuniversal"
], ],
"simMode": "swsim" "simMode": "swsim"
@@ -117,12 +138,13 @@
{ {
"groupId": "com.ctre.phoenix6.sim", "groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProTalonFX", "artifactId": "simProTalonFX",
"version": "24.3.0", "version": "25.1.0",
"isJar": false, "isJar": false,
"skipInvalidPlatforms": true, "skipInvalidPlatforms": true,
"validPlatforms": [ "validPlatforms": [
"windowsx86-64", "windowsx86-64",
"linuxx86-64", "linuxx86-64",
"linuxarm64",
"osxuniversal" "osxuniversal"
], ],
"simMode": "swsim" "simMode": "swsim"
@@ -130,12 +152,13 @@
{ {
"groupId": "com.ctre.phoenix6.sim", "groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProCANcoder", "artifactId": "simProCANcoder",
"version": "24.3.0", "version": "25.1.0",
"isJar": false, "isJar": false,
"skipInvalidPlatforms": true, "skipInvalidPlatforms": true,
"validPlatforms": [ "validPlatforms": [
"windowsx86-64", "windowsx86-64",
"linuxx86-64", "linuxx86-64",
"linuxarm64",
"osxuniversal" "osxuniversal"
], ],
"simMode": "swsim" "simMode": "swsim"
@@ -143,12 +166,27 @@
{ {
"groupId": "com.ctre.phoenix6.sim", "groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProPigeon2", "artifactId": "simProPigeon2",
"version": "24.3.0", "version": "25.1.0",
"isJar": false, "isJar": false,
"skipInvalidPlatforms": true, "skipInvalidPlatforms": true,
"validPlatforms": [ "validPlatforms": [
"windowsx86-64", "windowsx86-64",
"linuxx86-64", "linuxx86-64",
"linuxarm64",
"osxuniversal"
],
"simMode": "swsim"
},
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProCANrange",
"version": "25.1.0",
"isJar": false,
"skipInvalidPlatforms": true,
"validPlatforms": [
"windowsx86-64",
"linuxx86-64",
"linuxarm64",
"osxuniversal" "osxuniversal"
], ],
"simMode": "swsim" "simMode": "swsim"
@@ -158,7 +196,7 @@
{ {
"groupId": "com.ctre.phoenix6", "groupId": "com.ctre.phoenix6",
"artifactId": "wpiapi-cpp", "artifactId": "wpiapi-cpp",
"version": "24.3.0", "version": "25.1.0",
"libName": "CTRE_Phoenix6_WPI", "libName": "CTRE_Phoenix6_WPI",
"headerClassifier": "headers", "headerClassifier": "headers",
"sharedLibrary": true, "sharedLibrary": true,
@@ -166,6 +204,7 @@
"binaryPlatforms": [ "binaryPlatforms": [
"windowsx86-64", "windowsx86-64",
"linuxx86-64", "linuxx86-64",
"linuxarm64",
"linuxathena" "linuxathena"
], ],
"simMode": "hwsim" "simMode": "hwsim"
@@ -173,7 +212,7 @@
{ {
"groupId": "com.ctre.phoenix6", "groupId": "com.ctre.phoenix6",
"artifactId": "tools", "artifactId": "tools",
"version": "24.3.0", "version": "25.1.0",
"libName": "CTRE_PhoenixTools", "libName": "CTRE_PhoenixTools",
"headerClassifier": "headers", "headerClassifier": "headers",
"sharedLibrary": true, "sharedLibrary": true,
@@ -181,6 +220,7 @@
"binaryPlatforms": [ "binaryPlatforms": [
"windowsx86-64", "windowsx86-64",
"linuxx86-64", "linuxx86-64",
"linuxarm64",
"linuxathena" "linuxathena"
], ],
"simMode": "hwsim" "simMode": "hwsim"
@@ -188,7 +228,7 @@
{ {
"groupId": "com.ctre.phoenix6.sim", "groupId": "com.ctre.phoenix6.sim",
"artifactId": "wpiapi-cpp-sim", "artifactId": "wpiapi-cpp-sim",
"version": "24.3.0", "version": "25.1.0",
"libName": "CTRE_Phoenix6_WPISim", "libName": "CTRE_Phoenix6_WPISim",
"headerClassifier": "headers", "headerClassifier": "headers",
"sharedLibrary": true, "sharedLibrary": true,
@@ -196,6 +236,7 @@
"binaryPlatforms": [ "binaryPlatforms": [
"windowsx86-64", "windowsx86-64",
"linuxx86-64", "linuxx86-64",
"linuxarm64",
"osxuniversal" "osxuniversal"
], ],
"simMode": "swsim" "simMode": "swsim"
@@ -203,7 +244,7 @@
{ {
"groupId": "com.ctre.phoenix6.sim", "groupId": "com.ctre.phoenix6.sim",
"artifactId": "tools-sim", "artifactId": "tools-sim",
"version": "24.3.0", "version": "25.1.0",
"libName": "CTRE_PhoenixTools_Sim", "libName": "CTRE_PhoenixTools_Sim",
"headerClassifier": "headers", "headerClassifier": "headers",
"sharedLibrary": true, "sharedLibrary": true,
@@ -211,6 +252,7 @@
"binaryPlatforms": [ "binaryPlatforms": [
"windowsx86-64", "windowsx86-64",
"linuxx86-64", "linuxx86-64",
"linuxarm64",
"osxuniversal" "osxuniversal"
], ],
"simMode": "swsim" "simMode": "swsim"
@@ -218,7 +260,7 @@
{ {
"groupId": "com.ctre.phoenix6.sim", "groupId": "com.ctre.phoenix6.sim",
"artifactId": "simTalonSRX", "artifactId": "simTalonSRX",
"version": "24.3.0", "version": "25.1.0",
"libName": "CTRE_SimTalonSRX", "libName": "CTRE_SimTalonSRX",
"headerClassifier": "headers", "headerClassifier": "headers",
"sharedLibrary": true, "sharedLibrary": true,
@@ -226,21 +268,7 @@
"binaryPlatforms": [ "binaryPlatforms": [
"windowsx86-64", "windowsx86-64",
"linuxx86-64", "linuxx86-64",
"osxuniversal" "linuxarm64",
],
"simMode": "swsim"
},
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simTalonFX",
"version": "24.3.0",
"libName": "CTRE_SimTalonFX",
"headerClassifier": "headers",
"sharedLibrary": true,
"skipInvalidPlatforms": true,
"binaryPlatforms": [
"windowsx86-64",
"linuxx86-64",
"osxuniversal" "osxuniversal"
], ],
"simMode": "swsim" "simMode": "swsim"
@@ -248,7 +276,7 @@
{ {
"groupId": "com.ctre.phoenix6.sim", "groupId": "com.ctre.phoenix6.sim",
"artifactId": "simVictorSPX", "artifactId": "simVictorSPX",
"version": "24.3.0", "version": "25.1.0",
"libName": "CTRE_SimVictorSPX", "libName": "CTRE_SimVictorSPX",
"headerClassifier": "headers", "headerClassifier": "headers",
"sharedLibrary": true, "sharedLibrary": true,
@@ -256,6 +284,7 @@
"binaryPlatforms": [ "binaryPlatforms": [
"windowsx86-64", "windowsx86-64",
"linuxx86-64", "linuxx86-64",
"linuxarm64",
"osxuniversal" "osxuniversal"
], ],
"simMode": "swsim" "simMode": "swsim"
@@ -263,7 +292,7 @@
{ {
"groupId": "com.ctre.phoenix6.sim", "groupId": "com.ctre.phoenix6.sim",
"artifactId": "simPigeonIMU", "artifactId": "simPigeonIMU",
"version": "24.3.0", "version": "25.1.0",
"libName": "CTRE_SimPigeonIMU", "libName": "CTRE_SimPigeonIMU",
"headerClassifier": "headers", "headerClassifier": "headers",
"sharedLibrary": true, "sharedLibrary": true,
@@ -271,6 +300,7 @@
"binaryPlatforms": [ "binaryPlatforms": [
"windowsx86-64", "windowsx86-64",
"linuxx86-64", "linuxx86-64",
"linuxarm64",
"osxuniversal" "osxuniversal"
], ],
"simMode": "swsim" "simMode": "swsim"
@@ -278,7 +308,7 @@
{ {
"groupId": "com.ctre.phoenix6.sim", "groupId": "com.ctre.phoenix6.sim",
"artifactId": "simCANCoder", "artifactId": "simCANCoder",
"version": "24.3.0", "version": "25.1.0",
"libName": "CTRE_SimCANCoder", "libName": "CTRE_SimCANCoder",
"headerClassifier": "headers", "headerClassifier": "headers",
"sharedLibrary": true, "sharedLibrary": true,
@@ -286,6 +316,7 @@
"binaryPlatforms": [ "binaryPlatforms": [
"windowsx86-64", "windowsx86-64",
"linuxx86-64", "linuxx86-64",
"linuxarm64",
"osxuniversal" "osxuniversal"
], ],
"simMode": "swsim" "simMode": "swsim"
@@ -293,7 +324,7 @@
{ {
"groupId": "com.ctre.phoenix6.sim", "groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProTalonFX", "artifactId": "simProTalonFX",
"version": "24.3.0", "version": "25.1.0",
"libName": "CTRE_SimProTalonFX", "libName": "CTRE_SimProTalonFX",
"headerClassifier": "headers", "headerClassifier": "headers",
"sharedLibrary": true, "sharedLibrary": true,
@@ -301,6 +332,7 @@
"binaryPlatforms": [ "binaryPlatforms": [
"windowsx86-64", "windowsx86-64",
"linuxx86-64", "linuxx86-64",
"linuxarm64",
"osxuniversal" "osxuniversal"
], ],
"simMode": "swsim" "simMode": "swsim"
@@ -308,7 +340,7 @@
{ {
"groupId": "com.ctre.phoenix6.sim", "groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProCANcoder", "artifactId": "simProCANcoder",
"version": "24.3.0", "version": "25.1.0",
"libName": "CTRE_SimProCANcoder", "libName": "CTRE_SimProCANcoder",
"headerClassifier": "headers", "headerClassifier": "headers",
"sharedLibrary": true, "sharedLibrary": true,
@@ -316,6 +348,7 @@
"binaryPlatforms": [ "binaryPlatforms": [
"windowsx86-64", "windowsx86-64",
"linuxx86-64", "linuxx86-64",
"linuxarm64",
"osxuniversal" "osxuniversal"
], ],
"simMode": "swsim" "simMode": "swsim"
@@ -323,7 +356,7 @@
{ {
"groupId": "com.ctre.phoenix6.sim", "groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProPigeon2", "artifactId": "simProPigeon2",
"version": "24.3.0", "version": "25.1.0",
"libName": "CTRE_SimProPigeon2", "libName": "CTRE_SimProPigeon2",
"headerClassifier": "headers", "headerClassifier": "headers",
"sharedLibrary": true, "sharedLibrary": true,
@@ -331,6 +364,23 @@
"binaryPlatforms": [ "binaryPlatforms": [
"windowsx86-64", "windowsx86-64",
"linuxx86-64", "linuxx86-64",
"linuxarm64",
"osxuniversal"
],
"simMode": "swsim"
},
{
"groupId": "com.ctre.phoenix6.sim",
"artifactId": "simProCANrange",
"version": "25.1.0",
"libName": "CTRE_SimProCANrange",
"headerClassifier": "headers",
"sharedLibrary": true,
"skipInvalidPlatforms": true,
"binaryPlatforms": [
"windowsx86-64",
"linuxx86-64",
"linuxarm64",
"osxuniversal" "osxuniversal"
], ],
"simMode": "swsim" "simMode": "swsim"
+1 -1
View File
@@ -3,7 +3,7 @@
"name": "WPILib-New-Commands", "name": "WPILib-New-Commands",
"version": "1.0.0", "version": "1.0.0",
"uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266", "uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266",
"frcYear": "2024", "frcYear": "2025",
"mavenUrls": [], "mavenUrls": [],
"jsonUrl": "", "jsonUrl": "",
"javaDependencies": [ "javaDependencies": [
-35
View File
@@ -1,35 +0,0 @@
{
"fileName": "navx_frc.json",
"name": "KauaiLabs_navX_FRC",
"version": "3.1.413",
"uuid": "cb311d09-36e9-4143-a032-55bb2b94443b",
"mavenUrls": [
"https://repo1.maven.org/maven2/"
],
"jsonUrl": "https://www.kauailabs.com/dist/frc/2020/navx_frc.json",
"javaDependencies": [
{
"groupId": "com.kauailabs.navx.frc",
"artifactId": "navx-java",
"version": "3.1.413"
}
],
"jniDependencies": [],
"cppDependencies": [
{
"groupId": "com.kauailabs.navx.frc",
"artifactId": "navx-cpp",
"version": "3.1.413",
"headerClassifier": "headers",
"sourcesClassifier": "sources",
"sharedLibrary": false,
"libName": "navx_frc",
"skipInvalidPlatforms": true,
"binaryPlatforms": [
"linuxathena",
"linuxraspbian",
"windowsx86-64"
]
}
]
}