I have written a PID controller in ModelingToolkit (yes, I know it probably exists…). I need to clip the control output u
to lie in the range [u_min, u_max]. So I try to do:
# Constraining the unconstrained control signal u_u to the valid range [u_min, u_max]
u ~ max(u_min, min(u_max,u_u))
Problem is: when u_u
reaches u_max
, the simulation crashes.
A corresponding Modelica code doesn’t have any problems with doing a similar statement.
Questions:
- Is there a problem with using
min
andmax
? (note: the code works whileu_u
lies in the interval(u_min, u_max)
, so there must be some kind of allowance for these functions. - Or is the problem related to using the solver I use? … I have used
Rodas5()
.
At some stage, I also want to include anti-windup in the form of locking the integrator state while u_u
lies outside of [u_min, u_max]
.
I include my PID controller below.
# PID controller
# ===============
@mtkmodel control_PID begin
# Model parameters
@parameters begin
# Controller parameters
K_p = 1, [description = "Proportional gain"]
T_i = 1, [description = "Integral time"]
T_d = 1, [description = "Derivative time"]
eta = 0.1, [description = "Ratio, error filter time constant/derivative time, -"]
tau_f = T_d/eta, [description = "Filter time constant"]
#
kappa_p = K_p*(T_i+T_d)/T_i, [description = "Parallel P-gain"]
kappa_i = K_p/T_i, [description = "Parallel I-gain"]
kappa_d = K_p*T_d, [description = "Parallel D-gain"]
#
u_0 = 0.5, [description = "Assumed steady control signal"]
u_min = 0.0, [description = "Minimum valid control signal"]
u_max = 1.0, [description = "Maximum valid control signal"]
end
#
# Model variables, with initial values needed
@variables begin
xi_i(t)=u_0/kappa_i,[description = "Integral state"]
xi_f(t)=0, [description = "Filter state"]
e(t), [input=true,description = "Control error"]
u_u(t), [description = "Unconstrained control signal"]
u(t), [output=true,description = "Control signal"]
end
#
# Model equations
@equations begin
Dt(xi_i) ~ e
Dt(xi_f) ~ -(xi_f - e)/tau_f
u_u ~ kappa_p*e + kappa_i*xi_i + kappa_d*(e - xi_f/tau_f)
# Constraining the unconstrained control signal u_u to the valid range [u_min, u_max]
u ~ max(u_min, min(u_max,u_u))
end
end
;