For a home robotics project I just bought a BerryIMU to connect it to my Raspberry Pi. After hooking it up I ran the provided Python code to read out some values while moving it around.

If I keep the IMU (more or less) straight and in Northern direction I get the following line of output:

ACCX Angle  0.60 
ACCY Angle  4.58       
GRYX Angle -125.14  
GYRY Angle 114.15  
GYRZ Angle 93.74     
CFangleX Angle -0.26   
CFangleY Angle  4.45  
HEADING   1.02  
tiltCompensatedHeading  3.73  
kalmanX  0.48   
kalmanY  4.43

I am most interested in the compass (in 360 degrees), and how much it tilts right/left and front/back.

As far as I understand, the tiltCompensatedHeading tells me that it points 3.73 degrees right of the magnetic north. And I think kalmanX and kalmanY should give me the tilting of the IMU to the left/right (X) and to the front/back (Y) (compensated by a Kalman filter for smoothening).

So I played around with it and saw what the numbers did. In the images below I look slightly down on it. I hope the description on it explains how you see it.

enter image description here

From what you see here the X and Y degrees independently behave as I would expect them to. But what I don't understand is why "the other one" is always between 90 and 130. So if I tilt it 90 degrees forward I would expect

X ≈ 0
Y ≈ 90

similarly, if I tilt it 90 degrees backward, I would expect

X ≈ 0
Y ≈ -90

Instead X is around 100 for both of them and I really don't understand why it's not around 0.

Does anybody see the logic in this? What am I missing?

  • $\begingroup$ Hey. Look at this article, loaded it in dropbox for you dropbox.com/s/8xrdf0mb1cwhe4p/PitchRollEstimation.pdf?dl=0 . Read about regions of instability. It is highly possible that it is your problem. $\endgroup$
    – Long Smith
    Commented Mar 17, 2017 at 10:03
  • $\begingroup$ @LongSmith - Thanks for your answer. Although I don't really understand the math behind it, I presume this is indeed the problem. I checked out the numbers while tilting in angles less than 90 degrees, and then both the X and the Y angle seem to behave correctly. I still don't really understand how they overcome this issue in for example planes or phones, but if you add your comment as an answer I can accept it. $\endgroup$
    – kramer65
    Commented Mar 17, 2017 at 10:50
  • $\begingroup$ I don't think you wouldn't understand the math. Equations seem awful but actually all the article describes is just matrix multiplication of rotation matrices. For instance, if you choose rotation sequence xyz, you have to sequentially multiply rotation matrices around x, y and z axes. Now if you apply your transformation to gravity vector when it is perpendicular to the earth surface, you will get your accelerometer readings. Therefore to find angles you just have to solve system of 3 equations. That's all. $\endgroup$
    – Long Smith
    Commented Mar 17, 2017 at 11:18
  • $\begingroup$ Read more carefully about regions of instability, there is the solution for your problem. Will issue as an answer later. $\endgroup$
    – Long Smith
    Commented Mar 17, 2017 at 11:21

1 Answer 1


The problem is estimating angles in regions of instability.

Let us look at equations used for estimation of pitch and roll angles. For aerospace rotation sequence e.g. $xyz$:

$\tan(roll)=\frac{G_{y}}{G_{z}}\\ \tan(pitch)=\frac{-G_{x}}{\sqrt{G_{y}^2+G_{z}^2}}$

Now imagine that you rotated IMU around $y$ axis by 90 degrees so that $G_{x}=-g, G_{y}=0, G_{z}=0$ and look at the first equation. Since both parts of it are close to zero, $atan(\frac{\approx 0}{\approx 0})$, inverse tangent deals almost only with noise therefore you get unpredicted results. The second equation is $atan(\frac{g}{\approx0})=\frac{\pi}{2}$

For the $yxz$ rotation sequence so the equations are:

$\tan(roll)=\frac{G_{y}}{\sqrt{G_{x}^2+G_{z}^2}}\\ \tan(pitch)=\frac{-G_{x}}{G_{z}}$

This way your region includes cases when $y$ axis points upwards or downwards.

The possible solution is to modify unstable equations, for $yxz$ it would be:

$\tan(pitch)=\frac{-G_{x}}{sign(G_{z})\sqrt{G_{z}^2+\mu G_{y}^2}}$ where $\mu$ is a small scale factor.

Adding small amount of $G_{y}$ will prevent denominator from being zero ever. And it can be shown that until you are in unstable region the values estimated by original and modified equations are almost equal. However when we are in unstable region, pitch becomes just an approximation but still very close to the true result.

Actually I can not understand why you have wrong results in both cases: rotating around $x$ axis and $y$ axis. If we rotate sensor around $x$ axis so that $G_{x} = 0, G_{y}=g, G_{z} = 0$ and insert them into $xyz$ equations we will get $roll=atan(\frac{g}{\approx 0}) \approx \frac{\pi}{2}$ and $pitch=atan(\frac{\approx 0}{g})\approx0$. This case is stable as you can see.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.