# Quaternion - Angle computation using accelerometer and gyroscope

I have been using a 6dof LSM6DS0 IMU unit (with accelerometer and gyroscope) and am trying to calculate the angle of rotation around all three axes. I have tried many methods but am not getting the results as expected.

Methods tried:

(i) Complementary filter approach - I am able to get the angles using the formula provided in the link Angle computation method.

But the problem is that the angles are not at all consistent and drift a lot. Moreover, when the IMU is rotated around one axis, angles calculated over other axes wobble too much.

(ii) Quaternion based angle calculation: There were plenty of resources claiming the angles are calcluated very well using quaternion approach but none had a clear explanation. I have used this method in order to update the quaternion for every values taken from the IMU unit. But the link didn't explain how to calculate the angles from a quaternion.

I have used glm math library in order to convert the quaternion to Euler angles and also have tried the formula specified in the wiki link. With this method, since pitch calculation asin returns only $-90$ to $90$ degrees I am not able to rotate the object in 3D as shown in the link.

Has anyone tried the quaternion to angle conversion before? I need to calculate the angles around all the three axis in the range $0$ to $360$ degrees or $-180$ to $180$ degrees.

Any help would be really appreciated. Thanks in advance.

• Numberphile did a video on quaternions two weeks ago. There is at least some basic explanation, maybe it's what you're looking for? – Arthur Feb 9 '16 at 8:11
• Thanks for the link. Let me check and tell you is that what I needed. – karthik Feb 9 '16 at 8:14
• @Arthur: I have seen the video, they explained the basics very well there. So what I need is that, Lets say I have a quaternion (computed from accelerometer and gyroscope values), I need to know the angle of rotation around x,y and z axis, such that the results should be in the entire range of 0-360 degrees. – karthik Feb 9 '16 at 9:44

The simplest way to obtain the relative orientation is the integrating of kinematic equations Quaternion kinematics for the error-state KF (formula 107). All the explanations about quaternions are in the book.

Gyroscope measures angular velocity $\omega$, so the relative orientation you can evaluate by integrating (in real-time) the kinematic equation $\dot{q}=\frac{1}{2}q\circ\omega$, where normalized quaternion $q$ defines orientation of the body-frame relative to the initial frame. The disadvantage of this method is the result diverges with time (because of integration errors and precision of gyroscope).

There is a better approach uses other sensors.

If you want to represent relative orientation as a sequence of rotations around 3 axis you should learn a bit about the Euler angles. Actually the second angle $\beta$ should be always in range $-\frac{\pi}{2}..\frac{\pi}{2}$ or in $0..\pi$.

• thanks for the answer. I am not familiar in this area, so pardon me if I am asking silly questions.. Is there no way I can get, even the second angle in the range -180 to +180. I have to render a object in 3D with the angles computed from imu using opengl. opengl requires the angles to be in 360 degree range to cover all the faces. Is there a way to map?? – karthik Feb 9 '16 at 11:50
• You don't need Euler angles to rotate an object in OpenGL. OpenGL has function glRotate which requires 4 parameters (angle, and components of rotation vector). These parameters can be easily obtained from quaternion's components. Your quaternion $q$ can be represented as $q=\left(\cos\frac{\vartheta}{2},\vec{v}\cdot\sin\frac{\vartheta}{2}\right)$. So, the function glRotate requires angle $\vartheta=2\arccos q_{0}$ and vector $u$ with components $v_{x}=\frac{q_{1}}{\sin\arccos q_{0}}$, $v_{y}=\frac{q_{2}}{\sin\arccos q_{0}}$, $v_{z}=\frac{q_{3}}{\sin\arccos q_{0}}$. – Maksim Surov Feb 9 '16 at 12:12
• Actually you don't need to normalize the vector part of quaternion, OpenGL does this itself (see for details link). So, you can avoid singularity while rotating on $0^\circ$ or $360^\circ$. You can call just glRotated(2 * arccos(q[0]), q[1], q[2], q[3]). – Maksim Surov Feb 9 '16 at 12:55
• It worked for me to rotate the 3D object well. Thanks a lot Maksim.. So please clarify me, will the second angle always be in range −π/2..π/2 or in 0..π right?? just to know, so i cant get the 0-2π or -π to +π range.. – karthik Feb 9 '16 at 15:30
• It depends on what you are actually doing. $\beta$ should be in range $(0,\pi)$ (for Z-X-Z convention), but in practice (for example if you evaluate Euler angles by integrating kinematics equations of the rigid-body) these values may go beyond. Moreover kinematic equations have a singularity at $\beta=0,\pi$. That the reason why people usually use quaternions or rotation matrices to define rotations in $\mathbb{E}^3$. – Maksim Surov Feb 9 '16 at 16:25