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 Thu May 28 20:23:57 201534@author: rlabbe5"""678from math import cos, sin, sqrt, atan2, tan9import matplotlib.pyplot as plt10import numpy as np11from numpy import array, dot12from numpy.linalg import pinv13from numpy.random import randn14from filterpy.common import plot_covariance_ellipse15from filterpy.kalman import ExtendedKalmanFilter as EKF161718def print_x(x):19print(x[0, 0], x[1, 0], np.degrees(x[2, 0]))202122def normalize_angle(x, index):23if x[index] > np.pi:24x[index] -= 2*np.pi25if x[index] < -np.pi:26x[index] = 2*np.pi2728def residual(a,b):29y = a - b30normalize_angle(y, 1)31return y323334sigma_r = 0.135sigma_h = np.radians(1)36sigma_steer = np.radians(1)3738#only partway through. predict is using old control and movement code. computation of m uses39#old u.4041class RobotEKF(EKF):42def __init__(self, dt, wheelbase):43EKF.__init__(self, 3, 2, 2)44self.dt = dt45self.wheelbase = wheelbase4647def predict(self, u=0):4849self.x = self.move(self.x, u, self.dt)5051h = self.x[2, 0]52v = u[0]53steering_angle = u[1]5455dist = v*self.dt5657if abs(steering_angle) < 0.0001:58# approximate straight line with huge radius59r = 1.e-3060b = dist / self.wheelbase * tan(steering_angle)61r = self.wheelbase / tan(steering_angle) # radius626364sinh = sin(h)65sinhb = sin(h + b)66cosh = cos(h)67coshb = cos(h + b)6869F = array([[1., 0., -r*cosh + r*coshb],70[0., 1., -r*sinh + r*sinhb],71[0., 0., 1.]])7273w = self.wheelbase7475F = array([[1., 0., (-w*cosh + w*coshb)/tan(steering_angle)],76[0., 1., (-w*sinh + w*sinhb)/tan(steering_angle)],77[0., 0., 1.]])7879print('F', F)8081V = array(82[[-r*sinh + r*sinhb, 0],83[r*cosh + r*coshb, 0],84[0, 0]])858687t2 = tan(steering_angle)**288V = array([[0, w*sinh*(-t2-1)/t2 + w*sinhb*(-t2-1)/t2],89[0, w*cosh*(-t2-1)/t2 - w*coshb*(-t2-1)/t2],90[0,0]])919293t2 = tan(steering_angle)**29495a = steering_angle96d = v*dt97it = dt*v*tan(a)/w + h9899100101V[0,0] = dt*cos(d/w*tan(a) + h)102V[0,1] = (dt*v*(t2+1)*cos(it)/tan(a) -103w*sinh*(-t2-1)/t2 +104w*(-t2-1)*sin(it)/t2)105106107print(dt*v*(t2+1)*cos(it)/tan(a))108print(w*sinh*(-t2-1)/t2)109print(w*(-t2-1)*sin(it)/t2)110111112113V[1,0] = dt*sin(it)114115V[1,1] = (d*(t2+1)*sin(it)/tan(a) + w*cosh/t2*(-t2-1) -116w*(-t2-1)*cos(it)/t2)117118V[2,0] = dt/w*tan(a)119V[2,1] = d/w*(t2+1)120121theta = h122123v01 = (dt*v*(tan(a)**2 + 1)*cos(dt*v*tan(a)/w + theta)/tan(a) -124w*(-tan(a)**2 - 1)*sin(theta)/(tan(a)**2) +125w*(-tan(a)**2 - 1)*sin(dt*v*tan(a)/w + theta)/(tan(a)**2))126127print(dt*v*(tan(a)**2 + 1)*cos(dt*v*tan(a)/w + theta)/tan(a))128print(w*(-tan(a)**2 - 1)*sin(theta)/(tan(a)**2))129print(w*(-tan(a)**2 - 1)*sin(dt*v*tan(a)/w + theta)/(tan(a)**2))130131'''v11 = (dt*v*(tan(a)**2 + 1)*sin(dt*v*tan(a)/w + theta)/tan(a) +132w*(-tan(a)**2 - 1)*cos(theta)/tan(a)**2 -133w*(-tan(a)**2 - 1)*cos(dt*v*tan(a)/w + theta)/tan(a)**2)134135136print(dt*v*(tan(a)**2 + 1)*sin(dt*v*tan(a)/w + theta)/tan(a))137print(w*(-tan(a)**2 - 1)*cos(theta)/tan(a)**2)138print(w*(-tan(a)**2 - 1)*cos(dt*v*tan(a)/w + theta)/tan(a)**2)139print(v11)140print(V[1,1])1411/0142143V[1,1] = v11'''144145print(V)146147148# covariance of motion noise in control space149M = array([[0.1*v**2, 0],150[0, sigma_steer**2]])151152153fpf = dot(F, self.P).dot(F.T)154Q = dot(V, M).dot(V.T)155print('FPF', fpf)156print('V', V)157print('Q', Q)158print()159self.P = dot(F, self.P).dot(F.T) + dot(V, M).dot(V.T)160161162163def move(self, x, u, dt):164h = x[2, 0]165v = u[0]166steering_angle = u[1]167168dist = v*dt169170if abs(steering_angle) < 0.0001:171# approximate straight line with huge radius172r = 1.e-30173b = dist / self.wheelbase * tan(steering_angle)174r = self.wheelbase / tan(steering_angle) # radius175176177sinh = sin(h)178sinhb = sin(h + b)179cosh = cos(h)180coshb = cos(h + b)181182return x + array([[-r*sinh + r*sinhb],183[r*cosh - r*coshb],184[b]])185186187def H_of(x, p):188""" compute Jacobian of H matrix where h(x) computes the range and189bearing to a landmark for state x """190191px = p[0]192py = p[1]193hyp = (px - x[0, 0])**2 + (py - x[1, 0])**2194dist = np.sqrt(hyp)195196H = array(197[[-(px - x[0, 0]) / dist, -(py - x[1, 0]) / dist, 0],198[ (py - x[1, 0]) / hyp, -(px - x[0, 0]) / hyp, -1]])199return H200201202def Hx(x, p):203""" takes a state variable and returns the measurement that would204correspond to that state.205"""206px = p[0]207py = p[1]208dist = np.sqrt((px - x[0, 0])**2 + (py - x[1, 0])**2)209210Hx = array([[dist],211[atan2(py - x[1, 0], px - x[0, 0]) - x[2, 0]]])212return Hx213214dt = 1.0215ekf = RobotEKF(dt, wheelbase=0.5)216217#np.random.seed(1234)218219m = array([[5, 10],220[10, 5],221[15, 15]])222223ekf.x = array([[2, 6, .3]]).T224u = array([.5, .01])225ekf.P = np.diag([1., 1., 1.])226ekf.R = np.diag([sigma_r**2, sigma_h**2])227c = [0, 1, 2]228229xp = ekf.x.copy()230231plt.scatter(m[:, 0], m[:, 1])232for i in range(300):233xp = ekf.move(xp, u, dt/10.) # simulate robot234plt.plot(xp[0], xp[1], ',', color='g')235236if i % 10 == 0:237238ekf.predict(u=u)239240plot_covariance_ellipse((ekf.x[0,0], ekf.x[1,0]), ekf.P[0:2, 0:2], std=2,241facecolor='b', alpha=0.3)242243for lmark in m:244d = sqrt((lmark[0] - xp[0, 0])**2 + (lmark[1] - xp[1, 0])**2) + randn()*sigma_r245a = atan2(lmark[1] - xp[1, 0], lmark[0] - xp[0, 0]) - xp[2, 0] + randn()*sigma_h246z = np.array([[d], [a]])247248ekf.update(z, HJacobian=H_of, Hx=Hx, residual=residual,249args=(lmark), hx_args=(lmark))250251plot_covariance_ellipse((ekf.x[0,0], ekf.x[1,0]), ekf.P[0:2, 0:2], std=10,252facecolor='g', alpha=0.3)253254#plt.plot(ekf.x[0], ekf.x[1], 'x', color='r')255256plt.axis('equal')257plt.show()258259260261