@@ -149,9 +149,7 @@ def ti_quat_to_xyz(quat):
149149
150150 siny_cosp = q_wz - q_xy
151151 cosy_cosp = 1.0 - (q_yy + q_zz )
152- hypot_min = ti .min (siny_cosp , cosy_cosp )
153- hypot_max = ti .max (siny_cosp , cosy_cosp )
154- cosp = ti .select (hypot_max > 0.0 , hypot_max * ti .sqrt (1.0 + (hypot_min / hypot_max ) ** 2 ), 0.0 )
152+ cosp = ti .sqrt (cosy_cosp ** 2 + siny_cosp ** 2 )
155153
156154 roll = ti .atan2 (q_wx - q_yz , 1.0 - (q_xx + q_yy ))
157155 pitch = ti .atan2 (q_xz + q_wy , cosp )
@@ -652,10 +650,7 @@ def _np_quat_to_xyz(quat, rpy=False, out=None):
652650 siny_cosp = q_wz - q_xy
653651 cosr_cosp = 1.0 - (q_xx + q_yy )
654652 cosy_cosp = 1.0 - (q_yy + q_zz )
655-
656- hypot_min = np .minimum (siny_cosp , cosy_cosp )
657- hypot_max = np .maximum (siny_cosp , cosy_cosp )
658- cosp = np .where (hypot_max > 0.0 , hypot_max * np .sqrt (1.0 + (hypot_min / hypot_max ) ** 2 ), 0.0 )
653+ cosp = np .sqrt (cosy_cosp ** 2 + siny_cosp ** 2 )
659654
660655 out_ [..., 0 ] = np .arctan2 (sinr_cosp , cosr_cosp )
661656 out_ [..., 1 ] = np .arctan2 (sinp , cosp )
@@ -678,7 +673,9 @@ def _tc_quat_to_xyz(quat, rpy=False, out=None):
678673 q_yy , q_yz = torch .unbind (q_y * q_vec_s [..., 1 :], - 1 )
679674 q_zz = q_z [..., 0 ] * q_vec_s [..., 2 ]
680675
681- # Compute some intermediary quantities
676+ # Compute some intermediary quantities.
677+ # Numerical robustness of 'cos(pitch)' could be improved using 'hypot' implementation from Eigen:
678+ # https://gitlab.com/libeigen/eigen/-/blob/master/Eigen/src/Core/MathFunctionsImpl.h#L149
682679 if rpy :
683680 sinp = q_wy - q_xz
684681 sinr_cosp = q_wx + q_yz
@@ -689,14 +686,7 @@ def _tc_quat_to_xyz(quat, rpy=False, out=None):
689686 siny_cosp = q_wz - q_xy
690687 cosr_cosp = 1.0 - (q_xx + q_yy )
691688 cosy_cosp = 1.0 - (q_yy + q_zz )
692-
693- # Use numerical robust formula for computing cos(pitch)
694- # See Eigen implementation for reference:
695- # https://gitlab.com/libeigen/eigen/-/blob/master/Eigen/src/Geometry/EulerAngles.h#L45
696- # https://gitlab.com/libeigen/eigen/-/blob/master/Eigen/src/Core/MathFunctionsImpl.h#L149
697- hypot_min = torch .minimum (siny_cosp , cosy_cosp )
698- hypot_max = torch .maximum (siny_cosp , cosy_cosp )
699- cosp = torch .where (hypot_max > 0.0 , hypot_max * torch .sqrt (1.0 + (hypot_min / hypot_max ) ** 2 ), 0.0 )
689+ cosp = torch .sqrt (cosy_cosp ** 2 + siny_cosp ** 2 )
700690
701691 # Roll (x-axis rotation)
702692 out [..., 0 ] = torch .atan2 (sinr_cosp , cosr_cosp )
0 commit comments