bayes_update.cpp
Go to the documentation of this file.
1 
6 #include "filters.hpp"
7 #include <iostream>
8 
11 #include <chrono>
12 
13 namespace mitre_fast_layered_map
14 {
15 
17 {
18 }
19 
21 {
22 }
23 
25 {
26  // Required Parameters
27  if (!BayesUpdate::getParam(std::string("probability_layer"), probabilityLayerStr_))
28  {
29  ROS_ERROR("Bayes update did not find parameter probability layer.");
30  return false;
31  }
32 
33  if (!BayesUpdate::getParam(std::string("history_layer_prefix"), historyLayerPrefix_))
34  {
35  ROS_ERROR("Bayes update did not find parameter history_layer_prefix.");
36  return false;
37  }
38 
39  if (!BayesUpdate::getParam(std::string("history_count"), historyCount_))
40  {
41  ROS_ERROR("Bayes update did not find parameter history_count.");
42  return false;
43  }
44 
45  // Advanced features (optional)
46 
47  // Below are all sensor model parameters for how likely it is for your sensors are to
48  // register TP, FP, TN, FN's. We allow a "dynamic" setting for TP and FP based on number
49  // of points received.
50 
51  if (!BayesUpdate::getParam(std::string("starting_prob"), startingProb_))
52  {
53  ROS_DEBUG("Starting prob not set. Using default %f", startingProb_);
54  }
55 
56 
57  if (!BayesUpdate::getParam(std::string("prob_sense_emp_given_occ"), probSenseEmpGivenOcc_))
58  {
59  ROS_DEBUG("Prob sense emp given occ not set. Using default %f", probSenseEmpGivenOcc_);
60  }
61 
62  if (!BayesUpdate::getParam(std::string("prob_sense_emp_given_emp"), probSenseEmpGivenEmp_))
63  {
64  ROS_DEBUG("Prob sense emp given emp not set. Using default %f", probSenseEmpGivenEmp_);
65  }
66 
67  // We model our sensor as a RELU function, so these give the initial offset and linear rate of growth/decay
68  if (!BayesUpdate::getParam(std::string("prob_sense_occ_given_occ_rate"), probSenseOccGivenOccRate_))
69  {
70  ROS_DEBUG("Prob sense occ given occ rate not set. Using default %f", probSenseOccGivenOccRate_);
71  }
72 
73  if (!BayesUpdate::getParam(std::string("prob_sense_occ_given_occ_offset"), probSenseOccGivenOccOffset_))
74  {
75  ROS_DEBUG("Prob sense occ given occ offset not set. Using default %f", probSenseOccGivenOccOffset_);
76  }
77 
78  if (!BayesUpdate::getParam(std::string("prob_sense_occ_given_emp_rate"), probSenseOccGivenEmpRate_))
79  {
80  ROS_DEBUG("Prob sense occ given emp rate not set. Using default %f", probSenseOccGivenEmpRate_);
81  }
82 
83  if (!BayesUpdate::getParam(std::string("prob_sense_occ_given_emp_offset"), probSenseOccGivenEmpOffset_))
84  {
85  ROS_DEBUG("Prob sense occ given emp offset not set. Using default %f", probSenseOccGivenEmpOffset_);
86  }
87 
88  ROS_INFO("Bayes filter configured with parameters: Probability Layer = %s", probabilityLayerStr_.c_str());
89 
90  return true;
91 }
92 
99 {
100  if (!_mapIn.exists(probabilityLayerStr_))
101  {
102  ROS_ERROR("Layer %s does not exist in this map.", probabilityLayerStr_.c_str());
103  return false;
104  }
105 
106  _mapOut = _mapIn;
107  grid_map::Matrix& probabilityLayer = _mapOut[probabilityLayerStr_];
108 
109  // Add history layers and make sure they exist
110  std::vector<std::shared_ptr<grid_map::Matrix>> historyLayers;
111  for(int i = 0; i < historyCount_; i++)
112  {
113  std::string layer = historyLayerPrefix_ + std::to_string(i);
114  if (!_mapIn.exists(historyLayerPrefix_ + std::to_string(i)))
115  {
116  ROS_ERROR("Layer %s expected but not found in map", (historyLayerPrefix_ + std::to_string(i)).c_str());
117  return false;
118  }
119 
120  // If it exists add to vector of history layers
121  historyLayers.push_back(std::make_shared<grid_map::Matrix>(_mapOut[layer]));
122  }
123 
124  // Temp variables for ease
125  double probGivenOccToUse, probGivenEmpToUse, beliefOcc, beliefEmp, normalizer;
126  int numFramesInScope;
127  /*
128  * Below we run a bayes filter to determine our confidence in an obstacle
129  * being present in a given cell based on the last 10 readings. We specify
130  * the most recent readings so that the map can cells can update quickly.
131  */
132  for(grid_map::GridMapIterator it(_mapOut); !it.isPastEnd(); ++it)
133  {
134  const grid_map::Index index(*it);
135 
136  double currentProb = startingProb_;
137 
138  // Construct history of probability readings
139  std::vector<int> hitsHistory;
140 
141  // We may evaluate in a different order from which things were recorded,
142  // but order shouldn't matter
143  for (int i = 0; i < historyLayers.size(); i++)
144  {
145  grid_map::Matrix& history = *(historyLayers[i].get());
146  // Negative values represent no readings ever placed in layer
147  // Likely when cell has just come into scope
148  if (history(index(0), index(1)) >= 0)
149  {
150  hitsHistory.push_back(history(index(0), index(1)));
151  }
152  }
153 
154  // Update the probability for each reading currently stored in history
155  for (int i = 0; i < hitsHistory.size(); i++)
156  {
157  // Sense nothing in cell this iteration
158  if (hitsHistory[i] == 0)
159  {
160  probGivenOccToUse = probSenseEmpGivenOcc_;
161  probGivenEmpToUse = probSenseEmpGivenEmp_;
162  }
163  else // Received positive readings
164  {
165  probGivenOccToUse = dynamicSenseOccGivenOcc(hitsHistory[i]);
166  probGivenEmpToUse = dynamicSenseOccGivenEmp(hitsHistory[i]);
167  }
168 
169  // Apply bayes to determine probability of readings
170  beliefOcc = probGivenOccToUse * currentProb;
171  beliefEmp = probGivenEmpToUse * (1 - currentProb);
172  normalizer = 1 / (beliefOcc + beliefEmp);
173 
174  currentProb = beliefOcc * normalizer;
175  }
176 
177  probabilityLayer(index(0), index(1)) = currentProb;
178 
179  }
180 
181  return true;
182 }
183 
184 
195 {
196  return std::min(0.99, (numHits * probSenseOccGivenOccRate_) + probSenseOccGivenOccOffset_);
197 }
198 
205 {
206  return std::max(0.01, (numHits * probSenseOccGivenEmpRate_) + probSenseOccGivenEmpOffset_);
207 }
208 
209 } // namespace mitre_fast_layered_map
210 
211 
Eigen::Array2i Index
PLUGINLIB_EXPORT_CLASS(mitre_fast_layered_map::BayesUpdate, filters::FilterBase< grid_map::GridMap >)
Eigen::MatrixXf Matrix
double dynamicSenseOccGivenEmp(int numHits)
virtual bool update(const grid_map::GridMap &_mapIn, grid_map::GridMap &_mapOut)
std::string historyLayerPrefix_
Prefix for historys layers. Should follow prefix + (int) i standard.
Definition: filters.hpp:123
bool getParam(const std::string &name, std::string &value)
bool exists(const std::string &layer) const
double dynamicSenseOccGivenOcc(int numHits)
#define ROS_INFO(...)
std::string probabilityLayerStr_
Layer that holds accumulated probability until now.
Definition: filters.hpp:122
int historyCount_
Num history layers use.
Definition: filters.hpp:124
Filters that operate on a grid map instance.
#define ROS_ERROR(...)
#define ROS_DEBUG(...)


mitre_fast_layered_map
Author(s):
autogenerated on Thu Mar 11 2021 03:06:49