Skip to content

Commit 316bebb

Browse files
author
AshleySetter
committed
added python kalman filter and added timing into Use example along with plotting
1 parent 05a30d9 commit 316bebb

2 files changed

Lines changed: 65 additions & 1 deletion

File tree

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import numpy as np
2+
3+
# Implements a linear Kalman filter.
4+
class KalmanFilterLinear:
5+
def __init__(self,_A, _B, _H, _x, _P, _Q, _R):
6+
self.A = _A # State transition matrix.
7+
self.B = _B # Control-input matrix.
8+
self.H = _H # Observation model matrix.
9+
self.current_state_estimate = _x # Initial state estimate.
10+
self.current_prob_estimate = _P # Initial covariance estimate.
11+
self.Q = _Q # Estimated error in process.
12+
self.R = _R # Estimated error in measurements.
13+
self.KG = None
14+
def GetCurrentState(self):
15+
return self.current_state_estimate
16+
def Step(self,control_vector,measurement_vector):
17+
#---------------------------Prediction step-----------------------------
18+
predicted_state_estimate = self.A * self.current_state_estimate + self.B * control_vector
19+
20+
predicted_prob_estimate = (self.A * self.current_prob_estimate) * np.transpose(self.A) + self.Q
21+
#--------------------------Observation step-----------------------------
22+
innovation = measurement_vector - self.H*predicted_state_estimate
23+
self.Innovation = innovation[0, 0]
24+
innovation_covariance = self.H*predicted_prob_estimate*np.transpose(self.H) + self.R
25+
#-----------------------------Update step-------------------------------
26+
kalman_gain = predicted_prob_estimate * np.transpose(self.H) * np.linalg.inv(innovation_covariance)
27+
self.KG = kalman_gain
28+
self.current_state_estimate = predicted_state_estimate + kalman_gain * innovation
29+
# We need the size of the matrix so we can make an identity matrix.
30+
size = self.current_prob_estimate.shape[0]
31+
# eye(n) = nxn identity matrix.
32+
self.current_prob_estimate = (np.eye(size)-kalman_gain*self.H)*predicted_prob_estimate

‎KalmanFilterC/UseKalmanFilterCython.py‎

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import numpy as np
22
import sympy
33
import matplotlib.pyplot as plt
4+
import timeit
45

56
import KalmanFilter
7+
import KalmanFilterPurePython
68

9+
# Calculate parameters for Kalman filter
710
t = sympy.symbols('t', real = True, positive=True)
811
s = sympy.symbols('s', real = True, positive=True)
912
w = sympy.symbols('w', real = True, positive=True)
@@ -31,7 +34,8 @@ def TransformSystemsDynamicsMatrix(F):
3134
class data:
3235
pass
3336

34-
data.time = np.arange(0, 10*2*np.pi/w, Ts)
37+
data.time = np.arange(0, 100*2*np.pi/w, Ts) # 100 periods of oscillation
38+
print("{} Points to be filtered".format(len(data.time)))
3539
noiseAmp = 5
3640
data.trueSignal = 300 + 5*np.sin(w*data.time + 0)
3741
data.signal = data.trueSignal + np.random.normal(0, noiseAmp, len(data.trueSignal))
@@ -59,12 +63,40 @@ class data:
5963

6064
print("Executing Filtering")
6165

66+
start_time = timeit.default_timer()
6267
ResultData = kf.FilterData(data.signal, len(data.signal))
68+
elapsed = timeit.default_timer() - start_time
69+
print("C++ filtering took {}s".format(elapsed))
6370

71+
print("Constructing Python Filter")
72+
73+
KF2 = KalmanFilterPurePython.KalmanFilterLinear(A, B, H, x_init, P, Q, R)
74+
75+
print("Executing Python Filtering")
76+
77+
start_time = timeit.default_timer()
78+
KalmanPredictionArray = []
79+
KalmanErrorArray = []
80+
KalmanGainArray = []
81+
for i, x in enumerate(data.signal):
82+
X_state = np.matrix('{0} ; {1}'.format(x, 0))
83+
KF2.Step(np.matrix([0]), np.matrix([x]))
84+
KalmanPredictionArray.append(KF2.current_state_estimate)
85+
KalmanErrorArray.append(KF2.current_prob_estimate)
86+
KalmanGainArray.append(KF2.KG)
87+
88+
KalmanPredictionArray = np.array(KalmanPredictionArray)
89+
KalmanErrorArray = np.array(KalmanErrorArray)
90+
KalmanGainArray = np.array(KalmanGainArray)
91+
92+
x = KalmanPredictionArray[:, 0] + KalmanPredictionArray[:, 2]
93+
elapsed = timeit.default_timer() - start_time
94+
print("C++ filtering took {}s".format(elapsed))
6495

6596
plt.figure(figsize=[10, 10])
6697
plt.plot(data.time, data.signal, label="noisy sine wave", color='blue', alpha=0.6)
6798
plt.plot(data.time, data.trueSignal, label="pure source sine wave", lw=3, color='red', alpha=0.8)
99+
plt.plot(data.time, x, label="Pure Python Kalman Filter Output", lw=3, color='darkblue', alpha=0.9)
68100
plt.plot(data.time, ResultData, label="C++ Kalman Filter Output", lw=3, color='darkred', alpha=0.9)
69101

70102
plt.legend(loc="best")

0 commit comments

Comments
 (0)