MachineIntelligenceCore:ReinforcementLearning
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator
HistogramFilterMazeLocalization.cpp
Go to the documentation of this file.
1 
24 
25 #include <utils/DataCollector.hpp>
26 
27 namespace mic {
28 namespace application {
29 
34 void RegisterApplication (void) {
36 }
37 
38 
39 HistogramFilterMazeLocalization::HistogramFilterMazeLocalization(std::string node_name_) : OpenGLApplication(node_name_),
40  hidden_maze_number("hidden_maze", 0),
41  hidden_x("hidden_x", 0),
42  hidden_y("hidden_y", 0),
43  action("action", -1),
44  epsilon("epsilon", 0.0),
45  hit_factor("hit_factor", 0.6),
46  miss_factor("miss_factor", 0.2),
47  exact_move_probability("exact_move_probability", 1.0),
48  overshoot_move_probability("overshoot_move_probability", 0.0),
49  undershoot_move_probability("undershoot_move_probability", 0.0),
50  statistics_filename("statistics_filename","statistics_filename.csv")
51 
52  {
53  // Register properties - so their values can be overridden (read from the configuration file).
54  registerProperty(hidden_maze_number);
55  registerProperty(hidden_x);
56  registerProperty(hidden_y);
57  registerProperty(action);
58  registerProperty(epsilon);
59 
60  registerProperty(hit_factor);
61  registerProperty(miss_factor);
62  registerProperty(exact_move_probability);
63  registerProperty(overshoot_move_probability);
64  registerProperty(undershoot_move_probability);
65 
66  registerProperty(statistics_filename);
67 
68  LOG(LINFO) << "Properties registered";
69 }
70 
71 
74  delete(w_current_maze_chart);
75  delete(w_current_coordinate_x);
76  delete(w_current_coordinate_y);
77 }
78 
79 
80 void HistogramFilterMazeLocalization::initialize(int argc, char* argv[]) {
81  // Initialize GLUT! :]
82  VGL_MANAGER->initializeGLUT(argc, argv);
83 
84  // Create the visualization windows - must be created in the same, main thread :]
85  w_current_maze_chart = new WindowCollectorChart<float>("Current_maze", 256, 256, 0, 0);
86  maze_collector_ptr = std::make_shared < mic::utils::DataCollector<std::string, float> >( );
87  w_current_maze_chart->setDataCollectorPtr(maze_collector_ptr);
88 
89  w_current_coordinate_x = new WindowCollectorChart<float>("Current_x", 256, 256, 0, 326);
90  coordinate_x_collector_ptr = std::make_shared < mic::utils::DataCollector<std::string, float> >( );
91  w_current_coordinate_x->setDataCollectorPtr(coordinate_x_collector_ptr);
92 
93  w_current_coordinate_y = new WindowCollectorChart<float>("Current_y", 256, 256, 326, 326);
94  coordinate_y_collector_ptr = std::make_shared < mic::utils::DataCollector<std::string, float> >( );
95  w_current_coordinate_y->setDataCollectorPtr(coordinate_y_collector_ptr);
96 
97  w_max_probabilities_chart = new WindowCollectorChart<float>("Max_probabilities", 256, 256, 326, 0);
98  max_probabilities_collector_ptr = std::make_shared < mic::utils::DataCollector<std::string, float> >( );
99  w_max_probabilities_chart->setDataCollectorPtr(max_probabilities_collector_ptr);
100 
101 }
102 
104 
105  // Import mazes.
106  if ((!importer.importData()) || (importer.size() == 0)){
107  LOG(LERROR) << "The dataset must consists of at least one maze!";
108  exit(0);
109  }//: if
110 
111  // Show mazes.
112  LOG(LNOTICE) << "Loaded mazes";
113  for (size_t m=0; m<importer.size(); m++) {
114  // Display results.
115  LOG(LNOTICE) << "maze(" <<m<<"):\n" << (importer.data()[m]);
116  }//: for
117 
118  hf.setMazes(importer.data(), 10);
119 
121 
122  // Assign initial probabilities to all variables (uniform distribution).
124 
125  // Export probabilities to file (truncate it).
126 
127  mic::utils::DataCollector<std::string, int>::exportMatricesToCsv(statistics_filename, "mazes", importer.data());
128 
129  std::vector<std::string> maze_pose_labels;
130  for (size_t y=0; y < (size_t)importer.data(0)->rows(); y++)
131  for (size_t x=0; x < (size_t)importer.data(0)->cols(); x++) {
132  std::string label = "(" + std::to_string(y) + ";" + std::to_string(x) + ")";
133  maze_pose_labels.push_back(label);
134  }//: for
135  mic::utils::DataCollector<std::string, std::string>::exportVectorToCsv(statistics_filename, "maze pose labels",maze_pose_labels, true);
136 
137 
138  mic::utils::DataCollector<std::string, double>::exportVectorToCsv(statistics_filename, "observation distribution P(o)", hf.maze_patch_probabilities, true);
139  std::vector<int> obs_labels = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
140  mic::utils::DataCollector<std::string, int>::exportVectorToCsv(statistics_filename, "observation labels",obs_labels, true);
141 
142  mic::utils::DataCollector<std::string, double>::exportMatricesToCsv(statistics_filename, "initial P(p)", hf.maze_position_probabilities, true);
143  mic::utils::DataCollector<std::string, double>::exportVectorToCsv(statistics_filename, "initial P(m)", hf.maze_probabilities, true);
144  mic::utils::DataCollector<std::string, double>::exportVectorToCsv(statistics_filename, "initial P(x)", hf.maze_x_coordinate_probilities, true);
145  mic::utils::DataCollector<std::string, double>::exportVectorToCsv(statistics_filename, "initial P(y)", hf.maze_y_coordinate_probilities, true);
146  // Export hidden state
147  mic::utils::DataCollector<std::string, double>::exportValueToCsv(statistics_filename, "hidden_maze_number", hf.hidden_maze_number, true);
148  mic::utils::DataCollector<std::string, double>::exportValueToCsv(statistics_filename, "hidden_x", hf.hidden_x, true);
149  mic::utils::DataCollector<std::string, double>::exportValueToCsv(statistics_filename, "hidden_y", hf.hidden_y, true);
150 
151  // Create data containers - for visualization.
153 
154  // Store the "zero" state.
156 
157  // Get first observation.
159  mic::utils::DataCollector<std::string, short>::exportValueToCsv(statistics_filename, "First observation", hf.obs, true);
160 
161  // Update aggregated probabilities.
163 
164  // Export probabilities to file.
165  mic::utils::DataCollector<std::string, double>::exportMatricesToCsv(statistics_filename, "P(p) after first observation", hf.maze_position_probabilities, true);
166  mic::utils::DataCollector<std::string, double>::exportVectorToCsv(statistics_filename, "P(m) after first observation", hf.maze_probabilities, true);
167  mic::utils::DataCollector<std::string, double>::exportVectorToCsv(statistics_filename, "P(x) after first observation", hf.maze_x_coordinate_probilities, true);
168  mic::utils::DataCollector<std::string, double>::exportVectorToCsv(statistics_filename, "P(y) after first observation", hf.maze_y_coordinate_probilities, true);
169 
170  // Store the first state.
172 
173 }
174 
175 
176 
178  // Random device used for generation of colors.
179  std::random_device rd;
180  std::mt19937_64 rng_mt19937_64(rd());
181  // Initialize uniform index distribution - integers.
182  std::uniform_int_distribution<> color_dist(50, 200);
183  // Create a single container for each maze.
184  for (size_t m=0; m<importer.size(); m++) {
185  std::string label = "P(m" + std::to_string(m) +")";
186  int r= color_dist(rng_mt19937_64);
187  int g= color_dist(rng_mt19937_64);
188  int b= color_dist(rng_mt19937_64);
189  //std::cout << label << " g=" << r<< " g=" << r<< " b=" << b;
190 
191  // Add container to chart.
192  maze_collector_ptr->createContainer(label, mic::types::color_rgba(r, g, b, 180));
193 
194  }//: for
195 
196  // Create a single container for each x coordinate.
197  for (size_t x=0; x<(size_t)importer.maze_width; x++) {
198  std::string label = "P(x" + std::to_string(x) +")";
199  int r= color_dist(rng_mt19937_64);
200  int g= color_dist(rng_mt19937_64);
201  int b= color_dist(rng_mt19937_64);
202 
203  // Add container to chart.
204  coordinate_x_collector_ptr->createContainer(label, mic::types::color_rgba(r, g, b, 180));
205 
206  }//: for
207 
208 
209  // Create a single container for each y coordinate.
210  for (size_t y=0; y<(size_t)importer.maze_height; y++) {
211  std::string label = "P(y" + std::to_string(y) +")";
212  int r= color_dist(rng_mt19937_64);
213  int g= color_dist(rng_mt19937_64);
214  int b= color_dist(rng_mt19937_64);
215 
216  // Add container to chart.
217  coordinate_y_collector_ptr->createContainer(label, mic::types::color_rgba(r, g, b, 180));
218  }//: for
219 
220  // Create containers for three max probabilites.
221  max_probabilities_collector_ptr->createContainer("Max(Pm)", mic::types::color_rgba(255, 0, 0, 180));
222  max_probabilities_collector_ptr->createContainer("Max(Px)", mic::types::color_rgba(0, 255, 0, 180));
223  max_probabilities_collector_ptr->createContainer("Max(Py)", mic::types::color_rgba(0, 0, 255, 180));
224 
225 }
226 
228 
229  double max_pm = 0;
230  double max_px = 0;
231  double max_py = 0;
232 
233  if (synchronize_)
234  { // Enter critical section - with the use of scoped lock from AppState!
235  APP_DATA_SYNCHRONIZATION_SCOPED_LOCK();
236 
237  // Add data to chart windows.
238  for (size_t m=0; m<importer.size(); m++) {
239  std::string label = "P(m" + std::to_string(m) +")";
240  maze_collector_ptr->addDataToContainer(label, hf.maze_probabilities[m]);
241  max_pm = ( hf.maze_probabilities[m] > max_pm ) ? hf.maze_probabilities[m] : max_pm;
242  }//: for
243 
244  for (size_t x=0; x<importer.maze_width; x++) {
245  std::string label = "P(x" + std::to_string(x) +")";
246  coordinate_x_collector_ptr->addDataToContainer(label, hf.maze_x_coordinate_probilities[x]);
247  max_px = ( hf.maze_x_coordinate_probilities[x] > max_px ) ? hf.maze_x_coordinate_probilities[x] : max_px;
248  }//: for
249 
250  for (size_t y=0; y<importer.maze_height; y++) {
251  std::string label = "P(y" + std::to_string(y) +")";
252  coordinate_y_collector_ptr->addDataToContainer(label, hf.maze_y_coordinate_probilities[y]);
253  max_py = ( hf.maze_y_coordinate_probilities[y] > max_py ) ? hf.maze_y_coordinate_probilities[y] : max_py;
254  }//: for
255 
256  max_probabilities_collector_ptr->addDataToContainer("Max(Pm)", max_pm);
257  max_probabilities_collector_ptr->addDataToContainer("Max(Px)", max_px);
258  max_probabilities_collector_ptr->addDataToContainer("Max(Py)", max_py);
259 
260  }//: end of critical section.
261  else {
262  // Add data to chart windows.
263  for (size_t m=0; m<importer.size(); m++) {
264  std::string label = "P(m" + std::to_string(m) +")";
265  maze_collector_ptr->addDataToContainer(label, hf.maze_probabilities[m]);
266  max_pm = ( hf.maze_probabilities[m] > max_pm ) ? hf.maze_probabilities[m] : max_pm;
267  }//: for
268 
269  for (size_t x=0; x<importer.maze_width; x++) {
270  std::string label = "P(x" + std::to_string(x) +")";
271  coordinate_x_collector_ptr->addDataToContainer(label, hf.maze_x_coordinate_probilities[x]);
272  max_px = ( hf.maze_x_coordinate_probilities[x] > max_px ) ? hf.maze_x_coordinate_probilities[x] : max_px;
273  }//: for
274 
275  for (size_t y=0; y<importer.maze_height; y++) {
276  std::string label = "P(y" + std::to_string(y) +")";
277  coordinate_y_collector_ptr->addDataToContainer(label, hf.maze_y_coordinate_probilities[y]);
278  max_py = ( hf.maze_y_coordinate_probilities[y] > max_py ) ? hf.maze_y_coordinate_probilities[y] : max_py;
279  }//: for
280 
281  max_probabilities_collector_ptr->addDataToContainer("Max(Pm)", max_pm);
282  max_probabilities_collector_ptr->addDataToContainer("Max(Px)", max_px);
283  max_probabilities_collector_ptr->addDataToContainer("Max(Py)", max_py);
284  }//: else
285 }
286 
287 
288 
290  LOG(LINFO) << "Performing a single step (" << iteration << ")";
291 
292  short tmp_action = action;
293 
294  // Check epsilon-greedy action selection.
295  if ((double)epsilon > 0) {
296  if (RAN_GEN->uniRandReal() < (double)epsilon)
297  tmp_action = -3;
298  }//: if
299 
300  // Determine action.
301  mic::types::Action2DInterface act;
302  switch(tmp_action){
303  case (short)-3:
304  act = A_RANDOM; break;
305  case (short)-2:
307  case (short)-1:
308  act = hf.mostUniquePatchActionSelection(); break;
309  default:
310  act = mic::types::NESWAction((mic::types::NESW) (short)tmp_action);
311  }//: switch action
312 
313  std:: string label = "Action d_x at " + std::to_string(iteration);
314  mic::utils::DataCollector<std::string, int>::exportValueToCsv(statistics_filename, label, act.dx, true);
315  label = "Action d_y at " + std::to_string(iteration);
316  mic::utils::DataCollector<std::string, int>::exportValueToCsv(statistics_filename, label, act.dy, true);
317 
318  // Perform move.
320 
321  // Get current observation.
323 
324  label = "Observation (after motion) at " + std::to_string(iteration);
325  mic::utils::DataCollector<std::string, short>::exportValueToCsv(statistics_filename, label, hf.obs, true);
326 
327  // Update state.
329 
330  // Export probabilities to file.
331  label = "P(p) at " + std::to_string(iteration);
332  mic::utils::DataCollector<std::string, double>::exportMatricesToCsv(statistics_filename, label, hf.maze_position_probabilities, true);
333  label = "P(m) at " + std::to_string(iteration);
334  mic::utils::DataCollector<std::string, double>::exportVectorToCsv(statistics_filename, label, hf.maze_probabilities, true);
335  label = "P(x) at " + std::to_string(iteration);
336  mic::utils::DataCollector<std::string, double>::exportVectorToCsv(statistics_filename, label, hf.maze_x_coordinate_probilities, true);
337  label = "P(y) at " + std::to_string(iteration);
338  mic::utils::DataCollector<std::string, double>::exportVectorToCsv(statistics_filename, label, hf.maze_y_coordinate_probilities, true);
339 
340  label = "hidden_maze_number at " + std::to_string(iteration);
341  mic::utils::DataCollector<std::string, double>::exportValueToCsv(statistics_filename, label, hf.hidden_maze_number, true);
342  label = "hidden_x at " + std::to_string(iteration);
343  mic::utils::DataCollector<std::string, double>::exportValueToCsv(statistics_filename, label, hf.hidden_x, true);
344  label = "hidden_y at " + std::to_string(iteration);
345  mic::utils::DataCollector<std::string, double>::exportValueToCsv(statistics_filename, label, hf.hidden_y, true);
346 
347 
348 
349  // Export convergence diagram.
350  std::string filename = statistics_filename;
351  std::string tmp = filename.substr(0, (filename.find('.'))) + "-convergence.csv";
352  max_probabilities_collector_ptr->exportDataToCsv(tmp);
353 
354 
355  // Store collected data for visualization/export.
357 
358  return true;
359 }
360 
361 
362 
363 
364 
365 
366 } /* namespace application */
367 } /* namespace mic */
void probabilisticMove(mic::types::Action2DInterface ac_, double exact_move_probability_, double overshoot_move_probability_, double undershoot_move_probability_)
void setHiddenPose(int hidden_maze_number_, int hidden_x_, int hidden_y_)
size_t maze_height
Height of a maze.
HistogramFilterMazeLocalization(std::string node_name_="application")
mic::configuration::Property< double > hit_factor
Property: variable denoting the hit factor (the gain when the observation coincides with current posi...
mic::configuration::Property< short > hidden_maze_number
Property: variable denoting in which maze are we right now (unknown, to be determined).
mic::configuration::Property< std::string > statistics_filename
Property: name of the file to which the statistics will be exported.
mic::utils::DataCollectorPtr< std::string, float > coordinate_y_collector_ptr
WindowCollectorChart< float > * w_current_maze_chart
Window for displaying chart with statistics on current maze number.
mic::configuration::Property< short > hidden_y
Property: variable denoting the y position are we right now (unknown, to be determined).
mic::utils::DataCollectorPtr< std::string, float > coordinate_x_collector_ptr
mic::importers::MazeMatrixImporter importer
Importer responsible for loading mazes from file.
WindowCollectorChart< float > * w_current_coordinate_x
Window for displaying chart with statistics on current x coordinate.
mic::configuration::Property< double > miss_factor
Property: variable denoting the miss factor (the gain when the observation does not coincide with cur...
int hidden_maze_number
shortariable denoting in which maze are we right now (unknown, to be determined). ...
Declaration of a class being a histogram filter based maze localization application.
Class implementing a histogram filter based solution of the maze-of-digits problem.
WindowCollectorChart< float > * w_current_coordinate_y
Window for displaying chart with statistics on current y coordinate.
mic::configuration::Property< double > exact_move_probability
Property: variable storing the probability that we made the exact move (x+dx).
mic::configuration::Property< double > undershoot_move_probability
Property: variable storing the probability that we made the "undershoot" move (d+dx-1).
void sense(double hit_factor_, double miss_factor_)
mic::utils::DataCollectorPtr< std::string, float > maze_collector_ptr
int hidden_x
Variable denoting the x position are we right now (unknown, to be determined).
mic::types::Action2DInterface sumOfMostUniquePatchesActionSelection()
mic::configuration::Property< short > hidden_x
Property: variable denoting the x position are we right now (unknown, to be determined).
mic::utils::DataCollectorPtr< std::string, float > max_probabilities_collector_ptr
Data collector with maximal maze/x/y/ probabilities.
mic::types::Action2DInterface mostUniquePatchActionSelection()
std::vector< double > maze_patch_probabilities
Variable storing the probability that we can find given patch in a given maze.
mic::configuration::Property< double > overshoot_move_probability
Property: variable storing the probability that we made the "overshoot" move (d+dx+1).
std::vector< double > maze_probabilities
Variable storing the probability that we are currently moving in/observing a given maze...
mic::configuration::Property< double > epsilon
Property: variable denoting epsilon in aciton selection (the probability "below" which a random actio...
std::vector< double > maze_y_coordinate_probilities
Variable storing the probability that we are currently in a given y coordinate.
void setMazes(std::vector< mic::types::MatrixXiPtr > &mazes_, unsigned int number_of_distinctive_patches_)
mic::algorithms::MazeHistogramFilter hf
Histogram filter.
int hidden_y
Variable denoting the y position are we right now (unknown, to be determined).
std::vector< double > maze_x_coordinate_probilities
Variable storing the probability that we are currently in a given x coordinate.
void RegisterApplication(void)
Registers application.
WindowCollectorChart< float > * w_max_probabilities_chart
Window for displaying chart with maximal maze/x/y/ probabilities.
mic::configuration::Property< short > action
Property: performed action (0-3: NESW, -3: random, -2: sumOfMostUniquePatchesActionSelection, -1: mostUniquePatchActionSelection).
std::vector< mic::types::MatrixXdPtr > maze_position_probabilities
Variable storing the probability that we are in a given maze position.