Main MRPT website > C++ reference
MRPT logo
CAngularObservationMesh.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2014, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 #ifndef opengl_CAngularObservationMesh_H
10 #define opengl_CAngularObservationMesh_H
11 
15 #include <mrpt/math/CMatrixB.h>
17 #include <mrpt/slam/CPointsMap.h>
19 
20 #include <mrpt/math/geometry.h>
21 
22 namespace mrpt {
23 namespace opengl {
24  using namespace mrpt::utils;
25  using namespace mrpt::slam;
26  using namespace mrpt::poses;
27 
29 
30  /**
31  * A mesh built from a set of 2D laser scan observations.
32  * Each element of this set is a single scan through the yaw, given a specific pitch.
33  * Each scan has a CPose3D identifying the origin of the scan, which ideally is the
34  * same for every one of them.
35  *
36  * <div align="center">
37  * <table border="0" cellspan="4" cellspacing="4" style="border-width: 1px; border-style: solid;">
38  * <tr> <td> mrpt::opengl::CAngularObservationMesh </td> <td> \image html preview_CAngularObservationMesh.png </td> </tr>
39  * </table>
40  * </div>
41  *
42  * \ingroup mrpt_maps_grp
43  */
46  public:
47  /**
48  * Range specification type, with several uses.
49  */
51  private:
52  /**
53  * Range type.
54  * If 0, it's specified by an initial and a final value, and an increment.
55  * If 1, it's specified by an initial and a final value, and a fixed size of samples.
56  * If 2, it's specified by an aperture, a fixed size of samples and a boolean variable controlling direction. This type is always zero-centered.
57  */
58  char rangeType;
59  /**
60  * Union type with the actual data.
61  * \sa rangeType
62  */
63  union rd {
64  struct {
65  double initial;
66  double final;
67  double increment;
68  } mode0;
69  struct {
70  double initial;
71  double final;
72  size_t amount;
73  } mode1;
74  struct {
75  double aperture;
76  size_t amount;
77  bool negToPos;
78  } mode2;
79  } rangeData;
80  /**
81  * Constructor from initial value, final value and range.
82  */
83  TDoubleRange(double a,double b,double c):rangeType(0) {
84  rangeData.mode0.initial=a;
85  rangeData.mode0.final=b;
86  rangeData.mode0.increment=c;
87  }
88  /**
89  * Constructor from initial value, final value and amount of samples.
90  */
91  TDoubleRange(double a,double b,size_t c):rangeType(1) {
92  rangeData.mode1.initial=a;
93  rangeData.mode1.final=b;
94  rangeData.mode1.amount=c;
95  }
96  /**
97  * Constructor from aperture, amount of samples and scan direction.
98  */
99  TDoubleRange(double a,size_t b,bool c):rangeType(2) {
100  rangeData.mode2.aperture=a;
101  rangeData.mode2.amount=b;
102  rangeData.mode2.negToPos=c;
103  }
104  public:
105  /**
106  * Creates a range of values from the initial value, the final value and the increment.
107  * \throw std::logic_error if the increment is zero.
108  */
109  inline static TDoubleRange CreateFromIncrement(double initial,double final,double increment) {
110  if (increment==0) throw std::logic_error("Invalid increment value.");
111  return TDoubleRange(initial,final,increment);
112  }
113  /**
114  * Creates a range of values from the initial value, the final value and a desired amount of samples.
115  */
116  inline static TDoubleRange CreateFromAmount(double initial,double final,size_t amount) {
117  return TDoubleRange(initial,final,amount);
118  }
119  /**
120  * Creates a zero-centered range of values from an aperture, an amount of samples and a direction.
121  */
122  inline static TDoubleRange CreateFromAperture(double aperture,size_t amount,bool negToPos=true) {
123  return TDoubleRange(aperture,amount,negToPos);
124  }
125  /**
126  * Returns the total aperture of the range.
127  * \throw std::logic_error on invalid range type.
128  */
129  inline double aperture() const {
130  switch (rangeType) {
131  case 0:return (sign(rangeData.mode0.increment)==sign(rangeData.mode0.final-rangeData.mode0.initial))?fabs(rangeData.mode0.final-rangeData.mode0.initial):0;
132  case 1:return rangeData.mode1.final-rangeData.mode1.initial;
133  case 2:return rangeData.mode2.aperture;
134  default:throw std::logic_error("Unknown range type.");
135  }
136  }
137  /**
138  * Returns the first value of the range.
139  * \throw std::logic_error on invalid range type.
140  */
141  inline double initialValue() const {
142  switch (rangeType) {
143  case 0:
144  case 1:return rangeData.mode0.initial;
145  case 2:return rangeData.mode2.negToPos?-rangeData.mode2.aperture/2:rangeData.mode2.aperture/2;
146  default:throw std::logic_error("Unknown range type.");
147  }
148  }
149  /**
150  * Returns the last value of the range.
151  * \throw std::logic_error on invalid range type.
152  */
153  inline double finalValue() const {
154  switch (rangeType) {
155  case 0:return (sign(rangeData.mode0.increment)==sign(rangeData.mode0.final-rangeData.mode0.initial))?rangeData.mode0.final:rangeData.mode0.initial;
156  case 1:return rangeData.mode1.final;
157  case 2:return rangeData.mode2.negToPos?rangeData.mode2.aperture/2:-rangeData.mode2.aperture/2;
158  default:throw std::logic_error("Unknown range type.");
159  }
160  }
161  /**
162  * Returns the increment between two consecutive values of the range.
163  * \throw std::logic_error on invalid range type.
164  */
165  inline double increment() const {
166  switch (rangeType) {
167  case 0:return rangeData.mode0.increment;
168  case 1:return (rangeData.mode1.final-rangeData.mode1.initial)/static_cast<double>(rangeData.mode1.amount-1);
169  case 2:return rangeData.mode2.negToPos?rangeData.mode2.aperture/static_cast<double>(rangeData.mode2.amount-1):-rangeData.mode2.aperture/static_cast<double>(rangeData.mode2.amount-1);
170  default:throw std::logic_error("Unknown range type.");
171  }
172  }
173  /**
174  * Returns the total amount of values in this range.
175  * \throw std::logic_error on invalid range type.
176  */
177  inline size_t amount() const {
178  switch (rangeType) {
179  case 0:return (sign(rangeData.mode0.increment)==sign(rangeData.mode0.final-rangeData.mode0.initial))?1+static_cast<size_t>(ceil((rangeData.mode0.final-rangeData.mode0.initial)/rangeData.mode0.increment)):1;
180  case 1:return rangeData.mode1.amount;
181  case 2:return rangeData.mode2.amount;
182  default:throw std::logic_error("Unknown range type.");
183  }
184  }
185  /**
186  * Gets a vector with every value in the range.
187  * \throw std::logic_error on invalid range type.
188  */
189  void values(std::vector<double> &vals) const;
190  /**
191  * Returns the direction of the scan. True if the increment is positive, false otherwise.
192  * \throw std::logic_error on invalid range type.
193  */
194  inline bool negToPos() const {
195  switch (rangeType) {
196  case 0:return sign(rangeData.mode0.increment)>0;
197  case 1:return sign(rangeData.mode1.final-rangeData.mode1.initial)>0;
198  case 2:return rangeData.mode2.negToPos;
199  default:throw std::logic_error("Unknown range type.");
200  }
201  }
202  };
203 
204  void getBoundingBox(mrpt::math::TPoint3D &bb_min, mrpt::math::TPoint3D &bb_max) const;
205 
206  protected:
207  /**
208  * Updates the mesh, if needed. It's a const method, but modifies mutable content.
209  */
210  void updateMesh() const;
211  /**
212  * Empty destructor.
213  */
215  /**
216  * Actual set of triangles to be displayed.
217  */
218  mutable std::vector<CSetOfTriangles::TTriangle> triangles;
219  /**
220  * Internal method to add a triangle to the mutable mesh.
221  */
222  void addTriangle(const TPoint3D &p1,const TPoint3D &p2,const TPoint3D &p3) const;
223  /**
224  * Whether the mesh will be displayed wireframe or solid.
225  */
227  /**
228  * Mutable variable which controls if the object has suffered any change since last time the mesh was updated.
229  */
230  mutable bool meshUpToDate;
231  /**
232  * Whether the object may present transparencies or not.
233  */
235  /**
236  * Mutable object with the mesh's points.
237  */
239  /**
240  * Scan validity matrix.
241  */
243  /**
244  * Observation pitch range. When containing exactly two elements, they represent the bounds.
245  */
246  std::vector<double> pitchBounds;
247  /**
248  * Actual scan set which is used to generate the mesh.
249  */
250  std::vector<CObservation2DRangeScan> scanSet;
251  /**
252  * Basic constructor.
253  */
254  CAngularObservationMesh():mWireframe(true),meshUpToDate(false),mEnableTransparency(true),actualMesh(0,0),validityMatrix(0,0),pitchBounds(),scanSet() {}
255  public:
256  /**
257  * Returns whether the object is configured as wireframe or solid.
258  */
259  inline bool isWireframe() const {
260  return mWireframe;
261  }
262  /**
263  * Sets the display mode for the object. True=wireframe, False=solid.
264  */
265  inline void setWireframe(bool enabled=true) {
266  mWireframe=enabled;
268  }
269  /**
270  * Returns whether the object may be transparent or not.
271  */
272  inline bool isTransparencyEnabled() const {
273  return mEnableTransparency;
274  }
275  /**
276  * Enables or disables transparencies.
277  */
278  inline void enableTransparency(bool enabled=true) {
279  mEnableTransparency=enabled;
281  }
282  /**
283  * Renderizes the object.
284  * \sa mrpt::opengl::CRenderizable
285  */
286  virtual void render_dl() const;
287  /**
288  * Traces a ray to the object, returning the distance to a given pose through its X axis.
289  * \sa mrpt::opengl::CRenderizable,trace2DSetOfRays,trace1DSetOfRays
290  */
291  virtual bool traceRay(const mrpt::poses::CPose3D &o,double &dist) const;
292  /**
293  * Sets the pitch bounds for this range.
294  */
295  void setPitchBounds(const double initial,const double final);
296  /**
297  * Sets the pitch bounds for this range.
298  */
299  void setPitchBounds(const std::vector<double> bounds);
300  /**
301  * Gets the initial and final pitch bounds for this range.
302  */
303  void getPitchBounds(double &initial,double &final) const;
304  /**
305  * Gets the pitch bounds for this range.
306  */
307  void getPitchBounds(std::vector<double> &bounds) const;
308  /**
309  * Gets the scan set.
310  */
311  void getScanSet(std::vector<CObservation2DRangeScan> &scans) const;
312  /**
313  * Sets the scan set.
314  */
315  bool setScanSet(const std::vector<CObservation2DRangeScan> &scans);
316  /**
317  * Gets the mesh as a set of triangles, for displaying them.
318  * \sa generateSetOfTriangles(std::vector<TPolygon3D> &),mrpt::opengl::CSetOfTriangles,mrpt::opengl::CSetOfTriangles::TTriangle
319  */
320  void generateSetOfTriangles(CSetOfTrianglesPtr &res) const;
321  /**
322  * Returns the scanned points as a 3D point cloud. The target pointmap must be passed as a pointer to allow the use of any derived class.
323  */
324  void generatePointCloud(CPointsMap *out_map) const;
325  /**
326  * Gets a set of lines containing the traced rays, for displaying them.
327  * \sa getUntracedRays,mrpt::opengl::CSetOfLines
328  */
329  void getTracedRays(CSetOfLinesPtr &res) const;
330  /**
331  * Gets a set of lines containing the untraced rays, up to a specified distance, for displaying them.
332  * \sa getTracedRays,mrpt::opengl::CSetOfLines
333  */
334  void getUntracedRays(CSetOfLinesPtr &res,double dist) const;
335  /**
336  * Gets the mesh as a set of polygons, to work with them.
337  * \sa generateSetOfTriangles(mrpt::opengl::CSetOfTriangles &)
338  */
339  void generateSetOfTriangles(std::vector<TPolygon3D> &res) const;
340  /**
341  * Retrieves the full mesh, along with the validity matrix.
342  */
344  if (!meshUpToDate) updateMesh();
345  pts=actualMesh;
346  validity=validityMatrix;
347  }
348  private:
349  /**
350  * Internal functor class to trace a ray.
351  */
352  template<class T> class FTrace1D {
353  protected:
354  const CPose3D &initial;
355  const T &e;
356  std::vector<double> &values;
357  std::vector<char> &valid;
358  public:
359  FTrace1D(const T &s,const CPose3D &p,std::vector<double> &v,std::vector<char> &v2):initial(p),e(s),values(v),valid(v2) {}
360  void operator()(double yaw) {
361  double dist;
362  const CPose3D pNew=initial+CPose3D(0.0,0.0,0.0,yaw,0.0,0.0);
363  if (e->traceRay(pNew,dist)) {
364  values.push_back(dist);
365  valid.push_back(1);
366  } else {
367  values.push_back(0);
368  valid.push_back(0);
369  }
370  }
371  };
372  /**
373  * Internal functor class to trace a set of rays.
374  */
375  template<class T> class FTrace2D {
376  protected:
377  const T &e;
378  const CPose3D &initial;
379  CAngularObservationMeshPtr &caom;
381  std::vector<CObservation2DRangeScan> &vObs;
382  const CPose3D &pBase;
383  public:
384  FTrace2D(const T &s,const CPose3D &p,CAngularObservationMeshPtr &om,const CAngularObservationMesh::TDoubleRange &y,std::vector<CObservation2DRangeScan> &obs,const CPose3D &b):e(s),initial(p),caom(om),yaws(y),vObs(obs),pBase(b) {}
385  void operator()(double pitch) {
386  std::vector<double> yValues;
387  yaws.values(yValues);
389  const CPose3D pNew=initial+CPose3D(0,0,0,0,pitch,0);
390  std::vector<double> values;
391  std::vector<char> valid;
392  size_t nY=yValues.size();
393  values.reserve(nY);
394  valid.reserve(nY);
395  for_each(yValues.begin(),yValues.end(),FTrace1D<T>(e,pNew,values,valid));
396  o.aperture=yaws.aperture();
397  o.rightToLeft=yaws.negToPos();
398  o.maxRange=10000;
399  o.sensorPose=pNew;
400  o.deltaPitch=0;
401  o.scan.resize(values.size());
402  for (size_t i=0;i<values.size();i++) o.scan[i]=values[i];
403  o.validRange=valid;
404  vObs.push_back(o);
405  }
406  };
407  public:
408  /**
409  * 2D ray tracing (will generate a 3D mesh). Given an object and two ranges, realizes a scan from the initial pose and stores it in a CAngularObservationMesh object.
410  * The objective may be a COpenGLScene, a CRenderizable or any children of its.
411  * \sa mrpt::opengl::CRenderizable,mrpt::opengl::COpenGLScene.
412  */
413  template<class T> static void trace2DSetOfRays(const T &e,const CPose3D &initial,CAngularObservationMeshPtr &caom,const TDoubleRange &pitchs,const TDoubleRange &yaws);
414  /**
415  * 2D ray tracing (will generate a vectorial mesh inside a plane). Given an object and a range, realizes a scan from the initial pose and stores it in a CObservation2DRangeScan object.
416  * The objective may be a COpenGLScene, a CRenderizable or any children of its.
417  * \sa mrpt::opengl::CRenderizable,mrpt::opengl::COpenGLScene.
418  */
419  template<class T> static void trace1DSetOfRays(const T &e,const CPose3D &initial,CObservation2DRangeScan &obs,const TDoubleRange &yaws) {
420  std::vector<double> yValues;
421  yaws.values(yValues);
422  std::vector<double> scanValues;
423  std::vector<char> valid;
424  size_t nV=yaws.amount();
425  scanValues.reserve(nV);
426  valid.reserve(nV);
427  for_each(yValues.begin(),yValues.end(),FTrace1D<T>(e,initial,scanValues,valid));
428  obs.aperture=yaws.aperture();
429  obs.rightToLeft=yaws.negToPos();
430  obs.maxRange=10000;
431  obs.sensorPose=initial;
432  obs.deltaPitch=0;
433  obs.scan=scanValues;
434  obs.validRange=valid;
435  }
436  };
437  DEFINE_SERIALIZABLE_POST_CUSTOM_BASE_LINKAGE(CAngularObservationMesh,CRenderizableDisplayList, MAPS_IMPEXP)
438 
439  template<class T>
440  void CAngularObservationMesh::trace2DSetOfRays(const T &e,const CPose3D &initial,CAngularObservationMeshPtr &caom,const TDoubleRange &pitchs,const TDoubleRange &yaws) {
441  std::vector<double> pValues;
442  pitchs.values(pValues);
443  std::vector<CObservation2DRangeScan> vObs;
444  vObs.reserve(pValues.size());
445  for_each(pValues.begin(),pValues.end(),FTrace2D<T>(e,initial,caom,yaws,vObs,initial));
446  caom->mWireframe=false;
447  caom->mEnableTransparency=false;
448  caom->setPitchBounds(pValues);
449  caom->setScanSet(vObs);
450  }
451 }
452 }
453 #endif
A "CObservation"-derived class that represents a 2D range scan measurement (typically from a laser sc...
bool meshUpToDate
Mutable variable which controls if the object has suffered any change since last time the mesh was up...
std::vector< CObservation2DRangeScan > & vObs
A mesh built from a set of 2D laser scan observations.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
Definition: zip.h:16
double initialValue() const
Returns the first value of the range.
Internal functor class to trace a set of rays.
double increment() const
Returns the increment between two consecutive values of the range.
Internal functor class to trace a ray.
TDoubleRange(double a, size_t b, bool c)
Constructor from aperture, amount of samples and scan direction.
std::vector< char > validRange
It's false (=0) on no reflected rays, referenced to elements in "scan" (Added in the streamming versi...
virtual ~CAngularObservationMesh()
Empty destructor.
std::vector< float > scan
The range values of the scan, in meters.
double deltaPitch
If the laser gathers data by sweeping in the pitch/elevation angle, this holds the increment in "pitc...
void values(std::vector< double > &vals) const
Gets a vector with every value in the range.
EIGEN_STRONG_INLINE void notifyChange() const
Must be called to notify that the object has changed (so, the display list must be updated) ...
FTrace2D(const T &s, const CPose3D &p, CAngularObservationMeshPtr &om, const CAngularObservationMesh::TDoubleRange &y, std::vector< CObservation2DRangeScan > &obs, const CPose3D &b)
bool mEnableTransparency
Whether the object may present transparencies or not.
void setWireframe(bool enabled=true)
Sets the display mode for the object.
This namespace contains algorithms for SLAM, localization, map building, representation of robot's ac...
A renderizable object suitable for rendering with OpenGL's display lists.
CPose3D sensorPose
The 6D pose of the sensor on the robot.
float aperture
The aperture of the range finder, in radians (typically M_PI = 180 degrees).
bool negToPos() const
Returns the direction of the scan.
double aperture() const
Returns the total aperture of the range.
mrpt::math::CMatrixB validityMatrix
Scan validity matrix.
#define DEFINE_SERIALIZABLE_PRE_CUSTOM_BASE_LINKAGE(class_name, base_name, _LINKAGE_)
This declaration must be inserted in all CSerializable classes definition, before the class declarati...
void getActualMesh(mrpt::math::CMatrixTemplate< mrpt::math::TPoint3D > &pts, mrpt::math::CMatrixBool &validity) const
Retrieves the full mesh, along with the validity matrix.
bool isWireframe() const
Returns whether the object is configured as wireframe or solid.
static void trace1DSetOfRays(const T &e, const CPose3D &initial, CObservation2DRangeScan &obs, const TDoubleRange &yaws)
2D ray tracing (will generate a vectorial mesh inside a plane).
float maxRange
The maximum range allowed by the device, in meters (e.g.
double finalValue() const
Returns the last value of the range.
int sign(T x)
Returns the sign of X as "1" or "-1".
Definition: bits.h:88
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Definition: CPoint.h:17
std::vector< CObservation2DRangeScan > scanSet
Actual scan set which is used to generate the mesh.
mrpt::math::CMatrixTemplate< TPoint3D > actualMesh
Mutable object with the mesh's points.
bool BASE_IMPEXP traceRay(const vector< TPolygonWithPlane > &vec, const mrpt::poses::CPose3D &pose, double &dist)
Fast ray tracing method using polygons' properties.
bool isTransparencyEnabled() const
Returns whether the object may be transparent or not.
This template class provides the basic functionality for a general 2D any-size, resizable container o...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
#define DEFINE_SERIALIZABLE(class_name)
This declaration must be inserted in all CSerializable classes definition, within the class declarati...
static TDoubleRange CreateFromIncrement(double initial, double final, double increment)
Creates a range of values from the initial value, the final value and the increment.
static TDoubleRange CreateFromAmount(double initial, double final, size_t amount)
Creates a range of values from the initial value, the final value and a desired amount of samples...
const CAngularObservationMesh::TDoubleRange & yaws
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:69
bool mWireframe
Whether the mesh will be displayed wireframe or solid.
bool rightToLeft
The scanning direction.
static TDoubleRange CreateFromAperture(double aperture, size_t amount, bool negToPos=true)
Creates a zero-centered range of values from an aperture, an amount of samples and a direction...
size_t amount() const
Returns the total amount of values in this range.
FTrace1D(const T &s, const CPose3D &p, std::vector< double > &v, std::vector< char > &v2)
Range specification type, with several uses.
TDoubleRange(double a, double b, size_t c)
Constructor from initial value, final value and amount of samples.
This class is a "CSerializable" wrapper for "CMatrixBool".
Definition: CMatrixB.h:26
TDoubleRange(double a, double b, double c)
Constructor from initial value, final value and range.
A cloud of points in 2D or 3D, which can be built from a sequence of laser scans or other sensors...
Definition: CPointsMap.h:59
Lightweight 3D point.
void enableTransparency(bool enabled=true)
Enables or disables transparencies.
#define DEFINE_SERIALIZABLE_POST_CUSTOM_BASE_LINKAGE(class_name, base_name, _LINKAGE_)
std::vector< CSetOfTriangles::TTriangle > triangles
Actual set of triangles to be displayed.
std::vector< double > pitchBounds
Observation pitch range.



Page generated by Doxygen 1.8.8 for MRPT 1.2.2 SVN:Unversioned directory at Tue Oct 14 02:14:08 UTC 2014