Bayes Filters Library
The first particle filter: the Sequential Importance Sampling PF

The following snippet code shows how to run a Sequential Importance Sampling (SIS) particle filter using the implementation provided by the library.

1 /*
2  * Copyright (C) 2016-2019 Istituto Italiano di Tecnologia (IIT)
3  *
4  * This software may be modified and distributed under the terms of the
5  * BSD 3-Clause license. See the accompanying LICENSE file for details.
6  */
7 
8 #include <iostream>
9 #include <memory>
10 #include <string>
11 
20 #include <BayesFilters/SIS.h>
22 #include <BayesFilters/utils.h>
23 #include <Eigen/Dense>
24 
25 using namespace bfl;
26 using namespace Eigen;
27 
28 
29 class SISSimulation : public SIS
30 {
31 public:
32  SISSimulation
33  (
34  unsigned int num_particle,
35  std::size_t state_size,
36  unsigned int simulation_steps,
37  std::unique_ptr<ParticleSetInitialization> initialization,
38  std::unique_ptr<PFPrediction> prediction,
39  std::unique_ptr<PFCorrection> correction,
40  std::unique_ptr<Resampling> resampling
41  ) noexcept :
42  SIS(num_particle, state_size, std::move(initialization), std::move(prediction), std::move(correction), std::move(resampling)),
43  simulation_steps_(simulation_steps),
44  estimates_extraction_(state_size)
45  { }
46 
47 protected:
48  bool run_condition() override
49  {
50  if (step_number() < simulation_steps_)
51  return true;
52  else
53  return false;
54  }
55 
56  std::vector<std::string> log_file_names(const std::string& folder_path, const std::string& file_name_prefix) override
57  {
58  std::vector<std::string> sis_filenames = SIS::log_file_names(folder_path, file_name_prefix);
59 
60  /* Add file names for logging of the conditional expected value. */
61  sis_filenames.push_back(folder_path + "/" + file_name_prefix + "_mean");
62 
63  return sis_filenames;
64  }
65 
66  bool initialization_step() override
67  {
68  estimates_extraction_.setMethod(EstimatesExtraction::ExtractionMethod::mean);
69 
71  return false;
72 
73  return true;
74  }
75 
76  void log() override
77  {
78  VectorXd mean;
79  std::tie(std::ignore, mean) = estimates_extraction_.extract(cor_particle_.state(), cor_particle_.weight());
80 
81  logger(pred_particle_.state().transpose(), pred_particle_.weight().transpose(),
82  cor_particle_.state().transpose(), cor_particle_.weight().transpose(),
83  mean.transpose());
84  }
85 
86 private:
87  unsigned int simulation_steps_;
88 
89  EstimatesExtraction estimates_extraction_;
90 };
91 
92 
93 int main(int argc, char* argv[])
94 {
95  std::cout << "Running a SIS particle filter on a simulated target." << std::endl;
96 
97  const bool write_to_file = (argc > 1 ? std::string(argv[1]) == "ON" : false);
98  if (write_to_file)
99  std::cout << "Data is logged in the test folder with prefix testSIS." << std::endl;
100 
101 
102  /* A set of parameters needed to run a SIS particle filter in a simulated environment. */
103  double surv_x = 1000.0;
104  double surv_y = 1000.0;
105  unsigned int num_particle_x = 30;
106  unsigned int num_particle_y = 30;
107  unsigned int num_particle = num_particle_x * num_particle_y;
108  Vector4d initial_state(10.0f, 0.0f, 10.0f, 0.0f);
109  unsigned int simulation_time = 100;
110  std::size_t state_size = 4;
111 
112  /* Step 1 - Initialization */
113  /* Initialize initialization class. */
114  std::unique_ptr<ParticleSetInitialization> grid_initialization = utils::make_unique<InitSurveillanceAreaGrid>(surv_x, surv_y, num_particle_x, num_particle_y);
115 
116 
117  /* Step 2 - Prediction */
118  /* Step 2.1 - Define the state model */
119  /* Initialize a white noise acceleration state model. */
120  double T = 1.0f;
121  double tilde_q = 10.0f;
122 
123  std::unique_ptr<LinearStateModel> wna = utils::make_unique<WhiteNoiseAcceleration>(WhiteNoiseAcceleration::Dim::TwoD, T, tilde_q);
124 
125  /* Step 2.2 - Define the prediction step */
126  /* Initialize the particle filter prediction step and pass the ownership of the state model. */
127  std::unique_ptr<PFPrediction> pf_prediction = utils::make_unique<DrawParticles>(std::move(wna));
128 
129 
130  /* Step 3 - Correction */
131  /* Step 3.1 - Define where the measurement are originated from (either simulated or from a real process) */
132  /* Initialize simulaterd target model with a white noise acceleration. */
133  std::unique_ptr<StateModel> target_model = utils::make_unique<WhiteNoiseAcceleration>(WhiteNoiseAcceleration::Dim::TwoD, T, tilde_q);
134  std::unique_ptr<SimulatedStateModel> simulated_state_model = utils::make_unique<SimulatedStateModel>(std::move(target_model), initial_state, simulation_time);
135 
136  if (write_to_file)
137  simulated_state_model->enable_log("./", "testSIS");
138 
139  /* Initialize a measurement model (a linear sensor reading x and y coordinates). */
140  double sigma_x = 10.0;
141  double sigma_y = 10.0;
142  Eigen::MatrixXd R(2, 2);
143  R << std::pow(sigma_x, 2.0), 0.0,
144  0.0, std::pow(sigma_y, 2.0);
145 
146  std::unique_ptr<MeasurementModel> simulated_linear_sensor = utils::make_unique<SimulatedLinearSensor>(std::move(simulated_state_model), SimulatedLinearSensor::LinearMatrixComponent{ 4, std::vector<std::size_t>{ 0, 2 } }, R);
147 
148  if (write_to_file)
149  simulated_linear_sensor->enable_log("./", "testSIS");
150 
151 
152  /* Step 3.3 - Define the likelihood model */
153  /* Initialize the the exponential likelihood, a PFCorrection decoration of the particle filter correction step. */
154  std::unique_ptr<LikelihoodModel> exp_likelihood = utils::make_unique<GaussianLikelihood>();
155 
156  /* Step 3.4 - Define the correction step */
157  /* Initialize the particle filter correction step and pass the ownership of the measurement model. */
158  std::unique_ptr<PFCorrection> pf_correction = utils::make_unique<BootstrapCorrection>(std::move(simulated_linear_sensor), std::move(exp_likelihood));
159 
160 
161  /* Step 4 - Resampling */
162  /* Initialize a resampling algorithm */
163  std::unique_ptr<Resampling> resampling = utils::make_unique<Resampling>();
164 
165 
166  /* Step 5 - Assemble the particle filter */
167  std::cout << "Constructing SIS particle filter..." << std::flush;
168  SISSimulation sis_pf(num_particle, state_size, simulation_time, std::move(grid_initialization), std::move(pf_prediction), std::move(pf_correction), std::move(resampling));
169 
170  if (write_to_file)
171  sis_pf.enable_log("./", "testSIS");
172 
173  std::cout << "done!" << std::endl;
174 
175 
176  /* Step 6 - Prepare the filter to be run */
177  std::cout << "Booting SIS particle filter..." << std::flush;
178  sis_pf.boot();
179  std::cout << "completed!" << std::endl;
180 
181 
182  /* Step 7 - Run the filter and wait until it is closed */
183  /* Note that since this is a simulation, the filter will end upon simulation termination */
184  std::cout << "Running SIS particle filter..." << std::flush;
185  sis_pf.run();
186  std::cout << "waiting..." << std::flush;
187  if (!sis_pf.wait())
188  return EXIT_FAILURE;
189  std::cout << "completed!" << std::endl;
190 
191 
192  return EXIT_SUCCESS;
193 }
bfl::LinearModel::LinearMatrixComponent
std::pair< std::size_t, std::vector< std::size_t > > LinearMatrixComponent
Pair of data representing.
Definition: LinearModel.h:37
GaussianLikelihood.h
EstimatesExtraction.h
bfl::SIS
Definition: SIS.h:25
SimulatedLinearSensor.h
bfl
Port of boost::any for C++11 compilers.
Definition: AdditiveMeasurementModel.h:13
Resampling.h
bfl::WhiteNoiseAcceleration::Dim::TwoD
@ TwoD
bfl::SIS::initialization_step
bool initialization_step() override
Definition: SIS.cpp:52
bfl::SIS::log_file_names
std::vector< std::string > log_file_names(const std::string &folder_path, const std::string &file_name_prefix) override
Definition: SIS.cpp:93
InitSurveillanceAreaGrid.h
SIS.h
utils.h
bfl::EstimatesExtraction::ExtractionMethod::mean
@ mean
SimulatedStateModel.h
WhiteNoiseAcceleration.h
BootstrapCorrection.h
DrawParticles.h
bfl::EstimatesExtraction
Definition: EstimatesExtraction.h:23