00001 #ifndef _OCCUPANCY_GRID_HPP
00002 #define _OCCUPANCY_GRID_HPP
00003
00004 #include <iostream>
00005 #include <iomanip>
00006 #include "properties.hpp"
00007 #include "global.hpp"
00008 #include "grid.hpp"
00009
00010 namespace Arak {
00011
00016 class OccupancyGrid {
00017
00018 protected:
00019
00020
00021 class OccupancyEstimator;
00022 class StateComparator;
00023
00027 typedef Grid<OccupancyEstimator*> EstimatorGrid;
00028
00034 class OccupancyEstimator {
00035
00036 friend class OccupancyGrid;
00037 friend class OccupancyGrid::StateComparator;
00038
00039 protected:
00040
00044 double prior_log_odds;
00045
00050 double log_odds;
00051
00052 public:
00053
00057 OccupancyEstimator(double prior = 0.5) {
00058 this->log_odds = this->prior_log_odds = log(prior / (1 - prior));
00059 }
00060
00067 void condition(double posterior) {
00068 double obs_log_odds = log(posterior / (1.0 - posterior));
00069 log_odds += obs_log_odds - prior_log_odds;
00070 }
00071
00075 double estimate() const {
00076 return 1.0 - (1.0 / (1.0 + exp(log_odds)));
00077 }
00078
00079 };
00080
00084 EstimatorGrid* grid;
00085
00086 public:
00087
00093 OccupancyGrid(const Util::PropertyMap& props);
00094
00098 ~OccupancyGrid();
00099
00116 void laser(const Geometry::Point& source,
00117 const Geometry::Point& impact,
00118 double maxRange,
00119 double obstacleWidth,
00120 double p_given_obs,
00121 double p_given_free);
00122
00140 void laser_scan(const Geometry::Point& source,
00141 const std::vector<Geometry::Point>& impacts,
00142 double maxRange,
00143 double obstacleWidth,
00144 double p_given_obs,
00145 double p_given_free);
00162 void sonar(const Geometry::Point& source,
00163 double angle,
00164 double range,
00165 double maxRange,
00166 double obstacleWidth,
00167 double width,
00168 double p_given_obs,
00169 double p_given_free);
00170
00182 template<typename charT, typename traits>
00183 void write(std::basic_ostream<charT,traits>& out) const {
00184
00185
00186 out << 0 << std::endl;
00187
00188 out << grid->numRows() << " " << grid->numCols() << std::endl;
00189
00190 out << grid->boundary() << std::endl;
00191
00192 out << std::scientific << std::setw(16) << std::setprecision(12);
00193 for (int i = grid->numRows() - 1; i >= 0; i--) {
00194 for (int j = 0; j < grid->numCols(); j++) {
00195 const EstimatorGrid::Cell& cell = grid->getCell(i, j);
00196 const OccupancyEstimator* est = *(cell.getItemList().begin());
00197 out << est->estimate() << " ";
00198 }
00199 out << std::endl;
00200 }
00201 }
00202
00208 template<typename charT, typename traits>
00209 OccupancyGrid(std::basic_istream<charT,traits>& in) {
00210 in >> skipcomments;
00211 int unused, num_rows, num_cols;
00212 in >> unused >> num_rows >> num_cols;
00213 double xmin, ymin, xmax, ymax, prob;
00214 in >> xmin >> ymin >> xmax >> ymax;
00215 Geometry::Rectangle r(xmin, ymin, xmax, ymax);
00216 grid = new EstimatorGrid(r, num_rows, num_cols);
00217 for (int i = num_rows - 1; i >= 0; i--)
00218 for (int j = 0; j < num_cols; j++) {
00219 EstimatorGrid::Cell& cell = grid->getCell(i, j);
00220 OccupancyEstimator* est = new OccupancyEstimator();
00221 in >> prob;
00222 est->prior_log_odds = 0.0;
00223 est->log_odds = log(prob / (1.0 - prob));
00224 cell.add(est);
00225 }
00226 assert(in.good());
00227 }
00228
00229 };
00230
00231 }
00232
00233 #endif