Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/controller/execute.jl
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ julia> round.(getinfo(mpc)[:Ŷ], digits=3)
"""
function getinfo(mpc::PredictiveController{NT}) where NT<:Real
model, buffer, transcription = mpc.estim.model, mpc.buffer, mpc.transcription
nΔŨ, nK = mpc.Hc*model.nu + mpc.nϵ, mpc.Hp*model.nk
nΔŨ, nK = mpc.Hc*model.nu + mpc.nϵ, mpc.Hp*model.nk̄
nŶe, nUe = (mpc.Hp+1)*model.ny, (mpc.Hp+1)*model.nu
nX̂0, nÛ0 = mpc.estim.nx̂*mpc.Hp, model.nu*mpc.Hp
Z̃ = mpc.Z̃
Expand Down
12 changes: 6 additions & 6 deletions src/controller/nonlinmpc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -584,12 +584,12 @@ function addinfo!(info, mpc::NonLinMPC{NT}) where NT<:Real
hess = mpc.hessian
transcription = mpc.transcription
nu, ny, nx̂, nϵ = model.nu, model.ny, mpc.estim.nx̂, mpc.nϵ
nk = get_nk(model, transcription)
nk̄ = get_nk̄(model, transcription)
Hp, Hc = mpc.Hp, mpc.Hc
i_g = findall(mpc.con.i_g) # convert to non-logical indices for non-allocating @views
ng, ngi = length(mpc.con.i_g), sum(mpc.con.i_g)
nc, neq = con.nc, con.neq
nU, nŶ, nX̂, nK = mpc.Hp*nu, Hp*ny, Hp*nx̂, Hp*nk
nU, nŶ, nX̂, nK = mpc.Hp*nu, Hp*ny, Hp*nx̂, Hp*nk̄
nΔŨ, nUe, nŶe = nu*Hc + nϵ, nU + nu, nŶ + ny
ΔŨ = zeros(NT, nΔŨ)
x̂0end = zeros(NT, nx̂)
Expand Down Expand Up @@ -823,11 +823,11 @@ function get_nonlinobj_op(mpc::NonLinMPC, optim::JuMP.GenericModel{JNT}) where J
transcription = mpc.transcription
grad, hess = mpc.gradient, mpc.hessian
nu, ny, nx̂, nϵ = model.nu, model.ny, mpc.estim.nx̂, mpc.nϵ
nk = get_nk(model, transcription)
nk̄ = get_nk̄(model, transcription)
Hp, Hc = mpc.Hp, mpc.Hc
ng = length(mpc.con.i_g)
nc, neq = mpc.con.nc, mpc.con.neq
nZ̃, nU, nŶ, nX̂, nK = length(mpc.Z̃), Hp*nu, Hp*ny, Hp*nx̂, Hp*nk
nZ̃, nU, nŶ, nX̂, nK = length(mpc.Z̃), Hp*nu, Hp*ny, Hp*nx̂, Hp*nk̄
nΔŨ, nUe, nŶe = nu*Hc + nϵ, nU + nu, nŶ + ny
strict = Val(true)
myNaN = convert(JNT, NaN)
Expand Down Expand Up @@ -949,12 +949,12 @@ function get_nonlincon_oracle(mpc::NonLinMPC, ::JuMP.GenericModel{JNT}) where JN
transcription = mpc.transcription
jac, hess = mpc.jacobian, mpc.hessian
nu, ny, nx̂, nϵ = model.nu, model.ny, mpc.estim.nx̂, mpc.nϵ
nk = get_nk(model, transcription)
nk̄ = get_nk̄(model, transcription)
Hp, Hc = mpc.Hp, mpc.Hc
i_g = findall(mpc.con.i_g) # convert to non-logical indices for non-allocating @views
ng, ngi = length(mpc.con.i_g), sum(mpc.con.i_g)
nc, neq = mpc.con.nc, mpc.con.neq
nZ̃, nU, nŶ, nX̂, nK = length(mpc.Z̃), Hp*nu, Hp*ny, Hp*nx̂, Hp*nk
nZ̃, nU, nŶ, nX̂, nK = length(mpc.Z̃), Hp*nu, Hp*ny, Hp*nx̂, Hp*nk̄
nΔŨ, nUe, nŶe = nu*Hc + nϵ, nU + nu, nŶ + ny
strict = Val(true)
myNaN, myInf = convert(JNT, NaN), convert(JNT, Inf)
Expand Down
68 changes: 34 additions & 34 deletions src/controller/transcription.jl
Original file line number Diff line number Diff line change
Expand Up @@ -516,15 +516,15 @@ The matrices ``\mathbf{E_S}`` and ``\mathbf{K_S}`` are defined in the Extended H
\vdots & \vdots & \vdots & \vdots & \ddots & \vdots & \vdots & \vdots & \vdots \\
\mathbf{0} & \mathbf{0} & \mathbf{0} & \mathbf{0} & \cdots & λ_o\mathbf{I} & \mathbf{0} & \mathbf{-I} & \mathbf{0} \\
\mathbf{0} & \mathbf{0} & \mathbf{0} & \mathbf{0} & \cdots & \mathbf{0} & \mathbf{A_s} & \mathbf{0} & \mathbf{-I} \end{bmatrix} \\
\mathbf{E_{S}^{k}} &= \begin{bmatrix}
\mathbf{E_{S}^{}} &= \begin{bmatrix}
\mathbf{C_o} & \mathbf{0} & \cdots & \mathbf{0} \\
\mathbf{0} & \mathbf{0} & \cdots & \mathbf{0} \\
\mathbf{0} & \mathbf{C_o} & \cdots & \mathbf{0} \\
\mathbf{0} & \mathbf{0} & \cdots & \mathbf{0} \\
\vdots & \vdots & \ddots & \vdots \\
\mathbf{0} & \mathbf{0} & \cdots & \mathbf{C_o} \\
\mathbf{0} & \mathbf{0} & \cdots & \mathbf{0} \end{bmatrix} \\
\mathbf{E_S} &= \begin{bmatrix} \mathbf{E_{S}^{Δu}} & \mathbf{E_{S}^{x̂}} & \mathbf{E_{S}^{k}} \end{bmatrix} \\
\mathbf{E_S} &= \begin{bmatrix} \mathbf{E_{S}^{Δu}} & \mathbf{E_{S}^{x̂}} & \mathbf{E_{S}^{}} \end{bmatrix} \\
\mathbf{K_S} &= \begin{bmatrix}
λ_o\mathbf{I} & \mathbf{0} \\
\mathbf{0} & \mathbf{A_s} \\
Expand Down Expand Up @@ -558,7 +558,7 @@ function init_defectmat_orthocolloc(
Hp, Hc, Co, λo, As, nxs
) where {NT<:Real}
nu, nx, nd, nx̂ = model.nu, model.nx, model.nd, estim.nx̂
nk = get_nk(model, transcription)
nk̄ = get_nk̄(model, transcription)
λo_I = λo*I(nx)
# --- current state estimates x̂0 ---
KS = zeros(NT, nx̂*Hp, nx̂)
Expand All @@ -577,8 +577,8 @@ function init_defectmat_orthocolloc(
ESx̂[iRow_λo, iCol_λo] = λo_I
ESx̂[iRow_As, iCol_As] = As
end
ESk = repeatdiag([Co; zeros(NT, nxs, nk)], Hp)
ES = [ESΔu ESx̂ ESk]
ESk̄ = repeatdiag([Co; zeros(NT, nxs, nk̄)], Hp)
ES = [ESΔu ESx̂ ESk̄]
# --- current measured disturbances d0 and predictions D̂0 ---
GS = zeros(NT, nx̂*Hp, nd)
JS = zeros(NT, nx̂*Hp, nd*Hp)
Expand Down Expand Up @@ -1027,36 +1027,36 @@ It warm-starts the solver at:
\mathbf{x̂_0}(k+H_p-2|k-1) \\
\mathbf{x̂_0}(k+H_p-1|k-1) \\
\mathbf{x̂_0}(k+H_p-1|k-1) \\
\mathbf{k}(k+0|k-1) \\
\mathbf{k}(k+1|k-1) \\
\mathbf{}(k+0|k-1) \\
\mathbf{}(k+1|k-1) \\
\vdots \\
\mathbf{k}(k+H_p-3|k-1) \\
\mathbf{k}(k+H_p-2|k-1) \\
\mathbf{k}(k+H_p-2|k-1) \\
\mathbf{}(k+H_p-3|k-1) \\
\mathbf{}(k+H_p-2|k-1) \\
\mathbf{}(k+H_p-2|k-1) \\
ϵ_{k-1}
\end{bmatrix}
```
where ``\mathbf{x̂_0}(k+j|k-1)`` is the predicted state for time ``k+j`` computed at the
last control period ``k-1``, expressed as a deviation from the operating point
``\mathbf{x̂_{op}}``. The vector ``\mathbf{k}(k+j|k-1)`` include the ``n_o`` intermediate
``\mathbf{x̂_{op}}``. The vector ``\mathbf{}(k+j|k-1)`` include the ``n_o`` intermediate
stage predictions for the interval ``k+j``, and is also computed at the last control period.
"""
function set_warmstart_mpc!(
mpc::PredictiveController, transcription::OrthogonalCollocation, Z̃var
)
nu, nx̂ = mpc.estim.model.nu, mpc.estim.nx̂
Hp, Hc, Z̃s = mpc.Hp, mpc.Hc, mpc.buffer.Z̃
nk = get_nk(mpc.estim.model, transcription)
nΔU, nX̂, nK = nu*Hc, nx̂*Hp, nk*Hp
nk̄ = get_nk̄(mpc.estim.model, transcription)
nΔU, nX̂, nK = nu*Hc, nx̂*Hp, nk̄*Hp
# --- input increments ΔU ---
Z̃s[1:(nΔU-nu)] .= @views mpc.Z̃[(nu+1):(nΔU)]
Z̃s[(nΔU-nu+1):(nΔU)] .= 0
# --- predicted states X̂0 ---
Z̃s[(nΔU+1):(nΔU+nX̂-nx̂)] .= @views mpc.Z̃[(nΔU+nx̂+1):(nΔU+nX̂)]
Z̃s[(nΔU+nX̂-nx̂+1):(nΔU+nX̂)] .= @views mpc.Z̃[(nΔU+nX̂-nx̂+1):(nΔU+nX̂)]
# --- collocation points K ---
Z̃s[(nΔU+nX̂+1):(nΔU+nX̂+nK-nk)] .= @views mpc.Z̃[(nΔU+nX̂+nk+1):(nΔU+nX̂+nK)]
Z̃s[(nΔU+nX̂+nK-nk+1):(nΔU+nX̂+nK)] .= @views mpc.Z̃[(nΔU+nX̂+nK-nk+1):(nΔU+nX̂+nK)]
Z̃s[(nΔU+nX̂+1):(nΔU+nX̂+nK-nk̄)] .= @views mpc.Z̃[(nΔU+nX̂+nk̄+1):(nΔU+nX̂+nK)]
Z̃s[(nΔU+nX̂+nK-nk̄+1):(nΔU+nX̂+nK)] .= @views mpc.Z̃[(nΔU+nX̂+nK-nk̄+1):(nΔU+nX̂+nK)]
# --- slack variable ϵ ---
mpc.nϵ == 1 && (Z̃s[end] = mpc.Z̃[end])
JuMP.set_start_value.(Z̃var, Z̃s)
Expand Down Expand Up @@ -1169,16 +1169,16 @@ function predict!(
mpc::PredictiveController, model::NonLinModel, ::SingleShooting,
U0, _
)
nu, nx̂, ny, nd, nk, Hp = model.nu, mpc.estim.nx̂, model.ny, model.nd, model.nk, mpc.Hp
nu, nx̂, ny, nd, nk̄, Hp = model.nu, mpc.estim.nx̂, model.ny, model.nd, model.nk̄, mpc.Hp
D̂0 = mpc.D̂0
x̂0 = @views mpc.estim.x̂0[1:nx̂]
d̂0 = @views mpc.d0[1:nd]
for j=1:Hp
u0 = @views U0[(1 + nu*(j-1)):(nu*j)]
û0 = @views Û0[(1 + nu*(j-1)):(nu*j)]
k = @views K[(1 + nk*(j-1)):(nk*j)]
= @views K[(1 + nk̄*(j-1)):(nk̄*j)]
x̂0next = @views X̂0[(1 + nx̂*(j-1)):(nx̂*j)]
f̂!(x̂0next, û0, k, mpc.estim, model, x̂0, u0, d̂0)
f̂!(x̂0next, û0, , mpc.estim, model, x̂0, u0, d̂0)
x̂0 = @views X̂0[(1 + nx̂*(j-1)):(nx̂*j)]
d̂0 = @views D̂0[(1 + nd*(j-1)):(nd*j)]
ŷ0 = @views Ŷ0[(1 + ny*(j-1)):(ny*j)]
Expand Down Expand Up @@ -1338,7 +1338,7 @@ function con_nonlinprogeq!(
mpc::PredictiveController, model::NonLinModel, transcription::MultipleShooting,
U0, Z̃
)
nx̂, nx, nu, nd, nk = mpc.estim.nx̂, model.nx, model.nu, model.nd, model.nk
nx̂, nx, nu, nd, nk̄ = mpc.estim.nx̂, model.nx, model.nu, model.nd, model.nk̄
Hp, Hc = mpc.Hp, mpc.Hc
nΔU, nX̂ = nu*Hc, nx̂*Hp
f_threads = transcription.f_threads
Expand All @@ -1354,11 +1354,11 @@ function con_nonlinprogeq!(
d̂0 = @views D̂0[(1 + nd*(j-2)):(nd*(j-1))]
end
û0 = @views Û0[(1 + nu*(j-1)):(nu*j)]
k = @views K[(1 + nk*(j-1)):(nk*j)]
= @views K[(1 + nk̄*(j-1)):(nk̄*j)]
x̂dnext = @views X̂0[(1 + nx̂*(j-1)):(nx̂*(j-1) + nx)]
x̂dnext_Z̃ = @views X̂0_Z̃[(1 + nx̂*(j-1)):(nx̂*(j-1) + nx)]
ŝdnext = @views geq[(1 + nx*(j-1)):(nx*j)]
f!(x̂dnext, k, model, x̂d_Z̃, û0, d̂0, model.p)
f!(x̂dnext, , model, x̂d_Z̃, û0, d̂0, model.p)
ŝdnext .= @. x̂dnext - x̂dnext_Z̃
end
return geq
Expand Down Expand Up @@ -1400,7 +1400,7 @@ function con_nonlinprogeq!(
nΔU, nX̂ = nu*Hc, nx̂*Hp
f_threads = transcription.f_threads
Ts = model.Ts
nk = get_nk(model, transcription)
nk̄ = get_nk̄(model, transcription)
D̂0 = mpc.D̂0
X̂0_Z̃ = @views Z̃[(nΔU+1):(nΔU+nX̂)]
Û0 = disturbedinput!(Û0, mpc.estim, mpc.estim.x̂0, X̂0_Z̃, U0)
Expand All @@ -1413,7 +1413,7 @@ function con_nonlinprogeq!(
d̂0 = @views D̂0[(1 + nd*(j-2)):(nd*(j-1))]
end
û0 = @views Û0[(1 + nu*(j-1)):(nu*j)]
k̇ = @views K̇[(1 + nk*(j-1)):(nk*j)]
k̇ = @views K̇[(1 + nk̄*(j-1)):(nk̄*j)]
d̂0next = @views D̂0[(1 + nd*(j-1)):(nd*j)]
x̂dnext_Z̃ = @views X̂0_Z̃[(1 + nx̂*(j-1)):(nx̂*(j-1) + nx)]
ŝdnext = @views geq[(1 + nx*(j-1)):(nx*(j-1) + nx)]
Expand All @@ -1423,7 +1423,7 @@ function con_nonlinprogeq!(
# last iteration (j-1) may not be executed (iterations are re-orderable)
model.f!(k̇1, x̂d_Z̃, û0, d̂0, model.p)
else
k̇1 .= @views K̇[(1 + nk*(j-1)-nx):(nk*(j-1))] # k2 of of the last iter. j-1
k̇1 .= @views K̇[(1 + nk̄*(j-1)-nx):(nk̄*(j-1))] # k2 of of the last iter. j-1
end
if h < 1
model.f!(k̇2, x̂dnext_Z̃, û0, d̂0next, model.p)
Expand Down Expand Up @@ -1478,9 +1478,9 @@ function con_nonlinprogeq!(
nΔU, nX̂ = nu*Hc, nx̂*Hp
f_threads = transcription.f_threads
Mo, no, τ = mpc.Mo, transcription.no, transcription.τ
nk = get_nk(model, transcription)
nk̄ = get_nk̄(model, transcription)
D̂0 = mpc.D̂0
X̂0_Z̃, K_Z̃ = @views Z̃[(nΔU+1):(nΔU+nX̂)], Z̃[(nΔU+nX̂+1):(nΔU+nX̂+nk*Hp)]
X̂0_Z̃, K_Z̃ = @views Z̃[(nΔU+1):(nΔU+nX̂)], Z̃[(nΔU+nX̂+1):(nΔU+nX̂+nk̄*Hp)]
D̂temp = mpc.buffer.D̂
Û0 = disturbedinput!(Û0, mpc.estim, mpc.estim.x̂0, X̂0_Z̃, U0)
@threadsif f_threads for j=1:Hp
Expand All @@ -1492,23 +1492,23 @@ function con_nonlinprogeq!(
d̂0 = @views D̂0[(1 + nd*(j-2)):(nd*(j-1))]
end
û0 = @views Û0[(1 + nu*(j-1)):(nu*j)]
= @views K̇[(1 + nk*(j-1)):(nk*j)]
k_Z̃ = @views K_Z̃[(1 + nk*(j-1)):(nk*j)]
k̄dot = @views K̇[(1 + nk̄*(j-1)):(nk̄*j)]
k̄_Z̃ = @views K_Z̃[(1 + nk̄*(j-1)):(nk̄*j)]
d̂0next = @views D̂0[(1 + nd*(j-1)):(nd*j)]
ŝk = @views geq[(1 + nk*(j-1)):(nk*j)]
ŝk = @views geq[(1 + nk̄*(j-1)):(nk̄*j)]
# ----------------- collocation constraint defects -----------------------------
Δk =
Δk = k̄dot
for i=1:no
Δk[(1 + (i-1)*nx):(i*nx)] = @views k_Z̃[(1 + (i-1)*nx):(i*nx)] .- x̂d_Z̃
Δk[(1 + (i-1)*nx):(i*nx)] = @views k̄_Z̃[(1 + (i-1)*nx):(i*nx)] .- x̂d_Z̃
end
mul!(ŝk, Mo, Δk)
d̂i = @views D̂temp[(1 + nd*(j-1)):(nd*j)]
if h > 0
ûi = similar(û0) # TODO: remove this allocation
end
for i=1:no
k̇i = @views [(1 + (i-1)*nx):(i*nx)]
ki_Z̃ = @views k_Z̃[(1 + (i-1)*nx):(i*nx)]
k̇i = @views k̄dot[(1 + (i-1)*nx):(i*nx)]
ki_Z̃ = @views k̄_Z̃[(1 + (i-1)*nx):(i*nx)]
d̂i .= (1-τ[i]).*d̂0 .+ τ[i].*d̂0next
if h < 1
model.f!(k̇i, ki_Z̃, û0, d̂i, model.p)
Expand All @@ -1519,7 +1519,7 @@ function con_nonlinprogeq!(
model.f!(k̇i, ki_Z̃, ûi, d̂i, model.p)
end
end
ŝk .-=
ŝk .-= k̄dot
end
return geq
end
Expand Down
12 changes: 6 additions & 6 deletions src/estimator/construct.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
struct StateEstimatorBuffer{NT<:Real}
u ::Vector{NT}
û ::Vector{NT}
k ::Vector{NT}
::Vector{NT}
x̂ ::Vector{NT}
Z̃ ::Vector{NT}
V̂ ::Vector{NT}
Expand All @@ -21,7 +21,7 @@ end

@doc raw"""
StateEstimatorBuffer{NT}(
nu::Int, nx̂::Int, nym::Int, ny::Int, nd::Int, nk::Int=0
nu::Int, nx̂::Int, nym::Int, ny::Int, nd::Int, nk̄::Int=0
He::Int=0, nŵ::Int=nx̂, nε::Int=0,
transcription::TranscriptionMethod = SingleShooting()
)
Expand All @@ -31,15 +31,15 @@ Create a buffer for `StateEstimator` objects for estimated states and measured o
The buffer is used to store intermediate results during estimation without allocating.
"""
function StateEstimatorBuffer{NT}(
nu::Int, nx̂::Int, nym::Int, ny::Int, nd::Int, nk::Int=0,
nu::Int, nx̂::Int, nym::Int, ny::Int, nd::Int, nk̄::Int=0,
He::Int=0, nŵ::Int=nx̂, nε::Int=0,
transcription::TranscriptionMethod = SingleShooting()
) where NT <: Real
nZ̃ = nε + get_nZ_mhe(transcription, He, nx̂, nk, nŵ)
nZ̃ = nε + get_nZ_mhe(transcription, He, nx̂, nk̄, nŵ)
nV̂, nŴ, nX̂, nŶ, nD = nym*He, nŵ*He, nx̂*He, ny*He, nd*(He+1)
u = Vector{NT}(undef, nu)
û = Vector{NT}(undef, nu)
k = Vector{NT}(undef, nk)
= Vector{NT}(undef, nk̄)
x̂ = Vector{NT}(undef, nx̂)
Z̃ = Vector{NT}(undef, nZ̃)
V̂ = Vector{NT}(undef, nV̂)
Expand All @@ -56,7 +56,7 @@ function StateEstimatorBuffer{NT}(
d = Vector{NT}(undef, nd)
empty = Vector{NT}(undef, 0)
return StateEstimatorBuffer{NT}(
u, û, k, x̂, Z̃, V̂, Ŵ, X̂, Ŷ, D, P̂, Q̂, R̂, K̂, ym, ŷ, d, empty
u, û, , x̂, Z̃, V̂, Ŵ, X̂, Ŷ, D, P̂, Q̂, R̂, K̂, ym, ŷ, d, empty
)
end

Expand Down
8 changes: 4 additions & 4 deletions src/estimator/internal_model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ struct InternalModel{NT<:Real, SM<:SimModel} <: StateEstimator{NT}
function InternalModel{NT}(
model::SM, i_ym, Asm, Bsm, Csm, Dsm
) where {NT<:Real, SM<:SimModel}
nu, ny, nd, nk = model.nu, model.ny, model.nd, model.nk
nu, ny, nd, nk̄ = model.nu, model.ny, model.nd, model.nk̄
nym, nyu = validate_ym(model, i_ym)
validate_internalmodel(model, nym, Csm, Dsm)
As, Bs, Cs, Ds = stoch_ym2y(model, i_ym, Asm, Bsm, Csm, Dsm)
Expand All @@ -46,7 +46,7 @@ struct InternalModel{NT<:Real, SM<:SimModel} <: StateEstimator{NT}
ŷs = zeros(NT, ny)
direct = true # InternalModel always uses direct transmission from ym
prepared = [false]
buffer = StateEstimatorBuffer{NT}(nu, nx̂, nym, ny, nd, nk)
buffer = StateEstimatorBuffer{NT}(nu, nx̂, nym, ny, nd, nk̄)
return new{NT, SM}(
model,
x̂op, f̂op, x̂0, x̂d, x̂s, ŷs, x̂snext,
Expand Down Expand Up @@ -302,8 +302,8 @@ function update_estimate!(estim::InternalModel, u0, _ , d0)
model = estim.model
x̂d, x̂s, ŷs = estim.x̂d, estim.x̂s, estim.ŷs
# -------------- deterministic model ---------------------
x̂dnext, û0, k = estim.buffer.x̂, estim.buffer.û, estim.buffer.k
f̂!(x̂dnext, û0, k, estim, estim.model, x̂d, u0, d0)
x̂dnext, û0, = estim.buffer.x̂, estim.buffer.û, estim.buffer.
f̂!(x̂dnext, û0, , estim, estim.model, x̂d, u0, d0)
x̂d .= x̂dnext # this also updates estim.x̂0 (they are the same object)
# --------------- stochastic model -----------------------
x̂snext = estim.x̂snext
Expand Down
Loading
Loading