|
| 1 | +""" |
| 2 | +A Proportional-Integral-Derivative (PID) controller is a control loop mechanism that calculates an error |
| 3 | +value as the difference between a desired setpoint and a measured process variable. |
| 4 | +
|
| 5 | +It applies proportional, integral, and derivative corrections to minimize the error over time. |
| 6 | +
|
| 7 | +Refer - https://en.wikipedia.org/wiki/PID_controller |
| 8 | +""" |
| 9 | + |
| 10 | + |
| 11 | +class pid: |
| 12 | + |
| 13 | + def __init__(self, Kp: float, Ki: float, Kd: float, setpoint: float = 0): |
| 14 | + """ |
| 15 | + Initialize the PID controller. |
| 16 | +
|
| 17 | + :param Kp: Proportional gain |
| 18 | + :param Ki: Integral gain |
| 19 | + :param Kd: Derivative gain |
| 20 | + :param setpoint: Desired target value |
| 21 | + """ |
| 22 | + self.Kp = Kp |
| 23 | + self.Ki = Ki |
| 24 | + self.Kd = Kd |
| 25 | + self.setpoint = setpoint |
| 26 | + |
| 27 | + self.integral = 0 |
| 28 | + self.previous_error = 0 |
| 29 | + |
| 30 | + def compute(self, measured_value: float, dt: float) -> float: |
| 31 | + """ |
| 32 | + Compute the control signal based on the error. |
| 33 | +
|
| 34 | + :param measured_value: The current process variable |
| 35 | + :param dt: Time difference since the last update |
| 36 | + :return: Control output |
| 37 | + """ |
| 38 | + error = self.setpoint - measured_value |
| 39 | + self.integral += error * dt if error != 0 else 0 |
| 40 | + derivative = (error - self.previous_error) / dt if dt > 0 else 0 |
| 41 | + |
| 42 | + output = (self.Kp * error) + (self.Ki * self.integral) + (self.Kd * derivative) |
| 43 | + self.previous_error = error |
| 44 | + return output |
| 45 | + |
| 46 | + def reset(self): |
| 47 | + """Reset the integral and previous error values.""" |
| 48 | + self.integral = 0 |
| 49 | + self.previous_error = 0 |
| 50 | + |
| 51 | + |
| 52 | +if __name__ == "__main__": |
| 53 | + import doctest |
| 54 | + |
| 55 | + doctest.testmod() |
0 commit comments