@@ -437,33 +437,7 @@ function init_optimization!(mpc::NonLinMPC, model::SimModel, optim)
437
437
Jfunc, gfunc = get_optim_functions (mpc, mpc. optim)
438
438
@operator (optim, J, nΔŨ, Jfunc)
439
439
@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)
467
441
return nothing
468
442
end
469
443
@@ -506,7 +480,7 @@ function get_optim_functions(mpc::NonLinMPC, ::JuMP.GenericModel{JNT}) where JNT
506
480
Ŷe, Ue = extended_predictions! (Ŷe, Ue, Ū, mpc, model, Ŷ0, ΔŨ)
507
481
ϵ = (nϵ == 1 ) ? ΔŨ[end ] : zero (JNT) # ϵ = 0 if nϵ == 0 (meaning no relaxation)
508
482
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 , ϵ)
510
484
return obj_nonlinprog! (Ȳ, Ū, mpc, model, Ŷe, Ue, ΔŨ):: T
511
485
end
512
486
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
525
499
Ŷe, Ue = extended_predictions! (Ŷe, Ue, Ū, mpc, model, Ŷ0, ΔŨ)
526
500
ϵ = (nϵ == 1 ) ? ΔŨ[end ] : zero (JNT) # ϵ = 0 if nϵ == 0 (meaning no relaxation)
527
501
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 , ϵ)
529
503
end
530
504
return g[i]:: T
531
505
end
532
506
gfunc = [(ΔŨ... ) -> gfunc_i (i, ΔŨ) for i in 1 : ng]
533
507
return Jfunc, gfunc
534
508
end
535
509
536
- """
537
- extended_predictions!(Ŷe, Ue, Ū, mpc, model, Ŷ0, ΔŨ) -> Ŷe, Ue
538
510
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
540
556
541
- The function mutates `Ŷe`, `Ue` and `Ū` in arguments, without assuming any initial values.
542
557
"""
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
555
574
end
556
575
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}
560
583
) where JNT<: Real
561
584
ΔŨvar = optim[:ΔŨvar ]
562
585
con = mpc. con
@@ -585,21 +608,30 @@ function setnonlincon!(
585
608
return nothing
586
609
end
587
610
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
593
624
end
594
625
595
626
"""
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
597
628
598
629
Nonlinear constrains for [`NonLinMPC`](@ref) when `model` is not a [`LinModel`](@ref).
599
630
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.
601
633
"""
602
- function con_nonlinprog! (g, mpc:: NonLinMPC , :: SimModel , x̂0end, gc, Ŷ0, ΔŨ , ϵ)
634
+ function con_nonlinprog! (g, mpc:: NonLinMPC , :: SimModel , x̂0end, Ŷ0, gc , ϵ)
603
635
nx̂, nŶ = length (x̂0end), length (Ŷ0)
604
636
for i in eachindex (g)
605
637
mpc. con. i_g[i] || continue
@@ -623,10 +655,6 @@ function con_nonlinprog!(g, mpc::NonLinMPC, ::SimModel, x̂0end, gc, Ŷ0, ΔŨ
623
655
return g
624
656
end
625
657
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
-
630
658
" Evaluate the economic term `E*JE` of the objective function for [`NonLinMPC`](@ref)."
631
659
function obj_econ! (Ue, Ŷe, mpc:: NonLinMPC , model:: SimModel )
632
660
E_JE = iszero (mpc. E) ? 0.0 : mpc. E* mpc. JE (Ue, Ŷe, mpc. D̂e, mpc. p)
0 commit comments