-
-
Notifications
You must be signed in to change notification settings - Fork 224
refactor: directly solve initialization problem in linearization_function
#2762
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
src/systems/abstractsystem.jl
Outdated
@@ -1749,6 +1749,7 @@ The `simplified_sys` has undergone [`structural_simplify`](@ref) and had any occ | |||
- `outputs`: A vector of variables that indicate the outputs of the linearized input-output model. | |||
- `simplify`: Apply simplification in tearing. | |||
- `initialize`: If true, a check is performed to ensure that the operating point is consistent (satisfies algebraic equations). If the op is not consistent, initialization is performed. | |||
- `initialization_solver_alg`: A NonlinearSolve algorithm to use for solving the initialization problem. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- `initialization_solver_alg`: A NonlinearSolve algorithm to use for solving the initialization problem. | |
- `initialization_solver_alg`: A NonlinearSolve algorithm to use for solving for a feasible set of state and algebraic variables that satisfies the specified operating point. |
"initialization" has no well-defined meaning when linearizing, hence the slightly different language.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 406dc9a
Why is this just a draft? |
I wanted to make sure it's rebased before merging |
8ff1743
to
48c034e
Compare
On this PR branch, I get a funky error for this example using ModelingToolkit, ModelingToolkitStandardLibrary
using ModelingToolkitStandardLibrary.Blocks
@parameters t;
D = Differential(t);
rc = 0.25 # Reference concentration
@mtkmodel MixingTank begin
@parameters begin
c0 = 0.8, [description = "Nominal concentration"]
T0 = 308.5, [description = "Nominal temperature"]
a1 = 0.2674
a21 = 1.815
a22 = 0.4682
b = 1.5476
k0 = 1.05e14
ϵ = 34.2894
end
@variables begin
gamma(t), [description = "Reaction speed"]
xc(t) = c0, [description = "Concentration"]
xT(t) = T0, [description = "Temperature"]
xT_c(t) = T0, [description = "Cooling temperature"]
end
@components begin
T_c = RealInput()
c = RealOutput()
T = RealOutput()
end
begin
τ0 = 60
wk0 = k0/c0
wϵ = ϵ*T0
wa11 = a1/τ0
wa12 = c0/τ0
wa13 = c0*a1/τ0
wa21 = a21/τ0
wa22 = a22*T0/τ0
wa23 = T0*(a21 - b)/τ0
wb = b/τ0
end
@equations begin
gamma ~ xc*wk0*exp( -wϵ/xT)
D(xc) ~ -wa11*xc - wa12*gamma + wa13
D(xT) ~ -wa21*xT + wa22*gamma + wa23 + wb*xT_c
xc ~ c.u
xT ~ T.u
xT_c ~ T_c.u
end
end
@mtkmodel InverseControlledTank begin
begin
c0 = 0.8 # "Nominal concentration
T0 = 308.5 # "Nominal temperature
x10 = 0.42
x20 = 0.01
u0 = -0.0224
c_start = c0*(1-x10) # Initial concentration
T_start = T0*(1+x20) # Initial temperature
c_high_start = c0*(1-0.72) # Reference concentration
T_c_start = T0*(1+u0) # Initial cooling temperature
end
@components begin
ref = Constant(k=0.25) # Concentration reference
ff_gain = Gain(k=1) # To allow turning ff off
controller = PI(gainPI.k=10, T=500)
tank = MixingTank(xc=c_start, xT = T_start, c0=c0, T0=T0)
inverse_tank = MixingTank(xc=c_start, xT = T_start, c0=c0, T0=T0)
feedback = Feedback()
add = Add()
filter = SecondOrder(k=1, w=1) # Initialize filter states to the initial concentration
noise_filter = FirstOrder(k=1, T=1, x=T_start)
limiter = Limiter(y_max=370, y_min=250) # Saturate the control input
end
@equations begin
connect(ref.output, :r, filter.input)
connect(filter.output, inverse_tank.c)
connect(inverse_tank.T_c, ff_gain.input)
connect(ff_gain.output, :uff, limiter.input)
connect(limiter.output, add.input1)
connect(controller.ctr_output, :u, add.input2)
connect(add.output, :u_tot, tank.T_c)
connect(inverse_tank.T, feedback.input1)
connect(tank.T, :y, noise_filter.input)
connect(noise_filter.output, feedback.input2)
connect(feedback.output, :e, controller.err_input)
end
end;
@named model = InverseControlledTank()
get_sensitivity(model, :y)
|
48c034e
to
b453151
Compare
Fixed |
Thanks for quick fix 🎉 With this slight modification to the example, I get another error using ModelingToolkit, ModelingToolkitStandardLibrary
using ModelingToolkitStandardLibrary.Blocks
using ControlSystemsMTK
@parameters t;
D = Differential(t);
rc = 0.25 # Reference concentration
@mtkmodel MixingTank begin
@parameters begin
c0 = 0.8, [description = "Nominal concentration"]
T0 = 308.5, [description = "Nominal temperature"]
a1 = 0.2674
a21 = 1.815
a22 = 0.4682
b = 1.5476
k0 = 1.05e14
ϵ = 34.2894
end
@variables begin
gamma(t), [description = "Reaction speed"]
xc(t) = c0, [description = "Concentration"]
xT(t) = T0, [description = "Temperature"]
xT_c(t) = T0, [description = "Cooling temperature"]
end
@components begin
T_c = RealInput()
c = RealOutput()
T = RealOutput()
end
begin
τ0 = 60
wk0 = k0/c0
wϵ = ϵ*T0
wa11 = a1/τ0
wa12 = c0/τ0
wa13 = c0*a1/τ0
wa21 = a21/τ0
wa22 = a22*T0/τ0
wa23 = T0*(a21 - b)/τ0
wb = b/τ0
end
@equations begin
gamma ~ xc*wk0*exp( -wϵ/xT)
D(xc) ~ -wa11*xc - wa12*gamma + wa13
D(xT) ~ -wa21*xT + wa22*gamma + wa23 + wb*xT_c
xc ~ c.u
xT ~ T.u
xT_c ~ T_c.u
end
end
begin
Ftf = tf(1, [(100), 1])^3
Fss = ss(Ftf)
"Compute initial state that yields y0 as output"
function init_filter(y0)
(; A,B,C,D) = Fss
Fx0 = -A\B*y0
@assert C*Fx0 ≈ [y0] "C*Fx0*y0 ≈ y0 failed, got $(C*Fx0*y0) ≈ $(y0)]"
Fx0
end
# Create an MTK-compatible constructor
RefFilter(; y0, name) = ODESystem(Fss; name, x0=init_filter(y0))
end
@mtkmodel InverseControlledTank begin
begin
c0 = 0.8 # "Nominal concentration
T0 = 308.5 # "Nominal temperature
x10 = 0.42
x20 = 0.01
u0 = -0.0224
c_start = c0*(1-x10) # Initial concentration
T_start = T0*(1+x20) # Initial temperature
c_high_start = c0*(1-0.72) # Reference concentration
T_c_start = T0*(1+u0) # Initial cooling temperature
end
@components begin
ref = Constant(k=0.25) # Concentration reference
ff_gain = Gain(k=1) # To allow turning ff off
controller = PI(gainPI.k=10, T=500)
tank = MixingTank(xc=c_start, xT = T_start, c0=c0, T0=T0)
inverse_tank = MixingTank(xc=c_start, xT = T_start, c0=c0, T0=T0)
feedback = Feedback()
add = Add()
filter = RefFilter(y0=c_start) # Initialize filter states to the initial concentration
noise_filter = FirstOrder(k=1, T=1, x=T_start)
limiter = Limiter(y_max=370, y_min=250) # Saturate the control input
end
@equations begin
connect(ref.output, :r, filter.input)
connect(filter.output, inverse_tank.c)
connect(inverse_tank.T_c, ff_gain.input)
connect(ff_gain.output, :uff, limiter.input)
connect(limiter.output, add.input1)
connect(controller.ctr_output, :u, add.input2)
connect(add.output, :u_tot, tank.T_c)
connect(inverse_tank.T, feedback.input1)
connect(tank.T, :y, noise_filter.input)
connect(noise_filter.output, feedback.input2)
connect(feedback.output, :e, controller.err_input)
end
end;
@named model = InverseControlledTank()
get_sensitivity(model, :y)
|
That's the |
Is there an issue associated with this bug? |
There isn't. I can open one. |
5f1893f
to
568cd44
Compare
Close #2784
Checklist
contributor guidelines, in particular the SciML Style Guide and
COLPRAC.
Additional context
Add any other context about the problem here.