@@ -18,7 +18,8 @@ results ``\mathbf{u}(k)``. Following the receding horizon principle, the algorit
18
18
the optimal future manipulated inputs ``\m athbf{u}(k+1), \m athbf{u}(k+2), ...`` Note that
19
19
the method mutates `mpc` internal data but it does not modifies `mpc.estim` states. Call
20
20
[`preparestate!(mpc, ym, d)`](@ref) before `moveinput!`, and [`updatestate!(mpc, u, ym, d)`](@ref)
21
- after, to update `mpc` state estimates.
21
+ after, to update `mpc` state estimates. Setpoint and measured disturbance previews can
22
+ be implemented with the `R̂y`, `R̂u` and `D̂` keyword arguments.
22
23
23
24
Calling a [`PredictiveController`](@ref) object calls this method.
24
25
@@ -35,8 +36,8 @@ See also [`LinMPC`](@ref), [`ExplicitMPC`](@ref), [`NonLinMPC`](@ref).
35
36
in the future by default or ``\m athbf{d̂}(k+j)=\m athbf{d}(k)`` for ``j=1`` to ``H_p``.
36
37
- `R̂y=repeat(ry, mpc.Hp)` or *`Rhaty`* : predicted output setpoints ``\m athbf{R̂_y}``, constant
37
38
in the future by default or ``\m athbf{r̂_y}(k+j)=\m athbf{r_y}(k)`` for ``j=1`` to ``H_p``.
38
- - `R̂u=mpc.Uop` or *`Rhatu`* : predicted manipulated input setpoints, constant in the future
39
- by default or ``\m athbf{r̂_u}(k+j)=\m athbf{u_{op}}`` for ``j=0`` to ``H_p-1``.
39
+ - `R̂u=mpc.Uop` or *`Rhatu`* : predicted manipulated input setpoints `` \m athbf{R̂_u}`` , constant
40
+ in the future by default or ``\m athbf{r̂_u}(k+j)=\m athbf{u_{op}}`` for ``j=0`` to ``H_p-1``.
40
41
41
42
# Examples
42
43
```jldoctest
@@ -53,8 +54,8 @@ function moveinput!(
53
54
mpc:: PredictiveController ,
54
55
ry:: Vector = mpc. estim. model. yop,
55
56
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),
57
+ Dhat :: Vector = repeat! (mpc. buffer. D̂, d, mpc. Hp),
58
+ Rhaty:: Vector = repeat! (mpc. buffer. Ŷ , ry, mpc. Hp),
58
59
Rhatu:: Vector = mpc. Uop,
59
60
D̂ = Dhat,
60
61
R̂y = Rhaty,
@@ -127,9 +128,9 @@ function getinfo(mpc::PredictiveController{NT}) where NT<:Real
127
128
Ŷ = Ȳ
128
129
Ŷ .= @views Ŷe[model. ny+ 1 : end ]
129
130
oldF = copy (mpc. F)
130
- predictstoch! (mpc, mpc. estim)
131
- Ŷs .= mpc . F # predictstoch! init mpc.F with Ŷs value if estim is an InternalModel
132
- mpc . F .= oldF # restore old F value
131
+ F = predictstoch! (mpc, mpc. estim)
132
+ Ŷs .= F # predictstoch! init mpc.F with Ŷs value if estim is an InternalModel
133
+ F .= oldF # restore old F value
133
134
info[:ΔU ] = mpc. ΔŨ[1 : mpc. Hc* model. nu]
134
135
info[:ϵ ] = mpc. nϵ == 1 ? mpc. ΔŨ[end ] : zero (NT)
135
136
info[:J ] = J
@@ -189,36 +190,26 @@ They are computed with these equations using in-place operations:
189
190
```
190
191
"""
191
192
function initpred! (mpc:: PredictiveController , model:: LinModel , d, D̂, R̂y, R̂u)
192
- lastu = mpc. buffer. u
193
- lastu .= mpc. estim. lastu0 .+ model. uop
194
- mul! (mpc. T_lastu, mpc. T, lastu)
195
- ŷ, F, q̃, r = mpc. ŷ, mpc. F, mpc. q̃, mpc. r
196
- Cy, Cu, M_Hp_Ẽ, L_Hp_S̃ = mpc. buffer. Ŷ, mpc. buffer. U, mpc. buffer. Ẽ, mpc. buffer. S̃
197
- ŷ .= evaloutput (mpc. estim, d)
198
- predictstoch! (mpc, mpc. estim) # init F with Ŷs for InternalModel
193
+ F = initpred_common! (mpc, model, d, D̂, R̂y, R̂u)
199
194
F .+ = mpc. B # F = F + B
200
195
mul! (F, mpc. K, mpc. estim. x̂0, 1 , 1 ) # F = F + K*x̂0
201
196
mul! (F, mpc. V, mpc. estim. lastu0, 1 , 1 ) # F = F + V*lastu0
202
197
if model. nd ≠ 0
203
- mpc. d0 .= d .- model. dop
204
- mpc. D̂0 .= D̂ .- mpc. Dop
205
- mpc. D̂e[1 : model. nd] .= d
206
- mpc. D̂e[model. nd+ 1 : end ] .= D̂
207
198
mul! (F, mpc. G, mpc. d0, 1 , 1 ) # F = F + G*d0
208
199
mul! (F, mpc. J, mpc. D̂0, 1 , 1 ) # F = F + J*D̂0
209
200
end
201
+ Cy, Cu, M_Hp_Ẽ, L_Hp_S̃ = mpc. buffer. Ŷ, mpc. buffer. U, mpc. buffer. Ẽ, mpc. buffer. S̃
202
+ q̃, r = mpc. q̃, mpc. r
210
203
q̃ .= 0
211
204
r .= 0
212
205
# --- output setpoint tracking term ---
213
- mpc. R̂y .= R̂y
214
206
if ! mpc. weights. iszero_M_Hp[]
215
207
Cy .= F .+ mpc. Yop .- R̂y
216
208
mul! (M_Hp_Ẽ, mpc. weights. M_Hp, mpc. Ẽ)
217
209
mul! (q̃, M_Hp_Ẽ' , Cy, 1 , 1 ) # q̃ = q̃ + M_Hp*Ẽ'*Cy
218
210
r .+ = dot (Cy, mpc. weights. M_Hp, Cy) # r = r + Cy'*M_Hp*Cy
219
211
end
220
212
# --- input setpoint tracking term ---
221
- mpc. R̂u .= R̂u
222
213
if ! mpc. weights. iszero_L_Hp[]
223
214
Cu .= mpc. T_lastu .- R̂u
224
215
mul! (L_Hp_S̃, mpc. weights. L_Hp, mpc. S̃)
@@ -236,11 +227,23 @@ end
236
227
Init `ŷ, F, d0, D̂0, D̂e, R̂y, R̂u` vectors when model is not a [`LinModel`](@ref).
237
228
"""
238
229
function initpred! (mpc:: PredictiveController , model:: SimModel , d, D̂, R̂y, R̂u)
230
+ F = initpred_common! (mpc, model, d, D̂, R̂y, R̂u)
231
+ return nothing
232
+ end
233
+
234
+ """
235
+ initpred_common!(mpc::PredictiveController, model::SimModel, d, D̂, R̂y, R̂u) -> F
236
+
237
+ Common computations of `initpred!` for all types of [`SimModel`](@ref).
238
+
239
+ Will init `mpc.F` with 0 values, or with the stochastic predictions `Ŷs` if `mpc.estim` is
240
+ an [`InternalModel`](@ref). The function returns `mpc.F`.
241
+ """
242
+ function initpred_common! (mpc:: PredictiveController , model:: SimModel , d, D̂, R̂y, R̂u)
239
243
lastu = mpc. buffer. u
240
244
lastu .= mpc. estim. lastu0 .+ model. uop
241
245
mul! (mpc. T_lastu, mpc. T, lastu)
242
246
mpc. ŷ .= evaloutput (mpc. estim, d)
243
- predictstoch! (mpc, mpc. estim) # init F with Ŷs for InternalModel
244
247
if model. nd ≠ 0
245
248
mpc. d0 .= d .- model. dop
246
249
mpc. D̂0 .= D̂ .- mpc. Dop
@@ -249,22 +252,23 @@ function initpred!(mpc::PredictiveController, model::SimModel, d, D̂, R̂y, R̂
249
252
end
250
253
mpc. R̂y .= R̂y
251
254
mpc. R̂u .= R̂u
252
- return nothing
255
+ F = predictstoch! (mpc, mpc. estim) # init mpc.F with Ŷs for InternalModel
256
+ return F
253
257
end
254
258
255
259
@doc raw """
256
- predictstoch!(mpc::PredictiveController, estim::InternalModel)
260
+ predictstoch!(mpc::PredictiveController, estim::InternalModel) -> F
257
261
258
262
Init `mpc.F` vector with ``\m athbf{F = Ŷ_s}`` when `estim` is an [`InternalModel`](@ref).
259
263
"""
260
- function predictstoch! (mpc:: PredictiveController{NT} , estim:: InternalModel ) where {NT <: Real }
264
+ function predictstoch! (mpc:: PredictiveController , estim:: InternalModel )
261
265
Ŷs = mpc. F
262
266
mul! (Ŷs, mpc. Ks, estim. x̂s)
263
267
mul! (Ŷs, mpc. Ps, estim. ŷs, 1 , 1 )
264
- return nothing
268
+ return mpc . F
265
269
end
266
270
" Separate stochastic predictions are not needed if `estim` is not [`InternalModel`](@ref)."
267
- predictstoch! (mpc:: PredictiveController , :: StateEstimator ) = (mpc. F .= 0 ; nothing )
271
+ predictstoch! (mpc:: PredictiveController , :: StateEstimator ) = (mpc. F .= 0 )
268
272
269
273
@doc raw """
270
274
linconstraint!(mpc::PredictiveController, model::LinModel)
@@ -320,7 +324,7 @@ function linconstraint!(mpc::PredictiveController, ::SimModel)
320
324
mpc. con. b[(n+ 1 ): (n+ nΔŨ)] .= @. + mpc. con. ΔŨmax
321
325
if any (mpc. con. i_b)
322
326
lincon = mpc. optim[:linconstraint ]
323
- JuMP. set_normalized_rhs (lincon, mpc. con. b[mpc. con. i_b])
327
+ @views JuMP. set_normalized_rhs (lincon, mpc. con. b[mpc. con. i_b])
324
328
end
325
329
return nothing
326
330
end
@@ -476,12 +480,14 @@ solution. A failed optimization prints an `@error` log in the REPL and returns t
476
480
warm-start value.
477
481
"""
478
482
function optim_objective! (mpc:: PredictiveController{NT} ) where {NT<: Real }
479
- optim = mpc. optim
480
- model = mpc. estim . model
483
+ model, optim = mpc . estim . model, mpc. optim
484
+ nu, Hc = model . nu, mpc. Hc
481
485
ΔŨvar:: Vector{JuMP.VariableRef} = optim[:ΔŨvar ]
482
486
# initial ΔŨ (warm-start): [Δu_{k-1}(k); Δu_{k-1}(k+1); ... ; 0_{nu × 1}; ϵ_{k-1}]
483
- ϵ0 = (mpc. nϵ == 1 ) ? mpc. ΔŨ[end ] : empty (mpc. ΔŨ)
484
- ΔŨ0 = [mpc. ΔŨ[(model. nu+ 1 ): (mpc. Hc* model. nu)]; zeros (NT, model. nu); ϵ0]
487
+ ΔŨ0 = mpc. buffer. ΔŨ
488
+ ΔŨ0[1 : (Hc* nu- nu)] .= @views mpc. ΔŨ[nu+ 1 : Hc* nu]
489
+ ΔŨ0[(Hc* nu- nu+ 1 ): (Hc* nu)] .= 0
490
+ mpc. nϵ == 1 && (ΔŨ0[end ] = mpc. ΔŨ[end ])
485
491
JuMP. set_start_value .(ΔŨvar, ΔŨ0)
486
492
set_objective_linear_coef! (mpc, ΔŨvar)
487
493
try
0 commit comments