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 Jun 27 19:45:45 201534@author: Roger5"""67import numpy as np8import numpy.random9from numpy.random import randn, random, uniform10import scipy.stats111213class RobotLocalizationParticleFilter(object):1415def __init__(self, N, x_dim, y_dim, landmarks, measure_std_error):16self.particles = np.empty((N, 3)) # x, y, heading17self.N = N18self.x_dim = x_dim19self.y_dim = y_dim20self.landmarks = landmarks21self.R = measure_std_error2223# distribute particles randomly with uniform weight24self.weights = np.empty(N)25#self.weights.fill(1./N)26self.particles[:, 0] = uniform(0, x_dim, size=N)27self.particles[:, 1] = uniform(0, y_dim, size=N)28self.particles[:, 2] = uniform(0, 2*np.pi, size=N)293031def create_uniform_particles(self, x_range, y_range, hdg_range):32self.particles[:, 0] = uniform(x_range[0], x_range[1], size=N)33self.particles[:, 1] = uniform(y_range[0], y_range[1], size=N)34self.particles[:, 2] = uniform(hdg_range[0], hdg_range[1], size=N)35self.particles[:, 2] %= 2 * np.pi3637def create_gaussian_particles(self, mean, var):38self.particles[:, 0] = mean[0] + randn(self.N)*var[0]39self.particles[:, 1] = mean[1] + randn(self.N)*var[1]40self.particles[:, 2] = mean[2] + randn(self.N)*var[2]41self.particles[:, 2] %= 2 * np.pi424344def predict(self, u, std, dt=1.):45""" move according to control input u (heading change, velocity)46with noise std"""4748self.particles[:, 2] += u[0] + randn(self.N) * std[0]49self.particles[:, 2] %= 2 * np.pi5051d = u[1]*dt + randn(self.N) * std[1]52self.particles[:, 0] += np.cos(self.particles[:, 2]) * d53self.particles[:, 1] += np.sin(self.particles[:, 2]) * d545556def update(self, z):57self.weights.fill(1.)58for i, landmark in enumerate(self.landmarks):59distance = np.linalg.norm(self.particles[:, 0:2] - landmark, axis=1)60self.weights *= scipy.stats.norm(distance, self.R).pdf(z[i])61#self.weights *= Gaussian(distance, self.R, z[i])6263self.weights += 1.e-30064self.weights /= sum(self.weights) # normalize656667def neff(self):68return 1. / np.sum(np.square(self.weights))697071def resample(self):72cumulative_sum = np.cumsum(self.weights)73cumulative_sum[-1] = 1. # avoid round-off error74indexes = np.searchsorted(cumulative_sum, random(self.N))7576# resample according to indexes77self.particles = self.particles[indexes]78self.weights = self.weights[indexes]79self.weights /= np.sum(self.weights) # normalize808182def resample_from_index(self, indexes):83assert len(indexes) == self.N8485self.particles = self.particles[indexes]86self.weights = self.weights[indexes]87self.weights /= np.sum(self.weights)888990def estimate(self):91""" returns mean and variance """92pos = self.particles[:, 0:2]93mu = np.average(pos, weights=self.weights, axis=0)94var = np.average((pos - mu)**2, weights=self.weights, axis=0)9596return mu, var9798def mean(self):99""" returns weighted mean position"""100return np.average(self.particles[:, 0:2], weights=self.weights, axis=0)101102103104def residual_resample(w):105106N = len(w)107108w_ints = np.floor(N*w).astype(int)109residual = w - w_ints110residual /= sum(residual)111112indexes = np.zeros(N, 'i')113k = 0114for i in range(N):115for j in range(w_ints[i]):116indexes[k] = i117k += 1118cumsum = np.cumsum(residual)119cumsum[N-1] = 1.120for j in range(k, N):121indexes[j] = np.searchsorted(cumsum, random())122123return indexes124125126127def residual_resample2(w):128129N = len(w)130131w_ints =np.floor(N*w).astype(int)132133R = np.sum(w_ints)134m_rdn = N - R135136Ws = (N*w - w_ints)/ m_rdn137indexes = np.zeros(N, 'i')138i = 0139for j in range(N):140for k in range(w_ints[j]):141indexes[i] = j142i += 1143cumsum = np.cumsum(Ws)144cumsum[N-1] = 1 # just in case145146for j in range(i, N):147indexes[j] = np.searchsorted(cumsum, random())148149return indexes150151152153def systemic_resample(w):154N = len(w)155Q = np.cumsum(w)156indexes = np.zeros(N)157t = np.linspace(0, 1-1/N, N) + random()/N158159i, j = 0, 0160while i < N and j < N:161while Q[j] < t[i]:162j += 1163indexes[i] = j164i += 1165166return indexes167168169170171172def Gaussian(mu, sigma, x):173174# calculates the probability of x for 1-dim Gaussian with mean mu and var. sigma175g = (np.exp(-((mu - x) ** 2) / (sigma ** 2) / 2.0) /176np.sqrt(2.0 * np.pi * (sigma ** 2)))177for i in range(len(g)):178g[i] = max(g[i], 1.e-229)179return g180181if __name__ == '__main__':182183DO_PLOT_PARTICLES = False184from numpy.random import seed185import matplotlib.pyplot as plt186187#plt.figure()188189seed(5)190for count in range(1):191print()192print(count)193#numpy.random.set_state(fail_state)194#if count == 12:195# #fail_state = numpy.random.get_state()196# DO_PLOT_PARTICLES = True197198N = 4000199sensor_std_err = .1200landmarks = np.array([[-1, 2], [2,4], [10,6], [18,25]])201NL = len(landmarks)202203#landmarks = [[-1, 2], [2,4]]204205pf = RobotLocalizationParticleFilter(N, 20, 20, landmarks, sensor_std_err)206#pf.create_gaussian_particles([3, 2, 0], [5, 5, 2])207pf.create_uniform_particles((0,20), (0,20), (0, 6.28))208209if DO_PLOT_PARTICLES:210plt.scatter(pf.particles[:, 0], pf.particles[:, 1], alpha=.2, color='g')211212xs = []213for x in range(18):214zs = []215pos=(x+1, x+1)216217for landmark in landmarks:218d = np.sqrt((landmark[0]-pos[0])**2 + (landmark[1]-pos[1])**2)219zs.append(d + randn()*sensor_std_err)220221222zs = np.linalg.norm(landmarks - pos, axis=1) + randn(NL)*sensor_std_err223224225# move diagonally forward to (x+1, x+1)226pf.predict((0.00, 1.414), (.2, .05))227pf.update(z=zs)228if x == 0:229print(max(pf.weights))230#while abs(pf.neff() -N) < .1:231# print('neffing')232# pf.create_uniform_particles((0,20), (0,20), (0, 6.28))233# pf.update(z=zs)234#print(pf.neff())235#indexes = residual_resample2(pf.weights)236indexes = systemic_resample(pf.weights)237238pf.resample_from_index(indexes)239#pf.resample()240241mu, var = pf.estimate()242xs.append(mu)243if DO_PLOT_PARTICLES:244plt.scatter(pf.particles[:, 0], pf.particles[:, 1], alpha=.2)245plt.scatter(pos[0], pos[1], marker='*', color='r')246plt.scatter(mu[0], mu[1], marker='s', color='r')247plt.pause(.01)248249xs = np.array(xs)250plt.plot(xs[:, 0], xs[:, 1])251plt.show()252253254