14 #include <CTraitsTest.h> 15 #include <gtest/gtest.h> 22 template class mrpt::CTraitsTest<CPose3D>;
30 double x1,
double y1,
double z1,
double yaw1,
double pitch1,
33 const CPose3D p1(x1, y1, z1, yaw1, pitch1, roll1);
43 EXPECT_NEAR((HM * HMi - I4).array().abs().
sum(), 0, 1e-3)
46 << HMi <<
"inv(HM)*HM:\n" 63 <<
"p1: " << p1 <<
"p1_inv_inv: " << p1_inv_inv << endl;
65 EXPECT_NEAR((HMi_from_p1_inv - HMi).array().abs().
sum(), 0, 1e-4)
66 <<
"HMi_from_p1_inv:\n" 67 << HMi_from_p1_inv <<
"HMi:\n" 72 double x1,
double y1,
double z1,
double yaw1,
double pitch1,
73 double roll1,
double x2,
double y2,
double z2,
double yaw2,
74 double pitch2,
double roll2)
76 const CPose3D p1(x1, y1, z1, yaw1, pitch1, roll1);
77 const CPose3D p2(x2, y2, z2, yaw2, pitch2, roll2);
79 const CPose3D p1_c_p2 = p1 + p2;
80 const CPose3D p1_i_p2 = p1 - p2;
82 const CPose3D p1_c_p2_i_p2 = p1_c_p2 - p1;
83 const CPose3D p2_c_p1_i_p2 = p2 + p1_i_p2;
92 <<
"p2 : " << p2 << endl
93 <<
"p1_c_p2_i_p2: " << p1_c_p2_i_p2 << endl;
102 <<
"p1 : " << p1 << endl
103 <<
"p2 : " << p2 << endl
104 <<
"p2 matrix : " << endl
106 <<
"p1_i_p2 : " << p1_i_p2 << endl
107 <<
"p1_i_p2 matrix: " << endl
109 <<
"p2_c_p1_i_p2: " << p2_c_p1_i_p2 << endl;
156 EXPECT_FLOAT_EQ(p2d.
x(), p2d_bis.
x()) <<
"p2d: " << p2d << endl;
157 EXPECT_FLOAT_EQ(p2d.
y(), p2d_bis.
y()) <<
"p2d: " << p2d << endl;
158 EXPECT_FLOAT_EQ(p2d.
phi(), p2d_bis.
phi()) <<
"p2d: " << p2d << endl;
160 EXPECT_FLOAT_EQ(p2d.
phi(), p3d.
yaw()) <<
"p2d: " << p2d << endl;
164 double x1,
double y1,
double z1,
double yaw1,
double pitch1,
165 double roll1,
double x2,
double y2,
double z2,
double yaw2,
166 double pitch2,
double roll2)
168 const CPose3D p1(x1, y1, z1, yaw1, pitch1, roll1);
169 const CPose3D p2(x2, y2, z2, yaw2, pitch2, roll2);
171 const CPose3D p1_plus_p2 = p1 + p2;
184 <<
"p2 : " << p2 << endl
185 <<
"p1 : " << p1 << endl
186 <<
"p1_plus_p2 : " << p1_plus_p2 << endl
187 <<
"p1_plus_p2bis : " << p1_plus_p2bis << endl;
201 <<
"p2 : " << p2 << endl
202 <<
"p1 : " << p1 << endl
203 <<
"p1_plus_p2 : " << p1_plus_p2 << endl
204 <<
"p1_plus_p2bis : " << p1_plus_p2bis << endl;
218 <<
"p2 : " << p2 << endl
219 <<
"p1 : " << p1 << endl
220 <<
"p1_plus_p2 : " << p1_plus_p2 << endl
221 <<
"p1_plus_p2bis : " << p1_plus_p2bis << endl;
226 double x1,
double y1,
double z1,
double yaw1,
double pitch1,
227 double roll1,
double x,
double y,
double z)
229 const CPose3D p1(x1, y1, z1, yaw1, pitch1, roll1);
235 p.x(),
p.y(),
p.z(), p1_plus_p2.
x(), p1_plus_p2.
y(),
255 std::abs(lx - p1_plus_p.
x()) + std::abs(ly - p1_plus_p.
y()) +
256 std::abs(lz - p1_plus_p.z()),
263 p1.inverseComposePoint(
264 p1_plus_p.
x(), p1_plus_p.
y(), p1_plus_p.z(), p_recov2.
x(),
265 p_recov2.
y(), p_recov2.z());
288 for (
int i = 0; i < 3; i++) Y[i] = pp[i];
304 double x1,
double y1,
double z1,
double yaw1,
double pitch1,
305 double roll1,
double x,
double y,
double z,
bool use_aprox =
false)
307 const CPose3D p1(x1, y1, z1, yaw1, pitch1, roll1);
315 x,
y,
z, pp.
x, pp.
y, pp.
z, &df_dpoint, &df_dpose,
nullptr,
323 for (
int i = 0; i < 6; i++) x_mean[i] = p1[i];
330 x_incrs.assign(1e-7);
337 x_incrs, DUMMY, numJacobs);
339 numJacobs.extractMatrix(0, 0, num_df_dpose);
340 numJacobs.extractMatrix(0, 6, num_df_dpoint);
343 const double max_eror = use_aprox ? 0.1 : 3e-3;
346 0, (df_dpoint - num_df_dpoint).array().abs().
sum(), max_eror)
347 <<
"p1: " << p1 << endl
348 <<
"p: " <<
p << endl
349 <<
"Numeric approximation of df_dpoint: " << endl
350 << num_df_dpoint << endl
351 <<
"Implemented method: " << endl
354 << df_dpoint - num_df_dpoint << endl;
356 EXPECT_NEAR(0, (df_dpose - num_df_dpose).array().abs().
sum(), max_eror)
357 <<
"p1: " << p1 << endl
358 <<
"p: " <<
p << endl
359 <<
"Numeric approximation of df_dpose: " << endl
360 << num_df_dpose << endl
361 <<
"Implemented method: " << endl
364 << df_dpose - num_df_dpose << endl;
368 double x1,
double y1,
double z1,
double yaw1,
double pitch1,
371 const CPose3D p1(x1, y1, z1, yaw1, pitch1, roll1);
377 <<
"p1: " << p1 << endl;
381 double x1,
double y1,
double z1,
double yaw1,
double pitch1,
382 double roll1,
double x,
double y,
double z)
384 const CPose3D p1(x1, y1, z1, yaw1, pitch1, roll1);
392 x,
y,
z, pp.
x, pp.
y, pp.
z, &df_dpoint, &df_dpose);
399 for (
int i = 0; i < 6; i++) x_mean[i] = p1[i];
406 x_incrs.assign(1e-7);
413 x_incrs, DUMMY, numJacobs);
415 numJacobs.extractMatrix(0, 0, num_df_dpose);
416 numJacobs.extractMatrix(0, 6, num_df_dpoint);
419 EXPECT_NEAR(0, (df_dpoint - num_df_dpoint).array().abs().
sum(), 3e-3)
420 <<
"p1: " << p1 << endl
421 <<
"p: " <<
p << endl
422 <<
"Numeric approximation of df_dpoint: " << endl
423 << num_df_dpoint << endl
424 <<
"Implemented method: " << endl
427 << df_dpoint - num_df_dpoint << endl;
429 EXPECT_NEAR(0, (df_dpose - num_df_dpose).array().abs().
sum(), 3e-3)
430 <<
"p1: " << p1 << endl
431 <<
"p: " <<
p << endl
432 <<
"Numeric approximation of df_dpose: " << endl
433 << num_df_dpose << endl
434 <<
"Implemented method: " << endl
437 << df_dpose - num_df_dpose << endl;
445 EXPECT_EQ(
p.yaw(), 0);
446 EXPECT_EQ(
p.pitch(), 0);
447 EXPECT_EQ(
p.roll(), 0);
448 for (
size_t i = 0; i < 4; i++)
449 for (
size_t j = 0; j < 4; j++)
452 i == j ? 1.0 : 0.0, 1e-8)
453 <<
"Failed for (i,j)=" << i <<
"," << j << endl
454 <<
"Matrix is: " << endl
456 <<
"case was: " << label << endl;
465 for (
int i = 0; i < 3; i++) Y[i] = pp[i];
474 for (
int i = 0; i < 3; i++) Y[i] = pp[i];
483 x_l.
x, x_l.
y, x_l.
z, pp.
x, pp.
y, pp.
z,
nullptr,
nullptr, &df_dse3);
489 for (
int i = 0; i < 6; i++) x_mean[i] = 0;
492 for (
int i = 0; i < 3; i++) P[i] = pp[i];
495 x_incrs.assign(1e-9);
501 x_incrs, P, num_df_dse3);
504 EXPECT_NEAR(0, (df_dse3 - num_df_dse3).array().abs().
sum(), 3e-3)
505 <<
"p: " <<
p << endl
506 <<
"x_l: " << x_l << endl
507 <<
"Numeric approximation of df_dse3: " << endl
508 << num_df_dse3 << endl
509 <<
"Implemented method: " << endl
512 << df_dse3 - num_df_dse3 << endl;
520 p.inverseComposePoint(
521 x_g.
x, x_g.
y, x_g.
z, pp.
x, pp.
y, pp.
z,
nullptr,
nullptr, &df_dse3);
527 for (
int i = 0; i < 6; i++) x_mean[i] = 0;
530 for (
int i = 0; i < 3; i++) P[i] = pp[i];
533 x_incrs.assign(1e-9);
539 x_incrs, P, num_df_dse3);
542 EXPECT_NEAR(0, (df_dse3 - num_df_dse3).array().abs().
sum(), 3e-3)
543 <<
"p: " <<
p << endl
544 <<
"x_g: " << x_g << endl
545 <<
"Numeric approximation of df_dse3: " << endl
546 << num_df_dse3 << endl
547 <<
"Implemented method: " << endl
550 << df_dse3 - num_df_dse3 << endl;
567 for (
int i = 0; i < 6; i++) x_mean[i] = 0;
571 x_incrs.assign(1e-9);
578 x_incrs, dummy, numJacobs);
585 double vals[12 * 6] = {
586 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0,
588 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
590 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0,
592 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0};
595 EXPECT_NEAR((numJacobs - M).array().abs().maxCoeff(), 0, 1e-5)
597 << M <<
"numJacobs:\n" 598 << numJacobs <<
"\n";
607 p.setFrom12Vector(
x);
609 auto R =
p.getRotationMatrix();
611 R.jacobiSvd(Eigen::ComputeFullU | Eigen::ComputeFullV);
612 R = Rsvd.matrixU() * Rsvd.matrixV().transpose();
613 p.setRotationMatrix(
R);
620 double x1,
double y1,
double z1,
double yaw1,
double pitch1,
623 const CPose3D p(x1, y1, z1, yaw1, pitch1, roll1);
626 p.ln_jacob(theor_jacob);
631 p.getAs12Vector(x_mean);
635 x_incrs.assign(1e-6);
641 x_incrs, dummy, numJacobs);
644 EXPECT_NEAR((numJacobs - theor_jacob).array().abs().
sum(), 0, 1e-3)
645 <<
"Pose: " <<
p << endl
650 << theor_jacob << endl
652 << theor_jacob - numJacobs << endl;
662 const CPose3D expe_D = incr + D;
669 double x1,
double y1,
double z1,
double yaw1,
double pitch1,
672 const CPose3D p(x1, y1, z1, yaw1, pitch1, roll1);
674 Eigen::Matrix<double, 12, 6> theor_jacob;
683 x_incrs.assign(1e-6);
689 x_incrs,
p, numJacobs);
692 EXPECT_NEAR((numJacobs - theor_jacob).array().abs().maxCoeff(), 0, 1e-3)
693 <<
"Pose: " <<
p << endl
698 << theor_jacob << endl
700 << theor_jacob - numJacobs << endl;
722 double x1,
double y1,
double z1,
double yaw1,
double pitch1,
723 double roll1,
double x2,
double y2,
double z2,
double yaw2,
724 double pitch2,
double roll2)
726 const CPose3D A(x1, y1, z1, yaw1, pitch1, roll1);
727 const CPose3D D(x2, y2, z2, yaw2, pitch2, roll2);
729 Eigen::Matrix<double, 12, 6> theor_jacob;
741 x_incrs.assign(1e-6);
748 x_incrs,
params, numJacobs);
751 EXPECT_NEAR((numJacobs - theor_jacob).array().abs().maxCoeff(), 0, 1e-3)
752 <<
"Pose A: " << A << endl
753 <<
"Pose D: " << D << endl
757 << theor_jacob << endl
759 << theor_jacob - numJacobs << endl;
768 test_default_values(
p,
"Default");
773 test_default_values(
p,
"p=p2");
777 test_default_values(p1 + p2,
"p1+p2");
779 test_default_values(
p,
"p=p1+p2");
784 test_default_values(
p,
"p1-p2");
791 EXPECT_NEAR(
p.x(), 1, 1e-7);
792 EXPECT_NEAR(
p.y(), 2, 1e-7);
793 EXPECT_NEAR(
p.z(), 3, 1e-7);
794 EXPECT_NEAR(
p.yaw(), 0.2, 1e-7);
795 EXPECT_NEAR(
p.pitch(), 0.3, 1e-7);
796 EXPECT_NEAR(
p.roll(), 0.4, 1e-7);
802 EXPECT_NEAR(
p[0], 1, 1e-7);
803 EXPECT_NEAR(
p[1], 2, 1e-7);
804 EXPECT_NEAR(
p[2], 3, 1e-7);
805 EXPECT_NEAR(
p[3], 0.2, 1e-7);
806 EXPECT_NEAR(
p[4], 0.3, 1e-7);
807 EXPECT_NEAR(
p[5], 0.4, 1e-7);
813 {.0, .0, .0, .0, .0, .0},
814 {1.0, 2.0, 3.0, .0, .0, .0},
815 {1.0, 2.0, 3.0, 10.0, .0, .0},
816 {1.0, 2.0, 3.0, .0, 1.0, .0},
817 {1.0, 2.0, 3.0, .0, .0, 1.0},
818 {1.0, 2.0, 3.0, 80.0, 5.0, 5.0},
819 {1.0, 2.0, 3.0, -20.0, -30.0, -40.0},
820 {1.0, 2.0, 3.0, -45.0, 10.0, 70.0},
821 {1.0, 2.0, 3.0, 40.0, -5.0, 25.0},
822 {1.0, 2.0, 3.0, 40.0, 20.0, -15.0},
823 {-6.0, 2.0, 3.0, 40.0, 20.0, 15.0},
824 {6.0, -5.0, 3.0, 40.0, 20.0, 15.0},
825 {6.0, 2.0, -9.0, 40.0, 20.0, 15.0},
826 {0.0, 8.0, 5.0, -45.0, 10.0, 70.0},
827 {1.0, 0.0, 5.0, -45.0, 10.0, 70.0},
828 {1.0, 8.0, 0.0, -45.0, 10.0, 70.0}};
834 for (
size_t i = 0; i <
num_ptc; i++)
842 for (
size_t i = 0; i <
num_ptc; i++)
843 for (
size_t j = 0; j <
num_ptc; j++)
852 for (
size_t i = 0; i <
num_ptc; i++)
853 for (
size_t j = 0; j <
num_ptc; j++)
863 for (
size_t i = 0; i <
num_ptc; i++)
869 for (
size_t i = 0; i <
num_ptc; i++)
888 for (
size_t i = 0; i <
num_ptc; i++)
890 test_composePointJacob(
893 test_composePointJacob(
901 test_composePointJacob(
903 test_composePointJacob(
905 test_composePointJacob(
907 test_composePointJacob(
913 for (
size_t i = 0; i <
num_ptc; i++)
915 test_invComposePointJacob(
918 test_invComposePointJacob(
921 test_invComposePointJacob(
924 test_invComposePointJacob(
932 for (
size_t i = 0; i <
num_ptc; i++)
934 test_composePointJacob_se3(
939 test_composePointJacob_se3(
944 test_composePointJacob_se3(
953 for (
size_t i = 0; i <
num_ptc; i++)
955 test_invComposePointJacob_se3(
960 test_invComposePointJacob_se3(
965 test_invComposePointJacob_se3(
975 for (
size_t i = 0; i <
num_ptc; i++)
996 for (
size_t i = 0; i <
num_ptc; i++)
997 test_Jacob_dexpeD_de(
1004 for (
size_t i = 0; i <
num_ptc; i++)
1005 for (
size_t j = 0; j <
num_ptc; j++)
1006 test_Jacob_dAexpeD_de(
double x() const
Common members of all points & poses classes.
TEST_F(Pose3DTests, DefaultValues)
static void func_jacob_expe_D(const CArrayDouble< 6 > &eps, const CPose3D &D, CArrayDouble< 12 > &Y)
void test_composeFrom(double x1, double y1, double z1, double yaw1, double pitch1, double roll1, double x2, double y2, double z2, double yaw2, double pitch2, double roll2)
void test_Jacob_dexpeD_de(double x1, double y1, double z1, double yaw1, double pitch1, double roll1)
mrpt::math::CVectorDouble getAsVectorVal() const
Return the pose or point as a 1xN vector with all the components (see derived classes for each implem...
void test_invComposePointJacob_se3(const CPose3D &p, const TPoint3D x_g)
void test_Jacob_dAexpeD_de(double x1, double y1, double z1, double yaw1, double pitch1, double roll1, double x2, double y2, double z2, double yaw2, double pitch2, double roll2)
double DEG2RAD(const double x)
Degrees to radians.
GLdouble GLdouble GLdouble GLdouble q
void test_composePointJacob_se3(const CPose3D &p, const TPoint3D x_l)
CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...
double yaw() const
Get the YAW angle (in radians)
void test_ExpLnEqual(double x1, double y1, double z1, double yaw1, double pitch1, double roll1)
void inverse()
Convert this pose into its inverse, saving the result in itself.
void test_to_from_2d(double x, double y, double phi)
void test_composePoint(double x1, double y1, double z1, double yaw1, double pitch1, double roll1, double x, double y, double z)
void check_jacob_expe_e_at_0()
void estimateJacobian(const VECTORLIKE &x, const std::function< void(const VECTORLIKE &x, const USERPARAM &y, VECTORLIKE3 &out)> &functor, const VECTORLIKE2 &increments, const USERPARAM &userParam, MATRIXLIKE &out_Jacobian)
Estimate the Jacobian of a multi-dimensional function around a point "x", using finite differences of...
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.
A numeric matrix of compile-time fixed size.
This base provides a set of functions for maths stuff.
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...
void test_invComposePointJacob(double x1, double y1, double z1, double yaw1, double pitch1, double roll1, double x, double y, double z)
CONTAINER::Scalar sum(const CONTAINER &v)
Computes the sum of all the elements.
static void func_compose_point(const CArrayDouble< 6+3 > &x, const double &dummy, CArrayDouble< 3 > &Y)
double x
X,Y,Z coordinates.
GLsizei const GLchar ** string
static void func_compose_point_se3(const CArrayDouble< 6 > &x, const CArrayDouble< 3 > &P, CArrayDouble< 3 > &Y)
A class used to store a 3D point.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
static void func_inv_compose_point(const CArrayDouble< 6+3 > &x, const double &dummy, CArrayDouble< 3 > &Y)
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
static void func_jacob_LnT_T(const CArrayDouble< 12 > &x, const double &dummy, CArrayDouble< 6 > &Y)
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle...
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
void composePoint(double lx, double ly, double lz, double &gx, double &gy, double &gz, mrpt::math::CMatrixFixedNumeric< double, 3, 3 > *out_jacobian_df_dpoint=nullptr, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dpose=nullptr, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dse3=nullptr, 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...
MATRIX44 getHomogeneousMatrixVal() const
Returns the corresponding 4x4 homogeneous transformation matrix for the point(translation) or pose (t...
const double & phi() const
Get the phi angle of the 2D pose (in radians)
void getInverseHomogeneousMatrix(MATRIX44 &out_HM) const
Returns the corresponding 4x4 inverse homogeneous transformation matrix for this point or pose...
static void func_jacob_Aexpe_D(const CArrayDouble< 6 > &eps, const TParams_func_jacob_Aexpe_D ¶ms, CArrayDouble< 12 > &Y)
void check_jacob_LnT_T(double x1, double y1, double z1, double yaw1, double pitch1, double roll1)
static void func_jacob_expe_e(const CArrayDouble< 6 > &x, const double &dummy, CArrayDouble< 12 > &Y)
void test_compose(double x1, double y1, double z1, double yaw1, double pitch1, double roll1, double x2, double y2, double z2, double yaw2, double pitch2, double roll2)
static void func_invcompose_point_se3(const CArrayDouble< 6 > &x, const CArrayDouble< 3 > &P, CArrayDouble< 3 > &Y)
void getAs12Vector(ARRAYORVECTOR &vec12) const
Get the pose representation as an array with these 12 elements: [r11 r21 r31 r12 r22 r32 r13 r23 r33 ...
void ln(mrpt::math::CArrayDouble< 6 > &out_ln) const
Take the logarithm of the 3x4 matrix defined by this pose, generating the corresponding vector in the...
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).
GLenum const GLfloat * params
void test_inverse(double x1, double y1, double z1, double yaw1, double pitch1, double roll1)
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.
void test_default_values(const CPose3D &p, const std::string &label)
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=nullptr, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dpose=nullptr, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dse3=nullptr) const
Computes the 3D point L such as .
void test_composePointJacob(double x1, double y1, double z1, double yaw1, double pitch1, double roll1, double x, double y, double z, bool use_aprox=false)
#define MRPT_UNUSED_PARAM(a)
Determines whether this is an X86 or AMD64 platform.