mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-13 19:43:34 +08:00
EKF: Allow mag field estimates to stabilise before use
This commit is contained in:
@@ -1244,6 +1244,9 @@ void Ekf::controlMagFusion()
|
||||
_control_status.flags.update_mag_states_only = (_params.mag_fusion_type == MAG_FUSE_TYPE_AUTOFW)
|
||||
&& _control_status.flags.fixed_wing;
|
||||
|
||||
// For the first 10 seconds after switching to 3-axis fusion we allow the magnetic field state estimates to stabilise
|
||||
_flt_mag_align_converging = ((_imu_sample_delayed.time_us - _flt_mag_align_start_time) < (uint64_t)1e7);
|
||||
|
||||
if (!_control_status.flags.update_mag_states_only && _control_status_prev.flags.update_mag_states_only) {
|
||||
// When re-commencing use of magnetometer to correct vehicle states
|
||||
// set the field state variance to the observation variance and zero
|
||||
@@ -1293,6 +1296,12 @@ void Ekf::controlMagFusion()
|
||||
fuseDeclination();
|
||||
}
|
||||
|
||||
if (_flt_mag_align_converging) {
|
||||
_control_status.flags.mag_hdg = true;
|
||||
fuseHeading();
|
||||
_control_status.flags.mag_hdg = false;
|
||||
}
|
||||
|
||||
} else if (_control_status.flags.mag_hdg && _control_status.flags.yaw_align) {
|
||||
// fusion of an Euler yaw angle from either a 321 or 312 rotation sequence
|
||||
fuseHeading();
|
||||
|
||||
@@ -377,7 +377,9 @@ private:
|
||||
|
||||
// Variables used to control activation of post takeoff functionality
|
||||
float _last_on_ground_posD{0.0f}; ///< last vertical position when the in_air status was false (m)
|
||||
bool _flt_mag_align_complete{true}; ///< true when the in-flight mag field alignment has been completed
|
||||
bool _flt_mag_align_complete{false}; ///< true when the in-flight mag field alignment has been completed
|
||||
bool _flt_mag_align_converging{false}; ///< true when the in-flight mag field post alignment convergence is being performd
|
||||
uint64_t _flt_mag_align_start_time{0}; ///< time that inflight magnetic field alignment started (uSec)
|
||||
uint64_t _time_last_movement{0}; ///< last system time that sufficient movement to use 3-axis magnetometer fusion was detected (uSec)
|
||||
float _saved_mag_variance[6] {}; ///< magnetic field state variances that have been saved for use at the next initialisation (Gauss**2)
|
||||
bool _velpos_reset_request{false}; ///< true when a large yaw error has been fixed and a velocity and position state reset is required
|
||||
|
||||
@@ -437,6 +437,8 @@ bool Ekf::realignYawGPS()
|
||||
P[index][index] = sq(_params.mag_noise);
|
||||
}
|
||||
|
||||
// record the start time for the magnetic field alignment
|
||||
_flt_mag_align_start_time = _imu_sample_delayed.time_us;
|
||||
// calculate the amount that the quaternion has changed by
|
||||
_state_reset_status.quat_change = quat_before_reset.inversed() * _state.quat_nominal;
|
||||
|
||||
@@ -637,6 +639,9 @@ bool Ekf::resetMagHeading(Vector3f &mag_init)
|
||||
P[index][index] = sq(_params.mag_noise);
|
||||
}
|
||||
|
||||
// record the start time for the magnetic field alignment
|
||||
_flt_mag_align_start_time = _imu_sample_delayed.time_us;
|
||||
|
||||
// calculate the amount that the quaternion has changed by
|
||||
_state_reset_status.quat_change = quat_before_reset.inversed() * _state.quat_nominal;
|
||||
|
||||
|
||||
+5
-3
@@ -163,6 +163,8 @@ void Ekf::fuseMag()
|
||||
return;
|
||||
}
|
||||
|
||||
bool update_all_states = !_control_status.flags.update_mag_states_only && !_flt_mag_align_converging;
|
||||
|
||||
// update the states and covariance using sequential fusion of the magnetometer components
|
||||
for (uint8_t index = 0; index <= 2; index++) {
|
||||
|
||||
@@ -187,7 +189,7 @@ void Ekf::fuseMag()
|
||||
SK_MX[3] = 2.0f*q0*q2 - 2.0f*q1*q3;
|
||||
SK_MX[4] = 2.0f*q0*q3 + 2.0f*q1*q2;
|
||||
|
||||
if (!_control_status.flags.update_mag_states_only) {
|
||||
if (update_all_states) {
|
||||
Kfusion[0] = SK_MX[0]*(P[0][19] + P[0][1]*SH_MAG[0] - P[0][2]*SH_MAG[1] + P[0][3]*SH_MAG[2] + P[0][0]*SK_MX[2] - P[0][16]*SK_MX[1] + P[0][17]*SK_MX[4] - P[0][18]*SK_MX[3]);
|
||||
Kfusion[1] = SK_MX[0]*(P[1][19] + P[1][1]*SH_MAG[0] - P[1][2]*SH_MAG[1] + P[1][3]*SH_MAG[2] + P[1][0]*SK_MX[2] - P[1][16]*SK_MX[1] + P[1][17]*SK_MX[4] - P[1][18]*SK_MX[3]);
|
||||
Kfusion[2] = SK_MX[0]*(P[2][19] + P[2][1]*SH_MAG[0] - P[2][2]*SH_MAG[1] + P[2][3]*SH_MAG[2] + P[2][0]*SK_MX[2] - P[2][16]*SK_MX[1] + P[2][17]*SK_MX[4] - P[2][18]*SK_MX[3]);
|
||||
@@ -241,7 +243,7 @@ void Ekf::fuseMag()
|
||||
SK_MY[3] = 2.0f*q0*q3 - 2.0f*q1*q2;
|
||||
SK_MY[4] = 2.0f*q0*q1 + 2.0f*q2*q3;
|
||||
|
||||
if (!_control_status.flags.update_mag_states_only) {
|
||||
if (update_all_states) {
|
||||
Kfusion[0] = SK_MY[0]*(P[0][20] + P[0][0]*SH_MAG[2] + P[0][1]*SH_MAG[1] + P[0][2]*SH_MAG[0] - P[0][3]*SK_MY[2] - P[0][17]*SK_MY[1] - P[0][16]*SK_MY[3] + P[0][18]*SK_MY[4]);
|
||||
Kfusion[1] = SK_MY[0]*(P[1][20] + P[1][0]*SH_MAG[2] + P[1][1]*SH_MAG[1] + P[1][2]*SH_MAG[0] - P[1][3]*SK_MY[2] - P[1][17]*SK_MY[1] - P[1][16]*SK_MY[3] + P[1][18]*SK_MY[4]);
|
||||
Kfusion[2] = SK_MY[0]*(P[2][20] + P[2][0]*SH_MAG[2] + P[2][1]*SH_MAG[1] + P[2][2]*SH_MAG[0] - P[2][3]*SK_MY[2] - P[2][17]*SK_MY[1] - P[2][16]*SK_MY[3] + P[2][18]*SK_MY[4]);
|
||||
@@ -295,7 +297,7 @@ void Ekf::fuseMag()
|
||||
SK_MZ[3] = 2.0f*q0*q1 - 2.0f*q2*q3;
|
||||
SK_MZ[4] = 2.0f*q0*q2 + 2.0f*q1*q3;
|
||||
|
||||
if (!_control_status.flags.update_mag_states_only) {
|
||||
if (update_all_states) {
|
||||
Kfusion[0] = SK_MZ[0]*(P[0][21] + P[0][0]*SH_MAG[1] - P[0][1]*SH_MAG[2] + P[0][3]*SH_MAG[0] + P[0][2]*SK_MZ[2] + P[0][18]*SK_MZ[1] + P[0][16]*SK_MZ[4] - P[0][17]*SK_MZ[3]);
|
||||
Kfusion[1] = SK_MZ[0]*(P[1][21] + P[1][0]*SH_MAG[1] - P[1][1]*SH_MAG[2] + P[1][3]*SH_MAG[0] + P[1][2]*SK_MZ[2] + P[1][18]*SK_MZ[1] + P[1][16]*SK_MZ[4] - P[1][17]*SK_MZ[3]);
|
||||
Kfusion[2] = SK_MZ[0]*(P[2][21] + P[2][0]*SH_MAG[1] - P[2][1]*SH_MAG[2] + P[2][3]*SH_MAG[0] + P[2][2]*SK_MZ[2] + P[2][18]*SK_MZ[1] + P[2][16]*SK_MZ[4] - P[2][17]*SK_MZ[3]);
|
||||
|
||||
Reference in New Issue
Block a user