10 #include <CTraitsTest.h>    11 #include <gtest/gtest.h>    17 #include <Eigen/Dense>    24 template class mrpt::CTraitsTest<CPose3D>;
    37         auto I4 = CMatrixDouble44::Identity();
    40             (HM.asEigen() * HMi.asEigen() - I4.asEigen()).array().abs().sum(),
    44             << HMi << 
"inv(HM)*HM:\n"    45             << (HM * HMi) << endl;
    50         const auto HMi_from_p1_inv =
    62             << 
"p1: " << p1 << 
"p1_inv_inv: " << p1_inv_inv << endl;
    64         EXPECT_NEAR((HMi_from_p1_inv - HMi).sum_abs(), 0, 1e-4)
    65             << 
"HMi_from_p1_inv:\n"    66             << HMi_from_p1_inv << 
"HMi:\n"    72         const CPose3D p1_c_p2 = p1 + p2;
    73         const CPose3D p1_i_p2 = p1 - p2;
    75         const CPose3D p1_c_p2_i_p2 = p1_c_p2 - p1;  
    76         const CPose3D p2_c_p1_i_p2 = p2 + p1_i_p2;  
    86             << 
"p2          : " << p2 << endl
    87             << 
"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
   104             << 
"p2_c_p1_i_p2: " << p2_c_p1_i_p2 << endl;
   154         EXPECT_DOUBLE_EQ(p2d.
x(), p2d_bis.
x()) << 
"p2d: " << p2d << endl;
   155         EXPECT_DOUBLE_EQ(p2d.
y(), p2d_bis.
y()) << 
"p2d: " << p2d << endl;
   156         EXPECT_DOUBLE_EQ(p2d.
phi(), p2d_bis.
phi()) << 
"p2d: " << p2d << endl;
   158         EXPECT_DOUBLE_EQ(p2d.
phi(), p3d.
yaw()) << 
"p2d: " << p2d << endl;
   163         const CPose3D p1_plus_p2 = p1 + p2;
   177                 << 
"p2 : " << p2 << endl
   178                 << 
"p1 : " << p1 << endl
   179                 << 
"p1_plus_p2    : " << p1_plus_p2 << endl
   180                 << 
"p1_plus_p2bis : " << p1_plus_p2bis << endl;
   195                 << 
"p2 : " << p2 << endl
   196                 << 
"p1 : " << p1 << endl
   197                 << 
"p1_plus_p2    : " << p1_plus_p2 << endl
   198                 << 
"p1_plus_p2bis : " << p1_plus_p2bis << endl;
   213                 << 
"p2 : " << p2 << endl
   214                 << 
"p1 : " << p1 << endl
   215                 << 
"p1_plus_p2    : " << p1_plus_p2 << endl
   216                 << 
"p1_plus_p2bis : " << p1_plus_p2bis << endl;
   227             p.x(), p.y(), p.z(), p1_plus_p2.
x(), p1_plus_p2.
y(),
   248                 std::abs(lx - p1_plus_p.
x()) + std::abs(ly - p1_plus_p.
y()) +
   249                     std::abs(lz - p1_plus_p.z()),
   256         p1.inverseComposePoint(
   257             p1_plus_p.
x(), p1_plus_p.
y(), p1_plus_p.z(), p_recov2.
x(),
   258             p_recov2.
y(), p_recov2.z());
   283         CPose3D q(x[0], x[1], x[2], x[3], x[4], x[5]);
   284         const CPoint3D p(x[6 + 0], x[6 + 1], x[6 + 2]);
   286         for (
int i = 0; i < 3; i++) Y[i] = pp[i];
   293         CPose3D q(x[0], x[1], x[2], x[3], x[4], x[5]);
   294         const CPoint3D p(x[6 + 0], x[6 + 1], x[6 + 2]);
   302         const CPose3D& p1, 
double x, 
double y, 
double z, 
bool use_aprox = 
false)
   311             x, y, z, pp.
x, pp.
y, pp.
z, df_dpoint, df_dpose, std::nullopt,
   319             for (
int i = 0; i < 6; i++) x_mean[i] = p1[i];
   333                 x_incrs, DUMMY, numJacobs);
   335             num_df_dpose = numJacobs.
block<3, 6>(0, 0);
   336             num_df_dpoint = numJacobs.
block<3, 3>(0, 6);
   339         const double max_error = use_aprox ? 0.1 : 3e-3;
   341         EXPECT_NEAR(0, (df_dpoint - num_df_dpoint).sum_abs(), max_error)
   342             << 
"p1: " << p1 << endl
   343             << 
"p:  " << p << endl
   344             << 
"Numeric approximation of df_dpoint: " << endl
   345             << num_df_dpoint << endl
   346             << 
"Implemented method: " << endl
   349             << df_dpoint - num_df_dpoint << endl;
   353             (df_dpose.
asEigen() - num_df_dpose.
asEigen()).array().abs().sum(),
   355             << 
"p1: " << p1 << endl
   356             << 
"p:  " << p << endl
   357             << 
"Numeric approximation of df_dpose: " << endl
   358             << num_df_dpose.
asEigen() << endl
   359             << 
"Implemented method: " << endl
   369             << 
"p1: " << p1 << endl;
   373         const CPose3D& p1, 
double x, 
double y, 
double z)
   388             for (
int i = 0; i < 6; i++) x_mean[i] = p1[i];
   402                 x_incrs, DUMMY, numJacobs);
   404             num_df_dpose = numJacobs.
block<3, 6>(0, 0);
   405             num_df_dpoint = numJacobs.
block<3, 3>(0, 6);
   409             0, (df_dpoint - num_df_dpoint).asEigen().array().abs().
sum(), 3e-3)
   410             << 
"p1: " << p1 << endl
   411             << 
"p:  " << p << endl
   412             << 
"Numeric approximation of df_dpoint: " << endl
   413             << num_df_dpoint << endl
   414             << 
"Implemented method: " << endl
   417             << df_dpoint - num_df_dpoint << endl;
   421             (df_dpose.
asEigen() - num_df_dpose.
asEigen()).array().abs().sum(),
   423             << 
"p1: " << p1 << endl
   424             << 
"p:  " << p << endl
   425             << 
"Numeric approximation of df_dpose: " << endl
   426             << num_df_dpose.
asEigen() << endl
   427             << 
"Implemented method: " << endl
   441         for (
size_t i = 0; i < 4; i++)
   442             for (
size_t j = 0; j < 4; j++)
   445                     i == j ? 1.0 : 0.0, 1e-8)
   446                     << 
"Failed for (i,j)=" << i << 
"," << j << endl
   447                     << 
"Matrix is: " << endl
   449                     << 
"case was: " << label << endl;
   459         for (
int i = 0; i < 3; i++) Y[i] = pp[i];
   469         for (
int i = 0; i < 3; i++) Y[i] = pp[i];
   478             x_l.
x, x_l.
y, x_l.
z, pp.
x, pp.
y, pp.
z, std::nullopt, std::nullopt,
   485             for (
int i = 0; i < 6; i++) x_mean[i] = 0;
   488             for (
int i = 0; i < 3; i++) P[i] = pp[i];
   497                     &func_compose_point_se3),
   498                 x_incrs, P, num_df_dse3);
   502             0, (df_dse3.
asEigen() - num_df_dse3.
asEigen()).array().abs().sum(),
   504             << 
"p: " << p << endl
   505             << 
"x_l:  " << x_l << endl
   506             << 
"Numeric approximation of df_dse3: " << endl
   507             << num_df_dse3.
asEigen() << endl
   508             << 
"Implemented method: " << endl
   520             x_g.
x, x_g.
y, x_g.
z, pp.
x, pp.
y, pp.
z, std::nullopt, std::nullopt,
   527             for (
int i = 0; i < 6; i++) x_mean[i] = 0;
   530             for (
int i = 0; i < 3; i++) P[i] = pp[i];
   539                     &func_invcompose_point_se3),
   540                 x_incrs, P, num_df_dse3);
   544             0, (df_dse3.
asEigen() - num_df_dse3.
asEigen()).array().abs().sum(),
   546             << 
"p: " << p << endl
   547             << 
"x_g:  " << x_g << endl
   548             << 
"Numeric approximation of df_dse3: " << endl
   549             << num_df_dse3.
asEigen() << endl
   550             << 
"Implemented method: " << endl
   570         for (
int i = 0; i < 6; i++) x_mean[i] = 0;
   572         const double& dummy = 0.;
   581             x_incrs, dummy, numJacobs);
   588         double vals[12 * 6] = {
   589             0, 0, 0, 0, 0, 0,  0, 0, 0, 0,  0, 1, 0, 0, 0, 0, -1, 0,
   591             0, 0, 0, 0, 0, -1, 0, 0, 0, 0,  0, 0, 0, 0, 0, 1, 0,  0,
   593             0, 0, 0, 0, 1, 0,  0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0,  0,
   595             1, 0, 0, 0, 0, 0,  0, 1, 0, 0,  0, 0, 0, 0, 1, 0, 0,  0};
   602             << M.
asEigen() << 
"numJacobs:\n"   603             << numJacobs << 
"\n";
   616             R.asEigen().jacobiSvd(Eigen::ComputeFullU | Eigen::ComputeFullV);
   617         R = Rsvd.matrixU() * Rsvd.matrixV().transpose();
   633             const double& dummy = 0.;
   641                 x_incrs, dummy, numJacobs);
   645             (numJacobs.
asEigen() - theor_jacob.asEigen()).array().abs().sum(),
   647             << 
"Pose: " << p << endl
   652             << theor_jacob.
asEigen() << endl
   654             << theor_jacob.asEigen() - numJacobs.
asEigen() << endl;
   662         const CPose3D expe_D = incr + D;
   684                 x_incrs, p, numJacobs);
   688             (numJacobs.
asEigen() - theor_jacob.asEigen())
   693             << 
"Pose: " << p << endl
   698             << theor_jacob.
asEigen() << endl
   700             << theor_jacob.asEigen() - numJacobs.
asEigen() << endl;
   708         const CPose3D expe_D = D + incr;
   730                 x_incrs, p, numJacobs);
   734             (numJacobs.
asEigen() - theor_jacob.asEigen())
   739             << 
"Pose: " << p << endl
   744             << theor_jacob.
asEigen() << endl
   746             << theor_jacob.asEigen() - numJacobs.
asEigen() << endl;
   786                 x_incrs, 
params, numJacobs);
   790             (numJacobs.
asEigen() - theor_jacob.asEigen())
   795             << 
"Pose A: " << 
A << endl
   796             << 
"Pose D: " << D << endl
   800             << theor_jacob.
asEigen() << endl
   802             << theor_jacob.asEigen() - numJacobs.
asEigen() << endl;
   811         test_default_values(p, 
"Default");
   816         test_default_values(p, 
"p=p2");
   820         test_default_values(p1 + p2, 
"p1+p2");
   822         test_default_values(p, 
"p=p1+p2");
   827         test_default_values(p, 
"p1-p2");
   833     CPose3D p(1, 2, 3, 0.2, 0.3, 0.4);
   844     CPose3D p(1, 2, 3, 0.2, 0.3, 0.4);
   855 static const std::vector<mrpt::poses::CPose3D> 
