# tf API: Axes/order of rotation

Hello ROS users!

I'm working with tf and I've a few questions about the API.

I am defining frames such that Yaw is applied around Z, followed by Pitch around the new Y and then Roll around new X.

Consider a transform from base_link --> camera_frame. Assuming I only have constant rotation between the frames (zero translation), here's how I create the transform:

//Fixed transform values
double roll, pitch, yaw;
yaw = DEGREES_TO_RADIANS(90); // 90 degrees around Z
pitch = DEGREES_TO_RADIANS(0); // 0 degrees around new Y
roll = DEGREES_TO_RADIANS(-90); // -90 degrees around new X

//Create Quaternion from Euler angles
tf::Quaternion quat;
quat.setRPY(roll, pitch, yaw);
//quat.setEuler(pitch, roll, -yaw); //

//Set rotations

//Set translations


In another node, I have a tf::TransformListener object which receives this transform. Here I print out the values :

void printEulerAngles(tf::StampedTransform& transform){
double roll, pitch, yaw;
tf::Matrix3x3 m(transform.getRotation());

m.getRPY(roll, pitch, yaw);
//m.getEulerZYX(yaw, pitch, roll);
ROS_INFO("\nRoll    : %.3f\n"
"Pitch  : %.3f\n"
"Yaw    : %.3f\n",

}


I expected to see the transform as defined above. However, I see Roll, Pitch, Yaw (90,90, 0). I did some research and found that setRPY() and getRPY() follow this convention:

• (roll around X, pitch around Y and yaw around z) around fixed axes.

Here are my questions:

1) How do I define rotations when I need to rotate (w.r.t to base_link axes) in the following convention?

• (yaw around Z, then pitch around new Y, then roll around new X)

2) Once I get the above rotation from tf, how do I modify the printEulerAngles() method to display them in the same convention as above?

I'd really appreciate any assistance in understanding tf. Thanks!

edit retag close merge delete

Sort by » oldest newest most voted

I think you are looking for the setEulerYPR and getEulerYPR functions of tf::Matrix3x3. As far as I can tell, these follow the convention you are describing.

To generate the quaternion:

//Fixed transform values
double roll, pitch, yaw;
yaw = DEGREES_TO_RADIANS(90); // 90 degrees around Z
pitch = DEGREES_TO_RADIANS(0); // 0 degrees around new Y
roll = DEGREES_TO_RADIANS(-90); // -90 degrees around new X

//Create Matrix3x3 from Euler Angles
tf::Matrix3x3 m_rot;
m_rot.setEulerYPR(yaw, pitch, roll);

// Convert into quaternion
tf::Quaternion quat;
m_rot.getRotation(quat);


void printEulerAngles(tf::StampedTransform& transform){
double roll, pitch, yaw;
tf::Matrix3x3 m(transform.getRotation());
int solution_number = 1;

m.getEulerYPR(yaw, pitch, roll, solution_number);
ROS_INFO("\nRoll    : %.3f\n"
"Pitch  : %.3f\n"
"Yaw    : %.3f\n",
}


However, like I wrote in your previous question, there can be multiple representations of an identical rotation, so your angles might not be the same. You can play around witht the solution_number argument of getEulerYPR() but I don't know if that will help.

Good luck.

more

Hello, thanks for your suggestion. Unfortunately, I still don't see the correct angle. In tf_broadcaster_node, I have the same input: Y,P,R = (90,0,-90). However, in tf_listener_node, I see (0, 90, 90). I don't think it's an equivalent rotation.

( 2016-11-14 18:13:52 -0600 )edit