pf.c
Go to the documentation of this file.
1 /*
2  * Player - One Hell of a Robot Server
3  * Copyright (C) 2000 Brian Gerkey & Kasper Stoy
4  * gerkey@usc.edu kaspers@robotics.usc.edu
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21 /**************************************************************************
22  * Desc: Simple particle filter for localization.
23  * Author: Andrew Howard
24  * Date: 10 Dec 2002
25  * CVS: $Id: pf.c 6345 2008-04-17 01:36:39Z gerkey $
26  *************************************************************************/
27 
28 #include <assert.h>
29 #include <math.h>
30 #include <stdlib.h>
31 #include <time.h>
32 
33 #include "amcl/pf/pf.h"
34 #include "amcl/pf/pf_pdf.h"
35 #include "amcl/pf/pf_kdtree.h"
36 #include "portable_utils.hpp"
37 
38 
39 // Compute the required number of samples, given that there are k bins
40 // with samples in them.
41 static int pf_resample_limit(pf_t *pf, int k);
42 
43 
44 
45 // Create a new filter
46 pf_t *pf_alloc(int min_samples, int max_samples,
47  double alpha_slow, double alpha_fast,
48  pf_init_model_fn_t random_pose_fn, void *random_pose_data)
49 {
50  int i, j;
51  pf_t *pf;
53  pf_sample_t *sample;
54 
55  srand48(time(NULL));
56 
57  pf = calloc(1, sizeof(pf_t));
58 
59  pf->random_pose_fn = random_pose_fn;
60  pf->random_pose_data = random_pose_data;
61 
62  pf->min_samples = min_samples;
63  pf->max_samples = max_samples;
64 
65  // Control parameters for the population size calculation. [err] is
66  // the max error between the true distribution and the estimated
67  // distribution. [z] is the upper standard normal quantile for (1 -
68  // p), where p is the probability that the error on the estimated
69  // distrubition will be less than [err].
70  pf->pop_err = 0.01;
71  pf->pop_z = 3;
72  pf->dist_threshold = 0.5;
73 
74  // Number of leaf nodes is never higher than the max number of samples
75  pf->limit_cache = calloc(max_samples, sizeof(int));
76 
77  pf->current_set = 0;
78  for (j = 0; j < 2; j++)
79  {
80  set = pf->sets + j;
81 
82  set->sample_count = max_samples;
83  set->samples = calloc(max_samples, sizeof(pf_sample_t));
84 
85  for (i = 0; i < set->sample_count; i++)
86  {
87  sample = set->samples + i;
88  sample->pose.v[0] = 0.0;
89  sample->pose.v[1] = 0.0;
90  sample->pose.v[2] = 0.0;
91  sample->weight = 1.0 / max_samples;
92  }
93 
94  // HACK: is 3 times max_samples enough?
95  set->kdtree = pf_kdtree_alloc(3 * max_samples);
96 
97  set->cluster_count = 0;
98  set->cluster_max_count = max_samples;
99  set->clusters = calloc(set->cluster_max_count, sizeof(pf_cluster_t));
100 
101  set->mean = pf_vector_zero();
102  set->cov = pf_matrix_zero();
103  }
104 
105  pf->w_slow = 0.0;
106  pf->w_fast = 0.0;
107 
108  pf->alpha_slow = alpha_slow;
109  pf->alpha_fast = alpha_fast;
110 
111  //set converged to 0
112  pf_init_converged(pf);
113 
114  return pf;
115 }
116 
117 // Free an existing filter
118 void pf_free(pf_t *pf)
119 {
120  int i;
121 
122  free(pf->limit_cache);
123 
124  for (i = 0; i < 2; i++)
125  {
126  free(pf->sets[i].clusters);
127  pf_kdtree_free(pf->sets[i].kdtree);
128  free(pf->sets[i].samples);
129  }
130  free(pf);
131 
132  return;
133 }
134 
135 // Initialize the filter using a gaussian
136 void pf_init(pf_t *pf, pf_vector_t mean, pf_matrix_t cov)
137 {
138  int i;
140  pf_sample_t *sample;
141  pf_pdf_gaussian_t *pdf;
142 
143  set = pf->sets + pf->current_set;
144 
145  // Create the kd tree for adaptive sampling
146  pf_kdtree_clear(set->kdtree);
147 
148  set->sample_count = pf->max_samples;
149 
150  pdf = pf_pdf_gaussian_alloc(mean, cov);
151 
152  // Compute the new sample poses
153  for (i = 0; i < set->sample_count; i++)
154  {
155  sample = set->samples + i;
156  sample->weight = 1.0 / pf->max_samples;
157  sample->pose = pf_pdf_gaussian_sample(pdf);
158 
159  // Add sample to histogram
160  pf_kdtree_insert(set->kdtree, sample->pose, sample->weight);
161  }
162 
163  pf->w_slow = pf->w_fast = 0.0;
164 
166 
167  // Re-compute cluster statistics
168  pf_cluster_stats(pf, set);
169 
170  //set converged to 0
171  pf_init_converged(pf);
172 
173  return;
174 }
175 
176 
177 // Initialize the filter using some model
178 void pf_init_model(pf_t *pf, pf_init_model_fn_t init_fn, void *init_data)
179 {
180  int i;
182  pf_sample_t *sample;
183 
184  set = pf->sets + pf->current_set;
185 
186  // Create the kd tree for adaptive sampling
187  pf_kdtree_clear(set->kdtree);
188 
189  set->sample_count = pf->max_samples;
190 
191  // Compute the new sample poses
192  for (i = 0; i < set->sample_count; i++)
193  {
194  sample = set->samples + i;
195  sample->weight = 1.0 / pf->max_samples;
196  sample->pose = (*init_fn) (init_data);
197 
198  // Add sample to histogram
199  pf_kdtree_insert(set->kdtree, sample->pose, sample->weight);
200  }
201 
202  pf->w_slow = pf->w_fast = 0.0;
203 
204  // Re-compute cluster statistics
205  pf_cluster_stats(pf, set);
206 
207  //set converged to 0
208  pf_init_converged(pf);
209 
210  return;
211 }
212 
215  set = pf->sets + pf->current_set;
216  set->converged = 0;
217  pf->converged = 0;
218 }
219 
221 {
222  int i;
224  pf_sample_t *sample;
225  double total;
226 
227  set = pf->sets + pf->current_set;
228  double mean_x = 0, mean_y = 0;
229 
230  for (i = 0; i < set->sample_count; i++){
231  sample = set->samples + i;
232 
233  mean_x += sample->pose.v[0];
234  mean_y += sample->pose.v[1];
235  }
236  mean_x /= set->sample_count;
237  mean_y /= set->sample_count;
238 
239  for (i = 0; i < set->sample_count; i++){
240  sample = set->samples + i;
241  if(fabs(sample->pose.v[0] - mean_x) > pf->dist_threshold ||
242  fabs(sample->pose.v[1] - mean_y) > pf->dist_threshold){
243  set->converged = 0;
244  pf->converged = 0;
245  return 0;
246  }
247  }
248  set->converged = 1;
249  pf->converged = 1;
250  return 1;
251 }
252 
253 // Update the filter with some new action
254 void pf_update_action(pf_t *pf, pf_action_model_fn_t action_fn, void *action_data)
255 {
257 
258  set = pf->sets + pf->current_set;
259 
260  (*action_fn) (action_data, set);
261 
262  return;
263 }
264 
265 
266 #include <float.h>
267 // Update the filter with some new sensor observation
268 void pf_update_sensor(pf_t *pf, pf_sensor_model_fn_t sensor_fn, void *sensor_data)
269 {
270  int i;
272  pf_sample_t *sample;
273  double total;
274 
275  set = pf->sets + pf->current_set;
276 
277  // Compute the sample weights
278  total = (*sensor_fn) (sensor_data, set);
279 
280  set->n_effective = 0;
281 
282  if (total > 0.0)
283  {
284  // Normalize weights
285  double w_avg=0.0;
286  for (i = 0; i < set->sample_count; i++)
287  {
288  sample = set->samples + i;
289  w_avg += sample->weight;
290  sample->weight /= total;
291  set->n_effective += sample->weight*sample->weight;
292  }
293  // Update running averages of likelihood of samples (Prob Rob p258)
294  w_avg /= set->sample_count;
295  if(pf->w_slow == 0.0)
296  pf->w_slow = w_avg;
297  else
298  pf->w_slow += pf->alpha_slow * (w_avg - pf->w_slow);
299  if(pf->w_fast == 0.0)
300  pf->w_fast = w_avg;
301  else
302  pf->w_fast += pf->alpha_fast * (w_avg - pf->w_fast);
303  //printf("w_avg: %e slow: %e fast: %e\n",
304  //w_avg, pf->w_slow, pf->w_fast);
305  }
306  else
307  {
308  // Handle zero total
309  for (i = 0; i < set->sample_count; i++)
310  {
311  sample = set->samples + i;
312  sample->weight = 1.0 / set->sample_count;
313  }
314  }
315 
316  set->n_effective = 1.0/set->n_effective;
317  return;
318 }
319 
320 // copy set a to set b
322 {
323  int i;
324  double total;
325  pf_sample_t *sample_a, *sample_b;
326 
327  // Clean set b's kdtree
328  pf_kdtree_clear(set_b->kdtree);
329 
330  // Copy samples from set a to create set b
331  total = 0;
332  set_b->sample_count = 0;
333 
334  for(i = 0; i < set_a->sample_count; i++)
335  {
336  sample_b = set_b->samples + set_b->sample_count++;
337 
338  sample_a = set_a->samples + i;
339 
340  assert(sample_a->weight > 0);
341 
342  // Copy sample a to sample b
343  sample_b->pose = sample_a->pose;
344  sample_b->weight = sample_a->weight;
345 
346  total += sample_b->weight;
347 
348  // Add sample to histogram
349  pf_kdtree_insert(set_b->kdtree, sample_b->pose, sample_b->weight);
350  }
351 
352  // Normalize weights
353  for (i = 0; i < set_b->sample_count; i++)
354  {
355  sample_b = set_b->samples + i;
356  sample_b->weight /= total;
357  }
358 
359  set_b->converged = set_a->converged;
360 }
361 
362 // Resample the distribution
364 {
365  int i;
366  double total;
367  pf_sample_set_t *set_a, *set_b;
368  pf_sample_t *sample_a, *sample_b;
369 
370  //double r,c,U;
371  //int m;
372  //double count_inv;
373  double* c;
374 
375  double w_diff;
376 
377  set_a = pf->sets + pf->current_set;
378  set_b = pf->sets + (pf->current_set + 1) % 2;
379 
380  if (pf->selective_resampling != 0)
381  {
382  if (set_a->n_effective > 0.5*(set_a->sample_count))
383  {
384  // copy set a to b
385  copy_set(set_a,set_b);
386 
387  // Re-compute cluster statistics
388  pf_cluster_stats(pf, set_b);
389 
390  // Use the newly created sample set
391  pf->current_set = (pf->current_set + 1) % 2;
392  return;
393  }
394  }
395 
396  // Build up cumulative probability table for resampling.
397  // TODO: Replace this with a more efficient procedure
398  // (e.g., http://www.network-theory.co.uk/docs/gslref/GeneralDiscreteDistributions.html)
399  c = (double*)malloc(sizeof(double)*(set_a->sample_count+1));
400  c[0] = 0.0;
401  for(i=0;i<set_a->sample_count;i++)
402  c[i+1] = c[i]+set_a->samples[i].weight;
403 
404  // Create the kd tree for adaptive sampling
405  pf_kdtree_clear(set_b->kdtree);
406 
407  // Draw samples from set a to create set b.
408  total = 0;
409  set_b->sample_count = 0;
410 
411  w_diff = 1.0 - pf->w_fast / pf->w_slow;
412  if(w_diff < 0.0)
413  w_diff = 0.0;
414  //printf("w_diff: %9.6f\n", w_diff);
415 
416  // Can't (easily) combine low-variance sampler with KLD adaptive
417  // sampling, so we'll take the more traditional route.
418  /*
419  // Low-variance resampler, taken from Probabilistic Robotics, p110
420  count_inv = 1.0/set_a->sample_count;
421  r = drand48() * count_inv;
422  c = set_a->samples[0].weight;
423  i = 0;
424  m = 0;
425  */
426  while(set_b->sample_count < pf->max_samples)
427  {
428  sample_b = set_b->samples + set_b->sample_count++;
429 
430  if(drand48() < w_diff)
431  sample_b->pose = (pf->random_pose_fn)(pf->random_pose_data);
432  else
433  {
434  // Can't (easily) combine low-variance sampler with KLD adaptive
435  // sampling, so we'll take the more traditional route.
436  /*
437  // Low-variance resampler, taken from Probabilistic Robotics, p110
438  U = r + m * count_inv;
439  while(U>c)
440  {
441  i++;
442  // Handle wrap-around by resetting counters and picking a new random
443  // number
444  if(i >= set_a->sample_count)
445  {
446  r = drand48() * count_inv;
447  c = set_a->samples[0].weight;
448  i = 0;
449  m = 0;
450  U = r + m * count_inv;
451  continue;
452  }
453  c += set_a->samples[i].weight;
454  }
455  m++;
456  */
457 
458  // Naive discrete event sampler
459  double r;
460  r = drand48();
461  for(i=0;i<set_a->sample_count;i++)
462  {
463  if((c[i] <= r) && (r < c[i+1]))
464  break;
465  }
466  assert(i<set_a->sample_count);
467 
468  sample_a = set_a->samples + i;
469 
470  assert(sample_a->weight > 0);
471 
472  // Add sample to list
473  sample_b->pose = sample_a->pose;
474  }
475 
476  sample_b->weight = 1.0;
477  total += sample_b->weight;
478 
479  // Add sample to histogram
480  pf_kdtree_insert(set_b->kdtree, sample_b->pose, sample_b->weight);
481 
482  // See if we have enough samples yet
483  if (set_b->sample_count > pf_resample_limit(pf, set_b->kdtree->leaf_count))
484  break;
485  }
486 
487  // Reset averages, to avoid spiraling off into complete randomness.
488  if(w_diff > 0.0)
489  pf->w_slow = pf->w_fast = 0.0;
490 
491  //fprintf(stderr, "\n\n");
492 
493  // Normalize weights
494  for (i = 0; i < set_b->sample_count; i++)
495  {
496  sample_b = set_b->samples + i;
497  sample_b->weight /= total;
498  }
499 
500  // Re-compute cluster statistics
501  pf_cluster_stats(pf, set_b);
502 
503  // Use the newly created sample set
504  pf->current_set = (pf->current_set + 1) % 2;
505 
507 
508  free(c);
509  return;
510 }
511 
512 
513 // Compute the required number of samples, given that there are k bins
514 // with samples in them. This is taken directly from Fox et al.
515 int pf_resample_limit(pf_t *pf, int k)
516 {
517  double a, b, c, x;
518  int n;
519 
520  // Return max_samples in case k is outside expected range, this shouldn't
521  // happen, but is added to prevent any runtime errors
522  if (k < 1 || k > pf->max_samples)
523  return pf->max_samples;
524 
525  // Return value if cache is valid, which means value is non-zero positive
526  if (pf->limit_cache[k-1] > 0)
527  return pf->limit_cache[k-1];
528 
529  if (k == 1)
530  {
531  pf->limit_cache[k-1] = pf->max_samples;
532  return pf->max_samples;
533  }
534 
535  a = 1;
536  b = 2 / (9 * ((double) k - 1));
537  c = sqrt(2 / (9 * ((double) k - 1))) * pf->pop_z;
538  x = a - b + c;
539 
540  n = (int) ceil((k - 1) / (2 * pf->pop_err) * x * x * x);
541 
542  if (n < pf->min_samples)
543  {
544  pf->limit_cache[k-1] = pf->min_samples;
545  return pf->min_samples;
546  }
547  if (n > pf->max_samples)
548  {
549  pf->limit_cache[k-1] = pf->max_samples;
550  return pf->max_samples;
551  }
552 
553  pf->limit_cache[k-1] = n;
554  return n;
555 }
556 
557 
558 // Re-compute the cluster statistics for a sample set
560 {
561  int i, j, k, cidx;
562  pf_sample_t *sample;
563  pf_cluster_t *cluster;
564 
565  // Workspace
566  double m[4], c[2][2];
567  size_t count;
568  double weight;
569 
570  // Cluster the samples
571  pf_kdtree_cluster(set->kdtree);
572 
573  // Initialize cluster stats
574  set->cluster_count = 0;
575 
576  for (i = 0; i < set->cluster_max_count; i++)
577  {
578  cluster = set->clusters + i;
579  cluster->count = 0;
580  cluster->weight = 0;
581  cluster->mean = pf_vector_zero();
582  cluster->cov = pf_matrix_zero();
583 
584  for (j = 0; j < 4; j++)
585  cluster->m[j] = 0.0;
586  for (j = 0; j < 2; j++)
587  for (k = 0; k < 2; k++)
588  cluster->c[j][k] = 0.0;
589  }
590 
591  // Initialize overall filter stats
592  count = 0;
593  weight = 0.0;
594  set->mean = pf_vector_zero();
595  set->cov = pf_matrix_zero();
596  for (j = 0; j < 4; j++)
597  m[j] = 0.0;
598  for (j = 0; j < 2; j++)
599  for (k = 0; k < 2; k++)
600  c[j][k] = 0.0;
601 
602  // Compute cluster stats
603  for (i = 0; i < set->sample_count; i++)
604  {
605  sample = set->samples + i;
606 
607  //printf("%d %f %f %f\n", i, sample->pose.v[0], sample->pose.v[1], sample->pose.v[2]);
608 
609  // Get the cluster label for this sample
610  cidx = pf_kdtree_get_cluster(set->kdtree, sample->pose);
611  assert(cidx >= 0);
612  if (cidx >= set->cluster_max_count)
613  continue;
614  if (cidx + 1 > set->cluster_count)
615  set->cluster_count = cidx + 1;
616 
617  cluster = set->clusters + cidx;
618 
619  cluster->count += 1;
620  cluster->weight += sample->weight;
621 
622  count += 1;
623  weight += sample->weight;
624 
625  // Compute mean
626  cluster->m[0] += sample->weight * sample->pose.v[0];
627  cluster->m[1] += sample->weight * sample->pose.v[1];
628  cluster->m[2] += sample->weight * cos(sample->pose.v[2]);
629  cluster->m[3] += sample->weight * sin(sample->pose.v[2]);
630 
631  m[0] += sample->weight * sample->pose.v[0];
632  m[1] += sample->weight * sample->pose.v[1];
633  m[2] += sample->weight * cos(sample->pose.v[2]);
634  m[3] += sample->weight * sin(sample->pose.v[2]);
635 
636  // Compute covariance in linear components
637  for (j = 0; j < 2; j++)
638  for (k = 0; k < 2; k++)
639  {
640  cluster->c[j][k] += sample->weight * sample->pose.v[j] * sample->pose.v[k];
641  c[j][k] += sample->weight * sample->pose.v[j] * sample->pose.v[k];
642  }
643  }
644 
645  // Normalize
646  for (i = 0; i < set->cluster_count; i++)
647  {
648  cluster = set->clusters + i;
649 
650  cluster->mean.v[0] = cluster->m[0] / cluster->weight;
651  cluster->mean.v[1] = cluster->m[1] / cluster->weight;
652  cluster->mean.v[2] = atan2(cluster->m[3], cluster->m[2]);
653 
654  cluster->cov = pf_matrix_zero();
655 
656  // Covariance in linear components
657  for (j = 0; j < 2; j++)
658  for (k = 0; k < 2; k++)
659  cluster->cov.m[j][k] = cluster->c[j][k] / cluster->weight -
660  cluster->mean.v[j] * cluster->mean.v[k];
661 
662  // Covariance in angular components; I think this is the correct
663  // formula for circular statistics.
664  cluster->cov.m[2][2] = -2 * log(sqrt(cluster->m[2] * cluster->m[2] +
665  cluster->m[3] * cluster->m[3]) / cluster->weight);
666 
667  //printf("cluster %d %d %f (%f %f %f)\n", i, cluster->count, cluster->weight,
668  //cluster->mean.v[0], cluster->mean.v[1], cluster->mean.v[2]);
669  //pf_matrix_fprintf(cluster->cov, stdout, "%e");
670  }
671 
672  assert(fabs(weight) >= DBL_EPSILON);
673  if (fabs(weight) < DBL_EPSILON)
674  {
675  printf("ERROR : divide-by-zero exception : weight is zero\n");
676  return;
677  }
678  // Compute overall filter stats
679  set->mean.v[0] = m[0] / weight;
680  set->mean.v[1] = m[1] / weight;
681  set->mean.v[2] = atan2(m[3], m[2]);
682 
683  // Covariance in linear components
684  for (j = 0; j < 2; j++)
685  for (k = 0; k < 2; k++)
686  set->cov.m[j][k] = c[j][k] / weight - set->mean.v[j] * set->mean.v[k];
687 
688  // Covariance in angular components; I think this is the correct
689  // formula for circular statistics.
690  set->cov.m[2][2] = -2 * log(sqrt(m[2] * m[2] + m[3] * m[3]));
691 
692  return;
693 }
694 
695 void pf_set_selective_resampling(pf_t *pf, int selective_resampling)
696 {
697  pf->selective_resampling = selective_resampling;
698 }
699 
700 // Compute the CEP statistics (mean and variance).
701 void pf_get_cep_stats(pf_t *pf, pf_vector_t *mean, double *var)
702 {
703  int i;
704  double mn, mx, my, mrr;
706  pf_sample_t *sample;
707 
708  set = pf->sets + pf->current_set;
709 
710  mn = 0.0;
711  mx = 0.0;
712  my = 0.0;
713  mrr = 0.0;
714 
715  for (i = 0; i < set->sample_count; i++)
716  {
717  sample = set->samples + i;
718 
719  mn += sample->weight;
720  mx += sample->weight * sample->pose.v[0];
721  my += sample->weight * sample->pose.v[1];
722  mrr += sample->weight * sample->pose.v[0] * sample->pose.v[0];
723  mrr += sample->weight * sample->pose.v[1] * sample->pose.v[1];
724  }
725 
726  assert(fabs(mn) >= DBL_EPSILON);
727  if (fabs(mn) < DBL_EPSILON)
728  {
729  printf("ERROR : divide-by-zero exception : mn is zero\n");
730  return;
731  }
732 
733  mean->v[0] = mx / mn;
734  mean->v[1] = my / mn;
735  mean->v[2] = 0.0;
736 
737  *var = mrr / mn - (mx * mx / (mn * mn) + my * my / (mn * mn));
738 
739  return;
740 }
741 
742 
743 // Get the statistics for a particular cluster.
744 int pf_get_cluster_stats(pf_t *pf, int clabel, double *weight,
745  pf_vector_t *mean, pf_matrix_t *cov)
746 {
748  pf_cluster_t *cluster;
749 
750  set = pf->sets + pf->current_set;
751 
752  if (clabel >= set->cluster_count)
753  return 0;
754  cluster = set->clusters + clabel;
755 
756  *weight = cluster->weight;
757  *mean = cluster->mean;
758  *cov = cluster->cov;
759 
760  return 1;
761 }
762 
763 
pf_sample_t::weight
double weight
Definition: pf.h:65
pf_cluster_t::m
double m[4]
Definition: pf.h:84
_pf_t::selective_resampling
int selective_resampling
Definition: pf.h:142
pf_matrix_zero
pf_matrix_t pf_matrix_zero()
Definition: pf_vector.c:134
_pf_t::alpha_fast
double alpha_fast
Definition: pf.h:132
pf_kdtree_cluster
void pf_kdtree_cluster(pf_kdtree_t *self)
Definition: pf_kdtree.c:358
pf_kdtree.h
pf.h
pf_vector_t
Definition: pf_vector.h:38
_pf_t::w_fast
double w_fast
Definition: pf.h:129
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:744
_pf_t::random_pose_data
void * random_pose_data
Definition: pf.h:136
pf_update_action
void pf_update_action(pf_t *pf, pf_action_model_fn_t action_fn, void *action_data)
Definition: pf.c:254
pf_kdtree_get_cluster
int pf_kdtree_get_cluster(pf_kdtree_t *self, pf_vector_t pose)
Definition: pf_kdtree.c:168
_pf_sample_set_t::samples
pf_sample_t * samples
Definition: pf.h:94
time.h
pf_alloc
pf_t * pf_alloc(int min_samples, int max_samples, double alpha_slow, double alpha_fast, pf_init_model_fn_t random_pose_fn, void *random_pose_data)
Definition: pf.c:46
_pf_sample_set_t::n_effective
double n_effective
Definition: pf.h:107
pf_cluster_t::c
double c[2][2]
Definition: pf.h:84
_pf_t::pop_err
double pop_err
Definition: pf.h:118
_pf_sample_set_t::converged
int converged
Definition: pf.h:106
_pf_sample_set_t::clusters
pf_cluster_t * clusters
Definition: pf.h:101
_pf_sample_set_t::kdtree
pf_kdtree_t * kdtree
Definition: pf.h:97
_pf_sample_set_t::sample_count
int sample_count
Definition: pf.h:93
drand48
static double drand48(void)
Definition: portable_utils.hpp:13
pf_update_resample
void pf_update_resample(pf_t *pf)
Definition: pf.c:363
_pf_sample_set_t
Definition: pf.h:90
_pf_t::dist_threshold
double dist_threshold
Definition: pf.h:138
_pf_t::converged
int converged
Definition: pf.h:139
pf_kdtree_alloc
pf_kdtree_t * pf_kdtree_alloc(int max_size)
Definition: pf_kdtree.c:66
pf_pdf_gaussian_t
Definition: pf_pdf.h:45
srand48
static void srand48(long int seedval)
Definition: portable_utils.hpp:18
_pf_t::alpha_slow
double alpha_slow
Definition: pf.h:132
pf_set_selective_resampling
void pf_set_selective_resampling(pf_t *pf, int selective_resampling)
Definition: pf.c:695
pf_matrix_t::m
double m[3][3]
Definition: pf_vector.h:47
_pf_t
Definition: pf.h:112
pf_sensor_model_fn_t
double(* pf_sensor_model_fn_t)(void *sensor_data, struct _pf_sample_set_t *set)
Definition: pf.h:54
pf_init_model_fn_t
pf_vector_t(* pf_init_model_fn_t)(void *init_data)
Definition: pf.h:45
_pf_t::sets
pf_sample_set_t sets[2]
Definition: pf.h:126
_pf_t::min_samples
int min_samples
Definition: pf.h:115
pf_cluster_stats
void pf_cluster_stats(pf_t *pf, pf_sample_set_t *set)
Definition: pf.c:559
pf_pdf_gaussian_free
void pf_pdf_gaussian_free(pf_pdf_gaussian_t *pdf)
Definition: pf_pdf.c:75
pf_cluster_t::mean
pf_vector_t mean
Definition: pf.h:80
_pf_t::pop_z
double pop_z
Definition: pf.h:118
n
static int n
Definition: eig3.c:14
pf_vector_zero
pf_vector_t pf_vector_zero()
Definition: pf_vector.c:38
pf_init_model
void pf_init_model(pf_t *pf, pf_init_model_fn_t init_fn, void *init_data)
Definition: pf.c:178
pf_kdtree_clear
void pf_kdtree_clear(pf_kdtree_t *self)
Definition: pf_kdtree.c:100
pf_kdtree_t::leaf_count
int leaf_count
Definition: pf_kdtree.h:75
_pf_t::limit_cache
int * limit_cache
Definition: pf.h:121
pf_pdf.h
pf_sample_t
Definition: pf.h:59
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:47
pf_init
void pf_init(pf_t *pf, pf_vector_t mean, pf_matrix_t cov)
Definition: pf.c:136
pf_sample_t::pose
pf_vector_t pose
Definition: pf.h:62
pf_cluster_t
Definition: pf.h:71
pf_free
void pf_free(pf_t *pf)
Definition: pf.c:118
pf_kdtree_insert
void pf_kdtree_insert(pf_kdtree_t *self, pf_vector_t pose, double value)
Definition: pf_kdtree.c:112
portable_utils.hpp
pf_cluster_t::weight
double weight
Definition: pf.h:77
_pf_t::w_slow
double w_slow
Definition: pf.h:129
pf_resample_limit
static int pf_resample_limit(pf_t *pf, int k)
Definition: pf.c:515
pf_update_sensor
void pf_update_sensor(pf_t *pf, pf_sensor_model_fn_t sensor_fn, void *sensor_data)
Definition: pf.c:268
pf_matrix_t
Definition: pf_vector.h:45
copy_set
void copy_set(pf_sample_set_t *set_a, pf_sample_set_t *set_b)
Definition: pf.c:321
_pf_t::max_samples
int max_samples
Definition: pf.h:115
_pf_t::random_pose_fn
pf_init_model_fn_t random_pose_fn
Definition: pf.h:135
assert.h
pf_get_cep_stats
void pf_get_cep_stats(pf_t *pf, pf_vector_t *mean, double *var)
Definition: pf.c:701
pf_cluster_t::cov
pf_matrix_t cov
Definition: pf.h:81
_pf_t::current_set
int current_set
Definition: pf.h:125
pf_init_converged
void pf_init_converged(pf_t *pf)
Definition: pf.c:213
pf_action_model_fn_t
void(* pf_action_model_fn_t)(void *action_data, struct _pf_sample_set_t *set)
Definition: pf.h:49
pf_cluster_t::count
int count
Definition: pf.h:74
pf_vector_t::v
double v[3]
Definition: pf_vector.h:45
pf_kdtree_free
void pf_kdtree_free(pf_kdtree_t *self)
Definition: pf_kdtree.c:90
pf_pdf_gaussian_sample
pf_vector_t pf_pdf_gaussian_sample(pf_pdf_gaussian_t *pdf)
Definition: pf_pdf.c:106
pf_update_converged
int pf_update_converged(pf_t *pf)
Definition: pf.c:220


amcl
Author(s): Brian P. Gerkey, contradict@gmail.com
autogenerated on Mon Mar 6 2023 03:50:13