Skip to content

Commit 8cfe110

Browse files
committed
added: iszero_X field for the 4 weights in ControllerWeights
after some real benchmarking, the `noR̂u` field was useful to save some computation So I added similar information for the 4 weights
1 parent 7d8928b commit 8cfe110

File tree

3 files changed

+59
-29
lines changed

3 files changed

+59
-29
lines changed

src/controller/construct.jl

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ struct ControllerWeights{NT<:Real}
44
Ñ_Hc::Hermitian{NT, Matrix{NT}}
55
L_Hp::Hermitian{NT, Matrix{NT}}
66
E ::NT
7+
iszero_M_Hp::Vector{Bool}
8+
iszero_Ñ_Hc::Vector{Bool}
9+
iszero_L_Hp::Vector{Bool}
10+
iszero_E::Bool
711
function ControllerWeights{NT}(
812
model, Hp, Hc, M_Hp, N_Hc, L_Hp, Cwt=Inf, Ewt=0
913
) where NT<:Real
@@ -21,8 +25,12 @@ struct ControllerWeights{NT<:Real}
2125
# ΔŨ = ΔU (only hard constraints)
2226
Ñ_Hc = N_Hc
2327
end
24-
E = Ewt
25-
return new{NT}(M_Hp, Ñ_Hc, L_Hp, E)
28+
E = Ewt
29+
iszero_M_Hp = [iszero(M_Hp)]
30+
iszero_Ñ_Hc = [iszero(Ñ_Hc)]
31+
iszero_L_Hp = [iszero(L_Hp)]
32+
iszero_E = iszero(E)
33+
return new{NT}(M_Hp, Ñ_Hc, L_Hp, E, iszero_M_Hp, iszero_Ñ_Hc, iszero_L_Hp, iszero_E)
2634
end
2735
end
2836

