Problem 474065 · medium · Level 04 Non-Linear Data Structures

Replaying a 3D Printer's PID Log

PID control · update order · anti-windup · saturation · filtered derivative

A 3D printer's hot end is a small block of aluminium with a heater cartridge of up to u_max watts and a temperature sensor. Its firmware runs a PID controller every dt seconds. After a failed print the maker wants to check the firmware's arithmetic, so you are given its log: the setpoints and the sensor readings (°C), one pair per sample, and you must recompute the heater commands.

The controller keeps two numbers between samples: the integral term I (in watts, already multiplied by Ki) and the filtered derivative D (°C per second). Both start at 0. For each sample, in exactly this order:

e = r - y                                         (error, °C)
I = I + Ki * e * dt, then limited to 0..u_max     (clamped integral: no windup beyond the heater's range)
raw = -(y - y_previous) / dt                      (derivative on the measurement; 0 for the first sample)
D = D + dt / (Tf + dt) * (raw - D)                (low-pass filtered, time constant Tf seconds)
u = Kp * e + I + Kd * D, then limited to 0..u_max (watts)

Write pid_log(setpoints, readings, dt, Kp, Ki, Kd, Tf, u_max) that returns the list of commands u, one per sample.

Examples

Input:  setpoints = [200, 200, 200, 200], readings = [195.0, 196.0, 197.5, 198.5],
        dt = 0.5, Kp = 2, Ki = 0.4, Kd = 2, Tf = 0.5, u_max = 40
Output: [11.0, 7.8, 3.3, 1.6]
Explanation: sample 1: e = 5, I = 0.4 * 5 * 0.5 = 1, raw = 0, u = 10 + 1 = 11 W.
Sample 2: e = 4, I = 1.8, raw = -2 °C/s, D = 0 + 0.5 * (-2 - 0) = -1, u = 8 + 1.8 - 2 = 7.8 W.

Input:  setpoints = [210, 210, 210], readings = [25.0, 30.0, 36.0],
        dt = 0.5, Kp = 2, Ki = 0.4, Kd = 5, Tf = 0.5, u_max = 40
Output: [40.0, 40.0, 40.0]
Explanation: heating from cold the command is far above 40 W and is limited; the integral
term is held at 40 W too, so it cannot pile up while the heater is flat out.

Constraints

  • len(setpoints) == len(readings)
  • answers are compared with a tolerance of 1e-6; do not round

Goals

  • Implement a complete discrete PID update in a stated order
  • Clamp the integral term and the output to what the heater can deliver
  • Combine a derivative on the measurement with a low-pass filter
Starting Python…