Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EKF2] Tilt estimate improvements #24247

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft

Conversation

bresch
Copy link
Member

@bresch bresch commented Jan 23, 2025

Solved Problem

Constant small accelerations during gravity fusion creates a small tilt error. As a consequence, the accel bias gets incorrectly estimated and the gravity fusion (using this bias estimate) takes more time to correct back the error.

Solution

Stop accel bias estimation while gravity fusion is active.

Additionally:

  • start gravity fusion based on accelerometer LPF instead of a peak hold filter (this was causing the flag to switch on and off all the time due to vibrations/spikes). The innovation filter with a small gate (0.25) is more than enough to avoid fusing quick changes in accelerometer data
  • add a "update_tilt" parameter to declination to force the "tilt Kalman gains" to 0 as we already do in mag fusion

Test coverage

EKF replay, unit tests, SITL tests

Before: rapid flag switching
image

After: incorrect acceleration are rejected by he innovation filter and not the control flag
Screenshot from 2025-01-23 15-47-29

This prevent rapid switching in presence of noise and the innovation
filter is good at rejecting spikes
Gravity fusion uses the bias corrected accelerometer data to correct the
tilt estimate. We should not continue to estimate the accel bias when
this is active as it creates an unwanted feedback loop.
@bresch bresch requested review from dagar and haumarco January 23, 2025 15:05
@bresch bresch self-assigned this Jan 23, 2025
@@ -54,8 +54,9 @@ void Ekf::controlGravityFusion(const imuSample &imu)

const float upper_accel_limit = CONSTANTS_ONE_G * 1.1f;
const float lower_accel_limit = CONSTANTS_ONE_G * 0.9f;
const bool accel_lpf_norm_good = (_accel_magnitude_filt > lower_accel_limit)
&& (_accel_magnitude_filt < upper_accel_limit);
const float accel_lpf_norm_sq = _accel_lpf.getState().norm_squared();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_accel_lpf is only being updated during init, but I was thinking we should move it regardless.

bool Ekf::initialiseFilter()
{
// Filter accel for tilt initialization
const imuSample &imu_init = _imu_buffer.get_newest();
// protect against zero data
if (imu_init.delta_vel_dt < 1e-4f || imu_init.delta_ang_dt < 1e-4f) {
return false;
}
if (_is_first_imu_sample) {
_accel_lpf.reset(imu_init.delta_vel / imu_init.delta_vel_dt);
_gyro_lpf.reset(imu_init.delta_ang / imu_init.delta_ang_dt);
_is_first_imu_sample = false;
} else {
_accel_lpf.update(imu_init.delta_vel / imu_init.delta_vel_dt);
_gyro_lpf.update(imu_init.delta_ang / imu_init.delta_ang_dt);
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was moving it here, but got a little sidetracked. #24046

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ouch, I didn't realize that; thanks

@bresch bresch marked this pull request as draft January 24, 2025 07:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants