Skip to content

Commit 7457a9c

Browse files
committed
added : reduce allocations in MovingHorizoneEstimator
1 parent e9597f6 commit 7457a9c

3 files changed

Lines changed: 25 additions & 15 deletions

File tree

src/estimator/construct.jl

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
struct StateEstimatorBuffer{NT<:Real}
22
u ::Vector{NT}
33
::Vector{NT}
4-
k::Vector{NT}
4+
k ::Vector{NT}
55
::Vector{NT}
6+
::Vector{NT}
7+
::Vector{NT}
8+
::Vector{NT}
69
::Matrix{NT}
710
::Matrix{NT}
811
::Matrix{NT}
@@ -21,12 +24,19 @@ Create a buffer for `StateEstimator` objects for estimated states and measured o
2124
The buffer is used to store intermediate results during estimation without allocating.
2225
"""
2326
function StateEstimatorBuffer{NT}(
24-
nu::Int, nx̂::Int, nym::Int, ny::Int, nd::Int, nk::Int=0
27+
nu::Int, nx̂::Int, nym::Int, ny::Int, nd::Int, nk::Int=0, He::Int=0, nε::Int=0
2528
) where NT <: Real
29+
nŵ = nx̂
30+
nZ̃ = nx̂ + nŵ*He +
31+
nV̂ = nym*He
32+
nX̂ = nx̂*He
2633
u = Vector{NT}(undef, nu)
2734
= Vector{NT}(undef, nu)
2835
k = Vector{NT}(undef, nk)
2936
= Vector{NT}(undef, nx̂)
37+
= Vector{NT}(undef, nZ̃)
38+
= Vector{NT}(undef, nV̂)
39+
= Vector{NT}(undef, nX̂)
3040
= Matrix{NT}(undef, nx̂, nx̂)
3141
= Matrix{NT}(undef, nx̂, nx̂)
3242
= Matrix{NT}(undef, nym, nym)
@@ -35,7 +45,7 @@ function StateEstimatorBuffer{NT}(
3545
= Vector{NT}(undef, ny)
3646
d = Vector{NT}(undef, nd)
3747
empty = Vector{NT}(undef, 0)
38-
return StateEstimatorBuffer{NT}(u, û, k, x̂, P̂, Q̂, R̂, K̂, ym, ŷ, d, empty)
48+
return StateEstimatorBuffer{NT}(u, û, k, x̂, Z̃, V̂, X̂, P̂, Q̂, R̂, K̂, ym, ŷ, d, empty)
3949
end
4050

4151
"Include all the covariance matrices for the Kalman filters and moving horizon estimator."

src/estimator/mhe/construct.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ struct MovingHorizonEstimator{
160160
nD0 = direct ? nd*(He+1) : nd*He
161161
U0, D0 = zeros(NT, nu*He), zeros(NT, nD0)
162162
= zeros(NT, nx̂*He)
163-
buffer = StateEstimatorBuffer{NT}(nu, nx̂, nym, ny, nd, nk)
163+
buffer = StateEstimatorBuffer{NT}(nu, nx̂, nym, ny, nd, nk, He, nε)
164164
x̂0arr_old = zeros(NT, nx̂)
165165
P̂arr_old = copy(cov.P̂_0)
166166
Nk = [0]

src/estimator/mhe/execute.jl

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -490,12 +490,10 @@ If first warm-starts the solver with [`set_warmstart_mhe!`](@ref). It then calls
490490
"""
491491
function optim_objective!(estim::MovingHorizonEstimator{NT}) where NT<:Real
492492
model, optim, buffer = estim.model, estim.optim, estim.buffer
493-
nym, nx̂, nŵ, nε, Nk = estim.nym, estim.nx̂, estim.nx̂, estim., estim.Nk[]
494-
nx̃ =+ nx̂
493+
nŵ, nx̂, Nk = estim.nx̂, estim.nx̂, estim.Nk[]
494+
nx̃ = estim.+ nx̂
495495
Z̃var::Vector{JuMP.VariableRef} = optim[:Z̃var]
496-
= Vector{NT}(undef, nym*Nk) # TODO: remove this allocation
497-
X̂0 = Vector{NT}(undef, nx̂*Nk) # TODO: remove this allocation
498-
Z̃s = set_warmstart_mhe!(V̂, X̂0, estim, Z̃var)
496+
Z̃s = set_warmstart_mhe(estim, Z̃var)
499497
# ------- solve optimization problem --------------
500498
try
501499
JuMP.optimize!(optim)
@@ -534,14 +532,15 @@ function optim_objective!(estim::MovingHorizonEstimator{NT}) where NT<:Real
534532
# --------- update estimate -----------------------
535533
û0, ŷ0, k = buffer.û, buffer.ŷ, buffer.k
536534
estim.Ŵ[1:nŵ*Nk] .= @views estim.Z̃[nx̃+1:nx̃+nŵ*Nk] # update Ŵ with optimum for warm-start
537-
V̂, X̂0 = predict_mhe!(V̂, X̂0, û0, k, ŷ0, estim, model, estim.Z̃)
538-
x̂0next = @views X̂0[end-nx̂+1:end]
535+
V̂, X̂0 = estim.buffer.V̂, estim.buffer.
536+
predict_mhe!(V̂, X̂0, û0, k, ŷ0, estim, model, estim.Z̃)
537+
x̂0next = @views X̂0[Nk*nx̂-nx̂+1:Nk*nx̂]
539538
estim.x̂0 .= x̂0next
540539
return estim.
541540
end
542541

