[PYTHON] [Einführung in PID] Ich habe versucht, ♬ zu steuern und zu spielen

Die PID-Regelung scheint eine Technologie zu sein, die es schon lange gibt. Also habe ich es sorgfältig formuliert und damit gespielt, also werde ich es zusammenfassen.

【Referenz】 ①PID controller ② [PID-Regelung](https://ja.wikipedia.org/wiki/PID%E5%88%B6%E5%BE%A1#:~:text=PID%E5%88%B6%E5%BE%A1 % EF% BC% 88% E3% 83% 94% E3% 83% BC% E3% 82% A2% E3% 82% A4% E3% 83% 87% E3% 82% A3% E3% 83% BC% E3 % 81% 9B% E3% 81% 84,% E6% 96% B9% E6% B3% 95% E3% 81% AE% E3% 81% 93% E3% 81% A8% E3% 81% A7% E3% 81% 82% E3% 82% 8B% E3% 80% 82)

Es kann leicht durch das folgende Diagramm dargestellt werden. Aus der obigen Referenz ① By Arturo Urquizo - PID_en.svg.png Hier ist jede Menge wie folgt definiert.

\begin{align}
r(t)&;Zielbetrag\\
y(t)&;Nach dem Betrieb die aktuelle Menge der Zielanlage oder des Zielprozesses\\
e(t)&=r(t)-y(t);Aktueller Betrag-Rest berechnet nach Zielbetrag\\
u(t)&=P+I+D;Betriebsmenge\\
          &;Operationen an Zielanlagen und -prozessen\\
        &;Der zu fließende Stromwert zum Anheben und Absenken der Temperatur und der Winkel zum Betätigen des Griffs und des Ventils. ..\\
P&=K_pe(t);Proportionalsteuerung\\
I&=K_i\int_0^t e(\tau )d\tau;Integrale Steuerung\\
D&=K_d\frac{de(t)}{dt};Differentialsteuerung\\
\end{align}

Hier ist im Fall der Computersteuerung $ y (t) $ ein diskreter Wert, daher ist es besser, die Integralsteuerung und die Differenzialsteuerung durch numerische Integration und numerische Differenzierung wie folgt zu definieren. Zum Abtastzeitpunkt $ t = t_n $ wie folgt platzieren. Die numerische Differenzierung kann von höherer Ordnung sein, aber das Folgende kann unter Berücksichtigung der Praktikabilität und Reaktivität verwendet werden.

\int_0^te(\tau)d\tau = \Sigma_{i=0}^ne(t_i)\Delta t\\
(\frac{de(t)}{dt})_{t_n}=\frac{e(t_n)-e(t_{n-1})}{\Delta t}\\
\Delta t = t_n-t_{n-1} ; const=Auf 1 setzen

Versuchen Sie, es in den Code zu setzen

Erstens sind die Kontrollziele wie folgt. Mit anderen Worten, es ist ein Bild der Temperaturregelung von Elektroöfen.

def ufunc(M,u=0,t=0):
    M0=0.2
    m=0.05
    return M - m*(M-M0-u)

Die Reglerseite berücksichtigt die folgende PID-Regelung. Ein Teil des Codes basiert auf Folgendem. 【Referenz】 Versuchen Sie die PID-Regelung mit Python

t = 100
params_list = [(0,0,0)]  #Kp,Ki,Stellen Sie Kd ein
for kp,ki,kd in params_list:
    Kp,Ki,Kd=kp,ki,kd
    M0 = 2
    M=M0
    goal = 1.00
    e = 0.00 
    e1 = 0.00 
    u=0
    es=0
    x_list = []
    y_list = []
    u_list = []
    x_list.append(0)
    y_list.append(M)
    u_list.append(u)
    for i in range(1,t,1):
        M1 = M
        e1 = e
        e = goal - y_list[i-1] #Abweichung (e)=Objektiver Wert (Ziel)-Gegenwärtiger Wert
        es += e #Integrieren ist zusätzlich
        u = Kp * e + Ki * es + Kd * (e-e1) #Differenzierung ist Subtraktion
        M = ufunc(M,u,i) #Antwort vom Ziel
        x_list.append(i)
        y_list.append(M)
        u_list.append(u)
    plt.hlines([goal], 0, t, "red", linestyles='dashed') #Das Ziel wird mit einer rot gepunkteten Linie angezeigt
    plt.plot(x_list, y_list, color="b") #Die zeitliche Änderung der Antwort wird blau angezeigt
    plt.title('Kp={}, ki={}, kd={}'.format(Kp, Ki, Kd))
    #plt.plot(x_list, u_list, color="black") #Die Betriebsmenge wird schwarz angezeigt
    plt.ylim(-0.5, goal*2+0.2) #Höhenverstellung des Diagramms
    plt.pause(0.2)
    plt.savefig("output/Kp,Ki,Kd/imageKp{}Ki{}Kd{}M0{}.png ".format(Kp,Ki,Kd,M0))    
    plt.close()

Siehe die Zielreaktion mit params_list = [(0,0,0)]

Wenn t = 0, wenn M = 2 und die Raumtemperatur M0 = 0,2 ist, nähert es sich allmählich M = 0,2 wie folgt. imageKp0.0Ki0.0Kd0.0M02dt1.png

Dieses System wird durch die folgende Gleichung ausgedrückt.

\frac{dM}{dt}=-m(M-M0)

Die Lösung ist

M=M0+(2-M0)e^{-mt}\\
t=Wenn 0, M.=2

Ziegra Nichols Grenzempfindlichkeitsmethode

Sehen Sie die kritische Vibration des Objekts Laut Wikipedia werden, wenn Ki = Kp / Ti und Kd = Kp · Td, die optimalen Parameter wie folgt durch die Grenzempfindlichkeitsmethode von Ziegra Nichols bestimmt.

Kontroll-Methode Kp Ti Td
P 0.50Ku - - - -
PI 0.45Ku 0.83Tu - -
PID 0.6Ku 0.5Tu 0.125Tu

Hier sind Ku und Tu wie folgt definiert. "Die Proportionalverstärkung Kp wird allmählich von 0 erhöht, und wenn der Steuerbetrag die stabile Grenze erreicht und die Vibration mit konstanter Amplitude beibehalten wird, wird die Erhöhung von Kp gestoppt. Die Proportionalverstärkung zu diesem Zeitpunkt ist Ku (Grenzempfindlichkeit). , Wenn der Vibrationszyklus Tu ist Wenn die Grenzschwingung für das obige Objekt berechnet wird, wird sie als Tu = 2,0 berechnet, wenn Ku = 39, wie unten gezeigt. imageKp39.0Ki0.0Kd0.0M02dt1.png

Wenn Sie die obige Tabelle mit Ki, Kd,

Kontroll-Methode Kp Ki Kd
P 0.50Ku - - - -
PI 0.45Ku 0.54Ku/Tu - -
PID 0.6Ku 1.2Ku/Tu 3KuTu/40

Ergebnis

In der Tat, wenn Sie mit den oben genannten Parametern versuchen, P-Steuerung Kp19.5Ki0.0Kd0.0M02dt1 imageKp19.5Ki0.0Kd0.0M02dt1.png PI-Steuerung Kp17.55Ki10.57Kd0.0M02dt1 imageKp17.55Ki10.572289156626507Kd0.0M02dt1.png PID-Regelung Kp23.4Ki23.4Kd5.85M02dt1 imageKp23.4Ki23.4Kd5.85M02dt1.png Mit anderen Worten, die PID-Regelung schlägt aus irgendeinem Grund fehl Dies scheint auf den Rundungsfehler zurückzuführen zu sein.

dt Präzisionsverlängerung und Neuberechnung

Erweitern Sie dt so, dass es in beliebigen Schritten berechnet werden kann, wie unten gezeigt.

def ufunc(M,u=0,t=0,dt=1):
    M0=0.2
    m=0.05
    return M - m*(M-M0-u)*dt

t = 100
dt=0.1

Ku=39
Tu=2
params_list =[(0.5*Ku,0,0),(0.45*Ku,0.54*Ku/Tu,0),(0.6*Ku,1.2*Ku/Tu,3*Ku*Tu/40)]
for kp,ki,kd in params_list:
    Kp,Ki,Kd=kp,ki,kd
    ...
    for i in range(1,int(t/dt),1):
        ...
        e = goal - y_list[i-1] #Abweichung (e)=Objektiver Wert (Ziel)-Zuletzt realisierter Wert
        es += e*dt
        u = Kp * e + Ki * es + Kd * ((e-e1)/dt )
        M = ufunc(M,u,i,dt)

        x_list.append(i*dt)
        y_list.append(M)
        u_list.append(u)
        ...
    plt.savefig("output/Kp,Ki,Kd,dt/imageKp{}Ki{}Kd{}M0{}dt{}.png ".format(Kp,Ki,Kd,M0,dt))    
    plt.close()

Mit dt = 0.1 erneut ausgeführt, konnte ich wie erwartet gut zeichnen. PID-Regelung Kp23.4Ki23.4Kd5.85M02dt0.1 imageKp23.4Ki23.4Kd5.85M02dt0.1.png Da die große Änderung bei t = 0-10 endet, ist es jetzt möglich, den dt-Schritt im Detail zu berechnen. Berechnen wir also mit dem Schritt dt = 0,01 neu. P-Steuerung Kp19.5Ki0.0Kd0.0M02dt0.01 imageKp19.5Ki0.0Kd0.0M02dt0.01.png PI-Steuerung Kp17.55Ki10.57Kd0.0M02dt0.01 imageKp17.55Ki10.572289156626507Kd0.0M02dt0.01.png PID-Regelung Kp23.4Ki23.4Kd5.85M02dt0.01 imageKp23.4Ki23.4Kd5.85M02dt0.01.png

Graphische Wiedergabe der PID-Regelung

Versuchen Sie, die folgende Grafik der englischen Version von Wikipedia zu reproduzieren. Change_with_Ki.png Es scheint, dass die Bedingungen nicht gezeichnet sind. Wenn ich also unter den wahrscheinlichsten Bedingungen unterschiedlich zeichne, wird die Ki-Abhängigkeit unter den folgenden Bedingungen fast ähnlich.

def ufunc(M,u=0,t=0,dt=1):
    M0=0
    m=0.4
    return M + m*u*dt - m*(M-M0)*dt

Die Berechnung basiert auf den gleichen Parameterwerten wie gezeigt. Drei Graphen wurden gleichzeitig mit einer Legende gezeichnet. Der Zeichenbereich des Diagramms wird angepasst.

t = 20
dt=0.01
params_list =[(1,0.5,1),(1,1,1),(1,2,1)]
for kp,ki,kd in params_list:
    Kp,Ki,Kd=kp,ki,kd
    M0 = 0
    M=M0
    goal = 1.00
    e = 0.00 
    e1 = 0.00 
    u=0
    es=0
    x_list = []
    y_list = []
    u_list = []
    x_list.append(0)
    y_list.append(M)
    u_list.append(u)
    for i in range(1,int(t/dt),1):
        M1 = M
        e1 = e
        e = goal - y_list[i-1] #Abweichung (e)=Objektiver Wert (Ziel)-Zuletzt realisierter Wert
        es += e*dt
        u = Kp * e + Ki * es + Kd * ((e-e1)/dt )
        M = ufunc(M,u,i,dt)
        x_list.append(i*dt)
        y_list.append(M)
        u_list.append(u)
    plt.hlines([goal], 0, t, "red", linestyles='dashed') #Das Ziel wird mit einer rot gepunkteten Linie angezeigt
    plt.plot(x_list, y_list,label="Kp{}Ki{}Kd{}".format(Kp,Ki,Kd)) 
    plt.legend()
    plt.ylim(-0.1, 1.5) #Passen Sie die Höhe des Diagramms an
    plt.pause(0.2)
plt.savefig("output/Kp,Ki,Kd,dt/imageKp{}Ki{}Kd{}M0{}dt{}2.png ".format(Kp,Ki,Kd,M0,dt))    
plt.close()

Andererseits kann die Kp-Abhängigkeit wie folgt gezeichnet und nicht ohne Auswahl der Parameter reproduziert werden. imageKp1.6Ki1Kd1M00dt0.011.png Und die Kd-Abhängigkeit scheint fast wie folgt reproduziert zu werden. imageKp1Ki1Kd2M00dt0.013.png

Über das Kontrollziel

Dieses Mal setzen wir das Kontrollziel, indem wir uns die Temperatur des Elektroofens vorstellen. Bei der eigentlichen Steuerung müssen Sie etwas Dynamischeres steuern. In diesem Fall denke ich, dass dies durch Umschreiben von ufunc () realisiert werden kann, das dieses Mal eingeführt wurde. Abhängig vom Kontrollziel denke ich auch, dass es Ziele gibt, die nicht PID-geregelt werden können. Wir müssen die Grenzen dieses Bereichs weiter verfolgen.

Zusammenfassung

・ Ich habe versucht, mit der PID-Regelung zu spielen ・ Die Kontrollparameter wurden mit der Grenzempfindlichkeitsmethode von Ziegra Nichols bestimmt. ・ Ich habe versucht, die auf Wikipedia veröffentlichte Grafik zu reproduzieren ・ Ich konnte explizit eine Funktion definieren, die das gesteuerte Objekt beschreibt. ・ Einführung der Abtastzeit dt

・ Ich möchte es tatsächlich auf die Temperatur- und Motorsteuerung anwenden.

Recommended Posts

[Einführung in PID] Ich habe versucht, ♬ zu steuern und zu spielen
[Einführung in das Modell der Infektionskrankheiten] Ich habe versucht, zu passen und zu spielen ♬
Ich habe DCGAN implementiert und versucht, Äpfel zu generieren
Ich habe versucht zu debuggen.
Ich habe versucht, die Netzwerkbandbreite und -verzögerung mit dem Befehl tc zu steuern
[Einführung in AWS] Ich habe versucht, eine Konversations-App zu portieren und mit text2speech @ AWS playing zu spielen
Ich habe versucht, mit VOICEROID2 2 automatisch zu lesen und zu speichern
Ich habe pipenv und asdf für die Python-Versionskontrolle ausprobiert
Ich habe versucht, DCGAN mit PyTorch zu implementieren und zu lernen
Ich habe versucht, CPython ein Post-Inkrement hinzuzufügen. Übersicht und Zusammenfassung
Ich habe versucht, mit VOICEROID2 automatisch zu lesen und zu speichern
Ich habe versucht, Linux Systemaufrufe und Scheduler hinzuzufügen
[Einführung in Pytorch] Ich habe versucht, Cifar10 mit VGG16 ♬ zu kategorisieren
Ich habe versucht, Scrapy auf Anaconda zu installieren und konnte es nicht
[Einführung in AWS] Ich habe versucht, mit der Sprach-Text-Konvertierung zu spielen ♪
Ich habe versucht, PredNet zu lernen
[Ich habe versucht, Pythonista 3 zu verwenden] Einführung
Ich habe versucht, SVM zu organisieren.
Ich habe versucht, PCANet zu implementieren
Einführung in die nichtlineare Optimierung (I)
Ich habe versucht, Linux wieder einzuführen
Ich habe versucht, Pylint vorzustellen
Ich habe versucht, SparseMatrix zusammenzufassen
jupyter ich habe es berührt
Ich habe versucht, StarGAN (1) zu implementieren.
Ich habe versucht, Überlebende der Titanic mit Kaggle vorherzusagen und einzureichen
Ich habe versucht, Discord Bot und Gesichtserkennung für LT zu kombinieren.
Ich habe versucht, die Informationen des Webs mit "Requests" und "lxml" abzurufen.
[Einführung in die Simulation] Ich habe versucht, durch Simulation einer Koronainfektion zu spielen ♬
[Django] Ich habe versucht, Zugriffsbeschränkungen durch Klassenvererbung zu implementieren.
[Einführung in Pandas] Ich habe versucht, die Austauschdaten durch Dateninterpolation zu erhöhen ♬
Ich habe versucht, die Zeit und die Zeit der C-Sprache zu veranschaulichen
Ich habe versucht, die Uhrzeit und das heutige Wetter anzuzeigen
Mongodb Kürzeste Einführung (3) Ich habe versucht, sogar Millionen zu beschleunigen
Ich habe versucht, die Unterschiede zwischen Java und Python aufzuzählen
Ich habe versucht, die Benutzeroberfläche neben Python und Tkinter dreiäugig zu gestalten
[Einführung in Mac] Praktische Mac-Apps und -Einstellungen, die ich verwende
Ich habe versucht, Deep VQE zu implementieren
Ich habe versucht, eine Quip-API zu erstellen
Ich habe versucht, Python zu berühren (Installation)
[Einführung in Python3 Tag 1] Programmierung und Python
Ich habe versucht, eine kontroverse Validierung zu implementieren
Ich habe versucht, Pytorchs Datensatz zu erklären
Ich habe Teslas API berührt
Ich habe versucht, mich über MCMC zu organisieren.
Ich habe versucht, Realness GAN zu implementieren
Ich habe versucht, den Ball zu bewegen
Ich habe versucht, den Abschnitt zu schätzen.
Ich habe versucht, die Lesezeichen zu visualisieren, die mit Doc2Vec und PCA nach Slack fliegen
[Einführung in Python] Ich habe die Namenskonventionen von C # und Python verglichen.
[Einführung in die Simulation] Ich habe versucht, durch Simulation einer Koronainfektion zu spielen ♬ Teil 2
Ich habe versucht, Pepper über Ereignisinformationen und Mitgliederinformationen sprechen zu lassen
Ich habe versucht, mit Selenium und Python einen regelmäßigen Ausführungsprozess durchzuführen
Ich habe versucht, Bulls and Cows mit einem Shell-Programm zu erstellen
Ich habe versucht, Spieler- und Fertigkeitsnamen aus Sportartikeln zu extrahieren
Ich habe versucht, mit Go einen exklusiven Kontrollmechanismus zu erstellen
Ich habe versucht, einen Linebot zu erstellen (Implementierung)
Ich habe versucht, die Behandlung von Python-Ausnahmen zusammenzufassen