EKF: Save mag field covariance data before reset

This commit is contained in:
Paul Riseborough
2019-01-31 09:53:57 -05:00
committed by Daniel Agar
parent 82ce7a83a5
commit d52f53635b
3 changed files with 77 additions and 38 deletions
+40 -12
View File
@@ -239,12 +239,17 @@ void Ekf::controlExternalVisionFusion()
// flag the yaw as aligned // flag the yaw as aligned
_control_status.flags.yaw_align = true; _control_status.flags.yaw_align = true;
// turn on fusion of external vision yaw measurements and disable all magnetoemter fusion // turn on fusion of external vision yaw measurements and disable all magnetometer fusion
_control_status.flags.ev_yaw = true; _control_status.flags.ev_yaw = true;
_control_status.flags.mag_hdg = false; _control_status.flags.mag_hdg = false;
_control_status.flags.mag_3D = false;
_control_status.flags.mag_dec = false; _control_status.flags.mag_dec = false;
// save covariance data for re-use if currently doing 3-axis fusion
if (_control_status.flags.mag_3D) {
save_mag_cov_data();
_control_status.flags.mag_3D = false;
}
ECL_INFO("EKF commencing external vision yaw fusion"); ECL_INFO("EKF commencing external vision yaw fusion");
} }
} }
@@ -530,9 +535,14 @@ void Ekf::controlGpsFusion()
_control_status.flags.gps_yaw = true; _control_status.flags.gps_yaw = true;
_control_status.flags.ev_yaw = false; _control_status.flags.ev_yaw = false;
_control_status.flags.mag_hdg = false; _control_status.flags.mag_hdg = false;
_control_status.flags.mag_3D = false;
_control_status.flags.mag_dec = false; _control_status.flags.mag_dec = false;
// save covariance data for re-use if currently doing 3-axis fusion
if (_control_status.flags.mag_3D) {
save_mag_cov_data();
_control_status.flags.mag_3D = false;
}
ECL_INFO("EKF commencing GPS yaw fusion"); ECL_INFO("EKF commencing GPS yaw fusion");
} }
} }
@@ -1346,11 +1356,17 @@ void Ekf::controlDragFusion()
void Ekf::controlMagFusion() void Ekf::controlMagFusion()
{ {
if (_params.mag_fusion_type >= MAG_FUSE_TYPE_NONE) { if (_params.mag_fusion_type >= MAG_FUSE_TYPE_NONE) {
// do not use the magnetomer and deactivate magnetic field states // do not use the magnetomer and deactivate magnetic field states
// save covariance data for re-use if currently doing 3-axis fusion
if (_control_status.flags.mag_3D) {
save_mag_cov_data();
_control_status.flags.mag_3D = false;
}
zeroRows(P, 16, 21); zeroRows(P, 16, 21);
zeroCols(P, 16, 21); zeroCols(P, 16, 21);
_control_status.flags.mag_hdg = false; _control_status.flags.mag_hdg = false;
_control_status.flags.mag_3D = false;
return; return;
} }
@@ -1467,7 +1483,6 @@ void Ekf::controlMagFusion()
for (uint8_t index = 0; index <= 3; index ++) { for (uint8_t index = 0; index <= 3; index ++) {
P[index + 18][index + 18] = _saved_mag_bf_variance[index]; P[index + 18][index + 18] = _saved_mag_bf_variance[index];
} }
// re-instate the NE axis covariance sub-matrix // re-instate the NE axis covariance sub-matrix
for (uint8_t row = 0; row <= 1; row ++) { for (uint8_t row = 0; row <= 1; row ++) {
for (uint8_t col = 0; col <= 1; col ++) { for (uint8_t col = 0; col <= 1; col ++) {
@@ -1482,7 +1497,7 @@ void Ekf::controlMagFusion()
_control_status.flags.mag_hdg = !_control_status.flags.mag_3D; _control_status.flags.mag_hdg = !_control_status.flags.mag_3D;
} else { } else {
// save magnetic field state covariance data for next time // save covariance data for re-use if currently doing 3-axis fusion
if (_control_status.flags.mag_3D) { if (_control_status.flags.mag_3D) {
save_mag_cov_data(); save_mag_cov_data();
_control_status.flags.mag_3D = false; _control_status.flags.mag_3D = false;
@@ -1515,17 +1530,24 @@ void Ekf::controlMagFusion()
P[index + 16][index + 16] = sq(_params.mag_noise); P[index + 16][index + 16] = sq(_params.mag_noise);
} }
// Fuse the declination angle to prevent rapid rotation of earth field vector estimates if (_control_status.flags.mag_3D) {
fuseDeclination(0.02f); // Fuse the declination angle to prevent rapid rotation of earth field vector estimates
fuseDeclination(0.02f);
// save covariance data for re-use when auto-switching between heading and 3-axis fusion // save covariance data for re-use when auto-switching between heading and 3-axis fusion
save_mag_cov_data(); save_mag_cov_data();
}
} }
} else if (_params.mag_fusion_type == MAG_FUSE_TYPE_HEADING) { } else if (_params.mag_fusion_type == MAG_FUSE_TYPE_HEADING) {
// always use heading fusion // always use heading fusion
_control_status.flags.mag_hdg = true; _control_status.flags.mag_hdg = true;
_control_status.flags.mag_3D = false;
// save covariance data for re-use if currently doing 3-axis fusion
if (_control_status.flags.mag_3D) {
save_mag_cov_data();
_control_status.flags.mag_3D = false;
}
} else if (_params.mag_fusion_type == MAG_FUSE_TYPE_3D) { } else if (_params.mag_fusion_type == MAG_FUSE_TYPE_3D) {
// if transitioning into 3-axis fusion mode, we need to initialise the yaw angle and field states // if transitioning into 3-axis fusion mode, we need to initialise the yaw angle and field states
@@ -1541,7 +1563,13 @@ void Ekf::controlMagFusion()
} else { } else {
// do no magnetometer fusion at all // do no magnetometer fusion at all
_control_status.flags.mag_hdg = false; _control_status.flags.mag_hdg = false;
_control_status.flags.mag_3D = false;
// save covariance data for re-use if currently doing 3-axis fusion
if (_control_status.flags.mag_3D) {
save_mag_cov_data();
_control_status.flags.mag_3D = false;
}
} }
// if we are using 3-axis magnetometer fusion, but without external aiding, then the declination must be fused as an observation to prevent long term heading drift // if we are using 3-axis magnetometer fusion, but without external aiding, then the declination must be fused as an observation to prevent long term heading drift
+36 -25
View File
@@ -487,16 +487,18 @@ bool Ekf::realignYawGPS()
zeroRows(P, 16, 21); zeroRows(P, 16, 21);
zeroCols(P, 16, 21); zeroCols(P, 16, 21);
for (uint8_t index = 16; index <= 21; index ++) { if (_control_status.flags.mag_3D) {
P[index][index] = sq(_params.mag_noise); for (uint8_t index = 16; index <= 21; index ++) {
P[index][index] = sq(_params.mag_noise);
}
// Fuse the declination angle to prevent rapid rotation of earth field vector estimates
fuseDeclination(0.02f);
// save covariance data for re-use when auto-switching between heading and 3-axis fusion
save_mag_cov_data();
} }
// Fuse the declination angle to prevent rapid rotation of earth field vector estimates
fuseDeclination(0.02f);
// save covariance data for re-use when auto-switching between heading and 3-axis fusion
save_mag_cov_data();
// record the start time for the magnetic field alignment // record the start time for the magnetic field alignment
_flt_mag_align_start_time = _imu_sample_delayed.time_us; _flt_mag_align_start_time = _imu_sample_delayed.time_us;
@@ -528,16 +530,18 @@ bool Ekf::realignYawGPS()
zeroRows(P, 16, 21); zeroRows(P, 16, 21);
zeroCols(P, 16, 21); zeroCols(P, 16, 21);
for (uint8_t index = 16; index <= 21; index ++) { if (_control_status.flags.mag_3D) {
P[index][index] = sq(_params.mag_noise); for (uint8_t index = 16; index <= 21; index ++) {
P[index][index] = sq(_params.mag_noise);
}
// Fuse the declination angle to prevent rapid rotation of earth field vector estimates
fuseDeclination(0.02f);
// save covariance data for re-use when auto-switching between heading and 3-axis fusion
save_mag_cov_data();
} }
// Fuse the declination angle to prevent rapid rotation of earth field vector estimates
fuseDeclination(0.02f);
// save covariance data for re-use when auto-switching between heading and 3-axis fusion
save_mag_cov_data();
// record the start time for the magnetic field alignment // record the start time for the magnetic field alignment
_flt_mag_align_start_time = _imu_sample_delayed.time_us; _flt_mag_align_start_time = _imu_sample_delayed.time_us;
@@ -561,10 +565,15 @@ bool Ekf::resetMagHeading(Vector3f &mag_init)
if (_params.mag_fusion_type >= MAG_FUSE_TYPE_NONE) { if (_params.mag_fusion_type >= MAG_FUSE_TYPE_NONE) {
// do not use the magnetomer and deactivate magnetic field states // do not use the magnetomer and deactivate magnetic field states
// save covariance data for re-use if currently doing 3-axis fusion
if (_control_status.flags.mag_3D) {
save_mag_cov_data();
_control_status.flags.mag_3D = false;
}
zeroRows(P, 16, 21); zeroRows(P, 16, 21);
zeroCols(P, 16, 21); zeroCols(P, 16, 21);
_control_status.flags.mag_hdg = false; _control_status.flags.mag_hdg = false;
_control_status.flags.mag_3D = false;
return false; return false;
} }
@@ -693,16 +702,18 @@ bool Ekf::resetMagHeading(Vector3f &mag_init)
zeroRows(P, 16, 21); zeroRows(P, 16, 21);
zeroCols(P, 16, 21); zeroCols(P, 16, 21);
for (uint8_t index = 16; index <= 21; index ++) { if (_control_status.flags.mag_3D) {
P[index][index] = sq(_params.mag_noise); for (uint8_t index = 16; index <= 21; index ++) {
P[index][index] = sq(_params.mag_noise);
}
// Fuse the declination angle to prevent rapid rotation of earth field vector estimates
fuseDeclination(0.02f);
// save covariance data for re-use when auto-switching between heading and 3-axis fusion
save_mag_cov_data();
} }
// Fuse the declination angle to prevent rapid rotation of earth field vector estimates
fuseDeclination(0.02f);
// save covariance data for re-use when auto-switching between heading and 3-axis fusion
save_mag_cov_data();
// record the time for the magnetic field alignment event // record the time for the magnetic field alignment event
_flt_mag_align_start_time = _imu_sample_delayed.time_us; _flt_mag_align_start_time = _imu_sample_delayed.time_us;
+1 -1
View File
@@ -916,7 +916,7 @@ void Ekf::fuseDeclination(float decl_sigma)
} }
} }
// correct the covariance marix for gross errors // correct the covariance matrix for gross errors
fixCovarianceErrors(); fixCovarianceErrors();
// apply the state corrections // apply the state corrections