Thanks for confirming that the fuse() is where it takes place!

I’m broadly familiar with extended Kalman filters- however my own implementations have all been far less complex than the one used in PX4 so I’m at the bottom of a considerable learning curve.

I think what I’m after is the prediction and measurement functions that calculate the bias for the update- so I can find out how it’s calculated.

No problem, glad to help.
Not sure what you mean with “bias for the update” but the prediction step for the gyro bias state is just a stationary process so no change of the state (the uncertainty obviously grows and is calculated using Kahan summation). The update during the measurement step is calculated using sympy here and then copied into the code for the calculation of the Kalman gain for each measurement, e.g. here for the X axis in the 3D mag fusion.

One important thing to note is that the EKF uses an IMU model, i.e. the IMU isn’t fused as a measurement but regarded as a time varying parameter in the prediction step

I think you’ve touched on what may be confusing me- my understanding of the ‘imu modeling’ has been that the state estimation includes gyro and accelerator measurement bias values, which you’ve now told me is predicted to be unchanging in the next time step. These bias values are used in the predictState() function in ekf.cpp to correct the measured imu data.

Presumably, these bias values do actually change as the filter updates, due to some measurement being provided, but the only updates with any calculation I find are those for the covariance update you’ve mentioned already.

I’ve been trying to find out if a measurement to update the bias state actually exists, and if so where it comes from.

I know that a yaw measurement is often used in filters like this to fix bias in the gyro z axis, and presumed something similar was going on here.

If someone could clear this possible misunderstand up I’d be very thankful

Presumably, these bias values do actually change as the filter updates, due to some measurement being provided, but the only updates with any calculation I find are those for the covariance update you’ve mentioned already.

Yes, maybe you missed it but I linked the calculation in my previous reply:

The update during the measurement step is calculated using sympy here and then copied into the code for the calculation of the Kalman gain for each measurement, e.g. here for the X axis in the 3D mag fusion.

Maybe you are missing some of the Kalman filter fundamentals: For every measurement we calculate the Kalman gain, this is a 24 element vector which multiplied with the measurement innovation (or residual) defines how much we update the state. So generally all measurements update all states (how much obviously varies depending on the current covariance matrix etc)

I am looking into the same problem these days, so this discussion also interests me.
thanks for the detailed explanation @CarlOlsson, just trying to get some further clarifications.
As you already pointed out, gyro bias is considered as a stationary stochastic process, and not changed upon every updates.
It seems that @Uplinkc60 is asking about how the proper value of gyro bias parameter is acquired in the first place. Gyro bias is an attribute of gyro device, and is specific to different types of gyro device right? Given a selected onboard gyro device, how can I get the specific value of bias of this type of gyro? can I find it from its datasheet? if not, how do I get it, using an online measurement in realtime, or through some offline calculation over set of measured data, in order to use it as an input parameter to EKF functions?

I think my issue has been just getting lost in the fairly complex code, been a while since I’ve done any Kalman filtering so I’m a bit rusty.

@Orico4 My understanding of gyro bias is that it gradually increases over time for a given axes of the gyro, your gyro might have some data about how quickly this bias typically grows, but in my experience how you move it will also affect this significantly so that value can’t be relied on alone.

In the past I’ve calculated gyro bias by observing measured yaw change using a compass to obtain a angular rate, then comparing that to what the gyro reports.

I can see something similar being done with ‘yaw gyro bias learning’ in mag_control.cpp in the controlMagFusion() if the drone is on the ground.

My understanding of gyro bias is that it gradually increases over time for a given axes of the gyro, your gyro might have some data about how quickly this bias typically grows, but in my experience how you move it will also affect this significantly so that value can’t be relied on alone.

According to px4 source the gyro bias is time varying but as a stochastic process its expectation is constant, at least for a short period of time, and that is why EKF has a reset-interval parameter to reset the bias repeatedly to ensure that, am I get it correctly?

I can see something similar being done with ‘yaw gyro bias learning’ in mag_control.cpp in the controlMagFusion() if the drone is on the ground.

So that means gyro bias is learned online and EKF can not work properly without a magnetometer right?

@Orico4
I’m still a little unclear on how the bias is re-calculated during flight, it seems to be done as part of the Kalman gain calculation CarlOllson provided, but I’m not yet 100% sure on exactly what is being calculated.

The EKF can work without a magnetometer, but to do so requires some absolute source of yaw to be passed externally, eg from vision.

This is what prompted me to ask the question in the first place, I have a VIO system I don’t entirely trust and was trying to figure out what happens if bad ‘compass’ measurements are passed from my VIO.

As I can see from px4 source implementation, gyro bias is re-calculated in every measurement step, in function controlMagFusion() just as you pointed out. This function will then in turn call fuse() in the end, taking Kalman gain and innovation as input params. The Kalman gain and innovation are all calculated based on the covariance of in-run measured mag data. Only one thing that different from your previous description, I think the “bias learning” in controlMagFusion() is not only on the ground, but continuously on the flight in-run,.

If you are using a VIO system instead of mag, then the input to fuse() function changed to vision _heading_innov, which then gyro_bias will be recalculated upon. I think if the VIO system passing a bad measurement, then should be the same effect as passing in a bad mag measurement.

It maybe worth point out that, there is a flag (update_all_state) in px4 implementation, controlling if gyro bias should be updated during measurement step.
If update_all_state is set to false, then gyro bias remains unchanged all the way.