How to find the angle between two quaternions?

138 次查看(过去 30 天)
If quaternions represent an orientation in space, there is an axis between any two orientations and an angle between them. I'm looking for the procedure to find that angle.

采纳的回答

James Tursa
James Tursa 2019-8-17
编辑:James Tursa 2019-8-17
For example purposes I am using the coordinate frames as ECI and BODY
Q1 = quaternion from ECI->BODY1
Q2 = quaternion from ECI->BODY2
Then perform the following calculation
Q12 = conj(Q1) * Q2 % <- quaternion conjugate and quaternion multiply
Q12 = quaternion from BODY1->BODY2
There may be MATLAB functions to do the conjugate and multiply, but I don't know at the moment. The conjugate of Q1 is simply [Q(1),-Q(2:4)] of course assuming the scalar is the first element.
If we assume the scalar is the first element of the quaternion, matching the MATLAB quaternion functions convention, then you have
Q12(1) = cos(angle/2)
and
Q12(2:4) = sin(angle/2) * e
where e is the unit axis of rotation
From these you can solve for the angle
angle = 2 * atan2(norm(Q12(2:4)),Q12(1))
See also this post:
and this post:
  5 个评论
James Tursa
James Tursa 2019-8-19
编辑:James Tursa 2019-8-19
The confusion is caused by which element is the scalar part. The scalar part can be either the 1st element or the 4th element ... both are widely used in industry and both are "correct". If your quaternions are defined with the scalar as the 1st element (matching MATLAB toolboxes), then use the method above. If your quaternions are defined with the scalar in the 4th element (not matching MATLAB toolboxes), then use the other post.

请先登录,再进行评论。

更多回答(1 个)

Jim Riggs
Jim Riggs 2019-8-17
编辑:Jim Riggs 2019-8-17
I am more comfortable working with direction cosine matrices, so the way I would do this is to first convert the quaternions to DCM's;
Assume Quaternion A represents the orientation of body A in the I frame
Quaternion B represents the orientation of Body B in the I frame.
The direction cosine matrix, C, that transforms from I to A is defined as:
If the Quaternion is defined as [a, b, c, d], (where a is the scalar part and b, c, d is the vector part) then the direction cosine matrix in terms of the quaternion is
So, first compute the direction cosine matrix from quaternion A (DCMA) and from quaternion B (DCMB).
Now the direction cosine matrix for the transformation from A to B is
DCMAB = DCMB * transpose(DCMA).
Now that you have the transformation matrix from A to B, you can get the Euler angles or rotation vector from this DCM.
Matlab Answers 20190816c.JPG
Using DCMAB, this gives the rotation vector from A to B.
  2 个评论
Andrei Neboian
Andrei Neboian 2020-3-25
Hello Jim,
thanks for a detailed guideline using the DCM's.
Will this method work for the following setup/problem and do you think that there are additional issues that could arise from applying the DCM method you describe?
Setup: I have two IMU Sensors, each delivering Quaternion data (w1,x1,y1,z1) and (w2,x2,y2,z2) for their absolute orientation in space in real-time (these sensors produce magnetic compass, gyroscope, and accelerometer data, which are fused together inside the sensor to provide Quaternion data).
Problem: I want to know how both sensors are oriented to each other. In particular, I want to know the angle (-180deg to 180deg) between the y-axis of the first sensor and the y-axis of the second sensor - lets call this angle Theta.
I have tried two methods:
  • Quaternions -> convert to Euler Angles -> Pitch2-Pitch1 should (?) correspond to the angle Theta between the y-axes of both sensors (as far as my understanding goes),
  • Euler Angles -> determine Rotation matrices R1 and R2 for each sensor -> rotate unit-vector (0,1,0) along y-axis using R1 and R2 -> angle between both rotated unit-vectors should (?) correspond to the angle Theta I look for.
But both methods yielded an angle between both sensors. But at certain orientations of both sensors, the value of Theta was sporadically jumping like +-90 or +-180deg or so. I assume the reason for these jumps was the Gimbal Lock.
Jim Riggs
Jim Riggs 2020-3-25
编辑:Jim Riggs 2020-3-25
It sounds like the problem you are working is exactly the same as the original question in this post.
I offered a solution based on converting quaterions to DCM's and then manipulating the DCM's to get the relative DCM from sensor 1 to sensor 2. Then, from this relative DCM, extract the Euler angles, or rotation vector. I suggested this approach because I am less comfortable working with quaternion math, as in James Tursa's answer. His approach is, no doubt, the most direct.
I would advise against working with Euler angles until the very last step, because they are fraught with potential problems, like the indeterminant angles (+-90 or +-180 situation). This is not a sign of gimbal lock, but of an indeterminant solution in the Euler angle. Quaternions and direction cosine matrices do not have these issues, so you should calculate the relative orientation between the two frames using quaternion math (per James Tursa's answer) or using DCM's (as I suggest) and then, in the final step, you can get the relative Euler angles from the relative quaternion or DCM.

请先登录,再进行评论。

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by