template<typename _Scalar, class _System>
class Eigen::EulerAngles< _Scalar, _System >
Represents a rotation in a 3 dimensional space as three Euler angles.
Euler rotation is a set of three rotation of three angles over three fixed axes, defined by the EulerSystem given as a template parameter.
Here is how intrinsic Euler angles works:
- first, rotate the axes system over the alpha axis in angle alpha
- then, rotate the axes system over the beta axis(which was rotated in the first stage) in angle beta
- then, rotate the axes system over the gamma axis(which was rotated in the two stages above) in angle gamma
- Note
- This class support only intrinsic Euler angles for simplicity, see EulerSystem how to easily overcome this for extrinsic systems.
Rotation representation and conversions
It has been proved(see Wikipedia link below) that every rotation can be represented by Euler angles, but there is no single representation (e.g. unlike rotation matrices). Therefore, you can convert from Eigen rotation and to them (including rotation matrices, which is not called "rotations" by Eigen design).
Euler angles usually used for:
- convenient human representation of rotation, especially in interactive GUI.
- gimbal systems and robotics
- efficient encoding(i.e. 3 floats only) of rotation for network protocols.
However, Euler angles are slow comparing to quaternion or matrices, because their unnatural math definition, although it's simple for human. To overcome this, this class provide easy movement from the math friendly representation to the human friendly representation, and vise-versa.
All the user need to do is a safe simple C++ type conversion, and this class take care for the math. Additionally, some axes related computation is done in compile time.
Euler angles ranges in conversions
Rotations representation as EulerAngles are not single (unlike matrices), and even have infinite EulerAngles representations.
For example, add or subtract 2*PI from either angle of EulerAngles and you'll get the same rotation. This is the general reason for infinite representation, but it's not the only general reason for not having a single representation.
When converting rotation to EulerAngles, this class convert it to specific ranges When converting some rotation to EulerAngles, the rules for ranges are as follow:
- If the rotation we converting from is an EulerAngles (even when it represented as RotationBase explicitly), angles ranges are undefined.
- otherwise, alpha and gamma angles will be in the range [-PI, PI].
As for Beta angle: - If the system is Tait-Bryan, the beta angle will be in the range [-PI/2, PI/2].
- otherwise:
- If the beta axis is positive, the beta angle will be in the range [0, PI]
- If the beta axis is negative, the beta angle will be in the range [-PI, 0]
- See also
-
EulerAngles(const MatrixBase<Derived>&)
- EulerAngles(const RotationBase<Derived, 3>&)
Convenient user typedefs
Convenient typedefs for EulerAngles exist for float and double scalar, in a form of EulerAngles{A}{B}{C}{scalar}, e.g. EulerAnglesXYZd, EulerAnglesZYZf.
Only for positive axes{+x,+y,+z} Euler systems are have convenient typedef. If you need negative axes{-x,-y,-z}, it is recommended to create you own typedef with a word that represent what you need.
Example
#include <unsupported/Eigen/EulerAngles>
#include <iostream>
using namespace Eigen;
int main()
{
// A common Euler system by many armies around the world,
// where the first one is the azimuth(the angle from the north -
// the same angle that is show in compass)
// and the second one is elevation(the angle from the horizon)
// and the third one is roll(the angle between the horizontal body
// direction and the plane ground surface)
// Keep remembering we're using radian angles here!
typedef EulerSystem<-EULER_Z, EULER_Y, EULER_X> MyArmySystem;
typedef EulerAngles<double, MyArmySystem> MyArmyAngles;
MyArmyAngles vehicleAngles(
3.14/*PI*/ / 2, /* heading to east, notice that this angle is counter-clockwise */
-0.3, /* going down from a mountain */
0.1); /* slightly rolled to the right */
// Some Euler angles representation that our plane use.
EulerAnglesZYZd planeAngles(0.78474, 0.5271, -0.513794);
MyArmyAngles planeAnglesInMyArmyAngles(planeAngles);
std::cout << "vehicle angles(MyArmy): " << vehicleAngles << std::endl;
std::cout << "plane angles(ZYZ): " << planeAngles << std::endl;
std::cout << "plane angles(MyArmy): " << planeAnglesInMyArmyAngles << std::endl;
// Now lets rotate the plane a little bit
std::cout << "==========================================================\n";
std::cout << "rotating plane now!\n";
std::cout << "==========================================================\n";
Quaterniond planeRotated = AngleAxisd(-0.342, Vector3d::UnitY()) * planeAngles;
planeAngles = planeRotated;
planeAnglesInMyArmyAngles = planeRotated;
std::cout << "new plane angles(ZYZ): " << planeAngles << std::endl;
std::cout << "new plane angles(MyArmy): " << planeAnglesInMyArmyAngles << std::endl;
return 0;
}
Output:
vehicle angles(MyArmy): 1.57 -0.3 0.1
plane angles(ZYZ): 0.78474 0.5271 -0.513794
plane angles(MyArmy): -0.206273 0.453463 -0.278617
==========================================================
rotating plane now!
==========================================================
new plane angles(ZYZ): 1.44358 0.366507 -1.23637
new plane angles(MyArmy): -0.18648 0.117896 -0.347841
Additional reading
If you're want to get more idea about how Euler system work in Eigen see EulerSystem.
More information about Euler angles: https://en.wikipedia.org/wiki/Euler_angles
- Template Parameters
-
_Scalar |
the scalar type, i.e. the type of the angles. |
_System |
the EulerSystem to use, which represents the axes of rotation. |