Skip to content
This repository was archived by the owner on Jan 17, 2026. It is now read-only.

Commit 089306d

Browse files
committed
Use ctre sim for swerve
Signed-off-by: Jade Turner <[email protected]>
1 parent e446b85 commit 089306d

File tree

4 files changed

+40
-111
lines changed

4 files changed

+40
-111
lines changed

src/main/java/org/curtinfrc/frc2025/Constants.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* (log replay from a file).
1616
*/
1717
public final class Constants {
18-
public static final RobotType robotType = RobotType.COMPBOT;
18+
public static final RobotType robotType = RobotType.SIMBOT;
1919
public static final double ROBOT_X = 0.705;
2020
public static final double ROBOT_Y = 0.730;
2121
public static final double FIELD_LENGTH = aprilTagLayout.getFieldLength();

src/main/java/org/curtinfrc/frc2025/generated/CompTunerConstants.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,11 @@ public class CompTunerConstants {
9494
private static final int kPigeonId = 0;
9595

9696
// These are only used for simulation
97-
private static final MomentOfInertia kSteerInertia = KilogramSquareMeters.of(0.01);
98-
private static final MomentOfInertia kDriveInertia = KilogramSquareMeters.of(0.01);
97+
private static final MomentOfInertia kSteerInertia = KilogramSquareMeters.of(1);
98+
private static final MomentOfInertia kDriveInertia = KilogramSquareMeters.of(0.1);
9999
// Simulated voltage necessary to overcome friction
100100
private static final Voltage kSteerFrictionVoltage = Volts.of(0.2);
101-
private static final Voltage kDriveFrictionVoltage = Volts.of(0.2);
101+
private static final Voltage kDriveFrictionVoltage = Volts.of(0.4);
102102

103103
public static final SwerveDrivetrainConstants DrivetrainConstants =
104104
new SwerveDrivetrainConstants()
Lines changed: 32 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,138 +1,67 @@
1-
// Copyright 2021-2024 FRC 6328
2-
// http://github.com/Mechanical-Advantage
3-
//
4-
// This program is free software; you can redistribute it and/or
5-
// modify it under the terms of the GNU General Public License
6-
// version 3 as published by the Free Software Foundation or
7-
// available in the root directory of this project.
8-
//
9-
// This program is distributed in the hope that it will be useful,
10-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12-
// GNU General Public License for more details.
13-
141
package org.curtinfrc.frc2025.subsystems.drive;
152

163
import com.ctre.phoenix6.swerve.SwerveModuleConstants;
17-
import edu.wpi.first.math.MathUtil;
18-
import edu.wpi.first.math.controller.PIDController;
19-
import edu.wpi.first.math.geometry.Rotation2d;
204
import edu.wpi.first.math.system.plant.DCMotor;
215
import edu.wpi.first.math.system.plant.LinearSystemId;
22-
import edu.wpi.first.math.util.Units;
23-
import edu.wpi.first.wpilibj.Timer;
246
import edu.wpi.first.wpilibj.simulation.DCMotorSim;
257

26-
/**
27-
* Physics sim implementation of module IO. The sim models are configured using a set of module
28-
* constants from Phoenix. Simulation is always based on voltage control.
29-
*/
30-
public class ModuleIOSim implements ModuleIO {
31-
// TunerConstants doesn't support separate sim constants, so they are declared locally
32-
private static final double DRIVE_KP = 0.05;
33-
private static final double DRIVE_KD = 0.0;
34-
private static final double DRIVE_KS = 0.0;
35-
private static final double DRIVE_KV_ROT =
36-
0.91035; // Same units as TunerConstants: (volt * secs) / rotation
37-
private static final double DRIVE_KV = 1.0 / Units.rotationsToRadians(1.0 / DRIVE_KV_ROT);
38-
private static final double TURN_KP = 8.0;
39-
private static final double TURN_KD = 0.0;
8+
public class ModuleIOSim extends ModuleIOTalonFX {
409
private static final DCMotor DRIVE_GEARBOX = DCMotor.getKrakenX60Foc(1);
41-
private static final DCMotor TURN_GEARBOX = DCMotor.getKrakenX60Foc(1);
10+
private static final DCMotor TURN_GEARBOX = DCMotor.getKrakenX60(1);
4211

4312
private final DCMotorSim driveSim;
44-
private final DCMotorSim turnSim;
45-
46-
private boolean driveClosedLoop = false;
47-
private boolean turnClosedLoop = false;
48-
private PIDController driveController = new PIDController(DRIVE_KP, 0, DRIVE_KD);
49-
private PIDController turnController = new PIDController(TURN_KP, 0, TURN_KD);
50-
private double driveFFVolts = 0.0;
51-
private double driveAppliedVolts = 0.0;
52-
private double turnAppliedVolts = 0.0;
13+
private final DCMotorSim steerSim;
5314

5415
public ModuleIOSim(SwerveModuleConstants constants) {
55-
// Create drive and turn sim models
16+
super(constants);
17+
// Create drive and steer sim models
5618
driveSim =
5719
new DCMotorSim(
5820
LinearSystemId.createDCMotorSystem(
5921
DRIVE_GEARBOX, constants.DriveInertia, constants.DriveMotorGearRatio),
6022
DRIVE_GEARBOX);
61-
turnSim =
23+
steerSim =
6224
new DCMotorSim(
6325
LinearSystemId.createDCMotorSystem(
6426
TURN_GEARBOX, constants.SteerInertia, constants.SteerMotorGearRatio),
6527
TURN_GEARBOX);
66-
67-
// Enable wrapping for turn PID
68-
turnController.enableContinuousInput(-Math.PI, Math.PI);
6928
}
7029

71-
@Override
72-
public void updateInputs(ModuleIOInputs inputs) {
73-
// Run closed-loop control
74-
if (driveClosedLoop) {
75-
driveAppliedVolts =
76-
driveFFVolts + driveController.calculate(driveSim.getAngularVelocityRadPerSec());
77-
} else {
78-
driveController.reset();
79-
}
80-
if (turnClosedLoop) {
81-
turnAppliedVolts = turnController.calculate(turnSim.getAngularPositionRad());
82-
} else {
83-
turnController.reset();
84-
}
85-
86-
// Update simulation state
87-
driveSim.setInputVoltage(MathUtil.clamp(driveAppliedVolts, -12.0, 12.0));
88-
turnSim.setInputVoltage(MathUtil.clamp(turnAppliedVolts, -12.0, 12.0));
89-
driveSim.update(0.02);
90-
turnSim.update(0.02);
91-
92-
// Update drive inputs
93-
inputs.driveConnected = true;
94-
inputs.drivePositionRad = driveSim.getAngularPositionRad();
95-
inputs.driveVelocityRadPerSec = driveSim.getAngularVelocityRadPerSec();
96-
inputs.driveAppliedVolts = driveAppliedVolts;
97-
inputs.driveCurrentAmps = Math.abs(driveSim.getCurrentDrawAmps());
98-
99-
// Update turn inputs
100-
inputs.turnConnected = true;
101-
inputs.turnEncoderConnected = true;
102-
inputs.turnAbsolutePosition = new Rotation2d(turnSim.getAngularPositionRad());
103-
inputs.turnPosition = new Rotation2d(turnSim.getAngularPositionRad());
104-
inputs.turnVelocityRadPerSec = turnSim.getAngularVelocityRadPerSec();
105-
inputs.turnAppliedVolts = turnAppliedVolts;
106-
inputs.turnCurrentAmps = Math.abs(turnSim.getCurrentDrawAmps());
30+
private double driveOutput(double raw) {
31+
return raw * constants.DriveMotorGearRatio;
32+
}
10733

108-
// Update odometry inputs (50Hz because high-frequency odometry in sim doesn't matter)
109-
inputs.odometryTimestamps = new double[] {Timer.getFPGATimestamp()};
110-
inputs.odometryDrivePositionsRad = new double[] {inputs.drivePositionRad};
111-
inputs.odometryTurnPositions = new Rotation2d[] {inputs.turnPosition};
34+
private double driveVoltage(double raw) {
35+
return (Math.abs(raw) > constants.DriveFrictionVoltage) ? raw : 0;
11236
}
11337

114-
@Override
115-
public void setDriveOpenLoop(double output) {
116-
driveClosedLoop = false;
117-
driveAppliedVolts = output;
38+
private double steerOutput(double raw) {
39+
return (constants.SteerMotorInverted ? -raw : raw) * constants.SteerMotorGearRatio;
11840
}
11941

120-
@Override
121-
public void setTurnOpenLoop(double output) {
122-
turnClosedLoop = false;
123-
turnAppliedVolts = output;
42+
private double steerVoltage(double raw) {
43+
return (Math.abs(raw) > constants.SteerFrictionVoltage) ? raw : 0;
12444
}
12545

126-
@Override
127-
public void setDriveVelocity(double velocityRadPerSec, double feedforward) {
128-
driveClosedLoop = true;
129-
driveFFVolts = DRIVE_KS * Math.signum(velocityRadPerSec) + DRIVE_KV * velocityRadPerSec;
130-
driveController.setSetpoint(velocityRadPerSec);
46+
private void updateSimState(double dt) {
47+
var driveSimState = driveTalon.getSimState();
48+
driveSim.setInputVoltage(driveVoltage(driveSimState.getMotorVoltage()));
49+
driveSim.update(dt);
50+
driveSimState.setRawRotorPosition(driveOutput(driveSim.getAngularPositionRotations()));
51+
driveSimState.setRotorVelocity(driveOutput(driveSim.getAngularVelocityRPM() / 60));
52+
53+
var steerSimState = turnTalon.getSimState();
54+
var encoderSimState = cancoder.getSimState();
55+
steerSim.setInputVoltage(steerVoltage(steerSimState.getMotorVoltage()));
56+
steerSim.update(dt);
57+
encoderSimState.setRawPosition(-steerSim.getAngularPositionRotations());
58+
steerSimState.setRawRotorPosition(steerOutput(steerSim.getAngularPositionRotations()));
59+
steerSimState.setRotorVelocity(steerOutput(steerSim.getAngularVelocityRPM() / 60));
13160
}
13261

13362
@Override
134-
public void setTurnPosition(Rotation2d rotation) {
135-
turnClosedLoop = true;
136-
turnController.setSetpoint(rotation.getRadians());
63+
public void updateInputs(ModuleIOInputs inputs) {
64+
super.updateInputs(inputs);
65+
updateSimState(0.02);
13766
}
13867
}

src/main/java/org/curtinfrc/frc2025/subsystems/drive/ModuleIOTalonFX.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,14 @@
3939
* <p>Device configuration and other behaviors not exposed by TunerConstants can be customized here.
4040
*/
4141
public class ModuleIOTalonFX implements ModuleIO {
42-
private final SwerveModuleConstants<
42+
protected final SwerveModuleConstants<
4343
TalonFXConfiguration, TalonFXConfiguration, CANcoderConfiguration>
4444
constants;
4545

4646
// Hardware objects
47-
private final TalonFX driveTalon;
48-
private final TalonFX turnTalon;
49-
private final CANcoder cancoder;
47+
protected final TalonFX driveTalon;
48+
protected final TalonFX turnTalon;
49+
protected final CANcoder cancoder;
5050

5151
// Voltage control requests
5252
private final VoltageOut voltageRequest = new VoltageOut(0).withEnableFOC(true);

0 commit comments

Comments
 (0)