@@ -30,8 +30,8 @@ struct NonLinMPC{S<:StateEstimator, JEFunc<:Function} <: PredictiveController
3030 q̃ :: Vector{Float64}
3131 Ks:: Matrix{Float64}
3232 Ps:: Matrix{Float64}
33- d0 :: Vector{Float64}
34- D̂0 :: Vector{Float64}
33+ d :: Vector{Float64}
34+ D̂ :: Vector{Float64}
3535 Yop:: Vector{Float64}
3636 Dop:: Vector{Float64}
3737 function NonLinMPC {S, JEFunc} (
@@ -53,7 +53,7 @@ struct NonLinMPC{S<:StateEstimator, JEFunc<:Function} <: PredictiveController
5353 con, S̃_Hp, Ñ_Hc, Ẽ = init_defaultcon (model, Hp, Hc, C, S_Hp, S_Hc, N_Hc, E)
5454 P̃, q̃ = init_quadprog (model, Ẽ, S̃_Hp, M_Hp, Ñ_Hc, L_Hp)
5555 Ks, Ps = init_stochpred (estim, Hp)
56- d0, D̂0 = zeros (nd), zeros (nd* Hp)
56+ d, D̂ = zeros (nd), zeros (nd* Hp)
5757 Yop, Dop = repeat (model. yop, Hp), repeat (model. dop, Hp)
5858 nvar = size (Ẽ, 2 )
5959 ΔŨ = zeros (nvar)
@@ -65,7 +65,7 @@ struct NonLinMPC{S<:StateEstimator, JEFunc<:Function} <: PredictiveController
6565 S̃_Hp, T_Hp, T_Hc,
6666 Ẽ, F, G, J, Kd, Q, P̃, q̃,
6767 Ks, Ps,
68- d0, D̂0 ,
68+ d, D̂ ,
6969 Yop, Dop,
7070 )
7171 init_optimization! (mpc)
@@ -117,7 +117,7 @@ default arguments.
117117- `Nwt=fill(0.1,model.nu)` : main diagonal of ``\m athbf{N}`` weight matrix (vector)
118118- `Lwt=fill(0.0,model.nu)` : main diagonal of ``\m athbf{L}`` weight matrix (vector)
119119- `Cwt=1e5` : slack variable weight ``C`` (scalar), use `Cwt=Inf` for hard constraints only
120- - `Ewt=1 .0` : economic costs weight ``E`` (scalar).
120+ - `Ewt=0 .0` : economic costs weight ``E`` (scalar).
121121- `JE=(_,_,_)->0.0` : economic function ``J_E(\m athbf{U}_E, \m athbf{D̂}_E, \m athbf{Ŷ}_E)``.
122122- `ru=model.uop` : manipulated input setpoints ``\m athbf{r_u}`` (vector)
123123- `optim=JuMP.Model(Ipopt.Optimizer)` : nonlinear optimizer used in the predictive
@@ -179,7 +179,7 @@ function NonLinMPC(
179179 Nwt = fill (0.1 , estim. model. nu),
180180 Lwt = fill (0.0 , estim. model. nu),
181181 Cwt = 1e5 ,
182- Ewt = 1 .0 ,
182+ Ewt = 0 .0 ,
183183 JE:: JEFunc = (_,_,_) -> 0.0 ,
184184 ru = estim. model. uop,
185185 optim:: JuMP.Model = JuMP. Model (optimizer_with_attributes (Ipopt. Optimizer," sb" => " yes" ))
@@ -206,18 +206,21 @@ function init_optimization!(mpc::NonLinMPC)
206206 # --- nonlinear optimization init ---
207207 model = mpc. estim. model
208208 ncon = length (mpc. con. Ŷmin) + length (mpc. con. Ŷmax)
209- npred = mpc. Hp* mpc. estim. model. ny
210- Jfunc, Cfunc = let mpc= mpc, model= model, nvar= nvar, ncon= ncon, npred= npred
211- last_ΔŨ:: Vector{Float64} = zeros (nvar)
212- Ŷ:: Vector{Float64} = zeros (npred)
209+ nŶ = mpc. Hp* mpc. estim. model. ny
210+ Jfunc, Cfunc = let mpc= mpc, model= model, nvar= nvar, ncon= ncon, nŶ= nŶ
211+ # inspired from https://jump.dev/JuMP.jl/stable/tutorials/nonlinear/tips_and_tricks/#User-defined-functions-with-vector-outputs
212+ last_ΔŨtup = nothing
213+ Ŷ:: Vector{Float64} = zeros (nŶ)
213214 C:: Vector{Float64} = zeros (ncon)
214- last_dΔŨtup, dC, dŶ = nothing , nothing , nothing
215+ last_dΔŨtup = nothing
216+ dŶ = nothing
217+ dC = nothing
215218 function Jfunc (ΔŨtup:: Float64... )
216219 ΔŨ = collect (ΔŨtup)
217- if ΔŨ ≠ last_ΔŨ
220+ if ΔŨtup != = last_ΔŨtup
218221 Ŷ = predict (mpc, model, ΔŨ)
219222 C = con_nonlinprog (mpc, model, Ŷ, ΔŨ)
220- last_ΔŨ = ΔŨ
223+ last_ΔŨtup = ΔŨtup
221224 end
222225 return obj_nonlinprog (mpc, model, Ŷ, ΔŨ)
223226 end
@@ -231,11 +234,11 @@ function init_optimization!(mpc::NonLinMPC)
231234 return obj_nonlinprog (mpc, model, dŶ, dΔŨ)
232235 end
233236 function con_nonlinprog_i (i, ΔŨtup:: NTuple{N, Float64} ) where {N}
234- ΔŨ = collect ( ΔŨtup)
235- if ΔŨ ≠ last_ΔŨ
237+ if ΔŨtup ≠ last_ΔŨtup
238+ ΔŨ = collect (ΔŨtup)
236239 Ŷ = predict (mpc, model, ΔŨ)
237240 C = con_nonlinprog (mpc, model, Ŷ, ΔŨ)
238- last_ΔŨ = ΔŨ
241+ last_ΔŨtup = ΔŨtup
239242 end
240243 return C[i]
241244 end
@@ -293,12 +296,15 @@ end
293296Objective function for [`NonLinMPC`] when `model` is a [`LinModel`](@ref).
294297"""
295298function obj_nonlinprog (mpc:: NonLinMPC , model:: LinModel , Ŷ, ΔŨ:: Vector{T} ) where {T<: Real }
296- Jqp = obj_quadprog (ΔŨ, mpc. P̃, mpc. q̃)
297- U = mpc. S̃_Hp* ΔŨ + mpc. T_Hp* (mpc. estim. lastu0 + model. uop)
298- UE = [U; U[(end - model. nu + 1 ): end ]]
299- ŶE = [mpc. ŷ; Ŷ]
300- D̂E = [mpc. d0 + model. dop; mpc. D̂0 + mpc. Dop]
301- return Jqp + mpc. E* mpc. JE (UE, ŶE, D̂E)
299+ J = obj_quadprog (ΔŨ, mpc. P̃, mpc. q̃)
300+ if ! iszero (mpc. E)
301+ U = mpc. S̃_Hp* ΔŨ + mpc. T_Hp* (mpc. estim. lastu0 + model. uop)
302+ UE = [U; U[(end - model. nu + 1 ): end ]]
303+ ŶE = [mpc. ŷ; Ŷ]
304+ D̂E = [mpc. d; mpc. D̂]
305+ J += mpc. E* mpc. JE (UE, ŶE, D̂E)
306+ end
307+ return J
302308end
303309
304310"""
@@ -312,21 +318,29 @@ function obj_nonlinprog(mpc::NonLinMPC, model::SimModel, Ŷ, ΔŨ::Vector{T})
312318 JR̂y = êy' * mpc. M_Hp* êy
313319 # --- move suppression term ---
314320 JΔŨ = ΔŨ' * mpc. Ñ_Hc* ΔŨ
321+ # --- input over prediction horizon ---
322+ if ! isempty (mpc. R̂u) || ! iszero (mpc. E)
323+ U = mpc. S̃_Hp* ΔŨ + mpc. T_Hp* (mpc. estim. lastu0 + model. uop)
324+ end
315325 # --- input setpoint tracking term ---
316- U = mpc. S̃_Hp* ΔŨ + mpc. T_Hp* (mpc. estim. lastu0 + model. uop)
317326 if ! isempty (mpc. R̂u)
318- êu = mpc. R̂u - U
327+ êu = mpc. R̂u - U
319328 JR̂u = êu' * mpc. L_Hp* ê
320329 else
321330 JR̂u = 0.0
322331 end
323332 # --- slack variable term ---
324333 Jϵ = ! isinf (mpc. C) ? mpc. C* ΔŨ[end ] : 0.0
325334 # --- economic term ---
326- UE = [U; U[(end - model. nu + 1 ): end ]]
327- ŶE = [mpc. ŷ; Ŷ]
328- D̂E = [mpc. d0 + model. dop; mpc. D̂0 + mpc. Dop]
329- return JR̂y + JΔŨ + JR̂u + Jϵ + mpc. E* mpc. JE (UE, ŶE, D̂E)
335+ if ! iszero (mpc. E)
336+ UE = [U; U[(end - model. nu + 1 ): end ]]
337+ ŶE = [mpc. ŷ; Ŷ]
338+ D̂E = [mpc. d; mpc. D̂]
339+ E_JE = mpc. E* mpc. JE (UE, ŶE, D̂E)
340+ else
341+ E_JE = 0.0
342+ end
343+ return JR̂y + JΔŨ + JR̂u + Jϵ + E_JE
330344end
331345
332346
336350Nonlinear constraints for [`NonLinMPC`](@ref) when `model` is a [`LinModel`](@ref).
337351"""
338352function con_nonlinprog (mpc:: NonLinMPC , model:: LinModel , _, ΔŨ:: Vector{T} ) where {T<: Real }
339- return zeros (T, 2 * model . ny * mpc . Hp )
353+ return zeros (T, 0 )
340354end
341355"""
342356 con_nonlinprog(mpc::NonLinMPC, model::NonLinModel, ΔŨ::Vector{Real})
0 commit comments