@@ -42,33 +42,34 @@ See also [`LinMPC`](@ref), [`ExplicitMPC`](@ref), [`NonLinMPC`](@ref).
42
42
```jldoctest
43
43
julia> mpc = LinMPC(LinModel(tf(5, [2, 1]), 3), Nwt=[0], Hp=1000, Hc=1);
44
44
45
- julia> ry = [5]; u = moveinput!(mpc, ry); round.(u, digits=3)
45
+ julia> preparestate!(mpc, [0]); ry = [5];
46
+
47
+ julia> u = moveinput!(mpc, ry); round.(u, digits=3)
46
48
1-element Vector{Float64}:
47
49
1.0
48
50
```
49
51
"""
50
52
function moveinput! (
51
53
mpc:: PredictiveController ,
52
54
ry:: Vector = mpc. estim. model. yop,
53
- d :: Vector = mpc. estim . buffer. empty;
54
- Dhat :: Vector = repeat ( d, mpc. Hp),
55
- Rhaty:: Vector = repeat ( ry, mpc. Hp),
55
+ d :: Vector = mpc. buffer. empty;
56
+ Dhat :: Vector = repeat! (mpc . buffer . D̂, d, mpc. Hp),
57
+ Rhaty:: Vector = repeat! (mpc . buffer . R̂y, ry, mpc. Hp),
56
58
Rhatu:: Vector = mpc. Uop,
57
59
D̂ = Dhat,
58
60
R̂y = Rhaty,
59
61
R̂u = Rhatu
60
62
)
63
+ if mpc. estim. direct && ! mpc. estim. corrected[]
64
+ @warn " preparestate! should be called before moveinput! with current estimators"
65
+ end
61
66
validate_args (mpc, ry, d, D̂, R̂y, R̂u)
62
67
initpred! (mpc, mpc. estim. model, d, D̂, R̂y, R̂u)
63
68
linconstraint! (mpc, mpc. estim. model)
64
69
ΔŨ = optim_objective! (mpc)
65
- Δu = ΔŨ[1 : mpc. estim. model. nu] # receding horizon principle: only Δu(k) is used (1st one)
66
- u = mpc. estim. lastu0 + mpc. estim. model. uop + Δu
67
- return u
70
+ return getinput (mpc, ΔŨ)
68
71
end
69
72
70
-
71
-
72
73
@doc raw """
73
74
getinfo(mpc::PredictiveController) -> info
74
75
@@ -102,7 +103,7 @@ available for [`NonLinMPC`](@ref).
102
103
```jldoctest
103
104
julia> mpc = LinMPC(LinModel(tf(5, [2, 1]), 3), Nwt=[0], Hp=1, Hc=1);
104
105
105
- julia> u = moveinput!(mpc, [10]);
106
+ julia> preparestate!(mpc, [0]); u = moveinput!(mpc, [10]);
106
107
107
108
julia> round.(getinfo(mpc)[:Ŷ], digits=3)
108
109
1-element Vector{Float64}:
164
165
@doc raw """
165
166
initpred!(mpc::PredictiveController, model::LinModel, d, D̂, R̂y, R̂u) -> nothing
166
167
167
- Init linear model prediction matrices `F, q̃, p ` and current estimated output `ŷ`.
168
+ Init linear model prediction matrices `F, q̃, r ` and current estimated output `ŷ`.
168
169
169
170
See [`init_predmat`](@ref) and [`init_quadprog`](@ref) for the definition of the matrices.
170
171
They are computed with these equations using in-place operations:
@@ -176,15 +177,15 @@ They are computed with these equations using in-place operations:
176
177
\m athbf{C_u} &= \m athbf{T} \m athbf{u_0}(k-1) - (\m athbf{R̂_u - U_{op}}) \\
177
178
\m athbf{q̃} &= 2[(\m athbf{M}_{H_p} \m athbf{Ẽ})' \m athbf{C_y}
178
179
+ (\m athbf{L}_{H_p} \m athbf{S̃})' \m athbf{C_u}] \\
179
- p &= \m athbf{C_y}' \m athbf{M}_{H_p} \m athbf{C_y}
180
+ r &= \m athbf{C_y}' \m athbf{M}_{H_p} \m athbf{C_y}
180
181
+ \m athbf{C_u}' \m athbf{L}_{H_p} \m athbf{C_u}
181
182
\e nd{aligned}
182
183
```
183
184
"""
184
185
function initpred! (mpc:: PredictiveController , model:: LinModel , d, D̂, R̂y, R̂u)
185
186
mul! (mpc. T_lastu0, mpc. T, mpc. estim. lastu0)
186
- ŷ, F, q̃, p = mpc. ŷ, mpc. F, mpc. q̃, mpc. p
187
- ŷ .= evalŷ (mpc. estim, d)
187
+ ŷ, F, q̃, r = mpc. ŷ, mpc. F, mpc. q̃, mpc. r
188
+ ŷ .= evaloutput (mpc. estim, d)
188
189
predictstoch! (mpc, mpc. estim) # init mpc.F with Ŷs for InternalModel
189
190
F .+ = mpc. B
190
191
mul! (F, mpc. K, mpc. estim. x̂0, 1 , 1 )
@@ -201,13 +202,13 @@ function initpred!(mpc::PredictiveController, model::LinModel, d, D̂, R̂y, R̂
201
202
Cy = F .- mpc. R̂y0
202
203
M_Hp_Ẽ = mpc. M_Hp* mpc. Ẽ
203
204
mul! (q̃, M_Hp_Ẽ' , Cy)
204
- p .= dot (Cy, mpc. M_Hp, Cy)
205
+ r .= dot (Cy, mpc. M_Hp, Cy)
205
206
if ~ mpc. noR̂u
206
207
mpc. R̂u0 .= R̂u .- mpc. Uop
207
208
Cu = mpc. T_lastu0 .- mpc. R̂u0
208
209
L_Hp_S̃ = mpc. L_Hp* mpc. S̃
209
210
mul! (q̃, L_Hp_S̃' , Cu, 1 , 1 )
210
- p .+ = dot (Cu, mpc. L_Hp, Cu)
211
+ r .+ = dot (Cu, mpc. L_Hp, Cu)
211
212
end
212
213
lmul! (2 , q̃)
213
214
return nothing
@@ -220,7 +221,7 @@ Init `ŷ, F, d0, D̂0, D̂E, R̂y0, R̂u0` vectors when model is not a [`LinMod
220
221
"""
221
222
function initpred! (mpc:: PredictiveController , model:: SimModel , d, D̂, R̂y, R̂u)
222
223
mul! (mpc. T_lastu0, mpc. T, mpc. estim. lastu0)
223
- mpc. ŷ .= evalŷ (mpc. estim, d)
224
+ mpc. ŷ .= evaloutput (mpc. estim, d)
224
225
predictstoch! (mpc, mpc. estim) # init mpc.F with Ŷs for InternalModel
225
226
if model. nd ≠ 0
226
227
mpc. d0 .= d .- model. dop
@@ -367,9 +368,9 @@ at specific input increments `ΔŨ` and predictions `Ŷ0` values. It mutates t
367
368
function obj_nonlinprog! (
368
369
U0, Ȳ, _ , mpc:: PredictiveController , model:: LinModel , Ŷ0, ΔŨ:: AbstractVector{NT}
369
370
) where NT <: Real
370
- J = obj_quadprog (ΔŨ, mpc. H̃, mpc. q̃) + mpc. p []
371
+ J = obj_quadprog (ΔŨ, mpc. H̃, mpc. q̃) + mpc. r []
371
372
if ! iszero (mpc. E)
372
- ny, Hp, ŷ, D̂E = model . ny, mpc . Hp, mpc. ŷ, mpc. D̂E
373
+ ŷ, D̂E = mpc. ŷ, mpc. D̂E
373
374
U = U0
374
375
U .+ = mpc. Uop
375
376
uend = @views U[(end - model. nu+ 1 ): end ]
@@ -501,6 +502,24 @@ function preparestate!(mpc::PredictiveController, ym, d=mpc.estim.buffer.empty)
501
502
return preparestate! (mpc. estim, ym, d)
502
503
end
503
504
505
+ @doc raw """
506
+ getinput(mpc::PredictiveController, ΔŨ) -> u
507
+
508
+ Get current manipulated input `u` from a [`PredictiveController`](@ref) solution `ΔŨ`.
509
+
510
+ The first manipulated input ``\m athbf{u}(k)`` is extracted from the input increments vector
511
+ ``\m athbf{ΔŨ}`` and applied on the plant (from the receding horizon principle).
512
+ """
513
+ function getinput (mpc, ΔŨ)
514
+ Δu = mpc. buffer. u
515
+ for i in 1 : mpc. estim. model. nu
516
+ Δu[i] = ΔŨ[i]
517
+ end
518
+ u = Δu
519
+ u .+ = mpc. estim. lastu0 .+ mpc. estim. model. uop
520
+ return u
521
+ end
522
+
504
523
"""
505
524
updatestate!(mpc::PredictiveController, u, ym, d=[]) -> x̂next
506
525
0 commit comments