I have come across a handful of examples of PID controllers where the process input is the accumulated PID output, i.e. the controller loop is
u += pid(...) rather than
u = pid(...) where
u is the process input.
For the sake of example, say we are using PID to control the speed of a motor via PWM,
class PID: def __init__(self, kp, ki, kd): self.kp = kp self.ki = ki self.kd = kd ... def pid(self, set_point, process_variable): now = time() dt = now - self.last_time error = set_point - process_variable p = self.kp * error i = self.ki * error * dt + self.i_sum d = self.kd * (error - self.last_error) / dt output = p + i + d self.i_sum = i self.last_error = error self.last_time = now return output
My understanding of PID is that we should use the controller as
pid = PID(kp, ki, kd) ... motor_pwm = pid.pid(target_speed, measured_speed)
But I often see it implemented as
pid = PID(kp, ki, kd) ... motor_pwm += pid.pid(target_speed, measured_speed)
ki = kd = 0, the latter makes some intuitive sense to me; in fact, I think it actually gives you a kind of PI controller with
ki = kp, and
dt = 1 enforced. Once you introduce
ki != 0 or
kd != 0, however, I can't square this with any of the textbook explanations of PID I have read.
Is this 'accumulated'
u += pid(...) controller simply an incorrect implementation of PID?