Created
March 22, 2025 08:01
-
-
Save dmitryhd/a8fe8f5fce2a0563392d6bc863284039 to your computer and use it in GitHub Desktop.
pid regulator demo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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