ptc = {
   856     {.0, .0, .0, .0_deg, .0_deg, .0_deg},
   857     {1.0, 2.0, 3.0, .0_deg, .0_deg, .0_deg},
   858     {1.0, 2.0, 3.0, 10.0_deg, .0_deg, .0_deg},
   859     {1.0, 2.0, 3.0, .0_deg, 1.0_deg, .0_deg},
   860     {1.0, 2.0, 3.0, .0_deg, .0_deg, 1.0_deg},
   861     {1.0, 2.0, 3.0, 80.0_deg, 5.0_deg, 5.0_deg},
   862     {1.0, 2.0, 3.0, -20.0_deg, -30.0_deg, -40.0_deg},
   863     {1.0, 2.0, 3.0, -45.0_deg, 10.0_deg, 70.0_deg},
   864     {1.0, 2.0, 3.0, 40.0_deg, -5.0_deg, 25.0_deg},
   865     {1.0, 2.0, 3.0, 40.0_deg, 20.0_deg, -15.0_deg},
   866     {-6.0, 2.0, 3.0, 40.0_deg, 20.0_deg, 15.0_deg},
   867     {6.0, -5.0, 3.0, 40.0_deg, 20.0_deg, 15.0_deg},
   868     {6.0, 2.0, -9.0, 40.0_deg, 20.0_deg, 15.0_deg},
   869     {0.0, 8.0, 5.0, -45.0_deg, 10.0_deg, 70.0_deg},
   870     {1.0, 0.0, 5.0, -45.0_deg, 10.0_deg, 70.0_deg},
   871     {1.0, 8.0, 0.0, -45.0_deg, 10.0_deg, 70.0_deg}};
   876     for (
const auto& p : 
ptc) test_inverse(p);
   881     for (
const auto& p1 : 
ptc)
   882         for (
const auto& p2 : 
ptc) test_compose(p1, p2);
   886     for (
const auto& p1 : 
ptc)
   887         for (
const auto& p2 : 
ptc) test_composeFrom(p1, p2);
   892     for (
const auto& p : 
ptc) test_to_from_2d(p.x(), p.y(), p.yaw());
   897     for (
const auto& p : 
ptc)
   899         test_composePoint(p, 10, 11, 12);
   900         test_composePoint(p, -5, 1, 2);
   901         test_composePoint(p, 5, -1, 2);
   902         test_composePoint(p, 5, 1, -2);
   908     for (
const auto& p : 
ptc)
   910         test_composePointJacob(p, 10, 11, 12);
   911         test_composePointJacob(p, -5, 1, 2);
   917     test_composePointJacob(
   920     test_composePointJacob(
   923     test_composePointJacob(
   926     test_composePointJacob(
   933     for (
const auto& p : 
ptc)
   935         test_invComposePointJacob(p, 10, 11, 12);
   936         test_invComposePointJacob(p, -5, 1, 2);
   937         test_invComposePointJacob(p, 5, -1, 2);
   938         test_invComposePointJacob(p, 5, 1, -2);
   944     for (
const auto& p : 
ptc)
   946         test_composePointJacob_se3(p, 
TPoint3D(0, 0, 0));
   947         test_composePointJacob_se3(p, 
TPoint3D(10, 11, 12));
   948         test_composePointJacob_se3(p, 
TPoint3D(-5.0, -15.0, 8.0));
   953     for (
const auto& p : 
ptc)
   955         test_invComposePointJacob_se3(p, 
TPoint3D(0, 0, 0));
   956         test_invComposePointJacob_se3(p, 
TPoint3D(10, 11, 12));
   957         test_invComposePointJacob_se3(p, 
TPoint3D(-5.0, -15.0, 8.0));
   963     for (
const auto& p : 
ptc) test_ExpLnEqual(p);
   981     for (
const auto& p : 
ptc) test_Jacob_dexpeD_de(p);
   986     for (
const auto& p : 
ptc) test_Jacob_dDexpe_de(p);
   991     for (
const auto& p1 : 
ptc)
   992         for (
const auto& p2 : 
ptc) test_Jacob_dAexpeD_de(p1, p2);
 A compile-time fixed-size numeric matrix container. 
 
static void func_compose_point_se3(const CVectorFixedDouble< 6 > &x, const CVectorFixedDouble< 3 > &P, CVectorFixedDouble< 3 > &Y)
 
TEST_F(Pose3DTests, DefaultValues)
 
void test_invComposePointJacob_se3(const CPose3D &p, const TPoint3D x_g)
 
static void func_compose_point(const CVectorFixedDouble< 6+3 > &x, [[maybe_unused]] const double &dummy, CVectorFixedDouble< 3 > &Y)
 
static const std::vector< mrpt::poses::CPose3D > ptc
 
void inverseComposePoint(const double gx, const double gy, const double gz, double &lx, double &ly, double &lz, mrpt::optional_ref< mrpt::math::CMatrixDouble33 > out_jacobian_df_dpoint=std::nullopt, mrpt::optional_ref< mrpt::math::CMatrixDouble36 > out_jacobian_df_dpose=std::nullopt, mrpt::optional_ref< mrpt::math::CMatrixDouble36 > out_jacobian_df_dse3=std::nullopt) const
Computes the 3D point L such as . 
 
void test_inverse(const CPose3D &p1)
 
void test_composePointJacob_se3(const CPose3D &p, const TPoint3D x_l)
 
void test_invComposePointJacob(const CPose3D &p1, double x, double y, double z)
 
void test_Jacob_dexpeD_de(const CPose3D &p)
 
static void func_jacob_expe_D(const CVectorFixedDouble< 6 > &eps, const CPose3D &D, CVectorFixedDouble< 12 > &Y)
 
double pitch() const
Get the PITCH angle (in radians) 
 
void test_composePoint(const CPose3D &p1, double x, double y, double z)
 
double yaw() const
Get the YAW angle (in radians) 
 
mrpt::vision::TStereoCalibParams params
 
static void func_jacob_expe_e(const CVectorFixedDouble< 6 > &x, [[maybe_unused]] const double &dummy, CVectorFixedDouble< 12 > &Y)
 
void inverse()
Convert this pose into its inverse, saving the result in itself. 
 
void test_to_from_2d(double x, double y, double phi)
 
static void func_inv_compose_point(const CVectorFixedDouble< 6+3 > &x, [[maybe_unused]] const double &dummy, CVectorFixedDouble< 3 > &Y)
 
static void func_jacob_Aexpe_D(const CVectorFixedDouble< 6 > &eps, const TParams_func_jacob_Aexpe_D ¶ms, CVectorFixedDouble< 12 > &Y)
 
static void func_jacob_LnT_T(const CVectorFixedDouble< 12 > &x, [[maybe_unused]] const double &dummy, CVectorFixedDouble< 6 > &Y)
 
void setRotationMatrix(const mrpt::math::CMatrixDouble33 &ROT)
Sets the 3x3 rotation matrix. 
 
void check_jacob_expe_e_at_0()
 
This base provides a set of functions for maths stuff. 
 
void test_ExpLnEqual(const CPose3D &p1)
 
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...
 
double phi() const
Get the phi angle of the 2D pose (in radians) 
 
void test_Jacob_dAexpeD_de(const CPose3D &A, const CPose3D &D)
 
void getInverseHomogeneousMatrix(MATRIX44 &out_HM) const
Returns the corresponding 4x4 inverse homogeneous transformation matrix for this point or pose...
 
auto block(int start_row, int start_col)
non-const block(): Returns an Eigen::Block reference to the block 
 
CONTAINER::Scalar sum(const CONTAINER &v)
Computes the sum of all the elements. 
 
void test_composePointJacob(const CPose3D &p1, double x, double y, double z, bool use_aprox=false)
 
static void func_invcompose_point_se3(const CVectorFixedDouble< 6 > &x, const CVectorFixedDouble< 3 > &P, CVectorFixedDouble< 3 > &Y)
 
TPoint3D_< double > TPoint3D
Lightweight 3D point. 
 
double x() const
Common members of all points & poses classes. 
 
A class used to store a 3D point. 
 
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
 
double roll() const
Get the ROLL angle (in radians) 
 
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...
 
void test_compose(const CPose3D &p1, const CPose3D &p2)
 
void setFrom12Vector(const ARRAYORVECTOR &vec12)
Set pose from an array with these 12 elements: [r11 r21 r31 r12 r22 r32 r13 r23 r33 tx ty tz] where r...
 
Traits for SE(n), rigid-body transformations in R^n space. 
 
void test_Jacob_dDexpe_de(const CPose3D &p)
 
void check_jacob_LnT_T(const CPose3D &p)
 
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries. 
 
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). 
 
EXPECT_EQ(out.image_pair_was_used.size(), NUM_IMGS)
 
static void func_jacob_D_expe(const CVectorFixedDouble< 6 > &eps, const CPose3D &D, CVectorFixedDouble< 12 > &Y)
 
EIGEN_MAP asEigen()
Get as an Eigen-compatible Eigen::Map object. 
 
void test_composeFrom(const CPose3D &p1, const CPose3D &p2)
 
void composePoint(double lx, double ly, double lz, double &gx, double &gy, double &gz, mrpt::optional_ref< mrpt::math::CMatrixDouble33 > out_jacobian_df_dpoint=std::nullopt, mrpt::optional_ref< mrpt::math::CMatrixDouble36 > out_jacobian_df_dpose=std::nullopt, mrpt::optional_ref< mrpt::math::CMatrixDouble36 > out_jacobian_df_dse3=std::nullopt, 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...
 
EXPECT_NEAR(out.cam_params.rightCameraPose.x, 0.1194, 0.005)
 
void getRotationMatrix(mrpt::math::CMatrixDouble33 &ROT) const
Get the 3x3 rotation matrix. 
 
EIGEN_MAP asEigen()
Get as an Eigen-compatible Eigen::Map object. 
 
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 test_default_values(const CPose3D &p, const std::string &label)
 
vector_t asVectorVal() const
Return the pose or point as a 1xN vector with all the components (see derived classes for each implem...