Skip to content

Commit ae00ed9

Browse files
committed
Add methods for wrapping a Motor with a simulated motor
1 parent c7181ad commit ae00ed9

1 file changed

Lines changed: 139 additions & 0 deletions

File tree

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
package com.team2813.lib2813.control.motors;
2+
3+
import com.team2813.lib2813.control.ControlMode;
4+
import com.team2813.lib2813.control.Motor;
5+
import com.team2813.lib2813.control.PIDMotor;
6+
import com.team2813.lib2813.robot.PeriodicRegistry;
7+
import com.team2813.lib2813.robot.RobotState;
8+
import edu.wpi.first.math.numbers.N1;
9+
import edu.wpi.first.units.measure.Angle;
10+
import edu.wpi.first.units.measure.Current;
11+
import edu.wpi.first.wpilibj.RobotController;
12+
import edu.wpi.first.wpilibj.simulation.LinearSystemSim;
13+
14+
/** Helper methods for working with simulation for motors. */
15+
public class MotorSimulation {
16+
17+
/**
18+
* Wraps a motor and a simulated motor. The simulated motor will be updated when the motor is
19+
* updated.
20+
*
21+
* @param motor Motor to wrap
22+
* @param periodicRegistry Registry that will be used to register periodic functions
23+
* @param sim Simulation to associate with the motor
24+
* @return Wrapped motor
25+
*/
26+
public static Motor wrap(
27+
Motor motor, PeriodicRegistry periodicRegistry, LinearSystemSim<?, N1, ?> sim) {
28+
if (motor instanceof PIDMotor pidMotor) {
29+
return new PIDMotorWrapper(pidMotor, periodicRegistry, sim);
30+
}
31+
return new MotorWrapper<>(motor, periodicRegistry, sim);
32+
}
33+
34+
/**
35+
* Wraps a pid motor and a simulated motor. The simulated motor will be updated when the motor is
36+
* updated.
37+
*
38+
* @param motor Motor to wrap
39+
* @param periodicRegistry Registry that will be used to register periodic functions
40+
* @param sim Simulation to associate with the motor
41+
* @return Wrapped motor
42+
*/
43+
public static PIDMotor wrap(
44+
PIDMotor motor, PeriodicRegistry periodicRegistry, LinearSystemSim<?, N1, ?> sim) {
45+
return new PIDMotorWrapper(motor, periodicRegistry, sim);
46+
}
47+
48+
private static class MotorWrapper<M extends Motor> implements Motor {
49+
protected final M motor;
50+
private final LinearSystemSim<?, N1, ?> sim;
51+
private long lastSimUpdateTimeMillis = 0;
52+
53+
MotorWrapper(M motor, PeriodicRegistry periodicRegistry, LinearSystemSim<?, N1, ?> sim) {
54+
this.motor = motor;
55+
this.sim = sim;
56+
periodicRegistry.addSimulationPeriodic(this::simulationPeriodic);
57+
}
58+
59+
private void simulationPeriodic(RobotState robotState) {
60+
long currentTimeMicros = RobotController.getFPGATime();
61+
sim.update((currentTimeMicros - lastSimUpdateTimeMillis) / 1000.0);
62+
lastSimUpdateTimeMillis = currentTimeMicros;
63+
}
64+
65+
@Override
66+
public void set(ControlMode mode, double demand) {
67+
motor.set(mode, demand);
68+
sim.setInput(demand);
69+
}
70+
71+
@Override
72+
public void set(ControlMode mode, double demand, double feedForward) {
73+
motor.set(mode, demand, feedForward);
74+
sim.setInput(demand);
75+
}
76+
77+
@Override
78+
public Current getAppliedCurrent() {
79+
return motor.getAppliedCurrent();
80+
}
81+
82+
@Override
83+
public void disable() {
84+
motor.disable();
85+
}
86+
}
87+
88+
private static class PIDMotorWrapper extends MotorWrapper<PIDMotor> implements PIDMotor {
89+
90+
PIDMotorWrapper(
91+
PIDMotor motor, PeriodicRegistry periodicRegistry, LinearSystemSim<?, N1, ?> sim) {
92+
super(motor, periodicRegistry, sim);
93+
}
94+
95+
@Override
96+
public void configPIDF(int slot, double p, double i, double d, double f) {
97+
motor.configPIDF(slot, p, i, d, f);
98+
}
99+
100+
@Override
101+
public void configPIDF(double p, double i, double d, double f) {
102+
motor.configPIDF(p, i, d, f);
103+
}
104+
105+
@Override
106+
public void configPID(int slot, double p, double i, double d) {
107+
motor.configPID(slot, p, i, d);
108+
}
109+
110+
@Override
111+
public void configPID(double p, double i, double d) {
112+
motor.configPID(p, i, d);
113+
}
114+
115+
@Override
116+
public double position() {
117+
return motor.position();
118+
}
119+
120+
@Override
121+
public Angle getPositionMeasure() {
122+
return motor.getPositionMeasure();
123+
}
124+
125+
@Override
126+
public void setPosition(double position) {
127+
motor.setPosition(position);
128+
}
129+
130+
@Override
131+
public double getVelocity() {
132+
return motor.getVelocity();
133+
}
134+
}
135+
136+
private MotorSimulation() {
137+
throw new AssertionError("Not instantiable");
138+
}
139+
}

0 commit comments

Comments
 (0)