# Problem with quaternion rotation maths

1. Dec 2, 2011

### bras0463

Hi,
I am trying to work out the maths to keep a camera connected to a balloon pointing in a fixed direction. The camera can roll, pitch and yaw relative to the balloon which itself can roll, pitch and yaw relative to an inertial frame. Sensors provide the camera roll, pitch and yaw relative to the balloon and the balloon roll, pitch and yaw relative to the reference frame.

Here is the matlab code I'm using to try and find the desired camera roll, pitch and yaw angles of rotation:

Code (Text):
clear all;
clc;

% Setup target
initial_camera_relative_to_balloon_yaw      = 0;
initial_camera_relative_to_balloon_pitch    = 0;
initial_camera_relative_to_balloon_roll     = 0;

initial_balloon_relative_to_reference_yaw        = -90;
initial_balloon_relative_to_reference_pitch      = 0;
initial_balloon_relative_to_reference_roll       = 0;

target_relative_to_reference_quat           = quatmultiply(initial_camera_relative_to_balloon_quat, initial_balloon_relative_to_reference_quat)

% Normal running
balloon_relative_to_reference_yaw    = -90;
balloon_relative_to_reference_pitch  = 45;
balloon_relative_to_reference_roll   = 0;

reference_relative_to_balloon_quat   = quatinv(balloon_relative_to_reference_quat);
camera_relative_to_balloon_quat      = quatmultiply(target_relative_to_reference_quat, reference_relative_to_balloon_quat);

[c_yaw, c_pitch, c_roll] = quat2angle(camera_relative_to_balloon_quat);
% If the maths was right this should be [0 -45 0] not [0 0 -45]
[camera_yaw, camera_pitch, camera_roll]
There is clearly a problem with the maths but I can't see what it is. Does this quaternion maths look correct?

2. Dec 2, 2011

### chiro

Hey bras0463 and welcome to the forums.

It's been a while since I did this kind of thing so take my advice with a grain of salt.

My understanding is that if you want to transform something quaternions you have to use the identity x = p q p^-1. Then you take x and convert it to a matrix or euler angles (which you are doing in your code).

I noticed that your code does the right format, but your p^-1 does not correspond to the inverse of p, but rather a different set of parameters.

If you want to compose rotations, then you should do that the standard way, but when I did this kind of thing, I remember doing x = p q p^-1 to get my rotation information which was then converted to a linear map (matrix) to use for transforming points.

3. Dec 2, 2011

### bras0463

Hi thanks for the response.

I think if you want to rotate a vector then the formula you have is correct i.e.

Code (Text):
vector_result_in_quat_form = quaternion X vector_in_quat_form X quaternion^-1
where 'X' is quaternion multiplication.

I think what I'm trying to do is different. I'm trying to combine two rotation quaternions to create a combined rotation quaternion and that is performed by a straight quaternion multiplication.

Code (Text):
combined_b_and_a_quat = quat_a X quat_b
The reason I have the inverse there is that I want to perform the opposite rotation to the one I have the quaternion for.

There's a good chance that I'm wrong about this though, after all my code doesn't do what I expect! :)

4. Dec 2, 2011

### D H

Staff Emeritus
The problem is that there are four ways to use quaternions to represent rotations and transformations. You appear to be assuming a representation that is different from Matlab's. The four choices are (left versus right) × (rotation versus transformation).
• Left versus right: Which of qvq-1 or q-1vq are you using to rotate/transform a vector?
• Rotation versus transformation: Does your quaternion represent the physical rotation of some device, or does it represent the transformation of coordinates from one frame to another?

How a sequence of quaternions chain depends on your choice for a representation scheme. For example, left transformation quaternions chain from right to left, but left rotation quaternions chain from left to right.

I'll denote $Q_{A\to B}$ as the quaternion that rotates/transforms from orientation A to orientation B. Now look at the two quaternion multiplications in your code. Denoting R as reference, B as balloon, C as camera, T as target, the first quaternion multiplication is
Code (Text):
target_relative_to_reference_quat =
quatmultiply(initial_camera_relative_to_balloon_quat,
initial_balloon_relative_to_reference_quat)
$$Q_{R\to T} = Q_{B->C}Q_{R->B}$$
You are chaining from right to left here.

The second multiplication is
Code (Text):
camera_relative_to_balloon_quat =
quatmultiply(target_relative_to_reference_quat,
reference_relative_to_balloon_quat)
$$Q_{B'->C'} = Q_{R\to T}Q_{B'->R}$$
Once again you are chaining from right to left.

If the Matlab's representation scheme is such that quaternions chain from left to right, those computations should have been done as

Code (Text):
target_relative_to_reference_quat =
quatmultiply(initial_balloon_relative_to_reference_quat,
initial_camera_relative_to_balloon_quat)

...

camera_relative_to_balloon_quat =
quatmultiply(reference_relative_to_balloon_quat,
target_relative_to_reference_quat);

5. Dec 2, 2011

### bras0463

Thanks DH! You were absolutely right, making that change fixed it straight away.

6. Dec 2, 2011

### D H

Staff Emeritus
From http://www.mathworks.com/matlabcentral/fileexchange/1176-quaternion-toolbox, Matlab uses left rotation quaternions / right transformation quaternions, which chain left to right.

They mistakenly use the terms left-handed and right-handed quaternions on that web page. There's no handedness involved here, at least not in the sense of left-handed versus right-handed coordinates. The left/right distinction is with respect to qvq* versus q*vq: Does the unconjugated quaternion go to the left or the right of the vector to be transformed/rotated?