Closed kratsg closed 2 years ago
Playing around a bit more, this is what I ended up with
def slew_rate(actual, target, max_rate=15.0/60.0, dt=1.0):
delta = target - actual
if abs(delta) < max_rate * dt:
return (target, False)
if delta > max_rate * dt:
delta = max_rate * dt
elif delta < -max_rate * dt:
delta = -max_rate * dt
slew_target = actual + delta
return (slew_target, True)
pid = PID(-0.5*0.080, -0.8*0.5/24, -0.066*0.5/24, setpoint=0)
pid.proportional_on_measurement = True
pid.sample_time = 1.0
pid.output_limits = (0, 15)
try:
while True:
v = ps_peltier.measureVoltage()
t, is_slewed = slew_rate(get_temperature(), pid.setpoint)
if is_slewed:
pid._integral = 0.0
control = pid(t)
print(f"{t:0.4f} °C ({v:0.4f} V) -> {control:0.4f} V{' slewing' if is_slewed else ''}")
ps_peltier.setVoltageLevel(control)
time.sleep(pid.sample_time)
except KeyboardInterrupt:
ps_peltier.setVoltageLevel(0.0)
if there's any other suggestions.
Hi, I really can't offer any more insight than what you have already provided yourself. Thanks for sharing what you came up with, it could be really useful to someone else!
For reference - this package works pretty nicely as it stands. I'm wondering how one might add a slew rate, in order to set the maximum "acceleration" of the PID. Perhaps with
error_map
? (Is this where the slew term goes in?)