Forum: Mikrocontroller und Digitale Elektronik PID-Regler mit anti-windup in Python


von Johannes E. (scootty)


Lesenswert?

Hallo!

Ich bin gerade dabei einen digitalen PID-Regler für eine Steuerung in 
einem Simulations-Tool zu integrieren. Diese soll alle möglichen Arten 
von Bauteilen mit Pumpen, Wärmequellen etc. steuern.
Das Lesen der bisherigen Beiträge hat mich leider aufgrund der vielen 
unterschiedlichen Ansätze eher verwirrt, als dass es mir geholfen hat. 
Und meine Vorlesungen zur Regelungstechnik liegen mittlerweile schon 
fast 10 Jahre zurück... (D.h. Basiswissen ist noch da, aber ich komme 
damit in der praktischen Umsetzung nicht mehr weiter.)


Ich habe bisher den einfachsten Ansatz nach
gewählt und folgendermaßen in Python integriet (Code auf viele 
Einzeloperationen aufgesplittet, um ihn hier einfacher darzustellen):
1
# ein paar Beispielwerte
2
anti_windup = 50
3
cv_min = 0
4
cv_max = 1.0
5
6
err = setpoint - process_var
7
8
i_term = timestep * err + prev_i_term
9
10
# anti-windup implementation:
11
if i_term > anti_windup:
12
    i_term = anti_windup
13
elif i_term < - anti_windup:
14
    i_term = - anti_windup
15
16
d_term = (err - prev_err) / timestep
17
18
ctrl_var = Kp * err + Ki * i_term + Kd * d_term
19
20
# limit ctrl_var:
21
if ctrl_var > cv_max:
22
    ctrl_var = cv_max
23
elif ctrl_var < cv_min:
24
    ctrl_var = cv_min
25
26
prev_err = err
27
prev_i_term = i_term

Anti-Windup is hierbei essentiell für mich, da es z.B. auch mal eine 
Stunde dauern kann, bis die Temperatur nach einem Heizvorgang wieder 
unter den Sollwert fällt.


Jetzt gibt es hierbei mehrere Unklarheiten für mich:
- Bisher habe ich den vorigen i_term abgespeichert und als 
prev_i_term verwendet, da ich variable Zeitschritte habe. Häufig 
wird aber die Summe über die Fehler gebildet und dann
1
i_term = timestep * err_sum
 gerechnet. Hier vermute ich aber, dass bei nicht-konstanten 
Zeitschritten eine Fehlbewertung der Fehler auftreten kann. Ist das so? 
Gibt es hier Vor- und Nachteile?

