Nav2 Navigation Stack - rolling  main
ROS 2 Navigation Stack
pf_pdf.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: Useful pdf functions
23  * Author: Andrew Howard
24  * Date: 10 Dec 2002
25  * CVS: $Id: pf_pdf.c 6348 2008-04-17 02:53:17Z gerkey $
26  *************************************************************************/
27 
28 #include <assert.h>
29 #include <math.h>
30 #include <stdlib.h>
31 #include <string.h>
32 // #include <gsl/gsl_rng.h>
33 // #include <gsl/gsl_randist.h>
34 
35 #include "nav2_amcl/pf/pf_pdf.hpp"
36 
37 #include "nav2_amcl/portable_utils.hpp"
38 
39 // Random number generator seed value
40 static unsigned int pf_pdf_seed;
41 
42 
43 /**************************************************************************
44  * Gaussian
45  *************************************************************************/
46 
47 // Create a gaussian pdf
48 pf_pdf_gaussian_t * pf_pdf_gaussian_alloc(pf_vector_t x, pf_matrix_t cx)
49 {
50  pf_matrix_t cd;
51  pf_pdf_gaussian_t * pdf;
52 
53  pdf = calloc(1, sizeof(pf_pdf_gaussian_t));
54 
55  pdf->x = x;
56  pdf->cx = cx;
57  // pdf->cxi = pf_matrix_inverse(cx, &pdf->cxdet);
58 
59  // Decompose the convariance matrix into a rotation
60  // matrix and a diagonal matrix.
61  pf_matrix_unitary(&pdf->cr, &cd, pdf->cx);
62  pdf->cd.v[0] = sqrt(cd.m[0][0]);
63  pdf->cd.v[1] = sqrt(cd.m[1][1]);
64  pdf->cd.v[2] = sqrt(cd.m[2][2]);
65 
66  // Initialize the random number generator
67  // pdf->rng = gsl_rng_alloc(gsl_rng_taus);
68  // gsl_rng_set(pdf->rng, ++pf_pdf_seed);
69  srand48(++pf_pdf_seed);
70 
71  return pdf;
72 }
73 
74 
75 // Destroy the pdf
76 void pf_pdf_gaussian_free(pf_pdf_gaussian_t * pdf)
77 {
78  // gsl_rng_free(pdf->rng);
79  free(pdf);
80 }
81 
82 
83 /*
84 // Compute the value of the pdf at some point [x].
85 double pf_pdf_gaussian_value(pf_pdf_gaussian_t *pdf, pf_vector_t x)
86 {
87  int i, j;
88  pf_vector_t z;
89  double zz, p;
90 
91  z = pf_vector_sub(x, pdf->x);
92 
93  zz = 0;
94  for (i = 0; i < 3; i++)
95  for (j = 0; j < 3; j++)
96  zz += z.v[i] * pdf->cxi.m[i][j] * z.v[j];
97 
98  p = 1 / (2 * M_PI * pdf->cxdet) * exp(-zz / 2);
99 
100  return p;
101 }
102 */
103 
104 
105 // Generate a sample from the pdf.
106 pf_vector_t pf_pdf_gaussian_sample(pf_pdf_gaussian_t * pdf)
107 {
108  int i, j;
109  pf_vector_t r;
110  pf_vector_t x;
111 
112  // Generate a random vector
113  for (i = 0; i < 3; i++) {
114  // r.v[i] = gsl_ran_gaussian(pdf->rng, pdf->cd.v[i]);
115  r.v[i] = pf_ran_gaussian(pdf->cd.v[i]);
116  }
117 
118  for (i = 0; i < 3; i++) {
119  x.v[i] = pdf->x.v[i];
120  for (j = 0; j < 3; j++) {
121  x.v[i] += pdf->cr.m[i][j] * r.v[j];
122  }
123  }
124 
125  return x;
126 }
127 
128 // Draw randomly from a zero-mean Gaussian distribution, with standard
129 // deviation sigma.
130 // We use the polar form of the Box-Muller transformation, explained here:
131 // http://www.taygeta.com/random/gaussian.html
132 double pf_ran_gaussian(double sigma)
133 {
134  double x1, x2, w, r;
135 
136  do {
137  do {
138  r = drand48();
139  } while (r == 0.0);
140  x1 = 2.0 * r - 1.0;
141  do {
142  r = drand48();
143  } while (r == 0.0);
144  x2 = 2.0 * r - 1.0;
145  w = x1 * x1 + x2 * x2;
146  } while (w > 1.0 || w == 0.0);
147 
148  return sigma * x2 * sqrt(-2.0 * log(w) / w);
149 }