From d8c2096ad8fcc287ce3bfd330bc8f404c75da6ff Mon Sep 17 00:00:00 2001 From: Paul Riseborough Date: Mon, 8 Jun 2020 12:13:49 +1000 Subject: [PATCH] AP_NavEKF3: improve angle accuracy during no mag launch --- libraries/AP_NavEKF3/AP_NavEKF3_MagFusion.cpp | 5 ++- .../AP_NavEKF3/AP_NavEKF3_PosVelFusion.cpp | 39 +++++++++++++++---- libraries/AP_NavEKF3/AP_NavEKF3_core.h | 1 + 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/libraries/AP_NavEKF3/AP_NavEKF3_MagFusion.cpp b/libraries/AP_NavEKF3/AP_NavEKF3_MagFusion.cpp index 126ccc9f6f..cffb5470e9 100644 --- a/libraries/AP_NavEKF3/AP_NavEKF3_MagFusion.cpp +++ b/libraries/AP_NavEKF3/AP_NavEKF3_MagFusion.cpp @@ -19,7 +19,7 @@ void NavEKF3_core::controlMagYawReset() // Vehicles that can use a zero sideslip assumption (Planes) are a special case // They can use the GPS velocity to recover from bad initial compass data // This allows recovery for heading alignment errors due to compass faults - if (assume_zero_sideslip() && !finalInflightYawInit && inFlight ) { + if (assume_zero_sideslip() && !finalInflightYawInit && inFlight) { gpsYawResetRequest = true; return; } else { @@ -1499,6 +1499,9 @@ bool NavEKF3_core::EKFGSF_resetMainFilterYaw() // Fail the magnetomer so it doesn't get used and pull the yaw away from the correct value allMagSensorsFailed = true; + // record the yaw reset event + recordYawReset(); + // reset velocity and position states to GPS - if yaw is fixed then the filter should start to operate correctly ResetVelocity(); ResetPosition(); diff --git a/libraries/AP_NavEKF3/AP_NavEKF3_PosVelFusion.cpp b/libraries/AP_NavEKF3/AP_NavEKF3_PosVelFusion.cpp index 4748e13992..c8ab996abe 100644 --- a/libraries/AP_NavEKF3/AP_NavEKF3_PosVelFusion.cpp +++ b/libraries/AP_NavEKF3/AP_NavEKF3_PosVelFusion.cpp @@ -533,15 +533,38 @@ void NavEKF3_core::SelectVelPosFusion() } } - // If we are operating without any aiding, fuse in the last known position - // to constrain tilt drift. This assumes a non-manoeuvring vehicle - // Do this to coincide with the height fusion + // If we are operating without any aiding, fuse in constnat position of constant + // velocity measurements to constrain tilt drift. This assumes a non-manoeuvring + // vehicle. Do this to coincide with the height fusion. if (fuseHgtData && PV_AidingMode == AID_NONE) { - velPosObs[3] = lastKnownPositionNE.x; - velPosObs[4] = lastKnownPositionNE.y; - - fusePosData = true; - fuseVelData = false; + if (assume_zero_sideslip() && tiltAlignComplete && motorsArmed) { + // handle special case where we are launching a FW aircraft without magnetometer + fusePosData = false; + velPosObs[0] = 0.0f; + velPosObs[1] = 0.0f; + velPosObs[2] = stateStruct.velocity.z; + bool resetVelNE = !prevMotorsArmed; + // reset states to stop launch accel causing tilt error + if (imuDataDelayed.delVel.x > 1.1f * GRAVITY_MSS * imuDataDelayed.delVelDT) { + lastLaunchAccelTime_ms = imuSampleTime_ms; + fuseVelData = false; + resetVelNE = true; + } else if (lastLaunchAccelTime_ms != 0 && (imuSampleTime_ms - lastLaunchAccelTime_ms) < 10000) { + fuseVelData = false; + resetVelNE = true; + } else { + fuseVelData = true; + } + if (resetVelNE) { + stateStruct.velocity.x = 0.0f; + stateStruct.velocity.y = 0.0f; + } + } else { + fusePosData = true; + fuseVelData = false; + velPosObs[3] = lastKnownPositionNE.x; + velPosObs[4] = lastKnownPositionNE.y; + } } // perform fusion diff --git a/libraries/AP_NavEKF3/AP_NavEKF3_core.h b/libraries/AP_NavEKF3/AP_NavEKF3_core.h index 31a07a433b..99bafb6a93 100644 --- a/libraries/AP_NavEKF3/AP_NavEKF3_core.h +++ b/libraries/AP_NavEKF3/AP_NavEKF3_core.h @@ -1040,6 +1040,7 @@ private: uint32_t lastSynthYawTime_ms; // time stamp when yaw observation was last fused (msec) uint32_t ekfStartTime_ms; // time the EKF was started (msec) Vector2f lastKnownPositionNE; // last known position + uint32_t lastLaunchAccelTime_ms; uint32_t lastDecayTime_ms; // time of last decay of GPS position offset float velTestRatio; // sum of squares of GPS velocity innovation divided by fail threshold float posTestRatio; // sum of squares of GPS position innovation divided by fail threshold