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 void getAsVector(mrpt::math::CArrayDouble<7> &v) const {
00112 v[0] = m_coords[0]; v[1] = m_coords[1]; v[2] = m_coords[2];
00113 v[3] = m_quat[0]; v[4] = m_quat[1]; v[5] = m_quat[2]; v[6] = m_quat[3];
00114 }
00115
00116
00117
00118
00119
00120 void composeFrom(const CPose3DQuat& A, const CPose3DQuat& B );
00121
00122
00123
00124
00125
00126 void inverseComposeFrom(const CPose3DQuat& A, const CPose3DQuat& B );
00127
00128
00129
00130
00131 void composePoint(const double lx,const double ly,const double lz,double &gx,double &gy,double &gz,
00132 mrpt::math::CMatrixFixedNumeric<double,3,3> *out_jacobian_df_dpoint = NULL,
00133 mrpt::math::CMatrixFixedNumeric<double,3,7> *out_jacobian_df_dpose = NULL ) const;
00134
00135
00136
00137
00138 void inverseComposePoint(const double gx,const double gy,const double gz,double &lx,double &ly,double &lz,
00139 mrpt::math::CMatrixFixedNumeric<double,3,3> *out_jacobian_df_dpoint = NULL,
00140 mrpt::math::CMatrixFixedNumeric<double,3,7> *out_jacobian_df_dpose = NULL ) const;
00141
00142
00143
00144
00145 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]); }
00146
00147
00148 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]); }
00149
00150
00151 inline CPoint3D operator +( const CPoint3D &L) const { CPoint3D G; composePoint(L[0],L[1],L[2], G[0],G[1],G[2]); return G; }
00152
00153
00154 inline TPoint3D operator +( const TPoint3D &L) const { TPoint3D G; composePoint(L[0],L[1],L[2], G[0],G[1],G[2]); return G; }
00155
00156
00157 inline CPoint3D operator -( const CPoint3D &G) const { CPoint3D L; inverseComposePoint(G[0],G[1],G[2], L[0],L[1],L[2]); return L; }
00158
00159
00160 inline TPoint3D operator -( const TPoint3D &G) const { TPoint3D L; inverseComposePoint(G[0],G[1],G[2], L[0],L[1],L[2]); return L; }
00161
00162
00163
00164 virtual void operator *=(const double s);
00165
00166
00167 inline CPose3DQuat& operator += (const CPose3DQuat& b)
00168 {
00169 composeFrom(*this,b);
00170 return *this;
00171 }
00172
00173
00174 inline CPose3DQuat operator + (const CPose3DQuat& p) const
00175 {
00176 CPose3DQuat ret;
00177 ret.composeFrom(*this,p);
00178 return ret;
00179 }
00180
00181
00182 inline CPose3DQuat& operator -= (const CPose3DQuat& b)
00183 {
00184 inverseComposeFrom(*this,b);
00185 return *this;
00186 }
00187
00188
00189 inline CPose3DQuat operator - (const CPose3DQuat& p) const
00190 {
00191 CPose3DQuat ret;
00192 ret.inverseComposeFrom(*this,p);
00193 return ret;
00194 }
00195
00196
00197
00198
00199 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]); }
00200 inline std::string asString() const { std::string s; asString(s); return s; }
00201
00202
00203
00204
00205
00206 void fromString(const std::string &s) {
00207 CMatrixDouble m;
00208 if (!m.fromMatlabStringFormat(s)) THROW_EXCEPTION("Malformed expression in ::fromString");
00209 ASSERTMSG_(mrpt::math::size(m,1)==1 && mrpt::math::size(m,2)==7, "Wrong size of vector in ::fromString");
00210 m_coords[0] = m.get_unsafe(0,0); m_coords[1] = m.get_unsafe(0,1); m_coords[2] = m.get_unsafe(0,2);
00211 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);
00212 }
00213
00214
00215 inline const double &operator[](unsigned int i) const
00216 {
00217 switch(i)
00218 {
00219 case 0:return m_coords[0];
00220 case 1:return m_coords[1];
00221 case 2:return m_coords[2];
00222 case 3:return m_quat[0];
00223 case 4:return m_quat[1];
00224 case 5:return m_quat[2];
00225 case 6:return m_quat[3];
00226 default:
00227 throw std::runtime_error("CPose3DQuat::operator[]: Index of bounds.");
00228 }
00229 }
00230
00231 inline double &operator[](unsigned int i)
00232 {
00233 switch(i)
00234 {
00235 case 0:return m_coords[0];
00236 case 1:return m_coords[1];
00237 case 2:return m_coords[2];
00238 case 3:return m_quat[0];
00239 case 4:return m_quat[1];
00240 case 5:return m_quat[2];
00241 case 6:return m_quat[3];
00242 default:
00243 throw std::runtime_error("CPose3DQuat::operator[]: Index of bounds.");
00244 }
00245 }
00246
00247
00248
00249
00250
00251 void sphericalCoordinates(
00252 const TPoint3D &point,
00253 double &out_range,
00254 double &out_yaw,
00255 double &out_pitch,
00256 mrpt::math::CMatrixFixedNumeric<double,3,3> *out_jacob_dryp_dpoint = NULL,
00257 mrpt::math::CMatrixFixedNumeric<double,3,7> *out_jacob_dryp_dpose = NULL
00258 ) const;
00259
00260 public:
00261 typedef CPose3DQuat type_value;
00262 enum { is_3D_val = 1 };
00263 static inline bool is_3D() { return is_3D_val!=0; }
00264 enum { rotation_dimensions = 3 };
00265 enum { is_PDF_val = 1 };
00266 static inline bool is_PDF() { return is_PDF_val!=0; }
00267
00268 inline const type_value & getPoseMean() const { return *this; }
00269 inline type_value & getPoseMean() { return *this; }
00270
00271
00272
00273 typedef double value_type;
00274 typedef double& reference;
00275 typedef const double& const_reference;
00276 typedef std::size_t size_type;
00277 typedef std::ptrdiff_t difference_type;
00278
00279
00280 enum { static_size = 7 };
00281 static inline size_type size() { return static_size; }
00282 static inline bool empty() { return false; }
00283 static inline size_type max_size() { return static_size; }
00284 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))); }
00285
00286 inline void assign(const size_t N, const double val)
00287 {
00288 if (N!=7) throw std::runtime_error("CPose3DQuat::assign: Try to resize to length!=7.");
00289 m_coords.fill(val);
00290 m_quat.fill(val);
00291 }
00292
00293 struct iterator : public std::iterator<std::random_access_iterator_tag,value_type>
00294 {
00295 private:
00296 typedef std::iterator<std::random_access_iterator_tag,value_type> iterator_base;
00297 CPose3DQuat *m_obj;
00298 size_t m_cur_idx;
00299 typedef value_type T;
00300
00301 inline void check_limits(bool allow_end = false) const
00302 {
00303 #ifdef _DEBUG
00304 ASSERTMSG_(m_obj!=NULL,"non initialized iterator");
00305 if (m_cur_idx> (allow_end ? 7u : 6u) ) THROW_EXCEPTION("Index out of range in iterator.")
00306 #endif
00307 }
00308 public:
00309 inline bool operator <(const iterator &it2) const { return m_cur_idx < it2.m_cur_idx; }
00310 inline bool operator >(const iterator &it2) const { return m_cur_idx > it2.m_cur_idx; }
00311 inline iterator() : m_obj(NULL),m_cur_idx(0) { }
00312 inline iterator(CPose3DQuat &obj, size_t start_idx) : m_obj(&obj),m_cur_idx(start_idx) { check_limits(true); }
00313 inline CPose3DQuat::reference operator*() const { check_limits(); return (*m_obj)[m_cur_idx]; }
00314 inline iterator &operator++() {
00315 check_limits();
00316 ++m_cur_idx;
00317 return *this;
00318 }
00319 inline iterator operator++(int) {
00320 iterator it=*this;
00321 ++*this;
00322 return it;
00323 }
00324 inline iterator &operator--() {
00325 --m_cur_idx;
00326 check_limits();
00327 return *this;
00328 }
00329 inline iterator operator--(int) {
00330 iterator it=*this;
00331 --*this;
00332 return it;
00333 }
00334 inline iterator &operator+=(iterator_base::difference_type off) {
00335 m_cur_idx+=off;
00336 check_limits(true);
00337 return *this;
00338 }
00339 inline iterator operator+(iterator_base::difference_type off) const {
00340 iterator it=*this;
00341 it+=off;
00342 return it;
00343 }
00344 inline iterator &operator-=(iterator_base::difference_type off) {
00345 return (*this)+=(-off);
00346 }
00347 inline iterator operator-(iterator_base::difference_type off) const {
00348 iterator it=*this;
00349 it-=off;
00350 return it;
00351 }
00352 inline iterator_base::difference_type operator-(const iterator &it) const { return m_cur_idx - it.m_cur_idx; }
00353 inline CPose3DQuat::reference operator[](iterator_base::difference_type off) const { return (*m_obj)[m_cur_idx+off]; }
00354 inline bool operator==(const iterator &it) const { return m_obj==it.m_obj && m_cur_idx==it.m_cur_idx; }
00355 inline bool operator!=(const iterator &it) const { return !(operator==(it)); }
00356 };
00357
00358 struct const_iterator : public std::iterator<std::random_access_iterator_tag,value_type>
00359 {
00360 private:
00361 typedef std::iterator<std::random_access_iterator_tag,value_type> iterator_base;
00362 const CPose3DQuat *m_obj;
00363 size_t m_cur_idx;
00364 typedef value_type T;
00365
00366 inline void check_limits(bool allow_end = false) const
00367 {
00368 #ifdef _DEBUG
00369 ASSERTMSG_(m_obj!=NULL,"non initialized iterator");
00370 if (m_cur_idx> (allow_end ? 7u : 6u) ) THROW_EXCEPTION("Index out of range in iterator.")
00371 #endif
00372 }
00373 public:
00374 inline bool operator <(const const_iterator &it2) const { return m_cur_idx < it2.m_cur_idx; }
00375 inline bool operator >(const const_iterator &it2) const { return m_cur_idx > it2.m_cur_idx; }
00376 inline const_iterator() : m_obj(NULL),m_cur_idx(0) { }
00377 inline const_iterator(const CPose3DQuat &obj, size_t start_idx) : m_obj(&obj),m_cur_idx(start_idx) { check_limits(true); }
00378 inline CPose3DQuat::const_reference operator*() const { check_limits(); return (*m_obj)[m_cur_idx]; }
00379 inline const_iterator &operator++() {
00380 check_limits();
00381 ++m_cur_idx;
00382 return *this;
00383 }
00384 inline const_iterator operator++(int) {
00385 const_iterator it=*this;
00386 ++*this;
00387 return it;
00388 }
00389 inline const_iterator &operator--() {
00390 --m_cur_idx;
00391 check_limits();
00392 return *this;
00393 }
00394 inline const_iterator operator--(int) {
00395 const_iterator it=*this;
00396 --*this;
00397 return it;
00398 }
00399 inline const_iterator &operator+=(iterator_base::difference_type off) {
00400 m_cur_idx+=off;
00401 check_limits(true);
00402 return *this;
00403 }
00404 inline const_iterator operator+(iterator_base::difference_type off) const {
00405 const_iterator it=*this;
00406 it+=off;
00407 return it;
00408 }
00409 inline const_iterator &operator-=(iterator_base::difference_type off) {
00410 return (*this)+=(-off);
00411 }
00412 inline const_iterator operator-(iterator_base::difference_type off) const {
00413 const_iterator it=*this;
00414 it-=off;
00415 return it;
00416 }
00417 inline iterator_base::difference_type operator-(const const_iterator &it) const { return m_cur_idx - it.m_cur_idx; }
00418 inline CPose3DQuat::const_reference operator[](iterator_base::difference_type off) const { return (*m_obj)[m_cur_idx+off]; }
00419 inline bool operator==(const const_iterator &it) const { return m_obj==it.m_obj && m_cur_idx==it.m_cur_idx; }
00420 inline bool operator!=(const const_iterator &it) const { return !(operator==(it)); }
00421 };
00422
00423 typedef std::reverse_iterator<iterator> reverse_iterator;
00424 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00425 inline iterator begin() { return iterator(*this,0); }
00426 inline iterator end() { return iterator(*this,static_size); }
00427 inline const_iterator begin() const { return const_iterator(*this,0); }
00428 inline const_iterator end() const { return const_iterator(*this,static_size); }
00429 inline reverse_iterator rbegin() { return reverse_iterator(end()); }
00430 inline const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
00431 inline reverse_iterator rend() { return reverse_iterator(begin()); }
00432 inline const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
00433
00434
00435 void swap (CPose3DQuat& o)
00436 {
00437 std::swap(o.m_coords, m_coords);
00438 o.m_quat.swap(m_quat);
00439 }
00440
00441
00442
00443 typedef CPose3DQuat mrpt_autotype;
00444
00445
00446 };
00447
00448 std::ostream BASE_IMPEXP & operator << (std::ostream& o, const CPose3DQuat& p);
00449
00450
00451 }
00452 }
00453
00454 #endif