Hallo,
mir sind beim SRAMP-Baustein 3 Dinge aufgefallen:
1.) Er verzögert bei den Limit_High/Limit_Low-Werten nicht, sondern hält hart an. Der Beschleunigungsgrenzwert wird dann deutlich überschritten.
2.) Der Baustein erkennt zu spät, daß er Verzögern muß. Die Beschleunigung wird dann langsam höher gesetzt, damit er den Sollwert ohne Überschwinger noch erreicht. Kurz vor Erreichen des Sollwertes gibt es ebenfalls eine deutliche Beschleunigungsüberhöhung.
3.) Wenn der Sollwert und der Istwert identisch sind, wird hart die Geschwindigkeit auf 0 gesetzt, der Beschleunigungsgrenzwert wird deutlich überschritten.
Mit folgendem Code werden die 3 obigen Probleme behoben:
(* read the system_time in microseconds *)
cycle_time();
(* assure range of inputs *)
A_up := MAX(0.0, A_UP);
A_dn := MIN(0.0, A_dn);
VU_max := MAX(0.0, VU_max);
VD_max := MIN(0.0, VD_MAX);
X := LIMIT(LIMIT_LOW, X, LIMIT_HIGH);
(* calculate the output offset *)
IF rst OR NOT init THEN
init := TRUE;
Y := 0.0;
V := 0.0;
ELSIF X > Y THEN
(* suppress osscilation when in position *)
IF (X = Y) AND (V < A_UP * cycle_time.TC) THEN
v := 0.0;
ELSE
(* output is too low >> ramp up and brake at the end *)
(* accelerate the speed and limit to vu_max *)
v := MIN(v + A_UP * cycle_time.TC, vu_max);
(* calculate the max speed to be able to brake and select the lowest *)
v := MIN(SQRT((Y-X) * 2.0 * A_DN - 1.5 * cycle_time.TC * A_DN), v);
(* calculate the output and obey limits *)
y := LIMIT(limit_low, y + MIN(v * cycle_time.TC, X-Y), limit_high);
END_IF
ELSIF X <= Y THEN
(* suppress osscilation when in position *)
IF (X = Y) AND (V < A_DN * cycle_time.TC) THEN
v := 0.0;
ELSE
(* output is too high >> ramp dn and brake at the end *)
(* accelerate the speed and limit to vd_max *)
v := MAX(v + A_DN * cycle_time.TC, vd_max);
(* calculate the max speed to be able to brake and select the lowest *)
v := MAX(-SQRT((Y-X) * 2.0 * A_UP + 1.5 * cycle_time.TC * A_UP), v);
(* calculate the output and obey limits *)
y := LIMIT(limit_low, y + MAX(v * cycle_time.TC, X-Y), limit_high);
END_IF
END_IF;
Ansonsten wäre es noch wünschenswert, wenn die Ein- und Ausgänge mit Kommentaren versehen wären:
X : REAL; (* desired value *)
Y : REAL; (* actual value *)
V : REAL; (* actual velocity *)
Gruß
Alex