-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
157 lines (105 loc) · 3.53 KB
/
main.py
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import sys
import math
import numpy as np
import plot
import matplotlib.pyplot as plt
import pyrealsense2 as rs
pipeline = rs.pipeline()
config = rs.config()
config.enable_stream(rs.stream.accel, rs.format.motion_xyz32f, 200)
config.enable_stream(rs.stream.gyro, rs.format.motion_xyz32f, 200)
pipeline.start(config)
"""
#variables for low pass filter
cutoff =
sig = np.sin(fs*2*np.pi*t)
fs =
order =
"""
#covariance matrix
Q = np.diag([1, #var(x)
1, #var(y)
1, #var(yaw)
])**2
R = np.diag([1,1,1])**2
#noise parameter
input_noise = np.diag([1.0,np.deg2rad(5)])**2
#measurement matrix
H = np.diag([0.001,0.001,0.001])**2
dt = 0.1 # time-step
show_animation = True
def observation(xTrue, u):
xTrue = state_model(xTrue, u)
#adding noise to input
ud = u + input_noise @ np.random.randn(2,1)
return xTrue, ud
def state_model(x, u):
A = np.diag([1,1,1])**2
B = np.array([[dt * math.cos(x[2,0]), 0],
[dt * math.sin(x[2,0]), 0],
[0, dt]])
x = A @ x + B @ u
return x
def observation_model(x):
z = H @ x
return z
def ekf_estimation(xEst, PEst, z, u):
#Predict
xPred = state_model(xEst, u)
#state covariance
F = np.diag([1,1,1])**2
PPred = F*PEst*F.T + Q
#Update
zPred = observation_model(xPred)
y = z - zPred #measurement residual
S = H @ PPred @ H.T + R #Innovation covariance
K = PPred @ H.T @ np.linalg.inv(S) #kalman gain
xEst = xPred + K @ y #updating state
PEst = ((np.eye(3)) - K@H) @ PPred
return xEst, PEst
def main():
time = 0.0
#state vector
xEst = np.zeros((3,1))
xTrue = np.zeros((3,1))
PEst = np.array([[0.1,0,0],[0,0.1,0],[0,0,0.1]])
#history
hxEst = xEst
hxTrue = xTrue
haccel = np.zeros((3,1))
while True:
frames = pipeline.wait_for_frames()
raw_accel = frames[0].as_motion_frame().get_motion_data()
raw_gyro = frames[1].as_motion_frame().get_motion_data()
accel = np.asarray([raw_accel.x, raw_accel.y, raw_accel.z])
gyro = np.asarray([raw_gyro.x, raw_gyro.y, raw_gyro.z])
#re-shaping acceleration array
a = accel.reshape((3,1))
#calculating net acceleration
accel_net = math.sqrt((pow(accel[1],2) + pow(accel[2],2)))
u = np.array([[accel_net*dt], [gyro[1]]]) #control input
time+= dt
xTrue, ud = observation(xTrue, u)
z = observation_model(xTrue)
xEst, Pest = ekf_estimation(xEst, PEst, z, ud)
#store data histroy
hxEst = np.hstack((hxEst, xEst))
hxTrue = np.hstack((hxTrue, xTrue))
haccel = np.hstack((haccel, a))
if show_animation:
plt.cla()
# for stopping simulation with the esc key.
plt.gcf().canvas.mpl_connect('key_release_event',
lambda event: [exit(0) if event.key == 'escape' else None])
#plotting actual state (represented by blue line)
plt.plot(hxTrue[0, :], hxTrue[1, :], "-b")
#plotting estimated state (represented by red line)
plt.plot(hxEst[0, :], hxEst[1, :], "-r")
#plotting accelration(represented by green line)
plt.plot(haccel[0, :], haccel[1, :], color = "green")
plot.plot_covariance_ellipse(xEst[0, 0], xEst[1, 0], PEst)
plt.axis("equal")
plt.grid(True)
plt.pause(0.001)
if __name__ == '__main__':
main()