Herowaree

Particle Filter

Jul 12th, 2019
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.02 KB | None | 0 0
  1. #! /usr/bin/env python
  2.  
  3. # https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python/blob/master/12-Particle-Filters.ipynb
  4.  
  5. import numpy as np
  6. from scipy.stats import multivariate_normal
  7.  
  8. from numpy.random import uniform
  9. from math import sqrt, tan, cos, sin, atan2
  10.  
  11. class ParticleFilterKinect:
  12.  
  13. def __init__(self, num_particles, initial_pos,
  14. fov_vertical=43.0, fov_horizontal=57.0,
  15. max_depth=4.0, min_depth=0.8,
  16. cam_transl_x=-0.125, cam_transl_y=0.0, cam_transl_z=0.25):
  17.  
  18. self.num_particles = num_particles
  19. self.particles = np.zeros((num_particles, 3))
  20. self.weights = np.full(num_particles, 1) / num_particles
  21. cam_particles = np.zeros((num_particles, 3))
  22. robot_particles = np.zeros((num_particles, 3))
  23.  
  24. # Generate particles on camera space
  25. cam_particles[:, 2] = uniform(min_depth, max_depth, size=num_particles)
  26.  
  27. rnd = uniform(-1, 1, size=self.num_particles)
  28. cam_particles[:, 0] = rnd[:] * tan(fov_horizontal/2) * cam_particles[:, 2]
  29. rnd = uniform(-1, 1, size=self.num_particles)
  30. cam_particles[:, 1] = rnd[:] * tan(fov_vertical/2) * cam_particles[:, 2]
  31.  
  32. cam_particles[:, 0] = -cam_particles[:, 0]
  33. cam_particles[:, 1] = -cam_particles[:, 1]
  34.  
  35. # From camera space to robot space
  36. robot_particles[:, 0] = cam_particles[:, 2] + cam_transl_x
  37. robot_particles[:, 1] = cam_particles[:, 0] + cam_transl_y
  38. robot_particles[:, 2] = cam_particles[:, 1] + cam_transl_z
  39.  
  40. # From robot space to world space
  41. theta = 2*atan2(initial_pos[2], initial_pos[3])
  42.  
  43. self.particles[:, 0] = cos(theta)*robot_particles[:, 0] - sin(theta)*robot_particles[:, 1]
  44. self.particles[:, 1] = sin(theta)*robot_particles[:, 0] + cos(theta)*robot_particles[:, 1]
  45. self.particles[:, 2] = robot_particles[:, 2]
  46.  
  47. self.particles[:, 0] = self.particles[:, 0] + initial_pos[0]
  48. self.particles[:, 1] = self.particles[:, 1] + initial_pos[1]
  49.  
  50. def predict(self, last_pos, std=(0.5, 0.5, 0.5)):
  51. noise = uniform(-1, 1, (self.num_particles, 3))
  52.  
  53. self.particles[:, 0] = last_pos[0] + (noise[:, 0] * std[0])
  54. self.particles[:, 1] = last_pos[1] + (noise[:, 1] * std[1])
  55. self.particles[:, 2] = last_pos[2] + (noise[:, 2] * std[2])
  56.  
  57. def update(self, obs_conf, observations, R=.1):
  58. self.weights = np.zeros(self.num_particles)
  59. for i, observation in enumerate(observations):
  60. self.weights += multivariate_normal(mean=observation, cov=[[1,0,0], [0,1,0], [0,0,1]]).pdf(self.particles) * obs_conf[i]
  61.  
  62. self.weights += 1.e-300
  63. self.weights /= sum(self.weights)
  64.  
  65. def neff(self):
  66. return 1. / np.sum(np.square(self.weights))
  67.  
  68. def resample(self):
  69. cumulative_sum = np.cumsum(self.weights)
  70. cumulative_sum[-1] = 1. # avoid round-off error
  71. indexes = np.searchsorted(cumulative_sum, random(self.num_particles))
  72.  
  73. self.particles[:] = self.particles[indexes]
  74. self.weights.fill(1.0 / self.num_particles)
  75.  
  76. def estimate(self):
  77. pos = self.particles
  78. mean = np.average(pos, weights = self.weights, axis=0)
  79. var = np.average((pos-mean)**2, weights = self.weights, axis=0)
  80.  
  81. return mean, var
Advertisement
Add Comment
Please, Sign In to add comment