Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
Project: test
Views: 91872# -*- coding: utf-8 -*-1"""2Created on Sat Jul 5 16:07:29 201434@author: rlabbe5"""67import numpy as np8from KalmanFilter import KalmanFilter9from math import radians, sin, cos, sqrt, exp10import numpy.random as random11import matplotlib.markers as markers12import matplotlib.pyplot as plt13from RungeKutta import *141516class BallPath(object):17def __init__(self, x0, y0, omega_deg, velocity, g=9.8, noise=[1.0,1.0]):18omega = radians(omega_deg)19self.vx0 = velocity * cos(omega)20self.vy0 = velocity * sin(omega)2122self.x0 = x023self.y0 = y02425self.g = g26self.noise = noise2728def pos_at_t(self, t):29""" returns (x,y) tuple of ball position at time t"""30x = self.vx0*t + self.x031y = -0.5*self.g*t**2 + self.vy0*t + self.y03233return (x +random.randn()*self.noise[0], y +random.randn()*self.noise[1])343536def ball_kf(x, y, omega, v0, dt, r=0.5, q=0.02):3738g = 9.8 # gravitational constant39f1 = KalmanFilter(dim_x=5, dim_z=2)4041ay = .5*dt**242f1.F = np.mat ([[1, dt, 0, 0, 0], # x = x0+dx*dt43[0, 1, 0, 0, 0], # dx = dx44[0, 0, 1, dt, ay], # y = y0 +dy*dt+1/2*g*dt^245[0, 0, 0, 1, dt], # dy = dy0 + ddy*dt46[0, 0, 0, 0, 1]]) # ddy = -g.4748f1.H = np.mat([49[1, 0, 0, 0, 0],50[0, 0, 1, 0, 0]])5152f1.R *= r53f1.Q *= q5455omega = radians(omega)56vx = cos(omega) * v057vy = sin(omega) * v05859f1.x = np.mat([x,vx,y,vy,-9.8]).T6061return f162636465def ball_kf_noay(x, y, omega, v0, dt, r=0.5, q=0.02):6667g = 9.8 # gravitational constant68f1 = KalmanFilter(dim_x=5, dim_z=2)6970ay = .5*dt**271f1.F = np.mat ([[1, dt, 0, 0, 0], # x = x0+dx*dt72[0, 1, 0, 0, 0], # dx = dx73[0, 0, 1, dt, 0], # y = y0 +dy*dt74[0, 0, 0, 1, dt], # dy = dy0 + ddy*dt75[0, 0, 0, 0, 1]]) # ddy = -g.7677f1.H = np.mat([78[1, 0, 0, 0, 0],79[0, 0, 1, 0, 0]])8081f1.R *= r82f1.Q *= q8384omega = radians(omega)85vx = cos(omega) * v086vy = sin(omega) * v08788f1.x = np.mat([x,vx,y,vy,-9.8]).T8990return f1919293def test_kf():94dt = 0.195t = 096f1 = ball_kf (0,1, 35, 50, 0.1)97f2 = ball_kf_noay (0,1, 35, 50, 0.1)9899path = BallPath( 0, 1, 35, 50, noise=(0,0))100path_rk = BallRungeKutta(0, 1, 50, 35)101102xs = []103ys = []104while f1.x[2,0]>= 0:105t += dt106f1.predict()107f2.predict()108#x,y = path.pos_at_t(t)109x,y = path_rk.step(dt)110xs.append(x)111ys.append(y)112113plt.scatter (f1.x[0,0], f1.x[2,0], color='blue',alpha=0.6)114plt.scatter (f2.x[0,0], f2.x[2,0], color='red', alpha=0.6)115116plt.plot(xs, ys, c='g')117118119class BaseballPath(object):120def __init__(self, x0, y0, launch_angle_deg, velocity_ms, noise=(1.0,1.0)):121""" Create baseball path object in 2D (y=height above ground)122123x0,y0 initial position124launch_angle_deg angle ball is travelling respective to ground plane125velocity_ms speeed of ball in meters/second126noise amount of noise to add to each reported position in (x,y)127"""128129omega = radians(launch_angle_deg)130self.v_x = velocity_ms * cos(omega)131self.v_y = velocity_ms * sin(omega)132133self.x = x0134self.y = y0135136self.noise = noise137138139def drag_force (self, velocity):140""" Returns the force on a baseball due to air drag at141the specified velocity. Units are SI142"""143B_m = 0.0039 + 0.0058 / (1. + exp((velocity-35.)/5.))144return B_m * velocity145146147def update(self, dt, vel_wind=0.):148""" compute the ball position based on the specified time step and149wind velocity. Returns (x,y) position tuple.150"""151152# Euler equations for x and y153self.x += self.v_x*dt154self.y += self.v_y*dt155156# force due to air drag157v_x_wind = self.v_x - vel_wind158159v = sqrt (v_x_wind**2 + self.v_y**2)160F = self.drag_force(v)161162# Euler's equations for velocity163self.v_x = self.v_x - F*v_x_wind*dt164self.v_y = self.v_y - 9.81*dt - F*self.v_y*dt165166return (self.x + random.randn()*self.noise[0],167self.y + random.randn()*self.noise[1])168169170171def test_baseball_path():172ball = BaseballPath (0, 1, 35, 50)173while ball.y > 0:174ball.update (0.1, 0.)175plt.scatter (ball.x, ball.y)176177178179def test_ball_path():180181y = 15182x = 0183omega = 0.184noise = [1,1]185v0 = 100.186ball = BallPath (x0=x, y0=y, omega_deg=omega, velocity=v0, noise=noise)187dt = 1188189190f1 = KalmanFilter(dim_x=6, dim_z=2)191dt = 1/30. # time step192193ay = -.5*dt**2194195f1.F = np.mat ([[1, dt, 0, 0, 0, 0], # x=x0+dx*dt196[0, 1, dt, 0, 0, 0], # dx = dx197[0, 0, 0, 0, 0, 0], # ddx = 0198[0, 0, 0, 1, dt, ay], # y = y0 +dy*dt+1/2*g*dt^2199[0, 0, 0, 0, 1, dt], # dy = dy0 + ddy*dt200[0, 0, 0, 0, 0, 1]]) # ddy = -g201202203f1.H = np.mat([204[1, 0, 0, 0, 0, 0],205[0, 0, 0, 1, 0, 0]])206207f1.R = np.eye(2) * 5208f1.Q = np.eye(6) * 0.209210omega = radians(omega)211vx = cos(omega) * v0212vy = sin(omega) * v0213214f1.x = np.mat([x,vx,0,y,vy,-9.8]).T215216f1.P = np.eye(6) * 500.217218z = np.mat([[0,0]]).T219count = 0220markers.MarkerStyle(fillstyle='none')221222np.set_printoptions(precision=4)223while f1.x[3,0] > 0:224count += 1225#f1.update (z)226f1.predict()227plt.scatter(f1.x[0,0],f1.x[3,0], color='green')228229230231def drag_force (velocity):232""" Returns the force on a baseball due to air drag at233the specified velocity. Units are SI234"""235B_m = 0.0039 + 0.0058 / (1. + exp((velocity-35.)/5.))236return B_m * velocity237238def update_drag(f, dt):239vx = f.x[1,0]240vy = f.x[3,0]241v = sqrt(vx**2 + vy**2)242F = -drag_force(v)243print F244f.u[0,0] = -drag_force(vx)245f.u[1,0] = -drag_force(vy)246#f.x[2,0]=F*vx247#f.x[5,0]=F*vy248249def test_kf_drag():250251y = 1252x = 0253omega = 35.254noise = [0,0]255v0 = 50.256ball = BaseballPath (x0=x, y0=y,257launch_angle_deg=omega,258velocity_ms=v0, noise=noise)259#ball = BallPath (x0=x, y0=y, omega_deg=omega, velocity=v0, noise=noise)260261dt = 1262263264f1 = KalmanFilter(dim_x=6, dim_z=2)265dt = 1/30. # time step266267ay = -.5*dt**2268ax = .5*dt**2269270f1.F = np.mat ([[1, dt, ax, 0, 0, 0], # x=x0+dx*dt271[0, 1, dt, 0, 0, 0], # dx = dx272[0, 0, 1, 0, 0, 0], # ddx = 0273[0, 0, 0, 1, dt, ay], # y = y0 +dy*dt+1/2*g*dt^2274[0, 0, 0, 0, 1, dt], # dy = dy0 + ddy*dt275[0, 0, 0, 0, 0, 1]]) # ddy = -g276277# We will inject air drag using Bu278f1.B = np.mat([[0., 0., 1., 0., 0., 0.],279[0., 0., 0., 0., 0., 1.]]).T280281f1.u = np.mat([[0., 0.]]).T282283f1.H = np.mat([284[1, 0, 0, 0, 0, 0],285[0, 0, 0, 1, 0, 0]])286287f1.R = np.eye(2) * 5288f1.Q = np.eye(6) * 0.289290omega = radians(omega)291vx = cos(omega) * v0292vy = sin(omega) * v0293294f1.x = np.mat([x,vx,0,y,vy,-9.8]).T295296f1.P = np.eye(6) * 500.297298z = np.mat([[0,0]]).T299markers.MarkerStyle(fillstyle='none')300301np.set_printoptions(precision=4)302303t=0304while f1.x[3,0] > 0:305t+=dt306307#f1.update (z)308x,y = ball.update(dt)309#x,y = ball.pos_at_t(t)310update_drag(f1, dt)311f1.predict()312print f1.x.T313plt.scatter(f1.x[0,0],f1.x[3,0], color='red', alpha=0.5)314plt.scatter (x,y)315return f1316317if __name__ == '__main__':318#test_baseball_path()319#test_ball_path()320#test_kf()321f1 = test_kf_drag()322323324