Skip to content

Instantly share code, notes, and snippets.

@damp11113
Last active October 14, 2024 13:13
Show Gist options
  • Save damp11113/ba4ce2f147d9e405628988b69ccd3bd4 to your computer and use it in GitHub Desktop.
Save damp11113/ba4ce2f147d9e405628988b69ccd3bd4 to your computer and use it in GitHub Desktop.
a PID control with simulation and output to plot (with animation)
import matplotlib.pyplot as plt
import time
class PIDController:
def __init__(self, kp, ki, kd, setpoint, output_limits=(None, None)):
self.kp = kp
self.ki = ki
self.kd = kd
self.setpoint = setpoint
self.output_limits = output_limits
self._prev_error = 0
self._integral = 0
self._last_time = None
def update(self, feedback_value, current_time):
error = self.setpoint - feedback_value
if self._last_time is None:
self._last_time = current_time
delta_time = 0
else:
delta_time = current_time - self._last_time
self._last_time = current_time
p_term = self.kp * error
self._integral += error * delta_time
i_term = self.ki * self._integral
delta_error = error - self._prev_error
d_term = self.kd * (delta_error / delta_time) if delta_time > 0 else 0
output = p_term + i_term + d_term
if self.output_limits[0] is not None:
output = max(self.output_limits[0], output)
if self.output_limits[1] is not None:
output = min(self.output_limits[1], output)
self._prev_error = error
return output
# PID controller settings
pid = PIDController(kp=1, ki=0, kd=0, setpoint=1000)
# Simulation settings
feedback = 0
time_values = []
feedback_values = []
control_signals = []
setpoint_values = []
start_time = time.time()
# Initialize the plot
plt.ion() # Enable interactive mode
fig, ax = plt.subplots(figsize=(10, 6))
for _ in range(200):
current_time = time.time() - start_time
control_signal = pid.update(feedback, current_time)
# Update feedback for next loop (simulate process)
feedback += control_signal * 0.1
# Store data for plotting
time_values.append(current_time)
feedback_values.append(feedback)
control_signals.append(control_signal)
setpoint_values.append(pid.setpoint)
# Clear and update the plot in real-time
ax.clear()
ax.plot(time_values, setpoint_values, label="Setpoint", linestyle="--")
ax.plot(time_values, feedback_values, label="Feedback")
ax.plot(time_values, control_signals, label="Control Signal", linestyle=":")
ax.set_title("PID Controller Simulation (Real-Time)")
ax.set_xlabel("Time (s)")
ax.set_ylabel("Value")
ax.legend()
ax.grid(True)
# Pause to allow plot to update
plt.pause(0.01)
# Slow down the simulation for visualization purposes
#time.sleep(0.01)
plt.ioff() # Disable interactive mode when done
plt.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment