pf.c
Go to the documentation of this file.
1 //this package is based on amcl and has been modified to fit gmcl
2 /*
3  * Author: Mhd Ali Alshikh Khalil
4  * Date: 20 June 2021
5  *
6 */
7 
8 //amcl author clarification
9 /*
10  * Player - One Hell of a Robot Server
11  * Copyright (C) 2000 Brian Gerkey & Kasper Stoy
12  * gerkey@usc.edu kaspers@robotics.usc.edu
13  *
14  * This library is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU Lesser General Public
16  * License as published by the Free Software Foundation; either
17  * version 2.1 of the License, or (at your option) any later version.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  * Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public
25  * License along with this library; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27  *
28  */
29 /**************************************************************************
30  * Desc: Simple particle filter for localization.
31  * Author: Andrew Howard
32  * Date: 10 Dec 2002
33  * CVS: $Id: pf.c 6345 2008-04-17 01:36:39Z gerkey $
34  *************************************************************************/
35 
36 #include <assert.h>
37 #include <math.h>
38 #include <stdlib.h>
39 #include <time.h>
40 
41 #include "gmcl/map/map.h"
42 #include "gmcl/pf/pf.h"
43 #include "gmcl/pf/pf_pdf.h"
44 #include "gmcl/pf/pf_kdtree.h"
45 #include "portable_utils.hpp"
46 
47 // Compute the required number of samples, given that there are k bins
48 // with samples in them.
49 static int pf_resample_limit(pf_t *pf, int k);
50 
51 
52 
53 // Create a new filter
54 pf_t *pf_alloc(int min_samples, int max_samples,int N_aux_particles,
55  double alpha_slow, double alpha_fast,double crossover_alpha ,double mutation_prob ,
56  pf_init_model_fn_t random_pose_fn, void *random_pose_data , void *e_random_pose_data)
57 {
58  int i, j;
59  pf_t *pf;
61  pf_sample_t *sample;
62 
63  srand48(time(NULL));
64 
65  pf = calloc(1, sizeof(pf_t));
66 
67  pf->random_pose_fn = random_pose_fn;
68  pf->random_pose_data = random_pose_data ;
69  pf->e_random_pose_data = e_random_pose_data ;
70 
71  pf->min_samples = min_samples;
72  pf->max_samples = max_samples;
73  pf->N_aux_particles = N_aux_particles;
74  // Control parameters for the population size calculation. [err] is
75  // the max error between the true distribution and the estimated
76  // distribution. [z] is the upper standard normal quantile for (1 -
77  // p), where p is the probability that the error on the estimated
78  // distrubition will be less than [err].
79  pf->pop_err = 0.01;
80  pf->pop_z = 3;
81  pf->dist_threshold = 0.5;
82 
83 
84 
85  pf->current_set = 0;
86  for (j = 0; j < 2; j++)
87  {
88  set = pf->sets + j;
89 
90  set->updated_index = NULL;
91  set->updated_count = 0;
92  set->sample_count = max_samples;
93  set->samples = calloc(max_samples, sizeof(pf_sample_t));
94 
95  for (i = 0; i < set->sample_count; i++)
96  {
97  sample = set->samples + i;
98  sample->pose.v[0] = 0.0;
99  sample->pose.v[1] = 0.0;
100  sample->pose.v[2] = 0.0;
101  sample->weight = 1.0 / max_samples;
102  }
103 
104 
105 
106  set->cluster_count = 0;
107  set->cluster_max_count = max_samples;
108  set->clusters = calloc(set->cluster_max_count, sizeof(pf_cluster_t));
109 
110  set->mean = pf_vector_zero();
111  set->cov = pf_matrix_zero();
112 
113  set->pf = pf ;
114  }
115 
116  pf->w_slow = 0.0;
117  pf->w_fast = 0.0;
118 
119  pf->alpha_slow = alpha_slow;
120  pf->alpha_fast = alpha_fast;
121  pf->crossover_alpha = crossover_alpha;
122  pf->mutation_prob = mutation_prob;
123 
124  //set converged to 0
125  pf_init_converged(pf);
126 
127  return pf;
128 }
129 
130 // Free an existing filter
131 void pf_free(pf_t *pf)
132 {
133  int i;
135  free(pf->limit_cache);
136 
137  for (i = 0; i < 2; i++)
138  {
139  free(pf->sets[i].clusters);
141  pf_kdtree_free(pf->sets[i].kdtree);
142  free(pf->sets[i].samples);
143  if(pf->model.use_optimal_filter)
144  free(pf->sets[i].aux_samples);
145  }
146  free(pf);
147 
148  return;
149 }
150 
151 // Initialize the filter using a guassian
152 void pf_init(pf_t *pf, pf_vector_t mean, pf_matrix_t cov)
153 {
154  int i;
156  pf_sample_t *sample, *aux_sample;
157  pf_pdf_gaussian_t *pdf;
158 
159  set = pf->sets + pf->current_set;
160 
161  if(pf->model.use_adaptive_sampling) // Create the kd tree for adaptive sampling
162  pf_kdtree_clear(set->kdtree);
163 
164  set->sample_count = pf->max_samples;
165 
166  pdf = pf_pdf_gaussian_alloc(mean, cov);
167 
168  if(pf->model.use_adaptive_sampling) // Compute the new sample poses
169  for (i = 0; i < set->sample_count; i++)
170  {
171  sample = set->samples + i;
172  sample->weight = 1.0 / pf->max_samples;
173  sample->pose = pf_pdf_gaussian_sample(pdf);
174 
175  // Add sample to histogram
176  pf_kdtree_insert(set->kdtree, sample->pose, sample->weight);
177  }
178  else
179  for (i = 0; i < set->sample_count; i++)
180  {
181  sample = set->samples + i;
182  sample->weight = 1.0 / pf->max_samples;
183  sample->pose = pf_pdf_gaussian_sample(pdf);
184 
185  }
186 
187  if(pf->model.use_optimal_filter)
188  { for (int j = 0; j < set->sample_count; j++)
189  { sample = set->samples + j ;
190  for ( int loop=0 ; loop < pf->N_aux_particles ; loop++)
191  {
192  aux_sample = set->aux_samples + (j*pf->N_aux_particles+loop) ;
193  aux_sample->pose = sample->pose;
194  aux_sample->weight = 1.0;
195  }
196  }
197  }
198 
199  pf->w_slow = pf->w_fast = 0.0;
200 
202 
203  // Re-compute cluster statistics
204  pf_cluster_stats(pf, set);
205 
206  //set converged to 0
207  pf_init_converged(pf);
208 
209  return;
210 }
211 
212 
213 // Initialize the filter using some model
214 void pf_init_model(pf_t *pf, pf_init_model_fn_t init_fn, void *init_data , void *e_init_data)
215 {
216  int i;
218  pf_sample_t *sample, *aux_sample;
219 
220  set = pf->sets + pf->current_set;
221 
222  if(pf->model.use_adaptive_sampling) // Create the kd tree for adaptive sampling
223  pf_kdtree_clear(set->kdtree);
224 
225  set->sample_count = pf->max_samples;
226 
227  if(pf->model.use_adaptive_sampling) // Compute the new sample poses
228  for (i = 0; i < set->sample_count; i++)
229  {
230  sample = set->samples + i;
231  sample->weight = 1.0 / pf->max_samples;
232  sample->pose = (*init_fn) (pf, init_data , e_init_data);
233 
234  // Add sample to histogram
235  pf_kdtree_insert(set->kdtree, sample->pose, sample->weight);
236  }
237  else
238  for (i = 0; i < set->sample_count; i++)
239  {
240  sample = set->samples + i;
241  sample->weight = 1.0 / pf->max_samples;
242  sample->pose = (*init_fn) (pf, init_data , e_init_data);
243 
244  }
245  if(pf->model.use_optimal_filter)
246  { for (int j = 0; j < set->sample_count; j++)
247  { sample = set->samples + j ;
248  for ( int loop=0 ; loop < pf->N_aux_particles ; loop++)
249  {
250  aux_sample = set->aux_samples + (j*pf->N_aux_particles+loop) ;
251  aux_sample->pose = sample->pose;
252  aux_sample->weight = 1.0 ;
253  }
254  }
255  }
256 
257  pf->w_slow = pf->w_fast = 0.0;
258 
259  // Re-compute cluster statistics
260  pf_cluster_stats(pf, set);
261 
262  //set converged to 0
263  pf_init_converged(pf);
264 
265  return;
266 }
267 
270  set = pf->sets + pf->current_set;
271  set->converged = 0;
272  pf->converged = 0;
273 }
274 
276 {
277  int i;
279  pf_sample_t *sample;
280  double total;
281 
282  set = pf->sets + pf->current_set;
283  double mean_x = 0, mean_y = 0;
284 
285  for (i = 0; i < set->sample_count; i++){
286  sample = set->samples + i;
287 
288  mean_x += sample->pose.v[0];
289  mean_y += sample->pose.v[1];
290  }
291  mean_x /= set->sample_count;
292  mean_y /= set->sample_count;
293 
294  for (i = 0; i < set->sample_count; i++){
295  sample = set->samples + i;
296  if(fabs(sample->pose.v[0] - mean_x) > pf->dist_threshold ||
297  fabs(sample->pose.v[1] - mean_y) > pf->dist_threshold){
298  set->converged = 0;
299  pf->converged = 0;
300  return 0;
301  }
302  }
303  set->converged = 1;
304  pf->converged = 1;
305  return 1;
306 }
307 
308 // Update the filter with some new action
309 void pf_update_action(pf_t *pf, pf_action_model_fn_t action_fn, void *action_data)
310 {
312 
313  set = pf->sets + pf->current_set;
314 
315  (*action_fn) (action_data, set);
316 
317  return;
318 }
319 
320 #include <float.h>
321 
323 {
324 
325  return;
326 
327 }
328 // Update the filter with some new sensor observation
329 void pf_update_sensor(pf_t *pf, pf_laser_model_fn_t laser_fn, void *laser_data)
330 {
331  int i;
333  pf_sample_t *sample, *aux_sample;
334  double total;
335  double best;
336 
337  set = pf->sets + pf->current_set;
338  total = 0.0 ;
339  // Compute the sample weights
340 
341  (*laser_fn) (laser_data, set);
342 
343  if(pf->model.use_optimal_filter && set->updated_count == 0)
344  for (int j = 0; j < set->sample_count; j++)
345  { sample = set->samples + j ;
346  total += sample->weight;
347  best = 0.0 ;
348  for ( int loop=0 ; loop < pf->N_aux_particles ; loop++)
349  {
350  aux_sample = set->aux_samples + (j*pf->N_aux_particles+loop) ;
351  if(aux_sample->weight > best)
352  {
353  sample->pose = aux_sample->pose; //cause if intelligent true || resample interval > 1
354  best = aux_sample->weight;
355  }
356  }
357  }
358  else
359  for (i = 0; i < set->sample_count; i++)
360  {
361  sample = set->samples + i;
362  total += sample->weight;
363  }
364 
365  set->n_effective = 0;
366 
367  if (total > 0.0)
368  { if(pf->model.use_crossover_mutation && set->updated_count == 0)
369  { // for (i = 0; i < set->sample_count; i++)
370  // {
371  set->total_weight = total;
372  // sample = set->samples + i;
373  //sample->weight /= total;
374 
375  // }
376 
377  return ;
378  }
379  // Normalize weights
380  double w_avg=0.0;
381  for (i = 0; i < set->sample_count; i++)
382  {
383  sample = set->samples + i;
384  w_avg += sample->weight;
385  sample->weight /= total;
386  set->n_effective += sample->weight*sample->weight;
387 
388  }
389 
390  // Update running averages of likelihood of samples (Prob Rob p258)
391  w_avg /= set->sample_count;
392  if(pf->w_slow == 0.0)
393  pf->w_slow = w_avg;
394  else
395  pf->w_slow += pf->alpha_slow * (w_avg - pf->w_slow);
396  if(pf->w_fast == 0.0)
397  pf->w_fast = w_avg;
398  else
399  pf->w_fast += pf->alpha_fast * (w_avg - pf->w_fast);
400  // printf("w_avg: %e slow: %e fast: %e\n",
401  // w_avg, pf->w_slow, pf->w_fast);
402  }
403  else
404  {
405  // Handle zero total
406  for (i = 0; i < set->sample_count; i++)
407  {
408  sample = set->samples + i;
409  sample->weight = 1.0 / set->sample_count;
410  }
411  }
412 
413  set->n_effective = 1.0/set->n_effective;
414 
415 
416 
417  return;
418 }
419 
420 // copy set a to set b
422 {
423  int i;
424  double total;
425  pf_sample_t *sample_a, *sample_b;
426  pf_t* pf ;
427 
428  pf = set_a->pf;
429 
430  if(set_a->pf->model.use_adaptive_sampling)// Clean set b's kdtree
431  pf_kdtree_clear(set_b->kdtree);
432 
433  // Copy samples from set a to create set b
434  total = 0;
435  set_b->sample_count = 0;
437  for(i = 0; i < set_a->sample_count; i++)
438  {
439  sample_b = set_b->samples + set_b->sample_count++;
440 
441  sample_a = set_a->samples + i;
442 
443  assert(sample_a->weight > 0);
444 
445  // Copy sample a to sample b
446  sample_b->pose = sample_a->pose;
447  sample_b->weight = sample_a->weight;
448 
449  total += sample_b->weight;
450 
451  // Add sample to histogram
452  pf_kdtree_insert(set_b->kdtree, sample_b->pose, sample_b->weight);
453  }
454  else
455  for(i = 0; i < set_a->sample_count; i++)
456  {
457  sample_b = set_b->samples + set_b->sample_count++;
458 
459  sample_a = set_a->samples + i;
460 
461  assert(sample_a->weight > 0);
462 
463  // Copy sample a to sample b
464  sample_b->pose = sample_a->pose;
465  sample_b->weight = sample_a->weight;
466 
467  total += sample_b->weight;
468 
469  }
470 
471  // Normalize weights
472  for (i = 0; i < set_b->sample_count; i++)
473  {
474  sample_b = set_b->samples + i;
475  sample_b->weight /= total;
476  }
477 
478  set_b->converged = set_a->converged;
479 }
480 
481 // Resample the distribution
483 {
484  int i;
485  double total;
486  pf_sample_set_t *set_a, *set_b;
487  pf_sample_t *sample_a, *sample_b;
488 
489  //double r,c,U;
490  //int m;
491  //double count_inv;
492  double* c;
493 
494  double w_diff;
495 
496  set_a = pf->sets + pf->current_set;
497  set_b = pf->sets + (pf->current_set + 1) % 2;
498 
499  if (pf->selective_resampling != 0)
500  {
501  if (set_a->n_effective > 0.5*(set_a->sample_count))
502  { // printf("N_eff: %9.6f\n", set_a->n_effective );
503  // copy set a to b
504  copy_set(set_a,set_b);
505 
506  // Re-compute cluster statistics
507  pf_cluster_stats(pf, set_b);
508 
509  // Use the newly created sample set
510  pf->current_set = (pf->current_set + 1) % 2;
511  return;
512  }
513  }
514 
515  // Build up cumulative probability table for resampling.
516  // TODO: Replace this with a more efficient procedure
517  // (e.g., http://www.network-theory.co.uk/docs/gslref/GeneralDiscreteDistributions.html)
518  c = (double*)malloc(sizeof(double)*(set_a->sample_count+1));
519  c[0] = 0.0;
520  for(i=0;i<set_a->sample_count;i++)
521  c[i+1] = c[i]+set_a->samples[i].weight;
522 
523 
524 
525 
526  // Draw samples from set a to create set b.
527  total = 0;
528  set_b->sample_count = 0;
529 
530  w_diff = 1.0 - pf->w_fast / pf->w_slow;
531  if(w_diff < 0.0)
532  w_diff = 0.0;
533  //printf("w_diff: %9.6f\n", w_diff);
534 
535  // Can't (easily) combine low-variance sampler with KLD adaptive
536  // sampling, so we'll take the more traditional route.
537  /*
538  // Low-variance resampler, taken from Probabilistic Robotics, p110
539  count_inv = 1.0/set_a->sample_count;
540  r = drand48() * count_inv;
541  c = set_a->samples[0].weight;
542  i = 0;
543  m = 0;
544  */
546  { pf_kdtree_clear(set_b->kdtree); // Create the kd tree for adaptive sampling
547  while(set_b->sample_count < pf->max_samples)
548  {
549  sample_b = set_b->samples + set_b->sample_count++;
550 
551  if(drand48() < w_diff)
552  sample_b->pose = (pf->random_pose_fn)(pf, pf->random_pose_data , pf->e_random_pose_data );
553  else
554  {
555  // Can't (easily) combine low-variance sampler with KLD adaptive
556  // sampling, so we'll take the more traditional route.
557  /*
558  // Low-variance resampler, taken from Probabilistic Robotics, p110
559  U = r + m * count_inv;
560  while(U>c)
561  {
562  i++;
563  // Handle wrap-around by resetting counters and picking a new random
564  // number
565  if(i >= set_a->sample_count)
566  {
567  r = drand48() * count_inv;
568  c = set_a->samples[0].weight;
569  i = 0;
570  m = 0;
571  U = r + m * count_inv;
572  continue;
573  }
574  c += set_a->samples[i].weight;
575  }
576  m++;
577  */
578 
579  // Naive discrete event sampler
580  double r;
581  r = drand48();
582  for(i=0;i<set_a->sample_count;i++)
583  {
584  if((c[i] <= r) && (r < c[i+1]))
585  break;
586  }
587  assert(i<set_a->sample_count);
588 
589  sample_a = set_a->samples + i;
590 
591  assert(sample_a->weight > 0);
592 
593  // Add sample to list
594  sample_b->pose = sample_a->pose;
595  }
596 
597  sample_b->weight = 1.0;
598  total += sample_b->weight;
599 
600  // Add sample to histogram
601  pf_kdtree_insert(set_b->kdtree, sample_b->pose, sample_b->weight);
602 
603  // See if we have enough samples yet
604  if (set_b->sample_count > pf_resample_limit(pf, set_b->kdtree->leaf_count))
605  break;
606  }
607  }
608  else
609  for( int loop= 0 ; loop < set_a->sample_count ; loop++)
610  {
611  sample_b = set_b->samples + set_b->sample_count++;
612 
613  if(drand48() < w_diff)
614  sample_b->pose = (pf->random_pose_fn)(pf, pf->random_pose_data , pf->e_random_pose_data );
615  else
616  {
617  // Can't (easily) combine low-variance sampler with KLD adaptive
618  // sampling, so we'll take the more traditional route.
619  /*
620  // Low-variance resampler, taken from Probabilistic Robotics, p110
621  U = r + m * count_inv;
622  while(U>c)
623  {
624  i++;
625  // Handle wrap-around by resetting counters and picking a new random
626  // number
627  if(i >= set_a->sample_count)
628  {
629  r = drand48() * count_inv;
630  c = set_a->samples[0].weight;
631  i = 0;
632  m = 0;
633  U = r + m * count_inv;
634  continue;
635  }
636  c += set_a->samples[i].weight;
637  }
638  m++;
639  */
640 
641  // Naive discrete event sampler
642  double r;
643  r = drand48();
644  for(i=0;i<set_a->sample_count;i++)
645  {
646  if((c[i] <= r) && (r < c[i+1]))
647  break;
648  }
649  assert(i<set_a->sample_count);
650 
651  sample_a = set_a->samples + i;
652 
653  assert(sample_a->weight > 0);
654 
655  // Add sample to list
656  sample_b->pose = sample_a->pose;
657  }
658 
659  sample_b->weight = 1.0;
660  total += sample_b->weight;
661 
662  }
663 
664  // Reset averages, to avoid spiraling off into complete randomness.
665  if(w_diff > 0.0)
666  pf->w_slow = pf->w_fast = 0.0;
667 
668  //fprintf(stderr, "\n\n");
669 
670  // Normalize weights
671  for (i = 0; i < set_b->sample_count; i++)
672  {
673  sample_b = set_b->samples + i;
674  sample_b->weight /= total;
675  }
676 
677  // Re-compute cluster statistics
678  pf_cluster_stats(pf, set_b);
679 
680  // Use the newly created sample set
681  pf->current_set = (pf->current_set + 1) % 2;
682 
684 
685  free(c);
686  return;
687 }
688 
689 void pf_update_crossover_mutation(pf_t *pf, pf_reupdate_sensor_fn_t laser_fn, void *laser_data)
690 { int i ,j, num_ch , num_cl;
691  double r ;
692  int* C_h ;
693  int* C_l ;
694  double total;
696  pf_sample_t *sample , *sample_l , *sample_h ;
697 
698  num_ch = num_cl = 0 ;
699  set = pf->sets + pf->current_set;
700 
701  C_h = (int*)malloc(sizeof(int)*(set->sample_count));
702  C_l = (int*)malloc(sizeof(int)*(set->sample_count));
703 
704 if(set->total_weight ==0)
705  return;
706 total = set->total_weight ;
707  for(i=0 ; i<set->sample_count ; i++)
708  {
709  sample = set->samples + i ;
710 
711  if(sample->weight/total >= 1.0/set->sample_count)
712  C_h[num_ch++] = i ;
713 
714  else
715  C_l[num_cl++] = i ;
716  }
717 
718 
719  if(num_cl ==0)
720  {
721  return;
722  }
723 
724  num_cl /=3; // take only third of particles to make sure of diversity of particles
725  //printf("num_cl: %9.6d\n", num_cl);
726  for(i=0 ; i<num_cl ; i++)
727  { r = drand48()*num_ch;
728  //printf("r: %9.6f\n", r);
729  sample_l = set->samples +C_l[i] ;
730  sample_h = set->samples +C_h[(int)r] ;
731 
732  sample_l->weight /= sample_l->last_obs ;
733  r = drand48() ;
734 
735  if ( r <= pf->mutation_prob)
736  {
737  sample_l->pose.v[0] = pf->crossover_alpha*(2*sample_h->pose.v[0] - sample_l->pose.v[0])
738  + (1 - pf->crossover_alpha)*sample_h->pose.v[0];
739  sample_l->pose.v[1] = pf->crossover_alpha*(2*sample_h->pose.v[1] - sample_l->pose.v[1])
740  + (1 - pf->crossover_alpha)*sample_h->pose.v[1];
741  sample_l->pose.v[2] = pf->crossover_alpha*(2*sample_h->pose.v[2] - sample_l->pose.v[2])
742  + (1 - pf->crossover_alpha)*sample_h->pose.v[2];
743  }
744  else
745  {
746  sample_l->pose.v[0] = pf->crossover_alpha*sample_l->pose.v[0]
747  + (1 - pf->crossover_alpha)*sample_h->pose.v[0];
748  sample_l->pose.v[1] = pf->crossover_alpha*sample_l->pose.v[1]
749  + (1 - pf->crossover_alpha)*sample_h->pose.v[1];
750  sample_l->pose.v[2] = pf->crossover_alpha*sample_l->pose.v[2]
751  + (1 - pf->crossover_alpha)*sample_h->pose.v[2];
752  }
753 
754 
755  }
756  set->updated_index = C_l;
757  set->updated_count = num_cl;
758 
759 
760  (*laser_fn) (pf, laser_data); //update weights again for changed particles over particels
761 
762  set->updated_index = NULL;
763  set->updated_count = 0;
764  free(C_h) ;free(C_l);
765 }
766 
767 
768 // Compute the required number of samples, given that there are k bins
769 // with samples in them. This is taken directly from Fox et al.
770 int pf_resample_limit(pf_t *pf, int k)
771 {
772  double a, b, c, x;
773  int n;
774 
775  // Return max_samples in case k is outside expected range, this shouldn't
776  // happen, but is added to prevent any runtime errors
777  if (k < 1 || k > pf->max_samples)
778  return pf->max_samples;
779 
780  // Return value if cache is valid, which means value is non-zero positive
781  if (pf->limit_cache[k-1] > 0)
782  return pf->limit_cache[k-1];
783 
784  if (k == 1)
785  {
786  pf->limit_cache[k-1] = pf->max_samples;
787  return pf->max_samples;
788  }
789 
790  a = 1;
791  b = 2 / (9 * ((double) k - 1));
792  c = sqrt(2 / (9 * ((double) k - 1))) * pf->pop_z;
793  x = a - b + c;
794 
795  n = (int) ceil((k - 1) / (2 * pf->pop_err) * x * x * x);
796 
797  if (n < pf->min_samples)
798  {
799  pf->limit_cache[k-1] = pf->min_samples;
800  return pf->min_samples;
801  }
802  if (n > pf->max_samples)
803  {
804  pf->limit_cache[k-1] = pf->max_samples;
805  return pf->max_samples;
806  }
807 
808  pf->limit_cache[k-1] = n;
809  return n;
810 }
811 
812 
813 // Re-compute the cluster statistics for a sample set
815 {
816  if(pf->model.use_adaptive_sampling)// Cluster the samples
817 { int i, j, k, cidx;
818  pf_sample_t *sample;
819  pf_cluster_t *cluster;
820 
821  // Workspace
822  double m[4], c[2][2];
823  size_t count;
824  double weight;
825 
826 
827  pf_kdtree_cluster(set->kdtree); // Initialize cluster stats
828  set->cluster_count = 0;
829 
830 
831 
832  for (i = 0; i < set->cluster_max_count; i++)
833  {
834  cluster = set->clusters + i;
835  cluster->count = 0;
836  cluster->weight = 0;
837  cluster->mean = pf_vector_zero();
838  cluster->cov = pf_matrix_zero();
839 
840  for (j = 0; j < 4; j++)
841  cluster->m[j] = 0.0;
842  for (j = 0; j < 2; j++)
843  for (k = 0; k < 2; k++)
844  cluster->c[j][k] = 0.0;
845  }
846 
847  // Initialize overall filter stats
848  count = 0;
849  weight = 0.0;
850  set->mean = pf_vector_zero();
851  set->cov = pf_matrix_zero();
852  for (j = 0; j < 4; j++)
853  m[j] = 0.0;
854  for (j = 0; j < 2; j++)
855  for (k = 0; k < 2; k++)
856  c[j][k] = 0.0;
857 
858 
859 
860  for (i = 0; i < set->sample_count; i++) // Compute cluster stats
861  {
862  sample = set->samples + i;
863 
864  //printf("%d %f %f %f\n", i, sample->pose.v[0], sample->pose.v[1], sample->pose.v[2]);
865 
866  // Get the cluster label for this sample
867 
868  cidx = pf_kdtree_get_cluster(set->kdtree, sample->pose);
869  assert(cidx >= 0);
870  if (cidx >= set->cluster_max_count)
871  continue;
872  if (cidx + 1 > set->cluster_count)
873  set->cluster_count = cidx + 1;
874 
875  cluster = set->clusters + cidx;
876 
877  cluster->count += 1;
878  cluster->weight += sample->weight;
879 
880  count += 1;
881  weight += sample->weight;
882 
883  // Compute mean
884  cluster->m[0] += sample->weight * sample->pose.v[0];
885  cluster->m[1] += sample->weight * sample->pose.v[1];
886  cluster->m[2] += sample->weight * cos(sample->pose.v[2]);
887  cluster->m[3] += sample->weight * sin(sample->pose.v[2]);
888 
889  m[0] += sample->weight * sample->pose.v[0];
890  m[1] += sample->weight * sample->pose.v[1];
891  m[2] += sample->weight * cos(sample->pose.v[2]);
892  m[3] += sample->weight * sin(sample->pose.v[2]);
893 
894  // Compute covariance in linear components
895  for (j = 0; j < 2; j++)
896  for (k = 0; k < 2; k++)
897  {
898  cluster->c[j][k] += sample->weight * sample->pose.v[j] * sample->pose.v[k];
899  c[j][k] += sample->weight * sample->pose.v[j] * sample->pose.v[k];
900  }
901  }
902 
903  // Normalize
904  for (i = 0; i < set->cluster_count; i++)
905  {
906  cluster = set->clusters + i;
907 
908  cluster->mean.v[0] = cluster->m[0] / cluster->weight;
909  cluster->mean.v[1] = cluster->m[1] / cluster->weight;
910  cluster->mean.v[2] = atan2(cluster->m[3], cluster->m[2]);
911 
912  cluster->cov = pf_matrix_zero();
913 
914  // Covariance in linear components
915  for (j = 0; j < 2; j++)
916  for (k = 0; k < 2; k++)
917  cluster->cov.m[j][k] = cluster->c[j][k] / cluster->weight -
918  cluster->mean.v[j] * cluster->mean.v[k];
919 
920  // Covariance in angular components; I think this is the correct
921  // formula for circular statistics.
922  cluster->cov.m[2][2] = -2 * log(sqrt(cluster->m[2] * cluster->m[2] +
923  cluster->m[3] * cluster->m[3]));
924 
925  // printf("cluster %d %d %f (%f %f %f)\n", i, cluster->count, cluster->weight,
926  // cluster->mean.v[0], cluster->mean.v[1], cluster->mean.v[2]);
927  }
928  // Compute overall filter stats
929  set->mean.v[0] = m[0] / weight;
930  set->mean.v[1] = m[1] / weight;
931  set->mean.v[2] = atan2(m[3], m[2]);
932 
933  // Covariance in linear components
934  for (j = 0; j < 2; j++)
935  for (k = 0; k < 2; k++)
936  set->cov.m[j][k] = c[j][k] / weight - set->mean.v[j] * set->mean.v[k];
937 
938  set->cov.m[2][0] = set->cov.m[0][0] + set->cov.m[1][1];
939  // Covariance in angular components; I think this is the correct
940  // formula for circular statistics.
941  set->cov.m[2][2] = -2 * log(sqrt(m[2] * m[2] + m[3] * m[3]));
942 
943  return;
944  }
945  else
946  {
947  int i, j, k;
948  pf_sample_t *sample;
949  pf_cluster_t *cluster;
950 
951  // Workspace
952  double m[4], c[2][2];
953  size_t count;
954  double weight;
955  set->cluster_count = 1;
956 
957  cluster = set->clusters + 0;
958  cluster->count = set->sample_count;
959  cluster->weight = 1.0;
960  cluster->mean = pf_vector_zero();
961  cluster->cov = pf_matrix_zero();
962 
963  for (j = 0; j < 4; j++)
964  cluster->m[j] = 0.0;
965  for (j = 0; j < 2; j++)
966  for (k = 0; k < 2; k++)
967  cluster->c[j][k] = 0.0;
968 
969 
970  // Initialize overall filter stats
971 
972  set->mean = pf_vector_zero();
973  set->cov = pf_matrix_zero();
974  for (j = 0; j < 4; j++)
975  m[j] = 0.0;
976  for (j = 0; j < 2; j++)
977  for (k = 0; k < 2; k++)
978  c[j][k] = 0.0;
979 
980  // c[2][0] = 0.0;
981 // Compute cluster stats
982  for (i = 0; i < set->sample_count; i++)
983  {
984  sample = set->samples + i;
985 
986  //printf("%d %f %f %f\n", i, sample->pose.v[0], sample->pose.v[1], sample->pose.v[2]);
987 
988 
989  // Compute mean
990 
991  m[0] += sample->weight * sample->pose.v[0];
992  m[1] += sample->weight * sample->pose.v[1];
993  m[2] += sample->weight * cos(sample->pose.v[2]);
994  m[3] += sample->weight * sin(sample->pose.v[2]);
995 
996  // Compute covariance in linear components
997  for (j = 0; j < 2; j++)
998  for (k = 0; k < 2; k++)
999  {
1000  c[j][k] += sample->weight * sample->pose.v[j] * sample->pose.v[k];
1001 
1002  }
1003  // c[2][0] += sample->weight * sqrt( sample->pose.v[0] * sample->pose.v[0] + sample->pose.v[1] * sample->pose.v[1]) *
1004  // sqrt( sample->pose.v[0] * sample->pose.v[0] + sample->pose.v[1] * sample->pose.v[1]) ;
1005  }
1006 
1007  // Compute overall filter stats
1008 
1009  cluster->mean.v[0] = m[0];
1010  cluster->mean.v[1] = m[1];
1011  cluster->mean.v[2] = atan2(m[3], m[2]);
1012 
1013 
1014  set->mean.v[0] = cluster->mean.v[0];
1015  set->mean.v[1] = cluster->mean.v[1];
1016  set->mean.v[2] = cluster->mean.v[2];
1017 
1018 
1019  // Covariance in linear components
1020  for (j = 0; j < 2; j++)
1021  for (k = 0; k < 2; k++)
1022  {
1023  cluster->cov.m[j][k] = c[j][k] - set->mean.v[j] * set->mean.v[k];
1024  set->cov.m[j][k] = cluster->cov.m[j][k];
1025  }
1026  cluster->cov.m[2][0] = cluster->cov.m[0][0] +cluster->cov.m[1][1];
1027 
1028  // cluster->cov.m[2][0] = c[2][0] - sqrt( set->mean.v[0] * set->mean.v[0] +set->mean.v[1] * set->mean.v[1]) *sqrt( set->mean.v[0] * set->mean.v[0] +set->mean.v[1] * set->mean.v[1]) ;
1029  set->cov.m[2][0] = cluster->cov.m[2][0];
1030 
1031  // printf("cluster %f \n",set->cov.m[2][0] );
1032  // Covariance in angular components; I think this is the correct
1033  // formula for circular statistics.
1034  cluster->cov.m[2][2] = -2 * log(sqrt(m[2] * m[2] + m[3] * m[3]));
1035  set->cov.m[2][2] = cluster->cov.m[2][2];
1036 
1037  return;
1038  }
1039 
1040 
1041 }
1042 
1044 {
1047  pf->model.use_self_adaptive = pf_model->use_self_adaptive;
1049 
1050 
1051  for (int j = 0; j < 2; j++)
1052  { pf_sample_set_t *set = pf->sets + j;
1053  if(pf->model.use_adaptive_sampling)
1054  set->kdtree = pf_kdtree_alloc(3 * pf->max_samples);
1055  if(pf->model.use_optimal_filter)
1056  { int aux_count = pf->max_samples*pf->N_aux_particles;
1057  set->aux_samples = calloc(pf->max_samples*pf->N_aux_particles, sizeof(pf_sample_t));
1058  for (int i = 0; i < pf->max_samples*pf->N_aux_particles ; i++)
1059  {
1060  pf_sample_t* aux_sample = set->aux_samples + i;
1061  aux_sample->pose.v[0] = 0.0;
1062  aux_sample->pose.v[1] = 0.0;
1063  aux_sample->pose.v[2] = 0.0;
1064  aux_sample->weight = 1.0 ;
1065  }
1066  }
1067  }
1068  if(pf->model.use_adaptive_sampling) // Number of leaf nodes is never higher than the max number of samples
1069  pf->limit_cache = calloc(pf->max_samples, sizeof(int));
1070 }
1071 
1072 void pf_set_selective_resampling(pf_t *pf, int selective_resampling)
1073 {
1074  pf->selective_resampling = selective_resampling;
1075 }
1076 
1077 // Compute the CEP statistics (mean and variance).
1078 void pf_get_cep_stats(pf_t *pf, pf_vector_t *mean, double *var)
1079 {
1080  int i;
1081  double mn, mx, my, mrr;
1083  pf_sample_t *sample;
1084 
1085  set = pf->sets + pf->current_set;
1086 
1087  mn = 0.0;
1088  mx = 0.0;
1089  my = 0.0;
1090  mrr = 0.0;
1091 
1092  for (i = 0; i < set->sample_count; i++)
1093  {
1094  sample = set->samples + i;
1095 
1096  mn += sample->weight;
1097  mx += sample->weight * sample->pose.v[0];
1098  my += sample->weight * sample->pose.v[1];
1099  mrr += sample->weight * sample->pose.v[0] * sample->pose.v[0];
1100  mrr += sample->weight * sample->pose.v[1] * sample->pose.v[1];
1101  }
1102 
1103  mean->v[0] = mx / mn;
1104  mean->v[1] = my / mn;
1105  mean->v[2] = 0.0;
1106 
1107  *var = mrr / mn - (mx * mx / (mn * mn) + my * my / (mn * mn));
1108 
1109  return;
1110 }
1111 
1112 
1113 // Get the statistics for a particular cluster.
1114 int pf_get_cluster_stats(pf_t *pf, int clabel, double *weight,
1115  pf_vector_t *mean, pf_matrix_t *cov)
1116 {
1118  pf_cluster_t *cluster;
1119 
1120  set = pf->sets + pf->current_set;
1121 
1122  if (clabel >= set->cluster_count)
1123  return 0;
1124  cluster = set->clusters + clabel;
1125 
1126  *weight = cluster->weight;
1127  *mean = cluster->mean;
1128  *cov = cluster->cov;
1129 
1130  return 1;
1131 }
pf_sample_t::weight
double weight
Definition: pf.h:78
pf_cluster_t::m
double m[4]
Definition: pf.h:102
_pf_t::selective_resampling
int selective_resampling
Definition: pf.h:186
pf_matrix_zero
pf_matrix_t pf_matrix_zero()
Definition: pf_vector.c:142
_pf_t::alpha_fast
double alpha_fast
Definition: pf.h:172
pf_kdtree_cluster
void pf_kdtree_cluster(pf_kdtree_t *self)
Definition: pf_kdtree.c:366
pf_kdtree.h
pf.h
pf_vector_t
Definition: pf_vector.h:46
_pf_model_type::use_adaptive_sampling
bool use_adaptive_sampling
Definition: pf.h:146
_pf_t::e_random_pose_data
void * e_random_pose_data
Definition: pf.h:180
_pf_t::w_fast
double w_fast
Definition: pf.h:169
pf_get_cluster_stats
int pf_get_cluster_stats(pf_t *pf, int clabel, double *weight, pf_vector_t *mean, pf_matrix_t *cov)
Definition: pf.c:1114
_pf_t::random_pose_data
void * random_pose_data
Definition: pf.h:179
pf_update_action
void pf_update_action(pf_t *pf, pf_action_model_fn_t action_fn, void *action_data)
Definition: pf.c:309
_pf_t::crossover_alpha
double crossover_alpha
Definition: pf.h:175
pf_alloc
pf_t * pf_alloc(int min_samples, int max_samples, int N_aux_particles, double alpha_slow, double alpha_fast, double crossover_alpha, double mutation_prob, pf_init_model_fn_t random_pose_fn, void *random_pose_data, void *e_random_pose_data)
Definition: pf.c:54
_pf_sample_set_t::pf
struct _pf_t * pf
Definition: pf.h:131
pf_kdtree_get_cluster
int pf_kdtree_get_cluster(pf_kdtree_t *self, pf_vector_t pose)
Definition: pf_kdtree.c:176
pf_reupdate_sensor_fn_t
void(* pf_reupdate_sensor_fn_t)(struct _pf_t *pf, void *laser_data)
Definition: pf.h:67
_pf_sample_set_t::samples
pf_sample_t * samples
Definition: pf.h:111
time.h
pf_laser_model_fn_t
void(* pf_laser_model_fn_t)(void *laser_data, struct _pf_sample_set_t *set)
Definition: pf.h:64
_pf_sample_set_t::n_effective
double n_effective
Definition: pf.h:124
pf_cluster_t::c
double c[2][2]
Definition: pf.h:102
pf_update_sensor
void pf_update_sensor(pf_t *pf, pf_laser_model_fn_t laser_fn, void *laser_data)
Definition: pf.c:329
_pf_t::pop_err
double pop_err
Definition: pf.h:158
_pf_sample_set_t::converged
int converged
Definition: pf.h:123
_pf_sample_set_t::clusters
pf_cluster_t * clusters
Definition: pf.h:118
_pf_sample_set_t::kdtree
pf_kdtree_t * kdtree
Definition: pf.h:114
_pf_model_type::use_self_adaptive
bool use_self_adaptive
Definition: pf.h:143
_pf_sample_set_t::sample_count
int sample_count
Definition: pf.h:110
drand48
static double drand48(void)
Definition: portable_utils.hpp:13
pf_update_resample
void pf_update_resample(pf_t *pf)
Definition: pf.c:482
_pf_sample_set_t
Definition: pf.h:107
_pf_t::dist_threshold
double dist_threshold
Definition: pf.h:182
_pf_t::converged
int converged
Definition: pf.h:183
pf_kdtree_alloc
pf_kdtree_t * pf_kdtree_alloc(int max_size)
Definition: pf_kdtree.c:74
pf_pdf_gaussian_t
Definition: pf_pdf.h:53
srand48
static void srand48(long int seedval)
Definition: portable_utils.hpp:18
_pf_t::alpha_slow
double alpha_slow
Definition: pf.h:172
pf_set_selective_resampling
void pf_set_selective_resampling(pf_t *pf, int selective_resampling)
Definition: pf.c:1072
pf_matrix_t::m
double m[3][3]
Definition: pf_vector.h:55
_pf_t
Definition: pf.h:150
_pf_t::sets
pf_sample_set_t sets[2]
Definition: pf.h:166
_pf_t::min_samples
int min_samples
Definition: pf.h:155
pf_cluster_stats
void pf_cluster_stats(pf_t *pf, pf_sample_set_t *set)
Definition: pf.c:814
pf_pdf_gaussian_free
void pf_pdf_gaussian_free(pf_pdf_gaussian_t *pdf)
Definition: pf_pdf.c:83
pf_cluster_t::mean
pf_vector_t mean
Definition: pf.h:98
_pf_t::pop_z
double pop_z
Definition: pf.h:158
n
static int n
Definition: eig3.c:14
pf_update_crossover_mutation
void pf_update_crossover_mutation(pf_t *pf, pf_reupdate_sensor_fn_t laser_fn, void *laser_data)
Definition: pf.c:689
_pf_t::model
pf_model_type model
Definition: pf.h:153
map.h
pf_vector_zero
pf_vector_t pf_vector_zero()
Definition: pf_vector.c:46
pf_kdtree_clear
void pf_kdtree_clear(pf_kdtree_t *self)
Definition: pf_kdtree.c:108
pf_kdtree_t::leaf_count
int leaf_count
Definition: pf_kdtree.h:83
_pf_t::limit_cache
int * limit_cache
Definition: pf.h:161
pf_init_model
void pf_init_model(pf_t *pf, pf_init_model_fn_t init_fn, void *init_data, void *e_init_data)
Definition: pf.c:214
pf_init_model_fn_t
pf_vector_t(* pf_init_model_fn_t)(struct _pf_t *pf, void *init_data, void *e_init_data)
Definition: pf.h:55
pf_pdf.h
pf_sample_t
Definition: pf.h:72
_pf_t::mutation_prob
double mutation_prob
Definition: pf.h:175
set
ROSCPP_DECL void set(const std::string &key, bool b)
pf_pdf_gaussian_alloc
pf_pdf_gaussian_t * pf_pdf_gaussian_alloc(pf_vector_t x, pf_matrix_t cx)
Definition: pf_pdf.c:55
_pf_model_type
Definition: pf.h:135
pf_sample_t::last_obs
double last_obs
Definition: pf.h:81
pf_set_model_type
void pf_set_model_type(pf_t *pf, pf_model_type *pf_model)
Definition: pf.c:1043
pf_init
void pf_init(pf_t *pf, pf_vector_t mean, pf_matrix_t cov)
Definition: pf.c:152
pf_sample_t::pose
pf_vector_t pose
Definition: pf.h:75
pf_cluster_t
Definition: pf.h:89
pf_free
void pf_free(pf_t *pf)
Definition: pf.c:131
pf_kdtree_insert
void pf_kdtree_insert(pf_kdtree_t *self, pf_vector_t pose, double value)
Definition: pf_kdtree.c:120
portable_utils.hpp
pf_cluster_t::weight
double weight
Definition: pf.h:95
_pf_t::w_slow
double w_slow
Definition: pf.h:169
pf_resample_limit
static int pf_resample_limit(pf_t *pf, int k)
Definition: pf.c:770
pf_matrix_t
Definition: pf_vector.h:53
_pf_t::N_aux_particles
int N_aux_particles
Definition: pf.h:155
copy_set
void copy_set(pf_sample_set_t *set_a, pf_sample_set_t *set_b)
Definition: pf.c:421
_pf_t::max_samples
int max_samples
Definition: pf.h:155
_pf_t::random_pose_fn
pf_init_model_fn_t random_pose_fn
Definition: pf.h:178
_pf_sample_set_t::aux_samples
pf_sample_t * aux_samples
Definition: pf.h:112
assert.h
pf_get_cep_stats
void pf_get_cep_stats(pf_t *pf, pf_vector_t *mean, double *var)
Definition: pf.c:1078
pf_cluster_t::cov
pf_matrix_t cov
Definition: pf.h:99
_pf_t::current_set
int current_set
Definition: pf.h:165
_pf_model_type::use_optimal_filter
bool use_optimal_filter
Definition: pf.h:137
pf_init_converged
void pf_init_converged(pf_t *pf)
Definition: pf.c:268
pf_action_model_fn_t
void(* pf_action_model_fn_t)(void *action_data, struct _pf_sample_set_t *set)
Definition: pf.h:59
pf_cluster_t::count
int count
Definition: pf.h:92
pf_vector_t::v
double v[3]
Definition: pf_vector.h:53
_pf_model_type::use_crossover_mutation
bool use_crossover_mutation
Definition: pf.h:140
pf_kdtree_free
void pf_kdtree_free(pf_kdtree_t *self)
Definition: pf_kdtree.c:98
pf_pdf_gaussian_sample
pf_vector_t pf_pdf_gaussian_sample(pf_pdf_gaussian_t *pdf)
Definition: pf_pdf.c:114
pf_normlize_weight
void pf_normlize_weight(pf_t *pf)
Definition: pf.c:322
pf_update_converged
int pf_update_converged(pf_t *pf)
Definition: pf.c:275


gmcl
Author(s): Mhd Ali Alshikh Khalil, adler1994@gmail.com
autogenerated on Wed Mar 2 2022 00:20:14