# Yaw drift when implementing AHRS filter fusion

I am using the Matlab AHRS filter fusion algorithm with an InvenSense ICM-20948 to determine object orientation. I seem to be obtaining reasonable results however I am getting what appears to be substantial yaw/heading drift (please see attached plot).

The Matlab AHRS filter fusion algorithm requires the following hardware/scenario specific parameters to be set (which I think is where my problem is stemming from):

• Accelerometer noise - variance of accelerometer signal noise $$(\frac{m}{s^2})^2$$
• Magnetometer noise - variance of magnetometer signal noise $$T^2$$

• Gyroscope noise - variance of gyroscope signal noise $$(\frac{rad}{s})^2$$

• Gyroscope drift noise - variance of gyroscope offset drift $$(\frac{rad}{s})^2$$

• Linear acceleration noise - variance of linear acceleration noise
$$(\frac{m}{s^2})^2$$

• Linear acceleration decay factor (this appears to be dependent on the application/movement velocity)

• Magnetic disturbance noise - variance of magnetic disturbance noise $$T^2$$

• Magnetic disturbance decay factor - decay factor for magnetic disturbance

• Expected magnetic field strength (I understand this as being location dependant)

• Initial process noise - covariance matrix for process noise

I have calibrated my magnetometer to account for hard/soft iron effects. Additionally, I have found and am now using what I believe to be appropriate values for the Accelerometer noise and Gyroscope noise from the ICM-20948 data sheet.

Does anyone know where I may be going wrong or how I may obtain/set/measure any more of the above parameters to perhaps reduce this drift?

You haven't provided any sample data or your implementation, etc., so it's hard to say for sure, but I would imagine that the signal coming in on your magnetometer is small enough that it's insufficient to set the angle. If your magnetometer readings went to zero, you would effectively have no magnetometer and you would get the same drift you're seeing.

You said the magnetometer noise should be in units of $$T$$, but the Matlab documentation says otherwise:
What units are you passing to the filter? $$T$$ or $$\mu T$$? Per the documentation, it should be $$\mu T$$. The expected local strength should also be $$\mu T$$.