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 May 30 13:24:01 201534@author: rlabbe5"""67# -*- coding: utf-8 -*-8"""9Created on Thu May 28 20:23:57 20151011@author: rlabbe12"""131415from math import cos, sin, sqrt, atan2, tan16import matplotlib.pyplot as plt17import numpy as np18from numpy import array, dot19from numpy.random import randn20from filterpy.common import plot_covariance_ellipse21from filterpy.kalman import ExtendedKalmanFilter as EKF22from sympy import Matrix, symbols23import sympy2425def print_x(x):26print(x[0, 0], x[1, 0], np.degrees(x[2, 0]))272829def normalize_angle(x, index):30if x[index] > np.pi:31x[index] -= 2*np.pi32if x[index] < -np.pi:33x[index] = 2*np.pi3435def residual(a,b):36y = a - b37normalize_angle(y, 1)38return y394041sigma_r = 142sigma_h = .1#np.radians(1)43sigma_steer = np.radians(1)444546class RobotEKF(EKF):47def __init__(self, dt, wheelbase):48EKF.__init__(self, 3, 2, 2)49self.dt = dt50self.wheelbase = wheelbase5152a, x, y, v, w, theta, time = symbols(53'a, x, y, v, w, theta, t')5455d = v*time56beta = (d/w)*sympy.tan(a)57r = w/sympy.tan(a)585960self.fxu = Matrix([[x-r*sympy.sin(theta)+r*sympy.sin(theta+beta)],61[y+r*sympy.cos(theta)-r*sympy.cos(theta+beta)],62[theta+beta]])6364self.F_j = self.fxu.jacobian(Matrix([x, y, theta]))65self.V_j = self.fxu.jacobian(Matrix([v, a]))6667self.subs = {x: 0, y: 0, v:0, a:0, time:dt, w:wheelbase, theta:0}68self.x_x = x69self.x_y = y70self.v = v71self.a = a72self.theta = theta737475def predict(self, u=0):767778self.x = self.move(self.x, u, self.dt)7980self.subs[self.theta] = self.x[2, 0]81self.subs[self.v] = u[0]82self.subs[self.a] = u[1]838485F = array(self.F_j.evalf(subs=self.subs)).astype(float)86V = array(self.V_j.evalf(subs=self.subs)).astype(float)8788# covariance of motion noise in control space89M = array([[0.1*u[0]**2, 0],90[0, sigma_steer**2]])9192self.P = dot(F, self.P).dot(F.T) + dot(V, M).dot(V.T)939495def move(self, x, u, dt):96h = x[2, 0]97v = u[0]98steering_angle = u[1]99100dist = v*dt101102if abs(steering_angle) < 0.0001:103# approximate straight line with huge radius104r = 1.e-30105b = dist / self.wheelbase * tan(steering_angle)106r = self.wheelbase / tan(steering_angle) # radius107108109sinh = sin(h)110sinhb = sin(h + b)111cosh = cos(h)112coshb = cos(h + b)113114return x + array([[-r*sinh + r*sinhb],115[r*cosh - r*coshb],116[b]])117118119def H_of(x, p):120""" compute Jacobian of H matrix where h(x) computes the range and121bearing to a landmark 'p' for state x """122123px = p[0]124py = p[1]125hyp = (px - x[0, 0])**2 + (py - x[1, 0])**2126dist = np.sqrt(hyp)127128H = array(129[[(-px + x[0, 0]) / dist, (-py + x[1, 0]) / dist, 0.],130[ -(-py + x[1, 0]) / hyp, -(px - x[0, 0]) / hyp, -1.]])131return H132133134def Hx(x, p):135""" takes a state variable and returns the measurement that would136correspond to that state.137"""138px = p[0]139py = p[1]140dist = np.sqrt((px - x[0, 0])**2 + (py - x[1, 0])**2)141142Hx = array([[dist],143[atan2(py - x[1, 0], px - x[0, 0]) - x[2, 0]]])144return Hx145146dt = 1.0147ekf = RobotEKF(dt, wheelbase=0.5)148149#np.random.seed(1234)150151m = array([[5, 10],152[10, 5],153[15, 15]])154155ekf.x = array([[2, 6, .3]]).T156ekf.P = np.diag([.1, .1, .1])157ekf.R = np.diag([sigma_r**2, sigma_h**2])158159u = array([1.1, .01])160161xp = ekf.x.copy()162163plt.figure()164plt.scatter(m[:, 0], m[:, 1])165for i in range(250):166xp = ekf.move(xp, u, dt/10.) # simulate robot167plt.plot(xp[0], xp[1], ',', color='g')168169if i % 10 == 0:170171ekf.predict(u=u)172173plot_covariance_ellipse((ekf.x[0,0], ekf.x[1,0]), ekf.P[0:2, 0:2], std=3,174facecolor='b', alpha=0.08)175176for lmark in m:177d = sqrt((lmark[0] - xp[0, 0])**2 + (lmark[1] - xp[1, 0])**2) + randn()*sigma_r178a = atan2(lmark[1] - xp[1, 0], lmark[0] - xp[0, 0]) - xp[2, 0] + randn()*sigma_h179z = np.array([[d], [a]])180181ekf.update(z, HJacobian=H_of, Hx=Hx, residual=residual,182args=(lmark), hx_args=(lmark))183184plot_covariance_ellipse((ekf.x[0,0], ekf.x[1,0]), ekf.P[0:2, 0:2], std=3,185facecolor='g', alpha=0.4)186187#plt.plot(ekf.x[0], ekf.x[1], 'x', color='r')188189plt.axis('equal')190plt.title("EKF Robot localization")191plt.show()192193194195