Skip to content

Commit 656dcdd

Browse files
Fix Issue with Quaternion Angular Distance (#1473)
Original issue here: #1381 - Add new implementation for calculating angular distance between quaternions suggested by issue author, but include additional step of normalizing quaternions prior to the dot product operation - Add gmock test to verify that new implementation works even with small angular distances, e.g. 1.0e-6 - Decrease tolerance on expected values of angle distance calculations in similar tests, for parity
1 parent 02da8e2 commit 656dcdd

File tree

2 files changed

+13
-7
lines changed

2 files changed

+13
-7
lines changed

rviz_default_plugins/src/rviz_default_plugins/displays/odometry/quaternion_helper.hpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,12 @@ namespace rviz_default_plugins
4040

4141
float ogreQuaternionAngularDistance(Ogre::Quaternion first, Ogre::Quaternion second)
4242
{
43-
Ogre::Quaternion product = first * Ogre::Quaternion(second.w, -second.x, -second.y, -second.z);
44-
float imaginary_norm =
45-
sqrtf(powf(product.x, 2.0f) + powf(product.y, 2.0f) + powf(product.z, 2.0f));
43+
first.normalise();
44+
second.normalise();
45+
float dot = first.Dot(second);
46+
dot = std::clamp(dot, -1.0f, 1.0f);
4647

47-
return 2.0f * atan2f(imaginary_norm, sqrtf(powf(product.w, 2.0f)));
48+
return 2.0f * acosf(fabs(dot));
4849
}
4950

5051
} // namespace rviz_default_plugins

rviz_default_plugins/test/rviz_default_plugins/displays/odometry/quaternion_helper_test.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,21 @@ TEST(QuaternionHelper, ogreQuaternionHelper_returns_angle) {
4949
Ogre::Vector3 axis(1, 2, 3);
5050
axis.normalise();
5151
Ogre::Quaternion quaternion1;
52-
quaternion1.FromAngleAxis(Ogre::Radian(0), axis);
52+
quaternion1.FromAngleAxis(Ogre::Radian(0.0f), axis);
5353
Ogre::Quaternion quaternion2;
5454
quaternion2.FromAngleAxis(Ogre::Radian(0.5f), axis);
5555
Ogre::Quaternion quaternion3;
5656
quaternion3.FromAngleAxis(Ogre::Radian(1.2f), axis);
57+
Ogre::Quaternion quaternion4;
58+
quaternion4.FromAngleAxis(Ogre::Radian(1.0e-6f), axis);
5759

5860
EXPECT_THAT(
5961
rviz_default_plugins::ogreQuaternionAngularDistance(quaternion1, quaternion2),
60-
FloatNear(0.5f, 0.001f));
62+
FloatNear(0.5f, 1.0e-6f));
6163
EXPECT_THAT(
6264
rviz_default_plugins::ogreQuaternionAngularDistance(quaternion1, quaternion3),
63-
FloatNear(1.2f, 0.001f));
65+
FloatNear(1.2f, 1.0e-6f));
66+
EXPECT_THAT(
67+
rviz_default_plugins::ogreQuaternionAngularDistance(quaternion1, quaternion4),
68+
FloatNear(1.0e-6f, 1.0e-6f));
6469
}

0 commit comments

Comments
 (0)