Path: blob/master/experiments/ukf_range.py
1700 views
# -*- coding: utf-8 -*-1"""2Created on Sun Feb 8 09:34:36 201534@author: rlabbe5"""67import numpy as np8import matplotlib.pyplot as plt910from numpy import array, asarray11from numpy.random import randn12import math13from filterpy.kalman import UnscentedKalmanFilter as UKF14151617class RadarSim(object):18""" Simulates the radar signal returns from an object flying19at a constant altityude and velocity in 1D.20"""2122def __init__(self, dt, pos, vel, alt):23self.pos = pos24self.vel = vel25self.alt = alt26self.dt = dt2728def get_range(self):29""" Returns slant range to the object. Call once for each30new measurement at dt time from last call.31"""3233# add some process noise to the system34self.vel = self.vel + .1*randn()35self.alt = self.alt + .1*randn()36self.pos = self.pos + self.vel*self.dt3738# add measurement noise39err = self.pos * 0.05*randn()40slant_dist = math.sqrt(self.pos**2 + self.alt**2)4142return slant_dist + err43444546dt = 0.05474849def hx(x):50return (x[0]**2 + x[2]**2)**.551pass52535455def fx(x, dt):56result = x.copy()57result[0] += x[1]*dt58return result5960616263f = UKF(3, 1, dt= dt, hx=hx, fx=fx, kappa=1)64radar = RadarSim(dt, pos=-1000., vel=100., alt=1000.)6566f.x = array([0, 90, 1005])67f.R = 0.168f.Q *= 0.0026970717273xs = []74track = []7576for i in range(int(20/dt)):77z = radar.get_range()78track.append((radar.pos, radar.vel, radar.alt))7980f.predict()81f.update(array([z]))8283xs.append(f.x)848586xs = asarray(xs)87track = asarray(track)88time = np.arange(0,len(xs)*dt, dt)8990plt.figure()91plt.subplot(311)92plt.plot(time, track[:,0])93plt.plot(time, xs[:,0])94plt.legend(loc=4)95plt.xlabel('time (sec)')96plt.ylabel('position (m)')979899plt.subplot(312)100plt.plot(time, track[:,1])101plt.plot(time, xs[:,1])102plt.legend(loc=4)103plt.xlabel('time (sec)')104plt.ylabel('velocity (m/s)')105106plt.subplot(313)107plt.plot(time, track[:,2])108plt.plot(time, xs[:,2])109plt.ylabel('altitude (m)')110plt.legend(loc=4)111plt.xlabel('time (sec)')112plt.ylim((900,1600))113plt.show()114115116