Revision: 6368
http://playerstage.svn.sourceforge.net/playerstage/?rev=6368&view=rev
Author: gbiggs
Date: 2008-04-20 17:49:39 -0700 (Sun, 20 Apr 2008)
Log Message:
-----------
Merging changes 6344:6350 from trunk
Modified Paths:
--------------
code/player/branches/cmake/libplayercore/configfile.cc
code/player/branches/cmake/server/drivers/localization/amcl/CMakeLists.txt
code/player/branches/cmake/server/drivers/localization/amcl/pf/pf.c
code/player/branches/cmake/server/drivers/localization/amcl/pf/pf_pdf.c
code/player/branches/cmake/server/drivers/localization/amcl/pf/pf_pdf.h
code/player/branches/cmake/server/drivers/localization/amcl/pf/pf_vector.c
code/player/branches/cmake/server/drivers/localization/amcl/pf/pf_vector.h
Added Paths:
-----------
code/player/branches/cmake/server/drivers/localization/amcl/pf/eig3.c
code/player/branches/cmake/server/drivers/localization/amcl/pf/eig3.h
Removed Paths:
-------------
code/player/branches/cmake/server/drivers/localization/amcl/pf/gsl_discrete.c
Modified: code/player/branches/cmake/libplayercore/configfile.cc
===================================================================
--- code/player/branches/cmake/libplayercore/configfile.cc 2008-04-19
01:58:34 UTC (rev 6367)
+++ code/player/branches/cmake/libplayercore/configfile.cc 2008-04-21
00:49:39 UTC (rev 6368)
@@ -246,10 +246,33 @@
const char* name,
const char* value)
{
+ // Work out what the length units are
+ if(!strcmp(name, "unit_length"))
+ {
+ if (strcmp(value, "m") == 0)
+ this->unit_length = 1.0;
+ else if (strcmp(value, "cm") == 0)
+ this->unit_length = 0.01;
+ else if (strcmp(value, "mm") == 0)
+ this->unit_length = 0.001;
+ return;
+ }
+
+ // Work out what the angle units are
+ if(!strcmp(name, "unit_angle"))
+ {
+ if (strcmp(value, "degrees") == 0)
+ this->unit_angle = M_PI / 180;
+ else if (strcmp(value, "radians") == 0)
+ this->unit_angle = 1;
+ return;
+ }
+
// AddField checks whether the field already exists
int field = this->AddField(-1,name,0);
this->AddToken(ConfigFile::TokenWord, value, 0);
this->AddFieldValue(field, index, this->token_count-1);
+
}
Modified:
code/player/branches/cmake/server/drivers/localization/amcl/CMakeLists.txt
===================================================================
--- code/player/branches/cmake/server/drivers/localization/amcl/CMakeLists.txt
2008-04-19 01:58:34 UTC (rev 6367)
+++ code/player/branches/cmake/server/drivers/localization/amcl/CMakeLists.txt
2008-04-21 00:49:39 UTC (rev 6368)
@@ -1,48 +1,32 @@
PLAYERDRIVER_OPTION (amcl build_amcl ON)
-PLAYERDRIVER_REQUIRE_HEADER (amcl build_amcl gsl/gsl_version.h)
-
-SET (amclSrcs amcl.h
- amcl.cc
- amcl_sensor.h
+SET (amclSrcs amcl.cc
amcl_sensor.cc
- amcl_odom.h
amcl_odom.cc
- amcl_laser.h
amcl_laser.cc
- models/odometry.h
models/odometry.c
- models/sonar.h
models/sonar.c
- models/laser.h
models/laser.c
- models/wifi.h
models/wifi.c
- models/gps.h
models/gps.c
- models/imu.h
models/imu.c
pf/pf.c
pf/pf_kdtree.c
pf/pf_pdf.c
pf/pf_vector.c
pf/pf_draw.c
- pf/pf.h
- pf/pf_pdf.h
- pf/pf_kdtree.h
- pf/pf_vector.h
+ pf/eig3.c
map/map.c
map/map_range.c
map/map_store.c
- map/map_draw.c
- map/map.h)
+ map/map_draw.c)
IF (INCLUDE_RTKGUI)
- SET (linkFlags "-lgsl -lgslcblas ${GTK_LINKFLAGS}")
+ SET (linkFlags "${GTK_LINKFLAGS}")
SET (cFlags "-I${PROJECT_SOURCE_DIR}/rtk2 ${GTK_CFLAGS} -DINCLUDE_RTKGUI")
ELSE (INCLUDE_RTKGUI)
- SET (linkFlags "-lgsl -lgslcblas")
- SET (cFlags "")
+ SET (linkFlags)
+ SET (cFlags)
ENDIF (INCLUDE_RTKGUI)
-PLAYERDRIVER_ADD_DRIVER (amcl build_amcl "" "" ${linkFlags} "${cFlags}"
${amclSrcs})
\ No newline at end of file
+PLAYERDRIVER_ADD_DRIVER (amcl build_amcl "" "" "${linkFlags}" "${cFlags}"
${amclSrcs})
\ No newline at end of file
Copied: code/player/branches/cmake/server/drivers/localization/amcl/pf/eig3.c
(from rev 6350, code/player/trunk/server/drivers/localization/amcl/pf/eig3.c)
===================================================================
--- code/player/branches/cmake/server/drivers/localization/amcl/pf/eig3.c
(rev 0)
+++ code/player/branches/cmake/server/drivers/localization/amcl/pf/eig3.c
2008-04-21 00:49:39 UTC (rev 6368)
@@ -0,0 +1,271 @@
+
+/* Eigen decomposition code for symmetric 3x3 matrices, copied from the public
+ domain Java Matrix library JAMA. */
+
+#include <math.h>
+
+#ifndef MAX
+#define MAX(a, b) ((a)>(b)?(a):(b))
+#endif
+
+//#define n 3
+static int n = 3;
+
+static double hypot2(double x, double y) {
+ return sqrt(x*x+y*y);
+}
+
+// Symmetric Householder reduction to tridiagonal form.
+
+static void tred2(double V[n][n], double d[n], double e[n]) {
+
+// This is derived from the Algol procedures tred2 by
+// Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
+// Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
+// Fortran subroutine in EISPACK.
+
+ int i,j,k;
+ double f,g,h,hh;
+ for (j = 0; j < n; j++) {
+ d[j] = V[n-1][j];
+ }
+
+ // Householder reduction to tridiagonal form.
+
+ for (i = n-1; i > 0; i--) {
+
+ // Scale to avoid under/overflow.
+
+ double scale = 0.0;
+ double h = 0.0;
+ for (k = 0; k < i; k++) {
+ scale = scale + fabs(d[k]);
+ }
+ if (scale == 0.0) {
+ e[i] = d[i-1];
+ for (j = 0; j < i; j++) {
+ d[j] = V[i-1][j];
+ V[i][j] = 0.0;
+ V[j][i] = 0.0;
+ }
+ } else {
+
+ // Generate Householder vector.
+
+ for (k = 0; k < i; k++) {
+ d[k] /= scale;
+ h += d[k] * d[k];
+ }
+ f = d[i-1];
+ g = sqrt(h);
+ if (f > 0) {
+ g = -g;
+ }
+ e[i] = scale * g;
+ h = h - f * g;
+ d[i-1] = f - g;
+ for (j = 0; j < i; j++) {
+ e[j] = 0.0;
+ }
+
+ // Apply similarity transformation to remaining columns.
+
+ for (j = 0; j < i; j++) {
+ f = d[j];
+ V[j][i] = f;
+ g = e[j] + V[j][j] * f;
+ for (k = j+1; k <= i-1; k++) {
+ g += V[k][j] * d[k];
+ e[k] += V[k][j] * f;
+ }
+ e[j] = g;
+ }
+ f = 0.0;
+ for (j = 0; j < i; j++) {
+ e[j] /= h;
+ f += e[j] * d[j];
+ }
+ hh = f / (h + h);
+ for (j = 0; j < i; j++) {
+ e[j] -= hh * d[j];
+ }
+ for (j = 0; j < i; j++) {
+ f = d[j];
+ g = e[j];
+ for (k = j; k <= i-1; k++) {
+ V[k][j] -= (f * e[k] + g * d[k]);
+ }
+ d[j] = V[i-1][j];
+ V[i][j] = 0.0;
+ }
+ }
+ d[i] = h;
+ }
+
+ // Accumulate transformations.
+
+ for (i = 0; i < n-1; i++) {
+ V[n-1][i] = V[i][i];
+ V[i][i] = 1.0;
+ h = d[i+1];
+ if (h != 0.0) {
+ for (k = 0; k <= i; k++) {
+ d[k] = V[k][i+1] / h;
+ }
+ for (j = 0; j <= i; j++) {
+ g = 0.0;
+ for (k = 0; k <= i; k++) {
+ g += V[k][i+1] * V[k][j];
+ }
+ for (k = 0; k <= i; k++) {
+ V[k][j] -= g * d[k];
+ }
+ }
+ }
+ for (k = 0; k <= i; k++) {
+ V[k][i+1] = 0.0;
+ }
+ }
+ for (j = 0; j < n; j++) {
+ d[j] = V[n-1][j];
+ V[n-1][j] = 0.0;
+ }
+ V[n-1][n-1] = 1.0;
+ e[0] = 0.0;
+}
+
+// Symmetric tridiagonal QL algorithm.
+
+static void tql2(double V[n][n], double d[n], double e[n]) {
+
+// This is derived from the Algol procedures tql2, by
+// Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
+// Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
+// Fortran subroutine in EISPACK.
+
+ int i,j,m,l,k;
+ double g,p,r,dl1,h,f,tst1,eps;
+ double c,c2,c3,el1,s,s2;
+
+ for (i = 1; i < n; i++) {
+ e[i-1] = e[i];
+ }
+ e[n-1] = 0.0;
+
+ f = 0.0;
+ tst1 = 0.0;
+ eps = pow(2.0,-52.0);
+ for (l = 0; l < n; l++) {
+
+ // Find small subdiagonal element
+
+ tst1 = MAX(tst1,fabs(d[l]) + fabs(e[l]));
+ m = l;
+ while (m < n) {
+ if (fabs(e[m]) <= eps*tst1) {
+ break;
+ }
+ m++;
+ }
+
+ // If m == l, d[l] is an eigenvalue,
+ // otherwise, iterate.
+
+ if (m > l) {
+ int iter = 0;
+ do {
+ iter = iter + 1; // (Could check iteration count here.)
+
+ // Compute implicit shift
+
+ g = d[l];
+ p = (d[l+1] - g) / (2.0 * e[l]);
+ r = hypot2(p,1.0);
+ if (p < 0) {
+ r = -r;
+ }
+ d[l] = e[l] / (p + r);
+ d[l+1] = e[l] * (p + r);
+ dl1 = d[l+1];
+ h = g - d[l];
+ for (i = l+2; i < n; i++) {
+ d[i] -= h;
+ }
+ f = f + h;
+
+ // Implicit QL transformation.
+
+ p = d[m];
+ c = 1.0;
+ c2 = c;
+ c3 = c;
+ el1 = e[l+1];
+ s = 0.0;
+ s2 = 0.0;
+ for (i = m-1; i >= l; i--) {
+ c3 = c2;
+ c2 = c;
+ s2 = s;
+ g = c * e[i];
+ h = c * p;
+ r = hypot2(p,e[i]);
+ e[i+1] = s * r;
+ s = e[i] / r;
+ c = p / r;
+ p = c * d[i] - s * g;
+ d[i+1] = h + s * (c * g + s * d[i]);
+
+ // Accumulate transformation.
+
+ for (k = 0; k < n; k++) {
+ h = V[k][i+1];
+ V[k][i+1] = s * V[k][i] + c * h;
+ V[k][i] = c * V[k][i] - s * h;
+ }
+ }
+ p = -s * s2 * c3 * el1 * e[l] / dl1;
+ e[l] = s * p;
+ d[l] = c * p;
+
+ // Check for convergence.
+
+ } while (fabs(e[l]) > eps*tst1);
+ }
+ d[l] = d[l] + f;
+ e[l] = 0.0;
+ }
+
+ // Sort eigenvalues and corresponding vectors.
+
+ for (i = 0; i < n-1; i++) {
+ k = i;
+ p = d[i];
+ for (j = i+1; j < n; j++) {
+ if (d[j] < p) {
+ k = j;
+ p = d[j];
+ }
+ }
+ if (k != i) {
+ d[k] = d[i];
+ d[i] = p;
+ for (j = 0; j < n; j++) {
+ p = V[j][i];
+ V[j][i] = V[j][k];
+ V[j][k] = p;
+ }
+ }
+ }
+}
+
+void eigen_decomposition(double A[n][n], double V[n][n], double d[n]) {
+ int i,j;
+ double e[n];
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < n; j++) {
+ V[i][j] = A[i][j];
+ }
+ }
+ tred2(V, d, e);
+ tql2(V, d, e);
+}
Copied: code/player/branches/cmake/server/drivers/localization/amcl/pf/eig3.h
(from rev 6350, code/player/trunk/server/drivers/localization/amcl/pf/eig3.h)
===================================================================
--- code/player/branches/cmake/server/drivers/localization/amcl/pf/eig3.h
(rev 0)
+++ code/player/branches/cmake/server/drivers/localization/amcl/pf/eig3.h
2008-04-21 00:49:39 UTC (rev 6368)
@@ -0,0 +1,11 @@
+
+/* Eigen-decomposition for symmetric 3x3 real matrices.
+ Public domain, copied from the public domain Java library JAMA. */
+
+#ifndef _eig_h
+
+/* Symmetric matrix A => eigenvectors in columns of V, corresponding
+ eigenvalues in d. */
+void eigen_decomposition(double A[3][3], double V[3][3], double d[3]);
+
+#endif
Deleted:
code/player/branches/cmake/server/drivers/localization/amcl/pf/gsl_discrete.c
===================================================================
---
code/player/branches/cmake/server/drivers/localization/amcl/pf/gsl_discrete.c
2008-04-19 01:58:34 UTC (rev 6367)
+++
code/player/branches/cmake/server/drivers/localization/amcl/pf/gsl_discrete.c
2008-04-21 00:49:39 UTC (rev 6368)
@@ -1,394 +0,0 @@
-/* randist/discrete.c
- *
- * Copyright (C) 1996, 1997, 1998, 1999, 2000 James Theiler, Brian Gough
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- Random Discrete Events
-
- Given K discrete events with different probabilities P[k]
- produce a value k consistent with its probability.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details. You should have received
- a copy of the GNU General Public License along with this program;
- if not, write to the Free Foundation, Inc., 59 Temple Place, Suite
- 330, Boston, MA 02111-1307 USA
-*/
-
-/*
- * Based on: Alastair J Walker, An efficient method for generating
- * discrete random variables with general distributions, ACM Trans
- * Math Soft 3, 253-256 (1977). See also: D. E. Knuth, The Art of
- * Computer Programming, Volume 2 (Seminumerical algorithms), 3rd
- * edition, Addison-Wesley (1997), p120.
-
- * Walker's algorithm does some preprocessing, and provides two
- * arrays: floating point F[k] and integer A[k]. A value k is chosen
- * from 0..K-1 with equal likelihood, and then a uniform random number
- * u is compared to F[k]. If it is less than F[k], then k is
- * returned. Otherwise, A[k] is returned.
-
- * Walker's original paper describes an O(K^2) algorithm for setting
- * up the F and A arrays. I found this disturbing since I wanted to
- * use very large values of K. I'm sure I'm not the first to realize
- * this, but in fact the preprocessing can be done in O(K) steps.
-
- * A figure of merit for the preprocessing is the average value for
- * the F[k]'s (that is, SUM_k F[k]/K); this corresponds to the
- * probability that k is returned, instead of A[k], thereby saving a
- * redirection. Walker's O(K^2) preprocessing will generally improve
- * that figure of merit, compared to my cheaper O(K) method; from some
- * experiments with a perl script, I get values of around 0.6 for my
- * method and just under 0.75 for Walker's. Knuth has pointed out
- * that finding _the_ optimum lookup tables, which maximize the
- * average F[k], is a combinatorially difficult problem. But any
- * valid preprocessing will still provide O(1) time for the call to
- * gsl_ran_discrete(). I find that if I artificially set F[k]=1 --
- * ie, better than optimum! -- I get a speedup of maybe 20%, so that's
- * the maximum I could expect from the most expensive preprocessing.
- * Folding in the difference of 0.6 vs 0.75, I'd estimate that the
- * speedup would be less than 10%.
-
- * I've not implemented it here, but one compromise is to sort the
- * probabilities once, and then work from the two ends inward. This
- * requires O(K log K), still lots cheaper than O(K^2), and from my
- * experiments with the perl script, the figure of merit is within
- * about 0.01 for K up to 1000, and no sign of diverging (in fact,
- * they seemed to be converging, but it's hard to say with just a
- * handful of runs).
-
- * The O(K) algorithm goes through all the p_k's and decides if they
- * are "smalls" or "bigs" according to whether they are less than or
- * greater than the mean value 1/K. The indices to the smalls and the
- * bigs are put in separate stacks, and then we work through the
- * stacks together. For each small, we pair it up with the next big
- * in the stack (Walker always wanted to pair up the smallest small
- * with the biggest big). The small "borrows" from the big just
- * enough to bring the small up to mean. This reduces the size of the
- * big, so the (smaller) big is compared again to the mean, and if it
- * is smaller, it gets "popped" from the big stack and "pushed" to the
- * small stack. Otherwise, it stays put. Since every time we pop a
- * small, we are able to deal with it right then and there, and we
- * never have to pop more than K smalls, then the algorithm is O(K).
-
- * This implementation sets up two separate stacks, and allocates K
- * elements between them. Since neither stack ever grows, we do an
- * extra O(K) pass through the data to determine how many smalls and
- * bigs there are to begin with and allocate appropriately. In all
- * there are 2*K*sizeof(double) transient bytes of memory that are
- * used than returned, and K*(sizeof(int)+sizeof(double)) bytes used
- * in the lookup table.
-
- * Walker spoke of using two random numbers (an integer 0..K-1, and a
- * floating point u in [0,1]), but Knuth points out that one can just
- * use the integer and fractional parts of K*u where u is in [0,1].
- * In fact, Knuth further notes that taking F'[k]=(k+F[k])/K, one can
- * directly compare u to F'[k] without having to explicitly set
- * u=K*u-int(K*u).
-
- * Usage:
-
- * Starting with an array of probabilities P, initialize and do
- * preprocessing with a call to:
-
- * gsl_rng *r;
- * gsl_ran_discrete_t *f;
- * f = gsl_ran_discrete_preproc(K,P);
-
- * Then, whenever a random index 0..K-1 is desired, use
-
- * k = gsl_ran_discrete(r,f);
-
- * Note that several different randevent struct's can be
- * simultaneously active.
-
- * Aside: A very clever alternative approach is described in
- * Abramowitz and Stegun, p 950, citing: Marsaglia, Random variables
- * and computers, Proc Third Prague Conference in Probability Theory,
- * 1962. A more accesible reference is: G. Marsaglia, Generating
- * discrete random numbers in a computer, Comm ACM 6, 37-38 (1963).
- * If anybody is interested, I (jt) have also coded up this version as
- * part of another software package. However, I've done some
- * comparisons, and the Walker method is both faster and more stingy
- * with memory. So, in the end I decided not to include it with the
- * GSL package.
-
- * Written 26 Jan 1999, James Theiler, [EMAIL PROTECTED]
- * Adapted to GSL, 30 Jan 1999, jt
-
- */
-
-//#include <config.h>
-#include <stdio.h> /* used for NULL, also fprintf(stderr,...) */
-#include <stdlib.h> /* used for malloc's */
-#include <math.h>
-#include <gsl/gsl_rng.h>
-#include <gsl/gsl_randist.h>
-#define DEBUG 0
-#define KNUTH_CONVENTION 1 /* Saves a few steps of arithmetic
- * in the call to gsl_ran_discrete()
- */
-
-/*** Begin Stack (this code is used just in this file) ***/
-
-/* Stack code converted to use unsigned indices (i.e. s->i == 0 now
- means an empty stack, instead of -1), for consistency and to give a
- bigger allowable range. BJG */
-
-typedef struct {
- size_t N; /* max number of elts on stack */
- size_t *v; /* array of values on the stack */
- size_t i; /* index of top of stack */
-} gsl_stack_t;
-
-static gsl_stack_t *
-new_stack(size_t N) {
- gsl_stack_t *s;
- s = (gsl_stack_t *)malloc(sizeof(gsl_stack_t));
- s->N = N;
- s->i = 0; /* indicates stack is empty */
- s->v = (size_t *)malloc(sizeof(size_t)*N);
- return s;
-}
-
-static void
-push_stack(gsl_stack_t *s, size_t v)
-{
- if ((s->i) >= (s->N)) {
- fprintf(stderr,"Cannot push stack!\n");
- abort(); /* FIXME: fatal!! */
- }
- (s->v)[s->i] = v;
- s->i += 1;
-}
-
-static size_t pop_stack(gsl_stack_t *s)
-{
- if ((s->i) == 0) {
- fprintf(stderr,"Cannot pop stack!\n");
- abort(); /* FIXME: fatal!! */
- }
- s->i -= 1;
- return ((s->v)[s->i]);
-}
-
-static inline size_t size_stack(const gsl_stack_t *s)
-{
- return s->i;
-}
-
-static void free_stack(gsl_stack_t *s)
-{
- free((char *)(s->v));
- free((char *)s);
-}
-
-/*** End Stack ***/
-
-
-/*** Begin Walker's Algorithm ***/
-
-gsl_ran_discrete_t *
-gsl_ran_discrete_preproc(size_t Kevents, const double *ProbArray)
-{
- size_t k,b,s;
- gsl_ran_discrete_t *g;
- size_t nBigs, nSmalls;
- gsl_stack_t *Bigs;
- gsl_stack_t *Smalls;
- double *E;
- double pTotal = 0.0, mean, d;
-
- if (Kevents < 1) {
- /* Could probably treat Kevents=1 as a special case */
-
- GSL_ERROR_VAL ("number of events must be a positive integer",
- GSL_EINVAL, 0);
- }
-
- /* Make sure elements of ProbArray[] are positive.
- * Won't enforce that sum is unity; instead will just normalize
- */
-
- for (k=0; k<Kevents; ++k) {
- if (ProbArray[k] < 0) {
- GSL_ERROR_VAL ("probabilities must be non-negative",
- GSL_EINVAL, 0) ;
- }
- pTotal += ProbArray[k];
- }
-
- /* Begin setting up the main "object" (just a struct, no steroids) */
- g = (gsl_ran_discrete_t *)malloc(sizeof(gsl_ran_discrete_t));
- g->K = Kevents;
- g->F = (double *)malloc(sizeof(double)*Kevents);
- g->A = (size_t *)malloc(sizeof(size_t)*Kevents);
-
- E = (double *)malloc(sizeof(double)*Kevents);
-
- if (E==NULL) {
- GSL_ERROR_VAL ("Cannot allocate memory for randevent", ENOMEM, 0);
- }
-
- for (k=0; k<Kevents; ++k) {
- E[k] = ProbArray[k]/pTotal;
- }
-
- /* Now create the Bigs and the Smalls */
- mean = 1.0/Kevents;
- nSmalls=nBigs=0;
- for (k=0; k<Kevents; ++k) {
- if (E[k] < mean) ++nSmalls;
- else ++nBigs;
- }
- Bigs = new_stack(nBigs);
- Smalls = new_stack(nSmalls);
- for (k=0; k<Kevents; ++k) {
- if (E[k] < mean) {
- push_stack(Smalls,k);
- }
- else {
- push_stack(Bigs,k);
- }
- }
- /* Now work through the smalls */
- while (size_stack(Smalls) > 0) {
- s = pop_stack(Smalls);
- if (size_stack(Bigs) == 0) {
- /* Then we are on our last value */
- (g->A)[s]=s;
- (g->F)[s]=1.0;
- continue;
- }
- b = pop_stack(Bigs);
- (g->A)[s]=b;
- (g->F)[s]=Kevents*E[s];
-#if DEBUG
- fprintf(stderr,"s=%2d, A=%2d, F=%.4f\n",s,(g->A)[s],(g->F)[s]);
-#endif
- d = mean - E[s];
- E[s] += d; /* now E[s] == mean */
- E[b] -= d;
- if (E[b] < mean) {
- push_stack(Smalls,b); /* no longer big, join ranks of the small */
- }
- else if (E[b] > mean) {
- push_stack(Bigs,b); /* still big, put it back where you found it */
- }
- else {
- /* E[b]==mean implies it is finished too */
- (g->A)[b]=b;
- (g->F)[b]=1.0;
- }
- }
- while (size_stack(Bigs) > 0) {
- b = pop_stack(Bigs);
- (g->A)[b]=b;
- (g->F)[b]=1.0;
- }
- /* Stacks have been emptied, and A and F have been filled */
-
-
-#if 0
- /* if 1, then artificially set all F[k]'s to unity. This will
- * give wrong answers, but you'll get them faster. But, not
- * that much faster (I get maybe 20%); that's an upper bound
- * on what the optimal preprocessing would give.
- */
- for (k=0; k<Kevents; ++k) {
- (g->F)[k] = 1.0;
- }
-#endif
-
-#if KNUTH_CONVENTION
- /* For convenience, set F'[k]=(k+F[k])/K */
- /* This saves some arithmetic in gsl_ran_discrete(); I find that
- * it doesn't actually make much difference.
- */
- for (k=0; k<Kevents; ++k) {
- (g->F)[k] += k;
- (g->F)[k] /= Kevents;
- }
-#endif
-
- free_stack(Bigs);
- free_stack(Smalls);
- free((char *)E);
-
- return g;
-}
-
-size_t
-gsl_ran_discrete(const gsl_rng *r, const gsl_ran_discrete_t *g)
-{
- size_t c=0;
- double u,f;
- u = gsl_rng_uniform(r);
-#if KNUTH_CONVENTION
- c = (u*(g->K));
-#else
- u *= g->K;
- c = u;
- u -= c;
-#endif
- f = (g->F)[c];
- /* fprintf(stderr,"c,f,u: %d %.4f %f\n",c,f,u); */
- if (f == 1.0) return c;
-
- if (u < f) {
- return c;
- }
- else {
- return (g->A)[c];
- }
-}
-
-void gsl_ran_discrete_free(gsl_ran_discrete_t *g)
-{
- free((char *)(g->A));
- free((char *)(g->F));
- free((char *)g);
-}
-
-double
-gsl_ran_discrete_pdf(size_t k, const gsl_ran_discrete_t *g)
-{
- size_t i,K;
- double f,p=0;
- K= g->K;
- if (k>K) return 0;
- for (i=0; i<K; ++i) {
- f = (g->F)[i];
-#if KNUTH_CONVENTION
- f = K*f-i;
-#endif
- if (i==k) {
- p += f;
- } else if (k == (g->A)[i]) {
- p += 1.0 - f;
- }
- }
- return p/K;
-}
Modified: code/player/branches/cmake/server/drivers/localization/amcl/pf/pf.c
===================================================================
--- code/player/branches/cmake/server/drivers/localization/amcl/pf/pf.c
2008-04-19 01:58:34 UTC (rev 6367)
+++ code/player/branches/cmake/server/drivers/localization/amcl/pf/pf.c
2008-04-21 00:49:39 UTC (rev 6368)
@@ -217,15 +217,20 @@
{
int i;
double total;
- double *randlist;
+ //double *randlist;
pf_sample_set_t *set_a, *set_b;
pf_sample_t *sample_a, *sample_b;
- pf_pdf_discrete_t *pdf;
+ //pf_pdf_discrete_t *pdf;
+ double r,c,U;
+ int m;
+ double count_inv;
+
set_a = pf->sets + pf->current_set;
set_b = pf->sets + (pf->current_set + 1) % 2;
// Create the discrete distribution to sample from
+ /*
total = 0;
randlist = calloc(set_a->sample_count, sizeof(double));
for (i = 0; i < set_a->sample_count; i++)
@@ -233,21 +238,48 @@
total += set_a->samples[i].weight;
randlist[i] = set_a->samples[i].weight;
}
+ */
//printf("resample total %f\n", total);
// Initialize the random number generator
- pdf = pf_pdf_discrete_alloc(set_a->sample_count, randlist);
+ //pdf = pf_pdf_discrete_alloc(set_a->sample_count, randlist);
// Create the kd tree for adaptive sampling
pf_kdtree_clear(set_b->kdtree);
-
+
// Draw samples from set a to create set b.
total = 0;
set_b->sample_count = 0;
- while (set_b->sample_count < pf->max_samples)
+
+ // Low-variance resampler, taken from Probabilistic Robotics, p110
+ count_inv = 1.0/set_a->sample_count;
+ r = drand48() * count_inv;
+ c = set_a->samples[0].weight;
+ i = 0;
+ m = 0;
+ while(set_b->sample_count < pf->max_samples)
{
- i = pf_pdf_discrete_sample(pdf);
+ U = r + m * count_inv;
+ while(U>c)
+ {
+ i++;
+ // Handle wrap-around by resetting counters and picking a new random
+ // number
+ if(i >= set_a->sample_count)
+ {
+ r = drand48() * count_inv;
+ c = set_a->samples[0].weight;
+ i = 0;
+ m = 0;
+ U = r + m * count_inv;
+ continue;
+ }
+ c += set_a->samples[i].weight;
+ }
+
+ //i = pf_pdf_discrete_sample(pdf);
+
sample_a = set_a->samples + i;
//printf("%d %f\n", i, sample_a->weight);
@@ -263,17 +295,19 @@
pf_kdtree_insert(set_b->kdtree, sample_b->pose, sample_b->weight);
//fprintf(stderr, "resample %d %d %d\n", set_b->sample_count,
set_b->kdtree->leaf_count,
- // pf_resample_limit(pf, set_b->kdtree->leaf_count));
+ //pf_resample_limit(pf, set_b->kdtree->leaf_count));
// See if we have enough samples yet
if (set_b->sample_count > pf_resample_limit(pf, set_b->kdtree->leaf_count))
break;
+
+ m++;
}
//fprintf(stderr, "\n\n");
- pf_pdf_discrete_free(pdf);
- free(randlist);
+ //pf_pdf_discrete_free(pdf);
+ //free(randlist);
// Normalize weights
for (i = 0; i < set_b->sample_count; i++)
Modified:
code/player/branches/cmake/server/drivers/localization/amcl/pf/pf_pdf.c
===================================================================
--- code/player/branches/cmake/server/drivers/localization/amcl/pf/pf_pdf.c
2008-04-19 01:58:34 UTC (rev 6367)
+++ code/player/branches/cmake/server/drivers/localization/amcl/pf/pf_pdf.c
2008-04-21 00:49:39 UTC (rev 6368)
@@ -10,8 +10,8 @@
#include <math.h>
#include <stdlib.h>
#include <string.h>
-#include <gsl/gsl_rng.h>
-#include <gsl/gsl_randist.h>
+//#include <gsl/gsl_rng.h>
+//#include <gsl/gsl_randist.h>
#include "pf_pdf.h"
@@ -33,7 +33,7 @@
pdf->x = x;
pdf->cx = cx;
- pdf->cxi = pf_matrix_inverse(cx, &pdf->cxdet);
+ //pdf->cxi = pf_matrix_inverse(cx, &pdf->cxdet);
// Decompose the convariance matrix into a rotation
// matrix and a diagonal matrix.
@@ -43,8 +43,9 @@
pdf->cd.v[2] = sqrt(cd.m[2][2]);
// Initialize the random number generator
- pdf->rng = gsl_rng_alloc(gsl_rng_taus);
- gsl_rng_set(pdf->rng, ++pf_pdf_seed);
+ //pdf->rng = gsl_rng_alloc(gsl_rng_taus);
+ //gsl_rng_set(pdf->rng, ++pf_pdf_seed);
+ srand48(++pf_pdf_seed);
return pdf;
}
@@ -53,12 +54,13 @@
// Destroy the pdf
void pf_pdf_gaussian_free(pf_pdf_gaussian_t *pdf)
{
- gsl_rng_free(pdf->rng);
+ //gsl_rng_free(pdf->rng);
free(pdf);
return;
}
+/*
// Compute the value of the pdf at some point [x].
double pf_pdf_gaussian_value(pf_pdf_gaussian_t *pdf, pf_vector_t x)
{
@@ -77,6 +79,7 @@
return p;
}
+*/
// Generate a sample from the the pdf.
@@ -88,7 +91,10 @@
// Generate a random vector
for (i = 0; i < 3; i++)
- r.v[i] = gsl_ran_gaussian(pdf->rng, pdf->cd.v[i]);
+ {
+ //r.v[i] = gsl_ran_gaussian(pdf->rng, pdf->cd.v[i]);
+ r.v[i] = pf_ran_gaussian(pdf->cd.v[i]);
+ }
for (i = 0; i < 3; i++)
{
@@ -100,7 +106,28 @@
return x;
}
+// Draw randomly from a zero-mean Gaussian distribution, with standard
+// deviation sigma.
+// We use the polar form of the Box-Muller transformation, explained here:
+// http://www.taygeta.com/random/gaussian.html
+double pf_ran_gaussian(double sigma)
+{
+ double x1, x2, w, r;
+ do
+ {
+ do { r = drand48(); } while (r==0.0);
+ x1 = 2.0 * r - 1.0;
+ do { r = drand48(); } while (r==0.0);
+ x2 = 2.0 * r - 1.0;
+ w = x1*x1 + x2*x2;
+ } while(w > 1.0 || w==0.0);
+
+ return(sigma * x2 * sqrt(-2.0*log(w)/w));
+}
+
+#if 0
+
/**************************************************************************
* Discrete
* Note that GSL v1.3 and earlier contains a bug in the discrete
@@ -159,3 +186,5 @@
return i;
}
+
+#endif
Modified:
code/player/branches/cmake/server/drivers/localization/amcl/pf/pf_pdf.h
===================================================================
--- code/player/branches/cmake/server/drivers/localization/amcl/pf/pf_pdf.h
2008-04-19 01:58:34 UTC (rev 6367)
+++ code/player/branches/cmake/server/drivers/localization/amcl/pf/pf_pdf.h
2008-04-21 00:49:39 UTC (rev 6368)
@@ -11,8 +11,8 @@
#include "pf_vector.h"
-#include <gsl/gsl_rng.h>
-#include <gsl/gsl_randist.h>
+//#include <gsl/gsl_rng.h>
+//#include <gsl/gsl_randist.h>
#ifdef __cplusplus
extern "C" {
@@ -28,7 +28,7 @@
// Mean, covariance and inverse covariance
pf_vector_t x;
pf_matrix_t cx;
- pf_matrix_t cxi;
+ //pf_matrix_t cxi;
double cxdet;
// Decomposed covariance matrix (rotation * diagonal)
@@ -36,7 +36,7 @@
pf_vector_t cd;
// A random number generator
- gsl_rng *rng;
+ //gsl_rng *rng;
} pf_pdf_gaussian_t;
@@ -48,12 +48,20 @@
void pf_pdf_gaussian_free(pf_pdf_gaussian_t *pdf);
// Compute the value of the pdf at some point [z].
-double pf_pdf_gaussian_value(pf_pdf_gaussian_t *pdf, pf_vector_t z);
+//double pf_pdf_gaussian_value(pf_pdf_gaussian_t *pdf, pf_vector_t z);
+// Draw randomly from a zero-mean Gaussian distribution, with standard
+// deviation sigma.
+// We use the polar form of the Box-Muller transformation, explained here:
+// http://www.taygeta.com/random/gaussian.html
+double pf_ran_gaussian(double sigma);
+
// Generate a sample from the the pdf.
pf_vector_t pf_pdf_gaussian_sample(pf_pdf_gaussian_t *pdf);
+#if 0
+
/**************************************************************************
* Discrete
*************************************************************************/
@@ -85,6 +93,7 @@
// Generate a sample from the the pdf.
int pf_pdf_discrete_sample(pf_pdf_discrete_t *pdf);
+#endif
#ifdef __cplusplus
}
Modified:
code/player/branches/cmake/server/drivers/localization/amcl/pf/pf_vector.c
===================================================================
--- code/player/branches/cmake/server/drivers/localization/amcl/pf/pf_vector.c
2008-04-19 01:58:34 UTC (rev 6367)
+++ code/player/branches/cmake/server/drivers/localization/amcl/pf/pf_vector.c
2008-04-21 00:49:39 UTC (rev 6368)
@@ -7,11 +7,12 @@
*************************************************************************/
#include <math.h>
-#include <gsl/gsl_matrix.h>
-#include <gsl/gsl_eigen.h>
-#include <gsl/gsl_linalg.h>
+//#include <gsl/gsl_matrix.h>
+//#include <gsl/gsl_eigen.h>
+//#include <gsl/gsl_linalg.h>
#include "pf_vector.h"
+#include "eig3.h"
// Return a zero vector
@@ -156,6 +157,7 @@
}
+/*
// Compute the matrix inverse
pf_matrix_t pf_matrix_inverse(pf_matrix_t a, double *det)
{
@@ -193,6 +195,7 @@
return ai;
}
+*/
// Decompose a covariance matrix [a] into a rotation matrix [r] and a diagonal
@@ -200,6 +203,7 @@
void pf_matrix_unitary(pf_matrix_t *r, pf_matrix_t *d, pf_matrix_t a)
{
int i, j;
+ /*
gsl_matrix *aa;
gsl_vector *eval;
gsl_matrix *evec;
@@ -208,27 +212,45 @@
aa = gsl_matrix_alloc(3, 3);
eval = gsl_vector_alloc(3);
evec = gsl_matrix_alloc(3, 3);
+ */
+ double aa[3][3];
+ double eval[3];
+ double evec[3][3];
+
for (i = 0; i < 3; i++)
+ {
for (j = 0; j < 3; j++)
- gsl_matrix_set(aa, i, j, a.m[i][j]);
+ {
+ //gsl_matrix_set(aa, i, j, a.m[i][j]);
+ aa[i][j] = a.m[i][j];
+ }
+ }
// Compute eigenvectors/values
+ /*
w = gsl_eigen_symmv_alloc(3);
gsl_eigen_symmv(aa, eval, evec, w);
gsl_eigen_symmv_free(w);
+ */
+ eigen_decomposition(aa,evec,eval);
+
*d = pf_matrix_zero();
for (i = 0; i < 3; i++)
{
- d->m[i][i] = gsl_vector_get(eval, i);
+ //d->m[i][i] = gsl_vector_get(eval, i);
+ d->m[i][i] = eval[i];
for (j = 0; j < 3; j++)
- r->m[i][j] = gsl_matrix_get(evec, i, j);
+ {
+ //r->m[i][j] = gsl_matrix_get(evec, i, j);
+ r->m[i][j] = evec[i][j];
+ }
}
- gsl_matrix_free(evec);
- gsl_vector_free(eval);
- gsl_matrix_free(aa);
+ //gsl_matrix_free(evec);
+ //gsl_vector_free(eval);
+ //gsl_matrix_free(aa);
return;
}
Modified:
code/player/branches/cmake/server/drivers/localization/amcl/pf/pf_vector.h
===================================================================
--- code/player/branches/cmake/server/drivers/localization/amcl/pf/pf_vector.h
2008-04-19 01:58:34 UTC (rev 6367)
+++ code/player/branches/cmake/server/drivers/localization/amcl/pf/pf_vector.h
2008-04-21 00:49:39 UTC (rev 6368)
@@ -62,7 +62,7 @@
// Compute the matrix inverse. Will also return the determinant,
// which should be checked for underflow (indicated singular matrix).
-pf_matrix_t pf_matrix_inverse(pf_matrix_t a, double *det);
+//pf_matrix_t pf_matrix_inverse(pf_matrix_t a, double *det);
// Decompose a covariance matrix [a] into a rotation matrix [r] and a
// diagonal matrix [d] such that a = r * d * r^T.
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit