14 #include <gtest/gtest.h>
32 void test_compose(
double x1,
double y1,
double z1,
double yaw1,
double pitch1,
double roll1,
33 double x2,
double y2,
double z2,
double yaw2,
double pitch2,
double roll2 )
35 const CPose3D p1(x1,y1,z1,yaw1,pitch1,roll1);
36 const CPose3D p2(x2,y2,z2,yaw2,pitch2,roll2);
38 const CPose3D p1_c_p2 = p1 + p2;
39 const CPose3D p1_i_p2 = p1 - p2;
52 "p1_c_p2: " << p1_c_p2 << endl <<
53 "q1_c_p2: " << p_q1_c_q2 << endl;
56 "p1_i_p2: " << p1_i_p2 << endl <<
57 "q1_i_p2: " << p_q1_i_q2 << endl;
80 void test_composePoint(
double x1,
double y1,
double z1,
double yaw1,
double pitch1,
double roll1,
81 double x,
double y,
double z)
83 const CPose3D p1(x1,y1,z1,yaw1,pitch1,roll1);
91 "p1: " << p1 << endl <<
92 "q1: " << q1 << endl <<
94 "p1_plus_p: " << p1_plus_p << endl <<
95 "q1_plus_p: " << q1_plus_p << endl;
106 q.quat().normalize();
109 for (
int i=0;i<3;i++) Y[i]=pp[i];
113 double x,
double y,
double z)
129 for (
int i=0;i<7;i++) x_mean[i]=q1[i];
136 x_incrs.assign(1e-7);
140 numJacobs.extractMatrix(0,0, num_df_dpose);
141 numJacobs.extractMatrix(0,7, num_df_dpoint);
146 EXPECT_NEAR(0, (df_dpoint-num_df_dpoint).array().abs().
sum(), 3e-3 )
147 <<
"q1: " << q1 << endl
148 <<
"p: " <<
p << endl
149 <<
"Numeric approximation of df_dpoint: " << endl << num_df_dpoint << endl
150 <<
"Implemented method: " << endl << df_dpoint << endl
151 <<
"Error: " << endl << df_dpoint-num_df_dpoint << endl;
153 EXPECT_NEAR(0, (df_dpose-num_df_dpose).array().abs().
sum(), 3e-3 )
154 <<
"q1: " << q1 << endl
155 <<
"p: " <<
p << endl
156 <<
"Numeric approximation of df_dpose: " << endl << num_df_dpose << endl
157 <<
"Implemented method: " << endl << df_dpose << endl
158 <<
"Error: " << endl << df_dpose-num_df_dpose << endl;
163 double x,
double y,
double z)
165 const CPose3D p1(x1,y1,z1,yaw1,pitch1,roll1);
176 "p_minus_p1: " << p_minus_p1 << endl <<
177 "p_minus_q1: " << p_minus_q1 << endl;
179 EXPECT_NEAR(0, (p_rec.
getAsVectorVal()-
p.getAsVectorVal()).array().abs().sum(), 1e-5) <<
180 "p_rec: " << p_rec << endl <<
188 q.quat().normalize();
197 double x,
double y,
double z)
211 const double qr = q1.
quat().
r();
const double qx = q1.
quat().
x();
const double qy = q1.
quat().
y();
const double qz = q1.
quat().
z();
212 const double Ax =
x-x1;
213 const double Ay =
y-y1;
214 const double Az =
z-z1;
215 theorical.
x = Ax + 2*(Ay)*(qr*qz + qx*qy) - 2*(Az)*(qr*qy - qx*qz) - 2*(
square(qy) +
square(qz))*(Ax);
216 theorical.
y = Ay - 2*(Ax)*(qr*qz - qx*qy) + 2*(Az)*(qr*qx + qy*qz) - 2*(
square(qx) +
square(qz))*(Ay);
217 theorical.
z = Az + 2*(Ax)*(qr*qy + qx*qz) - 2*(Ay)*(qr*qx - qy*qz) - 2*(
square(qx) +
square(qy))*(Az);
219 EXPECT_NEAR(theorical.
x,l.
x, 1e-5);
220 EXPECT_NEAR(theorical.
y,l.
y, 1e-5);
221 EXPECT_NEAR(theorical.
z,l.
z, 1e-5);
228 for (
int i=0;i<7;i++) x_mean[i]=q1[i];
235 x_incrs.assign(1e-7);
239 numJacobs.extractMatrix(0,0, num_df_dpose);
240 numJacobs.extractMatrix(0,7, num_df_dpoint);
244 EXPECT_NEAR(0, (df_dpoint-num_df_dpoint).array().abs().
sum(), 3e-3 )
245 <<
"q1: " << q1 << endl
246 <<
"from pose: " <<
CPose3D(x1,y1,z1,yaw1,pitch1,roll1) << endl
247 <<
"p: " <<
p << endl
248 <<
"local: " << l << endl
249 <<
"Numeric approximation of df_dpoint: " << endl << num_df_dpoint << endl
250 <<
"Implemented method: " << endl << df_dpoint << endl
251 <<
"Error: " << endl << df_dpoint-num_df_dpoint << endl;
253 EXPECT_NEAR(0, (df_dpose-num_df_dpose).array().abs().
sum(), 3e-3 )
254 <<
"q1: " << q1 << endl
255 <<
"from pose: " <<
CPose3D(x1,y1,z1,yaw1,pitch1,roll1) << endl
256 <<
"p: " <<
p << endl
257 <<
"local: " << l << endl
258 <<
"Numeric approximation of df_dpose: " << endl << num_df_dpose << endl
259 <<
"Implemented method: " << endl << df_dpose << endl
260 <<
"Error: " << endl << df_dpose-num_df_dpose << endl;
266 const CPose3D p1(x1,y1,z1,yaw1,pitch1,roll1);
275 "p1: " << p1 << endl <<
276 "q1: " << q1 << endl <<
277 "p1r: " << p1r << endl;
282 const CPose3D p1(x1,y1,z1,yaw1,pitch1,roll1);
294 void test_copy(
double x1,
double y1,
double z1,
double yaw1,
double pitch1,
double roll1)
296 const CPose3D p1(x1,y1,z1,yaw1,pitch1,roll1);
308 double x1,
double y1,
double z1,
double yaw1,
double pitch1,
double roll1,
309 double x,
double y,
double z)
316 EXPECT_NEAR(
x,aux.
x, 1e-7);
317 EXPECT_NEAR(
y,aux.
y, 1e-7);
318 EXPECT_NEAR(
z,aux.
z, 1e-7);
322 double x1,
double y1,
double z1,
double yaw1,
double pitch1,
double roll1,
323 double x,
double y,
double z)
325 const CPose3D p1(x1,y1,z1,yaw1,pitch1,roll1);
331 EXPECT_NEAR(pt1.
x,pt2.
x, 1e-7);
332 EXPECT_NEAR(pt1.
y,pt2.
y, 1e-7);
333 EXPECT_NEAR(pt1.
z,pt2.
z, 1e-7);
337 double x1,
double y1,
double z1,
double yaw1,
double pitch1,
double roll1,
338 double x,
double y,
double z)
340 const CPose3D p1(x1,y1,z1,yaw1,pitch1,roll1);
346 EXPECT_NEAR(pt1.
x,pt2.
x, 1e-7);
347 EXPECT_NEAR(pt1.
y,pt2.
y, 1e-7);
348 EXPECT_NEAR(pt1.
z,pt2.
z, 1e-7);
353 float gx=
x,gy=
y,gz=
z;
355 double dist,yaw,
pitch;
362 q.inverseComposePoint(gx,gy,gz, lx2,ly2,lz2);
364 EXPECT_NEAR(lx,lx2, 1e-7);
365 EXPECT_NEAR(ly,ly2, 1e-7);
366 EXPECT_NEAR(lz,lz2, 1e-7);
375 q.quat().normalize();
377 q.sphericalCoordinates(
p,Y[0],Y[1],Y[2]);
381 double x,
double y,
double z)
397 for (
int i=0;i<7;i++) x_mean[i]=q1[i];
404 x_incrs.assign(1e-7);
408 numJacobs.extractMatrix(0,0, num_df_dpose);
409 numJacobs.extractMatrix(0,7, num_df_dpoint);
414 EXPECT_NEAR(0, (df_dpoint-num_df_dpoint).array().abs().
sum(), 3e-3 )
415 <<
"q1: " << q1 << endl
416 <<
"p: " <<
p << endl
417 <<
"Numeric approximation of df_dpoint: " << endl << num_df_dpoint << endl
418 <<
"Implemented method: " << endl << df_dpoint << endl
419 <<
"Error: " << endl << df_dpoint-num_df_dpoint << endl;
421 EXPECT_NEAR(0, (df_dpose-num_df_dpose).array().abs().
sum(), 3e-3 )
422 <<
"q1: " << q1 << endl
423 <<
"p: " <<
p << endl
424 <<
"Numeric approximation of df_dpose: " << endl << num_df_dpose << endl
425 <<
"Implemented method: " << endl << df_dpose << endl
426 <<
"Error: " << endl << df_dpose-num_df_dpose << endl;
434 for (
int i=0;i<4;i++)
q[i]=
x[i];
436 for (
int i=0;i<4;i++) Y[i]=
q[i];
441 const CPose3D pp(0,0,0,yaw1,pitch1,roll1);
453 for (
int i=0;i<4;i++) x_mean[i]=q1[i];
457 x_incrs.assign(1e-5);
461 numJacobs.extractMatrix(0,0, num_df_dpose);
466 EXPECT_NEAR(0, (df_dpose-num_df_dpose).array().abs().
sum(), 3e-3 )
467 <<
"q1: " << q1 << endl
468 <<
"Numeric approximation of df_dpose: " << endl << num_df_dpose << endl
469 <<
"Implemented method: " << endl << df_dpose << endl
470 <<
"Error: " << endl << df_dpose-num_df_dpose << endl;
566 test_composeAndInvComposePoint(1.0,2.0,3.0,
DEG2RAD(-30),
DEG2RAD(10),
DEG2RAD(60), 10.0, 20.0, 30.0 );
567 test_composeAndInvComposePoint(1.0,2.0,3.0,
DEG2RAD(10),
DEG2RAD(-50),
DEG2RAD(-40), -5.0, -15.0, 8.0 );
587 for (
size_t i=0;i<10;i++)
589 std::vector<double>
v(9);
591 test_invComposePoint_vs_CPose3D(
v[0],
v[1],
v[2],
v[3],
v[4],
v[5],
v[6],
v[7],
v[8]);
TEST_F(Pose3DQuatTests, FromYPRAndBack)
void test_unaryInverse(double x1, double y1, double z1, double yaw1, double pitch1, double roll1)
void test_invComposePointJacob(double x1, double y1, double z1, double yaw1, double pitch1, double roll1, double x, double y, double z)
static void func_normalizeJacob(const CArrayDouble< 4 > &x, const double &dummy, CArrayDouble< 4 > &Y)
void test_composePoint(double x1, double y1, double z1, double yaw1, double pitch1, double roll1, double x, double y, double z)
static void func_inv_compose_point(const CArrayDouble< 7+3 > &x, const double &dummy, CArrayDouble< 3 > &Y)
void test_composePointJacob(double x1, double y1, double z1, double yaw1, double pitch1, double roll1, double x, double y, double z)
void test_composeAndInvComposePoint(double x1, double y1, double z1, double yaw1, double pitch1, double roll1, double x, double y, double z)
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)
void test_composePoint_vs_CPose3D(double x1, double y1, double z1, double yaw1, double pitch1, double roll1, double x, double y, double z)
static void func_compose_point(const CArrayDouble< 7+3 > &x, const double &dummy, CArrayDouble< 3 > &Y)
void test_invComposePoint_vs_CPose3D(double x1, double y1, double z1, double yaw1, double pitch1, double roll1, double x, double y, double z)
void test_fromYPRAndBack(double x1, double y1, double z1, double yaw1, double pitch1, double roll1)
void test_invComposePoint(double x1, double y1, double z1, double yaw1, double pitch1, double roll1, double x, double y, double z)
void test_copy(double x1, double y1, double z1, double yaw1, double pitch1, double roll1)
void test_sphericalCoords(double x1, double y1, double z1, double yaw1, double pitch1, double roll1, double x, double y, double z)
void test_normalizeJacob(double yaw1, double pitch1, double roll1)
static void func_spherical_coords(const CArrayDouble< 7+3 > &x, const double &dummy, CArrayDouble< 3 > &Y)
A partial specialization of CArrayNumeric for double numbers.
A quaternion, which can represent a 3D rotation as pair , with a real part "r" and a 3D vector ,...
T z() const
Return z coordinate of the quaternion.
T x() const
Return x coordinate of the quaternion.
T r() const
Return r coordinate of the quaternion.
T y() const
Return y coordinate of the quaternion.
void normalizationJacobian(MATRIXLIKE &J) const
Calculate the 4x4 Jacobian of the normalization operation of this quaternion.
A class used to store a 3D point.
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
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.
mrpt::math::CMatrixDouble44 getHomogeneousMatrixVal() const
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)
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...
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 .
A class used to store a 3D pose as a translation (x,y,z) and a quaternion (qr,qx,qy,...
void sphericalCoordinates(const mrpt::math::TPoint3D &point, double &out_range, double &out_yaw, double &out_pitch, mrpt::math::CMatrixFixedNumeric< double, 3, 3 > *out_jacob_dryp_dpoint=NULL, mrpt::math::CMatrixFixedNumeric< double, 3, 7 > *out_jacob_dryp_dpose=NULL) const
Computes the spherical coordinates of a 3D point as seen from the 6D pose specified by this object.
mrpt::math::CQuaternionDouble & quat()
Read/Write access to the quaternion representing the 3D rotation.
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, 7 > *out_jacobian_df_dpose=NULL) const
Computes the 3D point L such as .
void composePoint(const double lx, const double ly, const double lz, double &gx, double &gy, double &gz, mrpt::math::CMatrixFixedNumeric< double, 3, 3 > *out_jacobian_df_dpoint=NULL, mrpt::math::CMatrixFixedNumeric< double, 3, 7 > *out_jacobian_df_dpose=NULL) const
Computes the 3D point G such as .
double x() const
Common members of all points & poses classes.
mrpt::math::CVectorDouble getAsVectorVal() const
Return the pose or point as a 1xN vector with all the components (see derived classes for each implem...
mrpt::math::CMatrixDouble44 getHomogeneousMatrixVal() const
Returns the corresponding 4x4 homogeneous transformation matrix for the point(translation) or pose (t...
void drawGaussian1DVector(VEC &v, const double mean=0, const double std=1)
Fills the given vector with independent, 1D-normally distributed samples.
GLdouble GLdouble GLdouble GLdouble q
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
void jacob_numeric_estimate(const VECTORLIKE &x, void(*functor)(const VECTORLIKE &x, const USERPARAM &y, VECTORLIKE3 &out), 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...
This base provides a set of functions for maths stuff.
CONTAINER::Scalar sum(const CONTAINER &v)
Computes the sum of all the elements.
CQuaternion< double > CQuaternionDouble
A quaternion of data type "double".
T square(const T x)
Inline function for the square of a number.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
BASE_IMPEXP CRandomGenerator randomGenerator
A static instance of a CRandomGenerator class, for use in single-thread applications.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values,...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
double z
X,Y,Z coordinates.