Rotation order of quatrotate
112 views (last 30 days)
I'm about the function quatrotate. I want to rotate the vector [0,0,1] (means pointing into z-direction of the world frame) by the quaternion [0.5,0.5,0.5,0.5] so that it points into the x-direction of the world frame.
v = [0,0,1];
q = [0.5,0.5,0.5,0.5];
Hence it looks like, the rotation is exactly done the other way round means, where was the vector pointing at when It is [0,0,1] after the rotation of [0.5,0.5,0.5,0.5].
Where is my lack of understanding?
James Tursa on 17 Dec 2019
Edited: James Tursa on 29 Apr 2021
I suppose this drawn out explanation is long overdue in this forum, so forgive me for being verbose, but a lot of posters have had similar questions over the years.
The MATLAB toolbox quaternion function documentation, like 99% of all quaternion documentation I read in books and online, is unfortunately lacking in convention details and also uses misleading phrases. To complicate matters, the Aerospace Toolbox convention is the conjugate of the Robotics Toolbox convention. You read that correctly ... MATLAB uses two different conventions in their own toolboxes. So you will get different results depending on which toolbox quaternion functions you are calling. I will describe one of these conventions below.
The MATLAB Aerospace Toolbox convention is as follows (the convention notation is my own invention):
(SV) Scalar first, Vector last
(P) Passive (meaning that its intended use is for coordinate transformations, as opposed to Active vector rotations)
(R) Successive coordinate transformations have the unmodified quaternion chain on the Right side of the triple product.
(+) Right-Handed Rule for the imaginary numbers i, j, k. (aka Hamilton)
What does all this mean? I will use the two coordinate frames ECI and BODY for illustration purposes.
(SV) Scalar first, Vector last:
For a MATLAB toolbox quaternion [q1,q2,q3,q4], q1 is the scalar part and [q2,q3,q4] is the vector part. Simple enough.
(For a VS convention q4 would be the scalar and [q1,q2,q3] would be the vector part)
In spite of the wording in the doc, the MATLAB Aerospace Toolbox quaternion is to be interpreted as a coordinate system transformation (Passive) and not a vector rotation within the same coordinate system (Active). E.g., For a Passive q, there is only one vector V involved ... you are simply expressing V in two different coordinate frames (e.g., Veci and Vbody):
For an Active q, there are actually two different V's involved ... the V before rotation and the V after rotation, both in the same coordinate system:
The Active and Passive senses have "opposite" effects on the coordinates of the resulting vector as can be seen in the pictures. In the Passive case you are rotating the coordinate frames and in the Active case you are rotating the vector. Hence, if you are trying to use the MATLAB Aerospace quaternion functions for an Active vector rotation instead of a Passive coordinate system transformation, you will get opposite results of what you expect. You can still use the MATLAB Aerospace toolbox functions for Active vector rotations, but you will need to change the sign sense of your rotation angles in order to get what you want (and you need to be really careful about this because it is easy to get things backwards from your intentions ... be sure to test some simple cases to make sure your code is correct).
(R) Right chain:
If the MATLAB toolbox q is an ECI_to_BODY quaternion and Veci and Vbody are the two different representations of the same vector V in the respective coordinate frames, then the unmodified quaternion q appears on the Right side of the triple quaternion product. I.e.,
Vbody = inv(q) * Veci * q (where inv(q) is a quaternion inverse and * is a quaternion multiply)
Successive operations "chain to the right".
A (L) Left chain convention would instead have Vbody = q * Veci * inv(q). NASA uses this convention for Passive coordinate system transformations. Successive operations "chain to the left". All Active vector rotation quaternions use this convention.
(+) Right-Handed Rule for i, j, k:
This simply means that i*j = k, j*k = i, and k*i = j. It is like right-handed cross products if you interpret the i, j, and k as coordinate frame axes. Also known as the Hamilton convention.
For a (-) Left-Handed Rule quaternion the signs of the result would be opposite (JPL convention does this).
The MATLAB doc further complicates this by using the quaternion element notation q0, q1, q2, q3 instead of the more natural indexing of q1, q2, q3, q4. So beware of this when reading the doc.
Now back to the original question and how the MATLAB Aerospace Toolbox functions are interpreting the vector and the quaternion. The quaternion q represents a Passive coordinate system transformation of 120 degrees about the [1/sqrt(3),1/sqrt(3),1/sqrt(3)] axis. And with that explanation and a picture things become suddenly clear:
The 120 degree "rotation" represents what you would physically do to the "FROM" frame to get it aligned with the "TO" frame. In this case you would physically rotate the ECI frame by 120 degrees about the [1/sqrt(3),1/sqrt(3),1/sqrt(3)] axis to get it aligned with the BODY frame. There is only one vector V, and the the results of the "rotation" (again, a bad choice of words in the doc) are really just the coordinates of the same vector V in the "TO" frame. The math done at the m-code level:
>> V = [0,0,1]; % V in the ECI frame
>> theta = 120; % The frame rotation angle
>> q = [cosd(theta/2) sind(theta/2)*[1/sqrt(3),1/sqrt(3),1/sqrt(3)]] % ECI to BODY
0.5000 0.5000 0.5000 0.5000
>> quatrotate(q,v) % V in the BODY frame
0.0000 1.0000 -0.0000
>> p = quatmultiply(quatconj(q),quatmultiply([0,v],q)); p(2:4) % V in the BODY frame
0.0000 1.0000 -0.0000
When the 120 degree "rotation" is interpreted as a Passive coordinate system transformation instead of an Active vector rotation, everything makes sense. In the ECI frame the vector V is aligned with the Zeci axis, but in the BODY frame the vector V is aligned with the Ybody axis. That is the result you get with the math, and you get the same result with quatrotate( ) as you do with a manual quaternion triple product.
Remember that this example used functions from the Aerospace Toolbox. Had we used functions from the Robotics Toolbox the results and comparisons would essentially involve conjugates of this example.
Note that MATLAB also has functionality that supports both Passive (i.e., frame) and Active (i.e., point) conventions depending on how you use them, such as the quaternion( ) class and the Sensor Fusion Toolbox.