Nav2 Navigation Stack - lyrical  lyrical
ROS 2 Navigation Stack
pf.c
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 <float.h>
29 #include <assert.h>
30 #include <math.h>
31 #include <stdint.h>
32 #include <stdlib.h>
33 #include <time.h>
34 
35 #include "nav2_amcl/pf/pf.hpp"
36 #include "nav2_amcl/pf/pf_pdf.hpp"
37 #include "nav2_amcl/pf/pf_kdtree.hpp"
38 
39 #include "nav2_amcl/portable_utils.hpp"
40 
41 
42 // Compute the required number of samples, given that there are k bins
43 // with samples in them.
44 static int pf_resample_limit(pf_t * pf, int k);
45 
46 
47 // Create a new filter
48 pf_t * pf_alloc(
49  int min_samples, int max_samples,
50  double alpha_slow, double alpha_fast,
51  pf_init_model_fn_t random_pose_fn)
52 {
53  int i, j;
54  pf_t * pf;
55  pf_sample_set_t * set;
56  pf_sample_t * sample;
57 
58  pf = calloc(1, sizeof(pf_t));
59 
60  pf->random_pose_fn = random_pose_fn;
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  // distribution will be less than [err].
70  pf->pop_err = 0.01;
71  pf->pop_z = 3;
72  pf->dist_threshold = 0.5;
73 
74  pf->current_set = 0;
75  for (j = 0; j < 2; j++) {
76  set = pf->sets + j;
77 
78  set->sample_count = max_samples;
79  set->samples = calloc(max_samples, sizeof(pf_sample_t));
80 
81  for (i = 0; i < set->sample_count; i++) {
82  sample = set->samples + i;
83  sample->pose.v[0] = 0.0;
84  sample->pose.v[1] = 0.0;
85  sample->pose.v[2] = 0.0;
86  sample->weight = 1.0 / max_samples;
87  }
88 
89  // HACK: is 3 times max_samples enough?
90  set->kdtree = pf_kdtree_alloc(3 * max_samples);
91 
92  set->cluster_count = 0;
93  set->cluster_max_count = max_samples;
94  set->clusters = calloc(set->cluster_max_count, sizeof(pf_cluster_t));
95 
96  set->mean = pf_vector_zero();
97  set->cov = pf_matrix_zero();
98  }
99 
100  pf->w_slow = 0.0;
101  pf->w_fast = 0.0;
102 
103  pf->alpha_slow = alpha_slow;
104  pf->alpha_fast = alpha_fast;
105 
106  // set converged to 0
107  pf_init_converged(pf);
108 
109  return pf;
110 }
111 
112 // Free an existing filter
113 void pf_free(pf_t * pf)
114 {
115  int i;
116 
117  for (i = 0; i < 2; i++) {
118  free(pf->sets[i].clusters);
119  pf_kdtree_free(pf->sets[i].kdtree);
120  free(pf->sets[i].samples);
121  }
122  free(pf);
123 }
124 
125 // Initialize the filter using a gaussian
126 void pf_init(pf_t * pf, pf_vector_t mean, pf_matrix_t cov)
127 {
128  int i;
129  pf_sample_set_t * set;
130  pf_sample_t * sample;
131  pf_pdf_gaussian_t * pdf;
132 
133  set = pf->sets + pf->current_set;
134 
135  // Create the kd tree for adaptive sampling
136  pf_kdtree_clear(set->kdtree);
137 
138  set->sample_count = pf->max_samples;
139 
140  pdf = pf_pdf_gaussian_alloc(mean, cov);
141 
142  // Compute the new sample poses
143  for (i = 0; i < set->sample_count; i++) {
144  sample = set->samples + i;
145  sample->weight = 1.0 / pf->max_samples;
146  sample->pose = pf_pdf_gaussian_sample(pdf);
147 
148  // Add sample to histogram
149  pf_kdtree_insert(set->kdtree, sample->pose, sample->weight);
150  }
151 
152  pf->w_slow = pf->w_fast = 0.0;
153 
154  pf_pdf_gaussian_free(pdf);
155 
156  // Re-compute cluster statistics
157  pf_cluster_stats(pf, set);
158 
159  // set converged to 0
160  pf_init_converged(pf);
161 }
162 
163 
164 // Initialize the filter using some model
165 void pf_init_model(pf_t * pf, pf_init_model_fn_t init_fn, void * init_data)
166 {
167  int i;
168  pf_sample_set_t * set;
169  pf_sample_t * sample;
170 
171  set = pf->sets + pf->current_set;
172 
173  // Create the kd tree for adaptive sampling
174  pf_kdtree_clear(set->kdtree);
175 
176  set->sample_count = pf->max_samples;
177 
178  // Compute the new sample poses
179  for (i = 0; i < set->sample_count; i++) {
180  sample = set->samples + i;
181  sample->weight = 1.0 / pf->max_samples;
182  sample->pose = (*init_fn)(init_data);
183 
184  // Add sample to histogram
185  pf_kdtree_insert(set->kdtree, sample->pose, sample->weight);
186  }
187 
188  pf->w_slow = pf->w_fast = 0.0;
189 
190  // Re-compute cluster statistics
191  pf_cluster_stats(pf, set);
192 
193  // set converged to 0
194  pf_init_converged(pf);
195 }
196 
197 void pf_init_converged(pf_t * pf)
198 {
199  pf_sample_set_t * set;
200  set = pf->sets + pf->current_set;
201  set->converged = 0;
202  pf->converged = 0;
203 }
204 
205 int pf_update_converged(pf_t * pf)
206 {
207  int i;
208  pf_sample_set_t * set;
209  pf_sample_t * sample;
210 
211  set = pf->sets + pf->current_set;
212  double mean_x = 0, mean_y = 0;
213 
214  for (i = 0; i < set->sample_count; i++) {
215  sample = set->samples + i;
216 
217  mean_x += sample->pose.v[0];
218  mean_y += sample->pose.v[1];
219  }
220  mean_x /= set->sample_count;
221  mean_y /= set->sample_count;
222 
223  for (i = 0; i < set->sample_count; i++) {
224  sample = set->samples + i;
225  if (fabs(sample->pose.v[0] - mean_x) > pf->dist_threshold ||
226  fabs(sample->pose.v[1] - mean_y) > pf->dist_threshold)
227  {
228  set->converged = 0;
229  pf->converged = 0;
230  return 0;
231  }
232  }
233  set->converged = 1;
234  pf->converged = 1;
235  return 1;
236 }
237 
238 // Update the filter with some new action
239 // void pf_update_action(pf_t * pf, pf_action_model_fn_t action_fn, void * action_data)
240 // {
241 // pf_sample_set_t * set;
242 
243 // set = pf->sets + pf->current_set;
244 
245 // (*action_fn)(action_data, set);
246 // }
247 
248 // Update the filter with some new sensor observation
249 void pf_update_sensor(pf_t * pf, pf_sensor_model_fn_t sensor_fn, void * sensor_data)
250 {
251  int i;
252  pf_sample_set_t * set;
253  pf_sample_t * sample;
254  double total;
255 
256  set = pf->sets + pf->current_set;
257 
258  // Compute the sample weights
259  total = (*sensor_fn)(sensor_data, set);
260 
261  if (total > 0.0) {
262  // Normalize weights
263  double w_avg = 0.0;
264  for (i = 0; i < set->sample_count; i++) {
265  sample = set->samples + i;
266  w_avg += sample->weight;
267  sample->weight /= total;
268  }
269  // Update running averages of likelihood of samples (Prob Rob p258)
270  w_avg /= set->sample_count;
271  if (pf->w_slow == 0.0) {
272  pf->w_slow = w_avg;
273  } else {
274  pf->w_slow += pf->alpha_slow * (w_avg - pf->w_slow);
275  }
276  if (pf->w_fast == 0.0) {
277  pf->w_fast = w_avg;
278  } else {
279  pf->w_fast += pf->alpha_fast * (w_avg - pf->w_fast);
280  }
281  } else {
282  // Handle zero total
283  for (i = 0; i < set->sample_count; i++) {
284  sample = set->samples + i;
285  sample->weight = 1.0 / set->sample_count;
286  }
287  }
288 }
289 
290 
291 // Resample the distribution
292 void pf_update_resample(pf_t * pf, void * random_pose_data)
293 {
294  int i;
295  double total;
296  pf_sample_set_t * set_a, * set_b;
297  pf_sample_t * sample_a, * sample_b;
298 
299  // double r,c,U;
300  // int m;
301  // double count_inv;
302  double * c;
303 
304  double w_diff;
305 
306  set_a = pf->sets + pf->current_set;
307  set_b = pf->sets + (pf->current_set + 1) % 2;
308 
309  // Build up cumulative probability table for resampling.
310  // TODO(?): Replace this with a more efficient procedure
311  // (e.g., http://www.network-theory.co.uk/docs/gslref/GeneralDiscreteDistributions.html)
312  c = (double *)malloc(sizeof(double) * (set_a->sample_count + 1));
313  c[0] = 0.0;
314  for (i = 0; i < set_a->sample_count; i++) {
315  c[i + 1] = c[i] + set_a->samples[i].weight;
316  }
317 
318  // Create the kd tree for adaptive sampling
319  pf_kdtree_clear(set_b->kdtree);
320 
321  // Draw samples from set a to create set b.
322  total = 0;
323  set_b->sample_count = 0;
324 
325  w_diff = 1.0 - pf->w_fast / pf->w_slow;
326  if (w_diff < 0.0) {
327  w_diff = 0.0;
328  }
329  // printf("w_diff: %9.6f\n", w_diff);
330 
331  // Can't (easily) combine low-variance sampler with KLD adaptive
332  // sampling, so we'll take the more traditional route.
333  /*
334  // Low-variance resampler, taken from Probabilistic Robotics, p110
335  count_inv = 1.0/set_a->sample_count;
336  r = drand48() * count_inv;
337  c = set_a->samples[0].weight;
338  i = 0;
339  m = 0;
340  */
341  while (set_b->sample_count < pf->max_samples) {
342  sample_b = set_b->samples + set_b->sample_count++;
343 
344  if (drand48() < w_diff) {
345  sample_b->pose = (pf->random_pose_fn)(random_pose_data);
346  } else {
347  // Can't (easily) combine low-variance sampler with KLD adaptive
348  // sampling, so we'll take the more traditional route.
349  /*
350  // Low-variance resampler, taken from Probabilistic Robotics, p110
351  U = r + m * count_inv;
352  while(U>c)
353  {
354  i++;
355  // Handle wrap-around by resetting counters and picking a new random
356  // number
357  if(i >= set_a->sample_count)
358  {
359  r = drand48() * count_inv;
360  c = set_a->samples[0].weight;
361  i = 0;
362  m = 0;
363  U = r + m * count_inv;
364  continue;
365  }
366  c += set_a->samples[i].weight;
367  }
368  m++;
369  */
370 
371  // Naive discrete event sampler
372  double r;
373  r = drand48();
374  for (i = 0; i < set_a->sample_count; i++) {
375  if ((c[i] <= r) && (r < c[i + 1])) {
376  break;
377  }
378  }
379  assert(i < set_a->sample_count);
380 
381  sample_a = set_a->samples + i;
382 
383  assert(sample_a->weight > 0);
384 
385  // Add sample to list
386  sample_b->pose = sample_a->pose;
387  }
388 
389  sample_b->weight = 1.0;
390  total += sample_b->weight;
391 
392  // Add sample to histogram
393  pf_kdtree_insert(set_b->kdtree, sample_b->pose, sample_b->weight);
394 
395  // See if we have enough samples yet
396  if (set_b->sample_count > pf_resample_limit(pf, set_b->kdtree->leaf_count)) {
397  break;
398  }
399  }
400 
401  // Reset averages, to avoid spiraling off into complete randomness.
402  if (w_diff > 0.0) {
403  pf->w_slow = pf->w_fast = 0.0;
404  }
405 
406  // fprintf(stderr, "\n\n");
407 
408  // Normalize weights
409  for (i = 0; i < set_b->sample_count; i++) {
410  sample_b = set_b->samples + i;
411  sample_b->weight /= total;
412  }
413 
414  // Re-compute cluster statistics
415  pf_cluster_stats(pf, set_b);
416 
417  // Use the newly created sample set
418  pf->current_set = (pf->current_set + 1) % 2;
419 
420  pf_update_converged(pf);
421 
422  free(c);
423 }
424 
425 
426 // Compute the required number of samples, given that there are k bins
427 // with samples in them. This is taken directly from Fox et al.
428 int pf_resample_limit(pf_t * pf, int k)
429 {
430  double a, b, c, x;
431  int n;
432 
433  if (k <= 1) {
434  return pf->max_samples;
435  }
436 
437  a = 1;
438  b = 2 / (9 * ((double) k - 1));
439  c = sqrt(2 / (9 * ((double) k - 1))) * pf->pop_z;
440  x = a - b + c;
441 
442  n = (int) ceil((k - 1) / (2 * pf->pop_err) * x * x * x);
443 
444  if (n < pf->min_samples) {
445  return pf->min_samples;
446  }
447  if (n > pf->max_samples) {
448  return pf->max_samples;
449  }
450 
451  return n;
452 }
453 
454 
455 // Re-compute the cluster statistics for a sample set
456 void pf_cluster_stats(pf_t * pf, pf_sample_set_t * set)
457 {
458  (void)pf;
459  int i, j, k, cidx;
460  pf_sample_t * sample;
461  pf_cluster_t * cluster;
462 
463  // Workspace
464  double m[4], c[2][2];
465  double weight;
466 
467  // Cluster the samples
468  pf_kdtree_cluster(set->kdtree);
469 
470  // Initialize cluster stats
471  set->cluster_count = 0;
472 
473  for (i = 0; i < set->cluster_max_count; i++) {
474  cluster = set->clusters + i;
475  cluster->weight = 0;
476  cluster->mean = pf_vector_zero();
477  cluster->cov = pf_matrix_zero();
478 
479  for (j = 0; j < 4; j++) {
480  cluster->m[j] = 0.0;
481  }
482  for (j = 0; j < 2; j++) {
483  for (k = 0; k < 2; k++) {
484  cluster->c[j][k] = 0.0;
485  }
486  }
487  }
488 
489  // Initialize overall filter stats
490  weight = 0.0;
491  set->mean = pf_vector_zero();
492  set->cov = pf_matrix_zero();
493  for (j = 0; j < 4; j++) {
494  m[j] = 0.0;
495  }
496  for (j = 0; j < 2; j++) {
497  for (k = 0; k < 2; k++) {
498  c[j][k] = 0.0;
499  }
500  }
501 
502  // Compute cluster stats
503  for (i = 0; i < set->sample_count; i++) {
504  sample = set->samples + i;
505 
506  // printf("%d %f %f %f\n", i, sample->pose.v[0], sample->pose.v[1], sample->pose.v[2]);
507 
508  // Get the cluster label for this sample
509  cidx = pf_kdtree_get_cluster(set->kdtree, sample->pose);
510  assert(cidx >= 0);
511  if (cidx >= set->cluster_max_count) {
512  continue;
513  }
514  if (cidx + 1 > set->cluster_count) {
515  set->cluster_count = cidx + 1;
516  }
517 
518  cluster = set->clusters + cidx;
519 
520  cluster->weight += sample->weight;
521 
522  weight += sample->weight;
523 
524  // Compute mean
525  cluster->m[0] += sample->weight * sample->pose.v[0];
526  cluster->m[1] += sample->weight * sample->pose.v[1];
527  cluster->m[2] += sample->weight * cos(sample->pose.v[2]);
528  cluster->m[3] += sample->weight * sin(sample->pose.v[2]);
529 
530  m[0] += sample->weight * sample->pose.v[0];
531  m[1] += sample->weight * sample->pose.v[1];
532  m[2] += sample->weight * cos(sample->pose.v[2]);
533  m[3] += sample->weight * sin(sample->pose.v[2]);
534 
535  // Compute covariance in linear components
536  for (j = 0; j < 2; j++) {
537  for (k = 0; k < 2; k++) {
538  cluster->c[j][k] += sample->weight * sample->pose.v[j] * sample->pose.v[k];
539  c[j][k] += sample->weight * sample->pose.v[j] * sample->pose.v[k];
540  }
541  }
542  }
543 
544  // Normalize
545  for (i = 0; i < set->cluster_count; i++) {
546  cluster = set->clusters + i;
547 
548  cluster->mean.v[0] = cluster->m[0] / cluster->weight;
549  cluster->mean.v[1] = cluster->m[1] / cluster->weight;
550  cluster->mean.v[2] = atan2(cluster->m[3], cluster->m[2]);
551 
552  cluster->cov = pf_matrix_zero();
553 
554  // Covariance in linear components
555  for (j = 0; j < 2; j++) {
556  for (k = 0; k < 2; k++) {
557  cluster->cov.m[j][k] = cluster->c[j][k] / cluster->weight -
558  cluster->mean.v[j] * cluster->mean.v[k];
559  }
560  }
561 
562  // Covariance in angular components; I think this is the correct
563  // formula for circular statistics.
564  cluster->cov.m[2][2] = -2 * log(
565  sqrt(
566  cluster->m[2] * cluster->m[2] +
567  cluster->m[3] * cluster->m[3]));
568 
569  // printf("cluster %d %d %f (%f %f %f)\n", i, cluster->count, cluster->weight,
570  // cluster->mean.v[0], cluster->mean.v[1], cluster->mean.v[2]);
571  // pf_matrix_fprintf(cluster->cov, stdout, "%e");
572  }
573 
574  // Compute overall filter stats
575  set->mean.v[0] = m[0] / weight;
576  set->mean.v[1] = m[1] / weight;
577  set->mean.v[2] = atan2(m[3], m[2]);
578 
579  // Covariance in linear components
580  for (j = 0; j < 2; j++) {
581  for (k = 0; k < 2; k++) {
582  set->cov.m[j][k] = c[j][k] / weight - set->mean.v[j] * set->mean.v[k];
583  }
584  }
585 
586  // Covariance in angular components; I think this is the correct
587  // formula for circular statistics.
588  set->cov.m[2][2] = -2 * log(sqrt(m[2] * m[2] + m[3] * m[3]));
589 }
590 
591 
592 // Compute the CEP statistics (mean and variance).
593 // void pf_get_cep_stats(pf_t * pf, pf_vector_t * mean, double * var)
594 // {
595 // int i;
596 // double mn, mx, my, mrr;
597 // pf_sample_set_t * set;
598 // pf_sample_t * sample;
599 
600 // set = pf->sets + pf->current_set;
601 
602 // mn = 0.0;
603 // mx = 0.0;
604 // my = 0.0;
605 // mrr = 0.0;
606 
607 // for (i = 0; i < set->sample_count; i++) {
608 // sample = set->samples + i;
609 
610 // mn += sample->weight;
611 // mx += sample->weight * sample->pose.v[0];
612 // my += sample->weight * sample->pose.v[1];
613 // mrr += sample->weight * sample->pose.v[0] * sample->pose.v[0];
614 // mrr += sample->weight * sample->pose.v[1] * sample->pose.v[1];
615 // }
616 
617 // mean->v[0] = mx / mn;
618 // mean->v[1] = my / mn;
619 // mean->v[2] = 0.0;
620 
621 // *var = mrr / mn - (mx * mx / (mn * mn) + my * my / (mn * mn));
622 // }
623 
624 
625 // Get the statistics for a particular cluster.
626 int pf_get_cluster_stats(
627  pf_t * pf, int clabel, double * weight,
628  pf_vector_t * mean, pf_matrix_t * cov)
629 {
630  pf_sample_set_t * set;
631  pf_cluster_t * cluster;
632 
633  set = pf->sets + pf->current_set;
634 
635  if (clabel >= set->cluster_count) {
636  return 0;
637  }
638  cluster = set->clusters + clabel;
639 
640  *weight = cluster->weight;
641  *mean = cluster->mean;
642  *cov = cluster->cov;
643 
644  return 1;
645 }
Definition: pf.hpp:114