Skip to content

Commit 69ae28d

Browse files
committed
Added AxialKalmanFilter
1 parent faf8e3d commit 69ae28d

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import numpy as np
2+
from pyrecest.distributions import GaussianDistribution
3+
from beartype import beartype
4+
from pyrecest.filters.abstract_axial_filter import AbstractAxialFilter
5+
6+
class AxialKalmanFilter(AbstractAxialFilter):
7+
def __init__(self, initial_state=None):
8+
if initial_state is None:
9+
initial_state = GaussianDistribution(np.array([1, 0, 0, 0]), np.eye(4, 4))
10+
self.filter_state = initial_state
11+
12+
@property
13+
def filter_state(self):
14+
return self._filter_state
15+
16+
@filter_state.setter
17+
@beartype
18+
def filter_state(self, new_state: GaussianDistribution):
19+
assert new_state.mu.shape == (2,) or new_state.mu.shape == (4,), "mu must be a 2d or 4d vector"
20+
assert abs(np.linalg.norm(new_state.mu) - 1) < 1e-5, "mean must be a unit vector"
21+
self._filter_state = new_state
22+
# TODO: define composition operator
23+
24+
@beartype
25+
def predict_identity(self, gauss_w: GaussianDistribution):
26+
assert abs(np.linalg.norm(gauss_w.mu) - 1) < 1e-5, "mean must be a unit vector"
27+
mu_ = self.composition_operator(self.gauss.mu, gauss_w.mu)
28+
C_ = self.gauss.C + gauss_w.C
29+
self.filter_state = GaussianDistribution(mu_, C_)
30+
31+
@beartype
32+
def update_identity(self, gauss_v: GaussianDistribution, z: np.ndarray):
33+
assert abs(np.linalg.norm(gauss_v.mu) - 1) < 1e-5, "mean must be a unit vector"
34+
assert gauss_v.mu.shape[0] == self.gauss.mu.shape[0]
35+
assert np.shape(z) == np.shape(self.gauss.mu)
36+
assert abs(np.linalg.norm(z) - 1) < 1e-5, "measurement must be a unit vector"
37+
38+
mu_v_conj = np.concatenate(([gauss_v.mu[0]], -gauss_v.mu[1:]))
39+
z = self.composition_operator(mu_v_conj, z)
40+
41+
if np.dot(z, self.gauss.mu) < 0:
42+
z = -z
43+
44+
d = self.dim
45+
H = np.eye(d, d)
46+
IS = H @ self.filter_state.C @ H.T + gauss_v.C
47+
K = self.filter_state.C @ H.T @ np.linalg.inv(IS)
48+
IM = z - H @ self.filter_state.mu
49+
mu = self.filter_state.mu + K @ IM
50+
C = (np.eye(d, d) - K @ H) @ self.filter_state.C
51+
52+
mu = mu / np.linalg.norm(mu)
53+
self.filter_state = GaussianDistribution(mu, C)
54+

0 commit comments

Comments
 (0)