- Both eul2quat and the quaternion class use intrinsic rotations.
- eul2quat([a b c], 'XYZ') is equivalent to quaternion([a b c], 'euler', 'XYZ', 'frame')
Why do the eul2quat and quaternion functions differ on the calculated results?
36 views (last 30 days)
The following discussion is all about external rotation, which corresponds to the point rotation in matlab：
I use the built-in functions "eul2quat" and "quaternion" for quaternion conversion of the same set of Euler angles data, but the results are slightly different and the signs are also different? How can I explain this, thanks in advance!
eulars = [-0.001180313 -0.1101197 -3.122032;
-0.001413606 -0.1086281 -3.119092;
-0.001928661 -0.1062565 -3.116415];
a = eul2quat(eulars,'XYZ') % first X, then Y, final Z ?
b = quaternion(eulars,'euler','XYZ','point') % first X, then Y, final Z ?
But I changed the order of eul2quat to "ZYX" and it seems that the differences in values are equal, but the output quaternions are in the opposite order.
a_OK = eul2quat(eulars,'ZYX') % first X, then Y, final Z , but the output order is a bit counter-intuitive, in the form of [w,z,y,x]
Brian Fanous on 26 May 2022
Quick takeaways :
Some more details about the quaternion class:
When you type quaternion([a b c], 'euler', 'XYZ', 'frame') that means find a quaternion q, such that
for a 3-by-1 vector v and rotation matrices R. (Obviously v on the right hand side is a pure quaternion with imaginary parts equal to v). The right hand side is quaternion frame rotation - hence frame in the quaternion() call. Also note that is the rotation matrix that rotates the frame of reference clockwise around the x axis by a. A new reference frame is achieved after each subsequent rotation because (as noted above), rotations are intrinsic.
When you type quaternion([a b c], 'euler', 'XYZ', 'point') that means find a quaternion q, such that
for a 3-by-1 vector v and rotation matrices T. (Again, v on the right hand side is a pure quaternion with imaginary parts equal to v). The right hand side is quaternion point rotation - hence point in the quaternion() call. Also note that is the rotation matrix that rotates a point clockwise around the x axis by a. Note here that
More Answers (3)
Sam Chak on 25 May 2022
I remember that previously we have talked about that Euler angles and quaternion are not unique. You need to check the rotation matrix. See example below:
eul = [-0.001180313 -0.1101197 -3.122032]
qXYZ = angle2quat(eul(1), eul(2), eul(3), 'XYZ')
dcm1 = angle2dcm(eul(1), eul(2), eul(3), 'XYZ')
dcm2 = quat2dcm(qXYZ)
dcm1 - dcm2
Paul on 25 May 2022
Edited: Paul on 26 May 2022
I think that both eul2quat and quaternion('frame') are using, right-handed, intrinsic rotations and the sequence of rotations is in the order of the sequence argument to those functions. Furthermore, eul2quat is doing a frame rotation.
Define three Euler angles
theta = rand(1,3);
Quaternion using eul2quat, intrinsic angles are: first around Z, second around Y', third around X''.
q1 = eul2quat(theta,'ZYX')
Quaternion based on frame rotation
q2 = quaternion(theta,'euler','ZYX','frame');
So those two are the same.
The confusion, at least for me, comes in when generating the associatied direction cosine matrices (DCMs). I'm going to generate a DCM that I understand as a frame rotation for the intrinsic ZYX sequence
Zrot = [cos(theta(1)) sin(theta(1)) 0; -sin(theta(1)) cos(theta(1)) 0;0 0 1];
Yrot = [cos(theta(2)) 0 -sin(theta(2)); 0 1 0; sin(theta(2)) 0 cos(theta(2))];
Xrot = [1 0 0;0 cos(theta(3)) sin(theta(3)); 0 -sin(theta(3)) cos(theta(3))];
DCMp = Xrot*Yrot*Zrot;
Given a vector v resolved in coordinate frame xyz expressed in a column, DCMp resolves that same vector into frame x''y''z'' via post-multiplication by v
v = rand(3,1);
vp = DCMp*v;
That works the same using q2
DCM2 = rotmat(q2,'frame');
v2 = DCM2*v
However, the doc page for quat2rotm says that DCM1 is used by pre-multiplying by transpose(v), which is actually called "post-multiply format" here! (side note: I very much dislike this idea of pre-multiplication by a row vector). So we'll do that, and then transpose the result to get it back to column vector for comparison
DCM1 = quat2rotm(q1);
v1 = (v.' * DCM1).';
Compare the results, they are very, very close.
format long e
[vp - v1, vp - v2]
So, we see that angle inputs to eul2quat define a right-handed, frame rotation, but we have to be careful about the pre- and post-multiplication convention.