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 Mon Jun 1 18:13:23 201534@author: rlabbe5"""67from filterpy.common import plot_covariance_ellipse8from filterpy.kalman import UnscentedKalmanFilter as UKF9from filterpy.kalman import MerweScaledSigmaPoints, JulierSigmaPoints10from math import tan, sin, cos, sqrt, atan2, radians, sqrt11import matplotlib.pyplot as plt12from numpy import array13import numpy as np14from numpy.random import randn, seed15161718def normalize_angle(x):19x = x % (2 * np.pi) # force in range [0, 2 pi)20if x > np.pi: # move to [-pi, pi]21x -= 2 * np.pi22return x232425def residual_h(aa, bb):26y = aa - bb27y[1] = normalize_angle(y[1])28return y293031def residual_x(a, b):32y = a - b33y[2] = normalize_angle(y[2])34return y353637def move(x, u, dt, wheelbase):38h = x[2]39v = u[0]40steering_angle = u[1]4142dist = v*dt4344if abs(steering_angle) > 0.001:45b = dist / wheelbase * tan(steering_angle)46r = wheelbase / tan(steering_angle) # radius4748sinh = sin(h)49sinhb = sin(h + b)50cosh = cos(h)51coshb = cos(h + b)5253return x + array([-r*sinh + r*sinhb, r*cosh - r*coshb, b])54else:55return x + array([dist*cos(h), dist*sin(h), 0])565758def state_mean(sigmas, Wm):59x = np.zeros(3)60sum_sin, sum_cos = 0., 0.6162for i in range(len(sigmas)):63s = sigmas[i]64x[0] += s[0] * Wm[i]65x[1] += s[1] * Wm[i]66sum_sin += sin(s[2])*Wm[i]67sum_cos += cos(s[2])*Wm[i]6869x[2] = atan2(sum_sin, sum_cos)70return x717273def z_mean(sigmas, Wm):74x = np.zeros(2)75sum_sin, sum_cos = 0., 0.7677for i in range(len(sigmas)):78s = sigmas[i]79x[0] += s[0] * Wm[i]80sum_sin += sin(s[1])*Wm[i]81sum_cos += cos(s[1])*Wm[i]8283x[1] = atan2(sum_sin, sum_cos)84return x858687sigma_r = .388sigma_h = .01#radians(.5)#np.radians(1)89#sigma_steer = radians(10)90dt = 0.191wheelbase = 0.59293m = array([[5., 10], [10, 5], [15, 15], [20, 5], [0, 30], [50, 30], [40, 10]])94#m = array([[5, 10], [10, 5], [15, 15], [20, 5],[5,5], [8, 8.4]])#, [0, 30], [50, 30], [40, 10]])95m = array([[5, 10], [10, 5]])#, [0, 30], [50, 30], [40, 10]])969798def fx(x, dt, u):99return move(x, u, dt, wheelbase)100101102def Hx(x, landmark):103""" takes a state variable and returns the measurement that would104correspond to that state.105"""106px, py = landmark107dist = sqrt((px - x[0])**2 + (py - x[1])**2)108angle = atan2(py - x[1], px - x[0])109return array([dist, normalize_angle(angle - x[2])])110111112points = MerweScaledSigmaPoints(n=3, alpha=.1, beta=2, kappa=0)113#points = JulierSigmaPoints(n=3, kappa=3)114ukf= UKF(dim_x=3, dim_z=2, fx=fx, hx=Hx, dt=dt, points=points,115x_mean_fn=state_mean, z_mean_fn=z_mean,116residual_x=residual_x, residual_z=residual_h)117ukf.x = array([2, 6, .3])118ukf.P = np.diag([.1, .1, .2])119ukf.R = np.diag([sigma_r**2, sigma_h**2])120ukf.Q = None#np.eye(3)*.00000121122123u = array([1.1, 0.])124125xp = ukf.x.copy()126127128plt.cla()129plt.scatter(m[:, 0], m[:, 1])130131cmds = [[v, .0] for v in np.linspace(0.001, 1.1, 30)]132cmds.extend([cmds[-1]]*50)133134v = cmds[-1][0]135cmds.extend([[v, a] for a in np.linspace(0, np.radians(2), 15)])136cmds.extend([cmds[-1]]*100)137138cmds.extend([[v, a] for a in np.linspace(np.radians(2), -np.radians(2), 15)])139cmds.extend([cmds[-1]]*200)140141cmds.extend([[v, a] for a in np.linspace(-np.radians(2), 0, 15)])142cmds.extend([cmds[-1]]*150)143144#cmds.extend([[v, a] for a in np.linspace(0, -np.radians(1), 25)])145146147148seed(12)149cmds = np.array(cmds)150151cindex = 0152u = cmds[0]153154track = []155156while cindex < len(cmds):157u = cmds[cindex]158xp = move(xp, u, dt, wheelbase) # simulate robot159track.append(xp)160161ukf.predict(fx_args=u)162163if cindex % 20 == 30:164plot_covariance_ellipse((ukf.x[0], ukf.x[1]), ukf.P[0:2, 0:2], std=18,165facecolor='b', alpha=0.58)166167#print(cindex, ukf.P.diagonal())168print(xp)169for lmark in m:170171d = sqrt((lmark[0] - xp[0])**2 + (lmark[1] - xp[1])**2) + randn()*sigma_r172bearing = atan2(lmark[1] - xp[1], lmark[0] - xp[0])173a = normalize_angle(bearing - xp[2] + randn()*sigma_h)174z = np.array([d, a])175176if cindex % 20 == 0:177plt.plot([lmark[0], lmark[0] - d*cos(a+xp[2])], [lmark[1], lmark[1]-d*sin(a+xp[2])], color='r')178179ukf.update(z, hx_args=(lmark,))180print(ukf.P)181print()182183if cindex % 20 == 0:184plot_covariance_ellipse((ukf.x[0], ukf.x[1]), ukf.P[0:2, 0:2], std=15,185facecolor='g', alpha=0.99)186cindex += 1187188189track = np.array(track)190plt.plot(track[:, 0], track[:,1], color='k')191192plt.axis('equal')193plt.title("UKF Robot localization")194plt.show()195print(ukf.P.diagonal())196197198