Skip to content

Commit c69c6e3

Browse files
committed
doc correction and reduce allocations NonLinMPC
1 parent 2e2eb6c commit c69c6e3

File tree

1 file changed

+33
-27
lines changed

1 file changed

+33
-27
lines changed

src/predictive_control.jl

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ Set the constraint parameters of `mpc` predictive controller.
6565
The predictive controllers support both soft and hard constraints, defined by:
6666
```math
6767
\begin{alignat*}{3}
68-
\mathbf{u_{min} - c_{u_{min}}} ϵ &≤ \mathbf{u}(k+j) &&≤ \mathbf{u_{max} + c_{u_{max}}} ϵ &&\qquad j = 0, 1 ,..., H_c - 1 \\
68+
\mathbf{u_{min} - c_{u_{min}}} ϵ &≤ \mathbf{u}(k+j) &&≤ \mathbf{u_{max} + c_{u_{max}}} ϵ &&\qquad j = 0, 1 ,..., H_p - 1 \\
6969
\mathbf{Δu_{min} - c_{Δu_{min}}} ϵ &≤ \mathbf{Δu}(k+j) &&≤ \mathbf{Δu_{max} + c_{Δu_{max}}} ϵ &&\qquad j = 0, 1 ,..., H_c - 1 \\
7070
\mathbf{y_{min} - c_{y_{min}}} ϵ &≤ \mathbf{ŷ}(k+j) &&≤ \mathbf{y_{max} + c_{y_{max}}} ϵ &&\qquad j = 1, 2 ,..., H_p
7171
\end{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 ``\mathbf{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 ``\mathbf{c}``. It is not possible to modify `±Inf` bounds
120120
at 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
\begin{alignat*}{3}
131131
\mathbf{U_{min} - c_{U_{min}}} ϵ &≤ \mathbf{U} &&≤ \mathbf{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,
486483
end
487484

488485
@doc raw"""
489-
predictstoch!(mpc, estim::InternalModel, x̂s, d, ym)
486+
predictstoch!(mpc::PredictiveController, estim::InternalModel, x̂s, d, ym)
490487
491488
Init `Ŷop` vector when if `estim` is an [`InternalModel`](@ref).
492489
493490
The vector combines the output operating points and the stochastic predictions:
494491
``\mathbf{Ŷ_{op} = Ŷ_{s} + Y_{op}}`` (both values are constant between the nonlinear
495492
programming 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
506503
end
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
513510
Evaluate the outputs predictions ``\mathbf{Ŷ}`` when `model` is a [`LinModel`](@ref).
514511
"""
515512
function 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
518514
end
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̂[:] = (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
540536
end
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
10411036
Init `i_b` and `A` for the linear inequality constraints (``\mathbf{A ΔŨ ≤ b}``).
10421037
1043-
`i_b` is a `BitVector` including the indices of ``\mathbf{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 ``\mathbf{b}`` that are finite
1041+
numbers.
10441042
"""
10451043
function 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
10521054
end
10531055

10541056
"Init values without predicted output constraints if `model` is not a [`LinModel`](@ref)."
10551057
function 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
10621068
end
10631069

0 commit comments

Comments
 (0)