AP_NavEKF3: update earth field at 1Hz

this prevents large mag errors on long distance flights
This commit is contained in:
Andrew Tridgell 2021-06-28 11:34:01 +10:00 committed by Randy Mackay
parent 399cd4ea03
commit e409202bef
3 changed files with 33 additions and 4 deletions

View File

@ -690,10 +690,7 @@ void NavEKF3_core::readGpsData()
if (gpsGoodToAlign && !have_table_earth_field) { if (gpsGoodToAlign && !have_table_earth_field) {
const auto *compass = dal.get_compass(); const auto *compass = dal.get_compass();
if (compass && compass->have_scale_factor(magSelectIndex) && compass->auto_declination_enabled()) { if (compass && compass->have_scale_factor(magSelectIndex) && compass->auto_declination_enabled()) {
table_earth_field_ga = AP_Declination::get_earth_field_ga(gpsloc).toftype(); getEarthFieldTable(gpsloc);
table_declination = radians(AP_Declination::get_declination(gpsloc.lat*1.0e-7,
gpsloc.lng*1.0e-7));
have_table_earth_field = true;
if (frontend->_mag_ef_limit > 0) { if (frontend->_mag_ef_limit > 0) {
// initialise earth field from tables // initialise earth field from tables
stateStruct.earth_magfield = table_earth_field_ga; stateStruct.earth_magfield = table_earth_field_ga;
@ -1456,3 +1453,27 @@ void NavEKF3_core::SampleDragData(const imu_elements &imu)
} }
#endif // EK3_FEATURE_DRAG_FUSION #endif // EK3_FEATURE_DRAG_FUSION
} }
/*
get the earth mag field
*/
void NavEKF3_core::getEarthFieldTable(const Location &loc)
{
table_earth_field_ga = AP_Declination::get_earth_field_ga(loc).toftype();
table_declination = radians(AP_Declination::get_declination(loc.lat*1.0e-7,
loc.lng*1.0e-7));
have_table_earth_field = true;
last_field_update_ms = imuSampleTime_ms;
}
/*
check if we should update the earth field, we update it at 1Hz
*/
void NavEKF3_core::checkUpdateEarthField(void)
{
if (have_table_earth_field && imuSampleTime_ms - last_field_update_ms > 1000) {
Location loc = EKF_origin;
loc.offset(stateStruct.position.x, stateStruct.position.y);
getEarthFieldTable(loc);
}
}

View File

@ -725,6 +725,9 @@ void NavEKF3_core::UpdateFilter(bool predict)
statesInitialised = false; statesInitialised = false;
InitialiseFilterBootstrap(); InitialiseFilterBootstrap();
} }
// check for update of earth field
checkUpdateEarthField();
} }
void NavEKF3_core::correctDeltaAngle(Vector3F &delAng, ftype delAngDT, uint8_t gyro_index) void NavEKF3_core::correctDeltaAngle(Vector3F &delAng, ftype delAngDT, uint8_t gyro_index)

View File

@ -1403,7 +1403,12 @@ private:
bool have_table_earth_field; // true when we have initialised table_earth_field_ga bool have_table_earth_field; // true when we have initialised table_earth_field_ga
Vector3F table_earth_field_ga; // earth field from WMM tables Vector3F table_earth_field_ga; // earth field from WMM tables
ftype table_declination; // declination in radians from the tables ftype table_declination; // declination in radians from the tables
uint32_t last_field_update_ms;
// handle earth field updates
void getEarthFieldTable(const Location &loc);
void checkUpdateEarthField(void);
// timing statistics // timing statistics
struct ekf_timing timing; struct ekf_timing timing;