@@ -384,7 +384,7 @@ function get_mutating_gc(NT, gc)
384384end
385385
386386function test_custom_functions (JE, gc!, uop; Uop, dop, Dop, ΔŨ, p)
387- # TODO : contunue here (important to guide the users , sim! can be used on NonLinModel
387+ # TODO : contunue here (important to guide the user , sim! can be used on NonLinModel,
388388 # but there is no similar function for the custom functions of NonLinMPC)
389389 Ue = [Uop; uop]
390390 D̂e = [dop; Dop]
@@ -458,6 +458,11 @@ function init_optimization!(mpc::NonLinMPC, model::SimModel, optim)
458458 name = Symbol (" g_x̂0max_$i " )
459459 optim[name] = JuMP. add_nonlinear_operator (optim, nΔŨ, gfunc[i_end_x̂min+ i]; name)
460460 end
461+ i_end_x̂max = 2 Hp* ny + 2 nx̂
462+ for i in 1 : con. nc
463+ name = Symbol (" g_c_$i " )
464+ optim[name] = JuMP. add_nonlinear_operator (optim, nΔŨ, gfunc[i_end_x̂max+ i]; name)
465+ end
461466 end
462467 return nothing
463468end
@@ -471,20 +476,21 @@ Inspired from: [User-defined operators with vector outputs](https://jump.dev/JuM
471476"""
472477function get_optim_functions (mpc:: NonLinMPC , :: JuMP.GenericModel{JNT} ) where JNT<: Real
473478 model = mpc. estim. model
474- nu, ny, nx̂, Hp = model. nu, model. ny, mpc. estim. nx̂, mpc. Hp
475- ng, nΔŨ, nU, nŶ = length (mpc. con. i_g), length (mpc. ΔŨ), Hp* nu, Hp* ny
479+ nu, ny, nx̂, nϵ, Hp = model. nu, model. ny, mpc. estim. nx̂, mpc . nϵ , mpc. Hp
480+ ng, nc, nΔŨ, nU, nŶ = length (mpc. con. i_g), mpc . con . nc , length (mpc. ΔŨ), Hp* nu, Hp* ny
476481 nUe, nŶe = nU + nu, nŶ + ny
477- Nc = nΔŨ + 3
478- ΔŨ_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nΔŨ), Nc)
479- Ŷe_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nŶe), Nc)
480- Ue_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nUe), Nc)
481- Ȳ_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nŶ), Nc)
482- Ū_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nU), Nc)
483- x̂0_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nx̂), Nc)
484- x̂0next_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nx̂), Nc)
485- u0_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nu), Nc)
486- û0_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nu), Nc)
487- g_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, ng), Nc)
482+ Ncache = nΔŨ + 3
483+ ΔŨ_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nΔŨ), Ncache)
484+ Ŷe_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nŶe), Ncache)
485+ Ue_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nUe), Ncache)
486+ Ȳ_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nŶ), Ncache)
487+ Ū_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nU), Ncache)
488+ x̂0_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nx̂), Ncache)
489+ x̂0next_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nx̂), Ncache)
490+ u0_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nu), Ncache)
491+ û0_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nu), Ncache)
492+ g_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, ng), Ncache)
493+ gc_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nc), Ncache)
488494 function Jfunc (ΔŨtup:: T... ) where T<: Real
489495 ΔŨ1 = ΔŨtup[begin ]
490496 ΔŨ, g = get_tmp (ΔŨ_cache, ΔŨ1), get_tmp (g_cache, ΔŨ1)
@@ -495,10 +501,12 @@ function get_optim_functions(mpc::NonLinMPC, ::JuMP.GenericModel{JNT}) where JNT
495501 Ȳ, Ū = get_tmp (Ȳ_cache, ΔŨ1), get_tmp (Ū_cache, ΔŨ1)
496502 x̂0, x̂0next = get_tmp (x̂0_cache, ΔŨ1), get_tmp (x̂0next_cache, ΔŨ1)
497503 u0, û0 = get_tmp (u0_cache, ΔŨ1), get_tmp (û0_cache, ΔŨ1)
498- g = get_tmp (g_cache , ΔŨ1)
504+ g, gc = get_tmp (g_cache, ΔŨ1), get_tmp (gc_cache , ΔŨ1)
499505 Ŷ0, x̂0end = predict! (Ȳ, x̂0, x̂0next, u0, û0, mpc, model, ΔŨ)
500506 Ŷe, Ue = extended_predictions! (Ŷe, Ue, Ū, mpc, model, Ŷ0, ΔŨ)
501- g = con_nonlinprog! (g, mpc, model, x̂0end, Ŷ0, ΔŨ)
507+ ϵ = (nϵ == 1 ) ? ΔŨ[end ] : zero (JNT) # ϵ = 0 if nϵ == 0 (meaning no relaxation)
508+ mpc. con. gc! (gc, Ue, Ŷe, mpc. D̂e, mpc. p, ϵ)
509+ g = con_nonlinprog! (g, mpc, model, x̂0end, gc, Ŷ0, ΔŨ, ϵ)
502510 return obj_nonlinprog! (Ȳ, Ū, mpc, model, Ŷe, Ue, ΔŨ):: T
503511 end
504512 function gfunc_i (i, ΔŨtup:: NTuple{N, T} ) where {N, T<: Real }
@@ -512,10 +520,12 @@ function get_optim_functions(mpc::NonLinMPC, ::JuMP.GenericModel{JNT}) where JNT
512520 Ȳ, Ū = get_tmp (Ȳ_cache, ΔŨ1), get_tmp (Ū_cache, ΔŨ1)
513521 x̂0, x̂0next = get_tmp (x̂0_cache, ΔŨ1), get_tmp (x̂0next_cache, ΔŨ1)
514522 u0, û0 = get_tmp (u0_cache, ΔŨ1), get_tmp (û0_cache, ΔŨ1)
515- g = get_tmp (g_cache , ΔŨ1)
523+ g, gc = get_tmp (g_cache, ΔŨ1), get_tmp (gc_cache , ΔŨ1)
516524 Ŷ0, x̂0end = predict! (Ȳ, x̂0, x̂0next, u0, û0, mpc, model, ΔŨ)
517525 Ŷe, Ue = extended_predictions! (Ŷe, Ue, Ū, mpc, model, Ŷ0, ΔŨ)
518- g = con_nonlinprog! (g, mpc, model, x̂0end, Ŷ0, ΔŨ)
526+ ϵ = (nϵ == 1 ) ? ΔŨ[end ] : zero (JNT) # ϵ = 0 if nϵ == 0 (meaning no relaxation)
527+ mpc. con. gc! (gc, Ue, Ŷe, mpc. D̂e, mpc. p, ϵ)
528+ g = con_nonlinprog! (g, mpc, model, x̂0end, gc, Ŷ0, ΔŨ, ϵ)
519529 end
520530 return g[i]:: T
521531 end
@@ -568,19 +578,29 @@ function setnonlincon!(
568578 gfunc_i = optim[Symbol (" g_x̂0max_$(i) " )]
569579 @constraint (optim, gfunc_i (ΔŨvar... ) <= 0 )
570580 end
581+ for i in 1 : con. nc
582+ gfunc_i = optim[Symbol (" g_c_$i " )]
583+ @constraint (optim, gfunc_i (ΔŨvar... ) <= 0 )
584+ end
585+ return nothing
586+ end
587+
588+ # TODO : MODIF THE FOLLOWING METHOD!
589+ function setnonlincon! (
590+ mpc:: NonLinMPC , :: LinModel , optim:: JuMP.GenericModel{JNT}
591+ ) where JNT<: Real
571592 return nothing
572593end
573594
574595"""
575- con_nonlinprog!(g, mpc::NonLinMPC, model::SimModel, x̂end, Ŷ, ΔŨ) -> g
596+ con_nonlinprog!(g, mpc::NonLinMPC, model::SimModel, x̂end, gc, Ŷ0, ΔŨ, ϵ ) -> g
576597
577598Nonlinear constrains for [`NonLinMPC`](@ref) when `model` is not a [`LinModel`](@ref).
578599
579- The method mutates the `g` vector in argument and returns it .
600+ The method mutates the `g` and `gc` vectors in argument .
580601"""
581- function con_nonlinprog! (g, mpc:: NonLinMPC , :: SimModel , x̂0end, Ŷ0, ΔŨ)
582- nx̂, nŶ = mpc. estim. nx̂, length (Ŷ0)
583- ϵ = mpc. nϵ == 1 ? ΔŨ[end ] : 0 # ϵ = 0 if Cwt=Inf (meaning: no relaxation)
602+ function con_nonlinprog! (g, mpc:: NonLinMPC , :: SimModel , x̂0end, gc, Ŷ0, ΔŨ, ϵ)
603+ nx̂, nŶ = length (x̂0end), length (Ŷ0)
584604 for i in eachindex (g)
585605 mpc. con. i_g[i] || continue
586606 if i ≤ nŶ
@@ -592,16 +612,20 @@ function con_nonlinprog!(g, mpc::NonLinMPC, ::SimModel, x̂0end, Ŷ0, ΔŨ)
592612 elseif i ≤ 2 nŶ + nx̂
593613 j = i - 2 nŶ
594614 g[i] = (mpc. con. x̂0min[j] - x̂0end[j]) - ϵ* mpc. con. c_x̂min[j]
595- else
615+ elseif i ≤ 2 nŶ + 2 nx̂
596616 j = i - 2 nŶ - nx̂
597617 g[i] = (x̂0end[j] - mpc. con. x̂0max[j]) - ϵ* mpc. con. c_x̂max[j]
618+ else
619+ j = i - 2 nŶ - 2 nx̂
620+ g[i] = gc[j]
598621 end
599622 end
600623 return g
601624end
602625
626+ # TODO : MODIF THE FOLLOWING METHOD!
603627" No nonlinear constraints if `model` is a [`LinModel`](@ref), return `g` unchanged."
604- con_nonlinprog! (g, :: NonLinMPC , :: LinModel , _ , _ , _ ) = g
628+ con_nonlinprog! (g, :: NonLinMPC , :: LinModel , _ , _ , _ , _ , _ ) = g
605629
606630" Evaluate the economic term `E*JE` of the objective function for [`NonLinMPC`](@ref)."
607631function obj_econ! (Ue, Ŷe, mpc:: NonLinMPC , model:: SimModel )
0 commit comments