ealt=e;// Regelabweichung für nächste Abtastung merken
10
if(y>1023)// Stellgröße auf 0..1023 begrenzen (10 bit PWM)
11
{
12
y=1023;
13
}
14
if(y<1)
15
{
16
y=0;
17
}
18
returny;// Stellgröße zurückgeben
19
}
Das Ganze ist für einen mega32 @ 16Mhz geschrieben und getestet.
OK, über die vielen doubles kann man streiten, den µC interessiert's
aber kaum, die Rechneleistung reicht locker dafür aus. Bei Messung einer
Frequenz für den Istwert (z.B. Drehzahl) per Input-Capture muss zur
Berechnung sowieso long int benutzt werden.
Die Variablen sind:
w => Sollwert (double)
x => Istwert (double)
e => Regelabweichung (double)
esum => Summe Regelabweichung für Integralanteil (double)
Kp => Proportionalanteil (double)
I => Integralantei (double)
D => Differentialanteil (double)
y => Stellgröße (double)
Für die Anti-Windup-Funktion wird bei übersteuertem Stellglied (hier <0
und >1023) der Integralanteil eingefroren (=> esum nicht weiter
aufintegriert). Dadurch wir ein extremer Überschwinger bei
Wiedereintritt in den nicht übersteuerten Bereich des Stellgliedes
vermieden.
Ich wollte das Teil etwas allgemein halten, so kann der Codeschnipsel
für den jeweils benötigten Zweck angepasst werden.
Ein paar Punkte:
- I*Ta sowie D/Ta sind Konstanten und brauchen nicht in Echtzeit
gerechnet zu werden.
- Ich würde dazu wirklich kein double verwenden. Hast du mal die Anzahl
der Taktzyklen ermittelt, die diese Methode benötigt? Interessant währe,
was eine Integerversion dem gegenüber braucht.
- Den Anti-Windup kann man noch verbessern, indem man den I-Anteil auf
den Wert begrenzt, der für eine bestimmte Strecke nötig ist um
Steady-State Fehler völlig zu beseitigen. Weil sonst macht der nämlich
nichts gutes.
- Den D-Anteil legt man (gerade bei digitalen Reglern) besser in die
Rückkopplung. Damit änderst du nichts am dynamischen Verhalten des
Systems, verhinderst aber den sog. Set-Point-Peak, der sonst immer
entsteht, wenn sich der Sollwert schlagartig ändert (und das tut er in
digitalen Systemen praktisch immer).
- Das ganze halte ich für ein heißes Thema für die Artikelsammlung, nach
Regelalgorithmen wird ja hier schließlich häufiger gefragt.
Sehe ich auch so, ich habe auch was gesucht und bin nicht richtig fündig
geworden. Darum habe ich mich etwas eingehender damit beschäftigt.
Könntest du Codebeispiele für deine oben genannten Vorschläge posten?
Das mit den Konstanten ist richtig, werde meinen Code dementsprechend
anpassen.
Wegen Taktzyklen habe ich noch nicht debuggt, aber ich messe und
berechne zusätzlich die Frequenz (Istwert) per ICP und gebe alle
Parameter zum Testen über fprintf auf UART aus. Ebenso wird ein LCD 2x16
in 1/3s-Takt bedient. Also kann's so schlimm nicht sein ;)
Ta hatte ich oben vergessen, ist die Abtastrate, in meinem Fall 20ms per
Output-Compare-INT.
DIe Variablen / Konstanten auf int zu ändern ist ja weniger das Problem.
Je nach Anwendugsfall (Geschwindigkeit, Codegröße) eben.
Thomas wrote:
> Ein paar Punkte:>> - I*Ta sowie D/Ta sind Konstanten und brauchen nicht in Echtzeit> gerechnet zu werden.
Sehr guter Einwand...
> - Ich würde dazu wirklich kein double verwenden. Hast du mal die Anzahl> der Taktzyklen ermittelt, die diese Methode benötigt? Interessant währe,> was eine Integerversion dem gegenüber braucht.
Gibts in der Abteilung Elektronik und µC schon... kommt bald in die
Codesammlung...
Zeitersparniss - sicher einiges!!!
> - Den Anti-Windup kann man noch verbessern, indem man den I-Anteil auf> den Wert begrenzt, der für eine bestimmte Strecke nötig ist um> Steady-State Fehler völlig zu beseitigen. Weil sonst macht der nämlich> nichts gutes.
Stellt sich die Frage, ob man das als Parameter übergeben soll?! Nja...
nichts gutes, is schon richtig nur muss man dafür die Strecke gut
kennen!
> - Den D-Anteil legt man (gerade bei digitalen Reglern) besser in die> Rückkopplung. Damit änderst du nichts am dynamischen Verhalten des> Systems, verhinderst aber den sog. Set-Point-Peak, der sonst immer> entsteht, wenn sich der Sollwert schlagartig ändert (und das tut er in> digitalen Systemen praktisch immer).
Auch ein sehr berechtigter Einwand...
> - Das ganze halte ich für ein heißes Thema für die Artikelsammlung, nach> Regelalgorithmen wird ja hier schließlich häufiger gefragt.
Das ist so seine Geschichte... weil extremst viel Entwicklungsaufwand
dahinter steckt und jeder zumindest einmal einen PID-Regler selbst
geproggt haben sollte und das ganze auch ein wenig verstehn - Stichwort:
Wo drehe ich damit sich wo, was ändert...
>ast du mal die Anzahl der Taktzyklen ermittelt, die diese Methode benötigt?
Taktzyklen nicht, aber ich hab's mal durch den Debugger laufen lassen:
knapp 50µs hat die komplette Funktion gebraucht.
THM wrote:
>>ast du mal die Anzahl der Taktzyklen ermittelt, die diese Methode benötigt?>> Taktzyklen nicht, aber ich hab's mal durch den Debugger laufen lassen:> knapp 50µs hat die komplette Funktion gebraucht.
In Integer od. in double?
THM wrote:
> In double, so wie's oben im Posting ist.
Oh ok... hätt ich mir schlimmer vorgestellt...
Ich hätt schon angefangen zu coden... also Grundgerüst steht... jetzt
muss ich mir mit den Datentypen noch was überlegen... kleine Hint's mit
denen ich allgemein double umgehen kann...
Aber zuerst: betrinken ^^
Ich werd morgen mal eine Version reinstellen!
Schönen Abend noch!
Thomas wrote:
> Ein paar Punkte:>> - I*Ta sowie D/Ta sind Konstanten und brauchen nicht in Echtzeit> gerechnet zu werden.
Wenn I und D konstant sind sollte das der Compiler selbst merken und
optimieren. Kann aber sein dass man "D/TA" explizit so hinschreiben
muss, weil der Compiler das nicht von selbst umsortieren darf
(geändertes Rundungsverhalten).
> - Ich würde dazu wirklich kein double verwenden. Hast du mal die Anzahl> der Taktzyklen ermittelt, die diese Methode benötigt? Interessant währe,> was eine Integerversion dem gegenüber braucht.
Wahrscheinlich ein hundertstel bis tausendstel der Rechenzeit. Aber ohne
Not würde ich mir nicht die Arbeit machen das in Integer umzuschreiben.
Ob der Prozessor z.B. bei einer Temperaturregelung 99% oder 99.99% der
Zeit Däumchen dreht ist egal.
Die avr-libc kennt übrigens kein double, sondern rechnet alles mit
normalem float.
> - Das ganze halte ich für ein heißes Thema für die Artikelsammlung, nach> Regelalgorithmen wird ja hier schließlich häufiger gefragt.
Ja, wäre super wenn sich jemand die Mühe machen würde das in einem
Artikel zusammenzufassen.
"Wenn I und D konstant sind sollte das der Compiler selbst merken und
optimieren."
Das ist richtig, aber wenn die Regelparameter zur Laufzeit angepasst
werden sollen, reicht es diese Terme nur bei Änderungen neu zu
berechnen. Vor allem entfällt dann die Division im Echtzeit-Task. OK,
bei float bringt das wahrscheinlich auch nicht viel.
"Kann aber sein dass man "D/TA" explizit so hinschreiben muss, weil der
Compiler das nicht von selbst umsortieren darf (geändertes
Rundungsverhalten)."
Wie meinst du das? Wegen dem (e-ealt) dazwischen? Also, dass er in
diesem Fall nicht optimiert?
"Wahrscheinlich ein hundertstel bis tausendstel der Rechenzeit. Aber
ohne Not würde ich mir nicht die Arbeit machen das in Integer
umzuschreiben. Ob der Prozessor z.B. bei einer Temperaturregelung 99%
oder 99.99% der Zeit Däumchen dreht ist egal."
Da hast du wohl Recht, aber in den meisten Fällen braucht man das
Ergebnis ja eh als Integer, hier z.B. für die PWM. Und wenn die Regelung
nur ein kleiner Task eines großen Prozesses ist, ist man für jeden
Geschwindigkeitsgewinn dankbar. Wobei sich irgendwann dann natürlich
schon die Frage stellt, ob ein kleiner 8 Bitter für so etwas überhaupt
noch die richtige Plattform ist. Zumal ja seit einiger Zeit auch die
ARM7 stark in den Hobbybereich vordringen...
Es ist natürlich bequem direkt in Real-World-Values zu rechnen, gar
keine Frage.
"Ja, wäre super wenn sich jemand die Mühe machen würde das in einem
Artikel zusammenzufassen."
Zur Regelungstechnik könnte ich hier bestimmt einiges beitragen, leider
bin ich beruflich zur Zeit so stark ausgelastet, dass ich nebenbei kaum
noch den Kopf für so etwas frei bekomme.
NaJa, es werden auch wieder ruhigere Zeiten kommen...
Da ich mir eine Blockspeicherheizung mit Solar- Elektrospeisung einbauen
will und dafür mehrere Regler benötige, habe ich spaßeshalber mal 10
PID-Regler auf einen µC gepackt:
1
doublePID_Berechnung(doublex,doublew)
2
{
3
e[i]=w-x;// aktuelle Regelabweichung bestimmen
4
if((y[i]<1023)&&(y[i]>0))// bei Übersteuertem stellglied Integration einfrieren
5
{// (Anti-Windup)
6
esum[i]=esum[i]+e[i];// Summe der Regelabweichung aktualisieren
i => index des aktiven Reglers
Alle Regelparameter ausse x und w als Array[10] indiziert
Ta => 0.2s (Abtastrate)
Da meine Regelungen fast nur langsame Temperaturregelungen sind kann die
Abtastrate getrost auf 1s oder größer gesetzt werden.
Durch aufruf von Regeln(); werden alle 10 Regler getaktet.
Bin mal auf die Regelalgo von JÜrgen G. gespannt, wird dann auch
implementiert. ;)
THM wrote:
> Bin mal auf die Regelalgo von JÜrgen G. gespannt, wird dann auch> implementiert. ;)
Wie lang haste denn Zeit? Ich hab mein Mega32 Board bei einem Versuch
mit der Teslaspule daneben gegrillt... jetzt kommen nächste Woche die
Bauteile für ein neues! Aber mal so viel: Ich hab das ganze getrennt in
einen Init Funktion die dann eine Struktur an den Regelalgo übergibt!
Damit lassen sich dann viele Regler mit verschiedenen
Reglereinstellungen basteln xP
Tut mir Leid das es so lang dauert!
THM wrote:
> @ JÜrgen G.:>> Nur keine Hetze! Gut Ding will Weile haben! ;)
Das schon... allerdings zu lange Zeit soll man sich auch nicht lassen...
^^
Aber ich hab Erkenntnis bekommen: den µC nicht neben 50kV@800kHz liegen
lassen xP
Ist es für einen "Universal-Eintrag" in der Codesammlung nicht sinnvoll,
z.B. die Grenze von PID->esum zu überwachen?
Bei der Verwendung von Integers könnte es ja schon vorkommen dass der
berechnete Wert über INT_MAX hinausgeht, falls die Reglerparameter
enstprechend gewählt wurden sodass die Stellgröße noch nicht auf
Anschlag ist.
Die Überläufe sollten prinzipiell schon überwacht werden.
Durch die (wenn auch einfache) anti-Windup-Funktion sollte ein Überlauf
von PID->esum eigentlich nicht vorkommen.
Falls doch wäre der Parameter für I extrem übredimensioniert. Also würde
ich besser die Regelparameter begrenzen.
In dem Fall von PID->esum, wird durch die Anti-Windup-Maßnahme eh
begrenzt... was nicht nur den eher unkritischen Fall ausschließt das
einfach der Wert über die Int-Grenzen läuft, sondern das Regelverhalten
des Digital-Reglers um einiges verbessert!
THM wrote:
> Falls doch wäre der Parameter für I extrem übredimensioniert. Also würde> ich besser die Regelparameter begrenzen.
Achja... Der I und D Anteil sind in ms anzugeben, falls nötig ist ein
größerer Datentyp erforderlich!
und @THM: willst dich nicht mal registriern? ^^
In der oben beschriebenen Variante wird der Anti-Windup auch nicht
funktionieren, da y eine lokale Variable ist.
Sie müsste also noch der globalen Struktur hinzugefügt werden.
@ JÜrgen G.:
>willst dich nicht mal registriern?
Bin ich schon, wechsle nur öfter den Rechner (Arbeitsplatz) und habe
mein Login nicht mit (Faul!).
Werde mich aber bessern!
ad JÜrgen G. (psicom) Datum: 18.11.2007 18:42
der so vorgestellte Algorithmus kann gar nicht richtig funktionieren
(hättest du beim test mit dem board aber bemerkt).
Da y eine lokale Variable ist, ist die Zeile
if ((y < 1023)&&(y > 0))
nutzlos bzw. die Entscheidung undefiniert, da y keinen zugewiesenen Wert
hat (zufälliges Bitmuster)
Des weiteren würde bei der Berechnung über die Zeile
y =
(PID->Kp*PID->e)+(PID->I*PID->Ta*PID->esum)+(PID->D*((PID->e-PID->ealt))
/PID->Ta); // Reglergleichung
schon bei kleinster Regelabweichung der gültige Zahlenbereich für int
überlaufen ( I*Ta*esum wird sofort zu groß ).
Bei einer Implementierung muss man unbedingt auf die Datentypen achten,
und auch darauf, ob bei der Addition nicht ein 2er Komplement-Überlauf
der signed integer auftritt.
Bin selbst gerade dabei, einen Regler in Assembler zu programmieren, der
möglichst nur mit schneller Verschiebemathematik auskommen soll.
PID->ealt=PID->e;// Regelabweichung für nächste Abtastung merken
55
if(PID->y>1023)// Stellgröße auf 0..1023 begrenzen (10 bit PWM)
56
{
57
PID->y=1023;
58
}
59
if(PID->y<1)
60
{
61
PID->y=0;
62
}
63
// Stellgröße zurückgeben
64
}
So, jetzt könnte man natürlich auch noch drüber streiten ob man x und w
auch noch in die Struktur übernimmt od. nicht...
Jetzt ist der Zugriff auf den Ausgangswert über Regler1.y möglich!
Team wrote:
> Also der schnelle Hack mit dem Float darf aber keiner sehen ;-)> War sowas auch in deiner Tesla-Anlage programmiert?
hab ich float geschrieben?
ach... tatsächlich... das tut natürlich der rechenzeit nicht gut...
sollte eigentlich long int sein... also 32bit
nö meine teslaanlage ist mit solid state ansteuerung... allerdings ohne
µC... aber meiner is zu weit in der nähe gelegen und hat was
abbekommen...
Hauke Radtki wrote:
>>zu weit in der nähe> Interessanter Ausdruck ;)
Bin Österreicher... mit Deutsch an sich haben wirs nicht so...
THM wrote:
> Sind long int, float und double beim AVR nicht alle 32 bit?
jup glaub schon... nur das float nachkommazahlen darstellt... und der
AVR keine floatingpoint unit hat tut der sich ein wenig schwerer...
OK, habe JÜrgen G's Version mal mit einer Ansprechschwelle ausgestattet.
Diese ist für langsame Regelungen (Temperatur) um das Stellglied
(Stellantrieb, z.B. Heizungsmischer) zu schonen, also möglichst wenig
Aktivität (Steps). Diese Antriebe werden mit Impulsen verschiedener
Länge und Häufigkeit (Freqenz) angesteuert.
Die Regelparameter müssen natürlich geändert werden, da Kp nun von der
Ansprechschwelle abhängt.
1
typedefstruct
2
{
3
intTa;// Abtastzeit in ms
4
intI;// Integralanteil
5
intKp;// Verstärkung
6
intD;// Differenzieller Anteil
7
inte;// Regelabweichung
8
floatesum;// Summe der Regelabweichungen
9
intealt;// Regelabweichung zum ZP z-1
10
inty;
11
intAS;// Ansprechschwelle
12
}
13
14
voidPID_Init(void)// In der Init müssen die Reglereinstellungen gemacht werden
15
{
16
Regler1.AS=1;
17
Regler1.y=0;
18
Regler1.Ta=10;
19
Regler1.I=100;
20
Regler1.D=0;
21
Regler1.Kp=1;
22
Regler1.esum=0;
23
Regler1.e=0;// Für weiteren Regler einfach Neue Variable erstellen
24
Regler1.ealt=0;// und hier Werte mit Regler2.xx=0 einstellen
25
}
26
27
// der Übersichtlichkeit halber nur diesen Ausschnitt
28
29
if((PID->e>=AS)||((PID->e*(-1))>=AS))// Betrag der Differenz prüfen
Und Thilo, wie gehts den Lüftern mit der neuen Version des Reglers?
Das mit der Ansprechschwelle find ich keine blöde Idee... nur wie wirkt
sich das ganze auf die Regelcharakteristik aus?
Der Lüfter läuft auch mit der neuen Version prima.
Nur ist hier die Ansprechschwelle weniger von Nöten. Die ist mehr für
langsame Regelungen mit Stellantrieb (Getriebemotor) gedacht. Der nutzt
sonst durch das ständige Regeln sehr schnell ab.
Die Regelcharakteristik ändert sich natürlich grundlegend, da die
Verstärkung (Kp) bei Überschreiten der Ansprechschwelle viel stärker zum
Eingriff kommt. Ist aber alles handhabbar und reine Einstellungssache.
Den D-Anteil kann man bei langsamen Regelungen sowieso weglassen.
esum müsste ein long int sein, da es sich ja aufsummiert könnte bei 16
bit (ADC) die int - Grenze schnell überschritten werden. Ob ich jetzt
double, float oder long int habe ist beim AVR egal, sind jedesmal 32
bit. Lediglich die Rechenzeit könnte sich minimal unterscheiden.
Bei langsamen Regelungen - wie ich sie habe - ist das aber zweitrangig.
Hallo
Vielen Dank für die Info. Ich fragte deshalb, weil sich das ungünstig
auf die Programmgrösse und die Programmgeschwindigkeit auswirken könnte.
Der C-Compiler von Microchip würde z.B. die floating-point library
einbindene (unnötiger Verbrauch von Speicher) und die Gleichung zum Teil
in floats berechnen (Geschwindigkeitsverlust).
Beste Grüsse
Martin
Thilo M. wrote:
> Ob ich jetzt double, float oder long int habe ist beim AVR egal, sind> jedesmal 32 bit. Lediglich die Rechenzeit könnte sich minimal unterscheiden.
Jup, weils mich interessiert hat, hab ich jetzt nachgeforscht... Ich hab
leider keine Codegrößenangaben od. exakte Rechenwerte weil der
PID-Regler möglich auf jedem µC laufen sollte!
Long Int hat 32-bit
float hat 32-bit
Das einzige was die beiden unterscheidet ist die Darstellungsweise:
Int ist allerdings in 2er komplement und float ist in matrisse und
exponent aufgeteilt, was ein rechnen mit long int, der einfachheit
halber schneller macht! CPU's von PC's haben allerdings eine eigene
floatingpoint unit drinnen, die nur für solche zahlen die eben aus
matrisse und exponent bestehen gemacht ist und diese ebenfalls mit einem
rechentakt abarbeiten können!
Faktum: PID->esum ist LONG INT
Klingt verlockend!
Nur muss ich das Ganze mal in Hardware verwirklichen, sprich meine
Heizungsanlage aufrüsten. Dann kann ich das Teil in der Praxis Testen.
Also ADC, evtl. DAC, SSR zur Mischersteuerung (Stellantriebe) und PT100
Temperaturmessung sind als Einzelkomponenten getestet und werden jetzt
'verheiratet'.
Dann gilt meine Aufmerksamkeit wieder der Regelungstechnik. ;)
Thilo M. wrote:
> Nur muss ich das Ganze mal in Hardware verwirklichen, sprich meine> Heizungsanlage aufrüsten. Dann kann ich das Teil in der Praxis Testen.> Also ADC, evtl. DAC, SSR zur Mischersteuerung (Stellantriebe) und PT100> Temperaturmessung sind als Einzelkomponenten getestet und werden jetzt> 'verheiratet'.
Es gibt immer was zu tun xP
Hallo zusammen, zwar ist der Thread schon etwas älter, jedoch denk ich
das es trotzdem noch passendürfte.
Ich bin vor kurzem auf den oben aufgeführten C-Code des PID Reglers
gestoßen und wollte ihn natürlich sofot mal testen, jedoch bekomm ich
mit diesem Regler so konfiguriert wie oben beschrieben egal was ich für
Soll und ISTwerte eintrage, immer als Stellgröße (y) 1023 raus bei
positivem e ( ISTwert- Sollwert) und y=0 bei negativem e....
wenn ich jetzt z.B. als sollwert 600 und als istwert 400 eintrage
kommt als y immer 0 raus... vertausche ich diese zwei werte, kommt als y
immer 1023 raus...
versteh nicht so ganz was ich falsch mache...
vielleicht weiß jemand Rat...
lg Thomas
Zumax schrieb:
> versteh nicht so ganz was ich falsch mache...
Die Frage ist immer, was passiert bei einem Stellwert.
Wenn der Stellwert positiv ist und der Regelkreis so reagiert, dass
dadurch die Istgröße abnimmt, dann passt ja alles. (bzw. umgekehrt)
Bsp. y sei ein Wasserventil
0 bedeutet ... komplett offen
1023 bedeutet ... komplett zu
Du gibst jetzt vor, dass die Durchflussmenge 600 l/min betragen soll.
Gemessen werden 400 l/min. Als Folge davon erredchnet der PID Regler
einen y-Wert von 0. Also: Ventil volle Pulle auf.
Was in dem Fall ja auch Sinn ergibt.
Vielen Dank Karl heinz Buchegger, für die absolut rasche Antwort,
soweit versteh ich das nun schon, da ja wie im Beispiel erklärt die
Wassermenge erhöht werden muss wird das Ventil erst mal voll aufgedreht,
damit erstmal mehr fließt, jedoch möchte ich den Fluß ja auf 600 l/min
begrenzen und nicht mit 1023 l/min fahren, muss ich die Funktion im
zweiten Durchlauf nachdem y=0 oder y=1023 nun erneut aufrufen und zwar
nun mit dem istWert 1023 bzw 0 und dem Sollwert von 600?? Also die
Funktion einfach nochmal bzw so lange aufrufen bis sich der Wert
einpendelt??? Jedoch mit dem neu berechneten ISTWERT aber natürlich dem
selben gewünschten SOLLWERT.
Wenn dem so wäre, könnte ich ja nie sagen wie oft ich die Funktion
aufrufen muss bis sich der Wert denn nun endlich schön eingependelt hat?
dachte die Funktion macht dies schon automatisch, also die
einpendelung..
Ich hoffe mal ich konnte das irgendwie halbwegs verständlich ausdrücken?
LG Thomas
Hallo
Am 3.11.2007 wurde von JÜrgen G. geschrieben:
> - Den D-Anteil legt man (gerade bei digitalen Reglern) besser in die> Rückkopplung. Damit änderst du nichts am dynamischen Verhalten des> Systems, verhinderst aber den sog. Set-Point-Peak, der sonst immer> entsteht, wenn sich der Sollwert schlagartig ändert (und das tut er in> digitalen Systemen praktisch immer).
Mich würde das mit dem D-Anteil in der Rückkopplung genauer
interessieren.
Wie muss da die Software dazu aussehen.
Danke,
>Mich würde das mit dem D-Anteil in der Rückkopplung genauer>interessieren.
Das würde mich auch mal interessieren. Hab schon danach geschaut aber
nix darüber gefunden. Bin zwar keine Regelungstechnik-Guru, habe aber
schon mit Reglern zu tun gehabt, aber das ist mir (wissentlich) noch
nicht über den Weg gelaufen.
Das Einzige was ich mal versucht habe, ist ein PT1-Messglied in der
Rückführung wegen der großen Verzögerung zu "kompensieren", was dann
letzendes in einer "nicht-kausalen" PD-Rückkopplungskorrektur geendet
hat, die nur Müll produzierte... hab's dann aber auch nicht
weiterverfolgt...
Zumax schrieb:
> [...]> Wenn dem so wäre, könnte ich ja nie sagen wie oft ich die Funktion> aufrufen muss bis sich der Wert denn nun endlich schön eingependelt hat?> dachte die Funktion macht dies schon automatisch, also die> einpendelung..>
...ist das mittlerweile klar geworden?
Hallo,
das mit dem D-Anteil in der Rückkopplung, der anscheinend bei digitalen
Regelungen wichtig ist, würde mich auch brennend interessieren.
Entwerfe momentan ein Regler für eine Hydralik und da wäre es
interessant, ob ich das mit einbeziehen muss.
Grüße,
hacker
Hallo, ich hab mal eine Frage bezüglich der Parameter.
@ Thilo M.
Ich nutze die Standardwerte.
Wie kann ich die Überschwinger kompensieren?
Gibt es da eine Faustformel nach der man die Werte wählen kann?
Wenn ich den I Anteil auf null setze (ist doch dann nur noch ein
PD-Regler) ändert sich nichts großartig.
(Die gelben Peaks sind nur Darstellungsfehler.)
Nimm bei dieser schnell reagierenden Regelung mal den D-Anteil 'raus.
Dann mit P und I-Anteil experimentieren. Ich denke mal, die
Überschwinger kommen vom D-Anteil.
@ Thilo
Hat ein Weilchen gedauert, aber jetzt funktioniert es.
Hab etwas an den Werten gespielt und bei einem sehr niedrigen I-Anteil
die besten Ergebnisse, ohne I -Anteil ist die Regelung nicht so schön
schnell.
Vorher hatte ich auch eine 8 Bit PWM, das war bestimmt das größte
Problem.
Jetzt ist es eine 14 Bit PWM.
(eigentlich nur eine aufgebohrte 8 Bit, der Wert springt also immer
zwischen zwei Werten)
Die restlichen hochfrequenten Rippel bekomme ich mit einem LC-Tiefpass
weg.
mfg Peter
Kann jemand bitte noch mal seinen aktuellen Source-Code für den PID
Regler senden?
Gibt es eigentlich schon einen WIKI-Arikel zu PID-Reglern auf
mikrocontroller.net?
@Peter Bandhauer:
Mit welchem Programm hasst du denn die schönen Graphen erstellt?
Sind das simulierte Werte oder sind die aus einer realen Messung
entstanden?
Das sind reale Werte von einem StepUp Wandler.
Beim ersten Bild: Eingangs-Strom/Spannung , Ausgangs-Strom/Spannung und
der aktuelle PWM-Wert.
Beim zweiten Bild ohne Strommessung, also Uin. Uout, PWM.
- mit 470 Ohm: von 9V -> 7V -> 10V
Jetzt habe ich noch 115 Ohm parallel geschaltet um zu testen wie weit
die Spannung einbricht bei Lastwechsel.
10V @ 470 Ohm => 21.3mA
10V @ 92 Ohm => 108.7mA
Es fließt jetzt 5 mal so viel Strom und die Spannung bricht bis auf 9V
ein.
Danach probiere ich noch 11V -> 12V -> 9V -> 6V -> 12V
Man sieht schön wie sich der PWM-Wert (grau) verhält, die Kurve sieht
optimal aus.
Ich habe dahinter ein LC Tiefpass, es kommen also keine Peaks am Ausgang
an.
Ich habe in Java nur die Linienn in ein Panel gezeichnet und ein paar
Slider um U-Soll und die P,I,D Werte an den Controller zu übertragen.
Hi,
ich hätte hier mal eine Frage zur Anti-WindUp-Maßnahme:
1
if((y<1023)&&(y>0))
2
{
3
esum=esum+e;
4
}
5
//...
6
//------------------------------
7
if(y>1023)
8
{
9
y=1023;
10
}
11
if(y<1)
12
{
13
y=0;
14
}
Kann es sein, dass diese nie ausgeführt wird?
Die Abfrage überprüft ob y größer oder kleiner als die Grenze ist.
Also ob y=1024 bis + unendlich oder -1 bis - unendlich ist?!
Aber durch die Begrenzung am Ende wird y mit minimal 0 oder maximal 1023
überschrieben und kann demnach nie kleiner 0 oder größer 1023 sein
oder?!
Also müsste die Abfrage für WindUp eigentlich so lauten:
1
if(y<=1023)&&(y>=0)
2
{...}
Ich steh hier geraude auf dem Schlauch und hoffe Ihr könnt mir
weiterhelfen.
Alex97 schrieb:> if (y<=1023) && (y>=0)
In dem Fall ist alles okay, er muss keinen Fehler abfangen ... also ist
die Abfrage dann so wie du es geschrieben hast sinnlos.
Hallo,
@Alex97:
Beim Anti-Windup geht es doch darum, das bei Vollaussteuerung der
Stellgröße Y eine weitere Aufsummierung der Abweichung esum verhindert
werden soll.
Wenn man nämlich länger im Bereich der Vollaussteuerung ist, wird der
I-Anteil ständig weiter steigen und diese Summe muss später wieder
abgebaut "werden", was nur geht, wenn die Regelabweichung e entsprechend
lang negativ ist, was man ja nicht will.
Die Vollaussteuerung ist hier 0 oder 1023 für die 10-Bit PWM.
( Man hätte es vielleicht auf den Bereich [0..1] umrechnen können, das
wäre anschaulicher, aber nicht praktischer. )
> if (y<=1023) && (y>=0)
führt aber dazu, dass immer aufsummiert wird, denn Y kann nur aus dem
Bereich 0..1023 sein.
Dann ist der Anti-Windup Effekt weg.
Apropos Anti-Windup:
http://de.wikipedia.org/wiki/Regler suche Wind-Up-Effekt:
/Dem tritt man mit der Begrenzung des I-Anteils auf die
Stellgrößen-Grenzen entgegen (Anti-Windup)./
Wenn ich das richtig lese, würde dort nicht
1
if((y<1023)&&(y>0))
2
{
3
esum=esum+e;
4
}
sondern dies ausgeführt:
1
// maximale Summe bei der alleine der Integralteil für Y= Y_max sorgt
Horst Hahn schrieb:> // maximale Summe bei der alleine der Integralteil für Y= Y_max sorgt>> esum_max = Y_max/(I*Ta ) // hier 1023>> esum_min = Y_min/(I*Ta ) // hier 0>> esum = esum + e;>> if (esum < esum_min)>> { esum = esum_min;}>> if (esum>esum_max)>> {esum =esum_max;}>>
Hallo Horst,
ich programmiert derzeit eine digitale PID Regler und habe auch riesige
problem mit der Anti windup. frühe habe wie die ander gemacht;
if ((y < 1023)&&(y > 0))
{
esum = esum + e;
}
hat nie funktioniert. nach ein paar Tage Recherche habe ich wie du
umgestellt. es klappt ein bisschen aber nicht ganz und ich weiß nicht
warum.
beim start des systems ist bei mir y schon initialisiert auf den soll
oder einen wert nahe den soll. ich rechne e=x-w und es kommt sofort e
negativ, was normal ist. Nach dem ersten Durchlauf ist e negativ bzw.
esum
entspricht diesem Fall bei dir
if (esum < esum_min)
>> { esum = esum_min;}
z.B meine ymax=1000
ymin=800.
soll ich esum_min auf 0 oder 800 begrenzenn oder wie ? oder hat es mit
negative Werte zu tun? wie kann man das proble lösen
danke
Sed
> Beitrag melden | Bearbeiten | Löschen |
Hallo,
hast Du Deine Regelstrecke mit den "richtigen" Werten für K_I,K_P und
K_D bestückt?
http://de.wikipedia.org/wiki/Faustformelverfahren_(Automatisierungstechnik)
Anti Wind-up erstmal weglassen.
Taste Dich doch zuerst mit K_i = K_D = 0 an den passenden K_p(P) Wert.
Zitat:
P K_p = 1/K_s \cdot T/T_t
PI K_p = 0.9/K_s \cdot T/T_t, T_n = 3.33 \cdot T_t
PID K_p = 1.2/K_s \cdot T/T_t, T_n = 2 \cdot T_t, T_v = 0.5 \cdot T_t
/Zitat
Oder stelle, falls möglich, als Wunschwert 0,5 des Bereiches ein und
drehe K_p(Test) von 0 langsam solange hoch, bis es schwingt dann ist
K_p(P) = 0,5*K_p(Test).
Dann K_p(PI) auf 0,9*K_p(P) und passenden K_i(PI) suchen
Dann K_p(PID) wieder auf 1,2* K_p(P) und K_i(PID) auf 2/3*K_i(PI) und
K_d bestimmen.
Lange Rede, wenig Sinn, ich schätze Dein K_i ist zu groß.
HALT :
Du solltest, wenn Du den Sollwert vorgibst "esum" so berechnen, das er
diesem entspricht.
Denn man muss sich klar machen, dass bei einem PI(D)- Regler im
störungsfreiem, eingeregeltem Zustand des Reglers ist e=ealt = 0.
Also nur der I-Anteil bestimmt die Stellgröße Y.
also müßtest Du zu Beginn
esum = Y(geschätzt)/(I*Ta); setzen.
Y_min,max bleiben gleich, sodass der komplette Stellgrößenbereich auch
genutzt werden kann.
Aber warum gibst Du Y(w) schon vor?
Der Regler sollte doch, wenn die Regelabweichung sehr gross ist, auch
mit Y_max oder Y_min möglichst schnell den neuen Zustand erreichen
können und nicht nur mit einem kleineren Wert.
P.S.
1
if((y<1023)&&(y>0))// bei Übersteuertem stellglied Integration einfrieren
Halte ich für einleuchtender, dass das schneller einschwingt.
Das müsste man mal testen.
Aber ich bin der Meinung, das es so sicherer ist,esum anschaulicher
durch y_i ersetzt und innen y_i zu begrenzen.
Das könnte Dir auch aufzeigen, das bei Dir der I-Anteil zu groß war,
oder die Berechung von e falsch skalierte.
Deshalb alles auf 0..1 rechnen.
1
[c]const
2
doubley_min=0;
3
doubley_max=1023;//(10 bit PWM)
4
doublex_min=0;
5
doublex_max=255;//z.B 8_Bit ADC
6
doubleTa=???;
7
doubleKp=????;
8
doubleKi=????*Ta;
9
doubleKd=????/Ta;
10
11
// w und x so umrechnen das sie aus dem Bereich 0..1 sind
12
//Spannung von 0..12 wird eben 0..100% von 12 Volt
13
doublePID_Berechnung(doublex,doublew)
14
{
15
e=w-x;// aktuelle Regelabweichung bestimmen
16
if((y<1)&&(y>0))// bei Übersteuertem stellglied Integration einfrieren
17
{// (Anti-Windup)
18
y_i=y_i+Ki*e;// Summe der Regelabweichung aktualisieren
19
}
20
y=Kp*e+Y_i+kd*(e-ealt);// Reglergleichung
21
ealt=e;// Regelabweichung für nächste Abtastung merken
22
if(y>1)// Stellgröße auf y_min..y_max begrenzen (10 bit PWM)
Wow ...
Da wollte ich nur einen Lüfter auf Drehzahl halten, laß was von PID, und
dann dieser ganze Stoff hier kopf qualm.
Jungs (Mädels ;)) - Ihr seid meine Götter !!
Werde mal schauen, ob ich Eure Informationen in einen (halbwegs)
lauffähigen Basic-Code (wie man so lesen kann, recht lahmer µC)
umgesetzt bekomme.
Ich erhoffe mir, daß ich mit Euren Code-Beispielen mein Ziel erreiche -
suchte nach 'Pseudo Code'/'Pseudo Basic'.
Werde mich, nach Hilfe schreiend g (stellt Euch ein schreiendes Pla
.... äh, Kleinkind gg vor) bestimmt noch Mal an Euch wenden.
Super, daß es Leuz wie Euch gibt
MtR (mit tierischem Respekt)
Pboy
Hallo,
welche Werte sollte man für eine Stellgröße-Ausgabe für eine Heizung
machen?
Und in welchen Zyklus soll berechnet werden?
Vor allem Fussbodenheizungen und Wandkollektoren kommen immer zum
Einsatz.
Der PID Regler soll das Ventil regeln, welches am Heizkörper montiert
ist.
Ich hab mal etwas getestet, aber er gibt anfangs (wenn Ist 2° unter
Soll) 3% aus und dann kontinuirlich 100%
Auch wenn die Ist weit über der Soll liegt.
Für Hilfe wäre ich dankbar,
Fohnbit
Hallo,
Fußbodenheizung ist doch viel zu träge, als dass dort P-Regler,
geschweige denn PID Regler Sinn machen.
Ich schätze/rate mal die Zeitkonstante.
Das Badezimmer hat 11 qm.
8,5 qm sind beheizt. Der Zementestrich ist 7 cm stark+ 1 cm Fliesen also
0,08 m.
Das ganze wiegt wohl 8,5*0,08*1900 ~ 1300 kg.
http://www.schweizer-fn.de/stoff/wkapazitaet/v2_wkapazitaet_baustoffe.htm
Spezifische Wärmekapazität = 1 Kj/kgK
Also muss man 1300 KJ an Wärmeenergie in den Heizestrich einbringen,
damit dieser sich bequemt, 1 Grad wärmer zu werden.
Jetzt brauche ich bei -14 Grad aussen im Bad maximal 720 Watt ( mit
allen Aufschlägen für Lüftung/Wärmebrücken..).
Entsprechend ist der maximale Durchfluss eingestellt.
Die Aufheizzeit für 1 Grad ohne Wärmeabgabe wäre schon 1300 [KJ/K] / 720
[W=J/s] /1 [K] = 1805 [s] = 30 min
Jetzt sind noch Wände (37 qm )und Decke( Ok.Abgehängt. Rigips mit
Schalldämmung obenauf ) im Bad die auch Wärme aufnehmen. Also dauert es
noch länger.Denn die müssen ja um 0.5 Grad wärmer werden.(1 Grad auf der
Innenseite und 0 auf der Aussenseite)
Also c~880 J/kgK und rho etwa 1600 kg/cbm und 17,5 cm stark
(KS-Vollstein)
ergibt: 880*37*1600*0,175 J/K = 9000 Kj/K bei 0,5 Grad eben 4500 KJ
Also um die Wände aufzuheizen auch eine ewige Zeit von fast 60 min.
Wenn man das vereinfacht abschnittweise betrachtet wird erst der Boden
warm und dann die Wände.Nach 1,5 Stunden merkt man was.
Das lohnt sich eine PID Regelung nicht. Die Aussentemperatutren ändern
sich ja schneller ;-)
Die Raumthermostate haben eine Hysterese/Schaltabstand zwischen ein und
aus von 0,5 Grad.
Die Schaltventile/Stellantriebe bewegen sich in 3min Sekunden von auf
nach zu, das ist doch schnell genug.
Horst Hahn schrieb:> Das lohnt sich eine PID Regelung nicht. Die Aussentemperatutren ändern>> sich ja schneller ;-)
So ist es.
Und es gilt zu beachten, dass die Stellzeit des Ventils einen I-Anteil
darstellt. Folglich braucht man einen Dreipunkt-Schrittregler für so ein
träges System mit Stellantrieb, um einen PI-Regler zu realisieren
(I-Anteil kann zusätzlich zu dem des Stellantriebes addiert werden,
falls nötig).
In meinen Heizkreisreglern ist die Außentemperatur stark (3 Minuten)
gedämpft, der Regler macht Impulse zwischen 0.8s und 4s, Pausen- und
Impulslänge hängen von der Regelabweichung und der Verstärkung ab.
Eine Ansprechschwelle von mindestens +/- 0.5°C um den Sollwert macht das
System ruhiger (weniger Regelsteps).
Hallo,
und durch diese Impulse wird aus dem Auf/Zu-Stellantrieb ein
kontinuirlicher?
Das sieht man man sicher am Durchflußmesser.
Das eigentliche Problem was ich dann hätte, wäre die Überlagerung der
Heizkurve.
Ich müsste ja dann jede Vor und Rücklauftemperatur messen, um mit der
Raum- und Außentemperatur zusammen den optimalen Durchfluß einzustellen.
Momentan habe ich nur die Heizkurve eingestellt und die alle Ventile
voll auf.
Ausser bei starken Temperaturwechseln funktioniert das sehr gut ( dann
habe ich plötzlich 21.0/ 19,5 statt 20.3 ) , vielleicht auch deshalb,
weil die Südseite bis Anfang März völlig verschattet und die Sonne in
der Heizperiode kaum eine Rolle spielt und natürlich die enormen
Wandmassen.
Ein Bekannter mit Euromac?-Haus (Styropor Schalensteine mit Beton
verfüllt ) hat alle Wandinnenseiten 50 mm Styropor mit Gipskarton
verkleidet, der bekommt seine Fussbodenheizung nicht in den Griff.Wenn
ein paar Leute kommen wird es direkt warm.
Er braucht für sein komplettes Haus 100 W/K , wie soll man das noch
regeln, wenn pro Person 100 W hinzukommen, die sich meistens in der
Küche aufhalten?
Horst Hahn schrieb:> Ich müsste ja dann jede Vor und Rücklauftemperatur messen, um mit der> Raum- und Außentemperatur zusammen den optimalen Durchfluß einzustellen.
Naja, an einer modernen Heizung musst du normalerweise gar nicht am
Thermostatventil eingreifen. Wenn der hydraulische Abgleich (jeder
Heizkörper im Durchfluss so eingestellt, dass auch ohne
Thermostatventilkopf der Rücklauf nicht wärmer als der Rücklauf +1..2°C
wird) ordentlich gemacht ist, kann mit dem Heikreisvorlaufmischer (an
der Heizung) mittels Außentemperaturkennlinie der gesamte Vorlauf
geregelt werden. Dann braucht's nur eine Regelung.
Horst Hahn schrieb:> Ein Bekannter mit Euromac?-Haus (Styropor Schalensteine mit Beton> verfüllt ) hat alle Wandinnenseiten 50 mm Styropor mit Gipskarton> verkleidet, der bekommt seine Fussbodenheizung nicht in den Griff.Wenn> ein paar Leute kommen wird es direkt warm.
Naja, Styropor ist suboptimal als Dämmung, weil nicht diffusionsoffen.
Heute nach EnEV auch als Dämmung nicht mehr erlaubt.
Wenn die Fußbodenheizung sich nicht regeln lässt gibt es mehrere Gründe.
Zum Einen kann sie überdimensioniert sein, oder die einzelnen Schleifen
schlecht oder gar nicht hydraulisch abgeglichen.
Zum Anderen kann die Heizung zu heißes Wasser zum Vorlauf bringen, der
Effekt ist dann, dass das Stellglied in einem extrem ungünstigen Bereich
regeln soll (Zu / fast Zu).
Darum ist ein Pufferspeicher, der nicht höher als 40°C aufgeladen wird
für eine Fußbodenheizung ideal. Ein Öl/Gasbrenner, der vllt. noch
überdimensioniert ist, läuft extrem unwirtschaftlich (ständig an-aus)
und die Regelung kriegt das heiße Wasser im Zulauf nicht in den Griff.
Horst Hahn schrieb:> Er braucht für sein komplettes Haus 100 W/K , wie soll man das noch> regeln, wenn pro Person 100 W hinzukommen, die sich meistens in der> Küche aufhalten?
Ein solches Haus braucht eine kontrollierte Wohnraumlüftung, sonst
kriegt man da weder die Temperatur noch den Schimmel in den Griff.
Hallo.
Der oben beschriebene Regler funktioniert sehr schön, sobald man ihn mit
vernünftigen Werten für P, I und D versorgt. Diese werte sind in dem
vorliegenden Fall aber nur Bits, virtuell. Wie komme ich jetz zu
SI-Einheiten?
Ich will einen universellen, flexiblen Regler bauen, der die Werte Kp,
Tv und Tn von außen (UART) bekommt. Gewünscht ist, dass ich bei einer
unbekannten Strecke das 2. Verfahren von Ziegler und Nichols anwenden
kann. Also I und D auf 0, P hochdrehen bis es schwingt, Periode messen
und aus der Periode Tn und Tv einstellen (Kp = 0.6 * Kpkrit, Tn = 0.5 *
Tkrit, Tv = 0,125 * Tkrit).
Meine Überlegungen vorab:
1. Die Samplingrate muss genau sein und in die Formel eingehen (ist hier
bereits).
2. Tn (was hier I entspricht) muss unter den Bruchstrich, wie in der
normalen PID-Regler-Formel. Also höhere Werte für Tn sollen den I-Anteil
des Reglers kleiner werden lassen.
Dan würde die Formel so aussehen:
y = (Kp*e)+((Ta*esum)/I)+(D*((e-ealt))/Ta);
Was meint Ihr dazu?
Die Regler-Parameter sind Faktoren und haben mit dem SI nichts zu tun.
Wenn du deinen Regler mit Floating Point betreibst, kannst du in Grenzen
der Auflösung dieses Typs deine Größen als SI benutzen und musst dann
beim Einlesen und Ausgeben entsprechend umrechnen.
Ich habe da mal eine kleine Frage zur Implementierung des Totbandes und
der Ansprechschwelle.
Weiter oben in den Beispielen ist diese Funktion immer vor der
eigentlichen Berechnung gemacht worden. Nun ist es ja so das bei Reglern
allgemein und vor allem mit I und D Anteil die Intervalle der
Reglerfunktionsaufrufe sehr genau eingehalten werden sollten. Durch die
Implementierung der Ansprechschwelle vor dem Regelalgorithmus ist dies
jedoch nicht mehr gegeben, was die Regelqualität negativ beeinflusst.
Weiterhin wird der Regler innerhalb des Totbandes komplett deaktiviert.
Ich würde die Schwellbegrenzung eher nach der Berechnung machen.
Was meint ihr dazu oder seh ich da jetzt was grundlegendes falsch?
Michael Knight schrieb:> Nun ist es ja so das bei Reglern> allgemein und vor allem mit I und D Anteil die Intervalle der> Reglerfunktionsaufrufe sehr genau eingehalten werden sollten.
Das stimmt, der Intervall sollte interruptgesteuert aufgerufen werden,
damit die zeitlichen Abläufe stimmen.
> Durch die> Implementierung der Ansprechschwelle vor dem Regelalgorithmus ist dies> jedoch nicht mehr gegeben, was die Regelqualität negativ beeinflusst.
Da der Regler innerhalb des Totbandes deaktiviert ist, findet keine
Regelaktivität statt. Also muss auch der Intervall nicht stattfinden.
Die Ansprechschwelle dient zum Ein- bzw. Ausschalten des Reglers. Die
Größe der Ansprechschwelle beeinflusst selbstverständlich den P-, I- und
D-Anteil, da bei überschreiten der Ansprechschwelle die Regelabweichung
von der Größe der Ansprechschwelle abhängt.
Hallo Thomas,
du hast geschrieben (2. Eintrag), dass man den D-Anteil lieber in die
Ausgangsrückführung steckt um den großen Sprung der Regelgröe zu
vermeiden. Braucht man dann bei diesem Verfahren also kein
Verzögerungsglied mehr?
Grüße, Gunnar
Hallo Thomas,
du hast geschrieben (2. Eintrag), dass man den D-Anteil lieber in die
Ausgangsrückführung steckt um den großen Sprung der Regelgröe zu
vermeiden. Braucht man dann bei diesem Verfahren also kein
Verzögerungsglied mehr?
Grüße, Gunnar
Hallo Leute!
Das Thema scheint zwar tot zu sein, aber ich versuche es dennoch mal.
Ich bin ganz neu hier und hab direkt eine Frage.
Ich muss für die Hochschule einen PI-Regler in C schreiben. Das Ziel ist
es einen Spannung zu Regeln und zwar darf dieser nicht mehr als 2,5V
betragen.
ICh habe den Code von Thilo M. benutzt, hab mein PWM Signal konfiguriert
usw. aber die myAVR Workpad Sofware wirf jede menge Fehler.
Ich hab schon mal uC programmiert, leider ist das aber etwas her und
mein C ist estwas eingerostet... Ich hoffe ihr erschlagt mich nicht
gleich... =)
Also hier erstmal der Code (hab den D-Anteil raukommentiert, da ich nur
einen PI-Regler benötige):
//----------------------------------------------------------------------
// Titel : C Grundgerüst für das myAVR-Board
//----------------------------------------------------------------------
// Funktion : ...
// Schaltung : ...
//----------------------------------------------------------------------
// Prozessor : ...
// Takt : 3.6864 MHz
// Sprache : C
// Datum : ...
// Version : ...
// Autor : ...
//----------------------------------------------------------------------
#define F_CPU 3686400 // Taktferquenz des myAVR-Boards
#include <avr\io.h> // AVR Register und Konstantendefinitionen
#include <stdint.h>
typedef struct
{
int Ta; // Abtastzeit in ms
int I; // Integralanteil
int Kp; // Verstärkung
// int D; // Differenzieller Anteil
int e; // Regelabweichung
float esum; // Summe der Regelabweichungen
int ealt; // Regelabweichung zum ZP z-1
int y;
int AS; // Ansprechschwelle
}
void main(void)
{
PID_Init();
int Ausgang, w,x;
timer_init();
OCR1A = 0x0000;
while(1)
{
PID_Cyclic(x,w,&Regler1); // Parameter für Regler1 übergeben
}
}
//----------------------------------------------------------------------
-----
void timer_init(void)
{
DDRB = (1 << PB1 );
TCCR1A = (1<<COM1A1) | (1<<WGM11)| (1<<WGM10);
TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS10);
// ICR1 = 0x0003;
}
//----------------------------------------------------------------------
-----
void PID_Init(void) // In der Init müssen die
Reglereinstellungen gemacht werden
{
Regler1.AS=1;
Regler1.y=0;
Regler1.Ta=10;
Regler1.I=100;
// Regler1.D=0;
Regler1.Kp=1;
Regler1.esum=0;
Regler1.e=0; // Für weiteren Regler einfach Neue
Variable erstellen
Regler1.ealt=0; // und hier Werte mit Regler2.xx=0
einstellen
}
//----------------------------------------------------------------------
-----
double PID_Berechnung (double x, double w)
{
e =w-x; // aktuelle Regelabweichung bestimmen
if ((e >= AS)||(e <= (AS*(-1)))) // Betrag der Differenz prüfen
{
if ((y < 1023)&&(y > 0)) // bei Übersteuertem stellglied
Integration einfrieren
{ // (Anti-Windup)
esum = esum + e; // Summe der Regelabweichung
aktualisieren
}
y = (Kp*e)+(I*Ta*esum); //+(D*((e-ealt))/Ta); // Reglergleichung
// (I-Anteil bei der Initialisierung mit
Abtastrate verrechnet)
ealt = e; // Regelabweichung für nächste Abtastung
merken
}
if (y > 1023) // Stellgröße auf 0..1023 begrenzen (10
bit PWM)
{
y = 1023;
}
if (y < 1)
{
y = 0;
}
return y;
}
Und das sind die dazugehörigen Fehlermeldungen....:
piRegler.cc:31 31: error: new types may not be defined in a return type
31: note: (perhaps a semicolon is missing after the definition of '')
31: error: two or more data types in declaration of 'main'
31: error: invalid function declaration
piRegler.cc In function 'void PID_Init()':
piRegler.cc:59 59: error: 'Regler1' was not declared in this scope
piRegler.cc In function 'double PID_Berechnung(double, double)':
piRegler.cc:73 73: error: 'e' was not declared in this scope
piRegler.cc:74 74: error: 'AS' was not declared in this scope
piRegler.cc:76 76: error: 'y' was not declared in this scope
piRegler.cc:78 78: error: 'esum' was not declared in this scope
piRegler.cc:80 80: error: 'y' was not declared in this scope
80: error: 'Kp' was not declared in this scope
80: error: 'I' was not declared in this scope
80: error: 'Ta' was not declared in this scope
80: error: 'esum' was not declared in this scope
piRegler.cc:82 82: error: 'ealt' was not declared in this scope
piRegler.cc:84 84: error: 'y' was not declared in this scope
piRegler.cc:88 88: error: 'y' was not declared in this scope
piRegler.cc:92 92: error: 'y' was not declared in this scope
Danke schon mal viel mals für eure Hilfe!
Liebe Grüße
Tanja
Hallo Jan!
Danke für die schnelle Antwort! Dadurch sind ein paar Fehlermeldungen
weniger geworden! Dennoch sind immernoch haufenweise "'xyz' was not
declared in this scope" errors da...
Also der hat mit diesem Teil noch Probleme:
int main()
{
PID_Init();
int Ausgang, w,x;
timer_init();
OCR1A = 0x0000;
while(1)
{
//******Hier gibts Probleme******
PID_Cyclic(x,w,&Regler1); // Parameter für Regler1 übergeben
}
}
//*******Er kennt die ganzen Variablen nicht, obwohl die doch in Regler1
definiert wurden, allerdings kommt der wohl gar nicht dahin, da der
schon Probleme mit "PID_Cyclic(x,w,&Regler1);" hat....
double PID_Berechnung (double x, double w)
{
e = w - x; // aktuelle Regelabweichung bestimmen
if ((e >= AS)||(e <= (AS*(-1)))) // Betrag der Differenz prüfen
{
if ((y < 1023)&&(y > 0)) // bei Übersteuertem stellglied
Integration einfrieren
{ // (Anti-Windup)
esum = esum + e; // Summe der Regelabweichung
aktualisieren
}
y = (Kp*e)+(I*Ta*esum); //+(D*((e-ealt))/Ta); // Reglergleichung
// (I-Anteil bei der Initialisierung mit
Abtastrate verrechnet)
ealt = e; // Regelabweichung für nächste Abtastung
merken
}
if (y > 1023) // Stellgröße auf 0..1023 begrenzen (10
bit PWM)
{
y = 1023;
}
if (y < 1)
{
y = 0;
}
return y;
}
Die Fehlermeldungen sind nun so:
piRegler.cc In function 'int main()':
piRegler.cc:71 71: error: 'PID_Cyclic' was not declared in this scope
piRegler.cc In function 'double PID_Berechnung(double, double)':
piRegler.cc:77 77: error: 'e' was not declared in this scope
piRegler.cc:78 78: error: 'AS' was not declared in this scope
piRegler.cc:80 80: error: 'y' was not declared in this scope
piRegler.cc:82 82: error: 'esum' was not declared in this scope
piRegler.cc:84 84: error: 'y' was not declared in this scope
84: error: 'Kp' was not declared in this scope
84: error: 'I' was not declared in this scope
84: error: 'Ta' was not declared in this scope
84: error: 'esum' was not declared in this scope
piRegler.cc:86 86: error: 'ealt' was not declared in this scope
piRegler.cc:88 88: error: 'y' was not declared in this scope
piRegler.cc:92 92: error: 'y' was not declared in this scope
piRegler.cc:96 96: error: 'y' was not declared in this scope
Danke nochmals für jegliche Hilfe!
Liebe Grüße
Tanja
Also wenn ich mir das so anschaue, dann würde ich mal sagen:
Deine C Kenntnisse sind nicht eingerostet, denn nichts kann nicht
rosten.
Sorry aber programmieren heisst nicht irgendwo Code abschreiben und das
Ergebnis incl. Compilerfehler sich in einem Forum lauffähig machen
lassen.
Auch nicht zu Guttenbergs Zeiten.
meine Meinung!
Tag,
das Problem ist das du keine Funktion mit dem Namen PID_Cyclic() hast.
Deine nennt sich PID_Berechnung(). Du kannst deine Funktion einfach
durch die PID_Cyclic() aus diesem Beitrag ersetzen:
Beitrag "Re: PID-Regler mit anti-Windup"
Da musst du noch im Funktionskopf "PID_Einstellung*" durch
"PI_Regler_t*" ersetzen.
Jan
Also, letzte Fehlermeldung:
piRegler.cc:63 63: error: 'AS' was not declared in this scope
Dabei hab ich doch schon AS in der PID_Init() deklariert...
Liebe Grüße
Tanja
if ((PID -> e >= AS) || (PID -> e) <= (AS * (-1)))
Ähm das versteh ich grad nicht so richtig... Ich verwende die
Ansprechwelle ja nur da in der if-Abfrage. Muss ich die davor noch wie
aktuelle Regelabweichung (PID -> e = w - x;) bestimmen?
Vielen vielen Dank nochmals Jan!
Liebe Grüße
Tanja
if((y<1)&&(y>0))// bei Übersteuertem stellglied Integration einfrieren
2
{// (Anti-Windup)
3
esum=esum+Ki*e;// Summe der Regelabweichung aktualisieren
4
}
Das ist für Ant-Windup ganz nett, sorgt aber dafür, dass der Regler sich
nicht beruhigt. Im Endeffekt vergrößert das den Fehler, den das I-Glied
doch gerade ausgleichen soll.
Für negative y muss meiner Meinung nach daher trotzdem eine Addition
durchgeführt werden. Sonst läuft der Regler weg, weil esum zwangsläufig
groß wird.
Beispiel:
Soll: 5000
Ist: 2000
e=3000, esum=3000.
Nächster Schritt:
e=1000, esum=4000.
soweit so klar, bei e=0 nehmen wir esum=5500 an.
Jetzt kommt folgendes Problem: Der Regler erreicht Soll und esum wird
nicht abgebaut. Sobald ein Schwinger nach unten kommt, hämmert der
Regler den vollen I-Anteil auf das Stellglied, die Strecke beginnt zu
schwingen. Und noch dazu ist esum jetzt noch etwas größer. Nach einigen
Schwingern ist esum bei 100000 angekommen und findet damit immernoch
kein Ende.
Der Regler wird mit zunehmender Zeit immer instabiler, weil sich das
normale Einschwingen zu Beginn des Regelvorganges zu einem heftigen
Überschwingen mausert.
Sollte sich der Regler mit der Zeit, zum Beispiel durch geänderte
Sollvorgaben wider Erwarten dennoch stabilisieren, wird eine erhebliche
Sollwertabweichung vorliegen, weil e groß bleibt.
Demzufolge muss(!) eine negative Regelabweichung (also Ist>Soll) von
esum abgezogen werden.
Zusammengefasst: e muss trotz gesättigtem Stellglied kleiner werden
können.
Ich konnte diese Effekte alle nachweisen und frage mich ehrlich gesagt,
wie eure Regler mit diesem Algorithmus stabil sein können. Der Fehler
zieht sich ja durch jedes Posting hier.
Die Bedingung fürs Anti-Windup muss jedenfalls lauten:
1
if((y<1)&&(esum>0))
2
esum+=e;
Die Prüfung auf esum ist notwendig, weil sonst esum tief ins negative
abdriften kann und damit wieder Windup (Wind-Down) auftritt. Damit wird
der Reglerausgang dann auch wirklich zu Null, wenn keine
Sollwertabweichung mehr vorhanden ist. Das ist mit den vorher gezeigten
Algorithmen nicht stabil möglich, weil die Drift des Reglers
positiv-lastig ist.
Korrigiert mich, wenn ich damit total falsch liege.
Davis schrieb:>> Die Bedingung fürs Anti-Windup muss jedenfalls lauten:>>> if ((y < 1)&&(esum > 0))> esum+=e;>>>> So steht es auch im Orginalbeitrag:>>
Ich kann die Ausführungen von Frank leider nicht nachvollziehen.
>Nach einigen Schwingern ist esum bei 100000 angekommen und findet damit immernoch >kein Ende.
Wenn dein esum 100000 erreichen kann ist dein I möglicherweise bei 0,01
eingestellt, was ein durchaus normaler Wert sein kann. Bei einem I von
0,01 könnte esum aber maximal 1023/0,01=102300 erreichen da es
anschließend in der Reglergleichung zu einem Y von 1023 wird.
>...nehmen wir esum=5500 an. Jetzt kommt folgendes Problem: Der Regler erreicht>Soll und esum wird nicht abgebaut.
Richtig das ist der Plan. Bei Ist=Soll muss der Integralanteil die
Störgröße ausgleichen weil der Proportionalanteil per Definition 0 ist.
>Sobald ein Schwinger nach unten kommt, hämmert der Regler den vollen I-Anteil>auf das Stellglied, die Strecke beginnt zu schwingen.
Ein esum von 5500 wird in der Reglergleichung nun mit I multipliziert zu
55. Bei einem Bereich von 0-1023 hämmert da nix, um bei deinen Worten zu
bleiben denn das I-Anteil wirkt ja schon die ganze Zeit auf den
Reglerausgang.
>Die Prüfung auf esum ist notwendig, weil sonst esum tief ins negative>abdriften kann und damit wieder Windup (Wind-Down) auftritt.
Warum willst du keinen Negativen Integralanteil? Der Proportional und
der Differentialanteil können auch negativ werden.
>Demzufolge muss(!) eine negative Regelabweichung (also Ist>Soll) von>esum abgezogen werden.
Richtig, deshalb müsste die Prüfung auf (esum>0) auch falsch sein.
>Damit wird der Reglerausgang dann auch wirklich zu Null, wenn keine>Sollwertabweichung mehr vorhanden ist.
Wie Bitte? Das ist normalerweise nicht die Aufgabe eines stetigen
Reglers, kommt aber vor wenn die Störgröße 0 wird und führt
Beispielsweise bei einem Computernetzteil ohne Last zu einer netten
Rauchwolke :)
Letzen Endes wird esum doch durch die Prüfung der Regelgrenzen und der
Sollwertabweichung begrenzt. Ist der Reglerausgang bei 0 oder der x <= w
wird esum nicht mehr kleiner. Ist der Reglerausgang bei 1023 oder der x
=> w wird esum nicht mehr größer. Reglerschwingungen werden
normalerweise nur durch falsche Parameter verursacht. Ein reiner
I-Regler ohne Proportionalanteil schwingt Prinzipbedingt immer.
Möglicherweise liegst du Richtig und alle anderen liegen Falsch oder du
hast dein Problem nicht verständlich machen können. Nimm einfach die
anti-Windup Prüfung raus und führe "esum = esum + e" ungeprüft aus, wenn
dein Regler immer noch Aufschwingt liegt es an den Parametern.
Anti-Windup soll aussergewöhnliche Betriebszustände und nicht Schwingen
des Reglers kompensieren. Deshalb ist es bei vernünftigen Parametern und
normalen Betriebszustand nicht notwendig.
Hallo Martin,
danke für deine Anmerkungen
Martin Klein schrieb:>>Sobald ein Schwinger nach unten kommt, hämmert der Regler den vollen I-Anteil>>auf das Stellglied, die Strecke beginnt zu schwingen.> Ein esum von 5500 wird in der Reglergleichung nun mit I multipliziert zu> 55. Bei einem Bereich von 0-1023 hämmert da nix, um bei deinen Worten zu> bleiben denn das I-Anteil wirkt ja schon die ganze Zeit auf den> Reglerausgang.
Hier liegt doch genau das Problem. Egal, wie klein der I-Parameter ist,
er wird massiv aufschwingen:
Wir nehmen an: esum=5500, I=0,01. Jetzt kommt ein Schwinger unter den
Sollwert.
Danach ist esum=5600. Soweit noch kein Problem. Nach 100
Sollwertunterschreitungen ist esum dann aber bei 15500 angekommen. Nach
einigen 100 Sollwertunterschreitungen bei angenommen 102300. Und jetzt
siehst du vielleicht das Problem: Der I-Anteil steuert jetzt den Ausgang
schon alleine komplett aus. Damit ergibt sich massives Überschwingen.
Mit jeder neuen Sollwertunterschreitung ergibt sich eine größere
Korrektur, weil esum immer größer wird. Deswegen schwingt der Regler
immer weiter auf.
Bei einer Sollwertüberschreitung muss aber esum wieder abgebaut werden
können, eben um bei der nächsten Unterschreitung wieder auf die reale
Störgröße reagieren zu können.
>>Die Prüfung auf esum ist notwendig, weil sonst esum tief ins negative>>abdriften kann und damit wieder Windup (Wind-Down) auftritt.> Warum willst du keinen Negativen Integralanteil? Der Proportional und> der Differentialanteil können auch negativ werden.
Klar können sie das. Aber bei der Summierung der Regelabweichungen
erreicht esum schnell große Werte im Negativen, was dann das selbe
Problem darstellt. Bis das wieder ausgeglichen ist, ist mir meine
Regelgröße schon weit weggelaufen. Im schlimmsten Fall geht esum bei
einer Sollwertänderung nach unten gegen -2e9 (int32 angenommen). Damit
schwingt der Regler massiv nach unten, bis der I-Anteil wieder
ausgeglichen ist.
>>Demzufolge muss(!) eine negative Regelabweichung (also Ist>Soll) von>>esum abgezogen werden.> Richtig, deshalb müsste die Prüfung auf (esum>0) auch falsch sein.
Jain. Die Prüfung auf >0 sollte besser auf einen negativen Wert lauten.
Die Prüfung auf 0 ist mehr oder weniger willkürlich (und sorgt
ihrerseits wieder für eine kleine Regelabweichung), wichtig ist, dass
esum eine untere Grenze braucht. Man könnte hier auch -1000 ansetzen.
Das würde den Regler nicht beeinflussen. Setzt man diese Begrenzung
nicht, nutzt der Regler den kompletten Wertebereich und wird bei einem
Überlauf sogar zur absoluten Katastrophe. Denn dann wird esum von -2e9
zu +2e9. Dass der Regler damit unabhängig vom Wert des I-Anteils
komplett aussteuert, sollte klar sein.
>>Damit wird der Reglerausgang dann auch wirklich zu Null, wenn keine>>Sollwertabweichung mehr vorhanden ist.> Wie Bitte? Das ist normalerweise nicht die Aufgabe eines stetigen> Reglers, kommt aber vor wenn die Störgröße 0 wird und führt> Beispielsweise bei einem Computernetzteil ohne Last zu einer netten> Rauchwolke :)
Stell dir das ganze einfach mal für eine Lageregelung vor. Dafür lassen
wir den D-Anteil aussen vor. Ist die Position erreicht, muss der Motor
nur noch entgegen wirkende Kräfte ausgleichen. Sind keine Gegenkräfte
(=Störgrößen) vorhanden, weil der Motor bspw. in der Horizontalen
arbeitet, dann muss der Reglerausgang zu 0 werden. Während der Motor
fährt, sind aber sehr wohl bspw. durch schwingende Lasten oder die
Trägheit der Anordnung Störgrößen vorhanden. Ohne meine Korrektur würde
der Motor nie zum Stillstand kommen.
> Letzen Endes wird esum doch durch die Prüfung der Regelgrenzen und der> Sollwertabweichung begrenzt. Ist der Reglerausgang bei 0 oder der x <= w> wird esum nicht mehr kleiner. Ist der Reglerausgang bei 1023 oder der x> => w wird esum nicht mehr größer. Reglerschwingungen werden> normalerweise nur durch falsche Parameter verursacht. Ein reiner> I-Regler ohne Proportionalanteil schwingt Prinzipbedingt immer.
Das ist genau der Punkt: esum wird nie kleiner. esum kann nur kleiner
werden, wenn ein negatives e auftritt. Dieses negative e sorgt aber
dafür, dass y außerhalb der Aussteuergrenzen liegt, denn y wird dadurch
ebenfalls negativ. Und ein negatives y sorgt dafür, dass (esum+=e) nicht
berechnet wird.
> Möglicherweise liegst du Richtig und alle anderen liegen Falsch oder du> hast dein Problem nicht verständlich machen können. Nimm einfach die> anti-Windup Prüfung raus und führe "esum = esum + e" ungeprüft aus, wenn> dein Regler immer noch Aufschwingt liegt es an den Parametern.> Anti-Windup soll aussergewöhnliche Betriebszustände und nicht Schwingen> des Reglers kompensieren. Deshalb ist es bei vernünftigen Parametern und> normalen Betriebszustand nicht notwendig.
Was heisst "normaler Betriebszustand"? Ein erlaubter, d.h. normaler
Betriebszustand kann auch sein, dass im Betrieb die Sollwertvorgabe
geändert wird. Dann greift Anti-Windup genauso. Nur dass eben ohne meine
Korrekturen überhaupt keine Regelcharakteristik mehr erkennbar ist, weil
der Regler extrem langsam wird.
Vielleicht habe ich hier wirklich einen massiven Denkfehler, oder ich
drücke mich nur nicht allzu verständlich aus, ich will das nicht
ausschliessen. Aber deine Argumentation überzeugt mich nicht ;-)
Noch ein Fall bei dem die Anti-windup versagen wird: Sollwertänderung
nach unten.
Bsp: eingeschwungen soll=100 -> p-anteil =0 i-anteil>55 >Y=55
soll neu 50
p-ant <0 Y angenommen <0 --> i-anteil bleibt konstant, dh der Anteil
wird nicht angepasst und treibt dann dominant / zu kräftig wenn das
System nahe an denn Sollwert driftet
Ich hab Antiwindup bei her Temp/Ofen Steuerung vom P-anteil abhängig
gemacht. Ist der alleine schon an der Stellgliedgrenze (100% oder 0%)
wird der I Anteil eingefroren, mit der Ausnahme das der I-anteil
betragsmäßig immer kleiner werden darf. Geht bei mir gut
Seeing is believing. Pack doch einfach den Code in ein einfaches
Testprogramm (Testbench) und simulier das. Dann sieht man, was passiert.
Kann auch jeder selbst nachvollziehen.
die Ansprechschwelle AS
if ((e >= AS)||(e <= (AS*(-1))))
was genau soll die eigentlich bewirken?
bzw. wozu genau brauch ich die eigentlich? Kann ich die nicht einfach
weg lassen?
@ klaus (Gast)
>die Ansprechschwelle AS>if ((e >= AS)||(e <= (AS*(-1))))>was genau soll die eigentlich bewirken?
Dass der Regler nur für Abweichungen >= +/- AS aktiv wird. Bei kleineren
Abweichungen reagiert er nicht. Das KANN bei bestimmten Problemen
vorteilhaft sein, bei anderen aber genaus das Gegenteil bewirken
(Totbereich ohne Wirkung).
>bzw. wozu genau brauch ich die eigentlich? Kann ich die nicht einfach>weg lassen?
Kann man.
Ich habe den Algorithmus nochmal etwas überarbeitet, hier jetzt mit
funktionierendem Anti-Wind-Up und Anti-Wind-Down.
Mein vorher angebrachter Vorschlag hatte noch ein paar unschöne
Kleinigkeiten zu bieten, die jetzt auch raus sind.
1
/* Regelalgorithmus */
2
e=Soll-Ist);// Soll - Ist
3
if(e<PWM_Aufloesung)//Anti-Wind-Up
4
esum+=e;
5
if(esum<0)esum=0;// Anti-Wind-Down
Ich betreibe den Regler ohne D-Anteil. Man kann jetzt darüber streiten,
ob man esum auf einen negativen Wert begrenzt, bei dem dann der I- den
P-Anteil aufheben würden, in dem Fall -(PWM-Auflösung/KI). Das kommt auf
die jeweilige Anwendung an.
In dieser Version wirkt der I- nur im Bereich rund um den Sollwert und
beim Hochregeln.
Zur Erklärung:
Ich betreibe damit eine Heizungsregelung. Da ich also nicht gezielt
abkühlen kann, ist die Regelcharakteristik beim Abkühlen egal. Das
Anti-Wind-Down ist dafür zwingend erforderlich, da ein Abkühlen mehrere
Minuten dauern kann. Damit sich in der Zwischenzeit esum nicht Richtung
minus unendlich verabschiedet, muss diese Bedingung her.
@ Frank Bär (f-baer)
>/* Regelalgorithmus */> e = Soll - Ist); // Soll - Ist
So ein Kommentar ist überflüssig, die Klammer am Ende ein Fehler.
Code abgetippt?
> if(e < PWM_Aufloesung) //Anti-Wind-Up
Was hat die PWM AUFLÖSUNG damit zu tun? Meinst du nicht eher den PWM
Maximalwert? Ausserdem ist das nicht korrekt, denn die Stellgröße wird
ja berechnet, indem noch I*Ta multipliziert werden.
>y = (Kp*e)+(I*Ta*esum); //+(D*((e-ealt))/Ta); // Reglergleichung> // (I-Anteil bei der Initialisierung mit> esum += e;> if(esum<0) esum=0; // Anti-Wind-Down
Naja, gilt aber nur hier, wo die Stellgrößer von 0-X im positiven
Bereich ist. Es gibt durchaus auch Fälle, wo negativ Stellgrößen
sinnvoll sind.
>Ich betreibe den Regler ohne D-Anteil. Man kann jetzt darüber streiten,>ob man esum auf einen negativen Wert begrenzt, bei dem dann der I- den>P-Anteil aufheben würden, in dem Fall -(PWM-Auflösung/KI). Das kommt auf>die jeweilige Anwendung an.
Ist sowas real denkbar? Dann müsste ja der I-Anteil eine SEHR kurze
Zeitkonstante haben, da er ja nach einem Überschwingen sehr schnell ins
Negative gehen müsste. Sowas ist praktisch SEHR selten, dann sowas ist
meist tierisch instabil.
Die Appnote von Atmel ist hier besser, weil der allgemeine Fall
dargestellt wird, konfigurierbar nach Bedarf.
http://www.atmel.com/Images/doc2558.pdfhttp://www.atmel.com/Images/AVR221.zip
Ach Falk...
Falk Brunner schrieb:> @ Frank Bär (f-baer)>>>/* Regelalgorithmus */>> e = Soll - Ist); // Soll - Ist>> So ein Kommentar ist überflüssig, die Klammer am Ende ein Fehler.> Code abgetippt?
Nein, es ist ein klassischer Tippfehler. Der Kommentar steht da, weil in
meinem Code die Variablen selbstverständlich nicht "Soll" und "Ist"
heissen. Das hätte ich dir eigentlich zugetraut, selbst zu erkennen.
Die Klammer ist bei der Ersetzung verlustig gegangen...
>> if(e < PWM_Aufloesung) //Anti-Wind-Up>> Was hat die PWM AUFLÖSUNG damit zu tun? Meinst du nicht eher den PWM> Maximalwert? Ausserdem ist das nicht korrekt, denn die Stellgröße wird> ja berechnet, indem noch I*Ta multipliziert werden.
Muss ich mir nochmal ansehen.
>>y = (Kp*e)+(I*Ta*esum); //+(D*((e-ealt))/Ta); // Reglergleichung>> // (I-Anteil bei der Initialisierung mit>>> esum += e;>> if(esum<0) esum=0; // Anti-Wind-Down>> Naja, gilt aber nur hier, wo die Stellgrößer von 0-X im positiven> Bereich ist. Es gibt durchaus auch Fälle, wo negativ Stellgrößen> sinnvoll sind.
Meine Güte... aber doch nicht in einem System, in dem das Stellglied auf
positive Stellgrößen beschränkt ist... Ich glaube, du hast das Prinzip
von Anti-Wind-Up nicht verstanden. Nochmal: Es geht nicht um den
Regelalgorithmus an sich, sondern eigentlich nur um Anti-Wind-Up und
Anti-Wind-Down.
>>Ich betreibe den Regler ohne D-Anteil. Man kann jetzt darüber streiten,>>ob man esum auf einen negativen Wert begrenzt, bei dem dann der I- den>>P-Anteil aufheben würden, in dem Fall -(PWM-Auflösung/KI). Das kommt auf>>die jeweilige Anwendung an.>> Ist sowas real denkbar? Dann müsste ja der I-Anteil eine SEHR kurze> Zeitkonstante haben, da er ja nach einem Überschwingen sehr schnell ins> Negative gehen müsste. Sowas ist praktisch SEHR selten, dann sowas ist> meist tierisch instabil.
Du missverstehst gewaltig: Wenn e negativ werden kann, dann ergibt sich
auch eine negative Stellgröße. Wenn der Regler das abbilden kann, dann
gibt es keinen Grund, e auf positive Werte zu begrenzen.
Und davon abgesehen: Manchmal will man vielleicht einfach, dass der
I-Anteil den P-Anteil kompensieren kann. Was weiß ich. Das war ein
Vorschlag um die Sache etwas allgemeiner zu fassen. In meiner Anwendung
ist es nicht notwendig.
> Die Appnote von Atmel ist hier besser, weil der allgemeine Fall> dargestellt wird, konfigurierbar nach Bedarf.>> http://www.atmel.com/Images/doc2558.pdf> http://www.atmel.com/Images/AVR221.zip
Wozu diskutieren wir dann hier? Mal ehrlich: Ich habe mich beim
Reglerdesign in diesem Thread etwas belesen. Dann habe ich einen Bug im
Regler gefunden. Jetzt dokumentiere ich, wie der behoben werden könnte.
Wo ist dein Problem? Warum postest du nicht einfach gleich eingangs die
Appnote und allen ist "geholfen"?
Falk Brunner schrieb:> Die Appnote von Atmel ist hier besser, weil der allgemeine Fall> dargestellt wird, konfigurierbar nach Bedarf.>> http://www.atmel.com/Images/doc2558.pdf> http://www.atmel.com/Images/AVR221.zip
Dafür ist leider der Code strukturell eine mittlere Katastrophe.
Abgesehen davon ist der Regler im Bezug auf Rechenzeit und Codegröße
deutlich schlechter als die Implementation hier im Thread.
Hallo allerseits
Ich knüpf hier mal an... Ich möchte ebenfalls einen PI Regler mit
anti-Windup implementieren. Ich hab jedoch einen anderen Ansatz gewählt.
Ich hab mir gedacht ich transformier meinen kontinuierlichen PI Regler
(ganz nach Schulbuch) mit Tustin s = 2(z-1)/(Ta(z+1)) in den Z-Bereich
-->
Und von dort dann in den Zeitbereich (ich hab hier die Konstanten der
Einfachheit halber zusammengefasst)
Das lässt sich so ganz einfach implementieren
e=w-x;
u=A*u_old+B*(e-e_old);
u_old=u;
e_old=e;
Meine Frage: Wie integrier ich hier das anti-Windup?
Was ist der Unterschied zwischen meiner Lösung und dem Beispiel vom
Anfang?
Würd mich freuen, wenn mir jemand weiterhelfen kann.
Frank Bär schrieb:> Abgesehen davon ist der Regler im Bezug auf Rechenzeit und Codegröße> deutlich schlechter als die Implementation hier im Thread.
Das glaub ich nicht. Schließlich verbraucht allein die Nutzung von
double ein paar Kilobyte. Der Code von Atmel nutzt keine
Fließkommazahlen. Daher sollte er schneller und kleiner sein.
IchBinIch schrieb:> Meine Frage: Wie integrier ich hier das anti-Windup?> Was ist der Unterschied zwischen meiner Lösung und dem Beispiel vom> Anfang?
Das Anti-Windup mathematisch zu integrieren ist etwas schwierig da es
sich dabei um eine nichtlineare und unstetige Funktion handelt.
Mathematisch verwendest du da einmal einen PI-Regler und wenn die
Stellgröße in der Begrenzung ist, also größer als ein bestimmter wert,
machst du aus deinem PI-Regler eine Art P-Regler, bedeutet du nimmst
zwar deinen I-Anteil immer noch mit in die Gleichung integrierst aber
nicht mehr auf.
Soweit mir bekannt ist wird Anti_Windup auch nur bei digitalen Reglern
eingesetzt und ist nur mehr oder weniger eine absicherung für den
Worst-Case denn generell sollten bei "kontinuierlichen" Reglern wie P,
PI oder PID Reglern keine Unstetigkeiten (Stellgrößenbegrenzung)
auftreten. Treten sie doch auf ist entweder die Regelung falsch
dimensioniert oder die Aktoren sind falsch dimensioniert
Peter Kremsner schrieb:> Soweit mir bekannt ist wird Anti_Windup auch nur bei digitalen Reglern> eingesetzt und ist nur mehr oder weniger eine absicherung für den> Worst-Case denn generell sollten bei "kontinuierlichen" Reglern wie P,> PI oder PID Reglern keine Unstetigkeiten (Stellgrößenbegrenzung)> auftreten. Treten sie doch auf ist entweder die Regelung falsch> dimensioniert oder die Aktoren sind falsch dimensioniert
Absolut korrekt ... richtig dimensioniert funktioniert dieser Regler
sehr gut (PI-Regler-Teil, der D-Regler-Teil wurde bei meiner Anwendung
nicht betrachtet). Das betrift im Übrigen auch die Größe des Wind-Ups
und die zeitliche Abtastung. Das lässt sich mathematisch als auch in
Testversuchen zeigen.
Eng wirds mit 8-bit Prozessioren und int16_t. Man muss sher genau
schauen, dass es nicht zum Überlauf kommt. Ich empfehle dann die Prüfung
von esum.
@IchBinIch:
Der Gezeigte PI-regler ist einfach die Geschwindigkeitsform. Die gibt es
erweitert um einen zusätzlichen Term (mit dem Fehler aus 2 Schritten
zurück) auch als PID-Regler.
In dieser Form macht man Antiwindup ganz einfach indem man u in der
Größe Begrenzt bevor man sich den Wert als u_old merkt. Da es so einfach
ist, fällt es manchmal nicht auf, das überhaupt ein Anti-Windup schon da
ist. Allerdings wird es damit schwieriger eine andere Anti Windup
Strategie zu implementieren.
Hallo zusammen,
macht es Sinn, einen so alten Thread nochmal "aufzuwärmen"? Ich hoffe
schon!
Ich wollte endlich mal etwas über Regler lernen (insbesondere PID) und
hab dafür viel gegoogled. Der Thread hier hat mir eigentlich am meisten
geholfen, daß ganze zu verstehen, insbesonder konnte ich dank des
Sourcecodes alles auch selbst ausprobieren.
Dabei ist mir auch aufgefallen, daß das Anti-Winding nur teilweise
funktioniert.
Wir betrachten ja hier eine Temperatur-Regelung!
Nach meinen Beobachtungen funktioniert es gut beim Aufheizen, aber nicht
beim Abkühlen (also Sollwert < Istwert). Das liegt meiner Meinung aber
an den Gegebenheiten der physikalischen Vorgänge.
Das Heizen machen wir aktiv, den Heizverlauf können wir deswegen regeln.
Das Abkühlen hängt NUR von den Gegebenheiten ab (Zimmer, Ofen,
Wärmeverlust über die Zeit).
Der Regler, so wie er programmiert ist, weiß davon aber nichts. Deswegen
summiert sich bei einem Sollwert > Istwert ein riesiges esum auf. Das
wird dann zum Problem, wenn die Temperatur aufgrund der Abkühlung den
Sollwert erreicht und dann unterschreitet. Durch das riesige esum dauert
es ewig, bis der Regler mal wieder zum Heizen anfängt.
Ich habe das ganze in einer Simulation nachprogrammiert und ein
einfaches Modell für einen Ofen gemacht. Damit lassen sich Effekte ganz
gut nachvollziehen. Ich bereite das Ganze gerade etwas auf und werde
dann Screenshots zur Verfügung stellen.
Grüße NBGer
Richard Rauch schrieb:> Das Heizen machen wir aktiv, den Heizverlauf können wir deswegen regeln.> Das Abkühlen hängt NUR von den Gegebenheiten ab (Zimmer, Ofen,> Wärmeverlust über die Zeit).> Der Regler, so wie er programmiert ist, weiß davon aber nichts. Deswegen> summiert sich bei einem Sollwert > Istwert ein riesiges esum auf. Das> wird dann zum Problem, wenn die Temperatur aufgrund der Abkühlung den> Sollwert erreicht und dann unterschreitet. Durch das riesige esum dauert> es ewig, bis der Regler mal wieder zum Heizen anfängt.
Ich hätte jetzt erwartet, dass esum beim abkühlen negativ ist... und
dass negative Werte von esum ignoriert werden., wenn es keine aktive
Kühlung gibt.
Hallo Richard,
der Anti Windup in dem Code tut genau das was er soll, nähmlich die
Integration stoppen solange die Stellgröße an der Endbeschränkung ist,
also in deinem Fall solange der Heizkörper voll an ist.
Das kann beim Einschalten sein wenn der P-Anteil alleine bereits die
Stellgröße übersteuert aber auch dann der Fall sein wenn P und I Anteil
gemeinsam übersteueren.
So wie du die Sache schilderst hört es sich nach einem falsch
Dimensionierten Regler mit zu hohem I Anteil an, das bedeutet der
Integrator Integriert viel zu schnell auf und ist daher Instabiel und
gegen Instabilität des gesammt Systems kann der Anti Windup auch nichts
machen.
Die Temperatur eines Raumes verhält sich ja normalerweise anähernd wie
ein Integrator, ich schalte die Heizung ein und die Temperatur steigt
(idealerweise) konstant mit einer Zeitkonstante an.
Mathematisch gesehen hast du daher eine Phasenverschiebung von 90°
hängts du da jetzt den PID-Regler dazu erzeugt dir der I-Anteil eine
zusätzliche Phasenverschiebung von 90° das führt dann dazu dass die
Regelung instabil ist wenn die Phasenverschiebung bei der 0-dB linie im
Bodediagramm >=180° ist.
Du musst den Regler so Auslegen dass der Knick des PI-Reglers vor der
+10dB linie ist damit dein Regelkreis stabil ist.
Versuche einfach mal den I-Anteil weg zu lassen wenn deine Regelung
nicht so genau sein muss, ohne I-Anteil sollte deine Strecke nicht
instabil werden.
ernst oellers schrieb:> Ich hätte jetzt erwartet, dass esum beim abkühlen negativ ist... und> dass negative Werte von esum ignoriert werden., wenn es keine aktive> Kühlung gibt.
sollte man nicht machen wenn man esum oder sonst einen wert auf ein
Intervall begrenzt ist das nichtlineares Verhalten und das macht jeden
noch so gut ausgelegten Regler mehr oder weniger zunichte.
Das Anti-Windup selbst ist bereits ein nichtlinearer eingriff in den
Regler wesswegen bei einem gut Dimensionierten Regelkreis das
Anti-Windup nicht eingreifen sollte.
Desweiteren sollte man einem Regler nie oder nur selten einen Sprung
aufschalten, weil man dadurch ja fast instabilität oder überschwingen
herausfordert, kommt in dem fall auf den Regler an, besser ist es immer
auch einen Vorfilter zu verwenden damit der Sollwert nicht springen kann
ok, das probier ich mal aus...
ich hab im Moment gar keine echte Anwendung dafür, vielleicht ist auch
mein Modell zur Simulation (Ofen, Raum,...) falsch.
Ich hab das Modell folgendermaßen aufgebaut:
1. die Temperatur des Ofens passt sich über die Zeit an die
Außentemperatur an. Je kleiner die Differenz, um so langsamer ist die
Anpassung (das ist auch die einzige Möglichkeit der Abkühlung!)
2. ein Heizelement kann über PWM angesteuert werden und den Ofen heizen.
Der Ofen passt sich (ähnlich wie bei der Außentemperatur, aber
schneller) der Temperatur des Heizelementes an
3. Auch die Temperatur des Heizelementes passt sich an die Temperatur
des Ofens entsprechend an (wird durch Abgabe von Wärme abgekühlt). Dies
wirkt vor allem, wenn das Element nicht heizt.
In C sieht das so aus:
Das Model sollte so passen.
Versuch es aber eine stufe einfacher, mach deinen Ofen nicht träge als
die Temperatur des ofens ist immer gleich der des Heizelements und dein
Heizelement verhätl sich auch nicht träge.
Versuche nur die Lufttemperatur des Raumes zu modelieren, also dein Raum
folgt der Temperatur des Ofens nur langsam auch wenn sich dieser
Sprungartig erwärmen kann.
Ist bei einer echten Heizung auch so der Ofen bzw das Heizelement
erwärmt sich so schnell im verhältnis zum Raum dass die geschwindigkeit
mit der sich das Heizelement erwärmt vernachlässigbar ist.
Wenn du jetzt jedoch in deinem Beispiel nicht von einem Heitkörtper
sondern von einem Backofen sprichst, ist dein Raum der Backraum des
Ofenens, und der ofen von dem ich rede das Heizelement ^^
Peter Kremsner schrieb:> Die Temperatur eines Raumes verhält sich ja normalerweise anähernd wie> ein Integrator
Da hab ich mich verschrieben, die Temperatur verhält sich natürlich
anähernd wie ein PT1.
der kern der aussage bleibt aber gleich bei einem PT1 ist es so dass es
sich überhalb der knickfrequenz anähernd wie ein Integrator verhält.
hmm...ich wollte es etwas realistischer machen, deswegen hat das
Heizelement einen eigenen Temperaturverlauf
Nehmen wir mal an, es wäre anstatt einem Ofen ein Raum mit einem
Heizkörper:
- Der Raum selbst (ungeheizt) kühlt mit der Zeit ab und nähert sich der
Außentemperatur z.B. 0 ° an. (je nach Dämmung langsame Zeitkonstante).
Also ohne Heizen würde es vielleicht nach ein paar Tagen innen auch fast
0 ° haben.
- Der Heizkörper ist das Heizelement und kann viel wärmer als der Raum
werden (z.b. 60 °)
- Der Raum wird durch den Heizkörper geheizt (schnelle Zeitkonstante),
der Heizkörper kühlt dadurch aber ab
- Die Regelung soll jetzt eigentlich das Thermostat-Ventil simulieren,
welches den Raum auf Soll-Temperatur hält. (z.B. 22 ° )
Mir geht es dabei nicht wirklich um eine Raum-Regelung. Auch ein
schlechter Regler wird wahrscheinlich irgendwann in etwa die
Soll-Temperatur einstellen. Ich möchte eher etwas über Regelung lernen
und beschäftige mich damit, wie der Regler arbeitet.
also, ich hab mal ein paar Screenshots gemacht.
Allerdings kann ich momentan das ursprüngliche Problem nicht mehr
nachstellen. Der Regler arbeitet einwandfrei, sowohl beim Hochheizen,
als auch beim Runterkühlen.
Trotzdem mal 2 Screenshots.
1. Verlauf beim Hochheizen von 20 ° auf 500 °
2. Verlauf beim Setzen einer neuen Solltemp. 100 ° (also von 500->100)
Erklärung zum Oszi-Schrieb:
User1 : Solltemperatur Vorgabe
User2 : Ist-Temperatur Verlauf
User3 : PID->y ; also der Vorgabewert für den PWM
User4 : PID->esum
User10: Temperaturverlauf des Heizelements
Richard Rauch schrieb:> Der Raum wird durch den Heizkörper geheizt (schnelle Zeitkonstante),> der Heizkörper kühlt dadurch aber ab
der Heizkörper kühlt nur dann ab wenn er durch die PWM weniger Leistung
bekommt. Die Temperatur des Heizers ist im stationären Fall immer
Wärmeübergangskoeffizient (°C/W) * Leistung. Der
Wärmeübergangskoeffizient ergibt sich bei einem Heizkörper aus fläche
und Oberflächenbeschaffenheit, den wert °C/W findet man typischerweise
bei der Angabe der Kühlkörper für Transistoren kann hier aber auch
verwendet werden.
Naja eine schlechte Regelung kann instabil sein, das bedeutet der Regler
wird nie die 22°C erreichen.
Wenn der Regler an der stabilitätsgrenze ist schwingt die Temperatur
immer um die 22°C, wird sie aber nie erreichen. Bei Instabilität wird
der Raum der theorie nach auf einen Bereich von -unendlich bis
+unendlich grad geheizt und erreicht auch nie 22°C
Im Regelfall spricht man von einem schlechten Regler dann wenn der
Regelkreis stabil ist aber einfach nur extrem langsam oder einfach
extrem lange nachschwingt.
Zum Thema Regelungstechnik kann ich dir das Buch Regelungstechnik von
Haager empfehlen ist ziemlich verständlich erklärt, wenn du aber wissen
willst wie so eine Regelung im detail funktioniert wirst du um so Sachen
wie Laplace-Transformation, Bode-Diagramm und Stabilitätskriterien nicht
drum herum kommen.
So ein Regler ist eben ein pures Mathematisches Konstrukt.
Im Allgemeinen kann man aber sagen der Regler hat einen P Anteil, der
Verstärkt einfach nur den unterschied zwischen soll und ist wert
Der Integralanteil summiert den Unterschied bei jedem aufruf der
Reglerfunktion auf
und der Differentialanteil Verstärkt einfach die Änderung im Unterschied
zwischen soll und ist, am ende werden diese einzelnen Anteile summiert
und das ist dein PID-Regler
Der PID-Regler steuert jetzt dein Stellglied, also bie dir den Heizer so
an dass die Temperatur(Ist_Wert) möglichst schnell den Sollwert
erreicht, dabei ist es aber wichtig wie deine Regelstrecke(der Raum)
beschaffen ist ansonsten kann es passieren dass der Regler sehr lange
zum erreichen der Solltemperatur braucht oder dass er sie gar nicht
erreichen kann, weil er selbst dass Stellglied so steuert dass die
Regelstrecke immer das macht was der Regler eigentlich nicht möchte.
Es ist also für den Regler essentiel das zu kennen was er Regeln möchte,
ich kann einen Regler für ein Walzwerk nicht in eine Temperaturregelung
einsetzen oder Umgekehrt, es gibt aber bestimmte einstellverfahren für
Regler:
http://de.wikipedia.org/wiki/Faustformelverfahren_%28Automatisierungstechnik%29
Oder wenn man die Regelstrecke als mathematisches Model hat kann man den
Regler auch nach gewissen Formeln einstellen:
http://de.wikipedia.org/wiki/Betragsoptimumhttp://de.wikipedia.org/wiki/Symmetrisches_Optimum
leider sind die beiden Wikiartikeln ziemlich spärlich, aber die Begriffe
stimmen zumindest.
spannend!
naja, ich bin nicht so ganz das Mathe-Genie, von daher tue ich mich
etwas schwer mit den mathematischen Grundlagen und Formeln.
wofür die P, I und D - Anteile sind, hab ich aber inzwischen
einigermaßen begriffen.
da werde ich mal weiter damit rumspielen und das unterschiedliche
Verhalten bei unterschiedlichen Paramtern ausprobieren.
was mir noch nicht ganz klar ist, wie bringe ich unterschiedliches
Zeitverhalten in den Regler rein? Es ist ja ein riesen Unterschied, ob
ich eine träge Temperatur oder eine schnell reagierende Drehzahl eines
Motors regeln will.
Meine Vorgehensweise zum Ausprobieren inklusive Screenshots und
Sourcecode habe ich übrigens hier abgelegt:
http://tiprom.itrgmbh.com/projects/itr-products-ecos-toolchain/wiki/ECos-PID-sample
Richard Rauch schrieb:> was mir noch nicht ganz klar ist, wie bringe ich unterschiedliches> Zeitverhalten in den Regler rein? Es ist ja ein riesen Unterschied, ob> ich eine träge Temperatur oder eine schnell reagierende Drehzahl eines> Motors regeln will.
Nunja die Mathematische Form eines Digitalen PID-Reglers wird durch eine
sogenannte Differenzengleichung dargestellt, die ist für den PID-Regler:
Wenn du dir den PID Algorithmus anschaust kannst du die
Differnzengleichung auch im Programm sehen, die Summe ist dort jedoch
durch esum ersetzt und
ist durch ealt ersetzt
Die Abtastzeitkonstante kommt daher dass dein Regler ja digital ist und
den Ist-Wert ja nur in bestimmten Zeitabständen aufnimmt.
der Integrierbeiwert gibt jetzt an wie schnell der Integrator
integrieren soll, je größer der Wert desto schneller ist der Integrator
man kann den Integrierbeiwert auch durch die Integrationszeitkonstante
ersetzen
das selbe gilt für den Differenzierbeiwert
durch diese beiden Konstanten bringst du das Zeitverhalten in den
PID-Regler
wie diese auszulegen sind kommt drauf an welche Eigenschaften deine
Regelung haben soll, soll sie gut und schnell der Stellgröße folgen,
oder soll sie gut Störungen kompensieren können, wie viel Prozent darf
die Stellgröße maximal über den Sollwert überschwingen usw.
Daher werden diese Zeitkonstanten entweder durch ein
Faustformelverfahren oder aber im Bode-Diagramm bzw durch Rechnungen im
Laplace-Bereich bestimmt, Rechnungen sind in diesem Fall ein muss wenn
es um sehr gute Regelungen geht, die Faustformeln eignen sich nur für
Regler die hald funktionieren sollen, bei denen die Spezifikationen aber
eher locker sind.
Hallo Peter,
vielen Dank. So eine gute Erklärung habe ich bisher noch nicht gefunden.
Vor allem die Darstellung der Zusammenhänge zwischen der mathematischen
Formel und der realen Implementierung ist sehr hilfreich.
Übrigens....mit der Implementierungs-Variante hier aus dem Thread, alles
mit Integer-Arithmetik zu machen (wegen Performance) bin ich überhaupt
nicht zurecht gekommen.
Therme waren immer sehr schnell 0 (wegen Abrundung!). Der Regler hat
dann nie den Sollwert erreicht. Außerdem funktioniert es bei mir am
Besten mit einem Integrierbeiwert von 0,1.
Im Falle von Integer hätte ich nur die Möglichkeit 0 oder 1.
Reglerimplementierungen mit Integern werden normal so gelöst, dass du
jeden Parameter(Alle Beiwerte Plus soll und Istwert) den du in den
Regler eingibst mit einem Faktor zb 100 Multiplizierst, der
Integrierbeiwert wird dann bei dir zB von 0.1 zu 10 du musst dir dann
hald nur merken dass die Stellgröße die dein Regler ausgibt 100* die
Tatsächliche Stellgröße ist, die kannst du jetzt durch 100 dividieren,
das sollte aber in Gleitkomma arithmetik passieren, oder du weist
aufgrund deiner Regelstrecke dass du den Faktor 100 sowieso benötigst,
beispielsweise bei einer PWM für die Prozent dutycycle, es macht da
eigentlich wenig sinn, die Reglerstellgröße durch 100 zu dividieren und
den wert den du dann erhältst mit 100 zu multiplizieren um von % auf
einen Integer zu kommen.
Andererseits kannst du diesen Faktor auch in deine Strecke
miteinbeziehen, du kannst sagen, mein Regler gibt wirklich meine
Stellgröße aus, aber in meinem Model ist der Proportionalanteil meiner
Strecke mit 100 multipliziert.
Atmel hat das mal in einem Application Note beschrieben
http://www.atmel.com/webdoc/atmel.docs/atmel.docs.33085.19841.html
dort gibts das PDF plus c-Code
in dem haben sie den PID Algorithmus auch noch ein bisschen angepasst
indem sie für d-Anteil nicht die Differenz der Regelabweichungen
verwenden sondern die differenz der Ist-Werte, das führt dazu, dass der
Reglerausgang nicht springt wenn sich der Sollwert sprungartig ändert.