mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-11-06 05:11:36 +08:00
EKF2: only fuse zero innovation if yaw var is large
This commit is contained in:
@@ -360,7 +360,6 @@ struct parameters {
|
|||||||
int32_t mag_fusion_type{0}; ///< integer used to specify the type of magnetometer fusion used
|
int32_t mag_fusion_type{0}; ///< integer used to specify the type of magnetometer fusion used
|
||||||
float mag_acc_gate{0.5f}; ///< when in auto select mode, heading fusion will be used when manoeuvre accel is lower than this (m/sec**2)
|
float mag_acc_gate{0.5f}; ///< when in auto select mode, heading fusion will be used when manoeuvre accel is lower than this (m/sec**2)
|
||||||
float mag_yaw_rate_gate{0.25f}; ///< yaw rate threshold used by mode select logic (rad/sec)
|
float mag_yaw_rate_gate{0.25f}; ///< yaw rate threshold used by mode select logic (rad/sec)
|
||||||
const float quat_max_variance{0.0001f}; ///< zero innovation yaw measurements will not be fused when the sum of quaternion variance is less than this
|
|
||||||
|
|
||||||
// GNSS heading fusion
|
// GNSS heading fusion
|
||||||
float gps_heading_noise{0.1f}; ///< measurement noise standard deviation used for GNSS heading fusion (rad)
|
float gps_heading_noise{0.1f}; ///< measurement noise standard deviation used for GNSS heading fusion (rad)
|
||||||
|
|||||||
@@ -666,9 +666,9 @@ private:
|
|||||||
bool fuseMag(const Vector3f &mag, estimator_aid_source3d_s &aid_src_mag, bool update_all_states = true);
|
bool fuseMag(const Vector3f &mag, estimator_aid_source3d_s &aid_src_mag, bool update_all_states = true);
|
||||||
|
|
||||||
// update quaternion states and covariances using an innovation, observation variance and Jacobian vector
|
// update quaternion states and covariances using an innovation, observation variance and Jacobian vector
|
||||||
// innovation : prediction - measurement
|
bool fuseYaw(float innovation, float variance, estimator_aid_source1d_s &aid_src_status);
|
||||||
// variance : observaton variance
|
bool fuseYaw(float innovation, float variance, estimator_aid_source1d_s &aid_src_status, const Vector24f &H_YAW);
|
||||||
bool fuseYaw(const float innovation, const float variance, estimator_aid_source1d_s &aid_src_status);
|
void computeYawInnovVarAndH(float variance, float &innovation_variance, Vector24f &H_YAW) const;
|
||||||
|
|
||||||
// fuse the yaw angle obtained from a dual antenna GPS unit
|
// fuse the yaw angle obtained from a dual antenna GPS unit
|
||||||
void fuseGpsYaw();
|
void fuseGpsYaw();
|
||||||
|
|||||||
@@ -226,16 +226,15 @@ bool Ekf::fuseMag(const Vector3f &mag, estimator_aid_source3d_s &aid_src_mag, bo
|
|||||||
// update quaternion states and covariances using the yaw innovation and yaw observation variance
|
// update quaternion states and covariances using the yaw innovation and yaw observation variance
|
||||||
bool Ekf::fuseYaw(const float innovation, const float variance, estimator_aid_source1d_s& aid_src_status)
|
bool Ekf::fuseYaw(const float innovation, const float variance, estimator_aid_source1d_s& aid_src_status)
|
||||||
{
|
{
|
||||||
aid_src_status.innovation = innovation;
|
|
||||||
|
|
||||||
Vector24f H_YAW;
|
Vector24f H_YAW;
|
||||||
|
computeYawInnovVarAndH(variance, aid_src_status.innovation_variance, H_YAW);
|
||||||
|
|
||||||
if (shouldUse321RotationSequence(_R_to_earth)) {
|
return fuseYaw(innovation, variance, aid_src_status, H_YAW);
|
||||||
sym::ComputeYaw321InnovVarAndH(getStateAtFusionHorizonAsVector(), P, variance, FLT_EPSILON, &aid_src_status.innovation_variance, &H_YAW);
|
}
|
||||||
|
|
||||||
} else {
|
bool Ekf::fuseYaw(const float innovation, const float variance, estimator_aid_source1d_s& aid_src_status, const Vector24f &H_YAW)
|
||||||
sym::ComputeYaw312InnovVarAndH(getStateAtFusionHorizonAsVector(), P, variance, FLT_EPSILON, &aid_src_status.innovation_variance, &H_YAW);
|
{
|
||||||
}
|
aid_src_status.innovation = innovation;
|
||||||
|
|
||||||
float heading_innov_var_inv = 0.f;
|
float heading_innov_var_inv = 0.f;
|
||||||
|
|
||||||
@@ -330,6 +329,16 @@ bool Ekf::fuseYaw(const float innovation, const float variance, estimator_aid_so
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Ekf::computeYawInnovVarAndH(float variance, float &innovation_variance, Vector24f &H_YAW) const
|
||||||
|
{
|
||||||
|
if (shouldUse321RotationSequence(_R_to_earth)) {
|
||||||
|
sym::ComputeYaw321InnovVarAndH(getStateAtFusionHorizonAsVector(), P, variance, FLT_EPSILON, &innovation_variance, &H_YAW);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
sym::ComputeYaw312InnovVarAndH(getStateAtFusionHorizonAsVector(), P, variance, FLT_EPSILON, &innovation_variance, &H_YAW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Ekf::fuseDeclination(float decl_sigma)
|
bool Ekf::fuseDeclination(float decl_sigma)
|
||||||
{
|
{
|
||||||
// observation variance (rad**2)
|
// observation variance (rad**2)
|
||||||
|
|||||||
@@ -74,12 +74,19 @@ void Ekf::controlZeroInnovationHeadingUpdate()
|
|||||||
} else {
|
} else {
|
||||||
// vehicle moving and tilt alignment completed
|
// vehicle moving and tilt alignment completed
|
||||||
|
|
||||||
// fuse zero innovation at a limited rate (every 200 milliseconds)
|
// fuse zero innovation at a limited rate if the yaw variance is too large
|
||||||
if (!yaw_aiding && isTimedOut(_time_last_heading_fuse, (uint64_t)200'000)) {
|
if (!yaw_aiding && isTimedOut(_time_last_heading_fuse, (uint64_t)200'000)) {
|
||||||
float innovation = 0.f;
|
float obs_var = 0.25f;
|
||||||
float obs_var = 0.01f;
|
estimator_aid_source1d_s aid_src_status;
|
||||||
estimator_aid_source1d_s unused;
|
Vector24f H_YAW;
|
||||||
fuseYaw(innovation, obs_var, unused);
|
|
||||||
|
computeYawInnovVarAndH(obs_var, aid_src_status.innovation_variance, H_YAW);
|
||||||
|
|
||||||
|
if ((aid_src_status.innovation_variance - obs_var) > sq(_params.mag_heading_noise)) {
|
||||||
|
// The yaw variance is too large, fuse fake measurement
|
||||||
|
float innovation = 0.f;
|
||||||
|
fuseYaw(innovation, obs_var, aid_src_status, H_YAW);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_last_static_yaw = NAN;
|
_last_static_yaw = NAN;
|
||||||
|
|||||||
Reference in New Issue
Block a user