Skip to content

Commit ac10279

Browse files
committed
add simulated swerve
1 parent d886d2f commit ac10279

File tree

6 files changed

+137
-10
lines changed

6 files changed

+137
-10
lines changed

src/main/java/org/codeorange/frc2024/robot/Constants.java

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package org.codeorange.frc2024.robot;
22

33
import edu.wpi.first.math.controller.ArmFeedforward;
4-
import edu.wpi.first.math.controller.SimpleMotorFeedforward;
54
import edu.wpi.first.math.geometry.Translation2d;
65
import edu.wpi.first.math.interpolation.InterpolatingDoubleTreeMap;
76
import edu.wpi.first.math.util.Units;
@@ -11,9 +10,7 @@
1110
import org.codeorange.frc2024.utility.swerve.SecondOrderKinematics;
1211
import org.jetbrains.annotations.NotNull;
1312

14-
import java.io.File;
1513
import java.net.SocketException;
16-
import java.nio.file.Files;
1714

1815
public final class Constants {
1916
//TODO: reorganize this mess
@@ -230,7 +227,7 @@ public static class Ports {
230227

231228
public static final double freeSpeed = 95.81986264394831;
232229
public static final boolean USE_SECOND_ORDER_KINEMATICS = false;
233-
public static final double STEER_MOTOR_POSITION_CONVERSION_FACTOR = 7.0 / 150.0;
230+
public static final double STEER_MOTOR_RTS = 7.0 / 150.0;
234231
public static final double DRIVE_MOTOR_REDUCTION = 9 / 53.125;
235232

236233
public static final double wheelBaseInches = isPrototype() ? 22.75 : 24.25; // not real number, just example

src/main/java/org/codeorange/frc2024/robot/Robot.java

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

88
import com.choreo.lib.ChoreoTrajectory;
99
import com.ctre.phoenix6.SignalLogger;
10+
import com.fasterxml.jackson.databind.Module;
1011
import edu.wpi.first.math.MathUtil;
1112
import edu.wpi.first.math.geometry.Pose2d;
1213
import edu.wpi.first.math.geometry.Rotation2d;
@@ -180,7 +181,7 @@ public void robotInit() {
180181
Logger.addDataReceiver(new NT4Publisher()); // Publish data to NetworkTables
181182
}
182183

183-
drive = new Drive(new ModuleIO() {}, new ModuleIO() {}, new ModuleIO() {}, new ModuleIO() {}, new GyroIO() {});
184+
drive = new Drive(new ModuleIOSim(), new ModuleIOSim(), new ModuleIOSim(), new ModuleIOSim(), new GyroIO() {});
184185
wrist = new Wrist(new WristIO() {});
185186
elevator = new Elevator(new ElevatorIO() {});
186187
shooter = new Shooter(new ShooterIO(){});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package org.codeorange.frc2024.subsystem.drive;
2+
3+
import edu.wpi.first.math.MathUtil;
4+
import edu.wpi.first.math.controller.SimpleMotorFeedforward;
5+
import edu.wpi.first.math.geometry.Rotation2d;
6+
import edu.wpi.first.math.system.plant.DCMotor;
7+
import org.codeorange.frc2024.utility.logging.DCMotorSimAutoLogger;
8+
import org.codeorange.frc2024.utility.simulation.BetterDCMotorSim;
9+
import org.codeorange.frc2024.utility.wpimodified.PIDController;
10+
import org.littletonrobotics.junction.Logger;
11+
12+
import static org.codeorange.frc2024.robot.Constants.*;
13+
14+
public class ModuleIOSim implements ModuleIO {
15+
private final PIDController driveController = new PIDController(SWERVE_DRIVE_GAINS.kP(), SWERVE_DRIVE_GAINS.kI(), SWERVE_DRIVE_GAINS.kD());
16+
private final SimpleMotorFeedforward driveFeedforward = new SimpleMotorFeedforward(SWERVE_DRIVE_GAINS.kS(), SWERVE_DRIVE_GAINS.kV(), SWERVE_DRIVE_GAINS.kA());
17+
private final PIDController steerController = new PIDController(SWERVE_STEER_GAINS.kP(), SWERVE_STEER_GAINS.kI(), SWERVE_STEER_GAINS.kD());
18+
19+
private final BetterDCMotorSim driveSim =
20+
new BetterDCMotorSim(
21+
DCMotor.getKrakenX60Foc(1),
22+
1 / (DRIVE_MOTOR_REDUCTION * SWERVE_METER_PER_ROTATION),
23+
0.025,
24+
driveController,
25+
driveFeedforward);
26+
private final BetterDCMotorSim steerSim =
27+
new BetterDCMotorSim(
28+
DCMotor.getKrakenX60Foc(1),
29+
1 / STEER_MOTOR_RTS,
30+
0.004,
31+
steerController,
32+
new SimpleMotorFeedforward(0,0,0));
33+
private final DCMotorSimAutoLogger driveLogger;
34+
private final DCMotorSimAutoLogger steerLogger;
35+
36+
public ModuleIOSim() {
37+
driveLogger = new DCMotorSimAutoLogger(driveSim);
38+
steerLogger = new DCMotorSimAutoLogger(steerSim);
39+
}
40+
41+
@Override
42+
public void updateInputs(ModuleInputs inputs) {
43+
inputs.driveMotor = driveLogger.log();
44+
inputs.steerMotor = steerLogger.log();
45+
inputs.steerMotorAbsolutePosition = inputs.steerMotor.position;
46+
47+
inputs.odometryTimestamps = new double[] {Logger.getRealTimestamp() * 1e-6};
48+
inputs.odometryDrivePositionsMeters = new double[] {inputs.driveMotor.position};
49+
inputs.odometryTurnPositions = new Rotation2d[] {Rotation2d.fromRotations(inputs.steerMotor.position)};
50+
}
51+
52+
@Override
53+
public void setDriveMotorVoltage(double volts) {
54+
driveSim.setInputVoltage(volts);
55+
}
56+
57+
@Override
58+
public void setSteerMotorVoltage(double volts) {
59+
steerSim.setInputVoltage(volts);
60+
}
61+
62+
@Override
63+
public void setSteerMotorPosition(double position) {
64+
setSteerMotorPosition(position, 0);
65+
}
66+
67+
@Override
68+
public void setSteerMotorPosition(double position, double omega) {
69+
steerSim.setPosition(position, omega * 0);
70+
}
71+
72+
@Override
73+
public void setDriveMotorVelocity(double velocity, double accel) {
74+
driveSim.setVelocity(velocity);
75+
}
76+
77+
@Override
78+
public void setDriveMotorDutyCycle(double dutyCycle) {
79+
setDriveMotorVoltage(12 * dutyCycle);
80+
}
81+
}

src/main/java/org/codeorange/frc2024/subsystem/drive/ModuleIOTalonFX.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public ModuleIOTalonFX(int id) {
102102
steerConfigs.Feedback.FeedbackSensorSource = FeedbackSensorSourceValue.FusedCANcoder;
103103
steerConfigs.Feedback.FeedbackRemoteSensorID = swerveCancoder.getDeviceID();
104104
steerConfigs.Feedback.SensorToMechanismRatio = 1;
105-
steerConfigs.Feedback.RotorToSensorRatio = 1 / STEER_MOTOR_POSITION_CONVERSION_FACTOR;
105+
steerConfigs.Feedback.RotorToSensorRatio = 1 / STEER_MOTOR_RTS;
106106
steerConfigs.MotorOutput.Inverted = InvertedValue.Clockwise_Positive;
107107
steerConfigs.MotorOutput.NeutralMode = NeutralModeValue.Coast;
108108
steerConfigs.MotionMagic.MotionMagicExpo_kV = 0;

src/main/java/org/codeorange/frc2024/utility/logging/DCMotorSimAutoLogger.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public MotorInputs log() {
1717
inputs.CANID = -1;
1818
inputs.position = motorSim.getAngularPositionRotations();
1919
inputs.velocity = motorSim.getAngularVelocityRPM();
20-
inputs.supplyVoltage = 12.5;
20+
inputs.supplyVoltage = 12.0;
2121
inputs.motorVoltage = motorSim.getInputVoltage();
2222
inputs.supplyCurrent = motorSim.getCurrentDrawAmps();
2323
inputs.statorCurrent = motorSim.getCurrentDrawAmps() / (inputs.motorVoltage / 12.5);

src/main/java/org/codeorange/frc2024/utility/simulation/BetterDCMotorSim.java

+51-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,37 @@
11
package org.codeorange.frc2024.utility.simulation;
22

3+
import edu.wpi.first.math.MathUtil;
34
import edu.wpi.first.math.Matrix;
5+
import edu.wpi.first.math.controller.ArmFeedforward;
6+
import edu.wpi.first.math.controller.SimpleMotorFeedforward;
47
import edu.wpi.first.math.numbers.N1;
58
import edu.wpi.first.math.numbers.N2;
69
import edu.wpi.first.math.system.LinearSystem;
710
import edu.wpi.first.math.system.plant.DCMotor;
11+
import edu.wpi.first.math.util.Units;
812
import edu.wpi.first.wpilibj.simulation.DCMotorSim;
13+
import org.codeorange.frc2024.utility.wpimodified.PIDController;
914

1015
/**
11-
* DCMotorSim but stores input voltage because i am lazy
16+
* DCMotorSim but stores input voltage and has built in gain calculation because i am lazy
1217
*/
1318
public class BetterDCMotorSim extends DCMotorSim {
1419
private double inputVoltage = 0;
20+
private PIDController pidController = new PIDController(0, 0, 0);
21+
private SimpleMotorFeedforward feedforward = new SimpleMotorFeedforward(0, 0, 0);
22+
23+
public void setPID(PIDController controller) {
24+
pidController = controller;
25+
}
26+
27+
public void setFeedforward(SimpleMotorFeedforward ff) {
28+
feedforward = ff;
29+
}
30+
31+
public void setGains(PIDController controller, SimpleMotorFeedforward ff) {
32+
setPID(controller);
33+
setFeedforward(ff);
34+
}
1535

1636
public BetterDCMotorSim(LinearSystem<N2, N1, N2> plant, DCMotor gearbox, double gearing) {
1737
super(plant, gearbox, gearing);
@@ -29,13 +49,41 @@ public BetterDCMotorSim(DCMotor gearbox, double gearing, double jKgMetersSquared
2949
super(gearbox, gearing, jKgMetersSquared, measurementStdDevs);
3050
}
3151

52+
public BetterDCMotorSim(DCMotor gearbox, double gearing, double jKgMetersSquared, PIDController pidController, SimpleMotorFeedforward feedforward) {
53+
this(gearbox, gearing, jKgMetersSquared);
54+
this.pidController = pidController;
55+
this.feedforward = feedforward;
56+
}
57+
3258
@Override
3359
public void setInputVoltage(double volts) {
34-
inputVoltage = volts;
35-
setInput(volts);
60+
inputVoltage = MathUtil.clamp(volts, -12, 12);
61+
setInput(inputVoltage);
3662
}
3763

3864
public double getInputVoltage() {
3965
return inputVoltage;
4066
}
67+
68+
public void setPosition(double setpoint) {
69+
setPosition(setpoint, 0);
70+
}
71+
72+
public void setPosition(double setpoint, double ffVolts) {
73+
setInputVoltage(
74+
pidController.calculate(getAngularPositionRotations(), setpoint)
75+
+ ffVolts
76+
);
77+
}
78+
79+
public void setVelocity(double setpoint) {
80+
setInputVoltage(
81+
feedforward.calculate(setpoint)
82+
+ pidController.calculate(getAngularVelocityRPS(), setpoint)
83+
);
84+
}
85+
86+
public double getAngularVelocityRPS() {
87+
return Units.radiansToRotations(getAngularVelocityRadPerSec());
88+
}
4189
}

0 commit comments

Comments
 (0)