mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-16 11:03:34 +08:00
EKF: Add Emergency yaw recovery using EKF-GSF estimator (#766)
* EKF: Use common rate vector calculation for offset corrections * EKF: Remove duplicate matrix entry calculations * EKF: Create a EKF-GSF yaw estimator class * EKF: add emergency yaw reset functionality * EKF: remove un-used function * EKF: Ensure required constants are defined for all builds * EKF: Fix CI build error * Revert "EKF: remove un-used function" This reverts commit 93005309c7f3794414ad99c86218b3062e00bbd3. * EKF: Replace in-lined Tait-Bryan 312 conversions with function call Also remove unnecessary operations * EKF: Remove unnecessary update of external vision rotation matrix * EKF: Use const * EKF: use const * EKF: don't use class variable as a temporary variable * EKF: update comments * EKF: Improve efficiency of yaw reset Use conversion from rotation matrix to Euler angles instead of quaternion to euler angles. * EKF: use const * EKF: remove un-used struct element * EKF: more descriptive function name * EKF: use existing matrix row operator * EKF: remove unnecessary rotation matrix update * EKF: Use square matrix type * EKF: Improve protection for bad innovation covariance * EKF: Use matrix library operations * EKF: Replace memcpy with better alternative memcpy bypasses compiler sanity checks and is unnecessary in this instance. * EKF: Split EKF-GSF yaw reset function Adds a common function to support yaw reset that can be used elsewhere. * EKF: Use common function for quaternion state and covariance yaw reset * EKF: Replace inlined matrix operation * EKF: Use const * EKF: Change accessor function name * EKF: Use const * EKF: Don't create unnecessary duplicate variable locations * EKF: Remove duplicate covariance innovation inverse * EKF: Don't create unnecessary duplicate variable locations * EKF: Rely on geo library to provide gravity * EKF: Improve protection from bad updates * EKF: Reduce effect of vibration on yaw estimator AHRS * EKF: Improve yaw estimator AHRS accuracy during manoeuvre transients
This commit is contained in:
+8
-34
@@ -624,46 +624,20 @@ void Ekf::fuseHeading()
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Calculate the 312 sequence euler angles that rotate from earth to body frame
|
||||
* Derived from https://github.com/PX4/ecl/blob/master/matlab/scripts/Inertial%20Nav%20EKF/quat2yaw312.m
|
||||
* Body to nav frame transformation using a yaw-roll-pitch rotation sequence is given by:
|
||||
*
|
||||
[ cos(pitch)*cos(yaw) - sin(pitch)*sin(roll)*sin(yaw), -cos(roll)*sin(yaw), cos(yaw)*sin(pitch) + cos(pitch)*sin(roll)*sin(yaw)]
|
||||
[ cos(pitch)*sin(yaw) + cos(yaw)*sin(pitch)*sin(roll), cos(roll)*cos(yaw), sin(pitch)*sin(yaw) - cos(pitch)*cos(yaw)*sin(roll)]
|
||||
[ -cos(roll)*sin(pitch), sin(roll), cos(pitch)*cos(roll)]
|
||||
*/
|
||||
float yaw = atan2f(-_R_to_earth(0, 1), _R_to_earth(1, 1)); // first rotation (yaw)
|
||||
const float roll = asinf(_R_to_earth(2, 1)); // second rotation (roll)
|
||||
const float pitch = atan2f(-_R_to_earth(2, 0), _R_to_earth(2, 2)); // third rotation (pitch)
|
||||
|
||||
predicted_hdg = yaw; // we will need the predicted heading to calculate the innovation
|
||||
// Use a Tait-Bryan 312 rotation sequence
|
||||
Vector3f rotVec312;
|
||||
predicted_hdg = atan2f(-_R_to_earth(0, 1), _R_to_earth(1, 1));
|
||||
rotVec312(0) = 0.0f; // first rotation (yaw) set to zero for alter use when rotating the mag field into earth frame
|
||||
rotVec312(1) = asinf(_R_to_earth(2, 1)); // second rotation (roll)
|
||||
rotVec312(2) = atan2f(-_R_to_earth(2, 0), _R_to_earth(2, 2)); // third rotation (pitch)
|
||||
|
||||
// calculate the observed yaw angle
|
||||
if (_control_status.flags.mag_hdg) {
|
||||
// Set the first rotation (yaw) to zero and rotate the measurements into earth frame
|
||||
yaw = 0.0f;
|
||||
|
||||
// Calculate the body to earth frame rotation matrix from the euler angles using a 312 rotation sequence
|
||||
// Equations from Tbn_312.c produced by https://github.com/PX4/ecl/blob/master/matlab/scripts/Inertial%20Nav%20EKF/quat2yaw312.m
|
||||
Dcmf R_to_earth;
|
||||
float sy = sinf(yaw);
|
||||
float cy = cosf(yaw);
|
||||
float sp = sinf(pitch);
|
||||
float cp = cosf(pitch);
|
||||
float sr = sinf(roll);
|
||||
float cr = cosf(roll);
|
||||
R_to_earth(0,0) = cy*cp-sy*sp*sr;
|
||||
R_to_earth(0,1) = -sy*cr;
|
||||
R_to_earth(0,2) = cy*sp+sy*cp*sr;
|
||||
R_to_earth(1,0) = sy*cp+cy*sp*sr;
|
||||
R_to_earth(1,1) = cy*cr;
|
||||
R_to_earth(1,2) = sy*sp-cy*cp*sr;
|
||||
R_to_earth(2,0) = -sp*cr;
|
||||
R_to_earth(2,1) = sr;
|
||||
R_to_earth(2,2) = cp*cr;
|
||||
// with yaw angle set to to zero
|
||||
|
||||
const Dcmf R_to_earth = taitBryan312ToRotMat(rotVec312);
|
||||
// rotate the magnetometer measurements into earth frame using a zero yaw angle
|
||||
if (_control_status.flags.mag_3D) {
|
||||
// don't apply bias corrections if we are learning them
|
||||
|
||||
Reference in New Issue
Block a user