mirror of
https://github.com/Team4388/2025RidgeScape.git
synced 2026-06-09 00:38:02 -06:00
Slightly overhaul status system
This commit is contained in:
@@ -7,10 +7,6 @@
|
|||||||
|
|
||||||
package frc4388.robot;
|
package frc4388.robot;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
// Advantagekit
|
// Advantagekit
|
||||||
import org.littletonrobotics.junction.LogFileUtil;
|
import org.littletonrobotics.junction.LogFileUtil;
|
||||||
import org.littletonrobotics.junction.LoggedRobot;
|
import org.littletonrobotics.junction.LoggedRobot;
|
||||||
@@ -19,23 +15,16 @@ import org.littletonrobotics.junction.networktables.NT4Publisher;
|
|||||||
import org.littletonrobotics.junction.wpilog.WPILOGReader;
|
import org.littletonrobotics.junction.wpilog.WPILOGReader;
|
||||||
import org.littletonrobotics.junction.wpilog.WPILOGWriter;
|
import org.littletonrobotics.junction.wpilog.WPILOGWriter;
|
||||||
|
|
||||||
import com.ctre.phoenix6.CANBus;
|
|
||||||
import com.ctre.phoenix6.CANBus.CANBusStatus;
|
|
||||||
|
|
||||||
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.robot.constants.BuildConstants;
|
import frc4388.robot.constants.BuildConstants;
|
||||||
import frc4388.robot.constants.Constants;
|
|
||||||
import frc4388.robot.constants.Constants.SimConstants;
|
import frc4388.robot.constants.Constants.SimConstants;
|
||||||
import frc4388.utility.DeferredBlock;
|
import frc4388.utility.DeferredBlock;
|
||||||
import frc4388.utility.DeferredBlockMulti;
|
import frc4388.utility.DeferredBlockMulti;
|
||||||
import frc4388.utility.Trim;
|
import frc4388.utility.Trim;
|
||||||
import frc4388.utility.compute.RobotTime;
|
import frc4388.utility.compute.RobotTime;
|
||||||
import frc4388.utility.status.CanDevice;
|
import frc4388.utility.status.FaultReporter;
|
||||||
import frc4388.utility.status.Status;
|
|
||||||
import frc4388.utility.status.Subsystem;
|
|
||||||
import frc4388.utility.status.Status.Report;
|
|
||||||
import frc4388.utility.status.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
|
||||||
@@ -63,23 +52,7 @@ public class Robot extends LoggedRobot {
|
|||||||
|
|
||||||
|
|
||||||
// Create a shuffleboard update thread, that will periodically update the values on shuffleboard
|
// Create a shuffleboard update thread, that will periodically update the values on shuffleboard
|
||||||
new Thread() {
|
FaultReporter.startThread();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -189,71 +162,7 @@ public class Robot extends LoggedRobot {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void testInit() {
|
public void testInit() {
|
||||||
|
FaultReporter.printReport();
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,10 @@ import frc4388.robot.constants.Constants.LiDARConstants;
|
|||||||
import frc4388.robot.constants.Constants.VisionConstants;
|
import frc4388.robot.constants.Constants.VisionConstants;
|
||||||
import frc4388.robot.constants.DriveConstants;
|
import frc4388.robot.constants.DriveConstants;
|
||||||
import frc4388.robot.subsystems.Lidar;
|
import frc4388.robot.subsystems.Lidar;
|
||||||
|
import frc4388.utility.status.FaultCANCoder;
|
||||||
|
import frc4388.utility.status.FaultPhotonCamera;
|
||||||
|
import frc4388.utility.status.FaultPidgeon2;
|
||||||
|
import frc4388.utility.status.FaultTalonFX;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines and holds all I/O objects on the Roborio. This is useful for unit
|
* Defines and holds all I/O objects on the Roborio. This is useful for unit
|
||||||
@@ -38,10 +42,6 @@ public class RobotMap {
|
|||||||
public final Lidar reverseLidar = new Lidar(LiDARConstants.REVERSE_LIDAR_DIO_CHANNEL, "Reverse");
|
public final Lidar reverseLidar = new Lidar(LiDARConstants.REVERSE_LIDAR_DIO_CHANNEL, "Reverse");
|
||||||
|
|
||||||
|
|
||||||
public RobotMap() {
|
|
||||||
configureDriveMotorControllers();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* LED Subsystem */
|
/* LED Subsystem */
|
||||||
// public final Spark LEDController = new Spark(LEDConstants.LED_SPARK_ID);
|
// public final Spark LEDController = new Spark(LEDConstants.LED_SPARK_ID);
|
||||||
|
|
||||||
@@ -66,6 +66,31 @@ public class RobotMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public RobotMap() {
|
||||||
|
configureDriveMotorControllers();
|
||||||
|
|
||||||
|
FaultPhotonCamera.addDevice(leftCamera, "Left Camera");
|
||||||
|
FaultPhotonCamera.addDevice(rightCamera, "Right Camera");
|
||||||
|
|
||||||
|
FaultPidgeon2.addDevice(swerveDrivetrain.getPigeon2(), "Gyro");
|
||||||
|
|
||||||
|
FaultTalonFX.addDevice(elevator, "Elevator");
|
||||||
|
FaultTalonFX.addDevice(endeffector, "Endeffector");
|
||||||
|
|
||||||
|
FaultTalonFX.addDevice(swerveDrivetrain.getModule(0).getDriveMotor(), "Module 0 Drive");
|
||||||
|
FaultTalonFX.addDevice(swerveDrivetrain.getModule(0).getSteerMotor(), "Module 0 Steer");
|
||||||
|
FaultCANCoder.addDevice(swerveDrivetrain.getModule(0).getEncoder(), "Module 0 CANCoder");
|
||||||
|
FaultTalonFX.addDevice(swerveDrivetrain.getModule(1).getDriveMotor(), "Module 1 Drive");
|
||||||
|
FaultTalonFX.addDevice(swerveDrivetrain.getModule(1).getSteerMotor(), "Module 1 Steer");
|
||||||
|
FaultCANCoder.addDevice(swerveDrivetrain.getModule(1).getEncoder(), "Module 1 CANCoder");
|
||||||
|
FaultTalonFX.addDevice(swerveDrivetrain.getModule(2).getDriveMotor(), "Module 2 Drive");
|
||||||
|
FaultTalonFX.addDevice(swerveDrivetrain.getModule(2).getSteerMotor(), "Module 2 Steer");
|
||||||
|
FaultCANCoder.addDevice(swerveDrivetrain.getModule(2).getEncoder(), "Module 2 CANCoder");
|
||||||
|
FaultTalonFX.addDevice(swerveDrivetrain.getModule(3).getDriveMotor(), "Module 3 Drive");
|
||||||
|
FaultTalonFX.addDevice(swerveDrivetrain.getModule(3).getSteerMotor(), "Module 3 Steer");
|
||||||
|
FaultCANCoder.addDevice(swerveDrivetrain.getModule(3).getEncoder(), "Module 3 CANCoder");
|
||||||
|
}
|
||||||
|
|
||||||
public class RobotMapSim {
|
public class RobotMapSim {
|
||||||
public PhotonCameraSim leftCamera;
|
public PhotonCameraSim leftCamera;
|
||||||
public PhotonCameraSim rightCamera;
|
public PhotonCameraSim rightCamera;
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ public final class BuildConstants {
|
|||||||
public static final String MAVEN_GROUP = "";
|
public static final String MAVEN_GROUP = "";
|
||||||
public static final String MAVEN_NAME = "2025RidgeScape";
|
public static final String MAVEN_NAME = "2025RidgeScape";
|
||||||
public static final String VERSION = "unspecified";
|
public static final String VERSION = "unspecified";
|
||||||
public static final int GIT_REVISION = 164;
|
public static final int GIT_REVISION = 165;
|
||||||
public static final String GIT_SHA = "06d525ade1118ae193383bc86066ea5563d86a1f";
|
public static final String GIT_SHA = "bf4da44338d8e91c50e34c3ac68dc12f9d335b08";
|
||||||
public static final String GIT_DATE = "2025-04-22 18:21:00 EDT";
|
public static final String GIT_DATE = "2025-07-11 14:07:53 MDT";
|
||||||
public static final String GIT_BRANCH = "advantagekit";
|
public static final String GIT_BRANCH = "advantagekit";
|
||||||
public static final String BUILD_DATE = "2025-07-11 15:07:31 EDT";
|
public static final String BUILD_DATE = "2025-07-11 17:46:28 MDT";
|
||||||
public static final long BUILD_UNIX_TIME = 1752260851324L;
|
public static final long BUILD_UNIX_TIME = 1752277588371L;
|
||||||
public static final int DIRTY = 1;
|
public static final int DIRTY = 1;
|
||||||
|
|
||||||
private BuildConstants(){}
|
private BuildConstants(){}
|
||||||
|
|||||||
@@ -243,5 +243,4 @@ public final class DriveConstants {
|
|||||||
// misc
|
// misc
|
||||||
public static final int TIMEOUT_MS = 30;
|
public static final int TIMEOUT_MS = 30;
|
||||||
public static final int SMARTDASHBOARD_UPDATE_FRAME = 2;
|
public static final int SMARTDASHBOARD_UPDATE_FRAME = 2;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,16 +12,18 @@ import com.ctre.phoenix6.hardware.TalonFX;
|
|||||||
|
|
||||||
import edu.wpi.first.wpilibj.drive.DifferentialDrive;
|
import edu.wpi.first.wpilibj.drive.DifferentialDrive;
|
||||||
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
|
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
|
||||||
|
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.compute.RobotTime;
|
import frc4388.utility.compute.RobotTime;
|
||||||
import frc4388.utility.status.Status;
|
import frc4388.utility.status.Status;
|
||||||
import frc4388.utility.status.Subsystem;
|
import frc4388.utility.status.FaultReporter;
|
||||||
|
import frc4388.utility.status.Queryable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add your docs here.
|
* Add your docs here.
|
||||||
*/
|
*/
|
||||||
public class DiffDrive extends Subsystem {
|
public class DiffDrive extends SubsystemBase implements Queryable {
|
||||||
// Put methods for controlling this subsystem
|
// Put methods for controlling this subsystem
|
||||||
// here. Call these from Commands.
|
// here. Call these from Commands.
|
||||||
|
|
||||||
@@ -40,7 +42,7 @@ public class DiffDrive extends Subsystem {
|
|||||||
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();
|
FaultReporter.register(this);
|
||||||
|
|
||||||
m_leftFrontMotor = leftFrontMotor;
|
m_leftFrontMotor = leftFrontMotor;
|
||||||
m_rightFrontMotor = rightFrontMotor;
|
m_rightFrontMotor = rightFrontMotor;
|
||||||
@@ -90,7 +92,7 @@ public class DiffDrive extends Subsystem {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSubsystemName() {
|
public String getName() {
|
||||||
return "Diff Drive";
|
return "Diff Drive";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +103,7 @@ public class DiffDrive extends Subsystem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Status diagnosticStatus() {
|
public Status diagnosticStatus() {
|
||||||
Log("Diagnostic info for this has not been inplemented!"); //TODO
|
// Log("Diagnostic info for this has not been inplemented!"); //TODO
|
||||||
return new Status();
|
return new Status();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,14 +10,16 @@ import com.ctre.phoenix6.signals.NeutralModeValue;
|
|||||||
|
|
||||||
import edu.wpi.first.wpilibj.DigitalInput;
|
import edu.wpi.first.wpilibj.DigitalInput;
|
||||||
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
|
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
|
||||||
|
import edu.wpi.first.wpilibj2.command.SubsystemBase;
|
||||||
import frc4388.robot.constants.Constants.AutoConstants;
|
import frc4388.robot.constants.Constants.AutoConstants;
|
||||||
import frc4388.robot.constants.Constants.ElevatorConstants;
|
import frc4388.robot.constants.Constants.ElevatorConstants;
|
||||||
import frc4388.robot.constants.Constants.LEDConstants;
|
import frc4388.robot.constants.Constants.LEDConstants;
|
||||||
import frc4388.utility.status.Status;
|
import frc4388.utility.status.Status;
|
||||||
import frc4388.utility.status.Subsystem;
|
import frc4388.utility.status.FaultReporter;
|
||||||
|
import frc4388.utility.status.Queryable;
|
||||||
import frc4388.utility.status.Status.ReportLevel;
|
import frc4388.utility.status.Status.ReportLevel;
|
||||||
|
|
||||||
public class Elevator extends Subsystem {
|
public class Elevator extends SubsystemBase implements Queryable {
|
||||||
/** Creates a new Elevator. */
|
/** Creates a new Elevator. */
|
||||||
private TalonFX elevatorMotor;
|
private TalonFX elevatorMotor;
|
||||||
private TalonFX endeffectorMotor;
|
private TalonFX endeffectorMotor;
|
||||||
@@ -77,6 +79,8 @@ public class Elevator extends Subsystem {
|
|||||||
elevatorMotor.getConfigurator().apply(ElevatorConstants.ELEVATOR_PID);
|
elevatorMotor.getConfigurator().apply(ElevatorConstants.ELEVATOR_PID);
|
||||||
endeffectorMotor.getConfigurator().apply(ElevatorConstants.ENDEFFECTOR_PID);
|
endeffectorMotor.getConfigurator().apply(ElevatorConstants.ENDEFFECTOR_PID);
|
||||||
currentState = CoordinationState.Ready;
|
currentState = CoordinationState.Ready;
|
||||||
|
|
||||||
|
FaultReporter.register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
//PID methods
|
//PID methods
|
||||||
@@ -370,7 +374,7 @@ public class Elevator extends Subsystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSubsystemName() {
|
public String getName() {
|
||||||
return "Elevator";
|
return "Elevator";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,8 +386,6 @@ public class Elevator extends Subsystem {
|
|||||||
Status status = new Status();
|
Status status = new Status();
|
||||||
|
|
||||||
status.addReport(ReportLevel.INFO, "Elevator Mode: " + currentState.name());
|
status.addReport(ReportLevel.INFO, "Elevator Mode: " + currentState.name());
|
||||||
status.diagnoseHardwareCTRE("Elevator Motor", elevatorMotor);
|
|
||||||
status.diagnoseHardwareCTRE("Endeffector Motor", endeffectorMotor);
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,9 +10,11 @@ package frc4388.robot.subsystems;
|
|||||||
import edu.wpi.first.wpilibj.DriverStation;
|
import edu.wpi.first.wpilibj.DriverStation;
|
||||||
import edu.wpi.first.wpilibj.motorcontrol.Spark;
|
import edu.wpi.first.wpilibj.motorcontrol.Spark;
|
||||||
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
|
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
|
||||||
|
import edu.wpi.first.wpilibj2.command.SubsystemBase;
|
||||||
import frc4388.robot.constants.Constants.LEDConstants;
|
import frc4388.robot.constants.Constants.LEDConstants;
|
||||||
import frc4388.utility.status.Status;
|
import frc4388.utility.status.Status;
|
||||||
import frc4388.utility.status.Subsystem;
|
import frc4388.utility.status.FaultReporter;
|
||||||
|
import frc4388.utility.status.Queryable;
|
||||||
import frc4388.utility.status.Status.ReportLevel;
|
import frc4388.utility.status.Status.ReportLevel;
|
||||||
import frc4388.utility.structs.LEDPatterns;
|
import frc4388.utility.structs.LEDPatterns;
|
||||||
|
|
||||||
@@ -20,7 +22,10 @@ import frc4388.utility.structs.LEDPatterns;
|
|||||||
* Allows for the control of a 5v LED Strip using a Rev Robotics Blinkin LED
|
* Allows for the control of a 5v LED Strip using a Rev Robotics Blinkin LED
|
||||||
* Driver
|
* Driver
|
||||||
*/
|
*/
|
||||||
public class LED extends Subsystem {
|
public class LED extends SubsystemBase implements Queryable {
|
||||||
|
public LED() {
|
||||||
|
FaultReporter.register(this);
|
||||||
|
}
|
||||||
|
|
||||||
private static Spark LEDController = new Spark(LEDConstants.LED_SPARK_ID);
|
private static Spark LEDController = new Spark(LEDConstants.LED_SPARK_ID);
|
||||||
private LEDPatterns mode = LEDConstants.DEFAULT_PATTERN;
|
private LEDPatterns mode = LEDConstants.DEFAULT_PATTERN;
|
||||||
@@ -44,7 +49,7 @@ public class LED extends Subsystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSubsystemName() {
|
public String getName() {
|
||||||
return "LEDs";
|
return "LEDs";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,9 +62,7 @@ public class LED extends Subsystem {
|
|||||||
public Status diagnosticStatus() {
|
public Status diagnosticStatus() {
|
||||||
Status status = new Status();
|
Status status = new Status();
|
||||||
|
|
||||||
if(LEDController.isAlive())
|
if(!LEDController.isAlive())
|
||||||
status.addReport(ReportLevel.INFO, "LED is CONNECTED");
|
|
||||||
else
|
|
||||||
status.addReport(ReportLevel.ERROR, "LED is DISCONNECTED");
|
status.addReport(ReportLevel.ERROR, "LED is DISCONNECTED");
|
||||||
|
|
||||||
status.addReport(ReportLevel.INFO, "LED Mode: " + mode.name());
|
status.addReport(ReportLevel.INFO, "LED Mode: " + mode.name());
|
||||||
|
|||||||
@@ -6,19 +6,23 @@ import edu.wpi.first.wpilibj.shuffleboard.BuiltInLayouts;
|
|||||||
import edu.wpi.first.wpilibj.shuffleboard.BuiltInWidgets;
|
import edu.wpi.first.wpilibj.shuffleboard.BuiltInWidgets;
|
||||||
import edu.wpi.first.wpilibj.shuffleboard.Shuffleboard;
|
import edu.wpi.first.wpilibj.shuffleboard.Shuffleboard;
|
||||||
import edu.wpi.first.wpilibj.shuffleboard.ShuffleboardLayout;
|
import edu.wpi.first.wpilibj.shuffleboard.ShuffleboardLayout;
|
||||||
|
import edu.wpi.first.wpilibj2.command.SubsystemBase;
|
||||||
import frc4388.robot.constants.Constants.LiDARConstants;
|
import frc4388.robot.constants.Constants.LiDARConstants;
|
||||||
import frc4388.utility.status.Status;
|
import frc4388.utility.status.Status;
|
||||||
import frc4388.utility.status.Subsystem;
|
import frc4388.utility.status.FaultReporter;
|
||||||
|
import frc4388.utility.status.Queryable;
|
||||||
import frc4388.utility.status.Status.ReportLevel;
|
import frc4388.utility.status.Status.ReportLevel;
|
||||||
|
|
||||||
// https://girlsofsteeldocs.readthedocs.io/en/latest/technical-resources/sensors/LIDAR-Lite-Distance-Sensor.html#minimal-roborio-interface
|
// https://girlsofsteeldocs.readthedocs.io/en/latest/technical-resources/sensors/LIDAR-Lite-Distance-Sensor.html#minimal-roborio-interface
|
||||||
public class Lidar extends Subsystem {
|
public class Lidar extends SubsystemBase implements Queryable {
|
||||||
|
|
||||||
private Counter LidarPWM;
|
private Counter LidarPWM;
|
||||||
private String name = "Lidar";
|
private String name = "Lidar";
|
||||||
|
|
||||||
private double distance = -1;
|
private double distance = -1;
|
||||||
public Lidar(int port, String name) {
|
public Lidar(int port, String name) {
|
||||||
|
FaultReporter.register(this);
|
||||||
|
|
||||||
this.name = name;
|
this.name = name;
|
||||||
LidarPWM = new Counter(port);
|
LidarPWM = new Counter(port);
|
||||||
LidarPWM.setMaxPeriod(1.00); //set the max period that can be measured
|
LidarPWM.setMaxPeriod(1.00); //set the max period that can be measured
|
||||||
@@ -27,7 +31,7 @@ public class Lidar extends Subsystem {
|
|||||||
|
|
||||||
|
|
||||||
subsystemLayout = Shuffleboard.getTab("Subsystems")
|
subsystemLayout = Shuffleboard.getTab("Subsystems")
|
||||||
.getLayout(getSubsystemName(), BuiltInLayouts.kList)
|
.getLayout(getName(), BuiltInLayouts.kList)
|
||||||
.withSize(2, 2);
|
.withSize(2, 2);
|
||||||
|
|
||||||
sbDistance = subsystemLayout
|
sbDistance = subsystemLayout
|
||||||
@@ -63,7 +67,7 @@ public class Lidar extends Subsystem {
|
|||||||
GenericEntry sbWithinDistance;
|
GenericEntry sbWithinDistance;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSubsystemName() {
|
public String getName() {
|
||||||
return "Lidar " + name;
|
return "Lidar " + name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,11 +81,8 @@ public class Lidar extends Subsystem {
|
|||||||
public Status diagnosticStatus() {
|
public Status diagnosticStatus() {
|
||||||
Status s = new Status();
|
Status s = new Status();
|
||||||
|
|
||||||
if(distance == -1){
|
if(distance == -1)
|
||||||
s.addReport(ReportLevel.ERROR, "LiDAR DISCONNECTED");
|
s.addReport(ReportLevel.ERROR, "LiDAR DISCONNECTED");
|
||||||
}else{
|
|
||||||
s.addReport(ReportLevel.INFO, "LiDAR Connected");
|
|
||||||
}
|
|
||||||
|
|
||||||
s.addReport(ReportLevel.INFO, "LiDAR Distance: " + distance);
|
s.addReport(ReportLevel.INFO, "LiDAR Distance: " + distance);
|
||||||
|
|
||||||
|
|||||||
@@ -25,11 +25,12 @@ import edu.wpi.first.wpilibj.shuffleboard.BuiltInWidgets;
|
|||||||
import edu.wpi.first.wpilibj.shuffleboard.Shuffleboard;
|
import edu.wpi.first.wpilibj.shuffleboard.Shuffleboard;
|
||||||
import edu.wpi.first.wpilibj.shuffleboard.ShuffleboardLayout;
|
import edu.wpi.first.wpilibj.shuffleboard.ShuffleboardLayout;
|
||||||
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
|
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
|
||||||
|
import edu.wpi.first.wpilibj2.command.SubsystemBase;
|
||||||
import frc4388.robot.constants.DriveConstants;
|
import frc4388.robot.constants.DriveConstants;
|
||||||
import frc4388.utility.compute.TimesNegativeOne;
|
import frc4388.utility.compute.TimesNegativeOne;
|
||||||
import frc4388.utility.status.Status;
|
import frc4388.utility.status.Status;
|
||||||
import frc4388.utility.status.Subsystem;
|
import frc4388.utility.status.FaultReporter;
|
||||||
import frc4388.utility.status.Status.ReportLevel;
|
import frc4388.utility.status.Queryable;
|
||||||
|
|
||||||
import com.pathplanner.lib.controllers.PPHolonomicDriveController;
|
import com.pathplanner.lib.controllers.PPHolonomicDriveController;
|
||||||
import com.pathplanner.lib.util.PathPlannerLogging;
|
import com.pathplanner.lib.util.PathPlannerLogging;
|
||||||
@@ -37,7 +38,7 @@ import com.pathplanner.lib.config.PIDConstants;
|
|||||||
import com.pathplanner.lib.auto.AutoBuilder;
|
import com.pathplanner.lib.auto.AutoBuilder;
|
||||||
import com.pathplanner.lib.config.RobotConfig;
|
import com.pathplanner.lib.config.RobotConfig;
|
||||||
|
|
||||||
public class SwerveDrive extends Subsystem {
|
public class SwerveDrive extends SubsystemBase implements Queryable {
|
||||||
private SwerveDrivetrain<TalonFX, TalonFX, CANcoder> swerveDriveTrain;
|
private SwerveDrivetrain<TalonFX, TalonFX, CANcoder> swerveDriveTrain;
|
||||||
|
|
||||||
private Vision vision;
|
private Vision vision;
|
||||||
@@ -65,7 +66,7 @@ public class SwerveDrive extends Subsystem {
|
|||||||
public SwerveDrive(SwerveDrivetrain<TalonFX, TalonFX, CANcoder> swerveDriveTrain, Vision vision) {
|
public SwerveDrive(SwerveDrivetrain<TalonFX, TalonFX, CANcoder> swerveDriveTrain, Vision vision) {
|
||||||
// public SwerveDrive(SwerveDrivetrain<TalonFX, TalonFX, CANcoder>
|
// public SwerveDrive(SwerveDrivetrain<TalonFX, TalonFX, CANcoder>
|
||||||
// swerveDriveTrain) {
|
// swerveDriveTrain) {
|
||||||
super();
|
FaultReporter.register(this);
|
||||||
|
|
||||||
this.swerveDriveTrain = swerveDriveTrain;
|
this.swerveDriveTrain = swerveDriveTrain;
|
||||||
this.vision = vision;
|
this.vision = vision;
|
||||||
@@ -448,12 +449,12 @@ public class SwerveDrive extends Subsystem {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSubsystemName() {
|
public String getName() {
|
||||||
return "Swerve Drive Controller";
|
return "Swerve Drive Controller";
|
||||||
}
|
}
|
||||||
|
|
||||||
ShuffleboardLayout subsystemLayout = Shuffleboard.getTab("Subsystems")
|
ShuffleboardLayout subsystemLayout = Shuffleboard.getTab("Subsystems")
|
||||||
.getLayout(getSubsystemName(), BuiltInLayouts.kList)
|
.getLayout(getName(), BuiltInLayouts.kList)
|
||||||
.withSize(2, 2);
|
.withSize(2, 2);
|
||||||
|
|
||||||
GenericEntry sbGyro = subsystemLayout
|
GenericEntry sbGyro = subsystemLayout
|
||||||
@@ -478,8 +479,8 @@ public class SwerveDrive extends Subsystem {
|
|||||||
public Status diagnosticStatus() {
|
public Status diagnosticStatus() {
|
||||||
Status status = new Status();
|
Status status = new Status();
|
||||||
|
|
||||||
status.addReport(ReportLevel.INFO,
|
// status.addReport(ReportLevel.INFO,
|
||||||
"Don't know how to diganose new CTRE swerve systems. please check under the CAN(t) section for more detailed information about the swerves there.");
|
// "Don't know how to diganose new CTRE swerve systems. please check under the CAN(t) section for more detailed information about the swerves there.");
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,13 +27,14 @@ import edu.wpi.first.wpilibj.shuffleboard.Shuffleboard;
|
|||||||
import edu.wpi.first.wpilibj.shuffleboard.ShuffleboardLayout;
|
import edu.wpi.first.wpilibj.shuffleboard.ShuffleboardLayout;
|
||||||
import edu.wpi.first.wpilibj.smartdashboard.Field2d;
|
import edu.wpi.first.wpilibj.smartdashboard.Field2d;
|
||||||
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
|
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
|
||||||
|
import edu.wpi.first.wpilibj2.command.SubsystemBase;
|
||||||
import frc4388.robot.constants.Constants.FieldConstants;
|
import frc4388.robot.constants.Constants.FieldConstants;
|
||||||
import frc4388.robot.constants.Constants.VisionConstants;
|
import frc4388.robot.constants.Constants.VisionConstants;
|
||||||
import frc4388.utility.status.Status;
|
import frc4388.utility.status.Status;
|
||||||
import frc4388.utility.status.Subsystem;
|
import frc4388.utility.status.FaultReporter;
|
||||||
import frc4388.utility.status.Status.ReportLevel;
|
import frc4388.utility.status.Queryable;
|
||||||
|
|
||||||
public class Vision extends Subsystem {
|
public class Vision extends SubsystemBase implements Queryable {
|
||||||
|
|
||||||
// private PhotonCamera leftCamera;
|
// private PhotonCamera leftCamera;
|
||||||
// private PhotonCamera rightCamera;
|
// private PhotonCamera rightCamera;
|
||||||
@@ -59,7 +60,7 @@ public class Vision extends Subsystem {
|
|||||||
private Field2d field = new Field2d();
|
private Field2d field = new Field2d();
|
||||||
|
|
||||||
ShuffleboardLayout subsystemLayout = Shuffleboard.getTab("Subsystems")
|
ShuffleboardLayout subsystemLayout = Shuffleboard.getTab("Subsystems")
|
||||||
.getLayout(getSubsystemName(), BuiltInLayouts.kList)
|
.getLayout(getName(), BuiltInLayouts.kList)
|
||||||
.withSize(2, 2);
|
.withSize(2, 2);
|
||||||
|
|
||||||
GenericEntry sbTagDetected = subsystemLayout
|
GenericEntry sbTagDetected = subsystemLayout
|
||||||
@@ -72,17 +73,8 @@ public class Vision extends Subsystem {
|
|||||||
.withWidget(BuiltInWidgets.kBooleanBox)
|
.withWidget(BuiltInWidgets.kBooleanBox)
|
||||||
.getEntry();
|
.getEntry();
|
||||||
|
|
||||||
GenericEntry sbLeftCamConnected = subsystemLayout
|
|
||||||
.add("Left Camera Connnected", false)
|
|
||||||
.withWidget(BuiltInWidgets.kBooleanBox)
|
|
||||||
.getEntry();
|
|
||||||
|
|
||||||
GenericEntry sbRightCamConnected = subsystemLayout
|
|
||||||
.add("Right Camera Connnected", false)
|
|
||||||
.withWidget(BuiltInWidgets.kBooleanBox)
|
|
||||||
.getEntry();
|
|
||||||
|
|
||||||
public Vision(PhotonCamera leftCamera, PhotonCamera rightCamera){
|
public Vision(PhotonCamera leftCamera, PhotonCamera rightCamera){
|
||||||
|
FaultReporter.register(this);
|
||||||
SmartDashboard.putData(field);
|
SmartDashboard.putData(field);
|
||||||
|
|
||||||
this.cameras = new PhotonCamera[]{leftCamera, rightCamera};
|
this.cameras = new PhotonCamera[]{leftCamera, rightCamera};
|
||||||
@@ -307,7 +299,7 @@ public class Vision extends Subsystem {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSubsystemName() {
|
public String getName() {
|
||||||
return "Vision";
|
return "Vision";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,27 +313,12 @@ public class Vision extends Subsystem {
|
|||||||
public void queryStatus() {
|
public void queryStatus() {
|
||||||
sbTagDetected.setBoolean(isTagDetected);
|
sbTagDetected.setBoolean(isTagDetected);
|
||||||
sbTagProcessed.setBoolean(isTagProcessed);
|
sbTagProcessed.setBoolean(isTagProcessed);
|
||||||
sbLeftCamConnected.setBoolean(cameras[0].isConnected());
|
|
||||||
sbRightCamConnected.setBoolean(cameras[1].isConnected());
|
|
||||||
// field.setRobotPose(getPose2d());
|
// field.setRobotPose(getPose2d());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Status diagnosticStatus() {
|
public Status diagnosticStatus() {
|
||||||
Status status = new Status();
|
return new Status();
|
||||||
|
|
||||||
if(cameras[0].isConnected())
|
|
||||||
status.addReport(ReportLevel.INFO, "Left Camera Connected");
|
|
||||||
else
|
|
||||||
status.addReport(ReportLevel.ERROR, "Left Camera DISCONNECTED");
|
|
||||||
|
|
||||||
if(cameras[1].isConnected())
|
|
||||||
status.addReport(ReportLevel.INFO, "Right Camera Connected");
|
|
||||||
else
|
|
||||||
status.addReport(ReportLevel.ERROR, "Right Camera DISCONNECTED");
|
|
||||||
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package frc4388.utility.status;
|
||||||
|
|
||||||
|
import com.ctre.phoenix6.controls.EmptyControl;
|
||||||
|
import com.ctre.phoenix6.hardware.CANcoder;
|
||||||
|
|
||||||
|
import frc4388.utility.status.Status.ReportLevel;
|
||||||
|
|
||||||
|
public class FaultCANCoder implements Queryable {
|
||||||
|
private String name;
|
||||||
|
private CANcoder cancoder;
|
||||||
|
|
||||||
|
public static void addDevice(CANcoder cancoder, String name) {
|
||||||
|
FaultCANCoder p = new FaultCANCoder();
|
||||||
|
|
||||||
|
p.name = name;
|
||||||
|
p.cancoder = cancoder;
|
||||||
|
|
||||||
|
FaultReporter.register(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queryStatus() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
// throw new UnsupportedOperationException("Unimplemented method 'queryStatus'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Status diagnosticStatus() {
|
||||||
|
Status s = new Status();
|
||||||
|
|
||||||
|
boolean debounceBad = !QueryUtils.isDebounceOk(cancoder.getSupplyVoltage());
|
||||||
|
boolean emptyControlBad = cancoder.setControl(new EmptyControl()).value != 0;
|
||||||
|
|
||||||
|
if(debounceBad || emptyControlBad) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "device is unreachable - Failed" +
|
||||||
|
(debounceBad ? " Failed debounce test" : "") +
|
||||||
|
(emptyControlBad ? " Failed empty control test" : "")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// faults
|
||||||
|
if (cancoder.getFault_Hardware().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "Hardware fault detected");
|
||||||
|
}
|
||||||
|
if (cancoder.getFault_BootDuringEnable().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "Device booted while enabled");
|
||||||
|
}
|
||||||
|
if (cancoder.getFault_BadMagnet().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "Bad magnet");
|
||||||
|
}
|
||||||
|
if (cancoder.getFault_Undervoltage().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "Device supply voltage near brownout");
|
||||||
|
}
|
||||||
|
if (cancoder.getFault_UnlicensedFeatureInUse().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "Unlicensed feature in use");
|
||||||
|
}
|
||||||
|
|
||||||
|
// sticky faults
|
||||||
|
if (cancoder.getStickyFault_Hardware().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "[STICKY] Hardware fault detected");
|
||||||
|
}
|
||||||
|
if (cancoder.getStickyFault_BootDuringEnable().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "[STICKY] Device booted while enabled");
|
||||||
|
}
|
||||||
|
if (cancoder.getStickyFault_BadMagnet().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "[STICKY] Bad magnet");
|
||||||
|
}
|
||||||
|
if (cancoder.getStickyFault_Undervoltage().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "[STICKY] Device supply voltage near brownout");
|
||||||
|
}
|
||||||
|
if (cancoder.getStickyFault_UnlicensedFeatureInUse().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "[STICKY] Unlicensed feature in use");
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package frc4388.utility.status;
|
||||||
|
|
||||||
|
import org.photonvision.PhotonCamera;
|
||||||
|
|
||||||
|
import frc4388.utility.status.Status.ReportLevel;
|
||||||
|
|
||||||
|
public class FaultPhotonCamera implements Queryable {
|
||||||
|
private String name;
|
||||||
|
private PhotonCamera cam;
|
||||||
|
|
||||||
|
public static void addDevice(PhotonCamera cam, String name) {
|
||||||
|
FaultPhotonCamera p = new FaultPhotonCamera();
|
||||||
|
|
||||||
|
p.name = name;
|
||||||
|
p.cam = cam;
|
||||||
|
|
||||||
|
FaultReporter.register(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queryStatus() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Status diagnosticStatus() {
|
||||||
|
Status s = new Status();
|
||||||
|
|
||||||
|
if(!cam.isConnected())
|
||||||
|
s.addReport(ReportLevel.ERROR, "Not Connected!");
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,174 @@
|
|||||||
|
package frc4388.utility.status;
|
||||||
|
|
||||||
|
import com.ctre.phoenix6.controls.EmptyControl;
|
||||||
|
import com.ctre.phoenix6.hardware.Pigeon2;
|
||||||
|
|
||||||
|
import frc4388.utility.status.Status.ReportLevel;
|
||||||
|
|
||||||
|
public class FaultPidgeon2 implements Queryable {
|
||||||
|
private String name;
|
||||||
|
private Pigeon2 pigeon2;
|
||||||
|
|
||||||
|
public static void addDevice(Pigeon2 pigeon2, String name) {
|
||||||
|
FaultPidgeon2 p = new FaultPidgeon2();
|
||||||
|
|
||||||
|
p.name = name;
|
||||||
|
p.pigeon2 = pigeon2;
|
||||||
|
|
||||||
|
FaultReporter.register(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queryStatus() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
// throw new UnsupportedOperationException("Unimplemented method 'queryStatus'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Status diagnosticStatus() {
|
||||||
|
Status s = new Status();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
boolean debounceBad = !QueryUtils.isDebounceOk(pigeon2.getSupplyVoltage());
|
||||||
|
boolean emptyControlBad = pigeon2.setControl(new EmptyControl()).value != 0;
|
||||||
|
|
||||||
|
if(debounceBad || emptyControlBad) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "device is unreachable - Failed" +
|
||||||
|
(debounceBad ? " Failed debounce test" : "") +
|
||||||
|
(emptyControlBad ? " Failed empty control test" : "")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
s.addReport(ReportLevel.INFO, "Voltage: " + pigeon2.getSupplyVoltage());
|
||||||
|
|
||||||
|
s.addReport(ReportLevel.INFO, "Pitch: " + pigeon2.getPitch());
|
||||||
|
s.addReport(ReportLevel.INFO, "Yaw: " + pigeon2.getYaw());
|
||||||
|
s.addReport(ReportLevel.INFO, "Roll: " + pigeon2.getRoll());
|
||||||
|
|
||||||
|
s.addReport(ReportLevel.INFO, "Acceleration X: " + pigeon2.getAccelerationX());
|
||||||
|
s.addReport(ReportLevel.INFO, "Acceleration Y: " + pigeon2.getAccelerationY());
|
||||||
|
s.addReport(ReportLevel.INFO, "Acceleration Z: " + pigeon2.getAccelerationZ());
|
||||||
|
|
||||||
|
s.addReport(ReportLevel.INFO, "Magnomiter X: " + pigeon2.getMagneticFieldX());
|
||||||
|
s.addReport(ReportLevel.INFO, "Magnomiter Y: " + pigeon2.getMagneticFieldY());
|
||||||
|
s.addReport(ReportLevel.INFO, "Magnomiter Z: " + pigeon2.getMagneticFieldZ());
|
||||||
|
|
||||||
|
|
||||||
|
// faults
|
||||||
|
if (pigeon2.getFault_BootDuringEnable().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "Device booted while enabled");
|
||||||
|
}
|
||||||
|
if (pigeon2.getFault_BootIntoMotion().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "Device booted while in motion");
|
||||||
|
}
|
||||||
|
if (pigeon2.getFault_BootupAccelerometer().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "Accelerometer fault detected");
|
||||||
|
}
|
||||||
|
if (pigeon2.getFault_BootupGyroscope().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "Gyro fault detected");
|
||||||
|
}
|
||||||
|
if (pigeon2.getFault_BootupMagnetometer().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "Magnetometer fault detected");
|
||||||
|
}
|
||||||
|
if (pigeon2.getFault_DataAcquiredLate().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(
|
||||||
|
ReportLevel.ERROR,
|
||||||
|
"Motion stack data acquisition slower than expected");
|
||||||
|
}
|
||||||
|
if (pigeon2.getFault_Hardware().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "Hardware fault detected");
|
||||||
|
}
|
||||||
|
if (pigeon2.getFault_LoopTimeSlow().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(
|
||||||
|
ReportLevel.ERROR,
|
||||||
|
"Motion stack loop time was slower than expected");
|
||||||
|
}
|
||||||
|
if (pigeon2.getFault_SaturatedAccelerometer().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(
|
||||||
|
ReportLevel.ERROR, "Accelerometer values are saturated");
|
||||||
|
}
|
||||||
|
if (pigeon2.getFault_SaturatedGyroscope().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "Gyro values are saturated");
|
||||||
|
}
|
||||||
|
if (pigeon2.getFault_SaturatedMagnetometer().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(
|
||||||
|
ReportLevel.ERROR, "Magnetometer values are saturated");
|
||||||
|
}
|
||||||
|
if (pigeon2.getFault_Undervoltage().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(
|
||||||
|
ReportLevel.ERROR, "Device supply voltage near brownout");
|
||||||
|
}
|
||||||
|
if (pigeon2.getFault_UnlicensedFeatureInUse().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "Unlicensed feature in use");
|
||||||
|
}
|
||||||
|
|
||||||
|
// sticky faults
|
||||||
|
if (pigeon2.getStickyFault_BootDuringEnable().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(
|
||||||
|
ReportLevel.ERROR, "[STICKY] Device booted while enabled");
|
||||||
|
}
|
||||||
|
if (pigeon2.getStickyFault_BootIntoMotion().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(
|
||||||
|
ReportLevel.ERROR, "[STICKY] Device booted while in motion");
|
||||||
|
}
|
||||||
|
if (pigeon2.getStickyFault_BootupAccelerometer().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(
|
||||||
|
ReportLevel.ERROR, "[STICKY] Accelerometer fault detected");
|
||||||
|
}
|
||||||
|
if (pigeon2.getStickyFault_BootupGyroscope().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "[STICKY] Gyro fault detected");
|
||||||
|
}
|
||||||
|
if (pigeon2.getStickyFault_BootupMagnetometer().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(
|
||||||
|
ReportLevel.ERROR, "[STICKY] Magnetometer fault detected");
|
||||||
|
}
|
||||||
|
if (pigeon2.getStickyFault_DataAcquiredLate().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(
|
||||||
|
ReportLevel.ERROR,
|
||||||
|
String.format(
|
||||||
|
"[STICKY] Motion stack data acquisition slower than expected"));
|
||||||
|
}
|
||||||
|
if (pigeon2.getStickyFault_Hardware().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(
|
||||||
|
ReportLevel.ERROR, "[STICKY] Hardware fault detected");
|
||||||
|
}
|
||||||
|
if (pigeon2.getStickyFault_LoopTimeSlow().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(
|
||||||
|
ReportLevel.ERROR,
|
||||||
|
String.format(
|
||||||
|
"[STICKY] Motion stack loop time was slower than expected"));
|
||||||
|
}
|
||||||
|
if (pigeon2.getStickyFault_SaturatedAccelerometer().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(
|
||||||
|
ReportLevel.ERROR,
|
||||||
|
"[STICKY] Accelerometer values are saturated");
|
||||||
|
}
|
||||||
|
if (pigeon2.getStickyFault_SaturatedGyroscope().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(
|
||||||
|
ReportLevel.ERROR, "[STICKY] Gyro values are saturated");
|
||||||
|
}
|
||||||
|
if (pigeon2.getStickyFault_SaturatedMagnetometer().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(
|
||||||
|
ReportLevel.ERROR,
|
||||||
|
"[STICKY] Magnetometer values are saturated");
|
||||||
|
}
|
||||||
|
if (pigeon2.getStickyFault_Undervoltage().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(
|
||||||
|
ReportLevel.ERROR,
|
||||||
|
"[STICKY] Device supply voltage near brownout");
|
||||||
|
}
|
||||||
|
if (pigeon2.getStickyFault_UnlicensedFeatureInUse().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(
|
||||||
|
ReportLevel.ERROR, "[STICKY] Unlicensed feature in use");
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
package frc4388.utility.status;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.ctre.phoenix6.CANBus;
|
||||||
|
import com.ctre.phoenix6.CANBus.CANBusStatus;
|
||||||
|
|
||||||
|
import frc4388.robot.constants.Constants;
|
||||||
|
import frc4388.utility.status.Status.Report;
|
||||||
|
import frc4388.utility.status.Status.ReportLevel;
|
||||||
|
|
||||||
|
public class FaultReporter {
|
||||||
|
|
||||||
|
private static final String REPORTS_HEADER =
|
||||||
|
"▄▖ ▗ \n" + //
|
||||||
|
"▙▘█▌▛▌▛▌▛▘▜▘▛▘\n" + //
|
||||||
|
"▌▌▙▖▙▌▙▌▌ ▐▖▄▌\n" + //
|
||||||
|
" ▌ ";
|
||||||
|
|
||||||
|
private static final String CAN_HEADER =
|
||||||
|
"▄▖▄▖▖ ▖ \n" + //
|
||||||
|
"▌ ▌▌▛▖▌ \n" + //
|
||||||
|
"▙▖▛▌▌▝▌(t)\n" + //
|
||||||
|
" ";
|
||||||
|
|
||||||
|
private static final String ERROR_HEADER =
|
||||||
|
"▄▖▄▖▄▖▄▖▄▖▄▖\n" + //
|
||||||
|
"▙▖▙▘▙▘▌▌▙▘▚ \n" + //
|
||||||
|
"▙▖▌▌▌▌▙▌▌▌▄▌\n" + //
|
||||||
|
" ";
|
||||||
|
|
||||||
|
private static List<Queryable> queryables = new ArrayList<>();
|
||||||
|
|
||||||
|
public static void startThread() {
|
||||||
|
new Thread() {
|
||||||
|
public void run() {
|
||||||
|
try{
|
||||||
|
while(!this.isInterrupted() && this.isAlive()){
|
||||||
|
Thread.sleep(500);
|
||||||
|
for(int i=0;i<queryables.size(); i++){
|
||||||
|
queryables.get(i).queryStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
// System.out.println("Updated statuses!");
|
||||||
|
|
||||||
|
}
|
||||||
|
}catch(Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void register(Queryable q) {
|
||||||
|
queryables.add(q);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Log(Queryable q, String s){
|
||||||
|
System.out.println(q.getName() + " - " + s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void printReport() {
|
||||||
|
|
||||||
|
List<String> errors = new ArrayList<>();
|
||||||
|
|
||||||
|
// Subsystems header
|
||||||
|
System.out.println(REPORTS_HEADER);
|
||||||
|
|
||||||
|
for(int i=0;i< queryables.size();i++){
|
||||||
|
|
||||||
|
Queryable q = queryables.get(i);
|
||||||
|
System.out.println("** Subsystem diagnostic report for " + q.getName() + ":");
|
||||||
|
Status status = q.diagnosticStatus();
|
||||||
|
|
||||||
|
for(int a=0;a<status.reports.size();a++){
|
||||||
|
Report r = status.reports.get(a);
|
||||||
|
if(r.reportLevel == ReportLevel.ERROR)
|
||||||
|
errors.add(q.getName() + " - " + r.toString());
|
||||||
|
Log(q, r.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// CAN header
|
||||||
|
System.out.println(CAN_HEADER);
|
||||||
|
|
||||||
|
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(ERROR_HEADER);
|
||||||
|
for(int i=0;i<errors.size(); i++){
|
||||||
|
System.out.println(errors.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
package frc4388.utility.status;
|
||||||
|
|
||||||
|
import com.ctre.phoenix6.controls.EmptyControl;
|
||||||
|
import com.ctre.phoenix6.hardware.TalonFX;
|
||||||
|
|
||||||
|
import frc4388.utility.status.Status.ReportLevel;
|
||||||
|
|
||||||
|
public class FaultTalonFX implements Queryable {
|
||||||
|
private String name;
|
||||||
|
private TalonFX motor;
|
||||||
|
|
||||||
|
public static void addDevice(TalonFX motor, String name) {
|
||||||
|
FaultTalonFX p = new FaultTalonFX();
|
||||||
|
|
||||||
|
p.name = name;
|
||||||
|
p.motor = motor;
|
||||||
|
|
||||||
|
FaultReporter.register(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queryStatus() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
// throw new UnsupportedOperationException("Unimplemented method 'queryStatus'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Status diagnosticStatus() {
|
||||||
|
Status s = new Status();
|
||||||
|
|
||||||
|
|
||||||
|
boolean debounceBad = !QueryUtils.isDebounceOk(motor.getSupplyVoltage());
|
||||||
|
boolean emptyControlBad = motor.setControl(new EmptyControl()).value != 0;
|
||||||
|
|
||||||
|
if(debounceBad || emptyControlBad) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "device is unreachable - Failed" +
|
||||||
|
(debounceBad ? " Failed debounce test" : "") +
|
||||||
|
(emptyControlBad ? " Failed empty control test" : "")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
s.addReport(ReportLevel.INFO, "Voltage: " + motor.getSupplyVoltage());
|
||||||
|
s.addReport(ReportLevel.INFO, "Current: " + motor.getSupplyCurrent());
|
||||||
|
s.addReport(ReportLevel.INFO, "Device temp: " + motor.getDeviceTemp());
|
||||||
|
s.addReport(ReportLevel.INFO, "Processor temp: " + motor.getProcessorTemp());
|
||||||
|
s.addReport(ReportLevel.INFO, "Position: " + motor.getPosition());
|
||||||
|
s.addReport(ReportLevel.INFO, "Velocity: " + motor.getVelocity());
|
||||||
|
s.addReport(ReportLevel.INFO, "Acceleration: " + motor.getAcceleration());
|
||||||
|
|
||||||
|
// faults<
|
||||||
|
if (motor.getFault_BootDuringEnable().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "Device booted while enabled");
|
||||||
|
}
|
||||||
|
if (motor.getFault_BridgeBrownout().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "Bridge was disabled most likely due to supply voltage dropping too low");
|
||||||
|
}
|
||||||
|
if (motor.getFault_DeviceTemp().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "Device temperature exceeded limit");
|
||||||
|
}
|
||||||
|
if (motor.getFault_FusedSensorOutOfSync().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "Remote sensor is out of sync");
|
||||||
|
}
|
||||||
|
if (motor.getFault_Hardware().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "Hardware failure detected");
|
||||||
|
}
|
||||||
|
if (motor.getFault_MissingDifferentialFX().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "The remote Talon used for differential control is not present");
|
||||||
|
}
|
||||||
|
if (motor.getFault_MissingHardLimitRemote().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR,"The remote limit switch device is not present");
|
||||||
|
}
|
||||||
|
if (motor.getFault_MissingSoftLimitRemote().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "The remote soft limit device is not present");
|
||||||
|
}
|
||||||
|
if (motor.getFault_OverSupplyV().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "Supply voltage exceeded limit");
|
||||||
|
}
|
||||||
|
if (motor.getFault_ProcTemp().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "Processor temperature exceeded limit");
|
||||||
|
}
|
||||||
|
if (motor.getFault_RemoteSensorDataInvalid().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "The remote sensor's data is no longer trusted");
|
||||||
|
}
|
||||||
|
if (motor.getFault_RemoteSensorPosOverflow().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "remote sensor position has overflowed");
|
||||||
|
}
|
||||||
|
if (motor.getFault_RemoteSensorReset().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "The remote sensor has reset");
|
||||||
|
}
|
||||||
|
if (motor.getFault_Undervoltage().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, " Device supply voltage near brownout");
|
||||||
|
}
|
||||||
|
if (motor.getFault_UnlicensedFeatureInUse().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "Unlicensed feature in use");
|
||||||
|
}
|
||||||
|
if (motor.getFault_UnstableSupplyV().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "Supply voltage is unstable");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// sticky faults
|
||||||
|
if (motor.getStickyFault_BootDuringEnable().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "[STICKY] Device booted while enabled");
|
||||||
|
}
|
||||||
|
if (motor.getStickyFault_BridgeBrownout().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "[STICKY] Bridge was disabled most likely due to supply voltage dropping too low");
|
||||||
|
}
|
||||||
|
if (motor.getStickyFault_DeviceTemp().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "[STICKY] Device temperature exceeded limit");
|
||||||
|
}
|
||||||
|
if (motor.getStickyFault_FusedSensorOutOfSync().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "[STICKY] Remote sensor is out of sync");
|
||||||
|
}
|
||||||
|
if (motor.getStickyFault_Hardware().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "[STICKY] Hardware failure detected");
|
||||||
|
}
|
||||||
|
if (motor.getStickyFault_MissingDifferentialFX().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "[STICKY] The remote Talon used for differential control is not present");
|
||||||
|
}
|
||||||
|
if (motor.getStickyFault_MissingHardLimitRemote().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "[STICKY] The remote limit switch device is not present");
|
||||||
|
}
|
||||||
|
if (motor.getStickyFault_MissingSoftLimitRemote().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "[STICKY] The remote soft limit device is not present");
|
||||||
|
}
|
||||||
|
if (motor.getStickyFault_OverSupplyV().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "[STICKY] Supply voltage exceeded limit");
|
||||||
|
}
|
||||||
|
if (motor.getStickyFault_ProcTemp().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "[STICKY] Processor temperature exceeded limit");
|
||||||
|
}
|
||||||
|
if (motor.getStickyFault_RemoteSensorDataInvalid().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "[STICKY] The remote sensor's data is no longer trusted");
|
||||||
|
}
|
||||||
|
if (motor.getStickyFault_RemoteSensorPosOverflow().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "[STICKY] The remote sensor position has overflowed");
|
||||||
|
}
|
||||||
|
if (motor.getStickyFault_RemoteSensorReset().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "[STICKY] The remote sensor has reset");
|
||||||
|
}
|
||||||
|
if (motor.getStickyFault_Undervoltage().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "[STICKY] Device supply voltage near brownout");
|
||||||
|
}
|
||||||
|
if (motor.getStickyFault_UnlicensedFeatureInUse().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "[STICKY] Unlicensed feature in use");
|
||||||
|
}
|
||||||
|
if (motor.getStickyFault_UnstableSupplyV().getValue() == Boolean.TRUE) {
|
||||||
|
s.addReport(ReportLevel.ERROR, "[STICKY] Supply voltage is unstable");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package frc4388.utility.status;
|
||||||
|
|
||||||
|
import com.ctre.phoenix6.StatusSignal;
|
||||||
|
|
||||||
|
import edu.wpi.first.math.filter.Debouncer;
|
||||||
|
|
||||||
|
public class QueryUtils {
|
||||||
|
public static boolean isDebounceOk(@SuppressWarnings("rawtypes") StatusSignal status) {
|
||||||
|
Debouncer connectedDebounce = new Debouncer(0.5);
|
||||||
|
status.refresh();
|
||||||
|
return connectedDebounce.calculate(status.getStatus().isOK());
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package frc4388.utility.status;
|
||||||
|
|
||||||
|
public interface Queryable {
|
||||||
|
// Get name of subsystem, for use in log.
|
||||||
|
String getName();
|
||||||
|
// Get what the subystem is currently doing, such as "Shooter spun up". This should post to SmartDashboard
|
||||||
|
void queryStatus();
|
||||||
|
// Proactivly search for any errors in each subsystem
|
||||||
|
Status diagnosticStatus();
|
||||||
|
}
|
||||||
@@ -44,6 +44,10 @@ public class Status {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void diagnoseHardwareCTRE(String deviceName, TalonFX motor) {
|
public void diagnoseHardwareCTRE(String deviceName, TalonFX motor) {
|
||||||
|
addReport(ReportLevel.ERROR, deviceName + " Motor (TalonFX) Alive?: " + (motor.isAlive() ? "Alive." : "Dead!"));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (motor.isAlive()) addReport(ReportLevel.INFO, deviceName + " Motor (TalonFX) Alive?: Alive.");
|
if (motor.isAlive()) addReport(ReportLevel.INFO, deviceName + " Motor (TalonFX) Alive?: Alive.");
|
||||||
else addReport(ReportLevel.ERROR, deviceName + " Motor (TalonFX) Alive?: Dead!");
|
else addReport(ReportLevel.ERROR, deviceName + " Motor (TalonFX) Alive?: Dead!");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
package frc4388.utility.status;
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user