Skip to content

Conversation

roman-y-wu
Copy link

Description

Fixes #796
Addresses numerical precision errors that occur during quaternion-to-matrix conversion, particularly near gimbal lock singularities. When matrix elements contain small numerical errors (around 1e-12), the atan2 function can return incorrect angles, such as 45° instead of 0° for roll values.

Changes:

  • Add epsilon thresholding (1e-10) to matrix elements before RPY computation
  • Improve singularity detection to handle near-singular cases
  • Add safety checks to prevent division by near-zero cosine values
  • Protect atan2 calls when both arguments are very small
  • Apply fixes to both Matrix3x3::getEulerYPR() and tf2::impl utilities
  • Update .gitignore with comprehensive build and temporary file patterns

This resolves issues where tf2_echo and other tf2 tools would report incorrect RPY angles due to floating-point precision limitations.

Is this user-facing behavior change?

  1. tf2_echo users will now see correct RPY values instead of erroneous ones when dealing with quaternions that have numerical
    precision issues
    - Before: RPY (degree) [45.000, -90.000, 0.000] (incorrect)
    - After: RPY (degree) [0.000, -90.000, 0.000] (correct)
  2. Any application using tf2 RPY conversion will get more accurate results, particularly:
    - Near gimbal lock singularities
    - When quaternions come from tf2 lookupTransform operations
    - When dealing with transformations that should have zero roll/yaw but show small numerical errors

Did you use Generative AI?

No.

Additional Information

Addresses numerical precision errors that occur during quaternion-to-matrix
conversion, particularly near gimbal lock singularities. When matrix elements
contain small numerical errors (around 1e-12), the atan2 function can return
incorrect angles, such as 45° instead of 0° for roll values.

Changes:
- Add epsilon thresholding (1e-10) to matrix elements before RPY computation
- Improve singularity detection to handle near-singular cases
- Add safety checks to prevent division by near-zero cosine values
- Protect atan2 calls when both arguments are very small
- Apply fixes to both Matrix3x3::getEulerYPR() and tf2::impl utilities
- Update .gitignore with comprehensive build and temporary file patterns

This resolves issues where tf2_echo and other tf2 tools would report
incorrect RPY angles due to floating-point precision limitations.
Changes the epsilon threshold from 1e-10 to 1e-8 to be more conservative
and avoid interfering with legitimate small values in normal quaternion
conversions. The 1e-8 threshold still effectively catches the numerical
precision errors that cause incorrect RPY results while ensuring existing
tests continue to pass.

Analysis showed that quaternion-to-matrix conversion preserves error
magnitude, so a threshold of 1e-8 provides adequate safety margin above
typical floating-point precision errors without affecting normal operations.
- Reorder headers to follow cpplint convention (C++ system headers first)
- Remove trailing whitespace from empty lines
- Addresses cpplint and uncrustify test failures
Signed-off-by: Roman Wu <[email protected]>
Copy link
Member

@mjcarroll mjcarroll left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally looks good to me, but I would like to see some tests added around this singularity case.

Copy link
Member

@mjcarroll mjcarroll left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more change here, but I think we are good.

Signed-off-by: Roman Wu <[email protected]>
Signed-off-by: Alejandro Hernández Cordero <[email protected]>
Signed-off-by: Alejandro Hernandez Cordero <[email protected]>
@ahcorde
Copy link
Contributor

ahcorde commented Aug 18, 2025

Pulls: #811
Gist: https://gist.githubusercontent.com/ahcorde/33090dcbff2ef34c0b140b75f1cfc92f/raw/c57298dfab2ca5949d666f30dc274921a4c69b78/ros2.repos
BUILD args: --packages-above-and-dependencies test_tf2 tf2
TEST args: --packages-above test_tf2 tf2
ROS Distro: rolling
Job: ci_launcher
ci_launcher ran: https://ci.ros2.org/job/ci_launcher/16733

  • Linux Build Status
  • Linux-aarch64 Build Status
  • Linux-rhel Build Status
  • Windows Build Status

Copy link
Contributor

@ahcorde ahcorde left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

singularityGimbalLock is failing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Numeric error produces unexpected behavior on RPY angles computation
3 participants