- 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?
조회 수: 26(최근 30일)
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 2022년 5월 26일
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
Sam Chak 2022년 5월 25일
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 2022년 5월 25일
편집: Paul 2022년 5월 26일
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.