jrowberg / i2cdevlib

I2C device library collection for AVR/Arduino or other C++-based MCUs
http://www.i2cdevlib.com
3.95k stars 7.51k forks source link

Serial Yaw Roll Pitch example of MPU6050_DMP6 lib #736

Open altomare23 opened 1 year ago

altomare23 commented 1 year ago

I built a box running the serial YPR example. Everything looks ok if roll is kept <90 degrees. But as soon as the box is tilted to have a roll >90 degrees, the pitch abruptly changes to >179 degrees. Why is roll affecting the pitch and viceversa ? Did anybody see this problem or did I something wrong? Is there anything to correct this problem ?

Aarpp commented 1 year ago

Hello altomare23 , its Dis encouraging when questions go ignored, I know. well, I decided to be the change I'd like to see,. Yes, I too noticed the same thing. I am working on a UAV, and I knew I would have to deal with this as well, so I decided to make an attempt.

the following only works with the roll angle from what I observed in testing. Feel free to apply the same to pitch just to experience it yourself. In theory this may allow for barrel rolls .


float PITCH = ypr[1]*180/M_PI;
float ROLL = ypr[2]*180/M_PI;

if(ROLL <=-90){PITCH =-(PITCH +180);}
if(ROLL >=90){PITCH =-(PITCH -180);}

barrel_sol_1 passing past 90 degrees

barrel_sol_2

However, its not perfect you would have to create conditions: what I mean is, if I roll 360 degrees there are two separate regions where pitch is affected and increments to 360 degrees, additional restrictions would need to be placed. This is just a snippet to hopefully get you started.

altomare23 commented 1 year ago

Thanks a lot Aarpp, you were so kind to confirm that the same problem is observed by others. Now, in order to bypass this problem, I implemented a mixed (interim) solution. YAW is evaluated as ypr[0]180/M_PI; but pitch and roll are computed in agreement with https://wiki.dfrobot.com/How_to_Use_a_Three-Axis_Accelerometer_for_Tilt_Sensing. So: ROLL = atan2(AY , AZ) 180.0 /M_PI; PITCH = atan2(-AX , sqrt(AY AY + AZ AZ)) * 180.0 /M_PI; This works much better minimizing interactions. In any case I will experiment your solution to improve all measurements. My special thanks !!!