@@ -437,33 +437,7 @@ function init_optimization!(mpc::NonLinMPC, model::SimModel, optim)
437437 Jfunc, gfunc = get_optim_functions (mpc, mpc. optim)
438438 @operator (optim, J, nΔŨ, Jfunc)
439439 @objective (optim, Min, J (ΔŨvar... ))
440- ny, nx̂, Hp = model. ny, mpc. estim. nx̂, mpc. Hp
441- if length (con. i_g) ≠ 0
442- for i in eachindex (con. Y0min)
443- name = Symbol (" g_Y0min_$i " )
444- optim[name] = JuMP. add_nonlinear_operator (optim, nΔŨ, gfunc[i]; name)
445- end
446- i_end_Ymin = 1 Hp* ny
447- for i in eachindex (con. Y0max)
448- name = Symbol (" g_Y0max_$i " )
449- optim[name] = JuMP. add_nonlinear_operator (optim, nΔŨ, gfunc[i_end_Ymin+ i]; name)
450- end
451- i_end_Ymax = 2 Hp* ny
452- for i in eachindex (con. x̂0min)
453- name = Symbol (" g_x̂0min_$i " )
454- optim[name] = JuMP. add_nonlinear_operator (optim, nΔŨ, gfunc[i_end_Ymax+ i]; name)
455- end
456- i_end_x̂min = 2 Hp* ny + nx̂
457- for i in eachindex (con. x̂0max)
458- name = Symbol (" g_x̂0max_$i " )
459- optim[name] = JuMP. add_nonlinear_operator (optim, nΔŨ, gfunc[i_end_x̂min+ i]; name)
460- 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
466- end
440+ init_nonlincon! (mpc, model, gfunc)
467441 return nothing
468442end
469443
@@ -506,7 +480,7 @@ function get_optim_functions(mpc::NonLinMPC, ::JuMP.GenericModel{JNT}) where JNT
506480 Ŷe, Ue = extended_predictions! (Ŷe, Ue, Ū, mpc, model, Ŷ0, ΔŨ)
507481 ϵ = (nϵ == 1 ) ? ΔŨ[end ] : zero (JNT) # ϵ = 0 if nϵ == 0 (meaning no relaxation)
508482 mpc. con. gc! (gc, Ue, Ŷe, mpc. D̂e, mpc. p, ϵ)
509- g = con_nonlinprog! (g, mpc, model, x̂0end, gc, Ŷ0, ΔŨ , ϵ)
483+ g = con_nonlinprog! (g, mpc, model, x̂0end, Ŷ0, gc , ϵ)
510484 return obj_nonlinprog! (Ȳ, Ū, mpc, model, Ŷe, Ue, ΔŨ):: T
511485 end
512486 function gfunc_i (i, ΔŨtup:: NTuple{N, T} ) where {N, T<: Real }
@@ -525,38 +499,87 @@ function get_optim_functions(mpc::NonLinMPC, ::JuMP.GenericModel{JNT}) where JNT
525499 Ŷe, Ue = extended_predictions! (Ŷe, Ue, Ū, mpc, model, Ŷ0, ΔŨ)
526500 ϵ = (nϵ == 1 ) ? ΔŨ[end ] : zero (JNT) # ϵ = 0 if nϵ == 0 (meaning no relaxation)
527501 mpc. con. gc! (gc, Ue, Ŷe, mpc. D̂e, mpc. p, ϵ)
528- g = con_nonlinprog! (g, mpc, model, x̂0end, gc, Ŷ0, ΔŨ , ϵ)
502+ g = con_nonlinprog! (g, mpc, model, x̂0end, Ŷ0, gc , ϵ)
529503 end
530504 return g[i]:: T
531505 end
532506 gfunc = [(ΔŨ... ) -> gfunc_i (i, ΔŨ) for i in 1 : ng]
533507 return Jfunc, gfunc
534508end
535509
536- """
537- extended_predictions!(Ŷe, Ue, Ū, mpc, model, Ŷ0, ΔŨ) -> Ŷe, Ue
538510
539- Compute the extended predictions `Ŷe` and `Ue` for the nonlinear optimization.
511+ function init_nonlincon! (mpc:: NonLinMPC , :: NonLinModel , gfunc:: Vector{<:Function} )
512+ optim, con = mpc. optim, mpc. con
513+ ny, nx̂, Hp, nΔŨ = mpc. estim. model. ny, mpc. estim. nx̂, mpc. Hp, length (mpc. ΔŨ)
514+ if length (con. i_g) ≠ 0
515+ i_base = 0
516+ for i in eachindex (con. Y0min)
517+ name = Symbol (" g_Y0min_$i " )
518+ optim[name] = JuMP. add_nonlinear_operator (optim, nΔŨ, gfunc[i_base+ i]; name)
519+ end
520+ i_base = 1 Hp* ny
521+ for i in eachindex (con. Y0max)
522+ name = Symbol (" g_Y0max_$i " )
523+ optim[name] = JuMP. add_nonlinear_operator (optim, nΔŨ, gfunc[i_base+ i]; name)
524+ end
525+ i_base = 2 Hp* ny
526+ for i in eachindex (con. x̂0min)
527+ name = Symbol (" g_x̂0min_$i " )
528+ optim[name] = JuMP. add_nonlinear_operator (optim, nΔŨ, gfunc[i_base+ i]; name)
529+ end
530+ i_base = 2 Hp* ny + nx̂
531+ for i in eachindex (con. x̂0max)
532+ name = Symbol (" g_x̂0max_$i " )
533+ optim[name] = JuMP. add_nonlinear_operator (optim, nΔŨ, gfunc[i_base+ i]; name)
534+ end
535+ i_base = 2 Hp* ny + 2 nx̂
536+ for i in 1 : con. nc
537+ name = Symbol (" g_c_$i " )
538+ optim[name] = JuMP. add_nonlinear_operator (optim, nΔŨ, gfunc[i_base+ i]; name)
539+ end
540+ end
541+ return nothing
542+ end
543+
544+ function init_nonlincon! (mpc:: NonLinMPC , :: LinModel , gfunc:: Vector{<:Function} )
545+ optim, con = mpc. optim, mpc. con
546+ nΔŨ = length (mpc. ΔŨ)
547+ if length (con. i_g) ≠ 0
548+ i_base = 0
549+ for i in 1 : con. nc
550+ name = Symbol (" g_c_$i " )
551+ optim[name] = JuMP. add_nonlinear_operator (optim, nΔŨ, gfunc[i_base+ i]; name)
552+ end
553+ end
554+ return nothing
555+ end
540556
541- The function mutates `Ŷe`, `Ue` and `Ū` in arguments, without assuming any initial values.
542557"""
543- function extended_predictions! (Ŷe, Ue, Ū, mpc, model, Ŷ0, ΔŨ)
544- ny, nu = model. ny, model. nu
545- # --- extended output predictions Ŷe = [ŷ(k); Ŷ] ---
546- Ŷe[1 : ny] .= mpc. ŷ
547- Ŷe[ny+ 1 : end ] .= Ŷ0 .+ mpc. Yop
548- # --- extended manipulated inputs Ue = [U; u(k+Hp-1)] ---
549- U0 = Ū
550- U0 .= mul! (U0, mpc. S̃, ΔŨ) .+ mpc. T_lastu0
551- Ue[1 : end - nu] .= U0 .+ mpc. Uop
552- # u(k + Hp) = u(k + Hp - 1) since Δu(k+Hp) = 0 (because Hc ≤ Hp):
553- Ue[end - nu+ 1 : end ] .= @views Ue[end - 2 nu+ 1 : end - nu]
554- return Ŷe, Ue
558+ set_nonlincon!(mpc::NonLinMPC, ::LinModel, optim)
559+
560+ Set the custom nonlinear inequality constraints for `LinModel`.
561+ """
562+ function set_nonlincon! (
563+ mpc:: NonLinMPC , :: LinModel , optim:: JuMP.GenericModel{JNT}
564+ ) where JNT<: Real
565+ ΔŨvar = optim[:ΔŨvar ]
566+ con = mpc. con
567+ nonlin_constraints = JuMP. all_constraints (optim, JuMP. NonlinearExpr, MOI. LessThan{JNT})
568+ map (con_ref -> JuMP. delete (optim, con_ref), nonlin_constraints)
569+ for i in 1 : con. nc
570+ gfunc_i = optim[Symbol (" g_c_$i " )]
571+ @constraint (optim, gfunc_i (ΔŨvar... ) <= 0 )
572+ end
573+ return nothing
555574end
556575
557- " Set the nonlinear constraints on the output predictions `Ŷ` and terminal states `x̂end`."
558- function setnonlincon! (
559- mpc:: NonLinMPC , :: NonLinModel , optim:: JuMP.GenericModel{JNT}
576+ """
577+ set_nonlincon!(mpc::NonLinMPC, ::NonLinModel, optim)
578+
579+ Also set output prediction `Ŷ` and terminal state `x̂end` constraints when not a `LinModel`.
580+ """
581+ function set_nonlincon! (
582+ mpc:: NonLinMPC , :: SimModel , optim:: JuMP.GenericModel{JNT}
560583) where JNT<: Real
561584 ΔŨvar = optim[:ΔŨvar ]
562585 con = mpc. con
@@ -585,21 +608,30 @@ function setnonlincon!(
585608 return nothing
586609end
587610
588- # TODO : MODIF THE FOLLOWING METHOD!
589- function setnonlincon! (
590- mpc:: NonLinMPC , :: LinModel , optim:: JuMP.GenericModel{JNT}
591- ) where JNT<: Real
592- return nothing
611+ """
612+ con_nonlinprog!(g, mpc::NonLinMPC, model::LinModel, _ , _ , gc, ϵ)
613+
614+ Nonlinear constrains for [`NonLinMPC`](@ref) when `model` is a [`LinModel`](@ref).
615+
616+ The method mutates the `g` vectors in argument and returns it. Only the custom constraints
617+ are include in the `g` vector.
618+ """
619+ function con_nonlinprog! (g, mpc:: NonLinMPC , :: LinModel , _ , _ , gc, ϵ)
620+ for i in eachindex (g)
621+ g[i] = gc[i]
622+ end
623+ return g
593624end
594625
595626"""
596- con_nonlinprog!(g, mpc::NonLinMPC, model::SimModel, x̂end, gc, Ŷ0, ΔŨ , ϵ) -> g
627+ con_nonlinprog!(g, mpc::NonLinMPC, model::SimModel, x̂0end, Ŷ0, gc , ϵ) -> g
597628
598629Nonlinear constrains for [`NonLinMPC`](@ref) when `model` is not a [`LinModel`](@ref).
599630
600- The method mutates the `g` and `gc` vectors in argument.
631+ The method mutates the `g` vectors in argument and returns it. The output prediction,
632+ the terminal state and the custom constraints are include in the `g` vector.
601633"""
602- function con_nonlinprog! (g, mpc:: NonLinMPC , :: SimModel , x̂0end, gc, Ŷ0, ΔŨ , ϵ)
634+ function con_nonlinprog! (g, mpc:: NonLinMPC , :: SimModel , x̂0end, Ŷ0, gc , ϵ)
603635 nx̂, nŶ = length (x̂0end), length (Ŷ0)
604636 for i in eachindex (g)
605637 mpc. con. i_g[i] || continue
@@ -623,10 +655,6 @@ function con_nonlinprog!(g, mpc::NonLinMPC, ::SimModel, x̂0end, gc, Ŷ0, ΔŨ
623655 return g
624656end
625657
626- # TODO : MODIF THE FOLLOWING METHOD!
627- " No nonlinear constraints if `model` is a [`LinModel`](@ref), return `g` unchanged."
628- con_nonlinprog! (g, :: NonLinMPC , :: LinModel , _ , _ , _ , _ , _ ) = g
629-
630658" Evaluate the economic term `E*JE` of the objective function for [`NonLinMPC`](@ref)."
631659function obj_econ! (Ue, Ŷe, mpc:: NonLinMPC , model:: SimModel )
632660 E_JE = iszero (mpc. E) ? 0.0 : mpc. E* mpc. JE (Ue, Ŷe, mpc. D̂e, mpc. p)
0 commit comments