Main MRPT website > C++ reference for MRPT 1.5.9
CPose3D.cpp
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 
10 #include "base-precomp.h" // Precompiled headers
11 
12 #include <mrpt/config.h> // for HAVE_SINCOS
13 #include <mrpt/utils/types_math.h> // for CVectorD...
14 #include <mrpt/math/CMatrix.h> // for CMatrix
15 #include <mrpt/math/geometry.h> // for skew_sym...
16 #include <mrpt/math/matrix_serialization.h> // for operator>>
17 #include <mrpt/math/wrap2pi.h> // for wrapToPi
18 #include <mrpt/poses/CPoint2D.h> // for CPoint2D
19 #include <mrpt/poses/CPoint3D.h> // for CPoint3D
20 #include <mrpt/poses/CPose2D.h> // for CPose2D
21 #include <mrpt/poses/CPose3D.h> // for CPose3D
22 #include <mrpt/poses/CPose3DQuat.h> // for CPose3DQuat
23 #include <mrpt/poses/CPose3DRotVec.h> // for CPose3DR...
24 #include <mrpt/utils/CStream.h> // for CStream
25 #include <algorithm> // for move
26 #include <cmath> // for fabs
27 #include <iomanip> // for operator<<
28 #include <limits> // for numeric_...
29 #include <ostream> // for operator<<
30 #include <string> // for allocator
31 #include <mrpt/math/CArrayNumeric.h> // for CArrayDo...
32 #include <mrpt/math/CMatrixFixedNumeric.h> // for CMatrixF...
33 #include <mrpt/math/CMatrixTemplateNumeric.h> // for CMatrixD...
34 #include <mrpt/math/CQuaternion.h> // for CQuatern...
35 #include <mrpt/math/homog_matrices.h> // for homogene...
36 #include <mrpt/math/lightweight_geom_data.h> // for TPoint3D
37 #include <mrpt/math/ops_containers.h> // for dotProduct
38 #include <mrpt/utils/CSerializable.h> // for CSeriali...
39 #include <mrpt/utils/bits.h> // for square
40 #include <mrpt/math/utils_matlab.h>
41 #include <mrpt/otherlibs/sophus/so3.hpp>
42 #include <mrpt/otherlibs/sophus/se3.hpp>
43 
44 using namespace mrpt;
45 using namespace mrpt::math;
46 using namespace mrpt::utils;
47 using namespace mrpt::poses;
48 
49 
51 
52 /*---------------------------------------------------------------
53  Constructors
54  ---------------------------------------------------------------*/
56  : m_ypr_uptodate(true), m_yaw(0),m_pitch(0),m_roll(0)
57 {
58  m_coords[0] =
59  m_coords[1] =
60  m_coords[2] = 0;
61  m_ROT.unit(3,1.0);
62 }
63 
64 CPose3D::CPose3D(const double x,const double y,const double z, const double yaw, const double pitch, const double roll)
65  : m_ROT(UNINITIALIZED_MATRIX), m_ypr_uptodate(false)
66 {
68 }
69 
71  : m_ypr_uptodate(false)
72 {
73  setFromValues(o.x,o.y,o.z,o.yaw,o.pitch,o.roll);
74 }
75 
77  : m_ypr_uptodate(false)
78 {
79  setFromValues(p.x(),p.y(),0, p.phi(),0,0);
80 }
81 
83  : m_ypr_uptodate(false), m_yaw(),m_pitch(),m_roll()
84 {
85  setFromValues(p.x(),p.y(),p.z());
86 }
87 
89  : m_ROT( UNINITIALIZED_MATRIX ), m_ypr_uptodate(false)
90 {
93  for (int r=0;r<3;r++)
94  for (int c=0;c<3;c++)
95  m_ROT(r,c)=m.get_unsafe(r,c);
96  for (int r=0;r<3;r++)
97  m_coords[r] = m.get_unsafe(r,3);
98 }
99 
100 
102  : m_ROT( UNINITIALIZED_MATRIX ), m_ypr_uptodate(false)
103 {
104  for (int r=0;r<3;r++)
105  for (int c=0;c<3;c++)
106  m_ROT(r,c)=m.get_unsafe(r,c);
107  for (int r=0;r<3;r++)
108  m_coords[r] = m.get_unsafe(r,3);
109 }
110 
111 /** Constructor from a quaternion (which only represents the 3D rotation part) and a 3D displacement. */
112 CPose3D::CPose3D(const mrpt::math::CQuaternionDouble &q, const double _x, const double _y, const double _z )
113  : m_ROT( UNINITIALIZED_MATRIX ), m_ypr_uptodate(false)
114 {
115  double yaw,pitch,roll;
116  q.rpy(roll,pitch,yaw);
117  this->setFromValues(_x,_y,_z,yaw,pitch,roll);
118 }
119 
120 /** Constructor from a quaternion-based full pose. */
122  : m_ROT( UNINITIALIZED_MATRIX ), m_ypr_uptodate(false)
123 {
124  // Extract XYZ + ROT from quaternion:
125  m_coords[0] = p.x();
126  m_coords[1] = p.y();
127  m_coords[2] = p.z();
128  p.quat().rotationMatrixNoResize(m_ROT);
129 }
130 
131 /** Constructor from a rotation vector-based full pose. */
133  : m_ROT( UNINITIALIZED_MATRIX ), m_ypr_uptodate(false)
134 {
135  m_coords[0] = p.m_coords[0];
136  m_coords[1] = p.m_coords[1];
137  m_coords[2] = p.m_coords[2];
138 
139  this->setRotationMatrix( this->exp_rotation( p.m_rotvec ) );
140 }
141 
142 /*---------------------------------------------------------------
143  Implements the writing to a CStream capability of
144  CSerializable objects
145  ---------------------------------------------------------------*/
147 {
148  if (version)
149  *version = 3;
150  else
151  {
152  // v2 serialized the equivalent CPose3DQuat representation.
153  // But this led to (**really** tiny) numerical differences between the
154  // original and reconstructed poses. To ensure bit-by-bit equivalence before
155  // and after serialization, let's get back to serializing the actual SO(3)
156  // matrix in serialization v3:
157  for (int i = 0; i < 3; i++) out << m_coords[i];
158  for (int r = 0; r < 3; r++)
159  for (int c = 0; c < 3; c++) out << m_ROT(r, c);
160  }
161 }
162 
163 /*---------------------------------------------------------------
164  Implements the reading from a CStream capability of
165  CSerializable objects
166  ---------------------------------------------------------------*/
168 {
169  switch(version)
170  {
171  case 0:
172  {
173  // The coordinates:
174  CMatrix HM2;
175  in >> HM2;
176  ASSERT_(mrpt::math::size(HM2,1)==4 && HM2.isSquare())
177 
178  m_ROT = HM2.block(0,0,3,3).cast<double>();
179 
180  m_coords[0] = HM2.get_unsafe(0,3);
181  m_coords[1] = HM2.get_unsafe(1,3);
182  m_coords[2] = HM2.get_unsafe(2,3);
183  m_ypr_uptodate = false;
184  } break;
185  case 1:
186  {
187  // The coordinates:
188  CMatrixDouble44 HM;
189  in >> HM;
190 
191  m_ROT = HM.block(0,0,3,3);
192 
193  m_coords[0] = HM.get_unsafe(0,3);
194  m_coords[1] = HM.get_unsafe(1,3);
195  m_coords[2] = HM.get_unsafe(2,3);
196  m_ypr_uptodate = false;
197  } break;
198  case 2:
199  {
200  // An equivalent CPose3DQuat
202  in >>p[0]>>p[1]>>p[2]>>p[3]>>p[4]>>p[5]>>p[6];
203 
204  // Extract XYZ + ROT from quaternion:
205  m_ypr_uptodate = false;
206  m_coords[0] = p.x();
207  m_coords[1] = p.y();
208  m_coords[2] = p.z();
209  p.quat().rotationMatrixNoResize(m_ROT);
210  } break;
211  case 3:
212  {
213  for (int i = 0; i < 3; i++) in >> m_coords[i];
214  for (int r = 0; r < 3; r++)
215  for (int c = 0; c < 3; c++) in >> m_ROT(r, c);
216  }
217  break;
218  default:
220 
221  };
222 }
223 
224 /** Textual output stream function.
225  */
226 std::ostream& mrpt::poses::operator << (std::ostream& o, const CPose3D& p)
227 {
228  const std::streamsize old_pre = o.precision();
229  const std::ios_base::fmtflags old_flags = o.flags();
230  o << "(x,y,z,yaw,pitch,roll)=(" << std::fixed << std::setprecision(4) << p.m_coords[0] << "," << p.m_coords[1] << "," << p.m_coords[2] << ","
231  << std::setprecision(2) << RAD2DEG(p.yaw()) << "deg," << RAD2DEG(p.pitch()) << "deg," << RAD2DEG(p.roll()) << "deg)";
232  o.flags(old_flags);
233  o.precision(old_pre);
234  return o;
235 }
236 
237 /*---------------------------------------------------------------
238  Implements the writing to a mxArray for Matlab
239  ---------------------------------------------------------------*/
240 #if MRPT_HAS_MATLAB
241 // Add to implement mexplus::from template specialization
243 
245 {
246  const char* fields[] = {"R","t"};
247  mexplus::MxArray pose_struct( mexplus::MxArray::Struct(sizeof(fields)/sizeof(fields[0]),fields) );
248  pose_struct.set("R", mrpt::math::convertToMatlab(this->m_ROT));
249  pose_struct.set("t", mrpt::math::convertToMatlab(this->m_coords));
250  return pose_struct.release();
251 }
252 #endif
253 
254 /*---------------------------------------------------------------
255  normalizeAngles
256 ---------------------------------------------------------------*/
258 {
260 }
261 
262 
263 /*---------------------------------------------------------------
264  Set the pose from 3D point and yaw/pitch/roll angles, in radians.
265 ---------------------------------------------------------------*/
267  const double x0,
268  const double y0,
269  const double z0,
270  const double yaw,
271  const double pitch,
272  const double roll)
273 {
274  m_coords[0] = x0;
275  m_coords[1] = y0;
276  m_coords[2] = z0;
277  this->m_yaw = mrpt::math::wrapToPi(yaw);
278  this->m_pitch = mrpt::math::wrapToPi(pitch);
279  this->m_roll = mrpt::math::wrapToPi(roll);
280 
281  m_ypr_uptodate = true;
282 
284 }
285 
286 /*---------------------------------------------------------------
287  Set the pose from 3D point and yaw/pitch/roll angles, in radians.
288 ---------------------------------------------------------------*/
290 {
291 #ifdef HAVE_SINCOS
292  double cy,sy;
293  ::sincos(m_yaw,&sy,&cy);
294  double cp,sp;
295  ::sincos(m_pitch,&sp,&cp);
296  double cr,sr;
297  ::sincos(m_roll,&sr,&cr);
298 #else
299  const double cy = cos(m_yaw);
300  const double sy = sin(m_yaw);
301  const double cp = cos(m_pitch);
302  const double sp = sin(m_pitch);
303  const double cr = cos(m_roll);
304  const double sr = sin(m_roll);
305 #endif
306 
307  MRPT_ALIGN16 const double rot_vals[] = {
308  cy*cp, cy*sp*sr-sy*cr, cy*sp*cr+sy*sr,
309  sy*cp, sy*sp*sr+cy*cr, sy*sp*cr-cy*sr,
310  -sp, cp*sr, cp*cr
311  };
312  m_ROT.loadFromArray(rot_vals);
313 }
314 
315 /*---------------------------------------------------------------
316  Scalar multiplication.
317 ---------------------------------------------------------------*/
318 void CPose3D::operator *=(const double s)
319 {
321  m_coords[0]*=s;
322  m_coords[1]*=s;
323  m_coords[2]*=s;
324  m_yaw*=s;
325  m_pitch*=s;
326  m_roll*=s;
328 }
329 
330 /*---------------------------------------------------------------
331  getYawPitchRoll
332 ---------------------------------------------------------------*/
333 void CPose3D::getYawPitchRoll( double &yaw, double &pitch, double &roll ) const
334 {
335  ASSERTDEBMSG_( std::abs(sqrt(square(m_ROT(0,0))+square(m_ROT(1,0))+square(m_ROT(2,0))) - 1 ) < 3e-3, "Homogeneous matrix is not orthogonal & normalized!: "+m_ROT.inMatlabFormat() )
336  ASSERTDEBMSG_( std::abs(sqrt(square(m_ROT(0,1))+square(m_ROT(1,1))+square(m_ROT(2,1))) - 1 ) < 3e-3, "Homogeneous matrix is not orthogonal & normalized!: "+m_ROT.inMatlabFormat() )
337  ASSERTDEBMSG_( std::abs(sqrt(square(m_ROT(0,2))+square(m_ROT(1,2))+square(m_ROT(2,2))) - 1 ) < 3e-3, "Homogeneous matrix is not orthogonal & normalized!: "+m_ROT.inMatlabFormat() )
338 
339  // Pitch is in the range [-pi/2, pi/2 ], so this calculation is enough:
340  pitch = atan2( - m_ROT(2,0), hypot( m_ROT(0,0),m_ROT(1,0) ) ); //asin( - m_ROT(2,0) );
341 
342  // Roll:
343  if ( (fabs(m_ROT(2,1))+fabs(m_ROT(2,2)))<10*std::numeric_limits<double>::epsilon() )
344  {
345  //Gimbal lock between yaw and roll. This one is arbitrarily forced to be zero.
346  //Check http://reference.mrpt.org/devel/classmrpt_1_1poses_1_1_c_pose3_d.html. If cos(pitch)==0, the homogeneous matrix is:
347  //When sin(pitch)==1:
348  // /0 cysr-sycr cycr+sysr x\ /0 sin(r-y) cos(r-y) x\.
349  // |0 sysr+cycr sycr-cysr y| = |0 cos(r-y) -sin(r-y) y|
350  // |-1 0 0 z| |-1 0 0 z|
351  // \0 0 0 1/ \0 0 0 1/
352  //
353  //And when sin(pitch)=-1:
354  // /0 -cysr-sycr -cycr+sysr x\ /0 -sin(r+y) -cos(r+y) x\.
355  // |0 -sysr+cycr -sycr-cysr y| = |0 cos(r+y) -sin(r+y) y|
356  // |1 0 0 z| |1 0 0 z|
357  // \0 0 0 1/ \0 0 0 1/
358  //
359  //Both cases are in a "gimbal lock" status. This happens because pitch is vertical.
360 
361  roll = 0.0;
362  if (pitch>0) yaw=atan2(m_ROT(1,2),m_ROT(0,2));
363  else yaw=atan2(-m_ROT(1,2),-m_ROT(0,2));
364  }
365  else
366  {
367  roll = atan2( m_ROT(2,1), m_ROT(2,2) );
368  // Yaw:
369  yaw = atan2( m_ROT(1,0), m_ROT(0,0) );
370  }
371 }
372 
373 
374 /*---------------------------------------------------------------
375  sphericalCoordinates
376 ---------------------------------------------------------------*/
378  const TPoint3D &point,
379  double &out_range,
380  double &out_yaw,
381  double &out_pitch ) const
382 {
383  // Pass to coordinates as seen from this 6D pose:
384  TPoint3D local;
385  this->inverseComposePoint(point.x,point.y,point.z, local.x,local.y,local.z);
386 
387  // Range:
388  out_range = local.norm();
389 
390  // Yaw:
391  if (local.y!=0 || local.x!=0)
392  out_yaw = atan2(local.y,local.x);
393  else out_yaw = 0;
394 
395  // Pitch:
396  if (out_range!=0)
397  out_pitch = -asin( local.z / out_range );
398  else out_pitch = 0;
399 
400 }
401 
402 
403 /*---------------------------------------------------------------
404  addComponents
405 ---------------------------------------------------------------*/
407 {
409  m_coords[0]+=p.m_coords[0];
410  m_coords[1]+=p.m_coords[1];
411  m_coords[2]+=p.m_coords[2];
412  m_yaw+=p.m_yaw;
413  m_pitch+=p.m_pitch;
414  m_roll+=p.m_roll;
416 }
417 
418 
419 /*---------------------------------------------------------------
420  distanceEuclidean6D
421 ---------------------------------------------------------------*/
422 double CPose3D::distanceEuclidean6D( const CPose3D &o ) const
423 {
425  o.updateYawPitchRoll();
426  return sqrt(
427  square( o.m_coords[0] - m_coords[0] ) +
428  square( o.m_coords[1] - m_coords[1] ) +
429  square( o.m_coords[2] - m_coords[2] ) +
430  square( wrapToPi( o.m_yaw - m_yaw ) ) +
431  square( wrapToPi( o.m_pitch - m_pitch ) ) +
432  square( wrapToPi( o.m_roll - m_roll ) ) );
433 }
434 
435 
436 /*---------------------------------------------------------------
437  composePoint
438 ---------------------------------------------------------------*/
439 void CPose3D::composePoint(double lx,double ly,double lz, double &gx, double &gy, double &gz,
440  mrpt::math::CMatrixFixedNumeric<double,3,3> *out_jacobian_df_dpoint,
441  mrpt::math::CMatrixFixedNumeric<double,3,6> *out_jacobian_df_dpose,
442  mrpt::math::CMatrixFixedNumeric<double,3,6> *out_jacobian_df_dse3,
443  bool use_small_rot_approx ) const
444 {
445  // Jacob: df/dpoint
446  if (out_jacobian_df_dpoint)
447  *out_jacobian_df_dpoint = m_ROT;
448 
449  // Jacob: df/dpose
450  if (out_jacobian_df_dpose)
451  {
452  if (use_small_rot_approx)
453  {
454  // Linearized Jacobians around (yaw,pitch,roll)=(0,0,0):
455  MRPT_ALIGN16 const double nums[3*6] = {
456  1, 0, 0, -ly, lz, 0,
457  0, 1, 0, lx, 0, -lz,
458  0, 0, 1, 0, -lx, ly };
459  out_jacobian_df_dpose->loadFromArray(nums);
460  }
461  else
462  {
463  // Exact Jacobians:
465  # ifdef HAVE_SINCOS
466  double cy,sy;
467  ::sincos(m_yaw,&sy,&cy);
468  double cp,sp;
469  ::sincos(m_pitch,&sp,&cp);
470  double cr,sr;
471  ::sincos(m_roll,&sr,&cr);
472  # else
473  const double cy = cos(m_yaw);
474  const double sy = sin(m_yaw);
475  const double cp = cos(m_pitch);
476  const double sp = sin(m_pitch);
477  const double cr = cos(m_roll);
478  const double sr = sin(m_roll);
479  # endif
480 
481  MRPT_ALIGN16 const double nums[3*6] = {
482  1, 0, 0,
483  -lx*sy*cp+ly*(-sy*sp*sr-cy*cr)+lz*(-sy*sp*cr+cy*sr), // d_x'/d_yaw
484  -lx*cy*sp+ly*(cy*cp*sr )+lz*(cy*cp*cr ), // d_x'/d_pitch
485  ly*(cy*sp*cr+sy*sr)+lz*(-cy*sp*sr+sy*cr), // d_x'/d_roll
486  0, 1, 0,
487  lx*cy*cp+ly*(cy*sp*sr-sy*cr)+lz*(cy*sp*cr+sy*sr), // d_y'/d_yaw
488  -lx*sy*sp+ly*(sy*cp*sr) +lz*(sy*cp*cr ), // d_y'/d_pitch
489  ly*(sy*sp*cr-cy*sr)+lz*(-sy*sp*sr-cy*cr), // d_y'/d_roll
490  0, 0, 1,
491  0, // d_z' / d_yaw
492  -lx*cp-ly*sp*sr-lz*sp*cr, // d_z' / d_pitch
493  ly*cp*cr-lz*cp*sr // d_z' / d_roll
494  };
495  out_jacobian_df_dpose->loadFromArray(nums);
496  }
497  }
498 
499  gx=m_ROT(0,0)*lx+m_ROT(0,1)*ly+m_ROT(0,2)*lz+m_coords[0];
500  gy=m_ROT(1,0)*lx+m_ROT(1,1)*ly+m_ROT(1,2)*lz+m_coords[1];
501  gz=m_ROT(2,0)*lx+m_ROT(2,1)*ly+m_ROT(2,2)*lz+m_coords[2];
502 
503  // Jacob: df/dse3
504  if (out_jacobian_df_dse3)
505  {
506  MRPT_ALIGN16 const double nums[3*6] = {
507  1, 0, 0, 0, gz, -gy,
508  0, 1, 0, -gz, 0, gx,
509  0, 0, 1, gy,-gx, 0 };
510  out_jacobian_df_dse3->loadFromArray(nums);
511  }
512 }
513 
514 
515 // TODO: Use SSE2? OTOH, this forces mem align...
516 #if MRPT_HAS_SSE2 && defined(MRPT_USE_SSE2)
517 /*static inline __m128 transformSSE(const __m128* matrix, const __m128& in)
518 {
519  ASSERT_(((size_t)matrix & 15) == 0);
520  __m128 a0 = _mm_mul_ps(_mm_load_ps((float*)(matrix+0)), _mm_shuffle_ps(in,in,_MM_SHUFFLE(0,0,0,0)));
521  __m128 a1 = _mm_mul_ps(_mm_load_ps((float*)(matrix+1)), _mm_shuffle_ps(in,in,_MM_SHUFFLE(1,1,1,1)));
522  __m128 a2 = _mm_mul_ps(_mm_load_ps((float*)(matrix+2)), _mm_shuffle_ps(in,in,_MM_SHUFFLE(2,2,2,2)));
523 
524  return _mm_add_ps(_mm_add_ps(a0,a1),a2);
525 }*/
526 #endif // SSE2
527 
528 /*---------------------------------------------------------------
529  getAsVector
530 ---------------------------------------------------------------*/
532 {
534  r.resize(6);
535  r[0]=m_coords[0];
536  r[1]=m_coords[1];
537  r[2]=m_coords[2];
538  r[3]=m_yaw;
539  r[4]=m_pitch;
540  r[5]=m_roll;
541 }
542 
544 {
546  r[0]=m_coords[0];
547  r[1]=m_coords[1];
548  r[2]=m_coords[2];
549  r[3]=m_yaw;
550  r[4]=m_pitch;
551  r[5]=m_roll;
552 }
553 
554 
555 /*---------------------------------------------------------------
556  unary -
557 ---------------------------------------------------------------*/
559 {
561  b.getInverseHomogeneousMatrix( B_INV );
562  return CPose3D(B_INV);
563 }
564 
566 {
568  mrpt::math::TPose3D(0, 0, 0, m_yaw, m_pitch, m_roll).getAsQuaternion(q, out_dq_dr);
569 }
570 
571 bool mrpt::poses::operator==(const CPose3D &p1,const CPose3D &p2)
572 {
573  return (p1.m_coords==p2.m_coords)&&(p1.getRotationMatrix()==p2.getRotationMatrix());
574 }
575 
576 bool mrpt::poses::operator!=(const CPose3D &p1,const CPose3D &p2)
577 {
578  return (p1.m_coords!=p2.m_coords)||(p1.getRotationMatrix()!=p2.getRotationMatrix());
579 }
580 
581 /*---------------------------------------------------------------
582  point3D = pose3D + point3D
583  ---------------------------------------------------------------*/
585 {
586  return CPoint3D(
587  m_coords[0] + m_ROT(0,0)*b.x() + m_ROT(0,1)*b.y() +m_ROT(0,2)*b.z(),
588  m_coords[1] + m_ROT(1,0)*b.x() + m_ROT(1,1)*b.y() +m_ROT(1,2)*b.z(),
589  m_coords[2] + m_ROT(2,0)*b.x() + m_ROT(2,1)*b.y() +m_ROT(2,2)*b.z());
590 }
591 
592 /*---------------------------------------------------------------
593  point3D = pose3D + point2D
594  ---------------------------------------------------------------*/
596 {
597  return CPoint3D(
598  m_coords[0] + m_ROT(0,0)*b.x() + m_ROT(0,1)*b.y(),
599  m_coords[1] + m_ROT(1,0)*b.x() + m_ROT(1,1)*b.y(),
600  m_coords[2] + m_ROT(2,0)*b.x() + m_ROT(2,1)*b.y());
601 }
602 
603 
604 /*---------------------------------------------------------------
605  this = A + B
606  ---------------------------------------------------------------*/
607 void CPose3D::composeFrom(const CPose3D& A, const CPose3D& B )
608 {
609  // The translation part HM(0:3,3)
610  if (this==&B)
611  {
612  // we need to make a temporary copy of the vector:
613  const CArrayDouble<3> B_coords = B.m_coords;
614  for (int r=0;r<3;r++)
615  m_coords[r] = A.m_coords[r] + A.m_ROT(r,0)*B_coords[0]+A.m_ROT(r,1)*B_coords[1]+A.m_ROT(r,2)*B_coords[2];
616  }
617  else
618  {
619  for (int r=0;r<3;r++)
620  m_coords[r] = A.m_coords[r] + A.m_ROT(r,0)*B.m_coords[0]+A.m_ROT(r,1)*B.m_coords[1]+A.m_ROT(r,2)*B.m_coords[2];
621  }
622 
623  // Important: Make this multiplication AFTER the translational part, to cope with the case when A==this
624  m_ROT.multiply_AB( A.m_ROT, B.m_ROT );
625 
626  m_ypr_uptodate=false;
627 }
628 
629 /** Convert this pose into its inverse, saving the result in itself. */
631 {
633  CArrayDouble<3> inv_xyz;
634 
636 
637  m_ROT = inv_rot;
638  m_coords = inv_xyz;
639  m_ypr_uptodate=false;
640 }
641 
642 /*---------------------------------------------------------------
643  isHorizontal
644  ---------------------------------------------------------------*/
645 bool CPose3D::isHorizontal( const double tolerance ) const
646 {
648  return (fabs(m_pitch)<=tolerance || M_PI-fabs(m_pitch) <=tolerance ) &&
649  ( fabs(m_roll)<=tolerance || fabs(mrpt::math::wrapToPi( m_roll-M_PI))<=tolerance );
650 }
651 
652 
653 /** Makes \f$ this = A \ominus B \f$ this method is slightly more efficient than "this= A - B;" since it avoids the temporary object.
654  * \note A or B can be "this" without problems.
655  * \sa composeFrom, composePoint
656  */
657 void CPose3D::inverseComposeFrom(const CPose3D& A, const CPose3D& B )
658 {
659  // this = A (-) B
660  // HM_this = inv(HM_B) * HM_A
661  //
662  // [ R_b | t_b ] -1 [ R_a | t_a ] [ R_b^t * Ra | .. ]
663  // [ ------+-----] * [ ------+-----] = [ ---------- +----------]
664  // [ 0 0 0 | 1 ] [ 0 0 0 | 1 ] [ 0 0 0 | 1 ]
665  //
666 
667  // XYZ part:
669  CArrayDouble<3> t_b_inv;
671 
672  for (int i=0;i<3;i++)
673  m_coords[i] = t_b_inv[i] + R_b_inv(i,0)*A.m_coords[0]+ R_b_inv(i,1)*A.m_coords[1]+ R_b_inv(i,2)*A.m_coords[2];
674 
675  // Rot part:
676  m_ROT.multiply_AB( R_b_inv, A.m_ROT );
677  m_ypr_uptodate=false;
678 }
679 
680 /** Computes the 3D point L such as \f$ L = G \ominus this \f$.
681  * \sa composePoint, composeFrom
682  */
683 void CPose3D::inverseComposePoint(const double gx,const double gy,const double gz,double &lx,double &ly,double &lz,
684  mrpt::math::CMatrixFixedNumeric<double,3,3> *out_jacobian_df_dpoint,
685  mrpt::math::CMatrixFixedNumeric<double,3,6> *out_jacobian_df_dpose,
686  mrpt::math::CMatrixFixedNumeric<double,3,6> *out_jacobian_df_dse3
687  )const
688 {
690  CArrayDouble<3> t_inv;
692 
693  // Jacob: df/dpoint
694  if (out_jacobian_df_dpoint)
695  *out_jacobian_df_dpoint = R_inv;
696 
697  // Jacob: df/dpose
698  if (out_jacobian_df_dpose)
699  {
700  // TODO: Perhaps this and the sin/cos's can be avoided if all needed terms are already in m_ROT ???
702 
703 # ifdef HAVE_SINCOS
704  double cy,sy;
705  ::sincos(m_yaw,&sy,&cy);
706  double cp,sp;
707  ::sincos(m_pitch,&sp,&cp);
708  double cr,sr;
709  ::sincos(m_roll,&sr,&cr);
710 # else
711  const double cy = cos(m_yaw);
712  const double sy = sin(m_yaw);
713  const double cp = cos(m_pitch);
714  const double sp = sin(m_pitch);
715  const double cr = cos(m_roll);
716  const double sr = sin(m_roll);
717 # endif
718 
719  const double m11_dy = -sy*cp; const double m12_dy = cy*cp; const double m13_dy = 0;
720  const double m11_dp = -cy*sp; const double m12_dp = -sy*sp; const double m13_dp = -cp;
721  const double m11_dr = 0; const double m12_dr = 0; const double m13_dr = 0;
722 
723  const double m21_dy = (-sy*sp*sr-cy*cr); const double m22_dy = (cy*sp*sr-sy*cr); const double m23_dy = 0;
724  const double m21_dp = (cy*cp*sr ); const double m22_dp = (sy*cp*sr ); const double m23_dp = -sp*sr;
725  const double m21_dr = (cy*sp*cr+sy*sr); const double m22_dr = (sy*sp*cr-cy*sr); const double m23_dr = cp*cr;
726 
727  const double m31_dy = (-sy*sp*cr+cy*sr); const double m32_dy = (cy*sp*cr+sy*sr); const double m33_dy = 0;
728  const double m31_dp = (cy*cp*cr ); const double m32_dp = (sy*cp*cr ); const double m33_dp = -sp*cr;
729  const double m31_dr = (-cy*sp*sr+sy*cr); const double m32_dr = (-sy*sp*sr-cy*cr); const double m33_dr = -cp*sr;
730 
731  const double Ax = gx-m_coords[0];
732  const double Ay = gy-m_coords[1];
733  const double Az = gz-m_coords[2];
734 
735  MRPT_ALIGN16 const double nums[3*6] = {
736  -m_ROT(0,0), -m_ROT(1,0), -m_ROT(2,0),
737  Ax*m11_dy + Ay*m12_dy + Az*m13_dy , // d_x'/d_yaw
738  Ax*m11_dp + Ay*m12_dp + Az*m13_dp, // d_x'/d_pitch
739  Ax*m11_dr + Ay*m12_dr + Az*m13_dr, // d_x'/d_roll
740 
741  -m_ROT(0,1), -m_ROT(1,1), -m_ROT(2,1),
742  Ax*m21_dy + Ay*m22_dy + Az*m23_dy, // d_x'/d_yaw
743  Ax*m21_dp + Ay*m22_dp + Az*m23_dp, // d_x'/d_pitch
744  Ax*m21_dr + Ay*m22_dr + Az*m23_dr, // d_x'/d_roll
745 
746  -m_ROT(0,2), -m_ROT(1,2), -m_ROT(2,2),
747  Ax*m31_dy + Ay*m32_dy + Az*m33_dy, // d_x'/d_yaw
748  Ax*m31_dp + Ay*m32_dp + Az*m33_dp, // d_x'/d_pitch
749  Ax*m31_dr + Ay*m32_dr + Az*m33_dr, // d_x'/d_roll
750  };
751  out_jacobian_df_dpose->loadFromArray(nums);
752  }
753 
754  lx = t_inv[0] + R_inv(0,0) * gx + R_inv(0,1) * gy + R_inv(0,2) * gz;
755  ly = t_inv[1] + R_inv(1,0) * gx + R_inv(1,1) * gy + R_inv(1,2) * gz;
756  lz = t_inv[2] + R_inv(2,0) * gx + R_inv(2,1) * gy + R_inv(2,2) * gz;
757 
758  // Jacob: df/dse3
759  if (out_jacobian_df_dse3)
760  {
761  MRPT_ALIGN16 const double nums[3*6] = {
762  -1, 0, 0, 0,-lz, ly,
763  0, -1, 0, lz, 0, -lx,
764  0, 0, -1, -ly, lx, 0 };
765  out_jacobian_df_dse3->loadFromArray(nums);
766  }
767 }
768 
769 CPose3D CPose3D::exp(const mrpt::math::CArrayNumeric<double,6> & mu,bool pseudo_exponential )
770 {
772  CPose3D::exp(mu,P,pseudo_exponential);
773  return P;
774 }
775 
776 void CPose3D::exp(const mrpt::math::CArrayNumeric<double,6> & mu, CPose3D &out_pose, bool pseudo_exponential)
777 {
778  if (pseudo_exponential)
779  {
780  auto R = Sophus::SO3<double>::exp( mu.block<3,1>(3,0) );
781  out_pose.setRotationMatrix(R.matrix());
782  out_pose.x(mu[0]);
783  out_pose.y(mu[1]);
784  out_pose.z(mu[2]);
785  }
786  else
787  {
788  auto R = Sophus::SE3<double>::exp(mu);
789  out_pose = CPose3D( CMatrixDouble44(R.matrix()));
790  }
791 }
792 
794 {
795  Sophus::SO3<double> R(this->m_ROT);
796  return R.log();
797 }
798 
800 {
801  auto R = Sophus::SO3<double>::exp(w);
802  return R.matrix();
803 }
804 
805 void CPose3D::ln(CArrayDouble<6> &result) const
806 {
807  const Sophus::SE3<double> RT(m_ROT, m_coords);
808  result = RT.log();
809 }
810 
811 /* The following code fragments are based on formulas originally reported in the TooN and RobotVision packages */
812 namespace mrpt
813 {
814  namespace poses
815  {
816  template <class VEC3,class MAT33>
817  inline void deltaR(const MAT33& R, VEC3 &v)
818  {
819  v[0]=R(2,1)-R(1,2);
820  v[1]=R(0,2)-R(2,0);
821  v[2]=R(1,0)-R(0,1);
822  }
823 
824  template <typename VEC3,typename MAT3x3,typename MAT3x9>
825  inline void M3x9(
826  const VEC3 &a,
827  const MAT3x3 &B,
828  MAT3x9 &RES)
829  {
830  MRPT_ALIGN16 const double vals[] = {
831  a[0], -B(0,2), B(0,1), B(0,2), a[0], -B(0,0),-B(0,1), B(0,0), a[0],
832  a[1], -B(1,2), B(1,1), B(1,2), a[1], -B(1,0),-B(1,1), B(1,0), a[1],
833  a[2], -B(2,2), B(2,1), B(2,2), a[2], -B(2,0),-B(2,1), B(2,0), a[2]
834  };
835  RES.loadFromArray(vals);
836  }
837 
839  {
840  const CMatrixDouble33 &R = P.getRotationMatrix();
841  const CArrayDouble<3> &t = P.m_coords;
842 
843  CArrayDouble<3> abc;
844  deltaR(R,abc);
845  double a = abc[0];
846  double b = abc[1];
847  double c = abc[2];
848 
849  MRPT_ALIGN16 const double vals[] = {
850  -b*t[1]-c*t[2], 2*b*t[0]-a*t[1], 2*c*t[0]-a*t[2],
851  -b*t[0]+2*a*t[1],-a*t[0]-c*t[2], 2*c*t[1]-b*t[2],
852  -c*t[0]+2*a*t[2],-c*t[1]+2*b*t[2],-a*t[0]-b*t[1]
853  };
854  return CMatrixDouble33(vals);
855  }
856 
857 
859  {
862 
863  const CMatrixDouble33 &R = P.getRotationMatrix();
864  const CArrayDouble<3> &t = P.m_coords;
865 
866  const double d = 0.5*( R(0,0)+R(1,1)+R(2,2)-1);
867 
868  if (d>0.9999)
869  {
870  a[0]=a[1]=a[2]=0;
871  B.zeros();
872  }
873  else
874  {
875  const double theta = acos(d);
876  const double theta2 = square(theta);
877  const double oned2 = (1-square(d));
878  const double sq = std::sqrt(oned2);
879  const double cot = 1./tan(0.5*theta);
880  const double csc2 = square(1./sin(0.5*theta));
881 
883  CArrayDouble<3> vr;
884  deltaR(R,vr);
885  mrpt::math::skew_symmetric3(vr,skewR);
886 
887  CArrayDouble<3> skewR_t;
888  skewR.multiply_Ab(t,skewR_t);
889 
890  skewR_t*= -(d*theta-sq)/(8*pow(sq,3));
891  a = skewR_t;
892 
894  skewR2.multiply_AB(skewR,skewR);
895 
896  CArrayDouble<3> skewR2_t;
897  skewR2.multiply_Ab(t,skewR2_t);
898  skewR2_t*= (((theta*sq-d*theta2)*(0.5*theta*cot-1))-theta*sq*((0.25*theta*cot)+0.125*theta2*csc2-1))/(4*theta2*square(oned2));
899  a += skewR2_t;
900 
902  B *=-0.5*theta/(2*sq);
903 
904  B += -(theta*cot-2)/(8*oned2) * ddeltaRt_dR(P);
905  }
906  M3x9(a,B,J);
907  }
908  }
909 }
910 
912 {
913  J.zeros();
914  // Jacobian structure 6x12:
915  // (3rows, for t) [ d_Vinvt_dR (3x9) | Vinv (3x3) ]
916  // [ -------------------------+------------- ]
917  // (3rows, for \omega) [ d_lnR_dR (3x9) | 0 (3x3) ]
918  //
919  // derivs wrt: R_col1 R_col2 R_col3 | t
920  //
921  // (Will be explained better in: http://www.mrpt.org/6D_poses:equivalences_compositions_and_uncertainty )
922  //
923  {
925  ln_rot_jacob(m_ROT, M);
926  J.insertMatrix(3,0, M);
927  }
928  {
930  dVinvt_dR(*this,M);
931  J.insertMatrix(0,0, M);
932  }
933 
934  const CMatrixDouble33 & R = m_ROT;
935  CArrayDouble<3> omega;
937 
939  V_inv.unit(3,1.0); // Start with the identity_3
940 
941  const double d = 0.5*( R(0,0)+R(1,1)+R(2,2)-1);
942  if (d>0.99999)
943  {
944  mrpt::poses::deltaR(R,omega);
945  omega*=0.5;
946  mrpt::math::skew_symmetric3(omega,Omega);
948  Omega2.multiply_AAt(Omega);
949  Omega2*=1.0/12.0;
950 
951  Omega*=0.5;
952 
953  V_inv -= Omega;
954  V_inv -= Omega2;
955  }
956  else
957  {
958  mrpt::poses::deltaR(R,omega);
959 
960  const double theta = acos(d);
961  omega *=theta/(2*std::sqrt(1-d*d));
962 
963  mrpt::math::skew_symmetric3(omega,Omega);
964 
966  Omega2.multiply_AAt(Omega);
967 
968  Omega2 *= (1-theta/(2*std::tan(theta*0.5)))/square(theta);
969  Omega *= 0.5;
970 
971  V_inv -= Omega;
972  V_inv += Omega2;
973  }
974  J.insertMatrix(0,9, V_inv);
975 }
976 
978 {
979  const double d = 0.5*(R(0,0)+R(1,1)+R(2,2)-1);
982  if(d>0.99999)
983  {
984  a[0]=a[1]=a[2]=0;
985  B.unit(3,-0.5);
986  }
987  else
988  {
989  const double theta = acos(d);
990  const double d2 = square(d);
991  const double sq = std::sqrt(1-d2);
992  deltaR(R,a);
993  a *= (d*theta-sq)/(4*(sq*sq*sq));
994  B.unit(3, -theta/(2*sq) );
995  }
996  M3x9(a,B, M);
997 }
998 
999 // Eq. 10.3.5 in tech report http://ingmec.ual.es/~jlblanco/papers/jlblanco2010geometry3D_techrep.pdf
1000 void CPose3D::jacob_dexpeD_de(const CPose3D &D, Eigen::Matrix<double,12,6> & jacob)
1001 {
1002  jacob.block<9,3>(0,0).setZero();
1003  jacob.block<3,3>(9,0).setIdentity();
1004  for (int i=0;i<3;i++) {
1005  Eigen::Block< Eigen::Matrix<double,12,6>,3,3,false> trg_blc = jacob.block<3,3>(3*i,3);
1006  mrpt::math::skew_symmetric3_neg( D.m_ROT.block<3,1>(0,i), trg_blc );
1007  }
1008  {
1009  Eigen::Block< Eigen::Matrix<double,12,6>,3,3,false> trg_blc = jacob.block<3,3>(9,3);
1011  }
1012 }
1013 
1014 // Eq. 10.3.7 in tech report http://ingmec.ual.es/~jlblanco/papers/jlblanco2010geometry3D_techrep.pdf
1015 void CPose3D::jacob_dAexpeD_de(const CPose3D &A, const CPose3D &D, Eigen::Matrix<double,12,6> & jacob)
1016 {
1017  jacob.block<9,3>(0,0).setZero();
1018  jacob.block<3,3>(9,0) = A.getRotationMatrix();
1019  Eigen::Matrix<double,3,3> aux;
1020  for (int i=0;i<3;i++) {
1021  mrpt::math::skew_symmetric3_neg( D.getRotationMatrix().block<3,1>(0,i),aux );
1022  jacob.block<3,3>(3*i,3) = A.m_ROT * aux;
1023  }
1025  jacob.block<3,3>(9,3) = A.m_ROT * aux;
1026 }
1027 
1029 {
1030  for (int i=0;i<3;i++)
1031  for (int j=0;j<3;j++)
1032  m_ROT(i,j) = std::numeric_limits<double>::quiet_NaN();
1033 
1034  for (int i=0;i<3;i++)
1035  m_coords[i] = std::numeric_limits<double>::quiet_NaN();
1036 }
void readFromStream(mrpt::utils::CStream &in, int version)
Introduces a pure virtual method responsible for loading from a CStream This can not be used directly...
Definition: CPose3D.cpp:167
#define local
Definition: zutil.h:47
double x() const
Common members of all points & poses classes.
Definition: CPoseOrPoint.h:113
void inverseComposeFrom(const CPose3D &A, const CPose3D &B)
Makes this method is slightly more efficient than "this= A - B;" since it avoids the temporary objec...
Definition: CPose3D.cpp:657
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
Definition: zip.h:16
GLdouble GLdouble t
Definition: glext.h:3610
GLdouble GLdouble z
Definition: glext.h:3734
static mrpt::math::CMatrixDouble33 exp_rotation(const mrpt::math::CArrayNumeric< double, 3 > &vect)
Exponentiate a vector in the Lie algebra to generate a new SO(3) (a 3x3 rotation matrix).
Definition: CPose3D.cpp:799
mxArray * convertToMatlab(const Eigen::EigenBase< Derived > &mat)
Convert vectors, arrays and matrices into Matlab vectors/matrices.
Definition: utils_matlab.h:38
The virtual base class which provides a unified interface for all persistent objects in MRPT...
Definition: CSerializable.h:39
void skew_symmetric3(const VECTOR &v, MATRIX &M)
Computes the 3x3 skew symmetric matrix from a 3-vector or 3-array: .
Definition: geometry.h:657
mrpt::math::CMatrixDouble33 m_ROT
The 3x3 rotation matrix, access with getRotationMatrix(), setRotationMatrix() (It&#39;s not safe to set t...
Definition: CPose3D.h:83
bool isHorizontal(const double tolerance=0) const
Return true if the 6D pose represents a Z axis almost exactly vertical (upwards or downwards)...
Definition: CPose3D.cpp:645
double roll
Roll coordinate (rotation angle over X coordinate).
bool m_ypr_uptodate
Whether yaw/pitch/roll members are up-to-date since the last rotation matrix update.
Definition: CPose3D.h:85
GLdouble GLdouble GLdouble GLdouble q
Definition: glext.h:3626
mrpt::math::CArrayDouble< 3 > ln_rotation() const
Take the logarithm of the 3x3 rotation matrix, generating the corresponding vector in the Lie Algebra...
Definition: CPose3D.cpp:793
This file implements several operations that operate element-wise on individual or pairs of container...
CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...
Definition: CArrayNumeric.h:25
double m_roll
These variables are updated every time that the object rotation matrix is modified (construction...
Definition: CPose3D.h:86
void getAsQuaternion(mrpt::math::CQuaternion< double > &q, mrpt::math::CMatrixFixedNumeric< double, 4, 3 > *out_dq_dr=NULL) const
Returns the quaternion associated to the rotation of this object (NOTE: XYZ translation is ignored) ...
Column vector, like Eigen::MatrixX*, but automatically initialized to zeros since construction...
Definition: eigen_frwds.h:35
CMatrixFixedNumeric< double, 4, 4 > CMatrixDouble44
Definition: eigen_frwds.h:49
double pitch() const
Get the PITCH angle (in radians)
Definition: CPose3D.h:392
double yaw() const
Get the YAW angle (in radians)
Definition: CPose3D.h:391
CPose3D operator+(const CPose3D &b) const
The operator is the pose compounding operator.
Definition: CPose3D.h:190
void rebuildRotationMatrix()
Rebuild the homog matrix from the angles.
Definition: CPose3D.cpp:289
#define M_PI
Definition: bits.h:78
double z
X,Y,Z coordinates.
double yaw
Yaw coordinate (rotation angle over Z axis).
IMPLEMENTS_SERIALIZABLE(CLogFileRecord_FullEval, CHolonomicLogFileRecord, mrpt::nav) IMPLEMENTS_SERIALIZABLE(CHolonomicFullEval
GLdouble s
Definition: glext.h:3602
void updateYawPitchRoll() const
Updates Yaw/pitch/roll members from the m_ROT.
Definition: CPose3D.h:92
void inverse()
Convert this pose into its inverse, saving the result in itself.
Definition: CPose3D.cpp:630
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:3962
void setRotationMatrix(const mrpt::math::CMatrixDouble33 &ROT)
Sets the 3x3 rotation matrix.
Definition: CPose3D.h:181
T square(const T x)
Inline function for the square of a number.
Definition: bits.h:52
double distanceEuclidean6D(const CPose3D &o) const
The euclidean distance between two poses taken as two 6-length vectors (angles in radians)...
Definition: CPose3D.cpp:422
#define ASSERTDEBMSG_(f, __ERROR_MSG)
static void jacob_dexpeD_de(const CPose3D &D, Eigen::Matrix< double, 12, 6 > &jacob)
The Jacobian d (e^eps * D) / d eps , with eps=increment in Lie Algebra.
Definition: CPose3D.cpp:1000
void skew_symmetric3_neg(const VECTOR &v, MATRIX &M)
Computes the negative version of a 3x3 skew symmetric matrix from a 3-vector or 3-array: ...
Definition: geometry.h:682
void composePoint(double lx, double ly, double lz, double &gx, double &gy, double &gz, mrpt::math::CMatrixFixedNumeric< double, 3, 3 > *out_jacobian_df_dpoint=NULL, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dpose=NULL, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dse3=NULL, bool use_small_rot_approx=false) const
An alternative, slightly more efficient way of doing with G and L being 3D points and P this 6D pose...
Definition: CPose3D.cpp:439
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:38
A numeric matrix of compile-time fixed size.
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:19
void dVinvt_dR(const CPose3D &P, CMatrixFixedNumeric< double, 3, 9 > &J)
Definition: CPose3D.cpp:858
mrpt::math::CArrayDouble< 3 > m_coords
The translation vector [x,y,z] access directly or with x(), y(), z() setter/getter methods...
Definition: CPose3D.h:81
void composeFrom(const CPose3D &A, const CPose3D &B)
Makes "this = A (+) B"; this method is slightly more efficient than "this= A + B;" since it avoids th...
Definition: CPose3D.cpp:607
void setToNaN() MRPT_OVERRIDE
Set all data fields to quiet NaN.
Definition: CPose3D.cpp:1028
const GLubyte * c
Definition: glext.h:5590
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
bool operator!=(const CPoint< DERIVEDCLASS > &p1, const CPoint< DERIVEDCLASS > &p2)
Definition: CPoint.h:138
CPose2D BASE_IMPEXP operator-(const CPose2D &p)
Unary - operator: return the inverse pose "-p" (Note that is NOT the same than a pose with negative x...
Definition: CPose2D.cpp:307
void addComponents(const CPose3D &p)
Scalar sum of all 6 components: This is diferent from poses composition, which is implemented as "+" ...
Definition: CPose3D.cpp:406
void sphericalCoordinates(const mrpt::math::TPoint3D &point, double &out_range, double &out_yaw, double &out_pitch) const
Computes the spherical coordinates of a 3D point as seen from the 6D pose specified by this object...
Definition: CPose3D.cpp:377
void M3x9(const VEC3 &a, const MAT3x3 &B, MAT3x9 &RES)
Definition: CPose3D.cpp:825
GLubyte GLubyte b
Definition: glext.h:5575
#define IMPLEMENTS_MEXPLUS_FROM(complete_type)
CMatrixFixedNumeric< double, 3, 3 > CMatrixDouble33
Definition: eigen_frwds.h:48
int version
Definition: mrpt_jpeglib.h:898
A class used to store a 3D pose as a translation (x,y,z) and a quaternion (qr,qx,qy,qz).
Definition: CPose3DQuat.h:41
void deltaR(const MAT33 &R, VEC3 &v)
Definition: CPose3D.cpp:817
T wrapToPi(T a)
Modifies the given angle to translate it into the ]-pi,pi] range.
Definition: wrap2pi.h:51
A class used to store a 2D point.
Definition: CPoint2D.h:36
A class used to store a 3D point.
Definition: CPoint3D.h:32
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Definition: CPoint.h:17
double roll() const
Get the ROLL angle (in radians)
Definition: CPose3D.h:393
double pitch
Pitch coordinate (rotation angle over Y axis).
void operator*=(const double s)
Scalar multiplication of x,y,z,yaw,pitch & roll (angles will be wrapped to the ]-pi,pi] interval).
Definition: CPose3D.cpp:318
void getYawPitchRoll(double &yaw, double &pitch, double &roll) const
Returns the three angles (yaw, pitch, roll), in radians, from the rotation matrix.
Definition: CPose3D.cpp:333
#define RAD2DEG
void ln_jacob(mrpt::math::CMatrixFixedNumeric< double, 6, 12 > &J) const
Jacobian of the logarithm of the 3x4 matrix defined by this pose.
Definition: CPose3D.cpp:911
const GLdouble * v
Definition: glext.h:3603
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
CMatrixDouble33 ddeltaRt_dR(const CPose3D &P)
Definition: CPose3D.cpp:838
void inverseComposePoint(const double gx, const double gy, const double gz, double &lx, double &ly, double &lz, mrpt::math::CMatrixFixedNumeric< double, 3, 3 > *out_jacobian_df_dpoint=NULL, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dpose=NULL, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dse3=NULL) const
Computes the 3D point L such as .
Definition: CPose3D.cpp:683
#define ASSERT_ABOVEEQ_(__A, __B)
GLdouble GLdouble GLdouble r
Definition: glext.h:3618
size_t size(const MATRIXLIKE &m, const int dim)
bool operator==(const CPoint< DERIVEDCLASS > &p1, const CPoint< DERIVEDCLASS > &p2)
Definition: CPoint.h:130
virtual mxArray * writeToMatlab() const
Introduces a pure virtual method responsible for writing to a mxArray Matlab object, typically a MATLAB struct whose contents are documented in each derived class.
Definition: CSerializable.h:79
void homogeneousMatrixInverse(const MATRIXLIKE1 &M, MATRIXLIKE2 &out_inverse_M)
Efficiently compute the inverse of a 4x4 homogeneous matrix by only transposing the rotation 3x3 part...
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle...
Definition: CPose2D.h:36
const float R
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:72
static void ln_rot_jacob(const mrpt::math::CMatrixDouble33 &R, mrpt::math::CMatrixFixedNumeric< double, 3, 9 > &M)
Static function to compute the Jacobian of the SO(3) Logarithm function, evaluated at a given 3x3 rot...
Definition: CPose3D.cpp:977
This file implements matrix/vector text and binary serialization.
mrpt::math::CArrayDouble< 3 > m_rotvec
The rotation vector [vx,vy,vz].
Definition: CPose3DRotVec.h:48
CPose3D()
Default constructor, with all the coordinates set to zero.
Definition: CPose3D.cpp:55
void setFromValues(const double x0, const double y0, const double z0, const double yaw=0, const double pitch=0, const double roll=0)
Set the pose from a 3D position (meters) and yaw/pitch/roll angles (radians) - This method recomputes...
Definition: CPose3D.cpp:266
Lightweight 3D pose (three spatial coordinates, plus three angular coordinates).
GLuint in
Definition: glext.h:6301
#define ASSERT_(f)
A partial specialization of CArrayNumeric for double numbers.
Definition: CArrayNumeric.h:74
GLenum GLint GLint y
Definition: glext.h:3516
void normalizeAngles()
Rebuild the internal matrix & update the yaw/pitch/roll angles within the ]-PI,PI] range (Must be cal...
Definition: CPose3D.cpp:257
mrpt::math::CArrayDouble< 6 > ln() const
Definition: CPose3D.h:477
A 3D pose, with a 3D translation and a rotation in 3D parameterized in rotation-vector form (equivale...
Definition: CPose3DRotVec.h:41
GLenum GLint x
Definition: glext.h:3516
A quaternion, which can represent a 3D rotation as pair , with a real part "r" and a 3D vector ...
Definition: CQuaternion.h:43
void getRotationMatrix(mrpt::math::CMatrixDouble33 &ROT) const
Get the 3x3 rotation matrix.
Definition: CPose3D.h:176
Lightweight 3D point.
void getAsVector(mrpt::math::CVectorDouble &v) const
Returns a 1x6 vector with [x y z yaw pitch roll].
Definition: CPose3D.cpp:531
This class is a "CSerializable" wrapper for "CMatrixFloat".
Definition: CMatrix.h:30
GLubyte GLubyte GLubyte a
Definition: glext.h:5575
static CPose3D exp(const mrpt::math::CArrayNumeric< double, 6 > &vect, bool pseudo_exponential=false)
Exponentiate a Vector in the SE(3) Lie Algebra to generate a new CPose3D (static method).
Definition: CPose3D.cpp:769
GLfloat GLfloat p
Definition: glext.h:5587
void writeToStream(mrpt::utils::CStream &out, int *getVersion) const
Introduces a pure virtual method responsible for writing to a CStream.
Definition: CPose3D.cpp:146
double z
X,Y,Z, coords.
#define MRPT_ALIGN16
void getAsQuaternion(mrpt::math::CQuaternionDouble &q, mrpt::math::CMatrixFixedNumeric< double, 4, 3 > *out_dq_dr=NULL) const
Returns the quaternion associated to the rotation of this object (NOTE: XYZ translation is ignored) ...
Definition: CPose3D.cpp:565
static void jacob_dAexpeD_de(const CPose3D &A, const CPose3D &D, Eigen::Matrix< double, 12, 6 > &jacob)
The Jacobian d (A * e^eps * D) / d eps , with eps=increment in Lie Algebra.
Definition: CPose3D.cpp:1015
struct mxArray_tag mxArray
Forward declaration for mxArray (avoid #including as much as possible to speed up compiling) ...
Definition: CSerializable.h:17
std::ostream & operator<<(std::ostream &o, const CPoint< DERIVEDCLASS > &p)
Dumps a point as a string [x,y] or [x,y,z].
Definition: CPoint.h:106



Page generated by Doxygen 1.8.14 for MRPT 1.5.9 Git: 690a4699f Wed Apr 15 19:29:53 2020 +0200 at miƩ abr 15 19:30:12 CEST 2020