Main MRPT website > C++ reference
MRPT logo
CPose3D.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | The Mobile Robot Programming Toolkit (MRPT) C++ library |
3  | |
4  | http://www.mrpt.org/ |
5  | |
6  | Copyright (C) 2005-2012 University of Malaga |
7  | |
8  | This software was written by the Machine Perception and Intelligent |
9  | Robotics Lab, University of Malaga (Spain). |
10  | Contact: Jose-Luis Blanco <jlblanco@ctima.uma.es> |
11  | |
12  | This file is part of the MRPT project. |
13  | |
14  | MRPT is free software: you can redistribute it and/or modify |
15  | it under the terms of the GNU General Public License as published by |
16  | the Free Software Foundation, either version 3 of the License, or |
17  | (at your option) any later version. |
18  | |
19  | MRPT is distributed in the hope that it will be useful, |
20  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
21  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22  | GNU General Public License for more details. |
23  | |
24  | You should have received a copy of the GNU General Public License |
25  | along with MRPT. If not, see <http://www.gnu.org/licenses/>. |
26  | |
27  +---------------------------------------------------------------------------+ */
28 #ifndef CPOSE3D_H
29 #define CPOSE3D_H
30 
31 #include <mrpt/poses/CPose.h>
33 #include <mrpt/math/CQuaternion.h>
34 
35 namespace mrpt
36 {
37 namespace poses
38 {
39  using namespace mrpt::math;
40 
42 
44 
45  /** A class used to store a 3D pose (a 3D translation + a rotation in 3D).
46  * The 6D transformation in SE(3) stored in this class is kept in two
47  * separate containers: a 3-array for the translation, and a 3x3 rotation matrix.
48  *
49  * This class allows parameterizing 6D poses as a 6-vector: [x y z yaw pitch roll] (read below
50  * for the angles convention). Note however,
51  * that the yaw/pitch/roll angles are only computed (on-demand and transparently)
52  * when the user requests them. Normally, rotations and transformations are always handled
53  * via the 3x3 rotation matrix.
54  *
55  * Yaw/Pitch/Roll angles are defined as successive rotations around *local* (dynamic) axes in the Z/Y/X order:
56  *
57  * <div align=center>
58  * <img src="CPose3D.gif">
59  * </div>
60  *
61  * It may be extremely confusing and annoying to find a different criterion also involving
62  * the names "yaw, pitch, roll" but regarding rotations around *global* (static) axes.
63  * Fortunately, it's very easy to see (by writing down the product of the three
64  * rotation matrices) that both conventions lead to exactly the same numbers.
65  * Only, that it's conventional to write the numbers in reverse order.
66  * That is, the same rotation can be described equivalently with any of these two
67  * parameterizations:
68  *
69  * - In local axes Z/Y/X convention: [yaw pitch roll] (This is the convention used in mrpt::poses::CPose3D)
70  * - In global axes X/Y/Z convention: [roll pitch yaw] (One of the Euler angles conventions)
71  *
72  * For further descriptions of point & pose classes, see mrpt::poses::CPoseOrPoint or refer
73  * to the <a href="http://www.mrpt.org/2D_3D_Geometry"> 2D/3D Geometry tutorial</a> online.
74  *
75  * To change the individual components of the pose, use CPose3D::setFromValues. This class assures that the internal
76  * 3x3 rotation matrix is always up-to-date with the "yaw pitch roll" members.
77  *
78  * Rotations in 3D can be also represented by quaternions. See mrpt::math::CQuaternion, and method CPose3D::getAsQuaternion.
79  *
80  * This class and CPose3DQuat are very similar, and they can be converted to the each other automatically via transformation constructors.
81  *
82  * There are Lie algebra methods: \a exp and \a ln (see the methods for documentation).
83  *
84  *
85  * \ingroup poses_grp
86  * \sa CPoseOrPoint,CPoint3D, mrpt::math::CQuaternion
87  */
88  class BASE_IMPEXP CPose3D : public CPose<CPose3D>, public mrpt::utils::CSerializable
89  {
90  // This must be added to any CSerializable derived class:
92 
93  public:
94  CArrayDouble<3> m_coords; //!< The translation vector [x,y,z] access directly or with x(), y(), z() setter/getter methods.
95  protected:
96  CMatrixDouble33 m_ROT; //!< The 3x3 rotation matrix, access with getRotationMatrix(), setRotationMatrix() (It's not safe to set this field as public)
97 
98  mutable bool m_ypr_uptodate; //!< Whether yaw/pitch/roll members are up-to-date since the last rotation matrix update.
99  mutable double m_yaw, m_pitch, m_roll; //!< These variables are updated every time that the object rotation matrix is modified (construction, loading from values, pose composition, etc )
100 
101  /** Rebuild the homog matrix from the angles. */
102  void rebuildRotationMatrix();
103 
104  /** Updates Yaw/pitch/roll members from the m_ROT */
105  inline void updateYawPitchRoll() const { if (!m_ypr_uptodate) { m_ypr_uptodate=true; getYawPitchRoll( m_yaw, m_pitch, m_roll ); } }
106 
107  public:
108  /** @name Constructors
109  @{ */
110 
111  /** Default constructor, with all the coordinates set to zero. */
112  CPose3D();
113 
114  /** Constructor with initilization of the pose; (remember that angles are always given in radians!) */
115  CPose3D(const double x,const double y,const double z,const double yaw=0, const double pitch=0, const double roll=0);
116 
117  /** Constructor from a 4x4 homogeneous matrix - the passed matrix can be actually of any size larger than or equal 3x4, since only those first values are used (the last row of a homogeneous 4x4 matrix are always fixed). */
118  explicit CPose3D(const math::CMatrixDouble &m);
119 
120  /** Constructor from a 4x4 homogeneous matrix: */
121  explicit CPose3D(const math::CMatrixDouble44 &m);
122 
123  /** Constructor from a 3x3 rotation matrix and a the translation given as a 3-vector, a 3-array, a CPoint3D or a TPoint3D */
124  template <class MATRIX33,class VECTOR3>
125  inline CPose3D(const MATRIX33 &rot, const VECTOR3& xyz) : m_ROT(UNINITIALIZED_MATRIX), m_ypr_uptodate(false)
126  {
128  for (int r=0;r<3;r++)
129  for (int c=0;c<3;c++)
130  m_ROT(r,c)=rot.get_unsafe(r,c);
131  for (int r=0;r<3;r++) m_coords[r]=xyz[r];
132  }
133  //! \overload
134  inline CPose3D(const CMatrixDouble33 &rot, const CArrayDouble<3>& xyz) : m_coords(xyz),m_ROT(rot), m_ypr_uptodate(false)
135  { }
136 
137  /** Constructor from a CPose2D object.
138  */
139  CPose3D(const CPose2D &);
140 
141  /** Constructor from a CPoint3D object.
142  */
143  CPose3D(const CPoint3D &);
144 
145  /** Constructor from lightweight object.
146  */
147  CPose3D(const mrpt::math::TPose3D &);
148 
149  /** Constructor from a quaternion (which only represents the 3D rotation part) and a 3D displacement. */
150  CPose3D(const mrpt::math::CQuaternionDouble &q, const double x, const double y, const double z );
151 
152  /** Constructor from a CPose3DQuat. */
153  CPose3D(const CPose3DQuat &);
154 
155  /** Fast constructor that leaves all the data uninitialized - call with UNINITIALIZED_POSE as argument */
156  inline CPose3D(TConstructorFlags_Poses constructor_dummy_param) : m_ROT(UNINITIALIZED_MATRIX), m_ypr_uptodate(false) { }
157 
158  /** Constructor from an array with these 12 elements: [r11 r21 r31 r12 r22 r32 r13 r23 r33 tx ty tz]
159  * where r{ij} are the entries of the 3x3 rotation matrix and t{x,y,z} are the 3D translation of the pose
160  * \sa setFrom12Vector, getAs12Vector
161  */
162  inline explicit CPose3D(const CArrayDouble<12> &vec12) : m_ROT( UNINITIALIZED_MATRIX ), m_ypr_uptodate(false) {
163  setFrom12Vector(vec12);
164  }
165 
166  /** @} */ // end Constructors
167 
168 
169 
170  /** @name Access 3x3 rotation and 4x4 homogeneous matrices
171  @{ */
172 
173  /** Returns the corresponding 4x4 homogeneous transformation matrix for the point(translation) or pose (translation+orientation).
174  * \sa getInverseHomogeneousMatrix, getRotationMatrix
175  */
176  inline void getHomogeneousMatrix(CMatrixDouble44 & out_HM ) const
177  {
178  out_HM.insertMatrix(0,0,m_ROT);
179  for (int i=0;i<3;i++) out_HM(i,3)=m_coords[i];
180  out_HM(3,0)=out_HM(3,1)=out_HM(3,2)=0.; out_HM(3,3)=1.;
181  }
182 
183  inline CMatrixDouble44 getHomogeneousMatrixVal() const { CMatrixDouble44 M; getHomogeneousMatrix(M); return M;}
184 
185  /** Get the 3x3 rotation matrix \sa getHomogeneousMatrix */
186  inline void getRotationMatrix( mrpt::math::CMatrixDouble33 & ROT ) const { ROT = m_ROT; }
187  //! \overload
188  inline const mrpt::math::CMatrixDouble33 & getRotationMatrix() const { return m_ROT; }
189 
190  /** Sets the 3x3 rotation matrix \sa getRotationMatrix, getHomogeneousMatrix */
191  inline void setRotationMatrix( const mrpt::math::CMatrixDouble33 & ROT ) { m_ROT = ROT; m_ypr_uptodate = false; }
192 
193  /** @} */ // end rot and HM
194 
195 
196  /** @name Pose-pose and pose-point compositions and operators
197  @{ */
198 
199  /** The operator \f$ a \oplus b \f$ is the pose compounding operator. */
200  inline CPose3D operator + (const CPose3D& b) const
201  {
202  CPose3D ret(UNINITIALIZED_POSE);
203  ret.composeFrom(*this,b);
204  return ret;
205  }
206 
207  /** The operator \f$ a \oplus b \f$ is the pose compounding operator. */
208  CPoint3D operator + (const CPoint3D& b) const;
209 
210  /** The operator \f$ a \oplus b \f$ is the pose compounding operator. */
211  CPoint3D operator + (const CPoint2D& b) const;
212 
213  /** Computes the spherical coordinates of a 3D point as seen from the 6D pose specified by this object. For the coordinate system see the top of this page. */
214  void sphericalCoordinates(
215  const TPoint3D &point,
216  double &out_range,
217  double &out_yaw,
218  double &out_pitch ) const;
219 
220  /** An alternative, slightly more efficient way of doing \f$ G = P \oplus L \f$ with G and L being 3D points and P this 6D pose.
221  * If pointers are provided, the corresponding Jacobians are returned.
222  * "out_jacobian_df_dse3" stands for the Jacobian with respect to the 6D locally Euclidean vector in the tangent space of SE(3).
223  * See <a href="http://www.mrpt.org/6D_poses:equivalences_compositions_and_uncertainty" >this report</a> for mathematical details.
224  * \param If set to true, the Jacobian "out_jacobian_df_dpose" uses a fastest linearized appoximation (valid only for small rotations!).
225  */
226  void composePoint(double lx,double ly,double lz, double &gx, double &gy, double &gz,
227  mrpt::math::CMatrixFixedNumeric<double,3,3> *out_jacobian_df_dpoint=NULL,
228  mrpt::math::CMatrixFixedNumeric<double,3,6> *out_jacobian_df_dpose=NULL,
229  mrpt::math::CMatrixFixedNumeric<double,3,6> *out_jacobian_df_dse3=NULL,
230  bool use_small_rot_approx = false) const;
231 
232  /** An alternative, slightly more efficient way of doing \f$ G = P \oplus L \f$ with G and L being 3D points and P this 6D pose.
233  * \note local_point is passed by value to allow global and local point to be the same variable
234  */
235  inline void composePoint(const TPoint3D local_point, TPoint3D &global_point) const {
236  composePoint(local_point.x,local_point.y,local_point.z, global_point.x,global_point.y,global_point.z );
237  }
238 
239  /** An alternative, slightly more efficient way of doing \f$ G = P \oplus L \f$ with G and L being 3D points and P this 6D pose. */
240  inline void composePoint(double lx,double ly,double lz, float &gx, float &gy, float &gz ) const {
241  double ggx, ggy,ggz;
242  composePoint(lx,ly,lz,ggx,ggy,ggz);
243  gx = ggx; gy = ggy; gz = ggz;
244  }
245 
246  /** Computes the 3D point L such as \f$ L = G \ominus this \f$.
247  * If pointers are provided, the corresponding Jacobians are returned.
248  * "out_jacobian_df_dse3" stands for the Jacobian with respect to the 6D locally Euclidean vector in the tangent space of SE(3).
249  * See <a href="http://www.mrpt.org/6D_poses:equivalences_compositions_and_uncertainty" >this report</a> for mathematical details.
250  * \sa composePoint, composeFrom
251  */
252  void inverseComposePoint(const double gx,const double gy,const double gz,double &lx,double &ly,double &lz,
253  mrpt::math::CMatrixFixedNumeric<double,3,3> *out_jacobian_df_dpoint=NULL,
254  mrpt::math::CMatrixFixedNumeric<double,3,6> *out_jacobian_df_dpose=NULL,
255  mrpt::math::CMatrixFixedNumeric<double,3,6> *out_jacobian_df_dse3=NULL ) const;
256 
257  /** Makes "this = A (+) B"; this method is slightly more efficient than "this= A + B;" since it avoids the temporary object.
258  * \note A or B can be "this" without problems.
259  */
260  void composeFrom(const CPose3D& A, const CPose3D& B );
261 
262  /** Make \f$ this = this \oplus b \f$ (\a b can be "this" without problems) */
263  inline CPose3D& operator += (const CPose3D& b)
264  {
265  composeFrom(*this,b);
266  return *this;
267  }
268 
269  /** Makes \f$ this = A \ominus B \f$ this method is slightly more efficient than "this= A - B;" since it avoids the temporary object.
270  * \note A or B can be "this" without problems.
271  * \sa composeFrom, composePoint
272  */
273  void inverseComposeFrom(const CPose3D& A, const CPose3D& B );
274 
275  /** Compute \f$ RET = this \oplus b \f$ */
276  inline CPose3D operator - (const CPose3D& b) const
277  {
278  CPose3D ret(UNINITIALIZED_POSE);
279  ret.inverseComposeFrom(*this,b);
280  return ret;
281  }
282 
283  /** Convert this pose into its inverse, saving the result in itself. \sa operator- */
284  void inverse();
285 
286  /** makes: this = p (+) this */
287  inline void changeCoordinatesReference( const CPose3D & p ) { composeFrom(p,CPose3D(*this)); }
288 
289  /** @} */ // compositions
290 
291 
292  /** @name Access and modify contents
293  @{ */
294 
295  /** Scalar sum of all 6 components: This is diferent from poses composition, which is implemented as "+" operators.
296  * \sa normalizeAngles
297  */
298  void addComponents(const CPose3D &p);
299 
300  /** Rebuild the internal matrix & update the yaw/pitch/roll angles within the ]-PI,PI] range (Must be called after using addComponents)
301  * \sa addComponents
302  */
303  void normalizeAngles();
304 
305  /** Scalar multiplication of x,y,z,yaw,pitch & roll (angles will be wrapped to the ]-pi,pi] interval). */
306  void operator *=(const double s);
307 
308  /** Set the pose from a 3D position (meters) and yaw/pitch/roll angles (radians) - This method recomputes the internal rotation matrix.
309  * \sa getYawPitchRoll, setYawPitchRoll
310  */
311  void setFromValues(
312  const double x0,
313  const double y0,
314  const double z0,
315  const double yaw=0,
316  const double pitch=0,
317  const double roll=0);
318 
319  /** Set the pose from a 3D position (meters) and a quaternion, stored as [x y z qr qx qy qz] in a 7-element vector.
320  * \sa setFromValues, getYawPitchRoll, setYawPitchRoll, CQuaternion, getAsQuaternion
321  */
322  template <typename VECTORLIKE>
323  inline void setFromXYZQ(
324  const VECTORLIKE &v,
325  const size_t index_offset = 0)
326  {
327  ASSERT_ABOVEEQ_(v.size(), 7+index_offset)
328  // The 3x3 rotation part:
329  mrpt::math::CQuaternion<typename VECTORLIKE::value_type> q( v[index_offset+3],v[index_offset+4],v[index_offset+5],v[index_offset+6] );
330  q.rotationMatrixNoResize(m_ROT);
331  m_ypr_uptodate=false;
332  m_coords[0] = v[index_offset+0];
333  m_coords[1] = v[index_offset+1];
334  m_coords[2] = v[index_offset+2];
335  }
336 
337  /** Set the 3 angles of the 3D pose (in radians) - This method recomputes the internal rotation coordinates matrix.
338  * \sa getYawPitchRoll, setFromValues
339  */
340  inline void setYawPitchRoll(
341  const double yaw_,
342  const double pitch_,
343  const double roll_)
344  {
345  setFromValues(x(),y(),z(),yaw_,pitch_,roll_);
346  }
347 
348  /** Set pose from an array with these 12 elements: [r11 r21 r31 r12 r22 r32 r13 r23 r33 tx ty tz]
349  * where r{ij} are the entries of the 3x3 rotation matrix and t{x,y,z} are the 3D translation of the pose
350  * \sa getAs12Vector
351  */
352  template <class ARRAYORVECTOR>
353  inline void setFrom12Vector(const ARRAYORVECTOR &vec12)
354  {
355  m_ROT.set_unsafe(0,0, vec12[0]); m_ROT.set_unsafe(0,1, vec12[3]); m_ROT.set_unsafe(0,2, vec12[6]);
356  m_ROT.set_unsafe(1,0, vec12[1]); m_ROT.set_unsafe(1,1, vec12[4]); m_ROT.set_unsafe(1,2, vec12[7]);
357  m_ROT.set_unsafe(2,0, vec12[2]); m_ROT.set_unsafe(2,1, vec12[5]); m_ROT.set_unsafe(2,2, vec12[8]);
358  m_ypr_uptodate = false;
359  m_coords[0] = vec12[ 9];
360  m_coords[1] = vec12[10];
361  m_coords[2] = vec12[11];
362  }
363 
364  /** Get the pose representation as an array with these 12 elements: [r11 r21 r31 r12 r22 r32 r13 r23 r33 tx ty tz]
365  * where r{ij} are the entries of the 3x3 rotation matrix and t{x,y,z} are the 3D translation of the pose
366  * \sa setFrom12Vector
367  */
368  template <class ARRAYORVECTOR>
369  inline void getAs12Vector(ARRAYORVECTOR &vec12) const
370  {
371  vec12[0] = m_ROT.get_unsafe(0,0); vec12[3] = m_ROT.get_unsafe(0,1); vec12[6] = m_ROT.get_unsafe(0,2);
372  vec12[1] = m_ROT.get_unsafe(1,0); vec12[4] = m_ROT.get_unsafe(1,1); vec12[7] = m_ROT.get_unsafe(1,2);
373  vec12[2] = m_ROT.get_unsafe(2,0); vec12[5] = m_ROT.get_unsafe(2,1); vec12[8] = m_ROT.get_unsafe(2,2);
374  vec12[ 9] = m_coords[0];
375  vec12[10] = m_coords[1];
376  vec12[11] = m_coords[2];
377  }
378 
379  /** Returns the three angles (yaw, pitch, roll), in radians, from the rotation matrix.
380  * \sa setFromValues, yaw, pitch, roll
381  */
382  void getYawPitchRoll( double &yaw, double &pitch, double &roll ) const;
383 
384  inline double yaw() const { updateYawPitchRoll(); return m_yaw; } //!< Get the YAW angle (in radians) \sa setFromValues
385  inline double pitch() const { updateYawPitchRoll(); return m_pitch; } //!< Get the PITCH angle (in radians) \sa setFromValues
386  inline double roll() const { updateYawPitchRoll(); return m_roll; } //!< Get the ROLL angle (in radians) \sa setFromValues
387 
388  /** Returns a 1x6 vector with [x y z yaw pitch roll] */
389  void getAsVector(vector_double &v) const;
390  /// \overload
391  void getAsVector(mrpt::math::CArrayDouble<6> &v) const;
392 
393  /** Returns the quaternion associated to the rotation of this object (NOTE: XYZ translation is ignored)
394  * \f[ \mathbf{q} = \left( \begin{array}{c} \cos (\phi /2) \cos (\theta /2) \cos (\psi /2) + \sin (\phi /2) \sin (\theta /2) \sin (\psi /2) \\ \sin (\phi /2) \cos (\theta /2) \cos (\psi /2) - \cos (\phi /2) \sin (\theta /2) \sin (\psi /2) \\ \cos (\phi /2) \sin (\theta /2) \cos (\psi /2) + \sin (\phi /2) \cos (\theta /2) \sin (\psi /2) \\ \cos (\phi /2) \cos (\theta /2) \sin (\psi /2) - \sin (\phi /2) \sin (\theta /2) \cos (\psi /2) \\ \end{array}\right) \f]
395  * With : \f$ \phi = roll \f$, \f$ \theta = pitch \f$ and \f$ \psi = yaw \f$.
396  * \param out_dq_dr If provided, the 4x3 Jacobian of the transformation will be computed and stored here. It's the Jacobian of the transformation from (yaw pitch roll) to (qr qx qy qz).
397  */
398  void getAsQuaternion(
401  ) const;
402 
403  inline const double &operator[](unsigned int i) const
404  {
405  updateYawPitchRoll();
406  switch(i)
407  {
408  case 0:return m_coords[0];
409  case 1:return m_coords[1];
410  case 2:return m_coords[2];
411  case 3:return m_yaw;
412  case 4:return m_pitch;
413  case 5:return m_roll;
414  default:
415  throw std::runtime_error("CPose3D::operator[]: Index of bounds.");
416  }
417  }
418  // CPose3D CANNOT have a write [] operator, since it'd leave the object in an inconsistent state (outdated rotation matrix).
419  // Use setFromValues() instead.
420  // inline double &operator[](unsigned int i)
421 
422  /** Returns a human-readable textual representation of the object (eg: "[x y z yaw pitch roll]", angles in degrees.)
423  * \sa fromString
424  */
425  void asString(std::string &s) const { updateYawPitchRoll(); s = mrpt::format("[%f %f %f %f %f %f]",m_coords[0],m_coords[1],m_coords[2],RAD2DEG(m_yaw),RAD2DEG(m_pitch),RAD2DEG(m_roll)); }
426  inline std::string asString() const { std::string s; asString(s); return s; }
427 
428  /** Set the current object value from a string generated by 'asString' (eg: "[x y z yaw pitch roll]", angles in deg. )
429  * \sa asString
430  * \exception std::exception On invalid format
431  */
432  void fromString(const std::string &s) {
433  CMatrixDouble m;
434  if (!m.fromMatlabStringFormat(s)) THROW_EXCEPTION("Malformed expression in ::fromString");
435  ASSERTMSG_(mrpt::math::size(m,1)==1 && mrpt::math::size(m,2)==6, "Wrong size of vector in ::fromString");
436  this->setFromValues(m.get_unsafe(0,0),m.get_unsafe(0,1),m.get_unsafe(0,2),DEG2RAD(m.get_unsafe(0,3)),DEG2RAD(m.get_unsafe(0,4)),DEG2RAD(m.get_unsafe(0,5)));
437  }
438 
439  /** Return true if the 6D pose represents a Z axis almost exactly vertical (upwards or downwards), with a given tolerance (if set to 0 exact horizontality is tested). */
440  bool isHorizontal( const double tolerance=0) const;
441 
442  /** The euclidean distance between two poses taken as two 6-length vectors (angles in radians). */
443  double distanceEuclidean6D( const CPose3D &o ) const;
444 
445  /** @} */ // modif. components
446 
447 
448 
449  /** @name Lie Algebra methods
450  @{ */
451 
452  /** Exponentiate a Vector in the SE(3) Lie Algebra to generate a new CPose3D (static method).
453  * \note Method from TooN (C) Tom Drummond (GNU GPL) */
454  static CPose3D exp(const mrpt::math::CArrayNumeric<double,6> & vect);
455 
456  /** Exponentiate a vector in the Lie algebra to generate a new SO(3) (a 3x3 rotation matrix).
457  * \note Method from TooN (C) Tom Drummond (GNU GPL) */
458  static CMatrixDouble33 exp_rotation(const mrpt::math::CArrayNumeric<double,3> & vect);
459 
460 
461  /** Take the logarithm of the 3x4 matrix defined by this pose, generating the corresponding vector in the SE(3) Lie Algebra.
462  * \note Method from TooN (C) Tom Drummond (GNU GPL)
463  * \sa ln_jacob
464  */
465  void ln(mrpt::math::CArrayDouble<6> &out_ln) const;
466 
467  /// \overload
468  inline mrpt::math::CArrayDouble<6> ln() const { mrpt::math::CArrayDouble<6> ret; ln(ret); return ret; }
469 
470  /** Jacobian of the logarithm of the 3x4 matrix defined by this pose.
471  * \note Method from TooN (C) Tom Drummond (GNU GPL)
472  * \sa ln
473  */
474  void ln_jacob(mrpt::math::CMatrixFixedNumeric<double,6,12> &J) const;
475 
476  /** Static function to compute the Jacobian of the SO(3) Logarithm function, evaluated at a given 3x3 rotation matrix R.
477  * \sa ln, ln_jacob
478  */
479  static void ln_rot_jacob(const CMatrixDouble33 &R, CMatrixFixedNumeric<double,3,9> &M);
480 
481  /** Take the logarithm of the 3x3 rotation matrix, generating the corresponding vector in the Lie Algebra.
482  * \note Method from TooN (C) Tom Drummond (GNU GPL) */
483  CArrayDouble<3> ln_rotation() const;
484 
485  /** @} */
486 
487  typedef CPose3D type_value; //!< Used to emulate CPosePDF types, for example, in mrpt::graphs::CNetworkOfPoses
488  enum { is_3D_val = 1 };
489  static inline bool is_3D() { return is_3D_val!=0; }
490  enum { rotation_dimensions = 3 };
491  enum { is_PDF_val = 0 };
492  static inline bool is_PDF() { return is_PDF_val!=0; }
493 
494  inline const type_value & getPoseMean() const { return *this; }
495  inline type_value & getPoseMean() { return *this; }
496 
497  /** @name STL-like methods and typedefs
498  @{ */
499  typedef double value_type; //!< The type of the elements
500  typedef double& reference;
501  typedef const double& const_reference;
502  typedef std::size_t size_type;
503  typedef std::ptrdiff_t difference_type;
504 
505 
506  // size is constant
507  enum { static_size = 6 };
508  static inline size_type size() { return static_size; }
509  static inline bool empty() { return false; }
510  static inline size_type max_size() { return static_size; }
511  static inline void resize(const size_t n) { if (n!=static_size) throw std::logic_error(format("Try to change the size of CPose3D to %u.",static_cast<unsigned>(n))); }
512  /** @} */
513 
514  }; // End of class def.
515 
516 
517  std::ostream BASE_IMPEXP & operator << (std::ostream& o, const CPose3D& p);
518 
519  /** Unary - operator: return the inverse pose "-p" (Note that is NOT the same than a pose with negative x y z yaw pitch roll) */
520  CPose3D BASE_IMPEXP operator -(const CPose3D &p);
521 
522  bool BASE_IMPEXP operator==(const CPose3D &p1,const CPose3D &p2);
523  bool BASE_IMPEXP operator!=(const CPose3D &p1,const CPose3D &p2);
524 
525 
526  // This is a member of CPose<>, but has to be defined here since in its header CPose3D is not declared yet.
527  /** The operator \f$ a \ominus b \f$ is the pose inverse compounding operator. */
528  template <class DERIVEDCLASS> CPose3D CPose<DERIVEDCLASS>::operator -(const CPose3D& b) const
529  {
531  b.getInverseHomogeneousMatrix( B_INV );
533  static_cast<const DERIVEDCLASS*>(this)->getHomogeneousMatrix(HM);
535  RES.multiply(B_INV,HM);
536  return CPose3D( RES );
537  }
538 
539 
540  } // End of namespace
541 } // End of namespace
542 
543 #endif



Page generated by Doxygen 1.8.3 for MRPT 0.9.6 SVN: at Fri Feb 15 22:05:02 EST 2013