src/controller/execute.jl

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ They are computed with these equations using in-place operations:
179179
\begin{aligned}
180180
\mathbf{F} &= \mathbf{G d_0}(k) + \mathbf{J D̂_0} + \mathbf{K x̂_0}(k)
181181
+ \mathbf{V u_0}(k-1) + \mathbf{B} + \mathbf{Ŷ_s} \\
182-
\mathbf{C_y} &= \mathbf{F} - (\mathbf{R̂_y - Y_{op}}) \\
182+
\mathbf{C_y} &= \mathbf{F} - (\mathbf{R̂_y - Y_{op}}) \\
183183
\mathbf{C_u} &= \mathbf{T} \mathbf{u_0}(k-1) - (\mathbf{R̂_u - U_{op}}) \\
184184
\mathbf{q̃} &= 2[(\mathbf{M}_{H_p} \mathbf{Ẽ})' \mathbf{C_y}
185185
+ (\mathbf{L}_{H_p} \mathbf{S̃})' \mathbf{C_u}] \\
@@ -193,32 +193,38 @@ function initpred!(mpc::PredictiveController, model::LinModel, d, D̂, R̂y, R̂
193193
ŷ, F, q̃, r = mpc.ŷ, mpc.F, mpc.q̃, mpc.r
194194
Cy, Cu, M_Hp_Ẽ, L_Hp_S̃ = mpc.buffer.Ŷ, mpc.buffer.U, mpc.buffer.Ẽ, mpc.buffer.
195195
ŷ .= evaloutput(mpc.estim, d)
196-
predictstoch!(mpc, mpc.estim) # init F with Ŷs for InternalModel
197-
F .+= mpc.B # F = F + B
198-
mul!(F, mpc.K, mpc.estim.x̂0, 1, 1) # F = F + K*x̂0
199-
mul!(F, mpc.V, mpc.estim.lastu0, 1, 1) # F = F + V*lastu0
196+
predictstoch!(mpc, mpc.estim) # init F with Ŷs for InternalModel
197+
F .+= mpc.B # F = F + B
198+
mul!(F, mpc.K, mpc.estim.x̂0, 1, 1) # F = F + K*x̂0
199+
mul!(F, mpc.V, mpc.estim.lastu0, 1, 1) # F = F + V*lastu0
200200
if model.nd 0
201201
mpc.d0 .= d .- model.dop
202202
mpc.D̂0 .=.- mpc.Dop
203203
mpc.D̂e[1:model.nd] .= d
204204
mpc.D̂e[model.nd+1:end] .=
205-
mul!(F, mpc.G, mpc.d0, 1, 1) # F = F + G*d0
206-
mul!(F, mpc.J, mpc.D̂0, 1, 1) # F = F + J*D̂0
205+
mul!(F, mpc.G, mpc.d0, 1, 1) # F = F + G*d0
206+
mul!(F, mpc.J, mpc.D̂0, 1, 1) # F = F + J*D̂0
207207
end
208+
q̃ .= 0
209+
r .= 0
208210
# --- output setpoint tracking term ---
209211
mpc.R̂y .= R̂y
210-
Cy .= F .- (R̂y .- mpc.Yop)
211-
mul!(M_Hp_Ẽ, mpc.weights.M_Hp, mpc.Ẽ)
212-
mul!(q̃, M_Hp_Ẽ', Cy) # q̃ = M_Hp*Ẽ'*Cy
213-
r .= dot(Cy, mpc.weights.M_Hp, Cy)
212+
if !mpc.weights.iszero_M_Hp[]
213+
Cy .= F .- (R̂y .- mpc.Yop)
214+
mul!(M_Hp_Ẽ, mpc.weights.M_Hp, mpc.Ẽ)
215+
mul!(q̃, M_Hp_Ẽ', Cy, 1, 1) # q̃ = q̃ + M_Hp*Ẽ'*Cy
216+
r .+= dot(Cy, mpc.weights.M_Hp, Cy) # r = r + Cy'*M_Hp*Cy
217+
end
214218
# --- input setpoint tracking term ---
215219
mpc.R̂u .= R̂u
216-
Cu .= mpc.T_lastu0 .- (R̂u .- mpc.Uop)
217-
mul!(L_Hp_S̃, mpc.weights.L_Hp, mpc.S̃)
218-
mul!(q̃, L_Hp_S̃', Cu, 1, 1) # q̃ = q̃ + L_Hp*S̃'*Cu
219-
r .+= dot(Cu, mpc.weights.L_Hp, Cu)
220+
if !mpc.weights.iszero_L_Hp[]
221+
Cu .= mpc.T_lastu0 .- (R̂u .- mpc.Uop)
222+
mul!(L_Hp_S̃, mpc.weights.L_Hp, mpc.S̃)
223+
mul!(q̃, L_Hp_S̃', Cu, 1, 1) # q̃ = q̃ + L_Hp*S̃'*Cu
224+
r .+= dot(Cu, mpc.weights.L_Hp, Cu) # r = r + Cu'*L_Hp*Cu
225+
end
220226
# --- finalize ---
221-
lmul!(2, q̃) # q̃ = 2*q̃
227+
lmul!(2, q̃) # q̃ = 2*q̃
222228
return nothing
223229
end
224230

@@ -230,7 +236,7 @@ Init `ŷ, F, d0, D̂0, D̂e, R̂y, R̂u` vectors when model is not a [`LinModel
230236
function initpred!(mpc::PredictiveController, model::SimModel, d, D̂, R̂y, R̂u)
231237
mul!(mpc.T_lastu0, mpc.T, mpc.estim.lastu0)
232238
mpc.ŷ .= evaloutput(mpc.estim, d)
233-
predictstoch!(mpc, mpc.estim) # init F with Ŷs for InternalModel
239+
predictstoch!(mpc, mpc.estim) # init F with Ŷs for InternalModel
234240
if model.nd 0
235241
mpc.d0 .= d .- model.dop
236242
mpc.D̂0 .=.- mpc.Dop
@@ -412,22 +418,36 @@ function obj_nonlinprog!(
412418
) where NT<:Real
413419
nu, ny = model.nu, model.ny
414420
# --- output setpoint tracking term ---
415-
Ȳ .= @views Ŷe[ny+1:end]
416-
Ȳ .= mpc.R̂y .-
417-
JR̂y = dot(Ȳ, mpc.weights.M_Hp, Ȳ)
421+
if mpc.weights.iszero_M_Hp[]
422+
JR̂y = zero(NT)
423+
else
424+
Ȳ .= @views Ŷe[ny+1:end]
425+
Ȳ .= mpc.R̂y .-
426+
JR̂y = dot(Ȳ, mpc.weights.M_Hp, Ȳ)
427+
end
418428
# --- move suppression and slack variable term ---
419-
JΔŨ = dot(ΔŨ, mpc.weights.Ñ_Hc, ΔŨ)
429+
if mpc.weights.iszero_Ñ_Hc[]
430+
JΔŨ = zero(NT)
431+
else
432+
JΔŨ = dot(ΔŨ, mpc.weights.Ñ_Hc, ΔŨ)
433+
end
420434
# --- input setpoint tracking term ---
421-
Ū .= @views Ue[1:end-nu]
422-
Ū .= mpc.R̂u .-
423-
JR̂u = dot(Ū, mpc.weights.L_Hp, Ū)
435+
if mpc.weights.iszero_L_Hp[]
436+
JR̂u = zero(NT)
437+
else
438+
Ū .= @views Ue[1:end-nu]
439+
Ū .= mpc.R̂u .-
440+
JR̂u = dot(Ū, mpc.weights.L_Hp, Ū)
441+
end
424442
# --- economic term ---
425443
E_JE = obj_econ(mpc, model, Ue, Ŷe)
426444
return JR̂y + JΔŨ + JR̂u + E_JE
427445
end
428446

429447
"By default, the economic term is zero."
430-
obj_econ(::PredictiveController, ::SimModel, _ , _ ) = 0.0
448+
function obj_econ(::PredictiveController, ::SimModel, _ , ::AbstractVector{NT}) where NT
449+
return zero(NT)
450+
end
431451

432452
@doc raw"""
433453
optim_objective!(mpc::PredictiveController) -> ΔŨ

src/controller/nonlinmpc.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,9 @@ function con_nonlinprog!(g, mpc::NonLinMPC, ::SimModel, x̂0end, Ŷ0, gc, ϵ)
702702
end
703703

704704
"Evaluate the economic term `E*JE` of the objective function for [`NonLinMPC`](@ref)."
705-
function obj_econ(mpc::NonLinMPC, model::SimModel, Ue, Ŷe)
706-
E_JE = iszero(mpc.weights.E) ? 0.0 : mpc.weights.E*mpc.JE(Ue, Ŷe, mpc.D̂e, mpc.p)
705+
function obj_econ(
706+
mpc::NonLinMPC, model::SimModel, Ue, Ŷe::AbstractVector{NT}
707+
) where NT<:Real
708+
E_JE = mpc.weights.iszero_E ? zero(NT) : mpc.weights.E*mpc.JE(Ue, Ŷe, mpc.D̂e, mpc.p)
707709
return E_JE
708710
end

0 commit comments

Comments
 (0)