MPU6050 Sending Bad values for Angular Velocity
At last! I have discovered the solution.

Quick Solution for those who don't like reading: Amend the previous rollRate formula to rollRate = (0.7 * rollRate) + (-0.3 * gx / 16.4);. Or, if you don't want the filter, rollRate = -1 * gx / 16.4;

The problem starts with the function mpu.getRotation(&amp;gx, &amp;gy, &amp;gz) which accepts int16_t types for gx, gy, and gz. Since int16_t is a 16 bit integer, it has a maximum range of -32,768...+32767. The reason this integer type is used is because the output range for the gyro is -32750...+32750, which fits nicely into the 16-bit integer's range.

The problem was that when I converted these values to a readable angular velocity (and complementarily filtered) using  rollRate = (0.7*rollRate) + (0.3*(-180 * gx / 131 / M_PI)); , the gx value was multiplied by -180 in part of the calculation. This means that if gx was high enough initially, it would have rolled over to -32786 and ruined the whole calculation, causing the horrible spikes in the graph.

At the same time I discovered this problem, I also realized that converting from radians to degrees was unnecessary, as the gyro output was already in units of degrees (just scaled by a sensitivity factor). After that big face-palm, I revised my rate formula to the following: rollRate = (0.7 * rollRate) + (-0.3 * gx / 16.4);. You will notice the scale factor has changed from 131 to 16.4. That is because the gyro range is actually +/-2000 deg/s by default, not 250 deg/s. I tried to change it back to +/-250 with mpu.setFullScaleGyroRange(MPU6050_GYRO_FS_250);, but after examining the graph, it appeares that mpu.dmpGetYawPitchRoll(ypr, &amp;q, &amp;gravity); does not account for this setting change, and resulted in the ypr overshooting and then leveling out to its correct value after a delay. I decided not to mess around with the quaternion container, q, and just accepted the lower sensitivity.


Like the previous image, I suggest zooming in.