test_compare_filters.cpp
Go to the documentation of this file.
1 // $Id: test_compare_filters.cpp 5925 2006-03-14 21:23:49Z tdelaet $
2 // Copyright (C) 2006 Klaas Gadeyne <first dot last at gmail dot com>
3 // Tinne De Laet <first dot last at mech dot kuleuven dot be>
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published by
7 // the Free Software Foundation; either version 2.1 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 
19 /* Demonstration program for the Bayesian Filtering Library.
20  Mobile robot localization with respect to wall with different possibilities for filter
21 */
22 
23 #include <filter/bootstrapfilter.h>
26 #include <filter/asirfilter.h>
28 
33 #include <pdf/gaussian.h>
34 
37 
38 #include <iostream>
39 #include <fstream>
40 #include <string>
41 
42 // Include file with properties
43 #include "../mobile_robot_wall_cts.h"
44 // Include pdf specific for this example
46 // Include the mobile_robot simulator
47 #include "../mobile_robot.h"
48 
49 /* The purpose of this program is to test different filter for the problem
50  of localisation of a mobile robot equipped with an ultrasonic sensor.
51  The ultrasonic measures the distance to the wall (it can be switched off:
52  see mobile_robot_wall_cts.h)
53 
54  The necessary SYSTEM MODEL is:
55 
56  x_k = x_{k-1} + v_{k-1} * cos(theta_{k-1} * delta_t
57  y_k = y_{k-1} + v_{k-1} * sin(theta_{k-1} * delta_t
58  theta_k = theta_{k-1} + omega_{k-1} * delta_t
59 
60  The used MEASUREMENT MODEL:
61  measuring the (perpendicular) distance z to the wall y = ax + b
62 
63  set WALL_CT = 1/sqrt(pow(a,2) + 1)
64  z = WALL_CT * a * x - WALL_CT * y + WALL_CT * b + GAUSSIAN_NOISE
65  or Z = H * X_k + J * U_k
66 
67  where
68 
69  H = [ WALL_CT * a - WALL_CT 0 ]
70  and GAUSSIAN_NOISE = N((WALL_CT * b), SIGMA_MEAS_NOISE)
71 
72 */
73 
74 using namespace MatrixWrapper;
75 using namespace BFL;
76 using namespace std;
77 
78 #define KALMAN 1
79 #define IE_KALMAN 2
80 #define BOOTSTRAP 3
81 #define EK_PARTICLE 4
82 #define ASIR 5
83 
84 int main(int argc, char** argv)
85 {
86  cerr << "==================================================" << endl
87  << "Test of switching between different filters" << endl
88  << "Mobile robot localisation example" << endl
89  << "==================================================" << endl;
90 
91 
92  int filter_name;
93  if (!(argc== 2 ))
94  {
95  cout << "Please provide one argument. Possible arguments are:" << endl
96  << " kalman_filter" << endl
97  << " bootstrap_filter" << endl
98  << " EK_particle_filter" << endl
99  << " ASIR_filter" << endl
100  << " IE_kalman_filter" << endl;
101  return 0;
102  }
103  else {
104  string argument = argv[1];
105  if (argument == "kalman_filter") filter_name = KALMAN;
106  else if (argument == "IE_kalman_filter") filter_name = IE_KALMAN;
107  else if (argument == "bootstrap_filter") filter_name = BOOTSTRAP;
108  else if (argument == "EK_particle_filter") filter_name = EK_PARTICLE;
109  else if (argument == "ASIR_filter") filter_name = ASIR;
110  else
111  {
112  cout << "Please provide another argument. Possible arguments are:" << endl
113  << " kalman_filter" << endl
114  << " bootstrap_filter" << endl
115  << " EK_particle_filter" << endl
116  << " ASIR_filter" << endl
117  << " IE_kalman_filter" << endl;
118  return 0 ;
119  }
120  }
121 
122  /***********************
123  * PREPARE FILESTREAMS *
124  **********************/
125  ofstream fout_time, fout_E, fout_cov, fout_meas, fout_states, fout_particles, fout_numparticles;
126 
127  fout_time.open("time.out");
128  fout_E.open("E.out");
129  fout_cov.open("cov.out");
130  fout_meas.open("meas.out");
131  fout_states.open("states.out");
132 
133  if ((filter_name == BOOTSTRAP) || (filter_name == EK_PARTICLE) ||(filter_name == ASIR))
134  {
135  fout_particles.open("particles.out");
136  fout_numparticles.open("numparticles.out");
137  }
138 
139 
140  /****************************
141  * Initialise system model *
142  ***************************/
143  ColumnVector sys_noise_Mu(STATE_SIZE);
144  sys_noise_Mu = 0.0;
145  sys_noise_Mu(1) = MU_SYSTEM_NOISE_X;
146  sys_noise_Mu(2) = MU_SYSTEM_NOISE_Y;
147  sys_noise_Mu(3) = MU_SYSTEM_NOISE_THETA;
148 
149  SymmetricMatrix sys_noise_Cov(STATE_SIZE);
150  sys_noise_Cov = 0.0;
151  sys_noise_Cov(1,1) = SIGMA_SYSTEM_NOISE_X;
152  sys_noise_Cov(1,2) = 0.0;
153  sys_noise_Cov(1,3) = 0.0;
154  sys_noise_Cov(2,1) = 0.0;
155  sys_noise_Cov(2,2) = SIGMA_SYSTEM_NOISE_Y;
156  sys_noise_Cov(2,3) = 0.0;
157  sys_noise_Cov(3,1) = 0.0;
158  sys_noise_Cov(3,2) = 0.0;
159  sys_noise_Cov(3,3) = SIGMA_SYSTEM_NOISE_THETA;
160 
161  Gaussian system_Uncertainty(sys_noise_Mu, sys_noise_Cov);
162  NonLinearAnalyticConditionalGaussianMobile sys_pdf(system_Uncertainty);
163  AnalyticSystemModelGaussianUncertainty sys_model(&sys_pdf);
164 
165 
166  /*********************************
167  * Initialise measurement model *
168  ********************************/
169  // Fill up H
170  double wall_ct = 2/(sqrt(pow(RICO_WALL,2.0) + 1));
171  Matrix H(MEAS_SIZE,STATE_SIZE);
172  H = 0.0;
173  H(1,1) = wall_ct * RICO_WALL;
174  H(1,2) = 0 - wall_ct;
175  cout<< "Measurment model H = " << H << endl;
176 
177  // Construct the measurement noise (a scalar in this case)
178  ColumnVector MeasNoise_Mu(MEAS_SIZE);
179  SymmetricMatrix MeasNoise_Cov(MEAS_SIZE);
180  MeasNoise_Mu(1) = MU_MEAS_NOISE;
181  MeasNoise_Cov(1,1) = SIGMA_MEAS_NOISE;
182 
183  Gaussian Measurement_Uncertainty(MeasNoise_Mu,MeasNoise_Cov);
184  LinearAnalyticConditionalGaussian meas_pdf(H,Measurement_Uncertainty);
186 
187 
188  /****************************
189  * Initialise prior DENSITY *
190  ***************************/
191  // Continuous Gaussian prior (for Kalman filters)
192  ColumnVector prior_mu(STATE_SIZE);
193  SymmetricMatrix prior_sigma(STATE_SIZE);
194  prior_mu(1) = PRIOR_MU_X;
195  prior_mu(2) = PRIOR_MU_Y;
196  prior_mu(STATE_SIZE) = PRIOR_MU_THETA;
197  prior_sigma = 0.0;
198  prior_sigma(1,1) = PRIOR_COV_X;
199  prior_sigma(2,2) = PRIOR_COV_Y;
200  prior_sigma(3,3) = PRIOR_COV_THETA;
201  Gaussian prior_cont(prior_mu,prior_sigma);
202 
203  // Discrete prior for Particle filter (using the continuous Gaussian prior)
204  vector<Sample<ColumnVector> > prior_samples(NUM_SAMPLES);
206  prior_cont.SampleFrom(prior_samples,NUM_SAMPLES,CHOLESKY,NULL);
207  prior_discr.ListOfSamplesSet(prior_samples);
208 
209  cout<< "Prior initialised"<< "" << endl;
210  cout << "Prior Mean = " << endl << prior_cont.ExpectedValueGet() << endl
211  << "Covariance = " << endl << prior_cont.CovarianceGet() << endl;
212 
213 
214 
215 
216  /***************************
217  * initialise MOBILE ROBOT *
218  **************************/
219  // Model of mobile robot in world with one wall
220  // The model is used to simultate the distance measurements.
221  MobileRobot mobile_robot;
222  ColumnVector input(INPUT_SIZE);
223  input(1) = LIN_SPEED * DELTA_T;
224  input(2) = ROT_SPEED * DELTA_T;
225  cout << "Mobile robot initialised"<< "" << endl;
226 
227 
228 
229  /******************************
230  * Construction of the Filter *
231  ******************************/
232  Filter<ColumnVector,ColumnVector> * my_filter = NULL;
233 
234  switch (filter_name){
235  case KALMAN:{
236  cout << "Using the Extended Kalman Filter" << endl;
237  my_filter = new ExtendedKalmanFilter(&prior_cont);
238  break;}
239  case IE_KALMAN:{
240  cout << "Using the Iterated Extended Kalman Filter, " << NUM_ITERATIONS << " iterations" << endl;
241  my_filter = new IteratedExtendedKalmanFilter(&prior_cont,NUM_ITERATIONS);
242  break;}
243  case BOOTSTRAP:{
244  cout << "Using the bootstrapfilter, " << NUM_SAMPLES << " samples, dynamic resampling" << endl;
246  break;}
247  case EK_PARTICLE:{
248  cout << "Using the Extended Particle Kalman Filter, " << NUM_SAMPLES << " samples, dynamic resampling" << endl;
249  my_filter = new EKParticleFilter(&prior_discr, 0, RESAMPLE_THRESHOLD);
250  break;}
251  //case ASIR:{
252  //cout << "Using the ASIR-filter, " << NUM_SAMPLES << " samples, fixed period resampling" << endl;
253  //my_filter = new ASIRFilter<ColumnVector,ColumnVector> (prior_discr, RESAMPLE_PERIOD, RESAMPLE_THRESHOLD);
254  //break;}
255  default:{
256  cout << "Type if filter not recognised on construction" <<endl;
257  return 0 ;}
258  }
259 
260 
261 
262  /*******************
263  * ESTIMATION LOOP *
264  *******************/
265  cout << "MAIN: Starting estimation" << endl;
266  unsigned int time_step;
267  for (time_step = 0; time_step < NUM_TIME_STEPS-1; time_step++)
268  {
269  // write date in files
270  fout_time << time_step << ";" << endl;
271  fout_meas << mobile_robot.Measure()(1) << ";" << endl;
272  fout_states << mobile_robot.GetState()(1) << "," << mobile_robot.GetState()(2) << ","
273  << mobile_robot.GetState()(3) << ";" << endl;
274 
275  // write posterior to file
276  Pdf<ColumnVector> * posterior = my_filter->PostGet();
277  fout_E << posterior->ExpectedValueGet()(1) << "," << posterior->ExpectedValueGet()(2)<< ","
278  << posterior->ExpectedValueGet()(3) << ";" << endl;
279  fout_cov << posterior->CovarianceGet()(1,1) << "," << posterior->CovarianceGet()(1,2) << ","
280  << posterior->CovarianceGet()(1,3) << "," << posterior->CovarianceGet()(2,2) << ","
281  << posterior->CovarianceGet()(2,3) << "," << posterior->CovarianceGet()(3,3) << ";" << endl;
282 
283 
284  // write particles to file
285  if ((filter_name == BOOTSTRAP) || (filter_name == EK_PARTICLE) ||(filter_name == ASIR))
286  {
287  fout_numparticles << ((MCPdf<ColumnVector>*)posterior)->NumSamplesGet() << ";" << endl;
288  vector<WeightedSample<ColumnVector> > samples_list = ((MCPdf<ColumnVector>*)posterior)->ListOfSamplesGet() ;
289  vector<WeightedSample<ColumnVector> >::iterator sample;
290  for ( sample = samples_list.begin() ; sample != samples_list.end() ; sample++ )
291  fout_particles << sample->ValueGet()(1) << "," << sample->ValueGet()(2) << ","
292  << sample->ValueGet()(3) << "," << sample->WeightGet() <<";"<<endl;
293  }
294 
295 
296  // DO ONE STEP WITH MOBILE ROBOT
297  mobile_robot.Move(input);
298 
299  // DO ONE MEASUREMENT
300  ColumnVector measurement = mobile_robot.Measure();
301 
302  // UPDATE FILTER
303  if (USE_MEASUREMENTS)
304  my_filter->Update(&sys_model,input,&meas_model, measurement);
305  else
306  my_filter->Update(&sys_model, input);
307  } // estimation loop
308 
309 
310 
311  Pdf<ColumnVector> * posterior = my_filter->PostGet();
312  cout << "After " << time_step+1 << " timesteps " << endl;
313  cout << " Posterior Mean = " << endl << posterior->ExpectedValueGet() << endl
314  << " Covariance = " << endl << posterior->CovarianceGet() << "" << endl;
315  cout << "=============================================" << endl;
316 
317 
318  // delete the filter
319  delete my_filter;
320 
321  cout << "==================================================" << endl
322  << "End of the Comparing filters test" << endl
323  << "=================================================="
324  << endl;
325 
326 
327 
328  /****************************
329  * CLOSE FILESTREAMS
330  ***************************/
331  fout_time.close();
332  fout_E.close();
333  fout_cov.close();
334  fout_meas.close();
335  fout_states.close();
336  if ((filter_name == BOOTSTRAP) || (filter_name == EK_PARTICLE) ||(filter_name == ASIR))
337  {
338  fout_particles.close();
339  fout_numparticles.close();
340  }
341  return 0;
342 }
virtual MatrixWrapper::SymmetricMatrix CovarianceGet() const
Get the Covariance Matrix E[(x - E[x])^2] of the Analytic pdf.
Definition: gaussian.cpp:187
MatrixWrapper::ColumnVector GetState()
Particular particle filter : Proposal PDF = SystemPDF.
virtual MatrixWrapper::ColumnVector ExpectedValueGet() const
Get the expected value E[x] of the pdf.
Definition: gaussian.cpp:181
#define MU_MEAS_NOISE
#define SIGMA_MEAS_NOISE
Class PDF: Virtual Base class representing Probability Density Functions.
Definition: pdf.h:53
This is a class simulating a mobile robot.
Definition: mobile_robot.h:47
virtual MatrixWrapper::SymmetricMatrix CovarianceGet() const
Get the Covariance Matrix E[(x - E[x])^2] of the Analytic pdf.
bool SampleFrom(vector< Sample< MatrixWrapper::ColumnVector > > &list_samples, const int num_samples, int method=DEFAULT, void *args=NULL) const
MatrixWrapper::ColumnVector Measure()
#define MEAS_SIZE
#define KALMAN
Class representing Gaussian (or normal density)
Definition: gaussian.h:27
#define NUM_ITERATIONS
#define EK_PARTICLE
#define MU_SYSTEM_NOISE_X
#define LIN_SPEED
#define BOOTSTRAP
#define ROT_SPEED
Particle filter using EKF for proposal step.
#define RICO_WALL
#define MU_SYSTEM_NOISE_THETA
#define RESAMPLE_THRESHOLD
#define SIGMA_SYSTEM_NOISE_THETA
virtual Pdf< StateVar > * PostGet()
Get Posterior density.
Definition: filter.cpp:126
#define STATE_SIZE
#define INPUT_SIZE
#define RESAMPLE_PERIOD
#define PRIOR_COV_THETA
#define PRIOR_COV_Y
virtual T ExpectedValueGet() const
Get the expected value E[x] of the pdf.
void Move(MatrixWrapper::ColumnVector inputs)
int main(int argc, char **argv)
Monte Carlo Pdf: Sample based implementation of Pdf.
Definition: mcpdf.h:49
Class for analytic system models with additive Gauss. uncertainty.
#define PRIOR_MU_X
#define PRIOR_MU_THETA
#define ASIR
#define PRIOR_COV_X
#define IE_KALMAN
Class for linear analytic measurementmodels with additive gaussian noise.
#define CHOLESKY
#define SIGMA_SYSTEM_NOISE_X
const unsigned int NUM_SAMPLES
Definition: pdf_test.cpp:37
#define PRIOR_MU_Y
virtual bool Update(SystemModel< StateVar > *const sysmodel, const StateVar &u, MeasurementModel< MeasVar, StateVar > *const measmodel, const MeasVar &z, const StateVar &s)
Full Update (system with inputs/sensing params)
Definition: filter.h:56
bool ListOfSamplesSet(const vector< WeightedSample< T > > &list_of_samples)
Set the list of weighted samples.
#define MU_SYSTEM_NOISE_Y
#define DELTA_T
#define SIGMA_SYSTEM_NOISE_Y
#define NUM_TIME_STEPS
#define USE_MEASUREMENTS


bfl
Author(s): Klaas Gadeyne, Wim Meeussen, Tinne Delaet and many others. See web page for a full contributor list. ROS package maintained by Wim Meeussen.
autogenerated on Mon Jun 10 2019 12:47:59