Unerwartetes Verhalten von CTRL_PID bzw. FT_PIWL

Begonnen von suud, 22. Oktober 2008, 15:29:11

Vorheriges Thema - Nächstes Thema

0 Mitglieder und 1 Gast betrachten dieses Thema.

suud

Hallo,
mir ist beim "spielen" mit dem Baustein CTRL_PID aufgefallen, dass er sich als reiner P-, D- oder PD-Regler
nicht wie erwartet verhält.
Das Problem entsteht im Baustein FT_PIWL wenn der Wertebereich mindestens einmal über- oder
unterschritten wurde. In dem Fall wird "i := LIM_H - p;" gesetzt und "i" ist fortan trotz eines
Integralfaktors von 0 immer ungleich 0. Man bekommt dann also immer einen I-Anteil zum P-Anteil
hinzuaddiert.
Ist das Problem schon bekannt?



FUNCTION_BLOCK FT_PIWL
VAR_INPUT
IN : REAL;
KP : REAL := 1.0;
KI : REAL := 1.0;
LIM_L : REAL := -1E38;
LIM_H : REAL := 1E38;
RST : BOOL := FALSE;
END_VAR
VAR_OUTPUT
Y : REAL;
LIM : BOOL;
END_VAR
VAR
init: BOOL;
tx: DWORD;
tc : REAL;
t_last: DWORD;
in_last : REAL;
i: REAL;
p: REAL;
END_VAR

(*
version 1.0 13. jun 2008
programmer hugo
tested by tobias

FT_PIWL is a PI controller.
The PID controller works according to the fomula Y = IN *(KP+ KI * INTEG(e) ).
a rst will reset the integrator to 0
lim_h and Lim_l set the possible output range of the controller.
the output flag lim will signal that the output limits are active.
the integrator ist equipped with anti wind-up circuitry which limits trhe total output ranke to lim_l and lim_h

default values for KP = 1, KI = 1, ILIM_L = -1E37, iLIM_H = +1E38.
*)

(* @END_DECLARATION := '0' *)
(* initialize at power_up *)
IF NOT init OR RST THEN
init := TRUE;
in_last := in;
t_last := T_PLC_US();
i := 0;
tc := 0;
ELSE
(* read last cycle time in Microseconds *)
tx := T_PLC_US();
tc := DWORD_TO_REAL(tx - t_last);
t_last := tx;

(* calculate proportional part *)
p := KP * IN;

(* run integrator *)
i := (IN + in_last) * 5E-7 * KI * tc + i;
in_last := IN;

(* calculate output Y *)
Y := p + i;

(* check output for limits *)
IF Y >= LIM_H THEN
Y := LIM_H;
i := LIM_H - p;
LIM := TRUE;
ELSIF Y <= LIM_L THEN
Y := LIM_L;
i := LIM_L - p;
LIM := TRUE;
ELSE
LIM := FALSE;
END_IF;
END_IF;



hugo

nein war noch nicht bekannt wir werden das die nächsten tage prüfen

hugo

habe mir das ganze gerade angesehen,
denke es ist richtig.

hintergrund:

wenn ein limit erreicht wurde dann setzt sich der ausgangswert aus P + I zusammen.

wird nun ein limit erreicht, so wird I lediglich auf den wert zurpückgestutzt das anschliessend p + i wieder der max wert errechen.
wichtig ist hierbei nur das die limits so liegen das sie nicht bereits mit p überschritten werden, das sollte aber generell bei reglern so sein.
der integrator arbeitet praktisch immer, die limits korrigieren lediglich seinen wert damit der regler nie aus seinem arbeitsbereich läuft.

hugo

in der nächsten release 301 wird der ft_piwl so geäöndert das ein anpassen des integrators nur noch dann stattfindet wenn ki > 0 ist.


suud

#4
Danke. Wird bei dem Baustein eigentlich davon ausgegangen, dass die Faktoren während dem "Betrieb" konstant bleiben?
Edit: Naja, is wohl ne blöde Frage. Es geht mir nur darum, dass dann das Problem weiterhin bestehen würde, bzw. der Baustein halt noch nicht Idiotensicher ist. ;)

hugo

nein der baustein erlaubt ssehr wohl die dynamische umschaltung der parameter.
das ist auch sehr wichtig denn regelparameter gelten ja immer nur für einen arbeitspunkt, und häufig werden abhängig von soll, ist oder regelabweichung die regelparameter verstellt.

idiotensicher wird ein regler wohl nie sein, das zeigt sich schon daran das wenn unpassende werte angelegt werden ein regler schwingt.

suud

Dann müsste man den Baustein aber nochmal ändern, denn wenn man erst mit KI >0 regelt und dann KI = 0 setzt hat man weiterhin einen I-Wert im Ergebnis
der nicht mehr verschwindet.

suud


hugo

#8
wr werden uns das eim nächsten release näher ansehen

bonk

Hallo Hugo, hallo suud,

an der Stelle hätte ich auch noch was zu melden. Mir ist aufgefallen, dass in der neuen Release (3.02) an der Stelle zum Überwachen der Limits etwas da steht wie "IF ki > 0 THEN i := LIM_L - p; END_IF;".
Ich habe nun folgendes Problem:
Bei meiner Solaranlage habe ich diesen Regler eingebaut. (siehe www.spssoft.de auf SPS Live! klicken) Er sorgt dafür, das die Temp. vom Kollektor konstant gehalten wird. Die Solltemp ist fast immer kleiner als die Isttemp. Soll-Ist ergibt also einen negativen Wert. Ich will aber ein pos. Stellsignal haben, also ganz einfach Kp und Ki neg. machen. Nur jetzt funktioniert die schöne I-Begrenzung nicht mehr, weil dieses IF ki > 0 drin steht. Hat das einen Grund?
Ich würde eh das Programm ändern, weil eigentlich die Rechenvorschrift für den Regler etwas anders lautet:
KP (1 + 1/TNs)
Hier berechnet sich der I-Anteil aus dem Produkt von KP und 1/TNs.
Damit müßte auch bei einem neg. KP der Ki-Anteil nicht negativ sein, womit wieder das obige IF ki > 0 funktioniert.

Wenn ich ehrlich bin; die Berechnung vom I-Anteil habe ich nicht verstanden:
(* run integrator *)
   i := (IN + in_last) * 5E-7 * KI * tc + i;
   in_last := IN;

Ich verstehte da nicht das (IN + in_last). Das bedeutet doch, das die Regelabweichung zwei mal auf den alten I-Anteil addiert wird, wenn wir mal davon ausgehen, dass sich die Regelabweichung zwischen 2 Zyklen nicht verändert hat.
Vielleicht habe ich da was nicht richtig verstanden.

Die Limitregelung halte ich für super. Damit wird der I-Anteil am Limit gestoppt und sogar korrigiert, wenn die Regelabweichung noch großer wird.

hugo

das (in - in_last) / 2 ist die sogenannte trapezregel.
die trapezregel wird angewendet um die genauigkeit des reglers zu verbessern.

nehmen wir ein signal ist seit dem letzten aufruf von 1 auf 2 gestiegen, und eine zeiteiheit ist vergangen.

in * T ergbit dann 2, mit der trapezregel (2-1) /2 ergint das ganze 1,5 und des entspricht hier eben einem genaueren wert.

den rest schauen wir uns für das nächste release nochamls genauer an
dein problem lönnen wir wahrscheinlich mit k <> 0 anstelle von K > 0 lösen.

gravieren


>den rest schauen wir uns für das nächste release nochamls genauer an
>dein problem lönnen wir wahrscheinlich
>mit k <> 0 anstelle von K > 0 lösen.

Wäre  ABS(K) > 0  nicht besser   ?   

k <> 0.0           K =   0.0000000001             -->   TRUE
k <> 0.0           K = - 0.0000000001             -->   TRUE

bonk

Hallo Hugo,

so habe ich es inzwischen gelöst. Und ABS ist noch ein ticken besser.
Die Traperegel habe ich auch kapiert (und genehmigt :) ).
Aber das KP (1 + 1/TNs) sollte man nicht vegessen.
Ich will nicht nerven, aber das sind so Kleinigkeiten, die ich für wichtig finde. Ich würde mich auch gerne nützlich machen beim codieren. Kann ich da mithelfen beim nächsten Release?

hugo

danke für deine inputs das nehmen wir auch sehr ernst und werden es auch entsprechend verarbeiten.
anfang februar in der release 3.04 sollte es perfekt sein

hugo

wieso sollte asb(K) > 0 besser sein als K <> 0

k <> 0 ist nur eine einzige operation und das moch eine sehr schnelle.

die abs bildung addiert eine weitere unnötige operation und > 0 ist genauso schnell wie <> 0

mathematisch ist das ergebnis exakt das gleiche