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)
Now, for 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?
1 Answer 1
It is not necessarily an incorrect implementation, if the feedback signal that your PID loop is tracking and controlling is the first derivative of the control output you need to emit. The continual accumulation of the PID output is equivalent to integration.
-
1\$\begingroup\$ Typical example: The output of the control loop is a voltage, which a motor turns into speed. Integrated speed is distance. \$\endgroup\$Janka– Janka2018年11月18日 13:35:11 +00:00Commented Nov 18, 2018 at 13:35
u
denotes. \$\endgroup\$u
is the process input. The code examples I am referring to are linked in the question. \$\endgroup\$