Skip to content

Commit 9325f68

Browse files
Misc drive fixes (#6)
* Implement Full Logging and Drivetrain Subsystem (#1) * Da Code * Add alerts on drive spark maxes * Add Config Changes from Meeting * Other lil bs * Add automatic brake disable on robot disable * add odometry * add SIM module * Add DriveCommands * Update RobotContainer.java * Formatting fixes * Misc Fixes * Add low voltage warning for DT * Add velocity scalars for DT * Update PID Coefficents and fix odometry issues * Update URCL.json --------- Fix CI Co-Authored-By: Talon540-root <[email protected]> * Increase voltage warning on battery and add CAN error alert * clean * Fix Modules Falsely Reporting as Disconnected * Cleanup typing, make errors more obvious * Cleanup dashboard setting stuff * Update sim characterization constants to be more accurate, stops a massive overshooting for some reason * Log drive motor temps * Formatting fixes * Inline tuning mode alert --------- Co-authored-by: Talon540-root <[email protected]>
1 parent 93e655d commit 9325f68

13 files changed

+92
-95
lines changed
+25-27
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,47 @@
11
package frc.robot;
22

3-
import edu.wpi.first.wpilibj.DriverStation;
3+
import edu.wpi.first.wpilibj.Alert;
44
import edu.wpi.first.wpilibj.RobotBase;
55

66
public class Constants {
7-
private static RobotType kRobotType = RobotType.ROBOT_2025_COMP;
7+
private static RobotType robotType = RobotType.COMPBOT;
88
// Allows tunable values to be changed when enabled. Also adds tunable selectors to AutoSelector
99
public static final boolean TUNING_MODE = true;
1010
// Disable the AdvantageKit logger from running
1111
public static final boolean ENABLE_LOGGING = true;
1212

1313
public static final double kLoopPeriodSecs = 0.02;
1414

15-
public static final double LOW_VOLTAGE_WARNING_THRESHOLD = 10.0;
16-
17-
public enum RobotMode {
18-
REAL,
19-
SIM,
20-
REPLAY
15+
public static RobotType getRobot() {
16+
if (RobotBase.isReal() && robotType == RobotType.SIMBOT) {
17+
new Alert(
18+
"Invalid robot selected, using competition robot as default.", Alert.AlertType.kError)
19+
.set(true);
20+
robotType = RobotType.COMPBOT;
21+
}
22+
return robotType;
2123
}
2224

23-
public enum RobotType {
24-
ROBOT_2025_COMP,
25-
ROBOT_SIMBOT
25+
public static Mode getMode() {
26+
return switch (robotType) {
27+
case COMPBOT -> RobotBase.isReal() ? Mode.REAL : Mode.REPLAY;
28+
case SIMBOT -> Mode.SIM;
29+
};
2630
}
2731

28-
public static RobotType getRobotType() {
29-
if (RobotBase.isReal() && kRobotType == RobotType.ROBOT_SIMBOT) {
30-
DriverStation.reportError(
31-
"Robot is set to SIM but it isn't a SIM, setting it to Competition Robot as redundancy.",
32-
false);
33-
kRobotType = RobotType.ROBOT_2025_COMP;
34-
}
32+
public enum Mode {
33+
/** Running on a real robot. */
34+
REAL,
3535

36-
if (RobotBase.isSimulation() && kRobotType != RobotType.ROBOT_SIMBOT) {
37-
DriverStation.reportError(
38-
"Robot is set to REAL but it is a SIM, setting it to SIMBOT as redundancy.", false);
39-
kRobotType = RobotType.ROBOT_SIMBOT;
40-
}
36+
/** Running a physics simulator. */
37+
SIM,
4138

42-
return kRobotType;
39+
/** Replaying from a log file. */
40+
REPLAY
4341
}
4442

45-
public static RobotMode getRobotMode() {
46-
if (getRobotType() == RobotType.ROBOT_SIMBOT) return RobotMode.SIM;
47-
else return RobotBase.isReal() ? RobotMode.REAL : RobotMode.REPLAY;
43+
public enum RobotType {
44+
SIMBOT,
45+
COMPBOT
4846
}
4947
}

src/main/java/frc/robot/Robot.java

+17-3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import edu.wpi.first.math.filter.Debouncer;
1717
import edu.wpi.first.wpilibj.Alert;
18+
import edu.wpi.first.wpilibj.Alert.AlertType;
1819
import edu.wpi.first.wpilibj.DriverStation;
1920
import edu.wpi.first.wpilibj.RobotController;
2021
import edu.wpi.first.wpilibj.Threads;
@@ -36,19 +37,26 @@
3637
* project.
3738
*/
3839
public class Robot extends LoggedRobot {
40+
private static final double LOW_VOLTAGE_WARNING_THRESHOLD = 11.75;
41+
3942
private Command autonomousCommand;
4043
private final RobotContainer robotContainer;
4144

45+
// System Alerts
46+
private final Alert canErrorAlert =
47+
new Alert("CAN errors detected, robot may not be controllable.", AlertType.kError);
48+
private final Debouncer canErrorDebouncer = new Debouncer(0.5);
49+
4250
private final Alert lowBatteryVoltageAlert =
4351
new Alert("Battery voltage is too low, change the battery", Alert.AlertType.kWarning);
44-
private final Debouncer batteryVoltageDebouncer = new Debouncer(0.5);
52+
private final Debouncer batteryVoltageDebouncer = new Debouncer(1.5);
4553

4654
public Robot() {
4755
super(Constants.kLoopPeriodSecs);
4856

4957
LoggerUtil.initializeLoggerMetadata();
5058

51-
switch (Constants.getRobotMode()) {
59+
switch (Constants.getMode()) {
5260
case REAL -> {
5361
// Running on a real robot, log to a USB stick
5462
var loggerPath = LoggerUtil.getLogPath();
@@ -92,10 +100,16 @@ public void robotPeriodic() {
92100
// Run command scheduler
93101
CommandScheduler.getInstance().run();
94102

103+
// Check CAN status
104+
var canStatus = RobotController.getCANStatus();
105+
canErrorAlert.set(
106+
canErrorDebouncer.calculate(
107+
canStatus.transmitErrorCount > 0 || canStatus.receiveErrorCount > 0));
108+
95109
// Update Battery Voltage Alert
96110
lowBatteryVoltageAlert.set(
97111
batteryVoltageDebouncer.calculate(
98-
RobotController.getBatteryVoltage() <= Constants.LOW_VOLTAGE_WARNING_THRESHOLD));
112+
RobotController.getBatteryVoltage() <= LOW_VOLTAGE_WARNING_THRESHOLD));
99113

100114
// Return to normal thread priority
101115
Threads.setCurrentThreadPriority(false, 10);

src/main/java/frc/robot/RobotContainer.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import edu.wpi.first.math.geometry.Pose2d;
44
import edu.wpi.first.math.geometry.Rotation2d;
5+
import edu.wpi.first.wpilibj.Alert;
56
import edu.wpi.first.wpilibj2.command.Command;
67
import edu.wpi.first.wpilibj2.command.Commands;
78
import edu.wpi.first.wpilibj2.command.button.CommandXboxController;
@@ -24,7 +25,7 @@ public class RobotContainer {
2425
private final LoggedDashboardChooser<Command> autoChooser;
2526

2627
public RobotContainer() {
27-
switch (Constants.getRobotMode()) {
28+
switch (Constants.getMode()) {
2829
case REAL -> {
2930
driveBase =
3031
new DriveBase(
@@ -58,6 +59,8 @@ public RobotContainer() {
5859
autoChooser = new LoggedDashboardChooser<>("Auto Choices");
5960

6061
if (Constants.TUNING_MODE) {
62+
new Alert("Robot in Tuning Mode", Alert.AlertType.kInfo).set(true);
63+
6164
// Set up Characterization routines
6265
autoChooser.addOption(
6366
"Drive Wheel Radius Characterization",

src/main/java/frc/robot/commands/DriveCommands.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,22 @@
1515
import frc.robot.subsystems.drive.DriveBase;
1616
import frc.robot.subsystems.drive.DriveConstants;
1717
import frc.robot.util.AllianceFlipUtil;
18-
import frc.robot.util.LoggedTunableNumber;
1918
import java.text.DecimalFormat;
2019
import java.text.NumberFormat;
2120
import java.util.LinkedList;
2221
import java.util.List;
2322
import java.util.function.DoubleSupplier;
2423
import java.util.function.Supplier;
24+
import org.littletonrobotics.junction.networktables.LoggedNetworkNumber;
2525

2626
public class DriveCommands {
2727
// Drive
2828
private static final double DEADBAND = 0.1;
2929

30-
private static final LoggedTunableNumber LINEAR_VELOCITY_SCALAR =
31-
new LoggedTunableNumber("TeleopDrive/LinearVelocityScalar", 1.0, true);
32-
private static final LoggedTunableNumber ANGULAR_VELOCITY_SCALAR =
33-
new LoggedTunableNumber("TeleopDrive/AngularVelocityScalar", 1.0, true);
30+
private static final LoggedNetworkNumber LINEAR_VELOCITY_SCALAR =
31+
new LoggedNetworkNumber("TeleopDrive/LinearVelocityScalar", 1.0);
32+
private static final LoggedNetworkNumber ANGULAR_VELOCITY_SCALAR =
33+
new LoggedNetworkNumber("TeleopDrive/AngularVelocityScalar", 0.7);
3434

3535
private static final double ANGLE_KP = 5.0;
3636
private static final double ANGLE_KD = 0.4;
@@ -66,6 +66,7 @@ public static Command joystickDrive(
6666
// Generate robot relative speeds
6767
double linearVelocityScalar = LINEAR_VELOCITY_SCALAR.get();
6868
double angularVelocityScalar = ANGULAR_VELOCITY_SCALAR.get();
69+
6970
var speeds =
7071
new ChassisSpeeds(
7172
x * DriveConstants.maxLinearVelocityMetersPerSec * linearVelocityScalar,

src/main/java/frc/robot/subsystems/drive/DriveBase.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,7 @@ public void periodic() {
154154
}
155155

156156
// Update gyro alert
157-
gyroDisconnectedAlert.set(
158-
!m_gyroInputs.connected && Constants.getRobotMode() != Constants.RobotMode.SIM);
157+
gyroDisconnectedAlert.set(!m_gyroInputs.connected && Constants.getMode() != Constants.Mode.SIM);
159158
}
160159

161160
/** Set brake mode to {@code enabled} doesn't change brake mode if already set. */

src/main/java/frc/robot/subsystems/drive/DriveConstants.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
public class DriveConstants {
1111
public static final double odometryFrequencyHz =
12-
Constants.getRobotMode() == Constants.RobotMode.SIM ? 50 : 250;
12+
Constants.getMode() == Constants.Mode.SIM ? 50 : 250;
1313

1414
public static final double trackWidthX = Units.inchesToMeters(20.75);
1515
public static final double trackWidthY = Units.inchesToMeters(20.75);

src/main/java/frc/robot/subsystems/drive/Module.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ public class Module {
2424
private static final LoggedTunableNumber turnkD = new LoggedTunableNumber("Drive/Module/TurnkD");
2525

2626
static {
27-
switch (Constants.getRobotType()) {
28-
case ROBOT_2025_COMP -> {
27+
switch (Constants.getRobot()) {
28+
case COMPBOT -> {
2929
drivekS.initDefault(0.19700);
3030
drivekV.initDefault(0.12941);
3131
drivekP.initDefault(0.005);
@@ -34,8 +34,8 @@ public class Module {
3434
turnkD.initDefault(0.05);
3535
}
3636
default -> {
37-
drivekS.initDefault(0.11400);
38-
drivekV.initDefault(0.84144);
37+
drivekS.initDefault(0.113190);
38+
drivekV.initDefault(0.841640);
3939
drivekP.initDefault(0.1);
4040
drivekD.initDefault(0.0);
4141
turnkP.initDefault(10.0);

src/main/java/frc/robot/subsystems/drive/ModuleIO.java

+2
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@ public static class ModuleIOInputs {
1111
public double driveVelocityRadPerSec = 0.0;
1212
public double driveAppliedVolts = 0.0;
1313
public double driveCurrentAmps = 0.0;
14+
public double driveTemperatureCelsius = 0.0;
1415

1516
public boolean turnConnected = false;
1617
public Rotation2d turnAbsolutePosition = new Rotation2d();
1718
public Rotation2d turnPosition = new Rotation2d();
1819
public double turnVelocityRadPerSec = 0.0;
1920
public double turnAppliedVolts = 0.0;
2021
public double turnCurrentAmps = 0.0;
22+
public double turnTemperatureCelsius = 0.0;
2123

2224
public double[] odometryDrivePositionsRad = new double[] {};
2325
public Rotation2d[] odometryTurnPositions = new Rotation2d[] {};

src/main/java/frc/robot/subsystems/drive/ModuleIOSpark.java

+7-5
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,13 @@ public class ModuleIOSpark implements ModuleIO {
4646
private final Debouncer turnConnectedDebounce = new Debouncer(0.5);
4747

4848
public ModuleIOSpark(int index) {
49-
switch (Constants.getRobotType()) {
50-
case ROBOT_2025_COMP -> {
49+
switch (Constants.getRobot()) {
50+
case COMPBOT -> {
5151
config = moduleConfigs[index];
5252
}
5353
default ->
5454
throw new IllegalStateException(
55-
"Unexpected RobotType for Spark Module: " + Constants.getRobotType());
55+
"Unexpected RobotType for Spark Module: " + Constants.getRobot());
5656
}
5757

5858
// Initialize Hardware Devices
@@ -134,15 +134,17 @@ public void updateInputs(ModuleIOInputs inputs) {
134134
inputs.driveVelocityRadPerSec = driveEncoder.getVelocity();
135135
inputs.driveAppliedVolts = driveSpark.getAppliedOutput() * driveSpark.getBusVoltage();
136136
inputs.driveCurrentAmps = driveSpark.getOutputCurrent();
137+
inputs.driveTemperatureCelsius = driveSpark.getMotorTemperature();
137138

138139
inputs.turnAbsolutePosition = getOffsetAbsoluteAngle();
139140
inputs.turnPosition = Rotation2d.fromRadians(turnEncoder.getPosition());
140141
inputs.turnVelocityRadPerSec = turnEncoder.getVelocity();
141142
inputs.turnAppliedVolts = turnSpark.getAppliedOutput() * turnSpark.getBusVoltage();
142143
inputs.turnCurrentAmps = turnSpark.getOutputCurrent();
144+
inputs.turnTemperatureCelsius = turnSpark.getMotorTemperature();
143145

144-
inputs.driveConnected = driveConnectedDebounce.calculate(driveSpark.hasActiveFault());
145-
inputs.turnConnected = turnConnectedDebounce.calculate(turnSpark.hasActiveFault());
146+
inputs.driveConnected = driveConnectedDebounce.calculate(!driveSpark.hasActiveFault());
147+
inputs.turnConnected = turnConnectedDebounce.calculate(!turnSpark.hasActiveFault());
146148

147149
inputs.odometryDrivePositionsRad =
148150
drivePositionQueue.stream().mapToDouble((Double value) -> value).toArray();

src/main/java/frc/robot/util/EqualsUtil.java

+6
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,11 @@ public static boolean epsilonEquals(Twist2d twist, Twist2d other) {
1818
&& EqualsUtil.epsilonEquals(twist.dy, other.dy)
1919
&& EqualsUtil.epsilonEquals(twist.dtheta, other.dtheta);
2020
}
21+
22+
public static boolean equalsZero(Twist2d twist) {
23+
return EqualsUtil.epsilonEquals(twist.dx, 0.0)
24+
&& EqualsUtil.epsilonEquals(twist.dy, 0.0)
25+
&& EqualsUtil.epsilonEquals(twist.dtheta, 0.0);
26+
}
2127
}
2228
}

src/main/java/frc/robot/util/LoggedTunableNumber.java

+3-28
Original file line numberDiff line numberDiff line change
@@ -20,38 +20,13 @@ public class LoggedTunableNumber {
2020

2121
private LoggedNetworkNumber dashboardNumber;
2222

23-
private final boolean ntPubEnabled;
24-
25-
/**
26-
* Create a new LoggedTunableNumber
27-
*
28-
* @param dashboardKey Key on dashboard
29-
* @param alwaysEnabled Always publish modifiers to NT, even if not in Tuning Mode
30-
*/
31-
public LoggedTunableNumber(String dashboardKey, boolean alwaysEnabled) {
32-
this.key = tableKey + "/" + dashboardKey;
33-
this.ntPubEnabled = alwaysEnabled;
34-
}
35-
3623
/**
3724
* Create a new LoggedTunableNumber
3825
*
3926
* @param dashboardKey Key on dashboard
4027
*/
4128
public LoggedTunableNumber(String dashboardKey) {
42-
this(dashboardKey, Constants.TUNING_MODE);
43-
}
44-
45-
/**
46-
* Create a new LoggedTunableNumber with the default value
47-
*
48-
* @param dashboardKey Key on dashboard
49-
* @param defaultValue Default value
50-
* @param alwaysEnabled Always publish modifiers to NT, even if not in Tuning Mode
51-
*/
52-
public LoggedTunableNumber(String dashboardKey, double defaultValue, boolean alwaysEnabled) {
53-
this(dashboardKey, alwaysEnabled);
54-
initDefault(defaultValue);
29+
this.key = tableKey + "/" + dashboardKey;
5530
}
5631

5732
/**
@@ -80,7 +55,7 @@ public void initDefault(double defaultValue) {
8055
}
8156

8257
this.defaultValue = defaultValue;
83-
if (ntPubEnabled) {
58+
if (Constants.TUNING_MODE) {
8459
dashboardNumber = new LoggedNetworkNumber(key, defaultValue);
8560
}
8661
}
@@ -99,7 +74,7 @@ public double get() {
9974
key));
10075
}
10176

102-
return ntPubEnabled ? dashboardNumber.get() : defaultValue;
77+
return Constants.TUNING_MODE ? dashboardNumber.get() : defaultValue;
10378
}
10479

10580
/**

src/main/java/frc/robot/util/LoggerUtil.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public class LoggerUtil {
1111
/** Initialize the Logger with the auto-generated data from the build. */
1212
public static void initializeLoggerMetadata() {
1313
// Record metadata from generated state file.
14-
Logger.recordMetadata("ROBOT_NAME", Constants.getRobotType().toString());
14+
Logger.recordMetadata("ROBOT_NAME", Constants.getRobot().toString());
1515
Logger.recordMetadata("RUNTIME_ENVIRONMENT", RobotBase.getRuntimeType().toString());
1616
Logger.recordMetadata("TUNING_MODE", Boolean.toString(Constants.TUNING_MODE));
1717
Logger.recordMetadata("PROJECT_NAME", BuildConstants.MAVEN_NAME);

0 commit comments

Comments
 (0)