hideakitai/MPU9250

YAW overshoots on rapid movement

Tobbera opened this issue · 5 comments

Environment

IDE (Arduino IDE.) :
Board/MCU (ESP32):
MPU-9250 Library Version: Latest

Problem Summary

When rotating the MPU-9250 rapidly the YAW overshoots significantly. And sometimes it does not overshoot at all but rather slowly finds its YAW. If this was a PID-loop I would start to fiddle with the kP, kI, kD values. But what can I tweak in this case? I tried to change the mpu.setFilterIterations(); from 1 to 20 without any noticeable difference.

bild

Reproducible & Minimal & Compilable Code

#include "src/MPU9250-master/MPU9250.h"
int interval = 20;

MPU9250 mpu;
float Yaw, Pitch, Roll, compassHeading;

void setup()
{

  Wire.begin();
  delay(2000);

  if (!mpu.setup(0x68))
  { // change to your own address
    while (1)
    {
      Serial.println("MPU connection failed. Please check your connection with `connection_check` example.");
      delay(5000);
    }
    Serial.print("millis, Yaw, Pitch, Roll, compassHeading");
  }


  delay(2000);

  mpu.setMagneticDeclination(-0.36); // Latitude: 9° 32' 55.5" N, Longitude: 100° 3' 9" E, Thailand, Magnetic Declination: -0° 36'
  mpu.setFilterIterations(20);        // The default value is 1. Generally 10-20 is good for stable yaw estimation. Please see [this discussion](https://github.com/kriswiner/MPU9250/issues/420) for the detail.
  mpu.setAccBias(-64.05, 19.68, 43.55);
  mpu.setGyroBias(-0.24, 0.16, 0.51);
  mpu.setMagBias(-43.15, 123.07, -19.13);
  mpu.setMagScale(0.87, 0.95, 1.25);
}

void loop()
{
  if (mpu.update())
  {
    Yaw = mpu.getYaw();
    Pitch = mpu.getPitch();
    Roll = mpu.getRoll();
    compassHeading = Yaw;
    if (compassHeading < 0)
    {
      compassHeading = (compassHeading + 360.00);
    }
  }

  if (millis() - previousMillis > interval)
  {
    previousMillis = millis();
    print_roll_pitch_yaw();
  }
}


void print_roll_pitch_yaw()
{
  // Serial.print("millis, Yaw, Pitch, Roll, compassHeading: ");
  Serial.print(millis());
  Serial.print(", ");
  Serial.print(Yaw, 2);
  Serial.print(", ");
  Serial.print(Pitch, 2);
  Serial.print(", ");
  Serial.print(Roll, 2);
  Serial.print(", ");
  Serial.println(compassHeading, 2);
  // Serial.print("Euler : ");
  // Serial.print(mpu.getEulerX(), 2);
  // Serial.print(", ");
  // Serial.print(mpu.getEulerY(), 2);
  // Serial.print(", ");
  // Serial.println(mpu.getEulerZ(), 2);
}


This is the startup behaviours which I suppose is rather normal. But posting it for the sake of it.

bild

Here the overshoot is very visible. In reality its a rotation of JAW of 5 degrees. But it overshoots with 20 (!!) degrees and is not normalized for almost 3 seconds.

bild

And then, a few minutes later, I get completely opposite results:

bild

I think the fast motion or the mechanical vibration can lead to this problem. How about using the quaternion form?

Please try adjusting parameters for filters

https://github.com/hideakitai/MPU9250/blob/master/MPU9250/QuaternionFilter.h

Or you can use other filters with raw sensor data like this

https://github.com/arduino-libraries/MadgwickAHRS