Skip to content
Snippets Groups Projects
Commit 7b01a780 authored by Angel Santamaria-Navarro's avatar Angel Santamaria-Navarro
Browse files

Fix odd bug about rotations...

Bug was: in Eigen matrix functions, passing a matrix expression by reference means
that each time the reference is needed the expression was reevaluated.
This produced that when calling a function
  e.g. f( Matrix::Random() ),
the parameter passed is an expression and not a matrix. Therefore, each
time the matrix is used in f(), a new Random was created.

Solution: use the .eval() method to evaluate the expression:
as in
  e.g. f( Matrix::Random().eval() )
parent c80b39c1
No related branches found
No related tags found
No related merge requests found
......@@ -67,7 +67,13 @@ inline Eigen::Matrix<typename Derived::Scalar, 3, 3> skew(const Eigen::MatrixBas
typedef typename Derived::Scalar T;
return (Eigen::Matrix<T, 3, 3>() << 0.0, -_v(2), +_v(1), +_v(2), 0.0, -_v(0), -_v(1), +_v(0), 0.0).finished();
Eigen::Matrix<T, 3, 3> sk;
sk << 0.0 , -_v(2), +_v(1),
+_v(2), 0.0 , -_v(0),
-_v(1), +_v(0), 0.0;
return sk;
}
/** \brief Inverse of skew symmetric matrix
......@@ -156,12 +162,17 @@ inline Eigen::Matrix<typename Derived::Scalar, 3, 3> exp_R(const Eigen::MatrixBa
typedef typename Derived::Scalar T;
Eigen::Matrix<typename Derived::Scalar, 3, 3> R;
T angle_squared = _v.squaredNorm();
T angle = sqrt(angle_squared);
if (angle > wolf::Constants::EPS)
return Eigen::AngleAxis<T>(angle, _v / angle).matrix();
R = Eigen::AngleAxis<T>(angle, _v.normalized()).toRotationMatrix();
else
return Eigen::Matrix<T, 3, 3>::Identity() + skew(_v);
R = Eigen::Matrix<T, 3, 3>::Identity() + skew(_v);
return R;
}
/** \brief Rotation matrix logarithmic map
......
......@@ -258,7 +258,7 @@ TEST(rotations, R2v_v2R_limits)
//Vector3s rv;
for(int i = 0; i<8; i++){
initial_matrix = v2R(Vector3s::Random() * scale);
initial_matrix = v2R(Vector3s::Random().eval() * scale);
R_to_v = R2v(initial_matrix);
v_to_R = v2R(R_to_v);
......@@ -277,7 +277,7 @@ TEST(rotations, R2v_v2R_AAlimits)
Vector3s rv;
for(int i = 0; i<8; i++){
rotation_mat = v2R(Vector3s::Random() * scale);
rotation_mat = v2R(Vector3s::Random().eval() * scale);
//rotation_mat(0,0) = 1.0;
//rotation_mat(1,1) = 1.0;
//rotation_mat(2,2) = 1.0;
......@@ -321,7 +321,7 @@ TEST(rotations, AngleAxis_limits)
Vector3s rv;
for(int i = 0; i<8; i++){ //FIX ME : Random() will not create a rotation matrix. Then, R2v(Random_matrix()) makes no sense at all.
rotation_mat = v2R(Vector3s::Random() * scale);
rotation_mat = v2R(Vector3s::Random().eval() * scale);
rotation_mati = rotation_mat;
//rv = R2v(rotation_mat); //decomposing R2v below
......@@ -352,7 +352,8 @@ TEST(rotations, AngleAxis_limits2)
//FIX ME : 5. Building a rot mat doing this is not safe; You cannot guarantee that R is valid.
// Highlight limitation of AngleAxis
rotation_mat = skew(Vector3s::Random()) *0.0001;
rotation_mat = skew(Vector3s::Random().eval()) * 1e-8;
rotation_mat(0,0) = 1;
rotation_mat(1,1) = 0.999999;
rotation_mat(2,2) = 1;
......@@ -367,9 +368,9 @@ TEST(rotations, AngleAxis_limits2)
aa0 = AngleAxis<wolf::Scalar>(rotation_mat);
rv = aa0.axis() * aa0.angle();
//checking if rv is 0 vector
ASSERT_TRUE(rv.isMuchSmallerThan(1, wolf::Constants::EPS_SMALL));
ASSERT_MATRIX_APPROX(rv, Eigen::Vector3s::Zero(), wolf::Constants::EPS);
rotation_mat = skew(Vector3s::Random()) *0.1;
rotation_mat = skew(Vector3s::Random().eval()) *0.1;
rotation_mat(0,0) = 1;
rotation_mat(1,1) = 0.9999999;
rotation_mat(2,2) = 1;
......@@ -384,7 +385,7 @@ TEST(rotations, AngleAxis_limits2)
aa0 = AngleAxis<wolf::Scalar>(rotation_mat);
rv = aa0.axis() * aa0.angle();
//checking if rv is 0 vector
ASSERT_TRUE(rv.isMuchSmallerThan(1, wolf::Constants::EPS_SMALL));
ASSERT_FALSE(rv.isMuchSmallerThan(1, wolf::Constants::EPS_SMALL));
}
TEST(rotations, Quat_compos_const_rateOfTurn)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment