@@ -20,7 +20,7 @@ function PredictiveControllerBuffer(
2020 estim:: StateEstimator{NT} , transcription:: TranscriptionMethod , Hp:: Int , Hc:: Int , nϵ:: Int
2121) where NT <: Real
2222 nu, ny, nd, nx̂ = estim. model. nu, estim. model. ny, estim. model. nd, estim. nx̂
23- nZ̃ = get_nZ̃ (estim, transcription, Hp, Hc, nϵ)
23+ nZ̃ = get_nZ (estim, transcription, Hp, Hc) + nϵ
2424 u = Vector {NT} (undef, nu)
2525 Z̃ = Vector {NT} (undef, nZ̃)
2626 D̂ = Vector {NT} (undef, nd* Hp)
@@ -238,7 +238,8 @@ function setconstraint!(
238238 ΔUmin = DeltaUmin, ΔUmax = DeltaUmax,
239239 C_Δumin = C_Deltaumin, C_Δumax = C_Deltaumax,
240240)
241- model, con, optim = mpc. estim. model, mpc. con, mpc. optim
241+ model, con = mpc. estim. model, mpc. con
242+ transcription, optim = mpc. transcription, mpc. optim
242243 nu, ny, nx̂, Hp, Hc = model. nu, model. ny, mpc. estim. nx̂, mpc. Hp, mpc. Hc
243244 nϵ, nc = mpc. nϵ, con. nc
244245 notSolvedYet = (JuMP. termination_status (optim) == JuMP. OPTIMIZE_NOT_CALLED)
@@ -370,7 +371,7 @@ function setconstraint!(
370371 i_x̂min, i_x̂max = .! isinf .(con. x̂0min), .! isinf .(con. x̂0max)
371372 if notSolvedYet
372373 con. i_b[:], con. i_g[:], con. A[:] = init_matconstraint_mpc (
373- model, nc,
374+ model, transcription, nc,
374375 i_Umin, i_Umax, i_ΔŨmin, i_ΔŨmax,
375376 i_Ymin, i_Ymax, i_x̂min, i_x̂max,
376377 con. A_Umin, con. A_Umax, con. A_ΔŨmin, con. A_ΔŨmax,
@@ -386,7 +387,7 @@ function setconstraint!(
386387 set_nonlincon! (mpc, model, optim)
387388 else
388389 i_b, i_g = init_matconstraint_mpc (
389- model, nc,
390+ model, transcription, nc,
390391 i_Umin, i_Umax, i_ΔŨmin, i_ΔŨmax,
391392 i_Ymin, i_Ymax, i_x̂min, i_x̂max
392393 )
400401
401402@doc raw """
402403 init_matconstraint_mpc(
403- model::LinModel, nc::Int,
404+ model::LinModel, transcription::TranscriptionMethod, nc::Int,
404405 i_Umin, i_Umax, i_ΔŨmin, i_ΔŨmax, i_Ymin, i_Ymax, i_x̂min, i_x̂max,
405406 args...
406407 ) -> i_b, i_g, A, Aeq
@@ -424,40 +425,59 @@ also returns the ``\mathbf{A, A_{eq}}`` matrices if `args` is provided. In such
424425`A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, A_Ymin, A_Ymax, A_x̂min, A_x̂max, A_ŝ`.
425426"""
426427function init_matconstraint_mpc (
427- :: LinModel{NT} , nc:: Int ,
428+ :: LinModel{NT} , :: TranscriptionMethod , nc:: Int ,
428429 i_Umin, i_Umax, i_ΔŨmin, i_ΔŨmax, i_Ymin, i_Ymax, i_x̂min, i_x̂max,
429430 args...
430431) where {NT<: Real }
432+ if isempty (args)
433+ A, Aeq = nothing , nothing
434+ else
435+ A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, A_Ymin, A_Ymax, A_x̂min, A_x̂max, A_ŝ = args
436+ A = [A_Umin; A_Umax; A_ΔŨmin; A_ΔŨmax; A_Ymin; A_Ymax; A_x̂min; A_x̂max]
437+ Aeq = A_ŝ
438+ end
431439 i_b = [i_Umin; i_Umax; i_ΔŨmin; i_ΔŨmax; i_Ymin; i_Ymax; i_x̂min; i_x̂max]
432440 i_g = trues (nc)
441+ return i_b, i_g, A, Aeq
442+ end
443+
444+ " Init `i_b` without output constraints if [`NonLinModel`](@ref) & [`MultipleShooting`](@ref)."
445+ function init_matconstraint_mpc (
446+ :: NonLinModel{NT} , :: MultipleShooting , nc:: Int ,
447+ i_Umin, i_Umax, i_ΔŨmin, i_ΔŨmax, i_Ymin, i_Ymax, i_x̂min, i_x̂max,
448+ args...
449+ ) where {NT<: Real }
433450 if isempty (args)
434451 A, Aeq = nothing , nothing
435452 else
436453 A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, A_Ymin, A_Ymax, A_x̂min, A_x̂max, A_ŝ = args
437454 A = [A_Umin; A_Umax; A_ΔŨmin; A_ΔŨmax; A_Ymin; A_Ymax; A_x̂min; A_x̂max]
438455 Aeq = A_ŝ
439456 end
457+ i_b = [i_Umin; i_Umax; i_ΔŨmin; i_ΔŨmax; i_x̂min; i_x̂max]
458+ i_g = [i_Ymin; i_Ymax; trues (nc)]
440459 return i_b, i_g, A, Aeq
441460end
442461
443- " Init `i_b, A ` without outputs and terminal constraints if `model` is not a [`LinModel `](@ref)."
462+ " Init `i_b` without output & terminal constraints if [`NonLinModel`](@ref) & [`SingleShooting `](@ref)."
444463function init_matconstraint_mpc (
445- :: SimModel {NT} , nc:: Int ,
464+ :: NonLinModel {NT}, :: SingleShooting , nc:: Int ,
446465 i_Umin, i_Umax, i_ΔŨmin, i_ΔŨmax, i_Ymin, i_Ymax, i_x̂min, i_x̂max,
447466 args...
448467) where {NT<: Real }
449- i_b = [i_Umin; i_Umax; i_ΔŨmin; i_ΔŨmax]
450- i_g = [i_Ymin; i_Ymax; i_x̂min; i_x̂max; trues (nc)]
451468 if isempty (args)
452469 A, Aeq = nothing , nothing
453470 else
454471 A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, A_Ymin, A_Ymax, A_x̂min, A_x̂max, A_ŝ = args
455472 A = [A_Umin; A_Umax; A_ΔŨmin; A_ΔŨmax; A_Ymin; A_Ymax; A_x̂min; A_x̂max]
456473 Aeq = A_ŝ
457474 end
475+ i_b = [i_Umin; i_Umax; i_ΔŨmin; i_ΔŨmax]
476+ i_g = [i_Ymin; i_Ymax; i_x̂min; i_x̂max; trues (nc)]
458477 return i_b, i_g, A, Aeq
459478end
460479
480+
461481" By default, there is no nonlinear constraint, thus do nothing."
462482set_nonlincon! (:: PredictiveController , :: SimModel , :: JuMP.GenericModel ) = nothing
463483
@@ -512,11 +532,12 @@ Init the quadratic programming Hessian `H̃` for MPC.
512532
513533The matrix appear in the quadratic general form:
514534```math
515- J = \m in_{\m athbf{ΔŨ }} \f rac{1}{2}\m athbf{(ΔŨ)'H̃(ΔŨ) } + \m athbf{q̃'(ΔŨ) } + r
535+ J = \m in_{\m athbf{Z̃ }} \f rac{1}{2}\m athbf{Z̃' H̃ Z̃ } + \m athbf{q̃' Z̃ } + r
516536```
517537The Hessian matrix is constant if the model and weights are linear and time invariant (LTI):
518538```math
519- \m athbf{H̃} = 2 ( \m athbf{Ẽ}'\m athbf{M}_{H_p}\m athbf{Ẽ} + \m athbf{Ñ}_{H_c}
539+ \m athbf{H̃} = 2 ( \m athbf{Ẽ}'\m athbf{M}_{H_p}\m athbf{Ẽ}
540+ + \m athbf{P̃}'\m athbf{Ñ}_{H_c}\m athbf{P̃}
520541 + \m athbf{S̃}'\m athbf{L}_{H_p}\m athbf{S̃} )
521542```
522543The vector ``\m athbf{q̃}`` and scalar ``r`` need recalculation each control period ``k``, see
@@ -571,19 +592,17 @@ function init_defaultcon_mpc(
571592 repeat_constraints (Hp, Hc, u0min, u0max, Δumin, Δumax, y0min, y0max)
572593 C_umin, C_umax, C_Δumin, C_Δumax, C_ymin, C_ymax =
573594 repeat_constraints (Hp, Hc, c_umin, c_umax, c_Δumin, c_Δumax, c_ymin, c_ymax)
574- A_Umin, A_Umax, S̃ = relaxU (model, nϵ, C_umin, C_umax, S)
575- A_ΔŨmin, A_ΔŨmax, ΔŨmin, ΔŨmax, P̃ = relaxΔU (
576- model, transcription, nϵ, C_Δumin, C_Δumax, ΔUmin, ΔUmax, P
577- )
578- A_Ymin, A_Ymax, Ẽ = relaxŶ (model, nϵ, C_ymin, C_ymax, E)
579- A_x̂min, A_x̂max, ẽx̂ = relaxterminal (model, nϵ, c_x̂min, c_x̂max, ex̂)
580- A_ŝ, Ẽŝ = augmentdefect (model, nϵ, Eŝ)
595+ A_Umin, A_Umax, S̃ = relaxU (S, C_umin, C_umax, nϵ)
596+ A_ΔŨmin, A_ΔŨmax, ΔŨmin, ΔŨmax, P̃ = relaxΔU (P, C_Δumin, C_Δumax, ΔUmin, ΔUmax, nϵ)
597+ A_Ymin, A_Ymax, Ẽ = relaxŶ (E, C_ymin, C_ymax, nϵ)
598+ A_x̂min, A_x̂max, ẽx̂ = relaxterminal (ex̂, c_x̂min, c_x̂max, nϵ)
599+ A_ŝ, Ẽŝ = augmentdefect (Eŝ, nϵ)
581600 i_Umin, i_Umax = .! isinf .(U0min), .! isinf .(U0max)
582601 i_ΔŨmin, i_ΔŨmax = .! isinf .(ΔŨmin), .! isinf .(ΔŨmax)
583602 i_Ymin, i_Ymax = .! isinf .(Y0min), .! isinf .(Y0max)
584603 i_x̂min, i_x̂max = .! isinf .(x̂0min), .! isinf .(x̂0max)
585604 i_b, i_g, A, Aeq = init_matconstraint_mpc (
586- model, nc,
605+ model, transcription, nc,
587606 i_Umin, i_Umax, i_ΔŨmin, i_ΔŨmax, i_Ymin, i_Ymax, i_x̂min, i_x̂max,
588607 A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, A_Ymin, A_Ymax, A_x̂max, A_x̂min,
589608 A_ŝ
@@ -615,10 +634,8 @@ function repeat_constraints(Hp, Hc, umin, umax, Δumin, Δumax, ymin, ymax)
615634 return Umin, Umax, ΔUmin, ΔUmax, Ymin, Ymax
616635end
617636
618- # TODO : change all the next docstringgs with Z̃ instead of ΔŨ !!!!!
619-
620637@doc raw """
621- relaxU(model, nϵ, C_umin, C_umax, S ) -> A_Umin, A_Umax, S̃
638+ relaxU(S, C_umin, C_umax, nϵ ) -> A_Umin, A_Umax, S̃
622639
623640Augment manipulated inputs constraints with slack variable ϵ for softening.
624641
@@ -640,7 +657,7 @@ constraints:
640657in which ``\m athbf{U_{min}}`` and ``\m athbf{U_{max}}`` vectors respectively contains
641658``\m athbf{u_{min}}`` and ``\m athbf{u_{max}}`` repeated ``H_p`` times.
642659"""
643- function relaxU (:: SimModel {NT} , nϵ, C_umin, C_umax, S ) where NT<: Real
660+ function relaxU (S :: Matrix {NT} , C_umin, C_umax, nϵ ) where NT<: Real
644661 if nϵ == 1 # Z̃ = [Z; ϵ]
645662 # ϵ impacts Z → U conversion for constraint calculations:
646663 A_Umin, A_Umax = - [S C_umin], [S - C_umax]
@@ -654,9 +671,7 @@ function relaxU(::SimModel{NT}, nϵ, C_umin, C_umax, S) where NT<:Real
654671end
655672
656673@doc raw """
657- relaxΔU(
658- model, transcription, nϵ, C_Δumin, C_Δumax, ΔUmin, ΔUmax, P
659- ) -> A_ΔŨmin, A_ΔŨmax, ΔŨmin, ΔŨmax, P̃
674+ relaxΔU(P, C_Δumin, C_Δumax, ΔUmin, ΔUmax, nϵ) -> A_ΔŨmin, A_ΔŨmax, ΔŨmin, ΔŨmax, P̃
660675
661676Augment input increments constraints with slack variable ϵ for softening.
662677
@@ -684,10 +699,7 @@ bound, which is more specific than a linear inequality constraint. However, it i
684699convenient to treat it as a linear inequality constraint since the optimizer `OSQP.jl` does
685700not support pure bounds on the decision variables.
686701"""
687- function relaxΔU (
688- :: SimModel{NT} , transcription:: TranscriptionMethod ,
689- nϵ, C_Δumin, C_Δumax, ΔUmin, ΔUmax, P
690- ) where NT<: Real
702+ function relaxΔU (P:: Matrix{NT} , C_Δumin, C_Δumax, ΔUmin, ΔUmax, nϵ) where NT<: Real
691703 nZ = size (P, 2 )
692704 if nϵ == 1 # Z̃ = [Z; ϵ]
693705 ΔŨmin, ΔŨmax = [ΔUmin; NT[0.0 ]], [ΔUmax; NT[Inf ]] # 0 ≤ ϵ ≤ ∞
@@ -703,7 +715,7 @@ function relaxΔU(
703715end
704716
705717@doc raw """
706- relaxŶ(::LinModel, nϵ, C_ymin, C_ymax, E ) -> A_Ymin, A_Ymax, Ẽ
718+ relaxŶ(E, C_ymin, C_ymax, nϵ ) -> A_Ymin, A_Ymax, Ẽ
707719
708720Augment linear output prediction constraints with slack variable ϵ for softening.
709721
@@ -724,8 +736,12 @@ Denoting the decision variables augmented with the slack variable
724736in which ``\m athbf{Y_{min}, Y_{max}}`` and ``\m athbf{Y_{op}}`` vectors respectively contains
725737``\m athbf{y_{min}, y_{max}}`` and ``\m athbf{y_{op}}`` repeated ``H_p`` times.
726738"""
727- function relaxŶ (:: LinModel {NT} , nϵ, C_ymin, C_ymax, E ) where NT<: Real
739+ function relaxŶ (E :: Matrix {NT} , C_ymin, C_ymax, nϵ ) where NT<: Real
728740 if nϵ == 1 # Z̃ = [Z; ϵ]
741+ if iszero (size (E, 1 ))
742+ # model is not a LinModel, thus Ŷ constraints are not linear:
743+ C_ymin = C_ymax = zeros (NT, 0 , 1 )
744+ end
729745 # ϵ impacts predicted output constraint calculations:
730746 A_Ymin, A_Ymax = - [E C_ymin], [E - C_ymax]
731747 # ϵ has no impact on output predictions:
@@ -737,15 +753,8 @@ function relaxŶ(::LinModel{NT}, nϵ, C_ymin, C_ymax, E) where NT<:Real
737753 return A_Ymin, A_Ymax, Ẽ
738754end
739755
740- " Return empty matrices if model is not a [`LinModel`](@ref)"
741- function relaxŶ (:: SimModel{NT} , nϵ, C_ymin, C_ymax, E) where NT<: Real
742- Ẽ = [E zeros (NT, 0 , nϵ)]
743- A_Ymin, A_Ymax = - Ẽ, Ẽ
744- return A_Ymin, A_Ymax, Ẽ
745- end
746-
747756@doc raw """
748- relaxterminal(::LinModel, nϵ, c_x̂min, c_x̂max, ex̂ ) -> A_x̂min, A_x̂max, ẽx̂
757+ relaxterminal(ex̂, c_x̂min, c_x̂max, nϵ ) -> A_x̂min, A_x̂max, ẽx̂
749758
750759Augment terminal state constraints with slack variable ϵ for softening.
751760
@@ -765,8 +774,13 @@ the inequality constraints:
765774\e nd{bmatrix}
766775```
767776"""
768- function relaxterminal (:: LinModel {NT} , nϵ, c_x̂min, c_x̂max, ex̂ ) where {NT<: Real }
777+ function relaxterminal (ex̂ :: Matrix {NT} , c_x̂min, c_x̂max, nϵ ) where {NT<: Real }
769778 if nϵ == 1 # Z̃ = [Z; ϵ]
779+ if iszero (size (ex̂, 1 ))
780+ # model is not a LinModel and transcription is a SingleShooting, thus terminal
781+ # state constraints are not linear:
782+ c_x̂min = c_x̂max = zeros (NT, 0 , 1 )
783+ end
770784 # ϵ impacts terminal state constraint calculations:
771785 A_x̂min, A_x̂max = - [ex̂ c_x̂min], [ex̂ - c_x̂max]
772786 # ϵ has no impact on terminal state predictions:
@@ -778,15 +792,8 @@ function relaxterminal(::LinModel{NT}, nϵ, c_x̂min, c_x̂max, ex̂) where {NT<
778792 return A_x̂min, A_x̂max, ẽx̂
779793end
780794
781- " Return empty matrices if model is not a [`LinModel`](@ref)"
782- function relaxterminal (:: SimModel{NT} , nϵ, c_x̂min, c_x̂max, ex̂) where {NT<: Real }
783- ẽx̂ = [ex̂ zeros (NT, 0 , nϵ)]
784- A_x̂min, A_x̂max = - ẽx̂, ẽx̂
785- return A_x̂min, A_x̂max, ẽx̂
786- end
787-
788795@doc raw """
789- augmentdefect(::LinModel{NT} , nϵ, Eŝ) where NT<:Real
796+ augmentdefect(Eŝ , nϵ) -> A_ŝ, Ẽŝ
790797
791798Augment defect equality constraints with slack variable ϵ if `nϵ == 1`.
792799
@@ -796,7 +803,7 @@ It returns the ``\mathbf{Ẽŝ}`` matrix that appears in the defect equation
796803\m athbf{A_ŝ Z̃} = - \m athbf{F_ŝ}
797804```
798805"""
799- function augmentdefect (:: LinModel {NT} , nϵ, Eŝ ) where NT<: Real
806+ function augmentdefect (Eŝ :: Matrix {NT} , nϵ) where NT<: Real
800807 if nϵ == 1 # Z̃ = [Z; ϵ]
801808 Ẽŝ = [Eŝ zeros (NT, size (Eŝ, 1 ), 1 )]
802809 else # Z̃ = Z (only hard constraints)
@@ -806,14 +813,6 @@ function augmentdefect(::LinModel{NT}, nϵ, Eŝ) where NT<:Real
806813 return A_ŝ, Ẽŝ
807814end
808815
809- " Return empty matrices if model is not a [`LinModel`](@ref)"
810- function augmentdefect (:: SimModel{NT} , nϵ, Eŝ) where NT<: Real
811- Ẽŝ = [Eŝ zeros (NT, 0 , nϵ)]
812- A_ŝ = Ẽŝ
813- return A_ŝ, Ẽŝ
814- end
815-
816-
817816@doc raw """
818817 init_stochpred(estim::InternalModel, Hp) -> Ks, Ps
819818
0 commit comments