Main MRPT website > C++ reference
MRPT logo
CPose3D.h
Go to the documentation of this file.
00001 /* +---------------------------------------------------------------------------+
00002    |          The Mobile Robot Programming Toolkit (MRPT) C++ library          |
00003    |                                                                           |
00004    |                       http://www.mrpt.org/                                |
00005    |                                                                           |
00006    |   Copyright (C) 2005-2011  University of Malaga                           |
00007    |                                                                           |
00008    |    This software was written by the Machine Perception and Intelligent    |
00009    |      Robotics Lab, University of Malaga (Spain).                          |
00010    |    Contact: Jose-Luis Blanco  <jlblanco@ctima.uma.es>                     |
00011    |                                                                           |
00012    |  This file is part of the MRPT project.                                   |
00013    |                                                                           |
00014    |     MRPT is free software: you can redistribute it and/or modify          |
00015    |     it under the terms of the GNU General Public License as published by  |
00016    |     the Free Software Foundation, either version 3 of the License, or     |
00017    |     (at your option) any later version.                                   |
00018    |                                                                           |
00019    |   MRPT is distributed in the hope that it will be useful,                 |
00020    |     but WITHOUT ANY WARRANTY; without even the implied warranty of        |
00021    |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         |
00022    |     GNU General Public License for more details.                          |
00023    |                                                                           |
00024    |     You should have received a copy of the GNU General Public License     |
00025    |     along with MRPT.  If not, see <http://www.gnu.org/licenses/>.         |
00026    |                                                                           |
00027    +---------------------------------------------------------------------------+ */
00028 #ifndef CPOSE3D_H
00029 #define CPOSE3D_H
00030 
00031 #include <mrpt/poses/CPose.h>
00032 #include <mrpt/math/CMatrixFixedNumeric.h>
00033 #include <mrpt/math/CQuaternion.h>
00034 
00035 namespace mrpt
00036 {
00037 namespace poses
00038 {
00039         using namespace mrpt::math;
00040 
00041         class BASE_IMPEXP CPose3DQuat;
00042 
00043         DEFINE_SERIALIZABLE_PRE( CPose3D )
00044 
00045         /** A class used to store a 3D pose (a 3D translation + a rotation in 3D).
00046          *   The 6D transformation in SE(3) stored in this class is kept in two
00047          *   separate containers: a 3-array for the translation, and a 3x3 rotation matrix.
00048          *
00049          *  The 6D pose is parameterized as a 6-vector: [x y z yaw pitch roll]. Note however,
00050          *   that the yaw/pitch/roll angles are only computed (on-demand and transparently)
00051          *   when the user requests them. Normally, rotations are handled via the 3x3 rotation matrix only.
00052          *
00053          *  For a complete descriptionan of Points/Poses, see mrpt::poses::CPoseOrPoint, or refer
00054          *    to the <a href="http://www.mrpt.org/2D_3D_Geometry"> 2D/3D Geometry tutorial</a> in the wiki.
00055          *
00056          *  To change the individual components of the pose, use CPose3D::setFromValues. This class assures that the internal
00057          *   3x3 rotation matrix is always up-to-date with the "yaw pitch roll" members.
00058          *
00059          *  Rotations in 3D can be also represented by quaternions. See mrpt::math::CQuaternion, and method CPose3D::getAsQuaternion.
00060          *
00061          *  This class and CPose3DQuat are very similar, and they can be converted to the each other automatically via transformation constructors.
00062          *
00063          *  There are Lie algebra methods: \a exp and \a ln (see the methods for documentation).
00064          *
00065          *  <div align=center>
00066          *   <img src="CPose3D.gif">
00067          *  </div>
00068          *
00069          * \ingroup poses_grp
00070          * \sa CPoseOrPoint,CPoint3D, mrpt::math::CQuaternion
00071          */
00072         class BASE_IMPEXP CPose3D : public CPose<CPose3D>, public mrpt::utils::CSerializable
00073         {
00074                 // This must be added to any CSerializable derived class:
00075                 DEFINE_SERIALIZABLE( CPose3D )
00076 
00077         public:
00078                 CArrayDouble<3>   m_coords; //!< The translation vector [x,y,z]
00079                 CMatrixDouble33   m_ROT;    //!< The 3x3 rotation matrix
00080 
00081         protected:
00082                 mutable bool    m_ypr_uptodate;                 //!< Whether yaw/pitch/roll members are up-to-date since the last rotation matrix update.
00083                 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 )
00084 
00085                 /** Rebuild the homog matrix from the angles. */
00086                 void  rebuildRotationMatrix();
00087 
00088                 /** Updates Yaw/pitch/roll members from the m_ROT  */
00089                 inline void updateYawPitchRoll() const { if (!m_ypr_uptodate) { m_ypr_uptodate=true; getYawPitchRoll( m_yaw, m_pitch, m_roll ); } }
00090 
00091          public:
00092                 /** @name Constructors
00093                     @{ */
00094 
00095                 /** Default constructor, with all the coordinates set to zero. */
00096                 CPose3D();
00097 
00098                 /** Constructor with initilization of the pose; (remember that angles are always given in radians!)  */
00099                 CPose3D(const double x,const double  y,const double  z,const double  yaw=0, const double  pitch=0, const double roll=0);
00100 
00101                 /** 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). */
00102                 explicit CPose3D(const math::CMatrixDouble &m);
00103 
00104                 /** Constructor from a 4x4 homogeneous matrix: */
00105                 explicit CPose3D(const math::CMatrixDouble44 &m);
00106 
00107                 /** Constructor from a 3x3 rotation matrix and a the translation given as a 3-vector, a 3-array, a CPoint3D or a TPoint3D */
00108                 template <class MATRIX33,class VECTOR3>
00109                 inline CPose3D(const MATRIX33 &rot, const VECTOR3& xyz) : m_ROT(UNINITIALIZED_MATRIX), m_ypr_uptodate(false)
00110                 {
00111                         ASSERT_EQUAL_(size(rot,1),3); ASSERT_EQUAL_(size(rot,2),3);ASSERT_EQUAL_(xyz.size(),3)
00112                         for (int r=0;r<3;r++)
00113                                 for (int c=0;c<3;c++)
00114                                         m_ROT(r,c)=rot.get_unsafe(r,c);
00115                         for (int r=0;r<3;r++) m_coords[r]=xyz[r];
00116                 }
00117                 //! \overload
00118                 inline CPose3D(const CMatrixDouble33 &rot, const CArrayDouble<3>& xyz) : m_coords(xyz),m_ROT(rot), m_ypr_uptodate(false)
00119                 { }
00120 
00121                 /** Constructor from a CPose2D object.
00122                 */
00123                 CPose3D(const CPose2D &);
00124 
00125                 /** Constructor from a CPoint3D object.
00126                 */
00127                 CPose3D(const CPoint3D &);
00128 
00129                 /** Constructor from lightweight object.
00130                 */
00131                 CPose3D(const mrpt::math::TPose3D &);
00132 
00133                 /** Constructor from a quaternion (which only represents the 3D rotation part) and a 3D displacement. */
00134                 CPose3D(const mrpt::math::CQuaternionDouble &q, const double x, const double y, const double z );
00135 
00136                 /** Constructor from a CPose3DQuat. */
00137                 CPose3D(const CPose3DQuat &);
00138 
00139                 /** Fast constructor that leaves all the data uninitialized - call with UNINITIALIZED_POSE as argument */
00140                 inline CPose3D(TConstructorFlags_Poses constructor_dummy_param) : m_ROT(UNINITIALIZED_MATRIX), m_ypr_uptodate(false) { }
00141 
00142                 /** Constructor from an array with these 12 elements: [r11 r21 r31 r12 r22 r32 r13 r23 r33 tx ty tz]
00143                   *  where r{ij} are the entries of the 3x3 rotation matrix and t{x,y,z} are the 3D translation of the pose
00144                   *  \sa setFrom12Vector, getAs12Vector
00145                   */
00146                 inline explicit CPose3D(const CArrayDouble<12> &vec12) : m_ROT( UNINITIALIZED_MATRIX ), m_ypr_uptodate(false) {
00147                         setFrom12Vector(vec12);
00148                 }
00149 
00150                 /** @} */  // end Constructors
00151 
00152 
00153 
00154                 /** @name Access 3x3 rotation and 4x4 homogeneous matrices
00155                     @{ */
00156 
00157                 /** Returns the corresponding 4x4 homogeneous transformation matrix for the point(translation) or pose (translation+orientation).
00158                   * \sa getInverseHomogeneousMatrix, getRotationMatrix
00159                   */
00160                 inline void  getHomogeneousMatrix(CMatrixDouble44 & out_HM ) const
00161                 {
00162                         out_HM.insertMatrix(0,0,m_ROT);
00163                         for (int i=0;i<3;i++) out_HM(i,3)=m_coords[i];
00164                         out_HM(3,0)=out_HM(3,1)=out_HM(3,2)=0.; out_HM(3,3)=1.;
00165                 }
00166 
00167                 inline CMatrixDouble44 getHomogeneousMatrixVal() const { CMatrixDouble44 M; getHomogeneousMatrix(M); return M;}
00168 
00169                 /** Get the 3x3 rotation matrix \sa getHomogeneousMatrix  */
00170                 inline void getRotationMatrix( mrpt::math::CMatrixDouble33 & ROT ) const { ROT = m_ROT; }
00171                 //! \overload
00172                 inline const mrpt::math::CMatrixDouble33 & getRotationMatrix() const { return m_ROT; }
00173 
00174                 /** @} */  // end rot and HM
00175 
00176 
00177                 /** @name Pose-pose and pose-point compositions and operators
00178                     @{ */
00179 
00180                 /** The operator \f$ a \oplus b \f$ is the pose compounding operator. */
00181                 inline CPose3D  operator + (const CPose3D& b) const
00182                 {
00183                         CPose3D   ret(UNINITIALIZED_POSE);
00184                         ret.composeFrom(*this,b);
00185                         return ret;
00186                 }
00187 
00188                 /** The operator \f$ a \oplus b \f$ is the pose compounding operator. */
00189                 CPoint3D  operator + (const CPoint3D& b) const;
00190 
00191                 /** The operator \f$ a \oplus b \f$ is the pose compounding operator. */
00192                 CPoint3D  operator + (const CPoint2D& b) const;
00193 
00194         /** 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. */
00195         void sphericalCoordinates(
00196             const TPoint3D &point,
00197             double &out_range,
00198             double &out_yaw,
00199             double &out_pitch ) const;
00200 
00201                 /** 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.
00202                   *  If pointers are provided, the corresponding Jacobians are returned.
00203                   *  "out_jacobian_df_dse3" stands for the Jacobian with respect to the 6D locally Euclidean vector in the tangent space of SE(3).
00204                   *  See <a href="http://www.mrpt.org/6D_poses:equivalences_compositions_and_uncertainty" >this report</a> for mathematical details.
00205                   *  \param  If set to true, the Jacobian "out_jacobian_df_dpose" uses a fastest linearized appoximation (valid only for small rotations!).
00206                   */
00207                 void composePoint(double lx,double ly,double lz, double &gx, double &gy, double &gz,
00208                         mrpt::math::CMatrixFixedNumeric<double,3,3>  *out_jacobian_df_dpoint=NULL,
00209                         mrpt::math::CMatrixFixedNumeric<double,3,6>  *out_jacobian_df_dpose=NULL,
00210                         mrpt::math::CMatrixFixedNumeric<double,3,6>  *out_jacobian_df_dse3=NULL,
00211                         bool use_small_rot_approx = false) const;
00212 
00213                 /** 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.
00214                   * \note local_point is passed by value to allow global and local point to be the same variable
00215                   */
00216                 inline void composePoint(const TPoint3D local_point, TPoint3D &global_point) const {
00217                         composePoint(local_point.x,local_point.y,local_point.z,  global_point.x,global_point.y,global_point.z );
00218                 }
00219 
00220                 /** 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.  */
00221                 inline void composePoint(double lx,double ly,double lz, float &gx, float &gy, float &gz ) const {
00222                         double ggx, ggy,ggz;
00223                         composePoint(lx,ly,lz,ggx,ggy,ggz);
00224                         gx = ggx; gy = ggy; gz = ggz;
00225                 }
00226 
00227                 /**  Computes the 3D point L such as \f$ L = G \ominus this \f$.
00228                   *  If pointers are provided, the corresponding Jacobians are returned.
00229                   *  "out_jacobian_df_dse3" stands for the Jacobian with respect to the 6D locally Euclidean vector in the tangent space of SE(3).
00230                   *  See <a href="http://www.mrpt.org/6D_poses:equivalences_compositions_and_uncertainty" >this report</a> for mathematical details.
00231                   * \sa composePoint, composeFrom
00232                   */
00233                 void inverseComposePoint(const double gx,const double gy,const double gz,double &lx,double &ly,double &lz,
00234                         mrpt::math::CMatrixFixedNumeric<double,3,3>  *out_jacobian_df_dpoint=NULL,
00235                         mrpt::math::CMatrixFixedNumeric<double,3,6>  *out_jacobian_df_dpose=NULL,
00236                         mrpt::math::CMatrixFixedNumeric<double,3,6>  *out_jacobian_df_dse3=NULL ) const;
00237 
00238                 /**  Makes "this = A (+) B"; this method is slightly more efficient than "this= A + B;" since it avoids the temporary object.
00239                   *  \note A or B can be "this" without problems.
00240                   */
00241                 void composeFrom(const CPose3D& A, const CPose3D& B );
00242 
00243                 /** Make \f$ this = this \oplus b \f$  (\a b can be "this" without problems) */
00244                 inline CPose3D&  operator += (const CPose3D& b)
00245                 {
00246                         composeFrom(*this,b);
00247                         return *this;
00248                 }
00249 
00250                 /**  Makes \f$ this = A \ominus B \f$ this method is slightly more efficient than "this= A - B;" since it avoids the temporary object.
00251                   *  \note A or B can be "this" without problems.
00252                   * \sa composeFrom, composePoint
00253                   */
00254                 void inverseComposeFrom(const CPose3D& A, const CPose3D& B );
00255 
00256                 /** Compute \f$ RET = this \oplus b \f$  */
00257                 inline CPose3D  operator - (const CPose3D& b) const
00258                 {
00259                         CPose3D ret(UNINITIALIZED_POSE);
00260                         ret.inverseComposeFrom(*this,b);
00261                         return ret;
00262                 }
00263 
00264                 /** Convert this pose into its inverse, saving the result in itself. \sa operator- */
00265                 void inverse();
00266 
00267                 /** makes: this = p (+) this */
00268                 inline void  changeCoordinatesReference( const CPose3D & p ) { composeFrom(p,CPose3D(*this)); }
00269 
00270                 /** @} */  // compositions
00271 
00272 
00273                 /** @name Access and modify contents
00274                         @{ */
00275 
00276                 /** Scalar sum of all 6 components: This is diferent from poses composition, which is implemented as "+" operators.
00277                   * \sa normalizeAngles
00278                   */
00279                 void addComponents(const CPose3D &p);
00280 
00281                 /** Rebuild the internal matrix & update the yaw/pitch/roll angles within the ]-PI,PI] range (Must be called after using addComponents)
00282                   * \sa addComponents
00283                   */
00284                 void  normalizeAngles();
00285 
00286                 /** Scalar multiplication of x,y,z,yaw,pitch & roll (angles will be wrapped to the ]-pi,pi] interval). */
00287                 void operator *=(const double s);
00288 
00289                 /** Set the pose from a 3D position (meters) and yaw/pitch/roll angles (radians) - This method recomputes the internal rotation matrix.
00290                   * \sa getYawPitchRoll, setYawPitchRoll
00291                   */
00292                 void  setFromValues(
00293                         const double            x0,
00294                         const double            y0,
00295                         const double            z0,
00296                         const double            yaw=0,
00297                         const double            pitch=0,
00298                         const double            roll=0);
00299 
00300                 /** 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.
00301                   * \sa setFromValues, getYawPitchRoll, setYawPitchRoll, CQuaternion, getAsQuaternion
00302                   */
00303                 template <typename VECTORLIKE>
00304                 inline void  setFromXYZQ(
00305                         const VECTORLIKE    &v,
00306                         const size_t        index_offset = 0)
00307                 {
00308                         ASSERT_ABOVEEQ_(v.size(), 7+index_offset)
00309                         // The 3x3 rotation part:
00310                         mrpt::math::CQuaternion<typename VECTORLIKE::value_type> q( v[index_offset+3],v[index_offset+4],v[index_offset+5],v[index_offset+6] );
00311                         q.rotationMatrixNoResize(m_ROT);
00312                         m_ypr_uptodate=false;
00313                         m_coords[0] = v[index_offset+0];
00314                         m_coords[1] = v[index_offset+1];
00315                         m_coords[2] = v[index_offset+2];
00316                 }
00317 
00318                 /** Set the 3 angles of the 3D pose (in radians) - This method recomputes the internal rotation coordinates matrix.
00319                   * \sa getYawPitchRoll, setFromValues
00320                   */
00321                 inline void  setYawPitchRoll(
00322                         const double            yaw_,
00323                         const double            pitch_,
00324                         const double            roll_)
00325                 {
00326                         setFromValues(x(),y(),z(),yaw_,pitch_,roll_);
00327                 }
00328 
00329                 /** Set pose from an array with these 12 elements: [r11 r21 r31 r12 r22 r32 r13 r23 r33 tx ty tz]
00330                   *  where r{ij} are the entries of the 3x3 rotation matrix and t{x,y,z} are the 3D translation of the pose
00331                   *  \sa getAs12Vector
00332                   */
00333                 template <class ARRAYORVECTOR>
00334                 inline void setFrom12Vector(const ARRAYORVECTOR &vec12)
00335                 {
00336                         m_ROT.set_unsafe(0,0, vec12[0]); m_ROT.set_unsafe(0,1, vec12[3]); m_ROT.set_unsafe(0,2, vec12[6]);
00337                         m_ROT.set_unsafe(1,0, vec12[1]); m_ROT.set_unsafe(1,1, vec12[4]); m_ROT.set_unsafe(1,2, vec12[7]);
00338                         m_ROT.set_unsafe(2,0, vec12[2]); m_ROT.set_unsafe(2,1, vec12[5]); m_ROT.set_unsafe(2,2, vec12[8]);
00339                         m_coords[0] = vec12[ 9];
00340                         m_coords[1] = vec12[10];
00341                         m_coords[2] = vec12[11];
00342                 }
00343 
00344                 /** Get the pose representation as an array with these 12 elements: [r11 r21 r31 r12 r22 r32 r13 r23 r33 tx ty tz]
00345                   *  where r{ij} are the entries of the 3x3 rotation matrix and t{x,y,z} are the 3D translation of the pose
00346                   *  \sa setFrom12Vector
00347                   */
00348                 template <class ARRAYORVECTOR>
00349                 inline void getAs12Vector(ARRAYORVECTOR &vec12) const
00350                 {
00351                         vec12[0] = m_ROT.get_unsafe(0,0); vec12[3] = m_ROT.get_unsafe(0,1); vec12[6] = m_ROT.get_unsafe(0,2);
00352                         vec12[1] = m_ROT.get_unsafe(1,0); vec12[4] = m_ROT.get_unsafe(1,1); vec12[7] = m_ROT.get_unsafe(1,2);
00353                         vec12[2] = m_ROT.get_unsafe(2,0); vec12[5] = m_ROT.get_unsafe(2,1); vec12[8] = m_ROT.get_unsafe(2,2);
00354                         vec12[ 9] = m_coords[0];
00355                         vec12[10] = m_coords[1];
00356                         vec12[11] = m_coords[2];
00357                 }
00358 
00359                 /** Returns the three angles (yaw, pitch, roll), in radians, from the rotation matrix.
00360                   * \sa setFromValues, yaw, pitch, roll
00361                   */
00362                 void  getYawPitchRoll( double &yaw, double &pitch, double &roll ) const;
00363 
00364                 inline double yaw() const { updateYawPitchRoll(); return m_yaw; }  //!< Get the YAW angle (in radians)  \sa setFromValues
00365                 inline double pitch() const { updateYawPitchRoll(); return m_pitch; }  //!< Get the PITCH angle (in radians) \sa setFromValues
00366                 inline double roll() const { updateYawPitchRoll(); return m_roll; }  //!< Get the ROLL angle (in radians) \sa setFromValues
00367 
00368                 /** Returns a 1x6 vector with [x y z yaw pitch roll] */
00369                 void getAsVector(vector_double &v) const;
00370 
00371                 /** Returns the quaternion associated to the rotation of this object (NOTE: XYZ translation is ignored)
00372                   * \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]
00373                   * With : \f$ \phi = roll \f$,  \f$ \theta = pitch \f$ and \f$ \psi = yaw \f$.
00374                   * \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).
00375                   */
00376                 void getAsQuaternion(
00377                         mrpt::math::CQuaternionDouble &q,
00378                         mrpt::math::CMatrixFixedNumeric<double,4,3>   *out_dq_dr = NULL
00379                         ) const;
00380 
00381                 inline const double &operator[](unsigned int i) const
00382                 {
00383                         updateYawPitchRoll();
00384                         switch(i)
00385                         {
00386                                 case 0:return m_coords[0];
00387                                 case 1:return m_coords[1];
00388                                 case 2:return m_coords[2];
00389                                 case 3:return m_yaw;
00390                                 case 4:return m_pitch;
00391                                 case 5:return m_roll;
00392                                 default:
00393                                 throw std::runtime_error("CPose3D::operator[]: Index of bounds.");
00394                         }
00395                 }
00396                 // CPose3D CANNOT have a write [] operator, since it'd leave the object in an inconsistent state (outdated rotation matrix).
00397                 // Use setFromValues() instead.
00398                 // inline double &operator[](unsigned int i)
00399 
00400                 /** Returns a human-readable textual representation of the object (eg: "[x y z yaw pitch roll]", angles in degrees.)
00401                   * \sa fromString
00402                   */
00403                 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)); }
00404                 inline std::string asString() const { std::string s; asString(s); return s; }
00405 
00406                 /** Set the current object value from a string generated by 'asString' (eg: "[x y z yaw pitch roll]", angles in deg. )
00407                   * \sa asString
00408                   * \exception std::exception On invalid format
00409                   */
00410                 void fromString(const std::string &s) {
00411                         CMatrixDouble  m;
00412                         if (!m.fromMatlabStringFormat(s)) THROW_EXCEPTION("Malformed expression in ::fromString");
00413                         ASSERTMSG_(mrpt::math::size(m,1)==1 && mrpt::math::size(m,2)==6, "Wrong size of vector in ::fromString");
00414                         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)));
00415                  }
00416 
00417                 /** 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). */
00418                 bool isHorizontal( const double tolerance=0) const;
00419 
00420                 /** The euclidean distance between two poses taken as two 6-length vectors (angles in radians). */
00421                 double distanceEuclidean6D( const CPose3D &o ) const;
00422 
00423                 /** @} */  // modif. components
00424 
00425 
00426 
00427                 /** @name Lie Algebra methods
00428                     @{ */
00429 
00430                 /** Exponentiate a Vector in the SE(3) Lie Algebra to generate a new CPose3D (static method).
00431                   * \note Method from TooN (C) Tom Drummond (GNU GPL) */
00432                 static CPose3D exp(const mrpt::math::CArrayNumeric<double,6> & vect);
00433 
00434                 /** Exponentiate a vector in the Lie algebra to generate a new SO(3) (a 3x3 rotation matrix).
00435                   * \note Method from TooN (C) Tom Drummond (GNU GPL) */
00436                 static CMatrixDouble33 exp_rotation(const mrpt::math::CArrayNumeric<double,3> & vect);
00437 
00438 
00439                 /** Take the logarithm of the 3x4 matrix defined by this pose, generating the corresponding vector in the SE(3) Lie Algebra.
00440                   * \note Method from TooN (C) Tom Drummond (GNU GPL)
00441                   * \sa ln_jacob
00442                   */
00443                 void ln(mrpt::math::CArrayDouble<6> &out_ln) const;
00444 
00445                 /// \overload
00446                 inline mrpt::math::CArrayDouble<6> ln() const { mrpt::math::CArrayDouble<6> ret; ln(ret); return ret; }
00447 
00448                 /** Jacobian of the logarithm of the 3x4 matrix defined by this pose.
00449                   * \note Method from TooN (C) Tom Drummond (GNU GPL)
00450                   * \sa ln
00451                   */
00452                 void ln_jacob(mrpt::math::CMatrixFixedNumeric<double,6,12> &J) const;
00453 
00454                 /** Static function to compute the Jacobian of the SO(3) Logarithm function, evaluated at a given 3x3 rotation matrix R.
00455                   * \sa ln, ln_jacob
00456                   */
00457                 static void ln_rot_jacob(const CMatrixDouble33 &R, CMatrixFixedNumeric<double,3,9> &M);
00458 
00459                 /** Take the logarithm of the 3x3 rotation matrix, generating the corresponding vector in the Lie Algebra.
00460                   * \note Method from TooN (C) Tom Drummond (GNU GPL) */
00461                 CArrayDouble<3> ln_rotation() const;
00462 
00463                 /** @} */
00464 
00465                 typedef CPose3D  type_value; //!< Used to emulate CPosePDF types, for example, in mrpt::graphs::CNetworkOfPoses
00466                 enum { is_3D_val = 1 };
00467                 static inline bool is_3D() { return is_3D_val!=0; }
00468                 enum { rotation_dimensions = 3 };
00469                 enum { is_PDF_val = 0 };
00470                 static inline bool is_PDF() { return is_PDF_val!=0; }
00471 
00472                 inline const type_value & getPoseMean() const { return *this; }
00473                 inline       type_value & getPoseMean()       { return *this; }
00474 
00475                 /** @name STL-like methods and typedefs
00476                    @{   */
00477                 typedef double         value_type;              //!< The type of the elements
00478                 typedef double&        reference;
00479                 typedef const double&  const_reference;
00480                 typedef std::size_t    size_type;
00481                 typedef std::ptrdiff_t difference_type;
00482 
00483 
00484                 // size is constant
00485                 enum { static_size = 6 };
00486                 static inline size_type size() { return static_size; }
00487                 static inline bool empty() { return false; }
00488                 static inline size_type max_size() { return static_size; }
00489                 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))); }
00490                 /** @} */
00491 
00492         }; // End of class def.
00493 
00494 
00495         std::ostream BASE_IMPEXP  & operator << (std::ostream& o, const CPose3D& p);
00496 
00497         /** Unary - operator: return the inverse pose "-p" (Note that is NOT the same than a pose with negative x y z yaw pitch roll) */
00498         CPose3D BASE_IMPEXP operator -(const CPose3D &p);
00499 
00500         bool BASE_IMPEXP operator==(const CPose3D &p1,const CPose3D &p2);
00501         bool BASE_IMPEXP operator!=(const CPose3D &p1,const CPose3D &p2);
00502 
00503 
00504         // This is a member of CPose<>, but has to be defined here since in its header CPose3D is not declared yet.
00505         /** The operator \f$ a \ominus b \f$ is the pose inverse compounding operator. */
00506         template <class DERIVEDCLASS> CPose3D CPose<DERIVEDCLASS>::operator -(const CPose3D& b) const
00507         {
00508                 CMatrixDouble44 B_INV(UNINITIALIZED_MATRIX);
00509                 b.getInverseHomogeneousMatrix( B_INV );
00510                 CMatrixDouble44 HM(UNINITIALIZED_MATRIX);
00511                 static_cast<const DERIVEDCLASS*>(this)->getHomogeneousMatrix(HM);
00512                 CMatrixDouble44 RES(UNINITIALIZED_MATRIX);
00513                 RES.multiply(B_INV,HM);
00514                 return CPose3D( RES );
00515         }
00516 
00517 
00518         } // End of namespace
00519 } // End of namespace
00520 
00521 #endif



Page generated by Doxygen 1.7.5 for MRPT 0.9.5 SVN: at Thu Oct 13 21:25:36 UTC 2011