@@ -72,38 +72,54 @@ struct NonLinMPC{S<:StateEstimator, JEFunc<:Function} <: PredictiveController
7272 A = con. A[con. i_b, :]
7373 b = con. b[con. i_b]
7474 @constraint (optim, linconstraint, A* ΔŨ .≤ b)
75- J = let mpc= mpc, model= model # capture mpc and model variables
76- (ΔŨ... ) -> obj_nonlinprog (mpc, model, ΔŨ)
75+
76+ last_ΔŨ, last_C, last_Ŷ = nothing , nothing , nothing
77+ function Jfunc (ΔŨ:: Float64... )
78+ if ΔŨ != = last_ΔŨ
79+ last_Ŷ = evalŶ (mpc, model, ΔŨ)
80+ last_C = con_nonlinprog (mpc, model, last_Ŷ, ΔŨ)
81+ last_ΔŨ = ΔŨ
82+ end
83+ return obj_nonlinprog (mpc, model, last_Ŷ, ΔŨ)
84+ end
85+ last_dΔŨ, last_dC, last_dŶ = nothing , nothing , nothing
86+ function Jfunc (dΔŨ:: T... ) where {T<: Real }
87+ if dΔŨ != = last_dΔŨ
88+ last_dŶ = evalŶ (mpc, model, dΔŨ)
89+ last_dC = con_nonlinprog (mpc, model, last_dŶ, dΔŨ)
90+ last_dΔŨ = dΔŨ
91+ end
92+ return obj_nonlinprog (mpc, model, last_dŶ, dΔŨ)
7793 end
78- register (optim, :J , nvar, J , autodiff= true )
79- @NLobjective (optim, Min, J (ΔŨ... ))
94+ register (optim, :Jfunc , nvar, Jfunc , autodiff= true )
95+ @NLobjective (optim, Min, Jfunc (ΔŨ... ))
8096 ncon = length (mpc. con. Ŷmin) + length (mpc. con. Ŷmax)
81- C = let mpc= mpc, model= model, ncon= ncon # capture the 3 variables
82- last_ΔŨ, last_C = nothing , nothing
83- function con_nonlinprog_i (i, ΔŨ:: NTuple{N, Float64} ) where {N}
84- if ΔŨ != = last_ΔŨ
85- last_C, last_ΔŨ = con_nonlinprog (mpc, model, ΔŨ), ΔŨ
86- end
87- return last_C[i]
97+ function con_nonlinprog_i (i, ΔŨ:: NTuple{N, Float64} ) where {N}
98+ if ΔŨ != = last_ΔŨ
99+ last_Ŷ = evalŶ (mpc, model, ΔŨ)
100+ last_C = con_nonlinprog (mpc, model, last_Ŷ, ΔŨ)
101+ last_ΔŨ = ΔŨ
88102 end
89- last_dΔŨ, last_dCdΔŨ = nothing , nothing
90- function con_nonlinprog_i (i, dΔŨ:: NTuple{N, T} ) where {N, T<: Real }
91- if dΔŨ != = last_dΔŨ
92- last_dCdΔŨ, last_dΔŨ = con_nonlinprog (mpc, model, dΔŨ), dΔŨ
93- end
94- return last_dCdΔŨ[i]
103+ return last_C[i]
104+ end
105+ function con_nonlinprog_i (i, dΔŨ:: NTuple{N, T} ) where {N, T<: Real }
106+ if dΔŨ != = last_dΔŨ
107+ last_dŶ = evalŶ (mpc, model, dΔŨ)
108+ last_dC = con_nonlinprog (mpc, model, last_dŶ, dΔŨ)
109+ last_dΔŨ = dΔŨ
95110 end
96- [(ΔŨ ... ) -> con_nonlinprog_i (i, ΔŨ) for i in 1 : ncon ]
111+ return last_dC[i ]
97112 end
113+ Cfunc = [(ΔŨ... ) -> con_nonlinprog_i (i, ΔŨ) for i in 1 : ncon]
98114 n = 0
99115 for i in eachindex (con. Ŷmin)
100116 sym = Symbol (" C_Ŷmin_$i " )
101- register (optim, sym, nvar, C [n + i], autodiff= true )
117+ register (optim, sym, nvar, Cfunc [n + i], autodiff= true )
102118 end
103119 n = lastindex (con. Ŷmin)
104120 for i in eachindex (con. Ŷmax)
105121 sym = Symbol (" C_Ŷmax_$i " )
106- register (optim, sym, nvar, C [n + i], autodiff= true )
122+ register (optim, sym, nvar, Cfunc [n + i], autodiff= true )
107123 end
108124 set_silent (optim)
109125 return mpc
@@ -253,12 +269,12 @@ init_objective!(mpc::NonLinMPC, _ ) = nothing
253269
254270Objective function for [`NonLinMPC`] when `model` is a [`LinModel`](@ref).
255271"""
256- function obj_nonlinprog (mpc:: NonLinMPC , model:: LinModel , ΔŨ:: NTuple{N, T} ) where {N, T}
272+ function obj_nonlinprog (mpc:: NonLinMPC , model:: LinModel , Ŷ, ΔŨ:: NTuple{N, T} ) where {N, T}
257273 ΔŨ = collect (ΔŨ) # convert NTuple to Vector
258274 Jqp = obj_quadprog (ΔŨ, mpc. P̃, mpc. q̃)
259275 U = mpc. S̃_Hp* ΔŨ + mpc. T_Hp* (mpc. estim. lastu0 + model. uop)
260276 UE = [U; U[(end - model. nu + 1 ): end ]]
261- ŶE = [mpc. ŷ; mpc . Ẽ * ΔŨ + mpc . F ]
277+ ŶE = [mpc. ŷ; Ŷ ]
262278 D̂E = [mpc. d0 + model. dop; mpc. D̂0 + mpc. Dop]
263279 return Jqp + mpc. E* mpc. JE (UE, ŶE, D̂E)
264280end
@@ -268,11 +284,10 @@ end
268284
269285Objective function for [`NonLinMPC`] when `model` is not a [`LinModel`](@ref).
270286"""
271- function obj_nonlinprog (mpc:: NonLinMPC , model:: SimModel , ΔŨ:: NTuple{N, T} ) where {N, T}
287+ function obj_nonlinprog (mpc:: NonLinMPC , model:: SimModel , Ŷ, ΔŨ:: NTuple{N, T} ) where {N, T}
272288 ΔŨ = collect (ΔŨ) # convert NTuple to Vector
273289 U0 = mpc. S̃_Hp* ΔŨ + mpc. T_Hp* (mpc. estim. lastu0)
274290 # --- output setpoint tracking term ---
275- Ŷ = evalŶ (mpc, model, mpc. x̂d, mpc. d0, mpc. D̂0, U0)
276291 êy = mpc. R̂y - Ŷ
277292 JR̂y = êy' * mpc. M_Hp* êy
278293 # --- move suppression term ---
@@ -300,18 +315,15 @@ end
300315
301316Nonlinear constraints for [`NonLinMPC`](@ref) when `model` is a [`LinModel`](@ref).
302317"""
303- function con_nonlinprog (mpc:: NonLinMPC , :: LinModel , ΔŨ:: NTuple{N, T} ) where {N, T}
304- return zeros (T, 2 * mpc . ny* mpc. Hp)
318+ function con_nonlinprog (mpc:: NonLinMPC , model :: LinModel , _ , ΔŨ:: NTuple{N, T} ) where {N, T}
319+ return zeros (T, 2 * model . ny* mpc. Hp)
305320end
306321"""
307322 con_nonlinprog(mpc::NonLinMPC, model::NonLinModel, ΔŨ::NTuple{N, T}) where {N, T}
308323
309324Nonlinear constrains for [`NonLinMPC`](@ref) when `model` is not a [`LinModel`](ref).
310325"""
311- function con_nonlinprog (mpc:: NonLinMPC , model:: SimModel , ΔŨ:: NTuple{N, T} ) where {N, T}
312- ΔŨ = collect (ΔŨ) # convert NTuple to Vector
313- U0 = mpc. S̃_Hp* ΔŨ + mpc. T_Hp* (mpc. estim. lastu0)
314- Ŷ = evalŶ (mpc, model, mpc. x̂d, mpc. d0, mpc. D̂0, U0)
326+ function con_nonlinprog (mpc:: NonLinMPC , :: SimModel , Ŷ, ΔŨ:: NTuple{N, T} ) where {N, T}
315327 if ! isinf (mpc. C) # constraint softening activated :
316328 ϵ = ΔŨ[end ]
317329 C_Ŷmin = (mpc. con. Ŷmin - Ŷ) - ϵ* mpc. con. c_Ŷmin
@@ -328,18 +340,31 @@ function con_nonlinprog(mpc::NonLinMPC, model::SimModel, ΔŨ::NTuple{N, T}) wh
328340end
329341
330342
343+ """
344+ evalŶ(mpc::NonLinMPC, model::LinModel, x̂d, d0, D̂0, U0::Vector{T}) where {T}
345+
346+ Evaluate the outputs predictions ``\\ mathbf{Ŷ}`` when `model` is a [`LinModel`](@ref).
347+ """
348+ function evalŶ (mpc:: NonLinMPC , :: LinModel , ΔŨ:: NTuple{N, T} ) where {N, T}
349+ ΔŨ = collect (ΔŨ) # convert NTuple to Vector
350+ return mpc. Ẽ* ΔŨ + mpc. F
351+ end
352+
331353"""
332354 evalŶ(mpc::NonLinMPC, model::SimModel, x̂d, d0, D̂0, U0::Vector{T}) where {T}
333355
334- Evaluate the outputs predictions ``\\ mathbf{Ŷ}`` when `model` is not a [`LinModel`](@ref).
356+ Evaluate ``\\ mathbf{Ŷ}`` when `model` is not a [`LinModel`](@ref).
335357"""
336- function evalŶ (mpc:: NonLinMPC , model:: SimModel , x̂d, d0, D̂0, U0:: Vector{T} ) where {T}
358+ function evalŶ (mpc:: NonLinMPC , model:: SimModel , ΔŨ:: NTuple{N, T} ) where {N, T}
359+ ΔŨ = collect (ΔŨ) # convert NTuple to Vector
360+ U0 = mpc. S̃_Hp* ΔŨ + mpc. T_Hp* (mpc. estim. lastu0)
337361 Ŷd0 = Vector {T} (undef, model. ny* mpc. Hp)
338- x̂d:: Vector{T} = copy (x̂d)
362+ x̂d:: Vector{T} = copy (mpc. x̂d)
363+ d0 = mpc. d0
339364 for j= 1 : mpc. Hp
340365 u0 = U0[(1 + model. nu* (j- 1 )): (model. nu* j)]
341366 x̂d[:] = f (model, x̂d, u0, d0)
342- d0 = D̂0[(1 + model. nd* (j- 1 )): (model. nd* j)]
367+ d0 = mpc . D̂0[(1 + model. nd* (j- 1 )): (model. nd* j)]
343368 Ŷd0[(1 + model. ny* (j- 1 )): (model. ny* j)] = h (model, x̂d, d0)
344369 end
345370 return Ŷd0 + mpc. F # F = Yop + Ŷs
0 commit comments