Skip to content

Commit bec06fe

Browse files
authored
Merge pull request #340 from JuliaControl/update_mtk_manual
doc: updating MTK example to v11 in manual.
2 parents b9c5c77 + 53c94fa commit bec06fe

File tree

3 files changed

+39
-41
lines changed

3 files changed

+39
-41
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "ModelPredictiveControl"
22
uuid = "61f9bdb8-6ae4-484a-811f-bbf86720c31c"
3-
version = "2.2.1"
3+
version = "2.2.2"
44
authors = ["Francis Gagnon"]
55

66
[deps]

docs/Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@ JuMP = "1"
1818
LinearAlgebra = "1.10"
1919
LinearMPC = "0.8.0"
2020
Logging = "1.10"
21-
ModelingToolkit = "10"
21+
ModelingToolkit = "10, 11"
2222
Plots = "1"

docs/src/manual/mtk.md

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
2925
We first construct and instantiate the pendulum model:
3026

3127
```@example 1
3228
using 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

5740
We than convert the MTK model to an [input-output system](https://docs.sciml.ai/ModelingToolkit/stable/basics/InputOutput/):
5841

5942
```@example 1
6043
function 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
10396
end
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)
10699
x_sym
107100
```
108101

109102
Since MTK is an acausal modeling framework, we do not have the control on the state
110103
realization chosen by the package. The content of `x_sym` above shows it settled for the
111104
state 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
116115
vu, vx, vy = ["\$τ\$ (Nm)"], ["\$ω\$ (rad/s)", "\$θ\$ (rad)"], ["\$θ\$ (°)"]
117116
Ts = 0.1
118117
model = 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

Comments
 (0)