00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 class BASE_IMPEXP CPose3DQuat : public CPose<CPose3DQuat>, public mrpt::utils::CSerializable
00064 {
00065
00066 DEFINE_SERIALIZABLE( CPose3DQuat )
00067
00068 public:
00069 CArrayDouble<3> m_coords;
00070 mrpt::math::CQuaternionDouble m_quat;
00071
00072 public:
00073
00074 inline mrpt::math::CQuaternionDouble & quat() { return m_quat; }
00075
00076 inline const mrpt::math::CQuaternionDouble & quat() const { return m_quat; }
00077
00078
00079 inline mrpt::math::CArrayDouble<3> & xyz() { return m_coords; }
00080
00081 inline const mrpt::math::CArrayDouble<3> & xyz() const { return m_coords; }
00082
00083
00084
00085 inline CPose3DQuat() : m_quat() { m_coords[0]=m_coords[1]=m_coords[2]=0.; }
00086
00087
00088 inline CPose3DQuat(TConstructorFlags_Quaternions constructor_dummy_param) : m_quat(UNINITIALIZED_QUATERNION) { }
00089
00090
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
00094 explicit CPose3DQuat(const CPose3D &p);
00095
00096
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
00100
00101 explicit CPose3DQuat(const CMatrixDouble44 &M);
00102
00103
00104
00105
00106 void getHomogeneousMatrix(CMatrixDouble44 & out_HM ) const;
00107
00108
00109 void getAsVector(vector_double &v) const;
00110
00111
00112
00113
00114
00115 void composeFrom(const CPose3DQuat& A, const CPose3DQuat& B );
00116
00117
00118
00119
00120
00121 void inverseComposeFrom(const CPose3DQuat& A, const CPose3DQuat& B );
00122
00123
00124
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
00131
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
00138
00139
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
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
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
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
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
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
00158
00159 virtual void operator *=(const double s);
00160
00161
00162 inline CPose3DQuat& operator += (const CPose3DQuat& b)
00163 {
00164 composeFrom(*this,b);
00165 return *this;
00166 }
00167
00168
00169 inline CPose3DQuat operator + (const CPose3DQuat& p) const
00170 {
00171 CPose3DQuat ret;
00172 ret.composeFrom(*this,p);
00173 return ret;
00174 }
00175
00176
00177 inline CPose3DQuat& operator -= (const CPose3DQuat& b)
00178 {
00179 inverseComposeFrom(*this,b);
00180 return *this;
00181 }
00182
00183
00184 inline CPose3DQuat operator - (const CPose3DQuat& p) const
00185 {
00186 CPose3DQuat ret;
00187 ret.inverseComposeFrom(*this,p);
00188 return ret;
00189 }
00190
00191
00192
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
00198
00199
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
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
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
00243
00244
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;
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
00267
00268 typedef double value_type;
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
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;
00293 size_t m_cur_idx;
00294 typedef value_type T;
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); }
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 };
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;
00358 size_t m_cur_idx;
00359 typedef value_type T;
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); }
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 };
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
00438 typedef CPose3DQuat mrpt_autotype;
00439
00440
00441 };
00442
00443 std::ostream BASE_IMPEXP & operator << (std::ostream& o, const CPose3DQuat& p);
00444
00445
00446 }
00447 }
00448
00449 #endif