- Wo genau wird Anti-Windup eingebaut? Stimmt die Position bei mir im 
Code, oder sollte das über prev_i_term laufen? Und mir fällt hier noch 
die Abschätzung sinnvoller Werte schwer. Hier 
(http://www.kramann.info/64_Regelungssysteme/11_Stabilitaet/03_Windup/index.php) 
wird zum Beispiel in der Code-Box ganz unten ein völlig anderer Ansatz 
für Anti-Windup gewählt, oder?

- Hier (Beitrag "Re: PID- Regler") wird zum 
Beispiel ein ganz anderer Ansatz gewählt. Wieso wird hier das Ergebnis 
aus dem vorigen Zeitschritt noch einmal verwendet? Und die Summe über 
die Fehler für den I-Anteil enthält dann nur zwei Elemente (err_1 und 
err_1 des vorigen Schritts)? Was sind die Vor- und Nachteile von dieser 
Methode?

Vielen Dank im Voraus!
Viele Grüße

: Bearbeitet durch User
von aSma>> (Gast)


Lesenswert?

Servus,
"ohne mein Aström sag ich nix."

Hilfreich ist immer ein passendes Schaltbild!

https://de.mathworks.com/help/simulink/examples/anti-windup-control-using-a-pid-controller.html

Es gibt mehrere Anti-Windup Verfahren und duzent weitere.


Johannes E. schrieb:
> - Wo genau wird Anti-Windup eingebaut? Stimmt die Position bei mir im
> Code, oder sollte das über prev_i_term laufen? Und mir fällt hier noch
> die Abschätzung sinnvoller Werte schwer. Hier
> (http://www.kramann.info/64_Regelungssysteme/11_Stabilitaet/03_Windup/index.php)
> wird zum Beispiel in der Code-Box ganz unten ein völlig anderer Ansatz
> für Anti-Windup gewählt, oder?

Beim Aström kann man nachlesen wie man den Faktor wählt. Ich meine der 
Ansatz war Kb = 1/Ki für den Anfang. Wichtig ist hier eine Regelungsform 
zu wählen, die man validieren kann!

> - Hier (Beitrag "Re: PID- Regler") wird zum
> Beispiel ein ganz anderer Ansatz gewählt. Wieso wird hier das Ergebnis
> aus dem vorigen Zeitschritt noch einmal verwendet? Und die Summe über
> die Fehler für den I-Anteil enthält dann nur zwei Elemente (err_1 und
> err_1 des vorigen Schritts)? Was sind die Vor- und Nachteile von dieser
> Methode?

Es gibt unendlich viele Möglichkeiten für einen PID-Regler. Bei der 
allgemeinen Form mit "sum" wird soweit vereinfacht, dass man nur ein err 
hat. Dadurch entstehen Fehler, die zu Instabilität führen können.

von Johannes E. (scootty)


Lesenswert?

Hallo aSma,

vielen Dank für deine schnelle Antwort!

Ok, dann versuche ich meine Problematik ein bisschen direkter auf meinen 
Problemfall zu beziehen:
Gibt es einen Reglerentwurf, der sich ganz besonders für variable 
Zeitschritte eignet?
Wenn ich meinen Regler für einen Zeitschritt stabil einstelle, bekomme 
ich bei größeren Zeitschritten schnell Schwingungungen der Stellgröße. 
Wie kann ich das vermeiden?

Zum Faktor: Danke! Das Kb = 1/Ki bezieht sich auf die Anti-Windup 
implementierung in der Art, wie ich es eingebaut habe?


Zu den unterschiedlichen Möglichkeiten zur Implementierung von 
PID-Reglern:
Wieso ist gerade die Summen-Form vereinfacht? Wenn ich mir ein Integral 
diskretisiere, dann ist das doch:
D.h. die Summe über den Fehler mal dem Zeitschritt ist doch gerade keine 
Vereinfachung (abgesehen von der Diskretisierung der Zeit).

Stattdessen müsste die Methode hier 
(Beitrag "Re: PID- Regler") eine Vereinfachung 
sein. Bzw. wenn ich mir das genauer ansehe, dann scheint es so, als sei 
die mathematische Herleitung hier auch nicht ganz korrekt. Das sieht mir 
eher so aus, als sei nach
 abgeleitet worden. Diese Ableitungen als Taylor-Reihe dann einmal 
vorwärts und einmal rückwärts und dann aufsummieren und Abbruchfehler 
höherer Ordnung vernachlässigen.
Aber falls das so ist: Wo ist hier das
 auf der rechten Seite, um mit der Diskretisierung der Stellgröße wieder 
auf die Stellgröße zu kommen?
Analog hier auf Wikipedia: 
(https://en.wikipedia.org/wiki/PID_controller#Discrete_implementation)
Oder habe ich da einen Denkfehler?

Vielen Dank für Eure Hilfe im Voraus!

von Johannes E. (scootty)


Lesenswert?

Ein Nachtrag

Bezüglich der K-Werte des Reglers bei nicht-konstanten Zeitschritten:
Ich habe die K-Werte jetzt mittels Ziegler-Nichols bei einem festen 
Zeitschritt t_mittel (der in etwa dem mittleren Zeitschritt 
entspricht) eingestellt und auf diesen Zeitschritt normiert.
Falls der aktuelle Zeitschritt t_k größer ist, werden die K-Werte über 
die Normierung mit
berechnet. Falls t_k <= t_mittel, werden die K-Werte von t_mittel 
verwendet.
Das läuft jetzt sehr stabil und mit zufriedenstellender Geschwindigkeit.
Gibt es hierzu Anregungen?
Insbesondere kritische Aussagen wie: "Mach das nicht, da sonst in Fall x 
das Resultat y zu erwarten ist!", sind erwünscht!

Viele Grüße

von aSma>> (Gast)


Angehängte Dateien:

Lesenswert?

Servus,

Johannes E. schrieb:
> Gibt es einen Reglerentwurf, der sich ganz besonders für variable
> Zeitschritte eignet?
> Wenn ich meinen Regler für einen Zeitschritt stabil einstelle, bekomme
> ich bei größeren Zeitschritten schnell Schwingungungen der Stellgröße.
> Wie kann ich das vermeiden?

Was meinst du mit Zeitschritt? Abtastzeit?

Der diskrete Regler ist immer von der Abtastzeit Ta abhängig! Wenn du 
diese änderst, dann müssest du die Koeffitienten des Reglerparameter mit 
ändern!

Weiterhin muss man die Echtzeit einhalten, damit der Regler wie auch in 
der Simulation fkt.

Der D-Anteil bring das System zum schwingen bei kleinen Ta. Deshalt muss 
ein Tiefpass rein (siehe Bild). Das raffen die meisten hier nicht.

Achtung für eine sehr träge Temperatur Strecke reicht ein PI vollkommen 
aus! Zur Not kann man ein Relais davorschalten.

> Zum Faktor: Danke! Das Kb = 1/Ki bezieht sich auf die Anti-Windup
> implementierung in der Art, wie ich es eingebaut habe?

Ich guck dann nochmal später drüber.

> Oder habe ich da einen Denkfehler?
Der im Forum angeführte Regler ist schon richtig. Man behilft sich mit 
einen mathematischen Trick. Dazu muss man Reihenfolge als Fläche sich 
vorstellen, die in Abhängigkeit von der Zeit ist. Durch die Subtraktion 
wird das Summenzeichen eleminiert...

Unnötig wenn mann die Z-Transformation beherrscht. Nur so an dieser 
Stelle.

Ich bevorzuge diesen angeführten Reglertyp am liebsten (Euler Vorwärts).
(https://en.wikipedia.org/wiki/PID_controller#Discr...)

Johannes E. schrieb:
> Das läuft jetzt sehr stabil und mit zufriedenstellender Geschwindigkeit.
> Gibt es hierzu Anregungen?
> Insbesondere kritische Aussagen wie: "Mach das nicht, da sonst in Fall x
> das Resultat y zu erwarten ist!", sind erwünscht!

Dazu habe ich schon weiter oben etwas gesagt. Nimm für die Regelung 
einen Timerinterrupt! Eine Statemaschiene geht auch.

von Johannes E. (scootty)


Lesenswert?

Nochmals vielen Dank!

Ja, Zeitschritt ist bei mir die Abtastzeit. Und während der Regler 
läuft, wird die Simulation angehalten. Das ist das, was du mit 
Timerinterrupt meinst?

Das mit dem D-Anteil bei kleinen Schritten hatte ich soweit beachtet. 
Daher kommt auch meine Einschränkung, die Anpassung der Koeffizienten 
nur bei Schritten größer als der Abtastzeit, für die der Regler 
eingestellt wurde, durchzuführen. Ein Tiefpass wäre hier leider ein 
Overkill an Rechenzeit bzw. Aufwand.

Wie würdest du die Zeitabhängigkeit der Koeffizienten umsetzen? Passt 
das so, wie ich es in meinem letzten Beitrag mit der Normierung 
ausgeführt habe?

Die Z-Transformation habe ich irgendwann im Studium mal gelernt. Da das 
aber ein digitaler Regler sein soll, den jeder der die Simulation 
benutzt an verschiedenen Stellen schnell einfügen können soll und der 
damit auf unterschiedlichste Umgebungen passen muss, habe ich das bisher 
weggelassen.

Was ist denn der Vorteil der Euler-vorwärts-Variante des PID-Reglers 
gegenüber der Implementierung, wie ich sie bisher gewählt habe?

von aSma>> (Gast)


Lesenswert?

Johannes E. schrieb:
> Ja, Zeitschritt ist bei mir die Abtastzeit. Und während der Regler
> läuft, wird die Simulation angehalten. Das ist das, was du mit
> Timerinterrupt meinst?

Ach, ich habe jetzt überlesen, dass die Steuerung simuliert wird und 
nicht ein µC benutzt wird.

> Wie würdest du die Zeitabhängigkeit der Koeffizienten umsetzen? Passt
> das so, wie ich es in meinem letzten Beitrag mit der Normierung
> ausgeführt habe?

Ja, nochmals. Der Begriff Echtzeit muss dir etwas sagen. Normalerweise 
wird eine äquidistante Abtastzeit gewählt und nur einmal der Regler 
ausgelegt. Wenn die Abastzeit Ta kleiner als 0.05*T1(kleinste 
Streckezeitkonstante), dann gilt die Regelung quasi 
zeitkontinuierlich...

Versuche irgendwie die Regelung periodisch zu machen. Es reicht ja die 
bewegten Achsen alle 25hz zu plotten, was ja die meiste Zeit kostet, 
aber die Regelung findet alle 0.01s statt...

> Die Z-Transformation habe ich irgendwann im Studium mal gelernt. Da das
> aber ein digitaler Regler sein soll, den jeder der die Simulation
> benutzt an verschiedenen Stellen schnell einfügen können soll und der
> damit auf unterschiedlichste Umgebungen passen muss, habe ich das bisher
> weggelassen.

Die Z-Transformation ist für digitale Regler!

> Was ist denn der Vorteil der Euler-vorwärts-Variante des PID-Reglers
> gegenüber der Implementierung, wie ich sie bisher gewählt habe?

-Validierung
-Stabilität
-zeitkritische Regelung kann diskret erstellt werden

Der letzte Punkt ist am wichtigsten für dich, da bei dir die Rechenpower 
fehlt.

von uuu (Gast)


Lesenswert?

Es gibt Antiwindup & Antiwindup.

Das Windup-Problem ergibt sich normalerweise am begrenzten Stellglied. 
Der Integrator darf nicht weiterlaufen wenn das Stellglied in der 
Begrenzung ist.

Hier, bei der Heizung, hat man ein anderes Problem. Das System ist nicht 
stetig. Ein stetiges Problem wuerde heizen & kuehlen. Der Kuehlteil 
faellt hier weg, wird ersetzt duerch nicht-Heizen. Das System ist daher 
nichtlinear und sollte anders angepackt werden.

von Johannes E. (scootty)


Lesenswert?

aSma>> schrieb:
> Johannes E. schrieb:
>> Ja, Zeitschritt ist bei mir die Abtastzeit. Und während der Regler
>> läuft, wird die Simulation angehalten. Das ist das, was du mit
>> Timerinterrupt meinst?
>
> Ach, ich habe jetzt überlesen, dass die Steuerung simuliert wird und
> nicht ein µC benutzt wird.

Ja genau, das ist alles Teil einer Systemsimulation.
Vielleicht sollte ich kurz zusammenfassen, was ich eigentlich mache:
Ich programmiere ein modulares Simulationsprogramm für thermische 
Anlagen. D.h. ich habe viele verschiedene Module wie Rohre, Pumpen 
Wärmetauscher etc., deren beschreibende DGL (je Modul mindestens eine 
DGL) gelöst werden, je nach Anwendung mittels Heun, RK4, 
Adams-Bashforth, etc.. Hier verwende ich eine Schrittweitensteuerung, es 
treten also immer andere Zeitschritte auf.
Nach jedem abgeschlossenen Schritt wird die Regelung aufgerufen und 
regelt vorher festgelegte aktive Komponenten wie Pumpen und Ventile.
Jedes aktive zu regelnde Bauteil bekommt seine eigene Regelung mit 
eigenen Koeffizienten zugewiesen. Der allgemeine Algorithmus ist aber 
immer der gleiche. D.h. eine Anpassung der Regelung auf die Regelstrecke 
ist ausschließlich über die Koeffizienten möglich. Daher hatte ich 
bisher eine streckenspezifische (ist das so oder geht das auch 
allgemein?) Z-Trafo ausgeschlossen.

>> Wie würdest du die Zeitabhängigkeit der Koeffizienten umsetzen? Passt
>> das so, wie ich es in meinem letzten Beitrag mit der Normierung
>> ausgeführt habe?
>
> Ja, nochmals. Der Begriff Echtzeit muss dir etwas sagen. Normalerweise
> wird eine äquidistante Abtastzeit gewählt und nur einmal der Regler
> ausgelegt. Wenn die Abastzeit Ta kleiner als 0.05*T1(kleinste
> Streckezeitkonstante), dann gilt die Regelung quasi
> zeitkontinuierlich...
>
> Versuche irgendwie die Regelung periodisch zu machen. Es reicht ja die
> bewegten Achsen alle 25hz zu plotten, was ja die meiste Zeit kostet,
> aber die Regelung findet alle 0.01s statt...

Echtzeit sagt mir etwas. Ist hier auch per Definition erfüllt, da die 
Simulation mit der Berechnung des nächsten Schritts wartet, bis die 
Regelung fertig ist.
Aber durch die Regelung zwischen den Schritten hat die Regelung auch 
gezwungenermaßen IMMER die Abtastzeit gleich der Schrittweite, d.h. in 
der Regel nicht äquidistant und auch nicht periodisch zu machen. Aber Ta 
kleiner als 0.05*T1 ist in über 95% der Fälle erfüllt, da thermische 
Systeme ja relativ träge sind.


>> Die Z-Transformation habe ich irgendwann im Studium mal gelernt. Da das
>> aber ein digitaler Regler sein soll, den jeder der die Simulation
>> benutzt an verschiedenen Stellen schnell einfügen können soll und der
>> damit auf unterschiedlichste Umgebungen passen muss, habe ich das bisher
>> weggelassen.
>
> Die Z-Transformation ist für digitale Regler!

Ja, Begründung und Erläuterung siehe oben. Aber vielleicht liege ich 
hier falsch. Meine Vorlesung zu Regelungstechnik ist schon knapp 8 Jahr 
her...

>> Was ist denn der Vorteil der Euler-vorwärts-Variante des PID-Reglers
>> gegenüber der Implementierung, wie ich sie bisher gewählt habe?
>
> -Validierung
> -Stabilität
> -zeitkritische Regelung kann diskret erstellt werden
>
> Der letzte Punkt ist am wichtigsten für dich, da bei dir die Rechenpower
> fehlt.

Ok, danke! Aber Rechenpower fehlt nicht. Die Simulation läuft auf großen 
Rechnern, möglicherweise auch auf dem LRZ-Cluster der TUM. Die Regelung 
macht nicht einmal einen Faktor von 1e-9 der gesamten Berechnung aus.

von Johannes E. (scootty)


Lesenswert?

uuu schrieb:
> Es gibt Antiwindup & Antiwindup.
>
> Das Windup-Problem ergibt sich normalerweise am begrenzten Stellglied.
> Der Integrator darf nicht weiterlaufen wenn das Stellglied in der
> Begrenzung ist.

Bei mir tritt eher das Problem auf, dass die Totzeit teils zu groß ist.

> Hier, bei der Heizung, hat man ein anderes Problem. Das System ist nicht
> stetig. Ein stetiges Problem wuerde heizen & kuehlen. Der Kuehlteil
> faellt hier weg, wird ersetzt duerch nicht-Heizen. Das System ist daher
> nichtlinear und sollte anders angepackt werden.

Was eignet sich am besten für solche nicht-linearen Probleme?
Ich habe sowas bisher immer einfach linearisiert, z.B. durch Definition 
einer mittleren Heizleistung als 0-Wert.
Oder ich habe eben negative Integralwerte auf 0 gesetzt.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.