Skip to content

Instantly share code, notes, and snippets.

@dmitryhd
Created March 22, 2025 08:01
Show Gist options
  • Save dmitryhd/a8fe8f5fce2a0563392d6bc863284039 to your computer and use it in GitHub Desktop.
Save dmitryhd/a8fe8f5fce2a0563392d6bc863284039 to your computer and use it in GitHub Desktop.
pid regulator demo
# run streamlit run pid_streamlit.py
# matplotlib==3.7.1
# streamlit==1.43.2
import matplotlib.pyplot as plt
import streamlit as st
class PidController:
def __init__(self, ki=1, kp=1, kd=1, target=0):
self.ki = ki
self.kp = kp
self.kd = kd
self.integral = 0.0
self.prev_error = 0.0
def get_correction(self, error, dt=1.0) -> float:
self.integral += error * dt
derivative = (error - self.prev_error) / dt
correction = self.kp * error + self.ki * self.integral + self.kd * derivative
self.prev_error = error
return correction
def simulate(
kp=0.2,
ki=0.1,
kd=0.05,
target_price=100,
initial_price=90,
time_steps=20,
):
pid = PidController(kp, ki, kd)
prices = []
errors = []
price = initial_price
for i in range(time_steps):
error = target_price - price
price += pid.get_correction(error)
errors.append(error)
prices.append(price)
return prices, errors
def main():
st.title("Демонстрация ПИД-регулятора (формирование цены)")
st.sidebar.header("Настройки ПИД:")
# Ползунки для KP, KI, KD
kp = st.sidebar.slider("Kp (пропорц.)", 0.0, 2.0, 0.5, 0.05)
ki = st.sidebar.slider("Ki (интегр.)", 0.0, 0.5, 0.1, 0.01)
kd = st.sidebar.slider("Kd (дифф.)", 0.0, 0.3, 0.05, 0.01)
time_steps = st.sidebar.slider("Количество шагов", 1, 50, 20)
prices, errors = simulate(kp, ki, kd, time_steps=time_steps)
st.subheader("Динамика цены на каждом шаге")
fig, ax = plt.subplots()
ax.plot(range(time_steps), prices, marker="o", label="Price")
ax.set_xlabel("Шаг")
ax.set_ylabel("Цена")
ax.set_title("Цена vs Шаги")
ax.legend()
st.pyplot(fig)
st.subheader("Ошибка (целевая цена - фактическая)")
fig2, ax2 = plt.subplots()
ax2.plot(range(time_steps), errors, marker="o", label="Error", color="red")
ax2.set_xlabel("Шаг")
ax2.set_ylabel("Ошибка")
ax2.set_title("Ошибка vs Шаги")
ax2.legend()
st.pyplot(fig2)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment