Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
96130 views
1
# -*- coding: utf-8 -*-
2
"""
3
Spyder Editor
4
5
This is a temporary script file.
6
"""
7
8
from KalmanFilter import *
9
from math import cos, sin, sqrt, atan2
10
11
12
def H_of (pos, pos_A, pos_B):
13
""" Given the position of our object at 'pos' in 2D, and two transmitters
14
A and B at positions 'pos_A' and 'pos_B', return the partial derivative
15
of H
16
"""
17
18
theta_a = atan2(pos_a[1]-pos[1], pos_a[0] - pos[0])
19
theta_b = atan2(pos_b[1]-pos[1], pos_b[0] - pos[0])
20
21
if False:
22
return np.mat([[0, -cos(theta_a), 0, -sin(theta_a)],
23
[0, -cos(theta_b), 0, -sin(theta_b)]])
24
else:
25
return np.mat([[-cos(theta_a), 0, -sin(theta_a), 0],
26
[-cos(theta_b), 0, -sin(theta_b), 0]])
27
28
class DMESensor(object):
29
def __init__(self, pos_a, pos_b, noise_factor=1.0):
30
self.A = pos_a
31
self.B = pos_b
32
self.noise_factor = noise_factor
33
34
def range_of (self, pos):
35
""" returns tuple containing noisy range data to A and B
36
given a position 'pos'
37
"""
38
39
ra = sqrt((self.A[0] - pos[0])**2 + (self.A[1] - pos[1])**2)
40
rb = sqrt((self.B[0] - pos[0])**2 + (self.B[1] - pos[1])**2)
41
42
return (ra + random.randn()*self.noise_factor,
43
rb + random.randn()*self.noise_factor)
44
45
46
pos_a = (100,-20)
47
pos_b = (-100, -20)
48
49
f1 = KalmanFilter(dim_x=4, dim_z=2)
50
51
f1.F = np.mat ([[0, 1, 0, 0],
52
[0, 0, 0, 0],
53
[0, 0, 0, 1],
54
[0, 0, 0, 0]])
55
56
f1.B = 0.
57
58
f1.R *= 1.
59
f1.Q *= .1
60
61
f1.x = np.mat([1,0,1,0]).T
62
f1.P = np.eye(4) * 5.
63
64
# initialize storage and other variables for the run
65
count = 30
66
xs, ys = [],[]
67
pxs, pys = [],[]
68
69
# create the simulated sensor
70
d = DMESensor (pos_a, pos_b, noise_factor=1.)
71
72
# pos will contain our nominal position since the filter does not
73
# maintain position.
74
pos = [0,0]
75
76
for i in range(count):
77
# move (1,1) each step, so just use i
78
pos = [i,i]
79
80
# compute the difference in range between the nominal track and measured
81
# ranges
82
ra,rb = d.range_of(pos)
83
rx,ry = d.range_of((i+f1.x[0,0], i+f1.x[2,0]))
84
85
print ra, rb
86
print rx,ry
87
z = np.mat([[ra-rx],[rb-ry]])
88
print z.T
89
90
# compute linearized H for this time step
91
f1.H = H_of (pos, pos_a, pos_b)
92
93
# store stuff so we can plot it later
94
xs.append (f1.x[0,0]+i)
95
ys.append (f1.x[2,0]+i)
96
pxs.append (pos[0])
97
pys.append(pos[1])
98
99
# perform the Kalman filter steps
100
f1.predict ()
101
f1.update(z)
102
103
104
p1, = plt.plot (xs, ys, 'r--')
105
p2, = plt.plot (pxs, pys)
106
plt.legend([p1,p2], ['filter', 'ideal'], 2)
107
plt.show()
108
109
110