I have this code in Python:
from scipy.spatial.transform import Rotation
r = Rotation.from_matrix(R)
angles = r.as_euler("zyx",degrees=True)
print(f'angles = {angles}')
Where R
is 3x3
rotation matrix.
And I have this code in C++ which is supposed to do exactly the same thing as Python bit:
Eigen::Map<Eigen::Matrix<float, 3, 3, Eigen::RowMajor>> eigen_R(R.ptr<float>());
Eigen::Quaternionf q(eigen_R);
Eigen::Vector3f euler = q.toRotationMatrix().eulerAngles(0, 1, 2);
double angle_x = euler[0];
double angle_y = euler[1];
double angle_z = euler[2];
// Convert angles to degrees
//double deg_factor = 180.0 / M_PI;
double deg_factor = 1.0;
float half_circle = M_PI * deg_factor;
float yaw_dim = angle_y > 0 ? half_circle : -half_circle;
_headPose[0] = (angle_y * deg_factor); // yaw
_headPose[1] = (angle_x * deg_factor); // pitch
_headPose[2] = (angle_z * deg_factor); // roll
The issue: if I run both Python and C++ codes with this R
matrix:
R = [[ 0.99640366 -0.05234712 0.06662979]
[ 0.05348801 0.99844889 -0.01545452]
[-0.06571744 0.01896283 0.99765807]]
They give the same results which is
Yaw = 3.82043
Pitch = 0.887488
Roll = 3.00733
But if R
matrix equals to
R = [[ 0.99321075 -0.08705603 0.07715995]
[ 0.08656997 0.99619924 0.00962846]
[-0.0777049 -0.00288336 0.99697223]]
Then Python code outputs:
yaw = 4.425338029132474, pitch = -0.5533284872549677, roll = 5.0092369943283375
When C++ outputs:
Yaw = 175.575
Pitch = 179.447
Roll = -174.991
In reality I am tracking the angle of a moving object and when there is a subtle change from (0, 0, 0) degrees point, angles in C++ become reversed for some reason. And in order to get the right angles I need to do something like:
_headPose[0] = yaw_dim - (angle_y * deg_factor); // yaw
_headPose[1] = (angle_x * deg_factor) - half_circle; // pitch
_headPose[2] = (angle_z * deg_factor) - half_circle; // roll
My knowledge on angles are very rusty and I do not understand why such a subtle change result in completely differently oriented values. Please advise how to fix it