import time class PID: """PID Controller """ def __init__(self, P=1.0, I=0.0, D=0.0): self.Kp = P self.Ki = I self.Kd = D self.SetPoint = 0.0 self.sample_time = 0.00 self.current_time = time.time() self.last_time = self.current_time self.clear() def clear(self): """Clears PID computations and coefficients""" self.SetPoint = 0.0 self.PTerm = 0.0 self.ITerm = 0.0 self.DTerm = 0.0 self.last_error = 0.0 # Windup Guard self.int_error = 0.0 self.windup_guard = 20.0 self.output = 0.0 self.thorro_ = 0.0 self.brake_ = 0.0 self.steer_ = 0.0 self.yrsteer_ = 0.0 def update(self, feedback_value): """Calculates PID value for given reference feedback .. math:: u(t) = K_p e(t) + K_i \int_{0}^{t} e(t)dt + K_d {de}/{dt} .. figure:: images/pid_1.png :align: center Test PID with Kp=1.2, Ki=1, Kd=0.001 (test_pid.py) """ error = self.SetPoint - feedback_value self.current_time = time.time() delta_time = self.current_time - self.last_time delta_error = error - self.last_error if (delta_time >= self.sample_time): self.PTerm = self.Kp * error self.ITerm += error * delta_time if (self.ITerm < -self.windup_guard): self.ITerm = -self.windup_guard elif (self.ITerm > self.windup_guard): self.ITerm = self.windup_guard self.DTerm = 0.0 if delta_time > 0: self.DTerm = delta_error / delta_time # Remember last time and last error for next calculation self.last_time = self.current_time self.last_error = error self.output = self.PTerm + (self.Ki * self.ITerm) + (self.Kd * self.DTerm) def setKp(self, proportional_gain): """Determines how aggressively the PID reacts to the current error with setting Proportional Gain""" self.Kp = proportional_gain def setKi(self, integral_gain): """Determines how aggressively the PID reacts to the current error with setting Integral Gain""" self.Ki = integral_gain def setKd(self, derivative_gain): """Determines how aggressively the PID reacts to the current error with setting Derivative Gain""" self.Kd = derivative_gain def setSetpoint(self, target): """Determines how aggressively the PID reacts to the current error with setting Derivative Gain""" self.SetPoint = target