Main MRPT website > C++ reference
MRPT logo
CPose3DQuat.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 CPose3DQuat_H
00029 #define CPose3DQuat_H
00030 
00031 #include <mrpt/poses/CPose.h>
00032 #include <mrpt/math/CMatrixFixedNumeric.h>
00033 #include <mrpt/math/CQuaternion.h>
00034 #include <mrpt/poses/CPoint3D.h>
00035 #include <mrpt/math/lightweight_geom_data.h>
00036 
00037 namespace mrpt
00038 {
00039 namespace poses
00040 {
00041         using namespace mrpt::math;
00042 
00043         class CPose3D;
00044 
00045         DEFINE_SERIALIZABLE_PRE( CPose3DQuat )
00046 
00047         /** A class used to store a 3D pose as a translation (x,y,z) and a quaternion (qr,qx,qy,qz).
00048          *
00049          *  For a complete description of Points/Poses, see mrpt::poses::CPoseOrPoint, or refer
00050          *    to the <a href="http://www.mrpt.org/2D_3D_Geometry"> 2D/3D Geometry tutorial</a> in the wiki.
00051          *
00052          *  To access the translation use x(), y() and z(). To access the rotation, use CPose3DQuat::quat().
00053          *
00054          *  This class also behaves like a STL container, since it has begin(), end(), iterators, and can be accessed with the [] operator
00055          *   with indices running from 0 to 6 to access the  [x y z qr qx qy qz] as if they were a vector. Thus, a CPose3DQuat can be used
00056          *   as a 7-vector anywhere the MRPT math functions expect any kind of vector.
00057          *
00058          *  This class and CPose3D are very similar, and they can be converted to the each other automatically via transformation constructors.
00059          *
00060          * \sa CPose3D (for a class based on a 4x4 matrix instead of a quaternion), mrpt::math::TPose3DQuat, mrpt::poses::CPose3DQuatPDF for a probabilistic version of this class,  mrpt::math::CQuaternion, CPoseOrPoint
00061          * \ingroup poses_grp
00062          */
00063         class BASE_IMPEXP CPose3DQuat : public CPose<CPose3DQuat>, public mrpt::utils::CSerializable
00064         {
00065                 // This must be added to any CSerializable derived class:
00066                 DEFINE_SERIALIZABLE( CPose3DQuat )
00067 
00068         public:
00069                 CArrayDouble<3>                 m_coords; //!< The translation vector [x,y,z]
00070                 mrpt::math::CQuaternionDouble   m_quat;   //!< The quaternion.
00071 
00072         public:
00073                 /** Read/Write access to the quaternion representing the 3D rotation. */
00074                 inline       mrpt::math::CQuaternionDouble & quat()       { return m_quat; }
00075                 /** Read-only access to the quaternion representing the 3D rotation. */
00076                 inline const mrpt::math::CQuaternionDouble & quat() const { return m_quat; }
00077 
00078                 /** Read/Write access to the translation vector in R^3. */
00079                 inline       mrpt::math::CArrayDouble<3> & xyz()       { return m_coords; }
00080                 /** Read-only access to the translation vector in R^3. */
00081                 inline const mrpt::math::CArrayDouble<3> & xyz() const { return m_coords; }
00082 
00083 
00084                 /** Default constructor, initialize translation to zeros and quaternion to no rotation. */
00085                 inline CPose3DQuat() : m_quat() { m_coords[0]=m_coords[1]=m_coords[2]=0.; }
00086 
00087                 /** Constructor which left all the quaternion members un-initialized, for use when speed is critical; Use UNINITIALIZED_POSE as argument to this constructor. */
00088                 inline CPose3DQuat(TConstructorFlags_Quaternions constructor_dummy_param) : m_quat(UNINITIALIZED_QUATERNION) { }
00089 
00090                 /** Constructor with initilization of the pose - the quaternion is normalized to make sure it's unitary */
00091                 inline CPose3DQuat(const double x,const double y,const double z,const mrpt::math::CQuaternionDouble &q ) : m_quat(q) { m_coords[0]=x; m_coords[1]=y; m_coords[2]=z; m_quat.normalize(); }
00092 
00093                 /** Constructor from a CPose3D */
00094                 explicit CPose3DQuat(const CPose3D &p);
00095 
00096                 /** Constructor from lightweight object. */
00097                 CPose3DQuat(const mrpt::math::TPose3DQuat &p) : m_quat(p.qr,p.qx,p.qy,p.qz) { x()=p.x; y()=p.y; z()=p.z; }
00098 
00099                 /** Constructor from a 4x4 homogeneous transformation matrix.
00100                   */
00101                 explicit CPose3DQuat(const CMatrixDouble44 &M);
00102 
00103                 /** Returns the corresponding 4x4 homogeneous transformation matrix for the point(translation) or pose (translation+orientation).
00104                   * \sa getInverseHomogeneousMatrix
00105                   */
00106                 void  getHomogeneousMatrix(CMatrixDouble44 & out_HM ) const;
00107 
00108                 /** Returns a 1x7 vector with [x y z qr qx qy qz] */
00109                 void getAsVector(vector_double &v) const;
00110 
00111                 /**  Makes \f$ this = A \oplus B \f$  this method is slightly more efficient than "this= A + B;" since it avoids the temporary object.
00112                   *  \note A or B can be "this" without problems.
00113                   * \sa inverseComposeFrom, composePoint
00114                   */
00115                 void composeFrom(const CPose3DQuat& A, const CPose3DQuat& B );
00116 
00117                 /**  Makes \f$ this = A \ominus B \f$ this method is slightly more efficient than "this= A - B;" since it avoids the temporary object.
00118                   *  \note A or B can be "this" without problems.
00119                   * \sa composeFrom, composePoint
00120                   */
00121                 void inverseComposeFrom(const CPose3DQuat& A, const CPose3DQuat& B );
00122 
00123                 /**  Computes the 3D point G such as \f$ G = this \oplus L \f$.
00124                   * \sa composeFrom, inverseComposePoint
00125                   */
00126                 void composePoint(const double lx,const double ly,const double lz,double &gx,double &gy,double &gz,
00127                          mrpt::math::CMatrixFixedNumeric<double,3,3>  *out_jacobian_df_dpoint = NULL,
00128                          mrpt::math::CMatrixFixedNumeric<double,3,7>  *out_jacobian_df_dpose = NULL ) const;
00129 
00130                 /**  Computes the 3D point L such as \f$ L = G \ominus this \f$.
00131                   * \sa composePoint, composeFrom
00132                   */
00133                 void inverseComposePoint(const double gx,const double gy,const double gz,double &lx,double &ly,double &lz,
00134                          mrpt::math::CMatrixFixedNumeric<double,3,3>  *out_jacobian_df_dpoint = NULL,
00135                          mrpt::math::CMatrixFixedNumeric<double,3,7>  *out_jacobian_df_dpose = NULL ) const;
00136 
00137                 /**  Computes the 3D point G such as \f$ G = this \oplus L \f$.
00138                   *  POINT1 and POINT1 can be anything supporing [0],[1],[2].
00139                   * \sa composePoint    */
00140                 template <class POINT1,class POINT2> inline void composePoint( const POINT1 &L, POINT2 &G) const { composePoint(L[0],L[1],L[2], G[0],G[1],G[2]); }
00141 
00142                 /**  Computes the 3D point L such as \f$ L = G \ominus this \f$.  \sa inverseComposePoint */
00143                 template <class POINT1,class POINT2> inline void inverseComposePoint( const POINT1 &G, POINT2 &L) const { inverseComposePoint(G[0],G[1],G[2],L[0],L[1],L[2]); }
00144 
00145                 /**  Computes the 3D point G such as \f$ G = this \oplus L \f$.  \sa composePoint    */
00146                 inline CPoint3D operator +( const CPoint3D &L) const { CPoint3D G; composePoint(L[0],L[1],L[2], G[0],G[1],G[2]); return G; }
00147 
00148                 /**  Computes the 3D point G such as \f$ G = this \oplus L \f$.  \sa composePoint    */
00149                 inline TPoint3D operator +( const TPoint3D &L) const { TPoint3D G; composePoint(L[0],L[1],L[2], G[0],G[1],G[2]); return G; }
00150 
00151                 /**  Computes the 3D point L such as \f$ L = G \ominus this \f$.  \sa inverseComposePoint    */
00152                 inline CPoint3D operator -( const CPoint3D &G) const { CPoint3D L; inverseComposePoint(G[0],G[1],G[2], L[0],L[1],L[2]); return L; }
00153 
00154                 /**  Computes the 3D point L such as \f$ L = G \ominus this \f$.  \sa inverseComposePoint    */
00155                 inline TPoint3D operator -( const TPoint3D &G) const { TPoint3D L; inverseComposePoint(G[0],G[1],G[2], L[0],L[1],L[2]); return L; }
00156 
00157                 /** Scalar multiplication (all x y z qr qx qy qz elements are multiplied by the scalar).
00158                   */
00159                 virtual void operator *=(const double  s);
00160 
00161                 /** Make \f$ this = this \oplus b \f$  */
00162                 inline CPose3DQuat&  operator += (const CPose3DQuat& b)
00163                 {
00164                         composeFrom(*this,b);
00165                         return *this;
00166                 }
00167 
00168                 /** Return the composed pose \f$ ret = this \oplus p \f$  */
00169                 inline CPose3DQuat operator + (const CPose3DQuat& p) const
00170                 {
00171                         CPose3DQuat ret;
00172                         ret.composeFrom(*this,p);
00173                         return ret;
00174                 }
00175 
00176                 /** Make \f$ this = this \ominus b \f$  */
00177                 inline CPose3DQuat&  operator -= (const CPose3DQuat& b)
00178                 {
00179                         inverseComposeFrom(*this,b);
00180                         return *this;
00181                 }
00182 
00183                 /** Return the composed pose \f$ ret = this \ominus p \f$  */
00184                 inline CPose3DQuat operator - (const CPose3DQuat& p) const
00185                 {
00186                         CPose3DQuat ret;
00187                         ret.inverseComposeFrom(*this,p);
00188                         return ret;
00189                 }
00190 
00191                  /** Returns a human-readable textual representation of the object (eg: "[x y z qr qx qy qz]", angles in degrees.)
00192                    * \sa fromString
00193                    */
00194                 void asString(std::string &s) const { s = mrpt::format("[%f %f %f %f %f %f %f]",m_coords[0],m_coords[1],m_coords[2],m_quat[0],m_quat[1],m_quat[2],m_quat[3]); }
00195                 inline std::string asString() const { std::string s; asString(s); return s; }
00196 
00197                  /** Set the current object value from a string generated by 'asString' (eg: "[0.02 1.04 -0.8 1 0 0 0]" )
00198                    * \sa asString
00199                    * \exception std::exception On invalid format
00200                    */
00201                  void fromString(const std::string &s) {
00202                         CMatrixDouble  m;
00203                         if (!m.fromMatlabStringFormat(s)) THROW_EXCEPTION("Malformed expression in ::fromString");
00204                         ASSERTMSG_(mrpt::math::size(m,1)==1 && mrpt::math::size(m,2)==7, "Wrong size of vector in ::fromString");
00205                         m_coords[0] = m.get_unsafe(0,0); m_coords[1] = m.get_unsafe(0,1); m_coords[2] = m.get_unsafe(0,2);
00206                         m_quat[0] = m.get_unsafe(0,3); m_quat[1] = m.get_unsafe(0,4); m_quat[2] = m.get_unsafe(0,5); m_quat[3] = m.get_unsafe(0,6);
00207                  }
00208 
00209                 /** Read only [] operator */
00210                 inline const double &operator[](unsigned int i) const
00211                 {
00212                         switch(i)
00213                         {
00214                                 case 0:return m_coords[0];
00215                                 case 1:return m_coords[1];
00216                                 case 2:return m_coords[2];
00217                                 case 3:return m_quat[0];
00218                                 case 4:return m_quat[1];
00219                                 case 5:return m_quat[2];
00220                                 case 6:return m_quat[3];
00221                                 default:
00222                                 throw std::runtime_error("CPose3DQuat::operator[]: Index of bounds.");
00223                         }
00224                 }
00225                 /** Read/write [] operator */
00226                 inline double &operator[](unsigned int i)
00227                 {
00228                         switch(i)
00229                         {
00230                                 case 0:return m_coords[0];
00231                                 case 1:return m_coords[1];
00232                                 case 2:return m_coords[2];
00233                                 case 3:return m_quat[0];
00234                                 case 4:return m_quat[1];
00235                                 case 5:return m_quat[2];
00236                                 case 6:return m_quat[3];
00237                                 default:
00238                                 throw std::runtime_error("CPose3DQuat::operator[]: Index of bounds.");
00239                         }
00240                 }
00241 
00242         /** Computes the spherical coordinates of a 3D point as seen from the 6D pose specified by this object.
00243           *  For the coordinate system see the top of this page.
00244                   *  If the matrix pointers are not NULL, the Jacobians will be also computed for the range-yaw-pitch variables wrt the passed 3D point and this 7D pose.
00245           */
00246         void sphericalCoordinates(
00247             const TPoint3D &point,
00248             double &out_range,
00249             double &out_yaw,
00250             double &out_pitch,
00251                         mrpt::math::CMatrixFixedNumeric<double,3,3> *out_jacob_dryp_dpoint = NULL,
00252                         mrpt::math::CMatrixFixedNumeric<double,3,7> *out_jacob_dryp_dpose = NULL
00253                         ) const;
00254 
00255         public:
00256                 typedef CPose3DQuat type_value; //!< Used to emulate CPosePDF types, for example, in mrpt::graphs::CNetworkOfPoses
00257                 enum { is_3D_val = 1 };
00258                 static inline bool is_3D() { return is_3D_val!=0; }
00259                 enum { rotation_dimensions = 3 };
00260                 enum { is_PDF_val = 1 };
00261                 static inline bool is_PDF() { return is_PDF_val!=0; }
00262 
00263                 inline const type_value & getPoseMean() const { return *this; }
00264                 inline       type_value & getPoseMean()       { return *this; }
00265 
00266                 /** @name STL-like methods and typedefs
00267                    @{   */
00268                 typedef double         value_type;              //!< The type of the elements
00269                 typedef double&        reference;
00270                 typedef const double&  const_reference;
00271                 typedef std::size_t    size_type;
00272                 typedef std::ptrdiff_t difference_type;
00273 
00274                 // size is constant
00275                 enum { static_size = 7 };
00276                 static inline size_type size() { return static_size; }
00277                 static inline bool empty() { return false; }
00278                 static inline size_type max_size() { return static_size; }
00279                 static inline void resize(const size_t n) { if (n!=static_size) throw std::logic_error(format("Try to change the size of CPose3DQuat to %u.",static_cast<unsigned>(n))); }
00280 
00281                 inline void assign(const size_t N, const double val)
00282                 {
00283                         if (N!=7) throw std::runtime_error("CPose3DQuat::assign: Try to resize to length!=7.");
00284                         m_coords.fill(val);
00285                         m_quat.fill(val);
00286                 }
00287 
00288                 struct iterator : public std::iterator<std::random_access_iterator_tag,value_type>
00289                 {
00290                 private:
00291                         typedef std::iterator<std::random_access_iterator_tag,value_type> iterator_base;
00292                         CPose3DQuat *m_obj;             //!< A reference to the source of this iterator
00293                         size_t          m_cur_idx;      //!< The iterator points to this element.
00294                         typedef value_type T; //!< The type of the matrix elements
00295 
00296                         inline void check_limits(bool allow_end = false) const
00297                         {
00298         #ifdef _DEBUG
00299                                 ASSERTMSG_(m_obj!=NULL,"non initialized iterator");
00300                                 if (m_cur_idx> (allow_end ? 7u : 6u) ) THROW_EXCEPTION("Index out of range in iterator.")
00301         #endif
00302                         }
00303                 public:
00304                         inline bool operator <(const iterator &it2) const { return m_cur_idx < it2.m_cur_idx; }
00305                         inline bool operator >(const iterator &it2) const { return m_cur_idx > it2.m_cur_idx; }
00306                         inline iterator() : m_obj(NULL),m_cur_idx(0) { }
00307                         inline iterator(CPose3DQuat &obj, size_t start_idx) : m_obj(&obj),m_cur_idx(start_idx) {  check_limits(true); /*Dont report as error an iterator to end()*/ }
00308                         inline CPose3DQuat::reference operator*() const {  check_limits();  return (*m_obj)[m_cur_idx];  }
00309                         inline iterator &operator++() {
00310                                 check_limits();
00311                                 ++m_cur_idx;
00312                                 return *this;
00313                         }
00314                         inline iterator operator++(int) {
00315                                 iterator it=*this;
00316                                 ++*this;
00317                                 return it;
00318                         }
00319                         inline iterator &operator--()   {
00320                                 --m_cur_idx;
00321                                 check_limits();
00322                                 return *this;
00323                         }
00324                         inline iterator operator--(int) {
00325                                 iterator it=*this;
00326                                 --*this;
00327                                 return it;
00328                         }
00329                         inline iterator &operator+=(iterator_base::difference_type off) {
00330                                 m_cur_idx+=off;
00331                                 check_limits(true);
00332                                 return *this;
00333                         }
00334                         inline iterator operator+(iterator_base::difference_type off) const     {
00335                                 iterator it=*this;
00336                                 it+=off;
00337                                 return it;
00338                         }
00339                         inline iterator &operator-=(iterator_base::difference_type off) {
00340                                 return (*this)+=(-off);
00341                         }
00342                         inline iterator operator-(iterator_base::difference_type off) const     {
00343                                 iterator it=*this;
00344                                 it-=off;
00345                                 return it;
00346                         }
00347                         inline iterator_base::difference_type operator-(const iterator &it) const       { return m_cur_idx - it.m_cur_idx; }
00348                         inline CPose3DQuat::reference operator[](iterator_base::difference_type off) const { return (*m_obj)[m_cur_idx+off]; }
00349                         inline bool operator==(const iterator &it) const { return m_obj==it.m_obj && m_cur_idx==it.m_cur_idx; }
00350                         inline bool operator!=(const iterator &it) const { return !(operator==(it)); }
00351                 }; // end iterator
00352 
00353                 struct const_iterator : public std::iterator<std::random_access_iterator_tag,value_type>
00354                 {
00355                 private:
00356                         typedef std::iterator<std::random_access_iterator_tag,value_type> iterator_base;
00357                         const CPose3DQuat *m_obj;               //!< A reference to the source of this iterator
00358                         size_t          m_cur_idx;      //!< The iterator points to this element.
00359                         typedef value_type T; //!< The type of the matrix elements
00360 
00361                         inline void check_limits(bool allow_end = false) const
00362                         {
00363         #ifdef _DEBUG
00364                                 ASSERTMSG_(m_obj!=NULL,"non initialized iterator");
00365                                 if (m_cur_idx> (allow_end ? 7u : 6u) ) THROW_EXCEPTION("Index out of range in iterator.")
00366         #endif
00367                         }
00368                 public:
00369                         inline bool operator <(const const_iterator &it2) const { return m_cur_idx < it2.m_cur_idx; }
00370                         inline bool operator >(const const_iterator &it2) const { return m_cur_idx > it2.m_cur_idx; }
00371                         inline const_iterator() : m_obj(NULL),m_cur_idx(0) { }
00372                         inline const_iterator(const CPose3DQuat &obj, size_t start_idx) : m_obj(&obj),m_cur_idx(start_idx) {  check_limits(true); /*Dont report as error an iterator to end()*/ }
00373                         inline CPose3DQuat::const_reference operator*() const   {  check_limits();  return (*m_obj)[m_cur_idx];  }
00374                         inline const_iterator &operator++() {
00375                                 check_limits();
00376                                 ++m_cur_idx;
00377                                 return *this;
00378                         }
00379                         inline const_iterator operator++(int)   {
00380                                 const_iterator it=*this;
00381                                 ++*this;
00382                                 return it;
00383                         }
00384                         inline const_iterator &operator--()     {
00385                                 --m_cur_idx;
00386                                 check_limits();
00387                                 return *this;
00388                         }
00389                         inline const_iterator operator--(int)   {
00390                                 const_iterator it=*this;
00391                                 --*this;
00392                                 return it;
00393                         }
00394                         inline const_iterator &operator+=(iterator_base::difference_type off)   {
00395                                 m_cur_idx+=off;
00396                                 check_limits(true);
00397                                 return *this;
00398                         }
00399                         inline const_iterator operator+(iterator_base::difference_type off) const       {
00400                                 const_iterator it=*this;
00401                                 it+=off;
00402                                 return it;
00403                         }
00404                         inline const_iterator &operator-=(iterator_base::difference_type off)   {
00405                                 return (*this)+=(-off);
00406                         }
00407                         inline const_iterator operator-(iterator_base::difference_type off) const       {
00408                                 const_iterator it=*this;
00409                                 it-=off;
00410                                 return it;
00411                         }
00412                         inline iterator_base::difference_type operator-(const const_iterator &it) const { return m_cur_idx - it.m_cur_idx; }
00413                         inline CPose3DQuat::const_reference operator[](iterator_base::difference_type off) const { return (*m_obj)[m_cur_idx+off]; }
00414                         inline bool operator==(const const_iterator &it) const { return m_obj==it.m_obj && m_cur_idx==it.m_cur_idx; }
00415                         inline bool operator!=(const const_iterator &it) const { return !(operator==(it)); }
00416                 }; // end const_iterator
00417 
00418                 typedef std::reverse_iterator<iterator>                 reverse_iterator;
00419                 typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
00420                 inline iterator                 begin()   { return iterator(*this,0); }
00421                 inline iterator                 end()     { return iterator(*this,static_size); }
00422                 inline const_iterator   begin() const   { return const_iterator(*this,0); }
00423                 inline const_iterator   end() const             { return const_iterator(*this,static_size); }
00424                 inline reverse_iterator                 rbegin()                { return reverse_iterator(end()); }
00425                 inline const_reverse_iterator   rbegin() const  { return const_reverse_iterator(end()); }
00426                 inline reverse_iterator                 rend()                  { return reverse_iterator(begin()); }
00427                 inline const_reverse_iterator   rend() const    { return const_reverse_iterator(begin()); }
00428 
00429 
00430                 void swap (CPose3DQuat& o)
00431                 {
00432                         std::swap(o.m_coords, m_coords);
00433                         o.m_quat.swap(m_quat);
00434                 }
00435 
00436                 /** @} */
00437                 //! See ops_containers.h
00438                 typedef CPose3DQuat  mrpt_autotype;
00439                 //DECLARE_MRPT_CONTAINER_TYPES
00440 
00441         }; // End of class def.
00442 
00443         std::ostream BASE_IMPEXP  & operator << (std::ostream& o, const CPose3DQuat& p);
00444 
00445 
00446         } // End of namespace
00447 } // End of namespace
00448 
00449 #endif



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