Main MRPT website > C++ reference
MRPT logo
CPose3DRotVec.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 CPOSE3DROTVEC_H
00029 #define CPOSE3DROTVEC_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 CPose3D;
00042         class BASE_IMPEXP CPose3DQuat;
00043 
00044         DEFINE_SERIALIZABLE_PRE( CPose3DRotVec )
00045 
00046         /** A 3D pose (a 3D translation + a rotation in 3D).
00047          *   The 6D transformation in SE(3) stored in this class is kept in two
00048          *   separate containers: a 3-array for the translation, and a 3-array for a rotation vector.
00049          *
00050          *   \code
00051          *    CPose3DRotVec  pose;
00052          *    pose.m_coords[{0:2}]=... // Translation
00053          *    pose.m_rotvec[{0:2}]=... // Rotation vector
00054          *   \endcode
00055          *
00056          *  For a complete descriptionan of Points/Poses, see mrpt::poses::CPoseOrPoint, or refer
00057          *    to the <a href="http://www.mrpt.org/2D_3D_Geometry"> 2D/3D Geometry tutorial</a> online.
00058          *
00059          *  There are Lie algebra methods: \a exp and \a ln (see the methods for documentation).
00060          *
00061          * \ingroup poses_grp
00062          * \sa CPose3DRotVec, CPoseOrPoint,CPoint3D, mrpt::math::CQuaternion
00063          */
00064         class BASE_IMPEXP CPose3DRotVec : public CPose<CPose3DRotVec>, public mrpt::utils::CSerializable
00065         {
00066                 // This must be added to any CSerializable derived class:
00067                 DEFINE_SERIALIZABLE( CPose3DRotVec )
00068 
00069         public:
00070                 CArrayDouble<3>   m_coords; //!< The translation vector [x,y,z]
00071                 CArrayDouble<3>   m_rotvec; //!< The rotation vector [vx,vy,vz]
00072 
00073                 /** @name Constructors
00074                     @{ */
00075 
00076                 /** Default constructor, with all the coordinates set to zero. */
00077                 inline CPose3DRotVec() {
00078                     m_coords[0]=m_coords[1]=m_coords[2]=0;
00079                     m_rotvec[0]=m_rotvec[1]=m_rotvec[2]=0;
00080                 }
00081 
00082                 /** Fast constructor that leaves all the data uninitialized - call with UNINITIALIZED_POSE as argument */
00083                 inline CPose3DRotVec(TConstructorFlags_Poses constructor_dummy_param) : m_coords(),m_rotvec()  { }
00084 
00085                 /** Constructor with initilization of the pose */
00086                 inline CPose3DRotVec(const double x,const double  y,const double  z,const double  vx, const double  vy, const double vz) {
00087                     m_coords[0]= x; m_coords[1]= y; m_coords[2]= z;
00088                     m_rotvec[0]=vx; m_rotvec[1]=vy; m_rotvec[2]=vz;
00089                 }
00090 
00091                 /** Constructor with initilization of the pose from a vector [x y z rx ry rz] */
00092                 inline CPose3DRotVec(const CArrayDouble<6> &v) {
00093                     m_coords[0]=v[0]; m_coords[1]=v[1]; m_coords[2]=v[2];
00094                     m_rotvec[0]=v[3]; m_rotvec[1]=v[4]; m_rotvec[2]=v[5];
00095                 }
00096 
00097                 /** Constructor from a 4x4 homogeneous matrix: */
00098                 explicit CPose3DRotVec(const math::CMatrixDouble44 &m);
00099 
00100                 /** Constructor from a CPose3D object.*/
00101                 explicit CPose3DRotVec(const CPose3D &);
00102 
00103                 /** Constructor from a quaternion (which only represents the 3D rotation part) and a 3D displacement. */
00104                 CPose3DRotVec(const mrpt::math::CQuaternionDouble &q, const double x, const double y, const double z );
00105 
00106                 /** Constructor from an array with these 6 elements: [x y z vx vy vz]
00107                   *  where r{ij} are the entries of the 3x3 rotation matrix and t{x,y,z} are the 3D translation of the pose
00108                   *  \sa setFrom12Vector, getAs12Vector
00109                   */
00110                 inline explicit CPose3DRotVec(const double *vec6) {
00111                     m_coords[0]=vec6[0]; m_coords[1]=vec6[1]; m_coords[2]=vec6[2];
00112                     m_rotvec[0]=vec6[3]; m_rotvec[1]=vec6[4]; m_rotvec[2]=vec6[5];
00113                 }
00114 
00115                 /** @} */  // end Constructors
00116 
00117 
00118                 /** @name Access 3x3 rotation and 4x4 homogeneous matrices
00119                     @{ */
00120 
00121                 /** Returns the corresponding 4x4 homogeneous transformation matrix for the point(translation) or pose (translation+orientation).
00122                   * \sa getInverseHomogeneousMatrix, getRotationMatrix
00123                   */
00124                 inline void  getHomogeneousMatrix(CMatrixDouble44 & out_HM) const {
00125                     out_HM.block<3,3>(0,0) = getRotationMatrix();
00126                     out_HM.get_unsafe(0,3)=m_coords[0];
00127                     out_HM.get_unsafe(1,3)=m_coords[1];
00128                     out_HM.get_unsafe(2,3)=m_coords[2];
00129                     out_HM.get_unsafe(3,0)=0; out_HM.get_unsafe(3,1)=0; out_HM.get_unsafe(3,2)=0; out_HM.get_unsafe(3,3)=1;
00130                 }
00131 
00132                 inline CMatrixDouble44 getHomogeneousMatrixVal() const { CMatrixDouble44 M; getHomogeneousMatrix(M); return M;}
00133 
00134                 /** Get the 3x3 rotation matrix \sa getHomogeneousMatrix  */
00135                 void getRotationMatrix( mrpt::math::CMatrixDouble33 & ROT ) const;
00136                 //! \overload
00137                 inline const mrpt::math::CMatrixDouble33 getRotationMatrix() const { mrpt::math::CMatrixDouble33 ROT(UNINITIALIZED_MATRIX); getRotationMatrix(ROT); return ROT; }
00138 
00139                 /** @} */  // end rot and HM
00140 
00141 
00142                 /** @name Pose-pose and pose-point compositions and operators
00143                     @{ */
00144 
00145                 /** The operator \f$ a \oplus b \f$ is the pose compounding operator. */
00146                 inline CPose3DRotVec  operator + (const CPose3DRotVec& b) const
00147                 {
00148                         CPose3DRotVec ret(UNINITIALIZED_POSE);
00149                         ret.composeFrom(*this,b);
00150                         return ret;
00151                 }
00152 
00153                 /** The operator \f$ a \oplus b \f$ is the pose compounding operator. */
00154                 CPoint3D  operator + (const CPoint3D& b) const;
00155 
00156                 /** The operator \f$ a \oplus b \f$ is the pose compounding operator. */
00157                 CPoint3D  operator + (const CPoint2D& b) const;
00158 
00159         /** Computes the spherical coordinates of a 3D point as seen from the 6D pose specified by this object. For the coordinate system see mrpt::poses::CPose3D */
00160         void sphericalCoordinates(
00161             const TPoint3D &point,
00162             double &out_range,
00163             double &out_yaw,
00164             double &out_pitch ) const;
00165 
00166                 /** 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.
00167                   *  If pointers are provided, the corresponding Jacobians are returned.
00168                   *  See <a href="http://www.mrpt.org/6D_poses:equivalences_compositions_and_uncertainty" >this report</a> for mathematical details.
00169                   */
00170                 void composePoint(double lx,double ly,double lz, double &gx, double &gy, double &gz,
00171                         mrpt::math::CMatrixFixedNumeric<double,3,3>  *out_jacobian_df_dpoint=NULL,
00172                         mrpt::math::CMatrixFixedNumeric<double,3,6>  *out_jacobian_df_dpose=NULL) const;
00173 
00174                 /** 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.
00175                   * \note local_point is passed by value to allow global and local point to be the same variable
00176                   */
00177                 inline void composePoint(const TPoint3D local_point, TPoint3D &global_point) const {
00178                         composePoint(local_point.x,local_point.y,local_point.z,  global_point.x,global_point.y,global_point.z );
00179                 }
00180 
00181                 /**  Computes the 3D point L such as \f$ L = G \ominus this \f$.
00182                   *  If pointers are provided, the corresponding Jacobians are returned.
00183                   *  See <a href="http://www.mrpt.org/6D_poses:equivalences_compositions_and_uncertainty" >this report</a> for mathematical details.
00184                   * \sa composePoint, composeFrom
00185                   */
00186                 void inverseComposePoint(const double gx,const double gy,const double gz,double &lx,double &ly,double &lz,
00187                         mrpt::math::CMatrixFixedNumeric<double,3,3>  *out_jacobian_df_dpoint=NULL,
00188                         mrpt::math::CMatrixFixedNumeric<double,3,6>  *out_jacobian_df_dpose=NULL) const;
00189 
00190                 /**  Makes "this = A (+) B"; this method is slightly more efficient than "this= A + B;" since it avoids the temporary object.
00191                   *  \note A or B can be "this" without problems.
00192                   */
00193                 void composeFrom(const CPose3DRotVec& A, const CPose3DRotVec& B );
00194 
00195                 /** Make \f$ this = this \oplus b \f$  (\a b can be "this" without problems) */
00196                 inline CPose3DRotVec&  operator += (const CPose3DRotVec& b)
00197                 {
00198                         composeFrom(*this,b);
00199                         return *this;
00200                 }
00201 
00202                 /**  Makes \f$ this = A \ominus B \f$ this method is slightly more efficient than "this= A - B;" since it avoids the temporary object.
00203                   *  \note A or B can be "this" without problems.
00204                   * \sa composeFrom, composePoint
00205                   */
00206                 void inverseComposeFrom(const CPose3DRotVec& A, const CPose3DRotVec& B );
00207 
00208                 /** Compute \f$ RET = this \oplus b \f$  */
00209                 inline CPose3DRotVec  operator - (const CPose3DRotVec& b) const
00210                 {
00211                         CPose3DRotVec ret(UNINITIALIZED_POSE);
00212                         ret.inverseComposeFrom(*this,b);
00213                         return ret;
00214                 }
00215 
00216                 /** Convert this pose into its inverse, saving the result in itself. \sa operator- */
00217                 void inverse();
00218 
00219                 /** makes: this = p (+) this */
00220                 inline void  changeCoordinatesReference( const CPose3DRotVec & p ) { composeFrom(p,CPose3DRotVec(*this)); }
00221 
00222                 /** @} */  // compositions
00223 
00224 
00225                 /** @name Access and modify contents
00226                         @{ */
00227 
00228         inline double rx() const { return m_rotvec[0]; }
00229         inline double ry() const { return m_rotvec[1]; }
00230         inline double rz() const { return m_rotvec[2]; }
00231 
00232         inline double &rx() { return m_rotvec[0]; }
00233         inline double &ry() { return m_rotvec[1]; }
00234         inline double &rz() { return m_rotvec[2]; }
00235 
00236                 /** Scalar sum of all 6 components: This is diferent from poses composition, which is implemented as "+" operators. */
00237                 inline void addComponents(const CPose3DRotVec &p) {
00238                     m_coords+=p.m_coords;
00239                     m_rotvec+=p.m_rotvec;
00240         }
00241 
00242                 /** Scalar multiplication of x,y,z,vx,vy,vz. */
00243                 inline void operator *=(const double s) {
00244             m_coords*=s;
00245             m_rotvec*=s;
00246                 }
00247 
00248                 /** Set the pose from a 3D position (meters) and yaw/pitch/roll angles (radians) - This method recomputes the internal rotation matrix.
00249                   * \sa getYawPitchRoll, setYawPitchRoll
00250                   */
00251                 void  setFromValues(
00252                         const double            x0,
00253                         const double            y0,
00254                         const double            z0,
00255                         const double            vx,
00256                         const double            vy,
00257                         const double            vz )
00258         {
00259             m_coords[0]=x0; m_coords[1]=y0; m_coords[2]=z0;
00260             m_rotvec[0]=vx; m_rotvec[1]=vy; m_rotvec[2]=vz;
00261         }
00262 
00263                 /** Set pose from an array with these 6 elements: [x y z vx vy vz]
00264                   *  where v{xyz} is the rotation vector and {xyz} the 3D translation of the pose
00265                   *  \sa getAs6Vector
00266                   */
00267                 template <class ARRAYORVECTOR>
00268                 inline void setFrom6Vector(const ARRAYORVECTOR &vec6)
00269                 {
00270                     m_rotvec[0]=vec6[3]; m_rotvec[1]=vec6[4]; m_rotvec[2]=vec6[5];
00271                     m_coords[0]=vec6[0]; m_coords[1]=vec6[1]; m_coords[2]=vec6[2];
00272                 }
00273 
00274                 /** Gets pose as an array with these 6 elements: [x y z vx vy vz]
00275                   *  where v{xyz} is the rotation vector and {xyz} the 3D translation of the pose
00276                   *  The target vector MUST ALREADY have space for 6 elements (i.e. no .resize() method will be called).
00277                   *  \sa setAs6Vector, getAsVector
00278                   */
00279                 template <class ARRAYORVECTOR>
00280                 inline void getAs6Vector(ARRAYORVECTOR &vec6) const
00281                 {
00282                     vec6[0]=m_coords[0]; vec6[1]=m_coords[1]; vec6[2]=m_coords[2];
00283                     vec6[3]=m_rotvec[0]; vec6[4]=m_rotvec[1]; vec6[5]=m_rotvec[2];
00284                 }
00285 
00286                 /** Like getAs6Vector() but for dynamic size vectors (required by base class CPoseOrPoint) */
00287                 template <class ARRAYORVECTOR>
00288                 inline void getAsVector(ARRAYORVECTOR &v) const { v.resize(6); getAs6Vector(v); }
00289 
00290                 inline const double &operator[](unsigned int i) const
00291                 {
00292                         switch(i)
00293                         {
00294                                 case 0:return m_coords[0];
00295                                 case 1:return m_coords[1];
00296                                 case 2:return m_coords[2];
00297                                 case 3:return m_rotvec[0];
00298                                 case 4:return m_rotvec[1];
00299                                 case 5:return m_rotvec[2];
00300                                 default:
00301                                 throw std::runtime_error("CPose3DRotVec::operator[]: Index of bounds.");
00302                         }
00303                 }
00304                 inline double &operator[](unsigned int i)
00305                 {
00306                         switch(i)
00307                         {
00308                                 case 0:return m_coords[0];
00309                                 case 1:return m_coords[1];
00310                                 case 2:return m_coords[2];
00311                                 case 3:return m_rotvec[0];
00312                                 case 4:return m_rotvec[1];
00313                                 case 5:return m_rotvec[2];
00314                                 default:
00315                                 throw std::runtime_error("CPose3DRotVec::operator[]: Index of bounds.");
00316                         }
00317                 }
00318 
00319                 /** Returns a human-readable textual representation of the object: "[x y z rx ry rz]"
00320                   * \sa fromString
00321                   */
00322                 void asString(std::string &s) const { s = mrpt::format("[%f %f %f %f %f %f]",m_coords[0],m_coords[1],m_coords[2],m_rotvec[0],m_rotvec[1],m_rotvec[2]); }
00323                 inline std::string asString() const { std::string s; asString(s); return s; }
00324 
00325                 /** Set the current object value from a string generated by 'asString' (eg: "[x y z yaw pitch roll]", angles in deg. )
00326                   * \sa asString
00327                   * \exception std::exception On invalid format
00328                   */
00329                 void fromString(const std::string &s) {
00330                         CMatrixDouble  m;
00331                         if (!m.fromMatlabStringFormat(s)) THROW_EXCEPTION("Malformed expression in ::fromString");
00332                         ASSERTMSG_(mrpt::math::size(m,1)==1 && mrpt::math::size(m,2)==6, "Wrong size of vector in ::fromString");
00333                         for (int i=0;i<3;i++) m_coords[i]=m.get_unsafe(0,i);
00334                         for (int i=0;i<3;i++) m_rotvec[i]=m.get_unsafe(0,3+i);
00335                  }
00336 
00337                 /** @} */  // modif. components
00338 
00339 
00340                 /** @name Lie Algebra methods
00341                     @{ */
00342 
00343                 /** Exponentiate a Vector in the SE(3) Lie Algebra to generate a new CPose3DRotVec (static method). */
00344                 static CPose3DRotVec exp(const mrpt::math::CArrayDouble<6> & vect);
00345 
00346                 /** Take the logarithm of the 3x4 matrix defined by this pose, generating the corresponding vector in the SE(3) Lie Algebra. */
00347                 void ln(mrpt::math::CArrayDouble<6> &out_ln) const;
00348 
00349                 /** Take the logarithm of the 3x3 rotation matrix part of this pose, generating the corresponding vector in the Lie Algebra. */
00350                 CArrayDouble<3> ln_rotation() const;
00351 
00352                 /** @} */
00353 
00354                 typedef CPose3DRotVec  type_value; //!< Used to emulate CPosePDF types, for example, in mrpt::graphs::CNetworkOfPoses
00355                 enum { is_3D_val = 1 };
00356                 static inline bool is_3D() { return is_3D_val!=0; }
00357                 enum { rotation_dimensions = 3 };
00358                 enum { is_PDF_val = 0 };
00359                 static inline bool is_PDF() { return is_PDF_val!=0; }
00360 
00361                 inline const type_value & getPoseMean() const { return *this; }
00362                 inline       type_value & getPoseMean()       { return *this; }
00363 
00364                 /** @name STL-like methods and typedefs
00365                    @{   */
00366                 typedef double         value_type;              //!< The type of the elements
00367                 typedef double&        reference;
00368                 typedef const double&  const_reference;
00369                 typedef std::size_t    size_type;
00370                 typedef std::ptrdiff_t difference_type;
00371 
00372 
00373                 // size is constant
00374                 enum { static_size = 6 };
00375                 static inline size_type size() { return static_size; }
00376                 static inline bool empty() { return false; }
00377                 static inline size_type max_size() { return static_size; }
00378                 static inline void resize(const size_t n) { if (n!=static_size) throw std::logic_error(format("Try to change the size of CPose3DRotVec to %u.",static_cast<unsigned>(n))); }
00379                 /** @} */
00380 
00381         }; // End of class def.
00382 
00383 
00384         std::ostream BASE_IMPEXP  & operator << (std::ostream& o, const CPose3DRotVec& p);
00385 
00386         /** Unary - operator: return the inverse pose "-p" (Note that is NOT the same than a pose with negative x y z yaw pitch roll) */
00387         CPose3DRotVec BASE_IMPEXP operator -(const CPose3DRotVec &p);
00388 
00389         bool BASE_IMPEXP operator==(const CPose3DRotVec &p1,const CPose3DRotVec &p2);
00390         bool BASE_IMPEXP operator!=(const CPose3DRotVec &p1,const CPose3DRotVec &p2);
00391 
00392 
00393         } // End of namespace
00394 } // End of namespace
00395 
00396 #endif



Page generated by Doxygen 1.7.4 for MRPT 0.9.5 SVN:2717 at Sun Oct 16 16:08:03 PDT 2011 Hosted on:
SourceForge.net Logo