Hi cui,
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
Quaternion using eul2quat, intrinsic angles are: first around Z, second around Y', third around X''.
q1 = eul2quat(theta,'ZYX')
q1 =
0.9404 0.1646 0.1866 0.2317
Quaternion based on frame rotation
q2 = quaternion(theta,'euler','ZYX','frame');
compact(q2)
ans =
0.9404 0.1646 0.1866 0.2317
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))];
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
That works the same using q2
DCM2 = rotmat(q2,'frame');
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 Compare the results, they are very, very close.
[vp - v1, vp - v2]
ans =
1.0e+00 *
1.110223024625157e-16 0
5.551115123125783e-17 -1.110223024625157e-16
-1.110223024625157e-16 -5.551115123125783e-17
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.