543542
@doc raw"""
544-
set_warmstart_mhe!(V̂, X̂0, estim::MovingHorizonEstimator, Z̃var) -> Z̃s
543+
set_warmstart_mhe(estim::MovingHorizonEstimator, Z̃var) -> Z̃s
545544
546545
Set and return the warm-start value of `Z̃var` for [`MovingHorizonEstimator`](@ref).
547546
@@ -564,11 +563,11 @@ computed at the last time step ``k-1``. If the objective function is not finite
564563
point, all the process noises ``\mathbf{ŵ}_{k-1}(k-j)`` are warm-started at zeros. The
565564
method mutates all the arguments.
566565
"""
567-
function set_warmstart_mhe!(V̂, X̂0, estim::MovingHorizonEstimator{NT}, Z̃var) where NT<:Real
566+
function set_warmstart_mhe(estim::MovingHorizonEstimator{NT}, Z̃var) where NT<:Real
568567
model, buffer = estim.model, estim.buffer
569-
nε, nx̂, nŵ, nZ̃, Nk = estim.nε, estim.nx̂, estim.nx̂, length(estim.Z̃), estim.Nk[]
568+
nε, nx̂, nŵ, Nk = estim.nε, estim.nx̂, estim.nx̂, estim.Nk[]
570569
nx̃ =+ nx̂
571-
Z̃s = Vector{NT}(undef, nZ̃) # TODO: remove this allocation
570+
Z̃s = estim.buffer.
572571
û0, ŷ0, x̄, k = buffer.û, buffer.ŷ, buffer.x̂, buffer.k
573572
# --- slack variable ε ---
574573
estim.== 1 && (Z̃s[begin] = estim.Z̃[begin])
@@ -577,6 +576,7 @@ function set_warmstart_mhe!(V̂, X̂0, estim::MovingHorizonEstimator{NT}, Z̃var
577576
# --- process noise estimates Ŵ ---
578577
Z̃s[nx̃+1:end] = estim.
579578
# verify definiteness of objective function:
579+
V̂, X̂0 = estim.buffer.V̂, estim.buffer.
580580
V̂, X̂0 = predict_mhe!(V̂, X̂0, û0, k, ŷ0, estim, model, Z̃s)
581581
Js = obj_nonlinprog!(x̄, estim, model, V̂, Z̃s)
582582
if !isfinite(Js)

0 commit comments

Comments
 (0)