@@ -22,44 +22,27 @@ the last section.
2222 as a basic starting template to combine both packages. There is no guarantee that it
2323 will work for all corner cases.
2424
25- !!! compat
26- The example works on ` ModelingToolkit.jl ` v10 (corresponding to the following ` [compat] `
27- entry: ` ModelingToolkit = "10" ` ).
28-
2925We first construct and instantiate the pendulum model:
3026
3127``` @example 1
3228using ModelPredictiveControl, ModelingToolkit
33- using ModelingToolkit: D_nounits as D, t_nounits as t, varmap_to_vars
34- @mtkmodel Pendulum begin
35- @parameters begin
36- g = 9.8
37- L = 0.4
38- K = 1.2
39- m = 0.3
40- end
41- @variables begin
42- θ(t) # state
43- ω(t) # state
44- τ(t) # input
45- y(t) # output
46- end
47- @equations begin
48- D(θ) ~ ω
49- D(ω) ~ -g/L*sin(θ) - K/m*ω + τ/m/L^2
50- y ~ θ * 180 / π
51- end
52- end
53- @named mtk_model = Pendulum()
54- mtk_model = complete(mtk_model)
29+ using ModelingToolkit: D_nounits as D, t_nounits as t
30+ @parameters g=9.8 L=0.4 K=1.2 m=0.3
31+ @variables θ(t)=0 ω(t)=0 τ(t)=0 y(t)
32+ eqs = [
33+ D(θ) ~ ω
34+ D(ω) ~ -g/L*sin(θ) - K/m*ω + τ/m/L^2
35+ y ~ θ * 180 / π
36+ ]
37+ @named mtk_model = System(eqs, t)
5538```
5639
5740We than convert the MTK model to an [ input-output system] ( https://docs.sciml.ai/ModelingToolkit/stable/basics/InputOutput/ ) :
5841
5942``` @example 1
6043function generate_f_h(model, inputs, outputs)
6144 (_, f_ip), x_sym, p_sym, io_sys = ModelingToolkit.generate_control_function(
62- model, inputs, split=false; outputs
45+ model, inputs, split=false, simplify=true
6346 )
6447 if any(ModelingToolkit.is_alg_equation, equations(io_sys))
6548 error("Systems with algebraic equations are not supported")
@@ -98,34 +81,49 @@ function generate_f_h(model, inputs, outputs)
9881 end
9982 return nothing
10083 end
101- p = varmap_to_vars(defaults(io_sys), p_sym)
102- return f!, h!, p, x_sym, nu, nx, ny
84+ ic = initial_conditions(io_sys)
85+ p_map = try
86+ Dict(sym => ic[sym] for sym in p_sym)
87+ catch err
88+ if err isa KeyError # the key presumably appears in `bindings(io_sys)`:
89+ error("Non-constant parameter values are not supported (a.k.a. bindings)")
90+ else
91+ rethrow()
92+ end
93+ end
94+ p = ModelingToolkit.varmap_to_vars(p_map, p_sym)
95+ return f!, h!, p, x_sym, p_sym, nu, nx, ny
10396end
104- inputs, outputs = [mtk_model. τ], [mtk_model. y]
105- f!, h!, p, x_sym, nu, nx, ny = generate_f_h(mtk_model, inputs, outputs)
97+ inputs, outputs = [τ], [y]
98+ f!, h!, p, x_sym, p_sym, nu, nx, ny = generate_f_h(mtk_model, inputs, outputs)
10699x_sym
107100```
108101
109102Since MTK is an acausal modeling framework, we do not have the control on the state
110103realization chosen by the package. The content of ` x_sym ` above shows it settled for the
111104state vector `` \mathbf{x}(t) = [\begin{smallmatrix}ω(t) && θ(t)\end{smallmatrix}]' `` ,
112- that is, the states of the [ last section] (@ref man_nonlin) in the reverse order. We can now
113- construct a [ ` NonLinModel ` ] ( @ref ) with this specific state realization:
105+ that is, the states of the [ last section] (@ref man_nonlin) in the reverse order. As the same
106+ also applies for the parameters, the ` p_sym ` object informs on how the ` p ` vector is sorted:
107+
108+ ``` @example 1
109+ [p_sym p]
110+ ```
111+
112+ We can now construct a [ ` NonLinModel ` ] ( @ref ) with this specific state realization:
114113
115114``` @example 1
116115vu, vx, vy = ["\$τ\$ (Nm)"], ["\$ω\$ (rad/s)", "\$θ\$ (rad)"], ["\$θ\$ (°)"]
117116Ts = 0.1
118117model = setname!(NonLinModel(f!, h!, Ts, nu, nx, ny; p); u=vu, x=vx, y=vy)
119118```
120119
121- We also instantiate a plant model with a 25 % larger friction coefficient `` K `` :
120+ We also instantiate a plant model with a 25 % larger friction coefficient `` K `` , which is
121+ the third element of ` p ` , as shown above:
122122
123123``` @example 1
124- @named mtk_plant = Pendulum(K=1.25*defaults(mtk_model)[mtk_model.K])
125- mtk_plant = complete(mtk_plant)
126- inputs, outputs = [mtk_plant.τ], [mtk_plant.y]
127- f2!, h2!, p2 = generate_f_h(mtk_plant, inputs, outputs)
128- plant = setname!(NonLinModel(f2!, h2!, Ts, nu, nx, ny; p=p2), u=vu, x=vx, y=vy)
124+ p2 = copy(p)
125+ p2[3] = 1.25*p[3]
126+ plant = setname!(NonLinModel(f!, h!, Ts, nu, nx, ny; p=p2), u=vu, x=vx, y=vy)
129127```
130128
131129## Controller Design
0 commit comments