From c57b25b4c92b4ec608b288de0e5cfa6d744b19c3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 27 Jul 2019 17:00:10 +1000 Subject: [PATCH] AP_NavEKF2: ensure that EKF origin stays in sync on all cores this prevents the EKF origin on different cores from being initialised to different values. A common value is stored in the frontend and used by a core if it doesn't have an origin --- libraries/AP_NavEKF2/AP_NavEKF2.h | 4 ++++ libraries/AP_NavEKF2/AP_NavEKF2_Control.cpp | 10 +++++++--- libraries/AP_NavEKF2/AP_NavEKF2_Measurements.cpp | 7 ++++++- libraries/AP_NavEKF2/AP_NavEKF2_core.h | 2 +- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/libraries/AP_NavEKF2/AP_NavEKF2.h b/libraries/AP_NavEKF2/AP_NavEKF2.h index 1683f09a7c..e6c35f2fc3 100644 --- a/libraries/AP_NavEKF2/AP_NavEKF2.h +++ b/libraries/AP_NavEKF2/AP_NavEKF2.h @@ -447,6 +447,10 @@ private: const float gndEffectBaroScaler = 4.0f; // scaler applied to the barometer observation variance when ground effect mode is active const uint8_t fusionTimeStep_ms = 10; // The minimum time interval between covariance predictions and measurement fusions in msec + // origin set by one of the cores + struct Location common_EKF_origin; + bool common_origin_valid; + struct { bool enabled:1; bool log_compass:1; diff --git a/libraries/AP_NavEKF2/AP_NavEKF2_Control.cpp b/libraries/AP_NavEKF2/AP_NavEKF2_Control.cpp index d9d9c95798..1beea0de5f 100644 --- a/libraries/AP_NavEKF2/AP_NavEKF2_Control.cpp +++ b/libraries/AP_NavEKF2/AP_NavEKF2_Control.cpp @@ -430,10 +430,10 @@ bool NavEKF2_core::setOriginLLH(const Location &loc) } // Set the NED origin to be used until the next filter reset -void NavEKF2_core::setOrigin() +void NavEKF2_core::setOrigin(const Location &loc) { // assume origin at current GPS location (no averaging) - EKF_origin = AP::gps().location(); + EKF_origin = loc; // if flying, correct for height change from takeoff so that the origin is at field elevation if (inFlight) { EKF_origin.alt += (int32_t)(100.0f * stateStruct.position.z); @@ -442,7 +442,11 @@ void NavEKF2_core::setOrigin() // define Earth rotation vector in the NED navigation frame at the origin calcEarthRateNED(earthRateNED, EKF_origin.lat); validOrigin = true; - gcs().send_text(MAV_SEVERITY_INFO, "EKF2 IMU%u Origin set to GPS",(unsigned)imu_index); + gcs().send_text(MAV_SEVERITY_INFO, "EKF2 IMU%u origin set",(unsigned)imu_index); + + // put origin in frontend as well to ensure it stays in sync between lanes + frontend->common_EKF_origin = EKF_origin; + frontend->common_origin_valid = true; } // record a yaw reset event diff --git a/libraries/AP_NavEKF2/AP_NavEKF2_Measurements.cpp b/libraries/AP_NavEKF2/AP_NavEKF2_Measurements.cpp index 966caa30dd..e4646c0e5a 100644 --- a/libraries/AP_NavEKF2/AP_NavEKF2_Measurements.cpp +++ b/libraries/AP_NavEKF2/AP_NavEKF2_Measurements.cpp @@ -547,12 +547,17 @@ void NavEKF2_core::readGpsData() // Post-alignment checks calcGpsGoodForFlight(); + // see if we can get origin from frontend + if (!validOrigin && frontend->common_origin_valid) { + setOrigin(frontend->common_EKF_origin); + } + // Read the GPS location in WGS-84 lat,long,height coordinates const struct Location &gpsloc = gps.location(); // Set the EKF origin and magnetic field declination if not previously set and GPS checks have passed if (gpsGoodToAlign && !validOrigin) { - setOrigin(); + setOrigin(gpsloc); // set the NE earth magnetic field states using the published declination // and set the corresponding variances and covariances diff --git a/libraries/AP_NavEKF2/AP_NavEKF2_core.h b/libraries/AP_NavEKF2/AP_NavEKF2_core.h index 91bf614f80..ce5390b9bb 100644 --- a/libraries/AP_NavEKF2/AP_NavEKF2_core.h +++ b/libraries/AP_NavEKF2/AP_NavEKF2_core.h @@ -710,7 +710,7 @@ private: void controlMagYawReset(); // Set the NED origin to be used until the next filter reset - void setOrigin(); + void setOrigin(const Location &loc); // determine if a takeoff is expected so that we can compensate for expected barometer errors due to ground effect bool getTakeoffExpected();