Examples.CSTRMPCExample ​
CSTR concentration control with ACADOSMPC, translated from the DyadControlSystems CSTR tutorial: the concentration of B is driven to 0.6 by the feed and the cooling heat flow with a pure penalty on the control increments (Q2 = 0, Q3 as in the tutorial's difference cost), hard input bounds and soft upper bounds on the reactor and jacket temperatures. The tutorial's collocation transcription, exact Hessian and L1 slack penalty have no counterpart here; acados integrates the model with a 3-stage Gauss-Legendre IRK scheme and the state bounds are quadratically soft. The tutorial's variable scaling corresponds to x_scale and u_scale, which this example leaves at their defaults, since the controller converges without them. Verified in test/test_acados_tutorials.jl.
Usage ​
MPCComponents.Examples.CSTRMPCExample()
Variables ​
| Name | Description | Units |
|---|---|---|
Cb | Concentration of B | – |
Tr | Reactor temperature | – |
Tk | Jacket temperature | – |
F | Feed | – |
Qdot | Heat flow | – |
flag | acados status | – |
Behavior ​
Behavior of this component cannot be rendered because it includes path variables.
Source ​
"""
CSTR concentration control with `ACADOSMPC`, translated from the DyadControlSystems CSTR tutorial: the
concentration of B is driven to 0.6 by the feed and the cooling heat flow with a pure penalty on the
control increments (`Q2 = 0`, `Q3` as in the tutorial's difference cost), hard input bounds and soft
upper bounds on the reactor and jacket temperatures. The tutorial's collocation transcription, exact
Hessian and L1 slack penalty have no counterpart here; acados integrates the model with a 3-stage
Gauss-Legendre IRK scheme and the state bounds are quadratically soft. The tutorial's variable scaling
corresponds to `x_scale` and `u_scale`, which this example leaves at their defaults, since the
controller converges without them. Verified in `test/test_acados_tutorials.jl`.
"""
example component CSTRMPCExample
periodicclock = DiscreteComponents.PeriodicClock(dt = 0.005) {
"Dyad": {"placement": {"diagram": {"x1": 470, "x2": 570, "y1": 480, "y2": 580}}}
}
plant = MPCComponents.Examples.CSTRPlant() {
"Dyad": {"placement": {"diagram": {"x1": 720, "x2": 820, "y1": 270, "y2": 370}}}
}
"Samplers of the four state variables"
s = [DiscreteComponents.Sampler() for i in 1:4] {
"Dyad": {"placement": {"diagram": {"x1": 570, "x2": 470, "y1": 720, "y2": 820}}}
}
sr = DiscreteComponents.Sampler() {
"Dyad": {"placement": {"diagram": {"x1": 160, "x2": 260, "y1": 230, "y2": 330}}}
}
"Holds of the feed and the heat flow"
zoh = [DiscreteComponents.ZeroOrderHold() for i in 1:2] {
"Dyad": {"placement": {"diagram": {"x1": 474, "x2": 574, "y1": 274, "y2": 374}}}
}
"Concentration reference for B"
ref = BlockComponents.Sources.Constant(k = 0.6) {
"Dyad": {"placement": {"diagram": {"x1": 10, "x2": 110, "y1": 230, "y2": 330}}}
}
mpc = MPCComponents.ACADOSMPC(dynamics = plant, inputs = ["F", "Qdot"], state_variables = ["Ca", "Cb", "Tr", "Tk"], outputs = ["Cb"], Ts = 0.005, Np = 30, Q1 = diagonal([1.0]), Q2 = diagonal([0.0, 0.0]), penalize_increments = true, Q3 = diagonal([5e-6, 2.5e-9]), umin = [5.0, -8500.0], umax = [100.0, 0.0], constrained = ["Tr", "Tk"], constrained_max = [142.0, 140.0], integrator = ACADOSIntegrator.IRK(), integrator_stages = 3, u_guess = [10.0, -1000.0]) {
"Dyad": {"placement": {"diagram": {"x1": 340, "x2": 440, "y1": 311, "y2": 411}}}
}
"Concentration of B"
variable Cb::Real
"Reactor temperature"
variable Tr::Real
"Jacket temperature"
variable Tk::Real
"Feed"
variable F::Real
"Heat flow"
variable Qdot::Real
"acados status"
variable flag::Real
relations
Cb = plant.Cb
Tr = plant.Tr
Tk = plant.Tk
F = mpc.u[1]
Qdot = mpc.u[2]
flag = mpc.exitflag
connect(plant.Ca_out, s[1].u) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 940, "y": 284}, {"x": 940, "y": 770}], "E": 2}],
"path": {}
}
}
connect(plant.Cb_out, s[2].u) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 900, "y": 309}, {"x": 900, "y": 770}], "E": 2}],
"path": {}
}
}
connect(plant.Tr_out, s[3].u) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 860, "y": 330}, {"x": 860, "y": 770}], "E": 2}],
"path": {}
}
}
connect(plant.Tk_out, s[4].u) {"Dyad": {"edges": [{"S": 1, "M": [{"x": 825, "y": 770}], "E": 2}], "path": {}}}
connect(ref.y, sr.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
connect(s[1].y, mpc.x[1], periodicclock.y) {
"Dyad": {
"edges": [
{"S": 1, "M": [{"x": 280, "y": 770}, {"x": 280, "y": 361}], "E": 2},
{"S": 2, "M": [{"x": 335, "y": 530}], "E": 3}
],
"path": {}
}
}
for i in 2:4
connect(s[i].y, mpc.x[i])
end
connect(sr.y, mpc.r[1]) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 320, "y": 280}, {"x": 320, "y": 326}], "E": 2}],
"path": {}
}
}
for i in 1:2
connect(mpc.u[i], zoh[i].u)
end
connect(zoh[1].y, plant.F)
connect(zoh[2].y, plant.Qdot)
metadata {"Dyad": {"doc": {"behavior": false}}}
endFlattened Source
"""
CSTR concentration control with `ACADOSMPC`, translated from the DyadControlSystems CSTR tutorial: the
concentration of B is driven to 0.6 by the feed and the cooling heat flow with a pure penalty on the
control increments (`Q2 = 0`, `Q3` as in the tutorial's difference cost), hard input bounds and soft
upper bounds on the reactor and jacket temperatures. The tutorial's collocation transcription, exact
Hessian and L1 slack penalty have no counterpart here; acados integrates the model with a 3-stage
Gauss-Legendre IRK scheme and the state bounds are quadratically soft. The tutorial's variable scaling
corresponds to `x_scale` and `u_scale`, which this example leaves at their defaults, since the
controller converges without them. Verified in `test/test_acados_tutorials.jl`.
"""
example component CSTRMPCExample
periodicclock = DiscreteComponents.PeriodicClock(dt = 0.005) {
"Dyad": {"placement": {"diagram": {"x1": 470, "x2": 570, "y1": 480, "y2": 580}}}
}
plant = MPCComponents.Examples.CSTRPlant() {
"Dyad": {"placement": {"diagram": {"x1": 720, "x2": 820, "y1": 270, "y2": 370}}}
}
"Samplers of the four state variables"
s = [DiscreteComponents.Sampler() for i in 1:4] {
"Dyad": {"placement": {"diagram": {"x1": 570, "x2": 470, "y1": 720, "y2": 820}}}
}
sr = DiscreteComponents.Sampler() {
"Dyad": {"placement": {"diagram": {"x1": 160, "x2": 260, "y1": 230, "y2": 330}}}
}
"Holds of the feed and the heat flow"
zoh = [DiscreteComponents.ZeroOrderHold() for i in 1:2] {
"Dyad": {"placement": {"diagram": {"x1": 474, "x2": 574, "y1": 274, "y2": 374}}}
}
"Concentration reference for B"
ref = BlockComponents.Sources.Constant(k = 0.6) {
"Dyad": {"placement": {"diagram": {"x1": 10, "x2": 110, "y1": 230, "y2": 330}}}
}
mpc = MPCComponents.ACADOSMPC(dynamics = plant, inputs = ["F", "Qdot"], state_variables = ["Ca", "Cb", "Tr", "Tk"], outputs = ["Cb"], Ts = 0.005, Np = 30, Q1 = diagonal([1.0]), Q2 = diagonal([0.0, 0.0]), penalize_increments = true, Q3 = diagonal([5e-6, 2.5e-9]), umin = [5.0, -8500.0], umax = [100.0, 0.0], constrained = ["Tr", "Tk"], constrained_max = [142.0, 140.0], integrator = ACADOSIntegrator.IRK(), integrator_stages = 3, u_guess = [10.0, -1000.0]) {
"Dyad": {"placement": {"diagram": {"x1": 340, "x2": 440, "y1": 311, "y2": 411}}}
}
"Concentration of B"
variable Cb::Real
"Reactor temperature"
variable Tr::Real
"Jacket temperature"
variable Tk::Real
"Feed"
variable F::Real
"Heat flow"
variable Qdot::Real
"acados status"
variable flag::Real
relations
Cb = plant.Cb
Tr = plant.Tr
Tk = plant.Tk
F = mpc.u[1]
Qdot = mpc.u[2]
flag = mpc.exitflag
connect(plant.Ca_out, s[1].u) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 940, "y": 284}, {"x": 940, "y": 770}], "E": 2}],
"path": {}
}
}
connect(plant.Cb_out, s[2].u) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 900, "y": 309}, {"x": 900, "y": 770}], "E": 2}],
"path": {}
}
}
connect(plant.Tr_out, s[3].u) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 860, "y": 330}, {"x": 860, "y": 770}], "E": 2}],
"path": {}
}
}
connect(plant.Tk_out, s[4].u) {"Dyad": {"edges": [{"S": 1, "M": [{"x": 825, "y": 770}], "E": 2}], "path": {}}}
connect(ref.y, sr.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
connect(s[1].y, mpc.x[1], periodicclock.y) {
"Dyad": {
"edges": [
{"S": 1, "M": [{"x": 280, "y": 770}, {"x": 280, "y": 361}], "E": 2},
{"S": 2, "M": [{"x": 335, "y": 530}], "E": 3}
],
"path": {}
}
}
for i in 2:4
connect(s[i].y, mpc.x[i])
end
connect(sr.y, mpc.r[1]) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 320, "y": 280}, {"x": 320, "y": 326}], "E": 2}],
"path": {}
}
}
for i in 1:2
connect(mpc.u[i], zoh[i].u)
end
connect(zoh[1].y, plant.F)
connect(zoh[2].y, plant.Qdot)
metadata {"Dyad": {"doc": {"behavior": false}}}
endTest Cases ​
No test cases defined.
Related ​
Examples
Experiments
Analyses