From 8a34df6528c4def61f31dfb48089b7d5b33e3a0e Mon Sep 17 00:00:00 2001 From: priseborough Date: Tue, 22 Nov 2016 09:21:01 +1100 Subject: [PATCH] AP_NavEKF2: Reduce unnecessary EKF core switching 1) Do not switch to a core until its states have been updated. 2) Distinguish between mandated switches required for health failure and optional switches required due to innovation checks failing. 3) Apply hyseresis to innovation check levels --- libraries/AP_NavEKF2/AP_NavEKF2.cpp | 51 ++++++++++++++------- libraries/AP_NavEKF2/AP_NavEKF2_Outputs.cpp | 24 ++++------ libraries/AP_NavEKF2/AP_NavEKF2_core.h | 4 +- 3 files changed, 44 insertions(+), 35 deletions(-) diff --git a/libraries/AP_NavEKF2/AP_NavEKF2.cpp b/libraries/AP_NavEKF2/AP_NavEKF2.cpp index a370deb52c..d7c4bcd4ca 100644 --- a/libraries/AP_NavEKF2/AP_NavEKF2.cpp +++ b/libraries/AP_NavEKF2/AP_NavEKF2.cpp @@ -639,37 +639,54 @@ void NavEKF2::UpdateFilter(void) const AP_InertialSensor &ins = _ahrs->get_ins(); + bool statePredictEnabled[num_cores]; for (uint8_t i=0; i 0) && (core[i-1].getFramesSincePredict() < 2) && (ins.get_sample_rate() > 200)) { - statePredictEnabled = false; + statePredictEnabled[i] = false; } else { - statePredictEnabled = true; + statePredictEnabled[i] = true; } - core[i].UpdateFilter(statePredictEnabled); + core[i].UpdateFilter(statePredictEnabled[i]); } - // If the current core selected has a bad fault score or is unhealthy, switch to a healthy core with the lowest fault score - if (core[primary].faultScore() > 0.0f || !core[primary].healthy()) { - float score = 1e9f; + // If the current core selected has a bad error score or is unhealthy, switch to a healthy core with the lowest fault score + float primaryErrorScore = core[primary].errorScore(); + if (primaryErrorScore > 1.0f || !core[primary].healthy()) { + float lowestErrorScore = primaryErrorScore; // lowest error score from all lanes bool has_switched = false; // true if a switch has occurred this frame - for (uint8_t i=0; i 1.0f) { - score += velTestRatio-1.0f; - } - if (posTestRatio > 1.0f) { - score += posTestRatio-1.0f; - } - if (hgtTestRatio > 1.0f) { - score += hgtTestRatio-1.0f; - } - // If the tilt error is excessive this adds to the score - const float tiltErrThreshold = 0.05f; - if (tiltAlignComplete && yawAlignComplete && tiltErrFilt > tiltErrThreshold) { - score += tiltErrFilt / tiltErrThreshold; + if (tiltAlignComplete && yawAlignComplete) { + score = MAX(score, velTestRatio); + score = MAX(score, posTestRatio); + score = MAX(score, hgtTestRatio); + const float tiltErrThreshold = 0.05f; + score = MAX(score, tiltErrFilt / tiltErrThreshold); } return score; } diff --git a/libraries/AP_NavEKF2/AP_NavEKF2_core.h b/libraries/AP_NavEKF2/AP_NavEKF2_core.h index 5cac261b76..c797480c55 100644 --- a/libraries/AP_NavEKF2/AP_NavEKF2_core.h +++ b/libraries/AP_NavEKF2/AP_NavEKF2_core.h @@ -66,9 +66,9 @@ public: // Check basic filter health metrics and return a consolidated health status bool healthy(void) const; - // Return a consolidated fault score where higher numbers are less healthy + // Return a consolidated error score where higher numbers are less healthy // Intended to be used by the front-end to determine which is the primary EKF - float faultScore(void) const; + float errorScore(void) const; // Write the last calculated NE position relative to the reference point (m). // If a calculated solution is not available, use the best available data and return false