From 7d4a50f4836a59eb820f2dfd1ae1bc542865ea9a Mon Sep 17 00:00:00 2001 From: priseborough Date: Tue, 13 Dec 2016 10:04:50 +1100 Subject: [PATCH] AP_NavEKF3: Prevent unwanted core switch on startup Require primary core to be healthy for 10 seconds before starting selection logic --- libraries/AP_NavEKF3/AP_NavEKF3.cpp | 14 ++++++++++++-- libraries/AP_NavEKF3/AP_NavEKF3.h | 2 ++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/libraries/AP_NavEKF3/AP_NavEKF3.cpp b/libraries/AP_NavEKF3/AP_NavEKF3.cpp index 4465a6d1d3..8e518c8cd7 100644 --- a/libraries/AP_NavEKF3/AP_NavEKF3.cpp +++ b/libraries/AP_NavEKF3/AP_NavEKF3.cpp @@ -548,7 +548,8 @@ NavEKF3::NavEKF3(const AP_AHRS *ahrs, AP_Baro &baro, const RangeFinder &rng) : gndEffectTimeout_ms(1000), // time in msec that baro ground effect compensation will timeout after initiation gndEffectBaroScaler(4.0f), // scaler applied to the barometer observation variance when operating in ground effect gndGradientSigma(50), // RMS terrain gradient percentage assumed by the terrain height estimation - fusionTimeStep_ms(10) // The minimum number of msec between covariance prediction and fusion operations + fusionTimeStep_ms(10), // The minimum number of msec between covariance prediction and fusion operations + runCoreSelection(false) // true when the default primary core has stabilised after startup and core selection can run { AP_Param::setup_object_defaults(this, var_info); } @@ -683,8 +684,17 @@ void NavEKF3::UpdateFilter(void) } // If the current core selected has a bad error score or is unhealthy, switch to a healthy core with the lowest fault score + // Don't start running the check until the primary core has started returned healthy for at least 10 seconds to avoid switching + // due to initial alignment fluctuations and race conditions + if (!runCoreSelection) { + static uint64_t lastUnhealthyTime_us = 0; + if (!core[primary].healthy() || lastUnhealthyTime_us == 0) { + lastUnhealthyTime_us = imuSampleTime_us; + } + runCoreSelection = (imuSampleTime_us - lastUnhealthyTime_us) > 1E7; + } float primaryErrorScore = core[primary].errorScore(); - if (primaryErrorScore > 1.0f || !core[primary].healthy()) { + if ((primaryErrorScore > 1.0f || !core[primary].healthy()) && runCoreSelection) { float lowestErrorScore = 0.67f * primaryErrorScore; uint8_t newPrimaryIndex = primary; // index for new primary for (uint8_t coreIndex=0; coreIndex