Skip to content

Commit e9ab0c4

Browse files
padalevmtilda
authored andcommitted
Added dt handover
1 parent 55f0ee2 commit e9ab0c4

File tree

1 file changed

+31
-31
lines changed

1 file changed

+31
-31
lines changed

src/lib.rs

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -210,12 +210,12 @@ where
210210
self
211211
}
212212

213-
/// Given a new measurement, calculates the next [control output](ControlOutput).
213+
/// Given a new measurement and dt, calculates the next [control output](ControlOutput).
214214
///
215215
/// # Panics
216216
///
217217
/// - If a setpoint has not been set via `update_setpoint()`.
218-
pub fn next_control_output(&mut self, measurement: T) -> ControlOutput<T> {
218+
pub fn next_control_output(&mut self, measurement: T, dt: T) -> ControlOutput<T> {
219219
// Calculate the error between the ideal setpoint and the current
220220
// measurement to compare against
221221
let error = self.setpoint - measurement;
@@ -229,7 +229,7 @@ where
229229
// just the error (no ki), because we support ki changing dynamically,
230230
// we store the entire term so that we don't need to remember previous
231231
// ki values.
232-
self.integral_term = self.integral_term + error * self.ki;
232+
self.integral_term = self.integral_term + error * self.ki * dt;
233233

234234
// Mitigate integral windup: Don't want to keep building up error
235235
// beyond what i_limit will allow.
@@ -240,7 +240,7 @@ where
240240
let d_unbounded = -match self.prev_measurement.as_ref() {
241241
Some(prev_measurement) => measurement - *prev_measurement,
242242
None => T::zero(),
243-
} * self.kd;
243+
} * self.kd / dt;
244244
self.prev_measurement = Some(measurement);
245245
let d = apply_limit(self.d_limit, d_unbounded);
246246

@@ -290,11 +290,11 @@ mod tests {
290290
assert_eq!(pid.setpoint, 10.0);
291291

292292
// Test simple proportional
293-
assert_eq!(pid.next_control_output(0.0).output, 20.0);
293+
assert_eq!(pid.next_control_output(0.0,1.0).output, 20.0);
294294

295295
// Test proportional limit
296296
pid.p_limit = 10.0;
297-
assert_eq!(pid.next_control_output(0.0).output, 10.0);
297+
assert_eq!(pid.next_control_output(0.0,1.0).output, 10.0);
298298
}
299299

300300
/// Derivative-only controller operation and limits
@@ -304,14 +304,14 @@ mod tests {
304304
pid.p(0.0, 100.0).i(0.0, 100.0).d(2.0, 100.0);
305305

306306
// Test that there's no derivative since it's the first measurement
307-
assert_eq!(pid.next_control_output(0.0).output, 0.0);
307+
assert_eq!(pid.next_control_output(0.0,1.0).output, 0.0);
308308

309309
// Test that there's now a derivative
310-
assert_eq!(pid.next_control_output(5.0).output, -10.0);
310+
assert_eq!(pid.next_control_output(5.0,1.0).output, -10.0);
311311

312312
// Test derivative limit
313313
pid.d_limit = 5.0;
314-
assert_eq!(pid.next_control_output(10.0).output, -5.0);
314+
assert_eq!(pid.next_control_output(10.0,1.0).output, -5.0);
315315
}
316316

317317
/// Integral-only controller operation and limits
@@ -321,26 +321,26 @@ mod tests {
321321
pid.p(0.0, 100.0).i(2.0, 100.0).d(0.0, 100.0);
322322

323323
// Test basic integration
324-
assert_eq!(pid.next_control_output(0.0).output, 20.0);
325-
assert_eq!(pid.next_control_output(0.0).output, 40.0);
326-
assert_eq!(pid.next_control_output(5.0).output, 50.0);
324+
assert_eq!(pid.next_control_output(0.0,1.0).output, 20.0);
325+
assert_eq!(pid.next_control_output(0.0,1.0).output, 40.0);
326+
assert_eq!(pid.next_control_output(5.0,1.0).output, 50.0);
327327

328328
// Test limit
329329
pid.i_limit = 50.0;
330-
assert_eq!(pid.next_control_output(5.0).output, 50.0);
330+
assert_eq!(pid.next_control_output(5.0,1.0).output, 50.0);
331331
// Test that limit doesn't impede reversal of error integral
332-
assert_eq!(pid.next_control_output(15.0).output, 40.0);
332+
assert_eq!(pid.next_control_output(15.0,1.0).output, 40.0);
333333

334334
// Test that error integral accumulates negative values
335335
let mut pid2 = Pid::new(-10.0, 100.0);
336336
pid2.p(0.0, 100.0).i(2.0, 100.0).d(0.0, 100.0);
337-
assert_eq!(pid2.next_control_output(0.0).output, -20.0);
338-
assert_eq!(pid2.next_control_output(0.0).output, -40.0);
337+
assert_eq!(pid2.next_control_output(0.0,1.0).output, -20.0);
338+
assert_eq!(pid2.next_control_output(0.0,1.0).output, -40.0);
339339

340340
pid2.i_limit = 50.0;
341-
assert_eq!(pid2.next_control_output(-5.0).output, -50.0);
341+
assert_eq!(pid2.next_control_output(-5.0,1.0).output, -50.0);
342342
// Test that limit doesn't impede reversal of error integral
343-
assert_eq!(pid2.next_control_output(-15.0).output, -40.0);
343+
assert_eq!(pid2.next_control_output(-15.0,1.0).output, -40.0);
344344
}
345345

346346
/// Checks that a full PID controller's limits work properly through multiple output iterations
@@ -349,11 +349,11 @@ mod tests {
349349
let mut pid = Pid::new(10.0, 1.0);
350350
pid.p(1.0, 100.0).i(0.0, 100.0).d(0.0, 100.0);
351351

352-
let out = pid.next_control_output(0.0);
352+
let out = pid.next_control_output(0.0,1.0);
353353
assert_eq!(out.p, 10.0); // 1.0 * 10.0
354354
assert_eq!(out.output, 1.0);
355355

356-
let out = pid.next_control_output(20.0);
356+
let out = pid.next_control_output(20.0,1.0);
357357
assert_eq!(out.p, -10.0); // 1.0 * (10.0 - 20.0)
358358
assert_eq!(out.output, -1.0);
359359
}
@@ -364,25 +364,25 @@ mod tests {
364364
let mut pid = Pid::new(10.0, 100.0);
365365
pid.p(1.0, 100.0).i(0.1, 100.0).d(1.0, 100.0);
366366

367-
let out = pid.next_control_output(0.0);
367+
let out = pid.next_control_output(0.0,1.0);
368368
assert_eq!(out.p, 10.0); // 1.0 * 10.0
369369
assert_eq!(out.i, 1.0); // 0.1 * 10.0
370370
assert_eq!(out.d, 0.0); // -(1.0 * 0.0)
371371
assert_eq!(out.output, 11.0);
372372

373-
let out = pid.next_control_output(5.0);
373+
let out = pid.next_control_output(5.0,1.0);
374374
assert_eq!(out.p, 5.0); // 1.0 * 5.0
375375
assert_eq!(out.i, 1.5); // 0.1 * (10.0 + 5.0)
376376
assert_eq!(out.d, -5.0); // -(1.0 * 5.0)
377377
assert_eq!(out.output, 1.5);
378378

379-
let out = pid.next_control_output(11.0);
379+
let out = pid.next_control_output(11.0,1.0);
380380
assert_eq!(out.p, -1.0); // 1.0 * -1.0
381381
assert_eq!(out.i, 1.4); // 0.1 * (10.0 + 5.0 - 1)
382382
assert_eq!(out.d, -6.0); // -(1.0 * 6.0)
383383
assert_eq!(out.output, -5.6);
384384

385-
let out = pid.next_control_output(10.0);
385+
let out = pid.next_control_output(10.0,1.0);
386386
assert_eq!(out.p, 0.0); // 1.0 * 0.0
387387
assert_eq!(out.i, 1.4); // 0.1 * (10.0 + 5.0 - 1.0 + 0.0)
388388
assert_eq!(out.d, 1.0); // -(1.0 * -1.0)
@@ -401,8 +401,8 @@ mod tests {
401401

402402
for _ in 0..5 {
403403
assert_eq!(
404-
pid_f32.next_control_output(0.0).output,
405-
pid_f64.next_control_output(0.0).output as f32
404+
pid_f32.next_control_output(0.0,1.0).output,
405+
pid_f64.next_control_output(0.0,1.0).output as f32
406406
);
407407
}
408408
}
@@ -419,8 +419,8 @@ mod tests {
419419

420420
for _ in 0..5 {
421421
assert_eq!(
422-
pid_i32.next_control_output(0).output,
423-
pid_i8.next_control_output(0i8).output as i32
422+
pid_i32.next_control_output(0,1).output,
423+
pid_i8.next_control_output(0i8,1i8).output as i32
424424
);
425425
}
426426
}
@@ -431,7 +431,7 @@ mod tests {
431431
let mut pid = Pid::new(10.0, 100.0);
432432
pid.p(1.0, 100.0).i(0.1, 100.0).d(1.0, 100.0);
433433

434-
let out = pid.next_control_output(0.0);
434+
let out = pid.next_control_output(0.0, 1.0);
435435
assert_eq!(out.p, 10.0); // 1.0 * 10.0
436436
assert_eq!(out.i, 1.0); // 0.1 * 10.0
437437
assert_eq!(out.d, 0.0); // -(1.0 * 0.0)
@@ -440,7 +440,7 @@ mod tests {
440440
pid.setpoint(0.0);
441441

442442
assert_eq!(
443-
pid.next_control_output(0.0),
443+
pid.next_control_output(0.0, 1.0),
444444
ControlOutput {
445445
p: 0.0,
446446
i: 1.0,
@@ -456,7 +456,7 @@ mod tests {
456456
let mut pid = Pid::new(10.0f32, -10.0);
457457
pid.p(1.0, -50.0).i(1.0, -50.0).d(1.0, -50.0);
458458

459-
let out = pid.next_control_output(0.0);
459+
let out = pid.next_control_output(0.0, 1.0);
460460
assert_eq!(out.p, 10.0);
461461
assert_eq!(out.i, 10.0);
462462
assert_eq!(out.d, 0.0);

0 commit comments

Comments
 (0)