@@ -77,6 +77,13 @@ struct NonLinMPC{S<:StateEstimator, JEFunc<:Function} <: PredictiveController
7777 end
7878 register (mpc. optim, :J , nvar, J, autodiff= true )
7979 @NLobjective (mpc. optim, Min, J (ΔŨ... ))
80+ nonlinconstraint = let mpc= mpc, model= model # capture mpc and model variables
81+ (ΔŨ... ) -> con_nonlinprog (mpc, model, ΔŨ)
82+ end
83+ register (mpc. optim, :nonlinconstraint , nvar, nonlinconstraint, autodiff= true )
84+ ncon = sum (con. i_Ŷmin) + sum (con. i_Ŷmax)
85+ @NLconstraint (mpc. optim, [i= 1 : ncon], nonlinconstraint (ΔŨ... ) ≤ zeros (ncon))
86+
8087 set_silent (optim)
8188 return mpc
8289 end
@@ -189,49 +196,65 @@ end
189196
190197init_objective! (mpc:: NonLinMPC , _ ) = nothing
191198
192- function obj_nonlinprog (mpc:: NonLinMPC , model:: LinModel , ΔŨ:: NTuple{N, T} ) where {T, N }
199+ function obj_nonlinprog (mpc:: NonLinMPC , model:: LinModel , ΔŨ:: NTuple{N, T} ) where {N, T }
193200 ΔŨ = collect (ΔŨ) # convert NTuple to Vector
194201 Jqp = obj_quadprog (ΔŨ, mpc. P̃, mpc. q̃)
195202 U = mpc. S̃_Hp* ΔŨ + mpc. T_Hp* (mpc. estim. lastu0 + model. uop)
196- UE = [U; U[end - model. nu+ 1 : end ]]
203+ UE = [U; U[( end - model. nu + 1 ) : end ]]
197204 ŶE = [mpc. ŷ; mpc. Ẽ* ΔŨ + mpc. F]
198205 D̂E = [mpc. d0 + model. dop; mpc. D̂0 + mpc. Dop]
199- return Jqp + mpc. JE (UE, ŶE, D̂E)
206+ return Jqp + mpc. E * mpc . JE (UE, ŶE, D̂E)
200207end
201208
202-
203- function obj_nonlinprog (mpc:: NonLinMPC , model:: SimModel , ΔŨ:: NTuple{N, T} ) where {T,N}
209+ function obj_nonlinprog (mpc:: NonLinMPC , model:: SimModel , ΔŨ:: NTuple{N, T} ) where {N, T}
204210 ΔŨ = collect (ΔŨ) # convert NTuple to Vector
205211 U0 = mpc. S̃_Hp* ΔŨ + mpc. T_Hp* (mpc. estim. lastu0)
206212 # --- output setpoint tracking term ---
207- Ŷd0 = Vector {T} (undef, model. ny* mpc. Hp)
208- x̂d = mpc. x̂d
209- d0 = mpc. d0
210- for i= 1 : mpc. Hp
211- u0 = U0[(1 + model. nu* (i- 1 )): (model. nu* i)]
212- x̂d = model. f (x̂d, u0, d0)
213- d0 = mpc. D̂0[(1 + model. nd* (i- 1 )): (model. nd* i)]
214- ŷd0 = model. h (x̂d, d0)
215- Ŷd0[(1 + model. ny* (i- 1 )): (model. ny* i)] = ŷd0
216- end
217- Ŷ = Ŷd0 + mpc. F
213+ Ŷ = evalŶ (mpc, model, mpc. x̂d, mpc. d0, mpc. D̂0, U0)
218214 êy = mpc. R̂y - Ŷ
219215 JR̂y = êy' * mpc. M_Hp* êy
220216 # --- move suppression term ---
221217 JΔŨ = ΔŨ' * mpc. Ñ_Hc* ΔŨ
222218 # --- input setpoint tracking term ---
223219 U = U0 + mpc. Uop
224220 if ! isempty (mpc. R̂u)
225- êu = mpc. R̂u - U
221+ êu = mpc. R̂u - U
226222 JR̂u = êu' * mpc. L_Hp* ê
227223 else
228224 JR̂u = 0.0
229225 end
230226 # --- slack variable term ---
231227 Jϵ = ! isinf (mpc. C) ? mpc. C* ΔŨ[end ] : 0.0
232228 # --- economic term ---
233- UE = [U; U[end - model. nu+ 1 : end ]]
229+ UE = [U; U[( end - model. nu + 1 ) : end ]]
234230 ŶE = [mpc. ŷ; Ŷ]
235231 D̂E = [mpc. d0 + model. dop; mpc. D̂0 + mpc. Dop]
236- return JR̂y + JΔŨ + JR̂u + Jϵ + mpc. JE (UE, ŶE, D̂E)
232+ return JR̂y + JΔŨ + JR̂u + Jϵ + mpc. E * mpc . JE (UE, ŶE, D̂E)
237233end
234+
235+ function con_nonlinprog (mpc:: NonLinMPC , model:: SimModel , ΔŨ:: NTuple{N, T} ) where {N, T}
236+ ΔŨ = collect (ΔŨ) # convert NTuple to Vector
237+ U0 = mpc. S̃_Hp* ΔŨ + mpc. T_Hp* (mpc. estim. lastu0)
238+ Ŷ = evalŶ (mpc, model, mpc. x̂d, mpc. d0, mpc. D̂0, U0)
239+ C_Ŷmin = (mpc. con. Ŷmin - Ŷ)[mpc. con. i_Ŷmin]
240+ C_Ŷmax = (Ŷ - mpc. con. Ŷmax)[mpc. con. i_Ŷmin]
241+ if ! isinf (mpc. C) # constraint softening activated :
242+ C_Ŷmin = C_Ŷmin - ΔŨ[end ]* mpc. con. c_Ŷmin[mpc. con. i_Ŷmin]
243+ C_Ŷmax = C_Ŷmax - ΔŨ[end ]* mpc. con. c_Ŷmin[mpc. con. i_Ŷmin]
244+ end
245+ C = [C_Ŷmin; C_Ŷmax]
246+ return C
247+ end
248+
249+ function evalŶ (mpc, model, x̂d, d0, D̂0, U0:: Vector{T} ) where {T}
250+ Ŷd0 = Vector {T} (undef, model. ny* mpc. Hp)
251+ x̂d:: Vector{T} = x̂d
252+ for j= 1 : mpc. Hp
253+ u0 = U0[(1 + model. nu* (j- 1 )): (model. nu* j)]
254+ x̂d[:] = model. f (x̂d, u0, d0)
255+ d0 = D̂0[(1 + model. nd* (j- 1 )): (model. nd* j)]
256+ Ŷd0[(1 + model. ny* (j- 1 )): (model. ny* j)] = model. h (x̂d, d0)
257+ end
258+ return Ŷd0 + mpc. F
259+ end
260+
0 commit comments