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 Sun Feb 8 09:55:24 201534@author: rlabbe5"""67from math import radians, sin, cos, sqrt, exp, atan2, radians8from numpy import array, asarray9from numpy.random import randn10import numpy as np11import math12import matplotlib.pyplot as plt13from filterpy.kalman import UnscentedKalmanFilter as UKF14from filterpy.common import runge_kutta41516171819202122class BaseballPath(object):23def __init__(self, x0, y0, launch_angle_deg, velocity_ms,24noise=(1.0,1.0)):25""" Create 2D baseball path object26(x = distance from start point in ground plane,27y=height above ground)2829x0,y0 initial position30launch_angle_deg angle ball is travelling respective to31ground plane32velocity_ms speeed of ball in meters/second33noise amount of noise to add to each position34in (x,y)35"""3637omega = radians(launch_angle_deg)38self.v_x = velocity_ms * cos(omega)39self.v_y = velocity_ms * sin(omega)4041self.x = x042self.y = y04344self.noise = noise454647def drag_force(self, velocity):48""" Returns the force on a baseball due to air drag at49the specified velocity. Units are SI50"""51B_m = 0.0039 + 0.0058 / (1. + exp((velocity-35.)/5.))52return B_m * velocity535455def update(self, dt, vel_wind=0.):56""" compute the ball position based on the specified time57step and wind velocity. Returns (x,y) position tuple58"""5960# Euler equations for x and y61self.x += self.v_x*dt62self.y += self.v_y*dt6364# force due to air drag65v_x_wind = self.v_x - vel_wind66v = sqrt(v_x_wind**2 + self.v_y**2)67F = self.drag_force(v)6869# Euler's equations for velocity70self.v_x = self.v_x - F*v_x_wind*dt71self.v_y = self.v_y - 9.81*dt - F*self.v_y*dt7273return (self.x, self.y)74757677radar_pos = (100,0)78omega = 45.798081def radar_sense(baseball, noise_rng, noise_brg):82x, y = baseball.x, baseball.y8384rx, ry = radar_pos[0], radar_pos[1]8586rng = ((x-rx)**2 + (y-ry)**2) ** .587bearing = atan2(y-ry, x-rx)8889rng += randn() * noise_rng90bearing += radians(randn() * noise_brg)9192return (rng, bearing)939495ball = BaseballPath(x0=0, y0=1, launch_angle_deg=45,96velocity_ms=60, noise=[0,0])979899'''100xs = []101ys = []102dt = 0.05103y = 1104105while y > 0:106x,y = ball.update(dt)107xs.append(x)108ys.append(y)109110plt.plot(xs, ys)111plt.axis('equal')112113114plt.show()115116'''117118119dt = 1/30.120121122def hx(x):123global radar_pos124125dx = radar_pos[0] - x[0]126dy = radar_pos[1] - x[2]127rng = (dx*dx + dy*dy)**.5128bearing = atan2(-dy, -dx)129130#print(x)131#print('hx:', rng, np.degrees(bearing))132133return array([rng, bearing])134135136137138def fx(x, dt):139140fx.ball.x = x[0]141fx.ball.y = x[2]142fx.ball.vx = x[1]143fx.ball.vy = x[3]144145N = 10146ball_dt = dt/float(N)147148for i in range(N):149fx.ball.update(ball_dt)150151#print('fx', fx.ball.x, fx.ball.v_x, fx.ball.y, fx.ball.v_y)152153return array([fx.ball.x, fx.ball.v_x, fx.ball.y, fx.ball.v_y])154155156fx.ball = BaseballPath(x0=0, y0=1, launch_angle_deg=45,157velocity_ms=60, noise=[0,0])158159160y = 1.161x = 0.162theta = 35. # launch angle163v0 = 50.164165166ball = BaseballPath(x0=x, y0=y, launch_angle_deg=theta,167velocity_ms=v0, noise=[.3,.3])168169kf = UKF(dim_x=4, dim_z=2, dt=dt, hx=hx, fx=fx, kappa=0)170171#kf.R *= r172173kf.R[0,0] = 0.1174kf.R[1,1] = radians(0.2)175omega = radians(omega)176vx = cos(omega) * v0177vy = sin(omega) * v0178179kf.x = array([x, vx, y, vy])180kf.R*= 0.01181#kf.R[1,1] = 0.01182kf.P *= 10183184f1 = kf185186187t = 0188xs = []189ys = []190191while y > 0:192t += dt193x,y = ball.update(dt)194z = radar_sense(ball, 0, 0)195#print('z', z)196#print('ball', ball.x, ball.v_x, ball.y, ball.v_y)197198199f1.predict()200f1.update(z)201xs.append(f1.x[0])202ys.append(f1.x[2])203f1.predict()204205p1 = plt.scatter(x, y, color='r', marker='o', s=75, alpha=0.5)206207p2, = plt.plot (xs, ys, lw=2, marker='o')208#p3, = plt.plot (xs2, ys2, lw=4)209#plt.legend([p1,p2, p3],210# ['Measurements', 'Kalman filter(R=0.5)', 'Kalman filter(R=10)'],211# loc='best', scatterpoints=1)212plt.show()213214215216