1
- struct SteadyKalmanFilter{NT<: Real , SM<: LinModel } <: StateEstimator{NT}
1
+ struct SteadyKalmanFilter{
2
+ NT<: Real ,
3
+ SM<: LinModel ,
4
+ KC<: KalmanCovariances
5
+ } <: StateEstimator{NT}
2
6
model:: SM
7
+ cov :: KC
3
8
x̂op :: Vector{NT}
4
9
f̂op :: Vector{NT}
5
10
x̂0 :: Vector{NT}
@@ -20,23 +25,21 @@ struct SteadyKalmanFilter{NT<:Real, SM<:LinModel} <: StateEstimator{NT}
20
25
D̂d :: Matrix{NT}
21
26
Ĉm :: Matrix{NT}
22
27
D̂dm :: Matrix{NT}
23
- Q̂:: Hermitian{NT, Matrix{NT}}
24
- R̂:: Hermitian{NT, Matrix{NT}}
25
28
K̂:: Matrix{NT}
26
29
direct:: Bool
27
30
corrected:: Vector{Bool}
28
31
buffer:: StateEstimatorBuffer{NT}
29
32
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 }
32
35
nu, ny, nd, nk = model. nu, model. ny, model. nd, model. nk
33
36
nym, nyu = validate_ym (model, i_ym)
34
37
As, Cs_u, Cs_y, nint_u, nint_ym = init_estimstoch (model, i_ym, nint_u, nint_ym)
35
38
nxs = size (As, 1 )
36
39
nx̂ = model. nx + nxs
37
40
Â, B̂u, Ĉ, B̂d, D̂d, x̂op, f̂op = augment_model (model, As, Cs_u, Cs_y)
38
41
Ĉm, D̂dm = Ĉ[i_ym, :], D̂d[i_ym, :]
39
- validate_kfcov (nym, nx̂, Q̂, R̂)
42
+ R̂, Q̂ = cov . R̂, cov . Q̂
40
43
if ny == nym
41
44
R̂_y = R̂
42
45
else
@@ -56,16 +59,15 @@ struct SteadyKalmanFilter{NT<:Real, SM<:LinModel} <: StateEstimator{NT}
56
59
end
57
60
end
58
61
x̂0 = [zeros (NT, model. nx); zeros (NT, nxs)]
59
- Q̂, R̂ = Hermitian (Q̂, :L ), Hermitian (R̂, :L )
60
62
corrected = [false ]
61
63
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,
64
67
x̂op, f̂op, x̂0,
65
68
i_ym, nx̂, nym, nyu, nxs,
66
69
As, Cs_u, Cs_y, nint_u, nint_ym,
67
70
Â, B̂u, Ĉ, B̂d, D̂d, Ĉm, D̂dm,
68
- Q̂, R̂,
69
71
K̂,
70
72
direct, corrected,
71
73
buffer
@@ -184,9 +186,9 @@ function SteadyKalmanFilter(
184
186
σQint_ym = sigmaQint_ym,
185
187
) where {NT<: Real , SM<: LinModel{NT} }
186
188
# 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)
190
192
end
191
193
192
194
@doc raw """
@@ -200,7 +202,8 @@ function SteadyKalmanFilter(
200
202
model:: SM , i_ym, nint_u, nint_ym, Q̂, R̂; direct= true
201
203
) where {NT<: Real , SM<: LinModel{NT} }
202
204
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)
204
207
end
205
208
206
209
" 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)
281
284
return nothing
282
285
end
283
286
284
- struct KalmanFilter{NT<: Real , SM<: LinModel } <: StateEstimator{NT}
287
+ struct KalmanFilter{
288
+ NT<: Real ,
289
+ SM<: LinModel ,
290
+ KC<: KalmanCovariances
291
+ } <: StateEstimator{NT}
285
292
model:: SM
293
+ cov :: KC
286
294
x̂op:: Vector{NT}
287
295
f̂op:: Vector{NT}
288
296
x̂0 :: Vector{NT}
289
- P̂:: Hermitian{NT, Matrix{NT}}
290
297
i_ym:: Vector{Int}
291
298
nx̂ :: Int
292
299
nym:: Int
@@ -304,38 +311,31 @@ struct KalmanFilter{NT<:Real, SM<:LinModel} <: StateEstimator{NT}
304
311
D̂d :: Matrix{NT}
305
312
Ĉm :: Matrix{NT}
306
313
D̂dm :: Matrix{NT}
307
- P̂_0:: Hermitian{NT, Matrix{NT}}
308
- Q̂:: Hermitian{NT, Matrix{NT}}
309
- R̂:: Hermitian{NT, Matrix{NT}}
310
314
K̂:: Matrix{NT}
311
315
direct:: Bool
312
316
corrected:: Vector{Bool}
313
317
buffer:: StateEstimatorBuffer{NT}
314
318
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 }
317
321
nu, ny, nd, nk = model. nu, model. ny, model. nd, model. nk
318
322
nym, nyu = validate_ym (model, i_ym)
319
323
As, Cs_u, Cs_y, nint_u, nint_ym = init_estimstoch (model, i_ym, nint_u, nint_ym)
320
324
nxs = size (As, 1 )
321
325
nx̂ = model. nx + nxs
322
326
Â, B̂u, Ĉ, B̂d, D̂d, x̂op, f̂op = augment_model (model, As, Cs_u, Cs_y)
323
327
Ĉm, D̂dm = Ĉ[i_ym, :], D̂d[i_ym, :]
324
- validate_kfcov (nym, nx̂, Q̂, R̂, P̂_0)
325
328
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
329
329
K̂ = zeros (NT, nx̂, nym)
330
330
corrected = [false ]
331
331
buffer = StateEstimatorBuffer {NT} (nu, nx̂, nym, ny, nd, nk)
332
- return new {NT, SM} (
332
+ return new {NT, SM, KC } (
333
333
model,
334
- x̂op, f̂op, x̂0, P̂,
334
+ cov,
335
+ x̂op, f̂op, x̂0,
335
336
i_ym, nx̂, nym, nyu, nxs,
336
337
As, Cs_u, Cs_y, nint_u, nint_ym,
337
338
Â, B̂u, Ĉ, B̂d, D̂d, Ĉm, D̂dm,
338
- P̂_0, Q̂, R̂,
339
339
K̂,
340
340
direct, corrected,
341
341
buffer
@@ -419,10 +419,10 @@ function KalmanFilter(
419
419
σQint_ym = sigmaQint_ym,
420
420
) where {NT<: Real , SM<: LinModel{NT} }
421
421
# 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)
426
426
end
427
427
428
428
@doc raw """
@@ -436,7 +436,8 @@ function KalmanFilter(
436
436
model:: SM , i_ym, nint_u, nint_ym, P̂_0, Q̂, R̂; direct= true
437
437
) where {NT<: Real , SM<: LinModel{NT} }
438
438
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)
440
441
end
441
442
442
443
@doc raw """
@@ -1177,24 +1178,6 @@ function init_estimate_cov!(
1177
1178
return nothing
1178
1179
end
1179
1180
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
-
1198
1181
"""
1199
1182
correct_estimate_kf!(estim::Union{KalmanFilter, ExtendedKalmanFilter}, y0m, d0, Ĉm)
1200
1183
0 commit comments