@@ -22,10 +22,6 @@ the last section.
22
22
as a basic starting template to combine both packages. There is no guarantee that it
23
23
will work for all corner cases.
24
24
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
-
29
25
We first construct and instantiate the pendulum model:
30
26
31
27
``` @example 1
@@ -58,15 +54,13 @@ We than convert the MTK model to an [input-output system](https://docs.sciml.ai/
58
54
59
55
``` @example 1
60
56
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(
62
58
model, inputs, split=false; outputs
63
59
)
64
60
if any(ModelingToolkit.is_alg_equation, equations(io_sys))
65
61
error("Systems with algebraic equations are not supported")
66
62
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)
70
64
function f!(ẋ, x, u, _ , p)
71
65
try
72
66
f_ip(ẋ, x, u, p, nothing)
@@ -100,35 +94,43 @@ function generate_f_h(model, inputs, outputs)
100
94
end
101
95
return nothing
102
96
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
104
99
end
105
100
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
110
103
```
111
104
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:
113
110
114
111
``` @example 1
112
+ vu, vx, vy = ["\$τ\$ (Nm)"], ["\$ω\$ (rad/s)", "\$θ\$ (rad)"], ["\$θ\$ (°)"]
113
+ Ts = 0.1
115
114
model = setname!(NonLinModel(f!, h!, Ts, nu, nx, ny; p); u=vu, x=vx, y=vy)
116
115
```
117
116
118
117
We also instantiate a plant model with a 25 % larger friction coefficient `` K `` :
119
118
120
119
``` @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)
124
125
```
125
126
126
127
## Controller Design
127
128
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:
129
131
130
132
``` @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]
132
134
estim = UnscentedKalmanFilter(model; α, σQ, σR, nint_u, σQint_u)
133
135
Hp, Hc, Mwt, Nwt = 20, 2, [0.5], [2.5]
134
136
nmpc = NonLinMPC(estim; Hp, Hc, Mwt, Nwt, Cwt=Inf)
@@ -152,7 +154,7 @@ savefig("plot1_MTK.svg"); nothing # hide
152
154
and also the output disturbance rejection:
153
155
154
156
``` @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])
156
158
plot(res_yd)
157
159
savefig("plot2_MTK.svg"); nothing # hide
158
160
```
0 commit comments