Path: blob/master/experiments/doppler.py
1700 views
# -*- coding: utf-8 -*-1"""2Created on Sat Jan 17 15:04:08 201534@author: rlabbe5"""6789from numpy.random import randn10import numpy as np11from numpy import array12import matplotlib.pyplot as plt13from filterpy.common import Q_discrete_white_noise14from filterpy.kalman import KalmanFilter15from math import sqrt16import math17import random1819pos_var = 1.20dop_var = 2.21dt = 1/20222324def rand_student_t(df, mu=0, std=1):25"""return random number distributed by student's t distribution with26`df` degrees of freedom with the specified mean and standard deviation.27"""28x = random.gauss(0, std)29y = 2.0*random.gammavariate(0.5*df, 2.0)30return x / (math.sqrt(y/df)) + mu31323334np.random.seed(124)35class ConstantVelocityObject(object):36def __init__(self, x0, vel, noise_scale):37self.x = np.array([x0, vel])38self.noise_scale = noise_scale39self.vel = vel404142def update(self, dt):43pnoise = abs(randn()*self.noise_scale)44if self.x[1] > self.vel:45pnoise = -pnoise4647self.x[1] += pnoise48self.x[0] += self.x[1]*dt4950return self.x.copy()515253def sense_pos(self):54return self.x[0] + [randn()*self.noise_scale[0]]555657def vel(self):58return self.x[1] + [randn()*self.noise_scale[1]]596061def sense(x, noise_scale=(1., 0.01)):62return x + [randn()*noise_scale[0], randn()*noise_scale[1]]6364def sense_t(x, noise_scale=(1., 0.01)):65return x + [rand_student_t(2)*noise_scale[0],66rand_student_t(2)*noise_scale[1]]676869707172R2 = np.zeros((2, 2))73R1 = np.zeros((1, 1))7475R2[0, 0] = pos_var76R2[1, 1] = dop_var7778R1[0,0] = dop_var7980H2 = np.array([[1., 0.], [0., 1.]])81H1 = np.array([[0., 1.]])82838485kf = KalmanFilter(2, 1)86kf.F = array([[1, dt],87[0, 1]])88kf.H = array([[1, 0],89[0, 1]])90kf.Q = Q_discrete_white_noise(2, dt, .02)91kf.x = array([0., 0.])92kf.R = R193kf.H = H194kf.P *= 10959697random.seed(1234)98track = []99zs = []100ests = []101sensor_noise = (sqrt(pos_var), sqrt(dop_var))102obj = ConstantVelocityObject(0., 1., noise_scale=.18)103104for i in range(30000):105x = obj.update(dt/10)106z = sense_t(x, sensor_noise)107if i % 10 != 0:108continue109110if i % 60 == 87687658760:111kf.predict()112kf.update(z, H=H2, R=R2)113else:114kf.predict()115kf.update(z[1], H=H1, R=R1)116117ests.append(kf.x)118119track.append(x)120zs.append(z)121122123track = np.asarray(track)124zs = np.asarray(zs)125ests = np.asarray(ests)126127plt.figure()128plt.subplot(211)129plt.plot(track[:,0], label='track')130plt.plot(zs[:,0], label='measurements')131plt.plot(ests[:,0], label='filter')132plt.legend(loc='best')133134plt.subplot(212)135plt.plot(track[:,1], label='track')136plt.plot(zs[:,1], label='measurements')137plt.plot(ests[:,1], label='filter')138plt.show()139140141142