@@ -72,7 +72,7 @@ function moveinput!(
7272 @warn " preparestate! should be called before moveinput! with current estimators"
7373 end
7474 validate_args (mpc, ry, d, lastu, D̂, R̂y, R̂u)
75- initpred! (mpc, mpc. estim. model, d, lastu, D̂, R̂y, R̂u)
75+ initpred! (mpc, mpc. estim. model, ry, d, lastu, D̂, R̂y, R̂u)
7676 linconstraint! (mpc, mpc. estim. model, mpc. transcription)
7777 linconstrainteq! (mpc, mpc. estim. model, mpc. transcription)
7878 Z̃ = optim_objective! (mpc)
@@ -202,7 +202,7 @@ function addinfo!(info, mpc::PredictiveController)
202202end
203203
204204@doc raw """
205- initpred!(mpc::PredictiveController, model::LinModel, d, lastu, D̂, R̂y, R̂u) -> nothing
205+ initpred!(mpc::PredictiveController, model::LinModel, ry, d, lastu, D̂, R̂y, R̂u) -> nothing
206206
207207Init linear model prediction matrices `F, q̃, r` and current estimated output `ŷ`.
208208
@@ -221,8 +221,8 @@ They are computed with these equations using in-place operations:
221221\e nd{aligned}
222222```
223223"""
224- function initpred! (mpc:: PredictiveController , model:: LinModel , d, lastu, D̂, R̂y, R̂u)
225- F = initpred_common! (mpc, model, d, lastu, D̂, R̂y, R̂u)
224+ function initpred! (mpc:: PredictiveController , model:: LinModel , ry, d, lastu, D̂, R̂y, R̂u)
225+ F = initpred_common! (mpc, model, ry, d, lastu, D̂, R̂y, R̂u)
226226 F .+ = mpc. B # F = F + B
227227 mul! (F, mpc. K, mpc. estim. x̂0, 1 , 1 ) # F = F + K*x̂0
228228 mul! (F, mpc. V, mpc. lastu0, 1 , 1 ) # F = F + V*lastu0
@@ -254,24 +254,26 @@ function initpred!(mpc::PredictiveController, model::LinModel, d, lastu, D̂, R
254254end
255255
256256@doc raw """
257- initpred!(mpc::PredictiveController, model::SimModel, d, lastu, D̂, R̂y, R̂u)
257+ initpred!(mpc::PredictiveController, model::SimModel, ry, d, lastu, D̂, R̂y, R̂u) -> nothing
258258
259259Init `lastu0, ŷ, F, d0, D̂0, D̂e, R̂y, R̂u` vectors when model is not a [`LinModel`](@ref).
260260"""
261- function initpred! (mpc:: PredictiveController , model:: SimModel , d, lastu, D̂, R̂y, R̂u)
262- F = initpred_common! (mpc, model, d, lastu, D̂, R̂y, R̂u)
261+ function initpred! (mpc:: PredictiveController , model:: SimModel , ry, d, lastu, D̂, R̂y, R̂u)
262+ initpred_common! (mpc, model, ry , d, lastu, D̂, R̂y, R̂u)
263263 return nothing
264264end
265265
266266"""
267- initpred_common!(mpc::PredictiveController, model::SimModel, d, lastu, D̂, R̂y, R̂u) -> F
267+ initpred_common!(mpc::PredictiveController, model::SimModel, ry, d, lastu, D̂, R̂y, R̂u) -> F
268268
269269Common computations of `initpred!` for all types of [`SimModel`](@ref).
270270
271271Will also init `mpc.F` with 0 values, or with the stochastic predictions `Ŷs` if `mpc.estim`
272272is an [`InternalModel`](@ref). The function returns `mpc.F`.
273273"""
274- function initpred_common! (mpc:: PredictiveController , model:: SimModel , d, lastu, D̂, R̂y, R̂u)
274+ function initpred_common! (
275+ mpc:: PredictiveController , model:: SimModel , ry, d, lastu, D̂, R̂y, R̂u
276+ )
275277 mpc. lastu0 .= lastu .- model. uop
276278 mul! (mpc. Tu_lastu0, mpc. Tu, mpc. lastu0)
277279 mpc. ŷ .= evaloutput (mpc. estim, d)
@@ -281,6 +283,7 @@ function initpred_common!(mpc::PredictiveController, model::SimModel, d, lastu,
281283 mpc. D̂e[1 : model. nd] .= d
282284 mpc. D̂e[model. nd+ 1 : end ] .= D̂
283285 end
286+ mpc. ry .= ry
284287 mpc. R̂y .= R̂y
285288 mpc. R̂u .= R̂u
286289 predictstoch! (mpc. F, mpc, mpc. estim)
300303" Fill `Ŷs` vector with 0 values when `estim` is not an [`InternalModel`](@ref)."
301304predictstoch! (Ŷs, mpc:: PredictiveController , :: StateEstimator ) = (Ŷs .= 0 ; nothing )
302305
306+ @doc raw """
307+ linconstraint_custom!(mpc::PredictiveController, model::SimModel)
308+
309+ Init the ``\m athbf{F_w}`` vector for the custom linear inequality constraints.
310+
311+ See [`relaxW`](@ref) for the definition of the vector. The function does nothing if
312+ `mpc.con.nw < 1`.
313+ """
314+ function linconstraint_custom! (mpc:: PredictiveController , model:: SimModel )
315+ mpc. con. nw < 1 && return nothing
316+ ny, nu, nd, buffer = model. ny, model. nu, model. nd, mpc. buffer
317+ Fw = mpc. con. Fw
318+ Ue_term, D̂e_term, R̂e_term = buffer. Ue, buffer. D̂e, buffer. Ŷe
319+ Fw .= 0
320+ Ue_term[1 : end - nu] .= mpc. Tu_lastu0 .+ mpc. Uop
321+ Ue_term[end - nu+ 1 : end ] .= mpc. lastu0 .+ model. uop
322+ mul! (Fw, mpc. con. W̄u, Ue_term, 1 , 1 )
323+ if model. nd > 0
324+ D̂e_term[1 : nd] .= mpc. d0 .+ model. dop
325+ D̂e_term[nd+ 1 : end ] .= mpc. D̂0 .+ mpc. Dop
326+ mul! (Fw, mpc. con. W̄d, D̂e_term, 1 , 1 )
327+ end
328+ R̂e_term[1 : ny] .= mpc. ry
329+ R̂e_term[ny+ 1 : end ] .= mpc. R̂y
330+ mul! (Fw, mpc. con. W̄r, R̂e_term, 1 , 1 )
331+ return linconstraint_custom_outputs! (mpc, model)
332+ end
333+
334+ " Also include the `W̄y` term in the custom linear constraints for [`LinModel`](@ref)."
335+ function linconstraint_custom_outputs! (mpc:: PredictiveController , model:: LinModel )
336+ Ŷe_term, Fw, ny = mpc. buffer. Ŷe, mpc. con. Fw, model. ny
337+ Ŷe_term[1 : ny] .= mpc. ŷ
338+ Ŷe_term[ny+ 1 : end ] .= mpc. F .+ mpc. Yop
339+ mul! (Fw, mpc. con. W̄y, Ŷe_term, 1 , 1 )
340+ return nothing
341+ end
342+ " Do nothing for other model types."
343+ linconstraint_custom_outputs! (:: PredictiveController , :: SimModel ) = nothing
344+
303345"""
304346 extended_vectors!(Ue, Ŷe, mpc::PredictiveController, U0, Ŷ0) -> Ue, Ŷe
305347
@@ -626,18 +668,28 @@ function setmodel_controller!(mpc::PredictiveController, uop_old, x̂op_old)
626668 weights = mpc. weights
627669 nu, ny, nd, Hp, Hc, nb = model. nu, model. ny, model. nd, mpc. Hp, mpc. Hc, mpc. nb
628670 optim, con = mpc. optim, mpc. con
671+ nZ = get_nZ (estim, transcription, Hp, Hc)
672+ Pu = mpc. P̃u[:, 1 : nZ]
629673 # --- prediction matrices ---
630674 E, G, J, K, V, B, ex̂, gx̂, jx̂, kx̂, vx̂, bx̂ = init_predmat (
631675 model, estim, transcription, Hp, Hc, nb
632676 )
633677 A_Ymin, A_Ymax, Ẽ = relaxŶ (E, con. C_ymin, con. C_ymax, mpc. nϵ)
678+ A_Wmin, A_Wmax, Ẽw = relaxW (E, Pu, Hp, con. W̄y, con. W̄u, con. C_wmin, con. C_wmax, mpc. nϵ)
634679 A_x̂min, A_x̂max, ẽx̂ = relaxterminal (ex̂, con. c_x̂min, con. c_x̂max, mpc. nϵ)
635680 mpc. Ẽ .= Ẽ
636681 mpc. G .= G
637682 mpc. J .= J
638683 mpc. K .= K
639684 mpc. V .= V
640685 mpc. B .= B
686+ # --- terminal constraints ---
687+ con. ẽx̂ .= ẽx̂
688+ con. gx̂ .= gx̂
689+ con. jx̂ .= jx̂
690+ con. kx̂ .= kx̂
691+ con. vx̂ .= vx̂
692+ con. bx̂ .= bx̂
641693 # --- defect matrices ---
642694 Eŝ, Gŝ, Jŝ, Kŝ, Vŝ, Bŝ = init_defectmat (model, estim, transcription, Hp, Hc, nb)
643695 A_ŝ, Ẽŝ = augmentdefect (Eŝ, mpc. nϵ)
@@ -647,15 +699,13 @@ function setmodel_controller!(mpc::PredictiveController, uop_old, x̂op_old)
647699 con. Kŝ .= Kŝ
648700 con. Vŝ .= Vŝ
649701 con. Bŝ .= Bŝ
702+ # --- custom linear constraints ---
703+ con. Ẽw .= Ẽw
650704 # --- linear inequality constraints ---
651- con. ẽx̂ .= ẽx̂
652- con. gx̂ .= gx̂
653- con. jx̂ .= jx̂
654- con. kx̂ .= kx̂
655- con. vx̂ .= vx̂
656- con. bx̂ .= bx̂
657705 con. A_Ymin .= A_Ymin
658706 con. A_Ymax .= A_Ymax
707+ con. A_Wmin .= A_Wmin
708+ con. A_Wmax .= A_Wmax
659709 con. A_x̂min .= A_x̂min
660710 con. A_x̂max .= A_x̂max
661711 con. A .= [
0 commit comments