00001
00002
00003 #ifndef GEOM_3D_OCCUPANCY_GRID_HPP
00004 #define GEOM_3D_OCCUPANCY_GRID_HPP
00005
00006 #include <cmath>
00007 #include <ostream>
00008 #include <vector>
00009 #include <map>
00010
00011 #include "boost/numeric/ublas/vector.hpp"
00012 #include "boost/numeric/ublas/io.hpp"
00013
00014 #include "jafarConfig.h"
00015
00016 #include "jmath/jblas.hpp"
00017
00018 #include "geom/t3d.hpp"
00019
00020 #ifdef HAVE_OPENGL
00021 #ifdef __APPLE__
00022 #include </System/Library/Frameworks/OpenGL.framework/Versions/A/Headers/gl.h>
00023 #else
00024 #include <GL/gl.h>
00025 #endif
00026 #endif // HAVE_OPENGL
00027
00028 namespace jafar {
00029 namespace geom {
00030
00031 class DenseOG;
00032
00037 typedef boost::numeric::ublas::bounded_vector<double,3> VoxelCoord;
00038 typedef boost::numeric::ublas::bounded_vector<int,3> VoxelIndex;
00039
00040 class VoxelIndexLess {
00041 public:
00042 inline bool operator()(VoxelIndex const& v1, VoxelIndex const& v2) const
00043 {
00044 if (v1(0) != v2(0))
00045 return v1(0) < v2(0);
00046 else if (v1(1) != v2(1))
00047 return v1(1) < v2(1);
00048 else
00049 return v1(2) < v2(2);
00050 }
00051 };
00052
00056 template<typename T>
00057 struct Box {
00058
00059 Box() : x(), size() {
00060 x.clear();
00061 size.clear();
00062 }
00063
00064 Box(Box const& box) :
00065 x(box.x), size(box.size) {}
00066
00067 boost::numeric::ublas::bounded_vector<T,3> x;
00068 boost::numeric::ublas::bounded_vector<T,3> size;
00069
00070 bool isEmpty() {
00071 return size(0) == 0 || size(1) == 0 || size(2) == 0;
00072 }
00073
00074 Box<T> intersect(Box<T> const& box) const {
00075 Box<T> inter;
00076 for (std::size_t i=0 ; i < 3 ; ++i) {
00077 inter.x(i) = std::max(box.x(i), x(i));
00078 inter.size(i) = std::min(box.x(i)+box.size(i), x(i)+size(i)) - inter.x(i);
00079 if (inter.size(i) <= 0)
00080 return Box<T>();
00081 }
00082 return inter;
00083 }
00084
00085 };
00086
00087 template<typename T>
00088 std::ostream& operator <<(std::ostream& s, Box<T> const& b) {
00089 s << "{" << b.x << " ; " << b.size << "}";
00090 return s;
00091 }
00092
00093 Box<int> metricToIndex(Box<double> const& bd, double sizeVoxel);
00094 VoxelIndex metricToIndex(VoxelCoord const& vid, double sizeVoxel);
00095 VoxelCoord indexToMetric(VoxelIndex const& vii, double sizeVoxel);
00096
00097 double pToLogOddsRatio(double p) {
00098 return log(p/(1.0-p));
00099 }
00100
00101 double logOddsRatioToP(double l) {
00102 return 1.0 - 1.0/(1.0+exp(l));
00103 }
00104
00105 VoxelIndex computeVoxelIndex(std::size_t flatIndex, Box<int> const& box);
00106
00110 class OGSensorModel {
00111
00112 public:
00113
00114 OGSensorModel();
00115 virtual ~OGSensorModel();
00116
00117 void setRefToSensor(jafar::geom::T3D const& refToSensor);
00118
00119 virtual void setupUpdate(DenseOG const& og) = 0;
00120
00121 Box<double> visibilityBox() const;
00122
00130 double inverseObservation(VoxelCoord const& voxel) const;
00131
00132 protected:
00133
00134 virtual Box<double> visibilityBoxInSensorFrame() const = 0;
00135 virtual double inverseObservationInSensorFrame(VoxelCoord const& voxel) const = 0;
00136
00137 private:
00138
00139 T3D* m_sensorToRef;
00140
00141 };
00142
00146 class DenseOG {
00147
00148 public:
00149
00150 typedef std::vector<double> OGType;
00151
00152 DenseOG(Box<double> const& box, double sizeVoxel, double emptyVoxelTh = 0.2, double fullVoxelTh = 0.8);
00153 DenseOG(Box<int> const& dox, double sizeVoxel, double emptyVoxelTh = 0.2, double fullVoxelTh = 0.8);
00154
00155 double sizeVoxel() const {return m_sizeVoxel;}
00156 Box<int> const& box() const {return m_box;}
00157 OGType const& og() const {return m_og;}
00158 double& get(VoxelCoord const& vi);
00159 double& get(VoxelIndex const& vi);
00160
00161 void randomize(unsigned int s = 1);
00162
00163 void update(OGSensorModel& model);
00164
00165 private:
00166
00167 double m_sizeVoxel;
00168 Box<int> m_box;
00169 OGType m_og;
00170
00174 double m_emptyVoxelLogTh;
00175
00179 double m_fullVoxelLogTh;
00180
00181 inline std::size_t computeFlatIndex(VoxelIndex const& vi)
00182 {
00183 return (size_t)(vi(0) - m_box.x(0))*m_box.size(1)*m_box.size(2) +
00184 (size_t)(vi(1) - m_box.x(1))*m_box.size(2) +
00185 (size_t)(vi(2) - m_box.x(2));
00186
00187 }
00188
00189 #ifdef HAVE_OPENGL
00190 public:
00191 void glInit();
00192 void glDraw();
00193 private:
00194 GLuint glOGList;
00195 #endif // HAVE_OPENGL
00196
00197 };
00198
00202 class SparseOG {
00203
00204 public:
00205
00206 typedef std::map<VoxelIndex,double,jafar::geom::VoxelIndexLess> OGType;
00207
00208 SparseOG(DenseOG const& denseOG, double threshold);
00209
00210 double sizeVoxel() const {return m_sizeVoxel;}
00211 Box<int> const& box() const {return m_box;}
00212 OGType const& og() const {return m_og;}
00213
00214
00215
00216 private:
00217
00218 double m_sizeVoxel;
00219 Box<int> m_box;
00220 OGType m_og;
00221
00222 #ifdef HAVE_OPENGL
00223 public:
00224 void glInit();
00225 void glDraw();
00226 private:
00227 GLuint glOGList;
00228 #endif // HAVE_OPENGL
00229
00230 };
00231
00232
00233
00234 }
00235 }
00236
00237 #endif // GEOM_3D_OCCUPANCY_GRID_HPP