@@ -2,16 +2,17 @@ const DEFAULT_NONLINMPC_OPTIMIZER = optimizer_with_attributes(Ipopt.Optimizer,"s
22
33struct NonLinMPC{
44 NT<: Real ,
5- SE<: StateEstimator ,
5+ SE<: StateEstimator ,
66 JM<: JuMP.GenericModel ,
77 JEfunc<: Function ,
8+ GCfunc<: Function ,
89 P<: Any
910} <: PredictiveController{NT}
1011 estim:: SE
1112 # note: `NT` and the number type `JNT` in `JuMP.GenericModel{JNT}` can be
1213 # different since solvers that support non-Float64 are scarce.
1314 optim:: JM
14- con:: ControllerConstraint{NT}
15+ con:: ControllerConstraint{NT, GCfunc }
1516 ΔŨ:: Vector{NT}
1617 ŷ :: Vector{NT}
1718 Hp:: Int
@@ -22,7 +23,6 @@ struct NonLinMPC{
2223 p:: P
2324 R̂u:: Vector{NT}
2425 R̂y:: Vector{NT}
25- noR̂u:: Bool
2626 S̃:: Matrix{NT}
2727 T:: Matrix{NT}
2828 T_lastu0:: Vector{NT}
@@ -45,18 +45,23 @@ struct NonLinMPC{
4545 Yop:: Vector{NT}
4646 Dop:: Vector{NT}
4747 buffer:: PredictiveControllerBuffer{NT}
48- function NonLinMPC {NT, SE, JM, JEfunc, P} (
49- estim:: SE , Hp, Hc, M_Hp, N_Hc, L_Hp, Cwt, Ewt, JE:: JEfunc , gc, nc, p:: P , optim:: JM
50- ) where {NT<: Real , SE<: StateEstimator , JM<: JuMP.GenericModel , JEfunc<: Function , P<: Any }
48+ function NonLinMPC {NT, SE, JM, JEfunc, GCfunc, P} (
49+ estim:: SE ,
50+ Hp, Hc, M_Hp, N_Hc, L_Hp, Cwt, Ewt, JE:: JEfunc , gc!:: GCfunc , nc, p:: P , optim:: JM
51+ ) where {
52+ NT<: Real ,
53+ SE<: StateEstimator ,
54+ JM<: JuMP.GenericModel ,
55+ JEfunc<: Function ,
56+ GCfunc<: Function ,
57+ P<: Any
58+ }
5159 model = estim. model
5260 nu, ny, nd, nx̂ = model. nu, model. ny, model. nd, estim. nx̂
5361 ŷ = copy (model. yop) # dummy vals (updated just before optimization)
54- validate_JE (NT, JE)
55- gc! = get_mutating_gc (NT, gc)
5662 weights = ControllerWeights {NT} (model, Hp, Hc, M_Hp, N_Hc, L_Hp, Cwt, Ewt)
5763 # dummy vals (updated just before optimization):
5864 R̂y, R̂u, T_lastu0 = zeros (NT, ny* Hp), zeros (NT, nu* Hp), zeros (NT, nu* Hp)
59- noR̂u = iszero (L_Hp)
6065 S, T = init_ΔUtoU (model, Hp, Hc)
6166 E, G, J, K, V, B, ex̂, gx̂, jx̂, kx̂, vx̂, bx̂ = init_predmat (estim, model, Hp, Hc)
6267 # dummy vals (updated just before optimization):
@@ -74,14 +79,14 @@ struct NonLinMPC{
7479 test_custom_functions (NT, model, JE, gc!, nc, Uop, Yop, Dop, p)
7580 nΔŨ = size (Ẽ, 2 )
7681 ΔŨ = zeros (NT, nΔŨ)
77- buffer = PredictiveControllerBuffer {NT} (nu, ny, nd, Hp)
78- mpc = new {NT, SE, JM, JEfunc, P} (
82+ buffer = PredictiveControllerBuffer {NT} (nu, ny, nd, Hp, Hc, nϵ )
83+ mpc = new {NT, SE, JM, JEfunc, GCfunc, P} (
7984 estim, optim, con,
8085 ΔŨ, ŷ,
8186 Hp, Hc, nϵ,
8287 weights,
8388 JE, p,
84- R̂u, R̂y, noR̂u,
89+ R̂u, R̂y,
8590 S̃, T, T_lastu0,
8691 Ẽ, F, G, J, K, V, B,
8792 H̃, q̃, r,
@@ -234,7 +239,7 @@ function NonLinMPC(
234239 L_Hp = diagm (repeat (Lwt, Hp)),
235240 Cwt = DEFAULT_CWT,
236241 Ewt = DEFAULT_EWT,
237- JE:: Function = (_,_,_,_) -> 0.0 ,
242+ JE :: Function = (_,_,_,_) -> 0.0 ,
238243 gc!:: Function = (_,_,_,_,_,_) -> nothing ,
239244 gc :: Function = gc!,
240245 nc:: Int = 0 ,
@@ -312,7 +317,7 @@ function NonLinMPC(
312317 L_Hp = diagm (repeat (Lwt, Hp)),
313318 Cwt = DEFAULT_CWT,
314319 Ewt = DEFAULT_EWT,
315- JE :: JEfunc = (_,_,_,_) -> 0.0 ,
320+ JE :: JEfunc = (_,_,_,_) -> 0.0 ,
316321 gc!:: Function = (_,_,_,_,_,_) -> nothing ,
317322 gc :: Function = gc!,
318323 nc = 0 ,
@@ -330,8 +335,11 @@ function NonLinMPC(
330335 @warn (" prediction horizon Hp ($Hp ) ≤ estimated number of delays in model " *
331336 " ($nk ), the closed-loop system may be unstable or zero-gain (unresponsive)" )
332337 end
333- return NonLinMPC {NT, SE, JM, JEfunc, P} (
334- estim, Hp, Hc, M_Hp, N_Hc, L_Hp, Cwt, Ewt, JE, gc, nc, p, optim
338+ validate_JE (NT, JE)
339+ gc! = get_mutating_gc (NT, gc)
340+ GCfunc = get_type_mutating_gc (gc!)
341+ return NonLinMPC {NT, SE, JM, JEfunc, GCfunc, P} (
342+ estim, Hp, Hc, M_Hp, N_Hc, L_Hp, Cwt, Ewt, JE, gc!, nc, p, optim
335343 )
336344end
337345
@@ -388,6 +396,9 @@ function get_mutating_gc(NT, gc)
388396 return gc!
389397end
390398
399+ " Get the type of the mutating version of the custom constrain function `gc!`."
400+ get_type_mutating_gc (:: GCfunc ) where {GCfunc<: Function } = GCfunc
401+
391402"""
392403 test_custom_functions(NT, model::SimModel, JE, gc!, nc, Uop, Yop, Dop, p)
393404
@@ -514,7 +525,7 @@ function get_optim_functions(mpc::NonLinMPC, ::JuMP.GenericModel{JNT}) where JNT
514525 gc = get_tmp (gc_cache, ΔŨ1)
515526 Ŷ0, x̂0end = predict! (Ȳ, x̂0, x̂0next, u0, û0, mpc, model, ΔŨ)
516527 Ue, Ŷe = extended_predictions! (Ue, Ŷe, Ū, mpc, model, Ŷ0, ΔŨ)
517- ϵ = (nϵ ≠ 0 ) ? ΔŨ[end ] : zero (T) # ϵ = 0 if nϵ == 0 (meaning no relaxation)
528+ ϵ = (nϵ ≠ 0 ) ? ΔŨ[end ] : 0 # ϵ = 0 if nϵ == 0 (meaning no relaxation)
518529 mpc. con. gc! (gc, Ue, Ŷe, mpc. D̂e, mpc. p, ϵ)
519530 g = con_nonlinprog! (g, mpc, model, x̂0end, Ŷ0, gc, ϵ)
520531 return obj_nonlinprog! (Ȳ, Ū, mpc, model, Ue, Ŷe, ΔŨ):: T
@@ -533,7 +544,7 @@ function get_optim_functions(mpc::NonLinMPC, ::JuMP.GenericModel{JNT}) where JNT
533544 gc = get_tmp (gc_cache, ΔŨ1)
534545 Ŷ0, x̂0end = predict! (Ȳ, x̂0, x̂0next, u0, û0, mpc, model, ΔŨ)
535546 Ue, Ŷe = extended_predictions! (Ue, Ŷe, Ū, mpc, model, Ŷ0, ΔŨ)
536- ϵ = (nϵ ≠ 0 ) ? ΔŨ[end ] : zero (T) # ϵ = 0 if nϵ == 0 (meaning no relaxation)
547+ ϵ = (nϵ ≠ 0 ) ? ΔŨ[end ] : 0 # ϵ = 0 if nϵ == 0 (meaning no relaxation)
537548 mpc. con. gc! (gc, Ue, Ŷe, mpc. D̂e, mpc. p, ϵ)
538549 g = con_nonlinprog! (g, mpc, model, x̂0end, Ŷ0, gc, ϵ)
539550 end
0 commit comments