1- struct SteadyKalmanFilter{NT<: Real , SM<: LinModel } <: StateEstimator{NT}
1+ struct SteadyKalmanFilter{
2+ NT<: Real ,
3+ SM<: LinModel ,
4+ KC<: KalmanCovariances
5+ } <: StateEstimator{NT}
26 model:: SM
7+ cov :: KC
38 x̂op :: Vector{NT}
49 f̂op :: Vector{NT}
510 x̂0 :: Vector{NT}
@@ -20,23 +25,21 @@ struct SteadyKalmanFilter{NT<:Real, SM<:LinModel} <: StateEstimator{NT}
2025 D̂d :: Matrix{NT}
2126 Ĉm :: Matrix{NT}
2227 D̂dm :: Matrix{NT}
23- Q̂:: Hermitian{NT, Matrix{NT}}
24- R̂:: Hermitian{NT, Matrix{NT}}
2528 K̂:: Matrix{NT}
2629 direct:: Bool
2730 corrected:: Vector{Bool}
2831 buffer:: StateEstimatorBuffer{NT}
2932 function SteadyKalmanFilter {NT} (
30- model:: SM , i_ym, nint_u, nint_ym, Q̂, R̂ ; direct= true
31- ) where {NT<: Real , SM<: LinModel }
33+ model:: SM , i_ym, nint_u, nint_ym, cov :: KC ; direct= true
34+ ) where {NT<: Real , SM<: LinModel , KC <: KalmanCovariances }
3235 nu, ny, nd, nk = model. nu, model. ny, model. nd, model. nk
3336 nym, nyu = validate_ym (model, i_ym)
3437 As, Cs_u, Cs_y, nint_u, nint_ym = init_estimstoch (model, i_ym, nint_u, nint_ym)
3538 nxs = size (As, 1 )
3639 nx̂ = model. nx + nxs
3740 Â, B̂u, Ĉ, B̂d, D̂d, x̂op, f̂op = augment_model (model, As, Cs_u, Cs_y)
3841 Ĉm, D̂dm = Ĉ[i_ym, :], D̂d[i_ym, :]
39- validate_kfcov (nym, nx̂, Q̂, R̂)
42+ R̂, Q̂ = cov . R̂, cov . Q̂
4043 if ny == nym
4144 R̂_y = R̂
4245 else
@@ -56,16 +59,15 @@ struct SteadyKalmanFilter{NT<:Real, SM<:LinModel} <: StateEstimator{NT}
5659 end
5760 end
5861 x̂0 = [zeros (NT, model. nx); zeros (NT, nxs)]
59- Q̂, R̂ = Hermitian (Q̂, :L ), Hermitian (R̂, :L )
6062 corrected = [false ]
6163 buffer = StateEstimatorBuffer {NT} (nu, nx̂, nym, ny, nd, nk)
62- return new {NT, SM} (
63- model,
64+ return new {NT, SM, KC} (
65+ model,
66+ cov,
6467 x̂op, f̂op, x̂0,
6568 i_ym, nx̂, nym, nyu, nxs,
6669 As, Cs_u, Cs_y, nint_u, nint_ym,
6770 Â, B̂u, Ĉ, B̂d, D̂d, Ĉm, D̂dm,
68- Q̂, R̂,
6971 K̂,
7072 direct, corrected,
7173 buffer
@@ -184,9 +186,9 @@ function SteadyKalmanFilter(
184186 σQint_ym = sigmaQint_ym,
185187) where {NT<: Real , SM<: LinModel{NT} }
186188 # estimated covariances matrices (variance = σ²) :
187- Q̂ = Hermitian ( diagm (NT [σQ; σQint_u; σQint_ym ]. ^ 2 ), :L )
188- R̂ = Hermitian ( diagm (NT [σR;]. ^ 2 ), :L )
189- return SteadyKalmanFilter {NT} (model, i_ym, nint_u, nint_ym, Q̂, R̂; direct)
189+ Q̂ = Diagonal ( [σQ; σQint_u; σQint_ym]. ^ 2 )
190+ R̂ = Diagonal ( [σR;]. ^ 2 )
191+ return SteadyKalmanFilter (model, i_ym, nint_u, nint_ym, Q̂, R̂; direct)
190192end
191193
192194@doc raw """
@@ -200,7 +202,8 @@ function SteadyKalmanFilter(
200202 model:: SM , i_ym, nint_u, nint_ym, Q̂, R̂; direct= true
201203) where {NT<: Real , SM<: LinModel{NT} }
202204 Q̂, R̂ = to_mat (Q̂), to_mat (R̂)
203- return SteadyKalmanFilter {NT} (model, i_ym, nint_u, nint_ym, Q̂, R̂; direct)
205+ cov = KalmanCovariances (model, i_ym, nint_u, nint_ym, Q̂, R̂)
206+ return SteadyKalmanFilter {NT} (model, i_ym, nint_u, nint_ym, cov; direct)
204207end
205208
206209" Throw an error if `setmodel!` is called on a SteadyKalmanFilter w/o the default values."
@@ -281,12 +284,16 @@ function predict_estimate_obsv!(estim::StateEstimator, _ , d0, u0)
281284 return nothing
282285end
283286
284- struct KalmanFilter{NT<: Real , SM<: LinModel } <: StateEstimator{NT}
287+ struct KalmanFilter{
288+ NT<: Real ,
289+ SM<: LinModel ,
290+ KC<: KalmanCovariances
291+ } <: StateEstimator{NT}
285292 model:: SM
293+ cov :: KC
286294 x̂op:: Vector{NT}
287295 f̂op:: Vector{NT}
288296 x̂0 :: Vector{NT}
289- P̂:: Hermitian{NT, Matrix{NT}}
290297 i_ym:: Vector{Int}
291298 nx̂ :: Int
292299 nym:: Int
@@ -304,38 +311,31 @@ struct KalmanFilter{NT<:Real, SM<:LinModel} <: StateEstimator{NT}
304311 D̂d :: Matrix{NT}
305312 Ĉm :: Matrix{NT}
306313 D̂dm :: Matrix{NT}
307- P̂_0:: Hermitian{NT, Matrix{NT}}
308- Q̂:: Hermitian{NT, Matrix{NT}}
309- R̂:: Hermitian{NT, Matrix{NT}}
310314 K̂:: Matrix{NT}
311315 direct:: Bool
312316 corrected:: Vector{Bool}
313317 buffer:: StateEstimatorBuffer{NT}
314318 function KalmanFilter {NT} (
315- model:: SM , i_ym, nint_u, nint_ym, P̂_0, Q̂, R̂ ; direct= true
316- ) where {NT<: Real , SM<: LinModel }
319+ model:: SM , i_ym, nint_u, nint_ym, cov :: KC ; direct= true
320+ ) where {NT<: Real , SM<: LinModel , KC <: KalmanCovariances }
317321 nu, ny, nd, nk = model. nu, model. ny, model. nd, model. nk
318322 nym, nyu = validate_ym (model, i_ym)
319323 As, Cs_u, Cs_y, nint_u, nint_ym = init_estimstoch (model, i_ym, nint_u, nint_ym)
320324 nxs = size (As, 1 )
321325 nx̂ = model. nx + nxs
322326 Â, B̂u, Ĉ, B̂d, D̂d, x̂op, f̂op = augment_model (model, As, Cs_u, Cs_y)
323327 Ĉm, D̂dm = Ĉ[i_ym, :], D̂d[i_ym, :]
324- validate_kfcov (nym, nx̂, Q̂, R̂, P̂_0)
325328 x̂0 = [zeros (NT, model. nx); zeros (NT, nxs)]
326- Q̂, R̂ = Hermitian (Q̂, :L ), Hermitian (R̂, :L )
327- P̂_0 = Hermitian (P̂_0, :L )
328- P̂ = Hermitian (copy (P̂_0. data), :L ) # copy on P̂_0.data necessary for Julia Nightly
329329 K̂ = zeros (NT, nx̂, nym)
330330 corrected = [false ]
331331 buffer = StateEstimatorBuffer {NT} (nu, nx̂, nym, ny, nd, nk)
332- return new {NT, SM} (
332+ return new {NT, SM, KC } (
333333 model,
334- x̂op, f̂op, x̂0, P̂,
334+ cov,
335+ x̂op, f̂op, x̂0,
335336 i_ym, nx̂, nym, nyu, nxs,
336337 As, Cs_u, Cs_y, nint_u, nint_ym,
337338 Â, B̂u, Ĉ, B̂d, D̂d, Ĉm, D̂dm,
338- P̂_0, Q̂, R̂,
339339 K̂,
340340 direct, corrected,
341341 buffer
@@ -419,10 +419,10 @@ function KalmanFilter(
419419 σQint_ym = sigmaQint_ym,
420420) where {NT<: Real , SM<: LinModel{NT} }
421421 # estimated covariances matrices (variance = σ²) :
422- P̂_0 = Hermitian ( diagm (NT [σP_0; σPint_u_0; σPint_ym_0]. ^ 2 ), :L )
423- Q̂ = Hermitian ( diagm (NT [σQ; σQint_u; σQint_ym ]. ^ 2 ), :L )
424- R̂ = Hermitian ( diagm (NT [σR;]. ^ 2 ), :L )
425- return KalmanFilter {NT} (model, i_ym, nint_u, nint_ym, P̂_0, Q̂ , R̂; direct)
422+ P̂_0 = Diagonal ( [σP_0; σPint_u_0; σPint_ym_0]. ^ 2 )
423+ Q̂ = Diagonal ( [σQ; σQint_u; σQint_ym ]. ^ 2 )
424+ R̂ = Diagonal ( [σR;]. ^ 2 )
425+ return KalmanFilter (model, i_ym, nint_u, nint_ym, P̂_0, Q̂, R̂; direct)
426426end
427427
428428@doc raw """
@@ -436,7 +436,8 @@ function KalmanFilter(
436436 model:: SM , i_ym, nint_u, nint_ym, P̂_0, Q̂, R̂; direct= true
437437) where {NT<: Real , SM<: LinModel{NT} }
438438 P̂_0, Q̂, R̂ = to_mat (P̂_0), to_mat (Q̂), to_mat (R̂)
439- return KalmanFilter {NT} (model, i_ym, nint_u, nint_ym, P̂_0, Q̂, R̂; direct)
439+ cov = KalmanCovariances (model, i_ym, nint_u, nint_ym, Q̂, R̂, P̂_0)
440+ return KalmanFilter {NT} (model, i_ym, nint_u, nint_ym, cov; direct)
440441end
441442
442443@doc raw """
@@ -1177,24 +1178,6 @@ function init_estimate_cov!(
11771178 return nothing
11781179end
11791180
1180- """
1181- validate_kfcov(nym, nx̂, Q̂, R̂, P̂_0=nothing)
1182-
1183- Validate sizes and Hermitianity of process `Q̂`` and sensor `R̂` noises covariance matrices.
1184-
1185- Also validate initial estimate covariance `P̂_0`, if provided.
1186- """
1187- function validate_kfcov (nym, nx̂, Q̂, R̂, P̂_0= nothing )
1188- size (Q̂) ≠ (nx̂, nx̂) && error (" Q̂ size $(size (Q̂)) ≠ nx̂, nx̂ $((nx̂, nx̂)) " )
1189- ! ishermitian (Q̂) && error (" Q̂ is not Hermitian" )
1190- size (R̂) ≠ (nym, nym) && error (" R̂ size $(size (R̂)) ≠ nym, nym $((nym, nym)) " )
1191- ! ishermitian (R̂) && error (" R̂ is not Hermitian" )
1192- if ~ isnothing (P̂_0)
1193- size (P̂_0) ≠ (nx̂, nx̂) && error (" P̂_0 size $(size (P̂_0)) ≠ nx̂, nx̂ $((nx̂, nx̂)) " )
1194- ! ishermitian (P̂_0) && error (" P̂_0 is not Hermitian" )
1195- end
1196- end
1197-
11981181"""
11991182 correct_estimate_kf!(estim::Union{KalmanFilter, ExtendedKalmanFilter}, y0m, d0, Ĉm)
12001183
0 commit comments