Path: blob/master/experiments/two_radar.py
1700 views
# -*- coding: utf-8 -*-1"""2Created on Sun Feb 15 14:29:23 201534@author: rlabbe5"""67# -*- coding: utf-8 -*-8"""9Created on Sun Feb 8 09:34:36 20151011@author: rlabbe12"""1314import numpy as np15import matplotlib.pyplot as plt1617from numpy import array, asarray18from numpy.linalg import norm19from numpy.random import randn20import math21from math import sin, cos, atan2, radians, degrees222324from filterpy.kalman import UnscentedKalmanFilter as UKF25from filterpy.common import Q_discrete_white_noise2627class RadarStation(object):2829def __init__(self, pos, range_std, bearing_std):30self.pos = asarray(pos)3132self.range_std = range_std33self.bearing_std = bearing_std343536def reading_of(self, ac_pos):37""" Returns range and bearing to aircraft as tuple. bearing is in38radians.39"""4041diff = np.subtract(ac_pos, self.pos)42rng = norm(diff)43brg = atan2(diff[1], diff[0])44return rng, brg454647def noisy_reading(self, ac_pos):48rng, brg = self.reading_of(ac_pos)49rng += randn() * self.range_std50brg += randn() * self.bearing_std51return rng, brg525354def z_to_x(self, slant_range, angle):55""" given a reading, convert to world coordinates"""5657x = cos(angle)*slant_range58z = sin(angle)*slant_range5960return self.pos + (x,z)61626364class ACSim(object):6566def __init__(self, pos, vel, vel_std):67self.pos = asarray(pos, dtype=float)68self.vel = asarray(vel, dtype=float)69self.vel_std = vel_std7071def update(self):72vel = self.vel + (randn() * self.vel_std)73self.pos += vel7475return self.pos767778def two_radar_constvel():79dt = 5808182def hx(x):83r1, b1 = hx.R1.reading_of((x[0], x[2]))84r2, b2 = hx.R2.reading_of((x[0], x[2]))8586return array([r1, b1, r2, b2])87pass88899091def fx(x, dt):92x_est = x.copy()93x_est[0] += x[1]*dt94x_est[2] += x[3]*dt95return x_est96979899100f = UKF(dim_x=4, dim_z=4, dt=dt, hx=hx, fx=fx, kappa=0)101aircraft = ACSim ((100,100), (0.1*dt,0.02*dt), 0.002)102103104range_std = 0.2105bearing_std = radians(0.5)106107R1 = RadarStation ((0,0), range_std, bearing_std)108R2 = RadarStation ((200,0), range_std, bearing_std)109110hx.R1 = R1111hx.R2 = R2112113f.x = array([100, 0.1, 100, 0.02])114f.R = np.diag([range_std**2, bearing_std**2, range_std**2, bearing_std**2])115q = Q_discrete_white_noise(2, var=0.002, dt=dt)116#q = np.array([[0,0],[0,0.0002]])117f.Q[0:2, 0:2] = q118f.Q[2:4, 2:4] = q119f.P = np.diag([.1, 0.01, .1, 0.01])120121122track = []123zs = []124125126for i in range(int(300/dt)):127128pos = aircraft.update()129130r1, b1 = R1.noisy_reading(pos)131r2, b2 = R2.noisy_reading(pos)132133z = np.array([r1, b1, r2, b2])134zs.append(z)135track.append(pos.copy())136137zs = asarray(zs)138139140xs, Ps, Pxz = f.batch_filter(zs)141ms, _, _ = f.rts_smoother2(xs, Ps, Pxz)142143track = asarray(track)144time = np.arange(0,len(xs)*dt, dt)145146plt.figure()147plt.subplot(411)148plt.plot(time, track[:,0])149plt.plot(time, xs[:,0])150plt.legend(loc=4)151plt.xlabel('time (sec)')152plt.ylabel('x position (m)')153154155156plt.subplot(412)157plt.plot(time, track[:,1])158plt.plot(time, xs[:,2])159plt.legend(loc=4)160plt.xlabel('time (sec)')161plt.ylabel('y position (m)')162163164plt.subplot(413)165plt.plot(time, xs[:,1])166plt.plot(time, ms[:,1])167plt.legend(loc=4)168plt.ylim([0, 0.2])169plt.xlabel('time (sec)')170plt.ylabel('x velocity (m/s)')171172plt.subplot(414)173plt.plot(time, xs[:,3])174plt.plot(time, ms[:,3])175plt.ylabel('y velocity (m/s)')176plt.legend(loc=4)177plt.xlabel('time (sec)')178179plt.show()180181182def two_radar_constalt():183dt = .05184185186def hx(x):187r1, b1 = hx.R1.reading_of((x[0], x[2]))188r2, b2 = hx.R2.reading_of((x[0], x[2]))189190return array([r1, b1, r2, b2])191pass192193194def fx(x, dt):195x_est = x.copy()196x_est[0] += x[1]*dt197return x_est198199200201vx = 100/1000 # meters/sec202vz = 0.203204f = UKF(dim_x=3, dim_z=4, dt=dt, hx=hx, fx=fx, kappa=0)205aircraft = ACSim ((0, 1), (vx*dt, vz*dt), 0.00)206207208range_std = 1/1000.209bearing_std =1/1000000.210211R1 = RadarStation (( 0, 0), range_std, bearing_std)212R2 = RadarStation ((60, 0), range_std, bearing_std)213214hx.R1 = R1215hx.R2 = R2216217f.x = array([aircraft.pos[0], vx, aircraft.pos[1]])218f.R = np.diag([range_std**2, bearing_std**2, range_std**2, bearing_std**2])219q = Q_discrete_white_noise(2, var=0.0002, dt=dt)220#q = np.array([[0,0],[0,0.0002]])221f.Q[0:2, 0:2] = q222f.Q[2,2] = 0.0002223f.P = np.diag([.1, 0.01, .1])*0.1224225226track = []227zs = []228229230for i in range(int(500/dt)):231pos = aircraft.update()232233r1, b1 = R1.noisy_reading(pos)234r2, b2 = R2.noisy_reading(pos)235236z = np.array([r1, b1, r2, b2])237zs.append(z)238track.append(pos.copy())239240zs = asarray(zs)241242243xs, Ps = f.batch_filter(zs)244ms, _, _ = f.rts_smoother(xs, Ps)245246track = asarray(track)247time = np.arange(0,len(xs)*dt, dt)248249plt.figure()250plt.subplot(311)251plt.plot(time, track[:,0])252plt.plot(time, xs[:,0])253plt.legend(loc=4)254plt.xlabel('time (sec)')255plt.ylabel('x position (m)')256257plt.subplot(312)258plt.plot(time, xs[:,1]*1000, label="UKF")259plt.plot(time, ms[:,1]*1000, label='RTS')260plt.legend(loc=4)261plt.xlabel('time (sec)')262plt.ylabel('velocity (m/s)')263264plt.subplot(313)265plt.plot(time, xs[:,2]*1000, label="UKF")266plt.plot(time, ms[:,2]*1000, label='RTS')267plt.legend(loc=4)268plt.xlabel('time (sec)')269plt.ylabel('altitude (m)')270plt.ylim([900,1100])271272for z in zs[:10]:273p = R1.z_to_x(z[0], z[1])274#plt.scatter(p[0], p[1], marker='+', c='k')275276p = R2.z_to_x(z[2], z[3])277#plt.scatter(p[0], p[1], marker='+', c='b')278279plt.show()280281282two_radar_constalt()283284