How to calculate relative pitch, roll and yaw given absolutes

3.4k Views Asked by At

I have two objects (a phone and a car), and know their pitch ($\alpha$), roll ($\beta$) and yaw ($\gamma$) relative to a common coordinate system.

How would I calculate the phone's pitch, roll and yaw relative to the car? Is it a simple subtraction?

1

There are 1 best solutions below

0
On BEST ANSWER

No, it is not that simple. Euler angles are deceptive: they can be defined in many different ways (the order and the axes that are rotated), and they are not as easy to manipulate as e.g. versors (unit quaternions).

What you need to do, is use your angles to form two rotation matrices. Let's say you define $\mathbf{M}_{c}$ to be the 3×3 rotation matrix corresponding to the Euler angles for the car, and $\mathbf{M}_{p}$ for the phone. Next, you need to compose the rotation matrix using the two: you start with the inverse of the phone matrix, then multiply it with the car matrix, so that the result describes the rotation of the phone relative to the car. $$\mathbf{M} = \mathbf{M}_{c} \mathbf{M}_{p}^{-1}$$ Fortunately, these matrices are orthogonal/orthonormal, which means their transpose is their inverse, so you only need to calculate $$\mathbf{M} = \mathbf{M}_{c} \mathbf{M}_{p}^{T}$$

Finally, you convert the matrix to your Euler angle convention, whatever it might be. The Wikipedia Rotation formalism page contains conversion formulae for extrinsic z-x-z Euler angles, for example.


Personally, I'd ditch the entire idea of Euler angles, and would use versors AKA unit quaternions instead. If you're a non-math-person, you can think of them as four-component vectors $(w,x,y,z)$ of unit length, $w^2+x^2+y^2+z^2=1$, that describe an orientation using a slightly weird axis-and-angle format. The axis is $\left(x/\sin(\theta/2), y/\sin(\theta/2), z/\sin(\theta/2)\right)$ and $w=\cos(\theta/2)$, with $\theta = 2 \arccos w$ being the amount of rotation around the axis. No rotation is $(1,0,0,0)$, by the way; its length must be 1 for it to describe a rotation. Subtraction and addition is normal, but quaternion multiplication -- Hamilton product -- is a bit complicated. Just obey quaternion math rules when operating on them, and you'll do fine. You'll see they're easy.

If $\mathbf{q}_{p} = \left(w_p, x_p, y_p, z_p\right)$ is an unit quaternion describing the orientation of the phone, and $\mathbf{q}_{c} = \left(w_c,x_c,y_c,z_c\right)$ is an unit quaternion describing the orientation of the car, both with respect to some common coordinate system, then the orientation of the phone with respect to the car is $$\mathbf{q} = \left(w_c,x_c,y_c,z_c\right) \times \left(-w_p,x_p,y_p,z_p\right)$$ where $\times$ denotes Hamilton product; i.e. $$\mathbf{q} = \begin{cases} w = -w_c w_p - x_c x_p - y_c y_p - z_c z_p \\ x = w_c x_p - x_c w_p + y_c z_p - z_c y_p \\ y = w_c y_p - x_c z_p - y_c w_p + z_c x_p \\ z = w_c z_p + x_c y_p - y_c x_p - z_c w_p \end{cases}$$ When using floating-point types, rounding errors occur, so it is recommended you normalize the resulting quaternion to unit length. (Unlike matrices, this normalization does not have any bias or order, so it is safe to do.)

The pseudo-code I use for normalizing quaternions is

Function QNormalize(q):
    n = sqrt(q.w*q.w + q.x*q.x + q.y*q.y + q.z*q.z)
    If n > 0.0:
        If q.w < 0.0:
            n = -n
        End if
        q.w = q.w / n
        q.x = q.x / n
        q.y = q.y / n
        q.z = q.z / n
    Else:
        q.w = 1.0
        q.x = 0.0
        q.y = 0.0
        q.z = 0.0
    End if

    Return q
End function

A funny property of unit quaternions is that negating all components does not change the rotation it represents. However, if $w$ is negative, the rotation is done the "long way"; negating all components reverses both the axis and the rotation, so the same end result is achieved, but "the short way".

This is important when interpolating quaternions. If you have quaternions $\mathbf{q}_0$ and $\mathbf{q}_1$, you can interpolate between them using $t$ ($0 \le t \le 1)$, with $$\mathbf{q}' = (1-t)\,\mathbf{q}_0 + t\,\mathbf{q}_1$$ and normalizing the result to unit length, $$\mathbf{q} = \frac{\mathbf{q}'}{\left\lVert\mathbf{q}'\right\rVert}$$


To apply the rotation described by an unit quaternion, you calculate the 3×3 rotation matrix first. There is no ambiguity, and the matrix you need is described in e.g. the Wikipedia Quaternions and spatial rotation page, albeit with a change of variable names, $w \to a, x \to b, y \to c, z \to d$.