@@ -340,7 +340,8 @@ function setconstraint!(
340340 i_Umin, i_Umax, i_ΔŨmin, i_ΔŨmax,
341341 i_Ymin, i_Ymax, i_x̂min, i_x̂max,
342342 con. A_Umin, con. A_Umax, con. A_ΔŨmin, con. A_ΔŨmax,
343- con. A_Ymin, con. A_Ymax, con. A_x̂min, con. A_x̂max
343+ con. A_Ymin, con. A_Ymax, con. A_x̂min, con. A_x̂max,
344+ con. A_ŝ
344345 )
345346 A = con. A[con. i_b, :]
346347 b = con. b[con. i_b]
@@ -368,23 +369,25 @@ end
368369 model::LinModel, nc::Int,
369370 i_Umin, i_Umax, i_ΔŨmin, i_ΔŨmax, i_Ymin, i_Ymax, i_x̂min, i_x̂max,
370371 args...
371- ) -> i_b, i_g, A
372+ ) -> i_b, i_g, A, Aeq
372373
373- Init `i_b`, `i_g` and `A ` matrices for the linear and nonlinear inequality constraints.
374+ Init `i_b`, `i_g`, `A` and `Aeq ` matrices for the linear and nonlinear constraints.
374375
375- The linear and nonlinear inequality constraints are respectively defined as:
376+ The linear and nonlinear constraints are respectively defined as:
376377```math
377378\b egin{aligned}
378- \m athbf{A ΔŨ } &≤ \m athbf{b} \\
379- \m athbf{g(ΔŨ)} &≤ \m athbf{0}
379+ \m athbf{A Z̃ } &≤ \m athbf{b} \\
380+ \m athbf{A_{eq} Z̃} &= \m athbf{b_{eq}} \\
381+ \m athbf{g(Z̃)} &≤ \m athbf{0} \\
382+ \m athbf{g_{eq}(Z̃)} &= \m athbf{0} \\
380383\e nd{aligned}
381384```
382- The argument `nc` is the number of custom nonlinear constraints in `` \m athbf{g_c}``. `i_b`
383- is a `BitVector` including the indices of ``\m athbf{b}`` that are finite numbers. `i_g` is a
384- similar vector but for the indices of ``\m athbf{g}``. The method also returns the
385- ``\m athbf{A} `` matrix if `args` is provided. In such a case, `args` needs to contain all
386- the inequality constraint matrices:
387- `A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, A_Ymin, A_Ymax, A_x̂min, A_x̂max`.
385+ The argument `nc` is the number of custom nonlinear inequality constraints in
386+ `` \m athbf{g_c}``. `i_b` is a `BitVector` including the indices of ``\m athbf{b}`` that are
387+ finite numbers. `i_g` is a similar vector but for the indices of ``\m athbf{g}``. The method
388+ also returns the ``\m athbf{A, A_{eq}} `` matrices if `args` is provided. In such a case,
389+ `args` needs to contain all the inequality and equality constraint matrices:
390+ `A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, A_Ymin, A_Ymax, A_x̂min, A_x̂max, A_ŝ `.
388391"""
389392function init_matconstraint_mpc (
390393 :: LinModel{NT} , nc:: Int ,
@@ -394,12 +397,13 @@ function init_matconstraint_mpc(
394397 i_b = [i_Umin; i_Umax; i_ΔŨmin; i_ΔŨmax; i_Ymin; i_Ymax; i_x̂min; i_x̂max]
395398 i_g = trues (nc)
396399 if isempty (args)
397- A = nothing
400+ A, Aeq = nothing , nothing
398401 else
399- A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, A_Ymin, A_Ymax, A_x̂min, A_x̂max = args
400- A = [A_Umin; A_Umax; A_ΔŨmin; A_ΔŨmax; A_Ymin; A_Ymax; A_x̂min; A_x̂max]
402+ A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, A_Ymin, A_Ymax, A_x̂min, A_x̂max, A_ŝ = args
403+ A = [A_Umin; A_Umax; A_ΔŨmin; A_ΔŨmax; A_Ymin; A_Ymax; A_x̂min; A_x̂max]
404+ Aeq = A_ŝ
401405 end
402- return i_b, i_g, A
406+ return i_b, i_g, A, Aeq
403407end
404408
405409" Init `i_b, A` without outputs and terminal constraints if `model` is not a [`LinModel`](@ref)."
@@ -411,12 +415,13 @@ function init_matconstraint_mpc(
411415 i_b = [i_Umin; i_Umax; i_ΔŨmin; i_ΔŨmax]
412416 i_g = [i_Ymin; i_Ymax; i_x̂min; i_x̂max; trues (nc)]
413417 if isempty (args)
414- A = nothing
418+ A, Aeq = nothing , nothing
415419 else
416- A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, _ , _ , _ , _ = args
417- A = [A_Umin; A_Umax; A_ΔŨmin; A_ΔŨmax]
420+ A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, A_Ymin, A_Ymax, A_x̂min, A_x̂max, A_ŝ = args
421+ A = [A_Umin; A_Umax; A_ΔŨmin; A_ΔŨmax; A_Ymin; A_Ymax; A_x̂min; A_x̂max]
422+ Aeq = A_ŝ
418423 end
419- return i_b, i_g, A
424+ return i_b, i_g, A, Aeq
420425end
421426
422427" By default, there is no nonlinear constraint, thus do nothing."
@@ -541,12 +546,14 @@ function init_defaultcon_mpc(
541546 i_ΔŨmin, i_ΔŨmax = .! isinf .(ΔŨmin), .! isinf .(ΔŨmax)
542547 i_Ymin, i_Ymax = .! isinf .(Y0min), .! isinf .(Y0max)
543548 i_x̂min, i_x̂max = .! isinf .(x̂0min), .! isinf .(x̂0max)
544- i_b, i_g, A = init_matconstraint_mpc (
549+ i_b, i_g, A, Aeq = init_matconstraint_mpc (
545550 model, nc,
546551 i_Umin, i_Umax, i_ΔŨmin, i_ΔŨmax, i_Ymin, i_Ymax, i_x̂min, i_x̂max,
547- A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, A_Ymin, A_Ymax, A_x̂max, A_x̂min
552+ A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, A_Ymin, A_Ymax, A_x̂max, A_x̂min,
553+ A_ŝ
548554 )
549- b = zeros (NT, size (A, 1 )) # dummy b vector (updated just before optimization)
555+ # dummy b and beq vectors (updated just before optimization)
556+ b, beq = zeros (NT, size (A, 1 )), zeros (NT, size (Aeq, 1 ))
550557 con = ControllerConstraint {NT, GCfunc} (
551558 ẽx̂ , fx̂ , gx̂ , jx̂ , kx̂ , vx̂ , bx̂ ,
552559 Ẽŝ , Fŝ , Gŝ , Jŝ , Kŝ , Vŝ , Bŝ ,
@@ -620,8 +627,10 @@ Augment input increments constraints with slack variable ϵ for softening.
620627Denoting the decision variables augmented with the slack variable
621628``\m athbf{Z̃} = [\b egin{smallmatrix} \m athbf{Z} \\ ϵ \e nd{smallmatrix}]``, it returns the
622629augmented conversion matrix ``\m athbf{P̃}``, similar to the one described at
623- [`init_ZtoΔU`](@ref). It also returns the augmented constraints ``\m athbf{ΔŨ_{min}}`` and
624- ``\m athbf{ΔŨ_{max}}`` and the ``\m athbf{A}`` matrices for the inequality constraints:
630+ [`init_ZtoΔU`](@ref). Knowing that ``0 ≤ ϵ ≤ ∞``, it also returns the augmented bounds
631+ ``\m athbf{ΔŨ_{min}} = [\b egin{smallmatrix} \m athbf{ΔU_{min}} \\ 0 \e nd{smallmatrix}]`` and
632+ ``\m athbf{ΔŨ_{max}} = [\b egin{smallmatrix} \m athbf{ΔU_{min}} \\ ∞ \e nd{smallmatrix}]``,
633+ and the ``\m athbf{A}`` matrices for the inequality constraints:
625634```math
626635\b egin{bmatrix}
627636 \m athbf{A_{ΔŨ_{min}}} \\
@@ -632,20 +641,21 @@ augmented conversion matrix ``\mathbf{P̃}``, similar to the one described at
632641 + \m athbf{ΔŨ_{max}}
633642\e nd{bmatrix}
634643```
644+ Note that strictly speaking, the lower bound on the slack variable ϵ is a decision variable
645+ bound, which is more specific than a linear inequality constraint. However, it is more
646+ convenient to treat it as a linear inequality constraint since the optimizer `OSQP.jl` does
647+ not support pure bounds on the decision variables.
635648"""
636649function relaxΔU (:: SimModel{NT} , nϵ, C_Δumin, C_Δumax, ΔUmin, ΔUmax, P) where NT<: Real
637- nΔU = length (ΔUmin)
638650 nZ = size (P, 2 )
639651 if nϵ == 1 # Z̃ = [Z; ϵ]
640- # 0 ≤ ϵ ≤ ∞
641- ΔŨmin, ΔŨmax = [ΔUmin; NT[0.0 ]], [ΔUmax; NT[Inf ]]
642- A_ϵ = [zeros (NT, 1 , nΔU) NT[1.0 ]]
643- A_ΔŨmin, A_ΔŨmax = - [I C_Δumin; A_ϵ], [I - C_Δumax; A_ϵ]
652+ ΔŨmin, ΔŨmax = [ΔUmin; NT[0.0 ]], [ΔUmax; NT[Inf ]] # 0 ≤ ϵ ≤ ∞
653+ A_ϵ = [zeros (NT, 1 , nZ) NT[1.0 ]]
654+ A_ΔŨmin, A_ΔŨmax = - [P C_Δumin; A_ϵ], [P - C_Δumax; A_ϵ]
644655 P̃ = [P zeros (NT, size (P, 1 ), 1 )]
645656 else # Z̃ = Z (only hard constraints)
646657 ΔŨmin, ΔŨmax = ΔUmin, ΔUmax
647- I_Hc = Matrix {NT} (I, nΔU, nΔU)
648- A_ΔŨmin, A_ΔŨmax = - I_Hc, I_Hc
658+ A_ΔŨmin, A_ΔŨmax = - P, P
649659 P̃ = P
650660 end
651661 return A_ΔŨmin, A_ΔŨmax, ΔŨmin, ΔŨmax, P̃
@@ -656,15 +666,15 @@ end
656666
657667Augment linear output prediction constraints with slack variable ϵ for softening.
658668
659- Denoting the input increments augmented with the slack variable
660- ``\m athbf{ΔŨ } = [\b egin{smallmatrix} \m athbf{ΔU } \\ ϵ \e nd{smallmatrix}]``, it returns the
669+ Denoting the decision variables augmented with the slack variable
670+ ``\m athbf{Z̃ } = [\b egin{smallmatrix} \m athbf{Z } \\ ϵ \e nd{smallmatrix}]``, it returns the
661671``\m athbf{Ẽ}`` matrix that appears in the linear model prediction equation
662- ``\m athbf{Ŷ_0 = Ẽ ΔŨ + F}``, and the ``\m athbf{A}`` matrices for the inequality constraints:
672+ ``\m athbf{Ŷ_0 = Ẽ Z̃ + F}``, and the ``\m athbf{A}`` matrices for the inequality constraints:
663673```math
664674\b egin{bmatrix}
665675 \m athbf{A_{Y_{min}}} \\
666676 \m athbf{A_{Y_{max}}}
667- \e nd{bmatrix} \m athbf{ΔŨ } ≤
677+ \e nd{bmatrix} \m athbf{Z̃ } ≤
668678\b egin{bmatrix}
669679 - \m athbf{(Y_{min} - Y_{op}) + F} \\
670680 + \m athbf{(Y_{max} - Y_{op}) - F}
@@ -674,12 +684,12 @@ in which ``\mathbf{Y_{min}, Y_{max}}`` and ``\mathbf{Y_{op}}`` vectors respectiv
674684``\m athbf{y_{min}, y_{max}}`` and ``\m athbf{y_{op}}`` repeated ``H_p`` times.
675685"""
676686function relaxŶ (:: LinModel{NT} , nϵ, C_ymin, C_ymax, E) where NT<: Real
677- if nϵ == 1 # ΔŨ = [ΔU ; ϵ]
687+ if nϵ == 1 # Z̃ = [Z ; ϵ]
678688 # ϵ impacts predicted output constraint calculations:
679689 A_Ymin, A_Ymax = - [E C_ymin], [E - C_ymax]
680690 # ϵ has no impact on output predictions:
681691 Ẽ = [E zeros (NT, size (E, 1 ), 1 )]
682- else # ΔŨ = ΔU (only hard constraints)
692+ else # Z̃ = Z (only hard constraints)
683693 Ẽ = E
684694 A_Ymin, A_Ymax = - E, E
685695 end
@@ -698,29 +708,29 @@ end
698708
699709Augment terminal state constraints with slack variable ϵ for softening.
700710
701- Denoting the input increments augmented with the slack variable
702- ``\m athbf{ΔŨ } = [\b egin{smallmatrix} \m athbf{ΔU } \\ ϵ \e nd{smallmatrix}]``, it returns the
711+ Denoting the decision variables augmented with the slack variable
712+ ``\m athbf{Z̃ } = [\b egin{smallmatrix} \m athbf{Z } \\ ϵ \e nd{smallmatrix}]``, it returns the
703713``\m athbf{ẽ_{x̂}}`` matrix that appears in the terminal state equation
704- ``\m athbf{x̂_0}(k + H_p) = \m athbf{ẽ_x̂ ΔŨ + f_x̂}``, and the ``\m athbf{A}`` matrices for
714+ ``\m athbf{x̂_0}(k + H_p) = \m athbf{ẽ_x̂ Z̃ + f_x̂}``, and the ``\m athbf{A}`` matrices for
705715the inequality constraints:
706716```math
707717\b egin{bmatrix}
708718 \m athbf{A_{x̂_{min}}} \\
709719 \m athbf{A_{x̂_{max}}}
710- \e nd{bmatrix} \m athbf{ΔŨ } ≤
720+ \e nd{bmatrix} \m athbf{Z̃ } ≤
711721\b egin{bmatrix}
712722 - \m athbf{(x̂_{min} - x̂_{op}) + f_x̂} \\
713723 + \m athbf{(x̂_{max} - x̂_{op}) - f_x̂}
714724\e nd{bmatrix}
715725```
716726"""
717727function relaxterminal (:: LinModel{NT} , nϵ, c_x̂min, c_x̂max, ex̂) where {NT<: Real }
718- if nϵ == 1 # ΔŨ = [ΔU ; ϵ]
728+ if nϵ == 1 # Z̃ = [Z ; ϵ]
719729 # ϵ impacts terminal state constraint calculations:
720730 A_x̂min, A_x̂max = - [ex̂ c_x̂min], [ex̂ - c_x̂max]
721731 # ϵ has no impact on terminal state predictions:
722732 ẽx̂ = [ex̂ zeros (NT, size (ex̂, 1 ), 1 )]
723- else # ΔŨ = ΔU (only hard constraints)
733+ else # Z̃ = Z (only hard constraints)
724734 ẽx̂ = ex̂
725735 A_x̂min, A_x̂max = - ex̂, ex̂
726736 end
@@ -734,15 +744,21 @@ function relaxterminal(::SimModel{NT}, nϵ, c_x̂min, c_x̂max, ex̂) where {NT<
734744 return A_x̂min, A_x̂max, ẽx̂
735745end
736746
737- """
747+ @doc raw """
738748 augmentdefect(::LinModel{NT}, nϵ, Eŝ) where NT<:Real
739749
740750Augment defect equality constraints with slack variable ϵ if `nϵ == 1`.
751+
752+ It returns the ``\m athbf{Ẽŝ}`` matrix that appears in the defect equation
753+ ``\m athbf{Ŝ = Ẽ_ŝ Z̃ + F_ŝ}`` and the ``\m athbf{A}`` matrix for the equality constraints:
754+ ```math
755+ \m athbf{A_ŝ Z̃} = - \m athbf{F_ŝ}
756+ ```
741757"""
742758function augmentdefect (:: LinModel{NT} , nϵ, Eŝ) where NT<: Real
743- if nϵ == 1 # ΔŨ = [ΔU ; ϵ]
759+ if nϵ == 1 # Z̃ = [Z ; ϵ]
744760 Ẽŝ = [Eŝ zeros (NT, size (Eŝ, 1 ), 1 )]
745- else # ΔŨ = ΔU (only hard constraints)
761+ else # Z̃ = Z (only hard constraints)
746762 Ẽŝ = Eŝ
747763 end
748764 A_ŝ = Ẽŝ
0 commit comments