@@ -42,33 +42,34 @@ See also [`LinMPC`](@ref), [`ExplicitMPC`](@ref), [`NonLinMPC`](@ref).
4242```jldoctest
4343julia> mpc = LinMPC(LinModel(tf(5, [2, 1]), 3), Nwt=[0], Hp=1000, Hc=1);
4444
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)
46481-element Vector{Float64}:
4749 1.0
4850```
4951"""
5052function moveinput! (
5153 mpc:: PredictiveController ,
5254 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),
5658 Rhatu:: Vector = mpc. Uop,
5759 D̂ = Dhat,
5860 R̂y = Rhaty,
5961 R̂u = Rhatu
6062)
63+ if mpc. estim. direct && ! mpc. estim. corrected[]
64+ @warn " preparestate! should be called before moveinput! with current estimators"
65+ end
6166 validate_args (mpc, ry, d, D̂, R̂y, R̂u)
6267 initpred! (mpc, mpc. estim. model, d, D̂, R̂y, R̂u)
6368 linconstraint! (mpc, mpc. estim. model)
6469 ΔŨ = 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, ΔŨ)
6871end
6972
70-
71-
7273@doc raw """
7374 getinfo(mpc::PredictiveController) -> info
7475
@@ -102,7 +103,7 @@ available for [`NonLinMPC`](@ref).
102103```jldoctest
103104julia> mpc = LinMPC(LinModel(tf(5, [2, 1]), 3), Nwt=[0], Hp=1, Hc=1);
104105
105- julia> u = moveinput!(mpc, [10]);
106+ julia> preparestate!(mpc, [0]); u = moveinput!(mpc, [10]);
106107
107108julia> round.(getinfo(mpc)[:Ŷ], digits=3)
1081091-element Vector{Float64}:
164165@doc raw """
165166 initpred!(mpc::PredictiveController, model::LinModel, d, D̂, R̂y, R̂u) -> nothing
166167
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 `ŷ`.
168169
169170See [`init_predmat`](@ref) and [`init_quadprog`](@ref) for the definition of the matrices.
170171They are computed with these equations using in-place operations:
@@ -176,15 +177,15 @@ They are computed with these equations using in-place operations:
176177 \m athbf{C_u} &= \m athbf{T} \m athbf{u_0}(k-1) - (\m athbf{R̂_u - U_{op}}) \\
177178 \m athbf{q̃} &= 2[(\m athbf{M}_{H_p} \m athbf{Ẽ})' \m athbf{C_y}
178179 + (\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}
180181 + \m athbf{C_u}' \m athbf{L}_{H_p} \m athbf{C_u}
181182\e nd{aligned}
182183```
183184"""
184185function initpred! (mpc:: PredictiveController , model:: LinModel , d, D̂, R̂y, R̂u)
185186 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)
188189 predictstoch! (mpc, mpc. estim) # init mpc.F with Ŷs for InternalModel
189190 F .+ = mpc. B
190191 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̂
201202 Cy = F .- mpc. R̂y0
202203 M_Hp_Ẽ = mpc. M_Hp* mpc. Ẽ
203204 mul! (q̃, M_Hp_Ẽ' , Cy)
204- p .= dot (Cy, mpc. M_Hp, Cy)
205+ r .= dot (Cy, mpc. M_Hp, Cy)
205206 if ~ mpc. noR̂u
206207 mpc. R̂u0 .= R̂u .- mpc. Uop
207208 Cu = mpc. T_lastu0 .- mpc. R̂u0
208209 L_Hp_S̃ = mpc. L_Hp* mpc. S̃
209210 mul! (q̃, L_Hp_S̃' , Cu, 1 , 1 )
210- p .+ = dot (Cu, mpc. L_Hp, Cu)
211+ r .+ = dot (Cu, mpc. L_Hp, Cu)
211212 end
212213 lmul! (2 , q̃)
213214 return nothing
@@ -220,7 +221,7 @@ Init `ŷ, F, d0, D̂0, D̂E, R̂y0, R̂u0` vectors when model is not a [`LinMod
220221"""
221222function initpred! (mpc:: PredictiveController , model:: SimModel , d, D̂, R̂y, R̂u)
222223 mul! (mpc. T_lastu0, mpc. T, mpc. estim. lastu0)
223- mpc. ŷ .= evalŷ (mpc. estim, d)
224+ mpc. ŷ .= evaloutput (mpc. estim, d)
224225 predictstoch! (mpc, mpc. estim) # init mpc.F with Ŷs for InternalModel
225226 if model. nd ≠ 0
226227 mpc. d0 .= d .- model. dop
@@ -367,9 +368,9 @@ at specific input increments `ΔŨ` and predictions `Ŷ0` values. It mutates t
367368function obj_nonlinprog! (
368369 U0, Ȳ, _ , mpc:: PredictiveController , model:: LinModel , Ŷ0, ΔŨ:: AbstractVector{NT}
369370) where NT <: Real
370- J = obj_quadprog (ΔŨ, mpc. H̃, mpc. q̃) + mpc. p []
371+ J = obj_quadprog (ΔŨ, mpc. H̃, mpc. q̃) + mpc. r []
371372 if ! iszero (mpc. E)
372- ny, Hp, ŷ, D̂E = model . ny, mpc . Hp, mpc. ŷ, mpc. D̂E
373+ ŷ, D̂E = mpc. ŷ, mpc. D̂E
373374 U = U0
374375 U .+ = mpc. Uop
375376 uend = @views U[(end - model. nu+ 1 ): end ]
@@ -501,6 +502,24 @@ function preparestate!(mpc::PredictiveController, ym, d=mpc.estim.buffer.empty)
501502 return preparestate! (mpc. estim, ym, d)
502503end
503504
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+
504523"""
505524 updatestate!(mpc::PredictiveController, u, ym, d=[]) -> x̂next
506525
0 commit comments