Advertisement
Guest User

Untitled

a guest
Jun 16th, 2019
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.47 KB | None | 0 0
  1. /**
  2.  * particle_filter.cpp
  3.  *
  4.  * Created on: Dec 12, 2016
  5.  * Author: Tiffany Huang
  6.  */
  7.  
  8. #include "particle_filter.h"
  9.  
  10. #include <math.h>
  11. #include <algorithm>
  12. #include <iostream>
  13. #include <iterator>
  14. #include <numeric>
  15. #include <random>
  16. #include <string>
  17. #include <vector>
  18.  
  19. #include "helper_functions.h"
  20.  
  21. using namespace std;//
  22.  
  23. using std::string;
  24. using std::vector;
  25.  
  26. static default_random_engine engine;//
  27. void ParticleFilter::init(double x, double y, double theta, double std[]) {
  28.   /**
  29.    * TODO: Set the number of particles. Initialize all particles to
  30.    *   first position (based on estimates of x, y, theta and their uncertainties
  31.    *   from GPS) and all weights to 1.
  32.    * TODO: Add random Gaussian noise to each particle.
  33.    * NOTE: Consult particle_filter.h for more information about this method
  34.    *   (and others in this file).
  35.    */
  36.   num_particles = 100;  // TODO: Set the number of particles
  37.  
  38.   normal_distribution<double> x_dev(x,std[0]);
  39.   normal_distribution<double> y_dev(y, std[1]);
  40.   normal_distribution<double> theta_dev(theta, std[2]);
  41.  
  42.   for(int i=0;i<num_particles;i++){
  43.     Particle pp;
  44.     pp.id = i;
  45.     pp.x = x_dev(engine);
  46.     pp.y = y_dev(engine);   //注意不是sense_y 而是y,因为:1.y的偏差由main.cpp中landmark measurement提供,
  47.         //2. sense_y为数组,y_dev为一个数
  48.     pp.theta = theta_dev(engine);
  49.     pp.weight = 1.0;
  50.     particles.push_back(pp);
  51. }
  52.   is_initialized = true;
  53. }
  54.  
  55. void ParticleFilter::prediction(double delta_t, double std_pos[],
  56.                                 double velocity, double yaw_rate) {
  57.   /**
  58.    * TODO: Add measurements to each particle and add random Gaussian noise.
  59.    * NOTE: When adding noise you may find std::normal_distribution
  60.    *   and std::default_random_engine useful.
  61.    *  http://en.cppreference.com/w/cpp/numeric/random/normal_distribution
  62.    *  http://www.cplusplus.com/reference/random/default_random_engine/
  63.    */
  64. //   int min_yaw_rate = 0.0001;  //第一次修改
  65.  
  66.   double min_yaw_rate = 0.0001;
  67.   for (unsigned int i=0;i<particles.size();i++) {  //第三次提交后修改,变量i需要初始化为0
  68.     if (abs(yaw_rate) > min_yaw_rate) {
  69. //       particles[i].x += velocity / yaw_rate * (cos(particles[i].theta) - cos(particles[i].theta + yaw_rate * delta_t));
  70. //       particles[i].y += velocity / yaw_rate * (sin(particles[i].theta + yaw_rate*delta_t) + sin(particles[i].theta));
  71.       particles[i].x += velocity / yaw_rate * (sin(particles[i].theta + yaw_rate * delta_t)-sin(particles[i].theta));
  72.       particles[i].y += velocity / yaw_rate * (cos(particles[i].theta)-cos(particles[i].theta + yaw_rate * delta_t));
  73.      
  74.       particles[i].theta += yaw_rate * delta_t;
  75.     }
  76.     else {
  77. //       particles[i].x = particles[i].x + velocity * cos(particles[i].theta);
  78. //       particles[i].y = particles[i].y + velocity * sin(particles[i].theta);
  79. //       particles[i].x = particles[i].x + velocity * sin(particles[i].theta);   //第二次修改
  80. //       particles[i].y = particles[i].y + velocity * cos(particles[i].theta);   //第二次修改
  81.      
  82.       particles[i].x = particles[i].x + velocity * cos(particles[i].theta);
  83.       particles[i].y = particles[i].y + velocity * sin(particles[i].theta);
  84.     }
  85.    
  86.     normal_distribution<double> x_dev(0,std_pos[0]);
  87.     normal_distribution<double> y_dev(0,std_pos[1]);
  88.     normal_distribution<double> theta_dev(0, std_pos[2]);
  89.    
  90.     particles[i].x += x_dev(engine);
  91.     particles[i].y += y_dev(engine);
  92.     particles[i].theta += theta_dev(engine);
  93.    
  94. //     std::cout<<"init"<<std::endl;
  95.   }
  96. }
  97.  
  98. void ParticleFilter::dataAssociation(vector<LandmarkObs> predicted,
  99.                                      vector<LandmarkObs>& observations) {
  100.   /**
  101.    * TODO: Find the predicted measurement that is closest to each
  102.    *   observed measurement and assign the observed measurement to this
  103.    *   particular landmark.
  104.    * NOTE: this method will NOT be called by the grading code. But you will
  105.    *   probably find it useful to implement this method and use it as a helper
  106.    *   during the updateWeights phase.
  107.    */
  108.   for (unsigned int i=0;i< observations.size();i++) {  //第三次提交后修改,变量i需要初始化为0
  109. //     double x_m;
  110. //     double y_m;
  111.     double cal;
  112.     double set_val = numeric_limits<double>::max();
  113.     int min_id;
  114.    
  115.     for (unsigned int j=0;j<predicted.size();j++){   //第三次提交后修改,变量i需要初始化为0
  116.       //x_m = predicted[i].x + (cos(particles[i].theta)*observations[i].x) - (sin(particles[i].theta)*observations[i].y);
  117.       //y_m = predicted[i].y + (sin(particles[i].theta)*observations[i].x) - (cos(particles[i].theta)*observations[i].y);
  118.       //从 helper_functions.h中可知,输入参数predicted和observations都为LandmarkObs,所以不需要坐标转换,而且我认为predicted是
  119.       //真实的地标?
  120.       cal = dist(observations[i].x, observations[i].y, predicted[i].x, predicted[i].y);
  121.       if (cal < set_val) {
  122.         set_val = cal;
  123.         min_id = observations[i].id;
  124.       }
  125.     }
  126.     observations[i].id = min_id;
  127.   }
  128. //   std::cout<< "remain" << &predicted << std::endl;  //调试用
  129. }
  130.  
  131. void ParticleFilter::updateWeights(double sensor_range, double std_landmark[],
  132.                                    const vector<LandmarkObs> &observations,
  133.                                    const Map &map_landmarks) {
  134.   /**
  135.    * TODO: Update the weights of each particle using a mult-variate Gaussian
  136.    *   distribution. You can read more about this distribution here:
  137.    *   https://en.wikipedia.org/wiki/Multivariate_normal_distribution
  138.    * NOTE: The observations are given in the VEHICLE'S coordinate system.
  139.    *   Your particles are located according to the MAP'S coordinate system.
  140.    *   You will need to transform between the two systems. Keep in mind that
  141.    *   this transformation requires both rotation AND translation (but no scaling).
  142.    *   The following is a good resource for the theory:
  143.    *   https://www.willamette.edu/~gorr/classes/GeneralGraphics/Transforms/transforms2d.htm
  144.    *   and the following is a good resource for the actual equation to implement
  145.    *   (look at equation 3.33) http://planning.cs.uiuc.edu/node99.html
  146.    */
  147. //   std::cout<< "%%%%%%%%%%%%" << std::endl;  //调试用
  148. //   std::cout<<num_particles<<std::endl; // 调试用
  149.   for (int i = 0;i<num_particles;i++) {  //第一次修改,添加 i=0
  150. //     std::cout<< "@@@@@@@@@@@@@@@" << std::endl;  // 调试用
  151.    
  152.     double p_x = particles[i].x;
  153.     double p_y = particles[i].y;
  154.    
  155.     vector<LandmarkObs> remain_landmarks;
  156.    
  157.    
  158.     for (unsigned int j=0;j<map_landmarks.landmark_list.size();j++) {   //第三次提交后修改,变量i需要初始化为0
  159.       double m_x = map_landmarks.landmark_list[j].x_f;
  160.       double m_y = map_landmarks.landmark_list[j].y_f;
  161.      
  162.       if ((fabs(p_x-m_x) <=sensor_range)&&(fabs(p_y-m_y)<=sensor_range)) {
  163.         remain_landmarks.push_back(LandmarkObs{ map_landmarks.landmark_list[j].id_i,m_x,m_y });
  164.        
  165.       }
  166.     }
  167.    
  168.     vector<LandmarkObs> objs;
  169.     for (unsigned int t = 0; t < observations.size(); t++){   //第二次修改
  170. //       double x_m = remain_landmarks[i].x + (cos(particles[i].theta)*observations[i].x) - (sin(particles[i].theta)*observations[i].y);  //第一次修改
  171. //       double y_m = remain_landmarks[i].y + (sin(particles[i].theta)*observations[i].x) - (cos(particles[i].theta)*observations[i].y);  //第一次修改
  172.      
  173. //       double x_m = particles[i].x + (cos(particles[i].theta)*observations[i].x) - (sin(particles[i].theta)*observations[i].y);  //第二次修改
  174. //       double y_m = particles[i].y + (sin(particles[i].theta)*observations[i].x) + (cos(particles[i].theta)*observations[i].y);
  175. //   第二次修改      
  176.       double x_m = particles[i].x + (cos(particles[i].theta)*observations[t].x) - (sin(particles[i].theta)*observations[t].y);
  177.       double y_m = particles[i].y + (sin(particles[i].theta)*observations[t].x) + (cos(particles[i].theta)*observations[t].y);
  178.  
  179.       objs.push_back(LandmarkObs{observations[i].id,x_m,y_m});
  180.     }
  181.    
  182.     dataAssociation(remain_landmarks,objs);
  183.    
  184.     particles[i].weight = 1.0;
  185.    
  186.     for (unsigned int t = 0; t < objs.size(); t++){   //第二次修改  
  187.       double objs_id = objs[t].id;
  188.       double objs_x = objs[t].x;
  189.       double objs_y = objs[t].y;
  190.       double r_l_x;   //添加
  191.       double r_l_y;   //添加
  192.      
  193. //       std::cout<< "@@@@@@@@@@@@@@@" << std::endl;   //调试用
  194. //       std::cout<< "%%%%%%%%%%"<<objs_id << std::endl;   //调试用
  195.      
  196.       for (unsigned int j = 0; j < remain_landmarks.size(); j++){
  197. //         std::cout<< "#########"<<remain_landmarks[j].id << std::endl;   //调试用
  198.         if (remain_landmarks[j].id == objs_id) {
  199. //           std::cout<< "@@@@@@@@@@@@@@@" << objs_id << std::endl;   //调试用
  200. //           particles[i].weight *= 1 / (2 * M_PI * std_landmark[0] * std_landmark[1]) * exp((pow(objs_x - remain_landmarks[j].x, 2) / (2 * pow(std_landmark[0], 2))) + (pow(objs_y - remain_landmarks[j].y, 2) / (2 * pow(std_landmark[1], 2)))); //第一次修改
  201. //           particles[i].weight *= (1/(2 * M_PI * std_landmark[0] * std_landmark[1])) * exp(-(pow(objs_x - remain_landmarks[j].x, 2) / (2 * pow(std_landmark[0], 2)) + (pow(objs_y - remain_landmarks[j].y, 2)/(2 * pow(std_landmark[1], 2)))));
  202.           r_l_x = remain_landmarks[j].x;    //添加
  203.           r_l_y = remain_landmarks[j].y;    //添加
  204. //           std::cout<< "@@@@@@@@@@@@@@@" << std::endl;   //调试用
  205.         }
  206. //          std::cout<< "$$$$$$$$$$$" << std::endl;    //调试用
  207.       }
  208.       particles[i].weight *= (1 / (2 * M_PI * std_landmark[0] * std_landmark[1])) * exp(-(pow(objs_x - r_l_x, 2) / (2 * pow(std_landmark[0], 2)) + (pow(objs_y - r_l_y, 2) / (2 * pow(std_landmark[1], 2)))));   //添加
  209.     }
  210.   }
  211. }
  212.  
  213. void ParticleFilter::resample() {
  214.   /**
  215.    * TODO: Resample particles with replacement with probability proportional
  216.    *   to their weight.
  217.    * NOTE: You may find std::discrete_distribution helpful here.
  218.    *   http://en.cppreference.com/w/cpp/numeric/random/discrete_distribution
  219.    */
  220.   vector<Particle> pp;
  221.  
  222.   uniform_int_distribution<int> particles_distribution(0, particles.size() - 1);  // 修改
  223.   int index = particles_distribution(engine);
  224.   //int index = int(engine * particles.size());
  225.   double beta = 0.0;
  226.   vector<double> weight_list;
  227.   for (unsigned int i = 0; i < particles.size(); i++)
  228.   {
  229.     weight_list.push_back(particles[i].weight);
  230.   }
  231.   double ww = *max_element(weight_list.begin(),weight_list.end());
  232.  
  233.   uniform_real_distribution<double> random_engine(0.0,ww);
  234.  
  235.   for (unsigned int i = 0; i < particles.size(); i++)
  236.   {
  237.     beta += random_engine(engine) * 2.0;
  238. //     while (beta > particles[i].weight)
  239. //     {
  240. //       beta -= particles[i].weight;
  241. //       index = (index + 1) % particles.size();
  242. //     }
  243.     while (beta > weight_list[index])
  244.     {
  245.       beta -= particles[i].weight;
  246.       index = (index + 1) % particles.size();
  247.     }
  248.     pp.push_back(particles[index]);
  249.   }
  250.   particles = pp;
  251. }
  252.  
  253. void ParticleFilter::SetAssociations(Particle& particle,
  254.                                      const vector<int>& associations,
  255.                                      const vector<double>& sense_x,
  256.                                      const vector<double>& sense_y) {
  257.   // particle: the particle to which assign each listed association,
  258.   //   and association's (x,y) world coordinates mapping
  259.   // associations: The landmark id that goes along with each listed association
  260.   // sense_x: the associations x mapping already converted to world coordinates
  261.   // sense_y: the associations y mapping already converted to world coordinates
  262.   particle.associations= associations;
  263.   particle.sense_x = sense_x;
  264.   particle.sense_y = sense_y;
  265. }
  266.  
  267. string ParticleFilter::getAssociations(Particle best) {
  268.   vector<int> v = best.associations;
  269.   std::stringstream ss;
  270.   copy(v.begin(), v.end(), std::ostream_iterator<int>(ss, " "));
  271.   string s = ss.str();
  272.   s = s.substr(0, s.length()-1);  // get rid of the trailing space
  273.   return s;
  274. }
  275.  
  276. string ParticleFilter::getSenseCoord(Particle best, string coord) {
  277.   vector<double> v;
  278.  
  279.   if (coord == "X") {
  280.     v = best.sense_x;
  281.   } else {
  282.     v = best.sense_y;
  283.   }
  284.  
  285.   std::stringstream ss;
  286.   copy(v.begin(), v.end(), std::ostream_iterator<float>(ss, " "));
  287.   string s = ss.str();
  288.   s = s.substr(0, s.length()-1);  // get rid of the trailing space
  289.   return s;
  290. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement