How do I create a rotation matrix using pitch, yaw, roll with Eigen library?
6 Answers
Seeing as how I couldn't find a prebuilt function that does this, I built one and here it is in case someone finds this question in the future
Eigen::AngleAxisd rollAngle(roll, Eigen::Vector3d::UnitZ());
Eigen::AngleAxisd yawAngle(yaw, Eigen::Vector3d::UnitY());
Eigen::AngleAxisd pitchAngle(pitch, Eigen::Vector3d::UnitX());
Eigen::Quaternion<double> q = rollAngle * yawAngle * pitchAngle;
Eigen::Matrix3d rotationMatrix = q.matrix();

- 9,483
- 8
- 40
- 66
-
5Nice answer, but as @narcispr said, the axis will depend on what application you have. Could you please specify in your answer that your target is aircraft applications to avoid confusion? – Adri C.S. Apr 14 '15 at 10:11
Caesar answer is ok but as David Hammen says it depends on your application. For me (underwater or aerial vehicles field) the winning combination is:
Eigen::Quaterniond
euler2Quaternion( const double roll,
const double pitch,
const double yaw )
{
Eigen::AngleAxisd rollAngle(roll, Eigen::Vector3d::UnitX());
Eigen::AngleAxisd pitchAngle(pitch, Eigen::Vector3d::UnitY());
Eigen::AngleAxisd yawAngle(yaw, Eigen::Vector3d::UnitZ());
Eigen::Quaterniond q = yawAngle * pitchAngle * rollAngle;
return q;
}

- 311
- 1
- 3
- 7
-
In aircraft principal axes Roll is Z, Pitch is X, and Yaw is Y. Is the standard different in underwater? http://en.wikipedia.org/wiki/Aircraft_principal_axes – Caesar Oct 10 '14 at 16:26
-
@Caesar In my case, I have a Ladybug panoramic camera and the axis are the same as in this answer. – Adri C.S. Apr 14 '15 at 10:06
How do I create a rotation matrix using pitch, yaw, roll with Eigen library?
There are 48 ways to do this. Which one do you want? Here are the factors:
- Extrinsic verus intrinsic.
Are the rotations about the axes of the fixed system (extrinsic) or are they about the rotated axes (intrinsic)? - Rotation versus transformation.
Do you want to represent the matrix that physically rotates some object or do you want to represent the matrix that transforms vectors from one reference frame to another? - Astronomical sequences.
There are six fundamental astronomical sequences. The canonical Euler sequence involves a rotation about the z axis followed by a rotation about the (rotated) x axis followed by a third rotation about (rotated again) z axis. There are five more of these astronomical-style sequences (x-y-x, x-z-x, y-x-y, y-z-y,and z-y-z) in addition to this canonical z-x-z sequence. - Aerospace sequences.
To add to the confusion, there are six fundamental aerospace sequences as well. For example, a pitch-yaw-roll sequence versus a roll-pitch-yaw sequence. While the astronomy community has pretty much settled on a z-x-z sequence, the same cannot be said of the aerospace community. Somewhere along the way you find people using every one of the six possible sequences. The six sequences in this group are x-y-z, x-z-y, y-z-x, y-x-z, z-x-y, and z-y-x.

- 2,780
- 3
- 25
- 59

- 32,454
- 9
- 60
- 108
-
How did you get 48? (6 Astronomical + 6 Aerospace) * (2 for Intrinsic, Extrinsic) = 24 Rotation vs Transformation still uses the same matrices. – Dylan Madisetti Mar 20 '20 at 23:42
-
@DylanMadisetti - Unless you consider the transpose of a matrix the same as the original, rotation (aka active rotation) and transformation (aka passive rotation) do not use the same matrices. Rotation / translation matrices are only rarely self-adjoint. – David Hammen Mar 21 '20 at 04:26
-
Sure, there is a pretty well-known ambiguity when selecting a particular Euler angles rotation scheme, but the question is definitely not about this ambiguity, and this answer definitely doesn't answer the question. – lisyarus Oct 12 '22 at 09:25
All you need to create a rotational matrix is the pitch, yaw, roll, and the ability to perform matrix multiplication.
First, create three rotational matrices, one for each axis of rotation (ie one for pitch, one for yaw, one for roll). These matrices will have the values:
Pitch Matrix:
1, 0, 0, 0,
0, cos(pitch), sin(pitch), 0,
0, -sin(pitch), cos(pitch), 0,
0, 0, 0, 1
Yaw Matrix:
cos(yaw), 0, -sin(yaw), 0,
0, 1, 0, 0,
sin(yaw), 0, cos(yaw), 0,
0, 0, 0, 1
Roll Matrix:
cos(roll), sin(roll), 0, 0,
-sin(roll), cos(roll), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
Next, multiply all of these together. The order here is important. For normal rotations, you will want to multiply the Roll Matrix by the Yaw Matrix first and then multiply the product by the Pitch Matrix. However, if you're trying to "undo" a rotation by going backwards, you'll want to perform the multiplications in reverse order (in addition to the angles having opposite values).

- 18,820
- 42
- 108
- 144

- 14,133
- 7
- 40
- 79
-
Thank you for the answer, I already knew about this but I was hoping that the library had a prebuilt function that does this. – Caesar Jan 28 '14 at 17:51
-
@MohammedMajeed I don't believe there is a built in function, but see http://stackoverflow.com/a/15043888/1530508 for a very concise technique using quaternions. – ApproachingDarknessFish Jan 28 '14 at 18:53
-
This is documented [there](http://eigen.tuxfamily.org/dox/group__TutorialGeometry.html#title3) – ggael Jan 28 '14 at 22:15
-
1This is for a left handed coordinate system I assume? To apply this for a right handed system you just have to change the input values sign. i.e. set roll = - roll , yaw = - yaw, pitch = -pitch – user183833 Nov 07 '16 at 19:02
-
I translate their Java implementation to C++ from this site: Euler Angle Visualization Tool
#include <iostream>
#include <math.h>
#include <Eigen/Dense>
Eigen::Matrix3d rotation_from_euler(double roll, double pitch, double yaw){
// roll and pitch and yaw in radians
double su = sin(roll);
double cu = cos(roll);
double sv = sin(pitch);
double cv = cos(pitch);
double sw = sin(yaw);
double cw = cos(yaw);
Eigen::Matrix3d Rot_matrix(3, 3);
Rot_matrix(0, 0) = cv*cw;
Rot_matrix(0, 1) = su*sv*cw - cu*sw;
Rot_matrix(0, 2) = su*sw + cu*sv*cw;
Rot_matrix(1, 0) = cv*sw;
Rot_matrix(1, 1) = cu*cw + su*sv*sw;
Rot_matrix(1, 2) = cu*sv*sw - su*cw;
Rot_matrix(2, 0) = -sv;
Rot_matrix(2, 1) = su*cv;
Rot_matrix(2, 2) = cu*cv;
return Rot_matrix;
}
int main() {
Eigen::Matrix3d rot_mat = rotation_from_euler(0, 0, 0.5*M_PI);
std::cout << rot_mat << std::endl;
return 0;
}

- 41
- 4
Here is an implementation using standard ZYX order like found in wikipedia
template <typename T>
Eigen::Matrix3<T> eulerZYX_2_rot(T roll_rad, T pitch_rad, T yaw_rad) {
// ZYX order, same as rot_z(yaw_rad) * rot_y(pitch_rad) * rot_x(roll_rad)
static_assert(std::is_floating_point_v<T>, "Floating point required.");
T sx = sin(roll_rad);
T cx = cos(roll_rad);
T sy = sin(pitch_rad);
T cy = cos(pitch_rad);
T sz = sin(yaw_rad);
T cz = cos(yaw_rad);
Eigen::Matrix3<T> rot(3, 3);
rot(0, 0) = cz * cy;
rot(0, 1) = cz * sy * sx - sz * cx;
rot(0, 2) = cz * sy * cx + sz * sx;
rot(1, 0) = sz * cy;
rot(1, 1) = sz * sy * sx + cz * cx;
rot(1, 2) = sz * sy * cx - cz * sx;
rot(2, 0) = -sy;
rot(2, 1) = cy * sx;
rot(2, 2) = cy * cx;
return rot;
}

- 11
- 4