Skip to content

Commit f5161c3

Browse files
authored
Completes PID controller preference APIs (#72)
This change brings the API surface of `PIDControllerPreference` and `ProfiledPIDControllerPreference` to parity with the non-deprecated API surface of WPILib. This change also corrects the initialization of the PD controllers to use the current gain preference values.
1 parent 9a5704d commit f5161c3

2 files changed

Lines changed: 327 additions & 138 deletions

File tree

nrgcommon/src/main/java/com/nrg948/preferences/PIDControllerPreference.java

Lines changed: 147 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,16 @@ of this software and associated documentation files (the "Software"), to deal
4040
* implements {@link Sendable} so that its parameters can be exposed to dashboards and other tools.
4141
*/
4242
public class PIDControllerPreference extends PreferenceValue implements Sendable {
43+
private static final double DEFAULT_PERIOD = 0.02;
44+
4345
private final double defaultP;
4446
private final double defaultI;
4547
private final double defaultD;
4648
private final PIDController controller;
4749

4850
/**
49-
* Creates a new PIDControllerPreference with the given group, name, and default PID gains.
51+
* Creates a new PIDControllerPreference with the given group, name, and default PID gains. Uses a
52+
* default period of 0.02 seconds.
5053
*
5154
* @param group The preference group.
5255
* @param name The preference name.
@@ -56,133 +59,149 @@ public class PIDControllerPreference extends PreferenceValue implements Sendable
5659
*/
5760
public PIDControllerPreference(
5861
String group, String name, double defaultP, double defaultI, double defaultD) {
62+
this(group, name, defaultP, defaultI, defaultD, DEFAULT_PERIOD);
63+
}
64+
65+
/**
66+
* Creates a new PIDControllerPreference with the given group, name, default PID gains, and
67+
* period.
68+
*
69+
* @param group The preference group.
70+
* @param name The preference name.
71+
* @param defaultP The default P gain.
72+
* @param defaultI The default I gain.
73+
* @param defaultD The default D gain.
74+
* @param period The period for this controller.
75+
*/
76+
public PIDControllerPreference(
77+
String group, String name, double defaultP, double defaultI, double defaultD, double period) {
5978
super(group, name);
6079
this.defaultP = defaultP;
6180
this.defaultI = defaultI;
6281
this.defaultD = defaultD;
63-
this.controller = new PIDController(defaultP, defaultI, defaultD);
6482

83+
// Initialize preference entries with defaults if they do not already exist.
6584
Preferences.initDouble(getKey() + "/kP", defaultP);
6685
Preferences.initDouble(getKey() + "/kI", defaultI);
6786
Preferences.initDouble(getKey() + "/kD", defaultD);
87+
88+
// Read the effective gains from preferences (existing tuned values or defaults).
89+
double p = Preferences.getDouble(getKey() + "/kP", defaultP);
90+
double i = Preferences.getDouble(getKey() + "/kI", defaultI);
91+
double d = Preferences.getDouble(getKey() + "/kD", defaultD);
92+
93+
// Construct the controller using the stored preference values.
94+
this.controller = new PIDController(p, i, d, period);
6895
}
6996

70-
/**
71-
* Returns the default P value.
72-
*
73-
* @return The default P value.
74-
*/
97+
/** {@return the default proportional gain} */
7598
public double getDefaultP() {
7699
return defaultP;
77100
}
78101

79-
/**
80-
* Returns the current P value.
81-
*
82-
* @return The current P value.
83-
*/
102+
/** {@return the current proportional gain} */
84103
public double getP() {
85104
return Preferences.getDouble(getKey() + "/kP", defaultP);
86105
}
87106

88107
/**
89-
* Sets the P value.
108+
* Sets the proportional gain.
90109
*
91-
* @param p The P value to set.
110+
* @param p The proportional gain to set.
92111
*/
93112
public void setP(double p) {
94113
controller.setP(p);
95114
Preferences.setDouble(getKey() + "/kP", p);
96115
}
97116

98-
/**
99-
* Returns the default I value.
100-
*
101-
* @return The default I value.
102-
*/
117+
/** {@return the default integral gain} */
103118
public double getDefaultI() {
104119
return defaultI;
105120
}
106121

107-
/**
108-
* Returns the current I value.
109-
*
110-
* @return The current I value.
111-
*/
122+
/** {@return the current integral gain} */
112123
public double getI() {
113124
return Preferences.getDouble(getKey() + "/kI", defaultI);
114125
}
115126

116127
/**
117-
* Sets the I value.
128+
* Sets the integral gain.
118129
*
119-
* @param i The I value to set.
130+
* @param i The integral gain to set.
120131
*/
121132
public void setI(double i) {
122133
controller.setI(i);
123134
Preferences.setDouble(getKey() + "/kI", i);
124135
}
125136

126-
/**
127-
* Returns the default D value.
128-
*
129-
* @return The default D value.
130-
*/
137+
/** {@return the default derivative gain} */
131138
public double getDefaultD() {
132139
return defaultD;
133140
}
134141

135-
/**
136-
* Returns the current D value.
137-
*
138-
* @return The current D value.
139-
*/
142+
/** {@return the current derivative gain} */
140143
public double getD() {
141144
return Preferences.getDouble(getKey() + "/kD", defaultD);
142145
}
143146

144147
/**
145-
* Sets the D value.
148+
* Sets the derivative gain.
146149
*
147-
* @param d The D value to set.
150+
* @param d The derivative gain to set.
148151
*/
149152
public void setD(double d) {
150153
controller.setD(d);
151154
Preferences.setDouble(getKey() + "/kD", d);
152155
}
153156

154157
/**
155-
* Returns whether the PID controller is at its setpoint.
158+
* Sets the PID coefficients.
156159
*
157-
* @return True if the PID controller is at its setpoint, false otherwise.
160+
* @param p The proportional gain to set.
161+
* @param i The integral gain to set.
162+
* @param d The derivative gain to set.
158163
*/
159-
public boolean atSetpoint() {
160-
return controller.atSetpoint();
164+
public void setPID(double p, double i, double d) {
165+
controller.setPID(p, i, d);
166+
Preferences.setDouble(getKey() + "/kP", p);
167+
Preferences.setDouble(getKey() + "/kI", i);
168+
Preferences.setDouble(getKey() + "/kD", d);
169+
}
170+
171+
/** {@return the maximum magnitude of the error to allow integral control} */
172+
public double getIZone() {
173+
return controller.getIZone();
161174
}
162175

163176
/**
164-
* Calculates the output of the PID controller for the given measurement.
177+
* Sets the maximum magnitude of the error to allow integral control.
165178
*
166-
* @param measurement The current measurement.
167-
* @return The output of the PID controller.
179+
* @param iZone The IZone to set.
168180
*/
169-
public double calculate(double measurement) {
170-
return controller.calculate(measurement);
181+
public void setIZone(double iZone) {
182+
controller.setIZone(iZone);
171183
}
172184

173185
/**
174-
* Calculates the output of the PID controller for the given measurement and setpoint.
186+
* Sets the minimum and maximum contributions of the integral term.
175187
*
176-
* @param measurement The current measurement.
177-
* @param setpoint The desired setpoint.
178-
* @return The output of the PID controller.
188+
* @param minimumIntegral The minimum integral value.
189+
* @param maximumIntegral The maximum integral value.
179190
*/
180-
public double calculate(double measurement, double setpoint) {
181-
return controller.calculate(measurement, setpoint);
191+
public void setIntegratorRange(double minimumIntegral, double maximumIntegral) {
192+
controller.setIntegratorRange(minimumIntegral, maximumIntegral);
193+
}
194+
195+
/** {@return the period of this controller} */
196+
public double getPeriod() {
197+
return controller.getPeriod();
182198
}
183199

184200
/**
185-
* Enables continuous input for the PID controller.
201+
* Enables continuous input for this controller.
202+
*
203+
* <p>Rather than use the minimum and maximum input as constraints, the controller considers them
204+
* to be the endpoints of a continuous range. This is useful for circular inputs, such as angles.
186205
*
187206
* @param minimumInput The minimum input value.
188207
* @param maximumInput The maximum input value.
@@ -191,27 +210,70 @@ public void enableContinuousInput(double minimumInput, double maximumInput) {
191210
controller.enableContinuousInput(minimumInput, maximumInput);
192211
}
193212

194-
/** Disables continuous input for the PID controller. */
213+
/** Disables continuous input for this controller. */
195214
public void disableContinuousInput() {
196215
controller.disableContinuousInput();
197216
}
198217

199218
/**
200-
* Returns whether continuous input is enabled for the PID controller.
219+
* Returns whether continuous input is enabled for this controller.
201220
*
202-
* @return True if continuous input is enabled, false otherwise.
221+
* @return Returns true if continuous input is enabled, false otherwise.
203222
*/
204223
public boolean isContinuousInputEnabled() {
205224
return controller.isContinuousInputEnabled();
206225
}
207226

208-
/** Resets the PID controller. */
227+
/** Resets this controller. */
209228
public void reset() {
210229
controller.reset();
211230
}
212231

213232
/**
214-
* Sets the setpoint for the PID controller.
233+
* Sets the error which is considered tolerable for use with {@link #atSetpoint()}.
234+
*
235+
* @param errorTolerance The error which is tolerable.
236+
*/
237+
public void setTolerance(double errorTolerance) {
238+
controller.setTolerance(errorTolerance);
239+
}
240+
241+
/**
242+
* Sets the error which is considered tolerable for use with {@link #atSetpoint()}.
243+
*
244+
* @param errorTolerance The error which is tolerable.
245+
* @param errorDerivativeTolerance The error derivative which is tolerable.
246+
*/
247+
public void setTolerance(double errorTolerance, double errorDerivativeTolerance) {
248+
controller.setTolerance(errorTolerance, errorDerivativeTolerance);
249+
}
250+
251+
/** {@return the error tolerance of this controller} */
252+
public double getErrorTolerance() {
253+
return controller.getErrorTolerance();
254+
}
255+
256+
/** {@return the error derivative tolerance of this controller} */
257+
public double getErrorDerivativeTolerance() {
258+
return controller.getErrorDerivativeTolerance();
259+
}
260+
261+
/** {@return the current setpoint of this controller} */
262+
public double getSetpoint() {
263+
return controller.getSetpoint();
264+
}
265+
266+
/**
267+
* Returns whether this controller is at its setpoint.
268+
*
269+
* @return Returns true if this controller is at its setpoint, false otherwise.
270+
*/
271+
public boolean atSetpoint() {
272+
return controller.atSetpoint();
273+
}
274+
275+
/**
276+
* Sets the setpoint for this controller.
215277
*
216278
* @param setpoint The setpoint to set.
217279
*/
@@ -220,22 +282,39 @@ public void setSetpoint(double setpoint) {
220282
}
221283

222284
/**
223-
* Sets the tolerance for the PID controller.
285+
* Calculates the output of this controller for the given measurement.
224286
*
225-
* @param errorTolerance The error which is considered acceptable.
287+
* @param measurement The current measurement.
288+
* @return The output of this controller.
226289
*/
227-
public void setTolerance(double errorTolerance) {
228-
controller.setTolerance(errorTolerance);
290+
public double calculate(double measurement) {
291+
return controller.calculate(measurement);
229292
}
230293

231294
/**
232-
* Sets the tolerance for the PID controller.
295+
* Calculates the output of this controller for the given measurement and setpoint.
233296
*
234-
* @param errorTolerance The error which is considered acceptable.
235-
* @param errorDerivativeTolerance The error derivative which is considered acceptable.
297+
* @param measurement The current measurement.
298+
* @param setpoint The desired setpoint.
299+
* @return The output of this controller.
236300
*/
237-
public void setTolerance(double errorTolerance, double errorDerivativeTolerance) {
238-
controller.setTolerance(errorTolerance, errorDerivativeTolerance);
301+
public double calculate(double measurement, double setpoint) {
302+
return controller.calculate(measurement, setpoint);
303+
}
304+
305+
/** {@return the current error of this controller} */
306+
public double getError() {
307+
return controller.getError();
308+
}
309+
310+
/** {@return the current accumulated error used in the integral calculation of this controller} */
311+
public double getAccumulatedError() {
312+
return controller.getAccumulatedError();
313+
}
314+
315+
/** {@return the current error derivative of this controller} */
316+
public double getErrorDerivative() {
317+
return controller.getErrorDerivative();
239318
}
240319

241320
@Override

0 commit comments

Comments
 (0)