-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLinearKalmanFilter.jl
120 lines (102 loc) · 3.53 KB
/
LinearKalmanFilter.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
struct LinearKF
xk::Vector
xp::Vector
P::AbstractMatrix
K::AbstractMatrix
S::AbstractMatrix
y::Vector
filter::SquareRootFilter
end
"""
sol = linear_kalman(
x, x₀, P, F, H, Q, R;
B=zeros(length(x), length(x)),
u=zeros(length(x)),
w=zeros(length(x)),
v=zeros(length(x)),
sqrt_filter=CholeskySqrt(),
)
Performs the simple Kalman filter algorithm for the estimation of a state x.
x: Vector with one measurement (observation) of m = length(x) variables
x₀: A priori estimation of the variables
P: Initial predicted process covariance matrix
F: Transition matrix (linear state model)
H: Measurement matrix (linear measurement model)
Q: Process noise covariance matrix
R: Measurement (observable) covariance matrix
B: Control-input matrix (linear state model)
u: Control vector (linear state model)
w: Process noise vector, w ~ N(0,Q)
v: Measurement (observable) noise vector, v ~ N(0,R)
sqrt_filter: Square root filtering technique for the covariance matrix.
Accepted values are: CholeskyModSqrt() (default), SVDSqrt(), CholeskySqrt()
sol: LinearKalman type
xk: Kalman filter state estimation
xp: Predicted state estimate
P: Process covariance matrix a posteriori
K: Kalman gain
S: Innovation (or pre-fit residual) covariance
y: Innovation or measurement pre-fit residual
filter: Type of SquareRootFilter selected
"""
function linear_kalman(
x::Vector,
x₀::Vector,
P::AbstractMatrix,
F::AbstractMatrix,
H::AbstractMatrix,
Q::AbstractMatrix,
R::AbstractMatrix;
B::AbstractMatrix=zeros(length(x), length(x)),
u::Union{Vector, Real}=zeros(length(x)),
w::Vector=zeros(length(x)),
v::Vector=zeros(length(x)),
sqrt_filter::SquareRootFilter=CholeskyModSqrt(),
)
m = length(x)
## Predict process
# State estimate propagation (Predicted state, a priori)
x̂ = _linear_state_model(x₀, F, B, u, w)
# Error covariance propagation (Predicted process covariance matrix, a priori)
P_ = _process_covariance_priori(P, F, Q)
# Innovation (or pre-fit residual) covariance
PHt = P_ * H'
S = _innovation_covariance(P_, PHt, H, R)
# Kalman gain
K = _kalman_gain(P_, PHt, S)
## Update process
# New observation (innovation process)
y = _linear_observation_model(x, H, v)
# Innovation or measurement pre-fit residual
y = muladd(-H, x̂, y)
# State estimate update (Current state, a posteriori)
xₖ = muladd(K, y, x̂)
# Error covariance update (Process covariance matrix, a posteriori)
P_ = _process_covariance_posteriori(P_, H, K, m)
return LinearKF(vec(xₖ), vec(x̂), P_, K, S, vec(y), sqrt_filter)
end
function _linear_state_model(
x::Vector, F::AbstractMatrix, B::AbstractMatrix, u::Union{Vector, Real}, w::Vector,
)
return vec(F*x .+ B .* u .+ w)
end
function _linear_observation_model(x::Vector, H::AbstractMatrix, v::Vector)
return vec(muladd(H, x, v))
end
function _process_covariance_priori(P::AbstractMatrix, F::AbstractMatrix, Q::AbstractMatrix)
return _return_type(P, F*P*F' .+ Q)
end
function _process_covariance_posteriori(
P::AbstractMatrix, H::AbstractMatrix, K::AbstractMatrix, m::Int64,
)
return _return_type(P, (eye(m) .- K*H) *P)
end
function _kalman_gain(P::AbstractMatrix, PHt::AbstractMatrix, S::AbstractMatrix)
F = qr(S)
return _return_type(P, F.R \ (F.Q' * PHt))
end
function _innovation_covariance(
P::AbstractMatrix, PHt::AbstractMatrix, H::AbstractMatrix, R::AbstractMatrix,
)
return _return_type(P, H*PHt .+ R)
end