Skip to content

Commit 1a38039

Browse files
authored
Merge pull request #251 from JuliaControl/mtk_update
doc: update pendulum exemple to MTK v10 in the manual
2 parents 0dbe0b9 + d87d22a commit 1a38039

File tree

2 files changed

+23
-21
lines changed

2 files changed

+23
-21
lines changed

docs/Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ Documenter = "1"
1616
JuMP = "1"
1717
LinearAlgebra = "1.10"
1818
Logging = "1.10"
19-
ModelingToolkit = "9.50 - 9.76"
19+
ModelingToolkit = "10"
2020
Plots = "1"

docs/src/manual/mtk.md

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@ 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` v9.50 to 9.76 (corresponding to the following
27-
`[compat]` entry: `ModelingToolkit = "9.50 - 9.76"`).
28-
2925
We first construct and instantiate the pendulum model:
3026

3127
```@example 1
@@ -58,15 +54,13 @@ We than convert the MTK model to an [input-output system](https://docs.sciml.ai/
5854

5955
```@example 1
6056
function generate_f_h(model, inputs, outputs)
61-
(_, f_ip), dvs, psym, io_sys = ModelingToolkit.generate_control_function(
57+
(_, f_ip), x_sym, p_sym, io_sys = ModelingToolkit.generate_control_function(
6258
model, inputs, split=false; outputs
6359
)
6460
if any(ModelingToolkit.is_alg_equation, equations(io_sys))
6561
error("Systems with algebraic equations are not supported")
6662
end
67-
nu, nx, ny = length(inputs), length(dvs), length(outputs)
68-
vx = string.(dvs)
69-
p = varmap_to_vars(defaults(io_sys), psym)
63+
nu, nx, ny = length(inputs), length(x_sym), length(outputs)
7064
function f!(ẋ, x, u, _ , p)
7165
try
7266
f_ip(ẋ, x, u, p, nothing)
@@ -100,35 +94,43 @@ function generate_f_h(model, inputs, outputs)
10094
end
10195
return nothing
10296
end
103-
return f!, h!, p, nu, nx, ny, vx
97+
p = varmap_to_vars(defaults(io_sys), p_sym)
98+
return f!, h!, p, x_sym, nu, nx, ny
10499
end
105100
inputs, outputs = [mtk_model.τ], [mtk_model.y]
106-
f!, h!, p, nu, nx, ny, vx = generate_f_h(mtk_model, inputs, outputs)
107-
Ts = 0.1
108-
vu, vy = ["\$τ\$ (Nm)"], ["\$θ\$ (°)"]
109-
nothing # hide
101+
f!, h!, p, x_sym, nu, nx, ny = generate_f_h(mtk_model, inputs, outputs)
102+
x_sym
110103
```
111104

112-
A [`NonLinModel`](@ref) can now be constructed:
105+
Since MTK is an acausal modeling framework, we do not have the control on the state
106+
realization chosen by the package. The content of `x_sym` above shows it settled for the
107+
state vector ``\mathbf{x}(t) = [\begin{smallmatrix}ω(t) && θ(t)\end{smallmatrix}]'``,
108+
that is, the states of the [last section](@ref man_nonlin) in the reverse order. We can now
109+
construct a [`NonLinModel`](@ref) with this specific state realization:
113110

114111
```@example 1
112+
vu, vx, vy = ["\$τ\$ (Nm)"], ["\$ω\$ (rad/s)", "\$θ\$ (rad)"], ["\$θ\$ (°)"]
113+
Ts = 0.1
115114
model = setname!(NonLinModel(f!, h!, Ts, nu, nx, ny; p); u=vu, x=vx, y=vy)
116115
```
117116

118117
We also instantiate a plant model with a 25 % larger friction coefficient ``K``:
119118

120119
```@example 1
121-
mtk_model.K = defaults(mtk_model)[mtk_model.K] * 1.25
122-
f_plant, h_plant, p = generate_f_h(mtk_model, inputs, outputs)
123-
plant = setname!(NonLinModel(f_plant, h_plant, Ts, nu, nx, ny; p); u=vu, x=vx, y=vy)
120+
@named mtk_plant = Pendulum(K=1.25*defaults(mtk_model)[mtk_model.K])
121+
mtk_plant = complete(mtk_plant)
122+
inputs, outputs = [mtk_plant.τ], [mtk_plant.y]
123+
f2!, h2!, p2 = generate_f_h(mtk_plant, inputs, outputs)
124+
plant = setname!(NonLinModel(f2!, h2!, Ts, nu, nx, ny; p=p2), u=vu, x=vx, y=vy)
124125
```
125126

126127
## Controller Design
127128

128-
We can than reproduce the Kalman filter and the controller design of the [last section](@ref man_nonlin):
129+
We can than reproduce the Kalman filter and the controller design of the [last section](@ref man_nonlin)
130+
by reversing the order of `σQ` vector, because of the different state realization:
129131

130132
```@example 1
131-
α=0.01; σQ=[0.1, 1.0]; σR=[5.0]; nint_u=[1]; σQint_u=[0.1]
133+
α=0.01; σQ=[1.0, 0.1]; σR=[5.0]; nint_u=[1]; σQint_u=[0.1]
132134
estim = UnscentedKalmanFilter(model; α, σQ, σR, nint_u, σQint_u)
133135
Hp, Hc, Mwt, Nwt = 20, 2, [0.5], [2.5]
134136
nmpc = NonLinMPC(estim; Hp, Hc, Mwt, Nwt, Cwt=Inf)
@@ -152,7 +154,7 @@ savefig("plot1_MTK.svg"); nothing # hide
152154
and also the output disturbance rejection:
153155

154156
```@example 1
155-
res_yd = sim!(nmpc, N, [180.0], plant=plant, x_0=[π, 0], x̂_0=[π, 0, 0], y_step=[10])
157+
res_yd = sim!(nmpc, N, [180.0], plant=plant, x_0=[0, π], x̂_0=[0, π, 0], y_step=[10])
156158
plot(res_yd)
157159
savefig("plot2_MTK.svg"); nothing # hide
158160
```

0 commit comments

Comments
 (0)