CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

| Download
Project: test
Views: 91872
1
# -*- coding: utf-8 -*-
2
"""
3
Created on Sun Feb 8 09:55:24 2015
4
5
@author: rlabbe
6
"""
7
8
from math import radians, sin, cos, sqrt, exp, atan2, radians
9
from numpy import array, asarray
10
from numpy.random import randn
11
import numpy as np
12
import math
13
import matplotlib.pyplot as plt
14
from filterpy.kalman import UnscentedKalmanFilter as UKF
15
from filterpy.common import runge_kutta4
16
17
18
19
20
21
22
23
class BaseballPath(object):
24
def __init__(self, x0, y0, launch_angle_deg, velocity_ms,
25
noise=(1.0,1.0)):
26
""" Create 2D baseball path object
27
(x = distance from start point in ground plane,
28
y=height above ground)
29
30
x0,y0 initial position
31
launch_angle_deg angle ball is travelling respective to
32
ground plane
33
velocity_ms speeed of ball in meters/second
34
noise amount of noise to add to each position
35
in (x,y)
36
"""
37
38
omega = radians(launch_angle_deg)
39
self.v_x = velocity_ms * cos(omega)
40
self.v_y = velocity_ms * sin(omega)
41
42
self.x = x0
43
self.y = y0
44
45
self.noise = noise
46
47
48
def drag_force(self, velocity):
49
""" Returns the force on a baseball due to air drag at
50
the specified velocity. Units are SI
51
"""
52
B_m = 0.0039 + 0.0058 / (1. + exp((velocity-35.)/5.))
53
return B_m * velocity
54
55
56
def update(self, dt, vel_wind=0.):
57
""" compute the ball position based on the specified time
58
step and wind velocity. Returns (x,y) position tuple
59
"""
60
61
# Euler equations for x and y
62
self.x += self.v_x*dt
63
self.y += self.v_y*dt
64
65
# force due to air drag
66
v_x_wind = self.v_x - vel_wind
67
v = sqrt(v_x_wind**2 + self.v_y**2)
68
F = self.drag_force(v)
69
70
# Euler's equations for velocity
71
self.v_x = self.v_x - F*v_x_wind*dt
72
self.v_y = self.v_y - 9.81*dt - F*self.v_y*dt
73
74
return (self.x, self.y)
75
76
77
78
radar_pos = (100,0)
79
omega = 45.
80
81
82
def radar_sense(baseball, noise_rng, noise_brg):
83
x, y = baseball.x, baseball.y
84
85
rx, ry = radar_pos[0], radar_pos[1]
86
87
rng = ((x-rx)**2 + (y-ry)**2) ** .5
88
bearing = atan2(y-ry, x-rx)
89
90
rng += randn() * noise_rng
91
bearing += radians(randn() * noise_brg)
92
93
return (rng, bearing)
94
95
96
ball = BaseballPath(x0=0, y0=1, launch_angle_deg=45,
97
velocity_ms=60, noise=[0,0])
98
99
100
'''
101
xs = []
102
ys = []
103
dt = 0.05
104
y = 1
105
106
while y > 0:
107
x,y = ball.update(dt)
108
xs.append(x)
109
ys.append(y)
110
111
plt.plot(xs, ys)
112
plt.axis('equal')
113
114
115
plt.show()
116
117
'''
118
119
120
dt = 1/30.
121
122
123
def hx(x):
124
global radar_pos
125
126
dx = radar_pos[0] - x[0]
127
dy = radar_pos[1] - x[2]
128
rng = (dx*dx + dy*dy)**.5
129
bearing = atan2(-dy, -dx)
130
131
#print(x)
132
#print('hx:', rng, np.degrees(bearing))
133
134
return array([rng, bearing])
135
136
137
138
139
def fx(x, dt):
140
141
fx.ball.x = x[0]
142
fx.ball.y = x[2]
143
fx.ball.vx = x[1]
144
fx.ball.vy = x[3]
145
146
N = 10
147
ball_dt = dt/float(N)
148
149
for i in range(N):
150
fx.ball.update(ball_dt)
151
152
#print('fx', fx.ball.x, fx.ball.v_x, fx.ball.y, fx.ball.v_y)
153
154
return array([fx.ball.x, fx.ball.v_x, fx.ball.y, fx.ball.v_y])
155
156
157
fx.ball = BaseballPath(x0=0, y0=1, launch_angle_deg=45,
158
velocity_ms=60, noise=[0,0])
159
160
161
y = 1.
162
x = 0.
163
theta = 35. # launch angle
164
v0 = 50.
165
166
167
ball = BaseballPath(x0=x, y0=y, launch_angle_deg=theta,
168
velocity_ms=v0, noise=[.3,.3])
169
170
kf = UKF(dim_x=4, dim_z=2, dt=dt, hx=hx, fx=fx, kappa=0)
171
172
#kf.R *= r
173
174
kf.R[0,0] = 0.1
175
kf.R[1,1] = radians(0.2)
176
omega = radians(omega)
177
vx = cos(omega) * v0
178
vy = sin(omega) * v0
179
180
kf.x = array([x, vx, y, vy])
181
kf.R*= 0.01
182
#kf.R[1,1] = 0.01
183
kf.P *= 10
184
185
f1 = kf
186
187
188
t = 0
189
xs = []
190
ys = []
191
192
while y > 0:
193
t += dt
194
x,y = ball.update(dt)
195
z = radar_sense(ball, 0, 0)
196
#print('z', z)
197
#print('ball', ball.x, ball.v_x, ball.y, ball.v_y)
198
199
200
f1.predict()
201
f1.update(z)
202
xs.append(f1.x[0])
203
ys.append(f1.x[2])
204
f1.predict()
205
206
p1 = plt.scatter(x, y, color='r', marker='o', s=75, alpha=0.5)
207
208
p2, = plt.plot (xs, ys, lw=2, marker='o')
209
#p3, = plt.plot (xs2, ys2, lw=4)
210
#plt.legend([p1,p2, p3],
211
# ['Measurements', 'Kalman filter(R=0.5)', 'Kalman filter(R=10)'],
212
# loc='best', scatterpoints=1)
213
plt.show()
214
215
216