@@ -65,7 +65,7 @@ Set the constraint parameters of `mpc` predictive controller.
6565The predictive controllers support both soft and hard constraints, defined by:
6666```math
6767\b egin{alignat*}{3}
68- \m athbf{u_{min} - c_{u_{min}}} ϵ &≤ \m athbf{u}(k+j) &&≤ \m athbf{u_{max} + c_{u_{max}}} ϵ &&\q quad j = 0, 1 ,..., H_c - 1 \\
68+ \m athbf{u_{min} - c_{u_{min}}} ϵ &≤ \m athbf{u}(k+j) &&≤ \m athbf{u_{max} + c_{u_{max}}} ϵ &&\q quad j = 0, 1 ,..., H_p - 1 \\
6969 \m athbf{Δu_{min} - c_{Δu_{min}}} ϵ &≤ \m athbf{Δu}(k+j) &&≤ \m athbf{Δu_{max} + c_{Δu_{max}}} ϵ &&\q quad j = 0, 1 ,..., H_c - 1 \\
7070 \m athbf{y_{min} - c_{y_{min}}} ϵ &≤ \m athbf{ŷ}(k+j) &&≤ \m athbf{y_{max} + c_{y_{max}}} ϵ &&\q quad j = 1, 2 ,..., H_p
7171\e nd{alignat*}
@@ -115,17 +115,17 @@ LinMPC controller with a sample time Ts = 4.0 s, OSQP optimizer, SteadyKalmanFil
115115```
116116
117117# Extended Help
118- The bounds can be modified after calling [`moveinput!`](@ref), that is at runtime, but not
119- the softness parameters ``\m athbf{c}``. It is not possible to modify `±Inf` constraints
118+ The constraints can be modified after calling [`moveinput!`](@ref), that is, at runtime, but
119+ not the softness parameters ``\m athbf{c}``. It is not possible to modify `±Inf` bounds
120120at runtime.
121121
122122!!! tip
123123 To keep a variable unconstrained while maintaining the ability to add a constraint later
124124 at runtime, set the bound to an absolute value sufficiently large when you create the
125- controller.
125+ controller (but different than `±Inf`) .
126126
127- It is also possible to specify time-varying constraints over prediction ``H_p`` and control
128- ``H_c`` horizons. In such a case, they are defined by:
127+ It is also possible to specify time-varying constraints over ``H_p`` and ``H_c`` horizons.
128+ In such a case, they are defined by:
129129```math
130130\b egin{alignat*}{3}
131131 \m athbf{U_{min} - c_{U_{min}}} ϵ &≤ \m athbf{U} &&≤ \m athbf{U_{max} + c_{U_{max}}} ϵ \\
@@ -269,10 +269,7 @@ function setconstraint!(
269269 @constraint (mpc. optim, linconstraint, A* ΔŨvar .≤ b)
270270 setnonlincon! (mpc, model)
271271 else
272- i_b, _ = init_linconstraint (model,
273- i_Umin, i_Umax, i_ΔŨmin, i_ΔŨmax, i_Ymin, i_Ymax,
274- con. A_Umin, con. A_Umax, con. A_ΔŨmin, con. A_ΔŨmax, con. A_Ymin, con. A_Ymax,
275- )
272+ i_b, _ = init_linconstraint (model, i_Umin, i_Umax, i_ΔŨmin, i_ΔŨmax, i_Ymin, i_Ymax)
276273 i_b == con. i_b || error (" Cannot modify ±Inf constraints after calling moveinput!" )
277274 end
278275 return mpc
@@ -486,15 +483,15 @@ function initpred!(mpc::PredictiveController, model::SimModel, d, ym, D̂, R̂y,
486483end
487484
488485@doc raw """
489- predictstoch!(mpc, estim::InternalModel, x̂s, d, ym)
486+ predictstoch!(mpc::PredictiveController , estim::InternalModel, x̂s, d, ym)
490487
491488Init `Ŷop` vector when if `estim` is an [`InternalModel`](@ref).
492489
493490The vector combines the output operating points and the stochastic predictions:
494491``\m athbf{Ŷ_{op} = Ŷ_{s} + Y_{op}}`` (both values are constant between the nonlinear
495492programming iterations).
496493"""
497- function predictstoch! (mpc, estim:: InternalModel , d, ym)
494+ function predictstoch! (mpc:: PredictiveController , estim:: InternalModel , d, ym)
498495 isnothing (ym) && error (" Predictive controllers with InternalModel need the measured " *
499496 " outputs ym in keyword argument to compute control actions u" )
500497 ŷd = h (estim. model, estim. x̂d, d - estim. model. dop) + estim. model. yop
@@ -505,16 +502,15 @@ function predictstoch!(mpc, estim::InternalModel, d, ym)
505502 return nothing
506503end
507504" Separate stochastic predictions are not needed if `estim` is not [`InternalModel`](@ref)."
508- predictstoch! (mpc, estim :: StateEstimator , _ , _ ) = nothing
505+ predictstoch! (:: PredictiveController , :: StateEstimator , _ , _ ) = nothing
509506
510507@doc raw """
511508 predict!(Ŷ, mpc::PredictiveController, model::LinModel, ΔŨ) -> Ŷ
512509
513510Evaluate the outputs predictions ``\m athbf{Ŷ}`` when `model` is a [`LinModel`](@ref).
514511"""
515512function predict! (Ŷ, mpc:: PredictiveController , :: LinModel , ΔŨ:: Vector{T} ) where {T<: Real }
516- Ŷ[:] = mpc. Ẽ* ΔŨ + mpc. F
517- return Ŷ
513+ return mul! (Ŷ, mpc. Ẽ, ΔŨ) + mpc. F # in-place operations to reduce allocations
518514end
519515
520516@doc raw """
@@ -529,13 +525,13 @@ function predict!(Ŷ, mpc::PredictiveController, model::SimModel, ΔŨ::Vector
529525 d0 = mpc. d - model. dop
530526 for j= 1 : Hp
531527 if j ≤ Hc
532- u0[:] + = @views ΔŨ[(1 + nu* (j- 1 )): (nu* j)]
528+ u0[:] = @views ΔŨ[(1 + nu* (j- 1 )): (nu* j)] + u0
533529 end
534530 x̂[:] = f̂ (mpc. estim, x̂, u0, d0)
535531 d0[:] = @views mpc. D̂[(1 + nd* (j- 1 )): (nd* j)] - model. dop
536532 Ŷ[(1 + ny* (j- 1 )): (ny* j)] = ĥ (mpc. estim, x̂, d0)
537533 end
538- Ŷ[:] += mpc. Ŷop # Ŷop = Ŷs + Yop, and Ŷs=0 if mpc.estim is not an InternalModel
534+ Ŷ[:] = Ŷ + mpc. Ŷop # Ŷop = Ŷs + Yop, and Ŷs=0 if mpc.estim is not an InternalModel
539535 return Ŷ
540536end
541537
@@ -1033,31 +1029,41 @@ init_stochpred(estim::StateEstimator, _ ) = zeros(0, estim.nxs), zeros(0, estim.
10331029
10341030
10351031@doc raw """
1036- init_linconstraint(model::LinModel,
1037- i_Umin, i_Umax, i_ΔŨmin, i_ΔŨmax, i_Ymin, i_Ymax,
1038- A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, A_Ymin, A_Ymax,
1032+ init_linconstraint(::LinModel,
1033+ i_Umin, i_Umax, i_ΔŨmin, i_ΔŨmax, i_Ymin, i_Ymax, args...
10391034 ) -> i_b, A
10401035
10411036Init `i_b` and `A` for the linear inequality constraints (``\m athbf{A ΔŨ ≤ b}``).
10421037
1043- `i_b` is a `BitVector` including the indices of ``\m athbf{b}`` that are finite numbers.
1038+ If provided, the arguments in `args` should be all the inequality constraint matrices:
1039+ `A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, A_Ymin, A_Ymax`. If not provided, it returns an empty `A`
1040+ matrix. `i_b` is a `BitVector` including the indices of ``\m athbf{b}`` that are finite
1041+ numbers.
10441042"""
10451043function init_linconstraint (:: LinModel ,
1046- i_Umin, i_Umax, i_ΔŨmin, i_ΔŨmax, i_Ymin, i_Ymax,
1047- A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, A_Ymin, A_Ymax,
1044+ i_Umin, i_Umax, i_ΔŨmin, i_ΔŨmax, i_Ymin, i_Ymax, args...
10481045)
10491046 i_b = [i_Umin; i_Umax; i_ΔŨmin; i_ΔŨmax; i_Ymin; i_Ymax]
1050- A = [A_Umin; A_Umax; A_ΔŨmin; A_ΔŨmax; A_Ymin; A_Ymax]
1047+ if isempty (args)
1048+ A = zeros (length (i_b), 0 )
1049+ else
1050+ A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, A_Ymin, A_Ymax = args
1051+ A = [A_Umin; A_Umax; A_ΔŨmin; A_ΔŨmax; A_Ymin; A_Ymax]
1052+ end
10511053 return i_b, A
10521054end
10531055
10541056" Init values without predicted output constraints if `model` is not a [`LinModel`](@ref)."
10551057function init_linconstraint (:: SimModel ,
1056- i_Umin, i_Umax, i_ΔŨmin, i_ΔŨmax, _ , _ ,
1057- A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, _ , _
1058+ i_Umin, i_Umax, i_ΔŨmin, i_ΔŨmax, _ , _ , args...
10581059)
10591060 i_b = [i_Umin; i_Umax; i_ΔŨmin; i_ΔŨmax]
1060- A = [A_Umin; A_Umax; A_ΔŨmin; A_ΔŨmax]
1061+ if isempty (args)
1062+ A = zeros (length (i_b), 0 )
1063+ else
1064+ A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, _ , _ = args
1065+ A = [A_Umin; A_Umax; A_ΔŨmin; A_ΔŨmax]
1066+ end
10611067 return i_b, A
10621068end
10631069
0 commit comments