13 #include <gtest/gtest.h> 29 double x1,
double y1,
double z1,
double yaw1,
double pitch1,
32 const CPose3D p1(x1, y1,
z1, yaw1, pitch1, roll1);
40 EXPECT_NEAR((HM * HMi - I4).array().abs().
sum(), 0, 1e-3)
43 << HMi <<
"inv(HM)*HM:\n" 60 <<
"p1: " << p1 <<
"p1_inv_inv: " << p1_inv_inv << endl;
62 EXPECT_NEAR((HMi_from_p1_inv - HMi).array().abs().
sum(), 0, 1e-4)
63 <<
"HMi_from_p1_inv:\n" 64 << HMi_from_p1_inv <<
"HMi:\n" 69 double x1,
double y1,
double z1,
double yaw1,
double pitch1,
70 double roll1,
double x2,
double y2,
double z2,
double yaw2,
71 double pitch2,
double roll2)
73 const CPose3D p1(x1, y1,
z1, yaw1, pitch1, roll1);
74 const CPose3D p2(x2, y2,
z2, yaw2, pitch2, roll2);
76 const CPose3D p1_c_p2 = p1 + p2;
77 const CPose3D p1_i_p2 = p1 - p2;
79 const CPose3D p1_c_p2_i_p2 = p1_c_p2 - p1;
80 const CPose3D p2_c_p1_i_p2 = p2 + p1_i_p2;
88 <<
"p2 : " << p2 << endl
89 <<
"p1_c_p2_i_p2: " << p1_c_p2_i_p2 << endl;
97 <<
"p1 : " << p1 << endl
98 <<
"p2 : " << p2 << endl
99 <<
"p2 matrix : " << endl
101 <<
"p1_i_p2 : " << p1_i_p2 << endl
102 <<
"p1_i_p2 matrix: " << endl
103 << p1_i_p2.getHomogeneousMatrixVal() << endl
104 <<
"p2_c_p1_i_p2: " << p2_c_p1_i_p2 << endl;
148 EXPECT_FLOAT_EQ(p2d.
x(), p2d_bis.
x()) <<
"p2d: " << p2d << endl;
149 EXPECT_FLOAT_EQ(p2d.
y(), p2d_bis.
y()) <<
"p2d: " << p2d << endl;
150 EXPECT_FLOAT_EQ(p2d.
phi(), p2d_bis.
phi()) <<
"p2d: " << p2d << endl;
152 EXPECT_FLOAT_EQ(p2d.
phi(), p3d.
yaw()) <<
"p2d: " << p2d << endl;
156 double x1,
double y1,
double z1,
double yaw1,
double pitch1,
157 double roll1,
double x2,
double y2,
double z2,
double yaw2,
158 double pitch2,
double roll2)
160 const CPose3D p1(x1, y1,
z1, yaw1, pitch1, roll1);
161 const CPose3D p2(x2, y2,
z2, yaw2, pitch2, roll2);
163 const CPose3D p1_plus_p2 = p1 + p2;
176 <<
"p2 : " << p2 << endl
177 <<
"p1 : " << p1 << endl
178 <<
"p1_plus_p2 : " << p1_plus_p2 << endl
179 <<
"p1_plus_p2bis : " << p1_plus_p2bis << endl;
193 <<
"p2 : " << p2 << endl
194 <<
"p1 : " << p1 << endl
195 <<
"p1_plus_p2 : " << p1_plus_p2 << endl
196 <<
"p1_plus_p2bis : " << p1_plus_p2bis << endl;
210 <<
"p2 : " << p2 << endl
211 <<
"p1 : " << p1 << endl
212 <<
"p1_plus_p2 : " << p1_plus_p2 << endl
213 <<
"p1_plus_p2bis : " << p1_plus_p2bis << endl;
218 double x1,
double y1,
double z1,
double yaw1,
double pitch1,
219 double roll1,
double x,
double y,
double z)
221 const CPose3D p1(x1, y1,
z1, yaw1, pitch1, roll1);
227 p.x(),
p.y(),
p.z(), p1_plus_p2.
x(), p1_plus_p2.
y(),
245 0, std::abs(
x - p1_plus_p.
x()) + std::abs(
y - p1_plus_p.
y()) +
246 std::abs(
z - p1_plus_p.z()),
253 p1.inverseComposePoint(
254 p1_plus_p.
x(), p1_plus_p.
y(), p1_plus_p.z(), p_recov2.
x(),
255 p_recov2.
y(), p_recov2.z());
277 for (
int i = 0; i < 3; i++) Y[i] = pp[i];
293 double x1,
double y1,
double z1,
double yaw1,
double pitch1,
294 double roll1,
double x,
double y,
double z,
bool use_aprox =
false)
296 const CPose3D p1(x1, y1,
z1, yaw1, pitch1, roll1);
304 x,
y,
z, pp.
x, pp.
y, pp.
z, &df_dpoint, &df_dpose,
nullptr,
312 for (
int i = 0; i < 6; i++) x_mean[i] = p1[i];
319 x_incrs.assign(1e-7);
322 x_mean, std::function<
void(
325 x_incrs, DUMMY, numJacobs);
327 numJacobs.extractMatrix(0, 0, num_df_dpose);
328 numJacobs.extractMatrix(0, 6, num_df_dpoint);
331 const double max_eror = use_aprox ? 0.1 : 3e-3;
334 0, (df_dpoint - num_df_dpoint).array().abs().
sum(), max_eror)
335 <<
"p1: " << p1 << endl
336 <<
"p: " <<
p << endl
337 <<
"Numeric approximation of df_dpoint: " << endl
338 << num_df_dpoint << endl
339 <<
"Implemented method: " << endl
342 << df_dpoint - num_df_dpoint << endl;
344 EXPECT_NEAR(0, (df_dpose - num_df_dpose).array().abs().
sum(), max_eror)
345 <<
"p1: " << p1 << endl
346 <<
"p: " <<
p << endl
347 <<
"Numeric approximation of df_dpose: " << endl
348 << num_df_dpose << endl
349 <<
"Implemented method: " << endl
352 << df_dpose - num_df_dpose << endl;
356 double x1,
double y1,
double z1,
double yaw1,
double pitch1,
359 const CPose3D p1(x1, y1,
z1, yaw1, pitch1, roll1);
365 <<
"p1: " << p1 << endl;
369 double x1,
double y1,
double z1,
double yaw1,
double pitch1,
370 double roll1,
double x,
double y,
double z)
372 const CPose3D p1(x1, y1,
z1, yaw1, pitch1, roll1);
380 x,
y,
z, pp.
x, pp.
y, pp.
z, &df_dpoint, &df_dpose);
387 for (
int i = 0; i < 6; i++) x_mean[i] = p1[i];
394 x_incrs.assign(1e-7);
397 x_mean, std::function<
void(
400 x_incrs, DUMMY, numJacobs);
402 numJacobs.extractMatrix(0, 0, num_df_dpose);
403 numJacobs.extractMatrix(0, 6, num_df_dpoint);
406 EXPECT_NEAR(0, (df_dpoint - num_df_dpoint).array().abs().
sum(), 3e-3)
407 <<
"p1: " << p1 << endl
408 <<
"p: " <<
p << endl
409 <<
"Numeric approximation of df_dpoint: " << endl
410 << num_df_dpoint << endl
411 <<
"Implemented method: " << endl
414 << df_dpoint - num_df_dpoint << endl;
416 EXPECT_NEAR(0, (df_dpose - num_df_dpose).array().abs().
sum(), 3e-3)
417 <<
"p1: " << p1 << endl
418 <<
"p: " <<
p << endl
419 <<
"Numeric approximation of df_dpose: " << endl
420 << num_df_dpose << endl
421 <<
"Implemented method: " << endl
424 << df_dpose - num_df_dpose << endl;
432 EXPECT_EQ(
p.yaw(), 0);
433 EXPECT_EQ(
p.pitch(), 0);
434 EXPECT_EQ(
p.roll(), 0);
435 for (
size_t i = 0; i < 4; i++)
436 for (
size_t j = 0; j < 4; j++)
438 p.getHomogeneousMatrixVal()(i, j), i == j ? 1.0 : 0.0, 1e-8)
439 <<
"Failed for (i,j)=" << i <<
"," << j << endl
440 <<
"Matrix is: " << endl
441 <<
p.getHomogeneousMatrixVal() << endl
442 <<
"case was: " << label << endl;
451 for (
int i = 0; i < 3; i++) Y[i] = pp[i];
460 for (
int i = 0; i < 3; i++) Y[i] = pp[i];
469 x_l.
x, x_l.
y, x_l.
z, pp.
x, pp.
y, pp.
z,
nullptr,
nullptr, &df_dse3);
475 for (
int i = 0; i < 6; i++) x_mean[i] = 0;
478 for (
int i = 0; i < 3; i++) P[i] = pp[i];
481 x_incrs.assign(1e-9);
483 x_mean, std::function<
void(
486 x_incrs, P, num_df_dse3);
489 EXPECT_NEAR(0, (df_dse3 - num_df_dse3).array().abs().
sum(), 3e-3)
490 <<
"p: " <<
p << endl
491 <<
"x_l: " << x_l << endl
492 <<
"Numeric approximation of df_dse3: " << endl
493 << num_df_dse3 << endl
494 <<
"Implemented method: " << endl
497 << df_dse3 - num_df_dse3 << endl;
505 p.inverseComposePoint(
506 x_g.
x, x_g.
y, x_g.
z, pp.
x, pp.
y, pp.
z,
nullptr,
nullptr, &df_dse3);
512 for (
int i = 0; i < 6; i++) x_mean[i] = 0;
515 for (
int i = 0; i < 3; i++) P[i] = pp[i];
518 x_incrs.assign(1e-9);
520 x_mean, std::function<
void(
523 x_incrs, P, num_df_dse3);
526 EXPECT_NEAR(0, (df_dse3 - num_df_dse3).array().abs().
sum(), 3e-3)
527 <<
"p: " <<
p << endl
528 <<
"x_g: " << x_g << endl
529 <<
"Numeric approximation of df_dse3: " << endl
530 << num_df_dse3 << endl
531 <<
"Implemented method: " << endl
534 << df_dse3 - num_df_dse3 << endl;
550 for (
int i = 0; i < 6; i++) x_mean[i] = 0;
554 x_incrs.assign(1e-9);
557 x_mean, std::function<
void(
560 x_incrs, dummy, numJacobs);
567 double vals[12 * 6] = {
568 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0,
570 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
572 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0,
574 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0};
577 EXPECT_NEAR((numJacobs - M).array().abs().maxCoeff(), 0, 1e-5)
579 << M <<
"numJacobs:\n" 580 << numJacobs <<
"\n";
589 p.setFrom12Vector(
x);
591 auto R =
p.getRotationMatrix();
593 R.jacobiSvd(Eigen::ComputeFullU | Eigen::ComputeFullV);
594 R = Rsvd.matrixU() * Rsvd.matrixV().transpose();
595 p.setRotationMatrix(
R);
602 double x1,
double y1,
double z1,
double yaw1,
double pitch1,
605 const CPose3D p(x1, y1,
z1, yaw1, pitch1, roll1);
608 p.ln_jacob(theor_jacob);
613 p.getAs12Vector(x_mean);
617 x_incrs.assign(1e-6);
619 x_mean, std::function<
void(
622 x_incrs, dummy, numJacobs);
625 EXPECT_NEAR((numJacobs - theor_jacob).array().abs().
sum(), 0, 1e-3)
626 <<
"Pose: " <<
p << endl
628 <<
p.getHomogeneousMatrixVal() <<
"Num. Jacob:\n" 631 << theor_jacob << endl
633 << theor_jacob - numJacobs << endl;
643 const CPose3D expe_D = incr + D;
650 double x1,
double y1,
double z1,
double yaw1,
double pitch1,
653 const CPose3D p(x1, y1,
z1, yaw1, pitch1, roll1);
655 Eigen::Matrix<double, 12, 6> theor_jacob;
664 x_incrs.assign(1e-6);
666 x_mean, std::function<
void(
669 x_incrs,
p, numJacobs);
672 EXPECT_NEAR((numJacobs - theor_jacob).array().abs().maxCoeff(), 0, 1e-3)
673 <<
"Pose: " <<
p << endl
675 <<
p.getHomogeneousMatrixVal() <<
"Num. Jacob:\n" 678 << theor_jacob << endl
680 << theor_jacob - numJacobs << endl;
702 double x1,
double y1,
double z1,
double yaw1,
double pitch1,
703 double roll1,
double x2,
double y2,
double z2,
double yaw2,
704 double pitch2,
double roll2)
706 const CPose3D A(x1, y1,
z1, yaw1, pitch1, roll1);
707 const CPose3D D(x2, y2,
z2, yaw2, pitch2, roll2);
709 Eigen::Matrix<double, 12, 6> theor_jacob;
721 x_incrs.assign(1e-6);
723 x_mean, std::function<
void(
727 x_incrs,
params, numJacobs);
730 EXPECT_NEAR((numJacobs - theor_jacob).array().abs().maxCoeff(), 0, 1e-3)
731 <<
"Pose A: " << A << endl
732 <<
"Pose D: " << D << endl
736 << theor_jacob << endl
738 << theor_jacob - numJacobs << endl;
747 test_default_values(
p,
"Default");
752 test_default_values(
p,
"p=p2");
756 test_default_values(p1 + p2,
"p1+p2");
758 test_default_values(
p,
"p=p1+p2");
763 test_default_values(
p,
"p1-p2");
770 EXPECT_NEAR(
p.x(), 1, 1e-7);
771 EXPECT_NEAR(
p.y(), 2, 1e-7);
772 EXPECT_NEAR(
p.z(), 3, 1e-7);
773 EXPECT_NEAR(
p.yaw(), 0.2, 1e-7);
774 EXPECT_NEAR(
p.pitch(), 0.3, 1e-7);
775 EXPECT_NEAR(
p.roll(), 0.4, 1e-7);
781 EXPECT_NEAR(
p[0], 1, 1e-7);
782 EXPECT_NEAR(
p[1], 2, 1e-7);
783 EXPECT_NEAR(
p[2], 3, 1e-7);
784 EXPECT_NEAR(
p[3], 0.2, 1e-7);
785 EXPECT_NEAR(
p[4], 0.3, 1e-7);
786 EXPECT_NEAR(
p[5], 0.4, 1e-7);
792 {.0, .0, .0, .0, .0, .0},
793 {1.0, 2.0, 3.0, .0, .0, .0},
794 {1.0, 2.0, 3.0, 10.0, .0, .0},
795 {1.0, 2.0, 3.0, .0, 1.0, .0},
796 {1.0, 2.0, 3.0, .0, .0, 1.0},
797 {1.0, 2.0, 3.0, 80.0, 5.0, 5.0},
798 {1.0, 2.0, 3.0, -20.0, -30.0, -40.0},
799 {1.0, 2.0, 3.0, -45.0, 10.0, 70.0},
800 {1.0, 2.0, 3.0, 40.0, -5.0, 25.0},
801 {1.0, 2.0, 3.0, 40.0, 20.0, -15.0},
802 {-6.0, 2.0, 3.0, 40.0, 20.0, 15.0},
803 {6.0, -5.0, 3.0, 40.0, 20.0, 15.0},
804 {6.0, 2.0, -9.0, 40.0, 20.0, 15.0},
805 {0.0, 8.0, 5.0, -45.0, 10.0, 70.0},
806 {1.0, 0.0, 5.0, -45.0, 10.0, 70.0},
807 {1.0, 8.0, 0.0, -45.0, 10.0, 70.0}};
813 for (
size_t i = 0; i <
num_ptc; i++)
821 for (
size_t i = 0; i <
num_ptc; i++)
822 for (
size_t j = 0; j <
num_ptc; j++)
831 for (
size_t i = 0; i <
num_ptc; i++)
832 for (
size_t j = 0; j <
num_ptc; j++)
842 for (
size_t i = 0; i <
num_ptc; i++)
848 for (
size_t i = 0; i <
num_ptc; i++)
867 for (
size_t i = 0; i <
num_ptc; i++)
869 test_composePointJacob(
872 test_composePointJacob(
880 test_composePointJacob(
882 test_composePointJacob(
884 test_composePointJacob(
886 test_composePointJacob(
892 for (
size_t i = 0; i <
num_ptc; i++)
894 test_invComposePointJacob(
897 test_invComposePointJacob(
900 test_invComposePointJacob(
903 test_invComposePointJacob(
911 for (
size_t i = 0; i <
num_ptc; i++)
913 test_composePointJacob_se3(
918 test_composePointJacob_se3(
923 test_composePointJacob_se3(
932 for (
size_t i = 0; i <
num_ptc; i++)
934 test_invComposePointJacob_se3(
939 test_invComposePointJacob_se3(
944 test_invComposePointJacob_se3(
954 for (
size_t i = 0; i <
num_ptc; i++)
975 for (
size_t i = 0; i <
num_ptc; i++)
976 test_Jacob_dexpeD_de(
983 for (
size_t i = 0; i <
num_ptc; i++)
984 for (
size_t j = 0; j <
num_ptc; j++)
985 test_Jacob_dAexpeD_de(
double x() const
Common members of all points & poses classes.
TEST_F(Pose3DTests, DefaultValues)
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
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)
GLdouble GLdouble GLdouble GLdouble q
void test_composePointJacob_se3(const CPose3D &p, const TPoint3D x_l)
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 jacob_numeric_estimate(const VECTORLIKE &x, std::function< void(const VECTORLIKE &x, const USERPARAM &y, VECTORLIKE3 &out)> functor, const VECTORLIKE2 &increments, const USERPARAM &userParam, MATRIXLIKE &out_Jacobian)
Numerical estimation of the Jacobian of a user-supplied function - this template redirects to mrpt::m...
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.
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
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...
mrpt::math::CMatrixDouble44 getHomogeneousMatrixVal() const
void test_invComposePointJacob(double x1, double y1, double z1, double yaw1, double pitch1, double roll1, double x, double y, double z)
void getInverseHomogeneousMatrix(mrpt::math::CMatrixDouble44 &out_HM) const
Returns the corresponding 4x4 inverse homogeneous transformation matrix for this point or pose...
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...
const double & phi() const
Get the phi angle of the 2D pose (in radians)
A partial specialization of CArrayNumeric for double numbers.
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)