mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-05-17 01:07:35 +08:00
Make mag_innov/-var a Matrix::Vector3f
This commit is contained in:
committed by
Mathieu Bresciani
parent
0ea7cd8360
commit
b8f937666a
@@ -412,8 +412,8 @@ private:
|
|||||||
float _heading_innov{0.0f}; ///< heading measurement innovation (rad)
|
float _heading_innov{0.0f}; ///< heading measurement innovation (rad)
|
||||||
float _heading_innov_var{0.0f}; ///< heading measurement innovation variance (rad**2)
|
float _heading_innov_var{0.0f}; ///< heading measurement innovation variance (rad**2)
|
||||||
|
|
||||||
float _mag_innov[3] {}; ///< earth magnetic field innovations (Gauss)
|
Vector3f _mag_innov; ///< earth magnetic field innovations (Gauss)
|
||||||
float _mag_innov_var[3] {}; ///< earth magnetic field innovation variance (Gauss**2)
|
Vector3f _mag_innov_var; ///< earth magnetic field innovation variance (Gauss**2)
|
||||||
|
|
||||||
float _drag_innov[2] {}; ///< multirotor drag measurement innovation (m/sec**2)
|
float _drag_innov[2] {}; ///< multirotor drag measurement innovation (m/sec**2)
|
||||||
float _drag_innov_var[2] {}; ///< multirotor drag measurement innovation variance ((m/sec**2)**2)
|
float _drag_innov_var[2] {}; ///< multirotor drag measurement innovation variance ((m/sec**2)**2)
|
||||||
|
|||||||
+5
-5
@@ -776,17 +776,17 @@ void Ekf::getHeadingInnovRatio(float &heading_innov_ratio) const
|
|||||||
|
|
||||||
void Ekf::getMagInnov(float mag_innov[3]) const
|
void Ekf::getMagInnov(float mag_innov[3]) const
|
||||||
{
|
{
|
||||||
memcpy(mag_innov, _mag_innov, sizeof(_mag_innov));
|
_mag_innov.copyTo(mag_innov);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ekf::getMagInnovVar(float mag_innov_var[3]) const
|
void Ekf::getMagInnovVar(float mag_innov_var[3]) const
|
||||||
{
|
{
|
||||||
memcpy(mag_innov_var, _mag_innov_var, sizeof(_mag_innov_var));
|
_mag_innov_var.copyTo(mag_innov_var);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ekf::getMagInnovRatio(float &mag_innov_ratio) const
|
void Ekf::getMagInnovRatio(float &mag_innov_ratio) const
|
||||||
{
|
{
|
||||||
mag_innov_ratio = math::max(math::max(_mag_test_ratio[0], _mag_test_ratio[1]), _mag_test_ratio[2]);
|
mag_innov_ratio = _mag_test_ratio.max();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ekf::getDragInnov(float drag_innov[2]) const
|
void Ekf::getDragInnov(float drag_innov[2]) const
|
||||||
@@ -1105,7 +1105,7 @@ void Ekf::get_innovation_test_status(uint16_t &status, float &mag, float &vel, f
|
|||||||
// return the integer bitmask containing the consistency check pass/fail status
|
// return the integer bitmask containing the consistency check pass/fail status
|
||||||
status = _innov_check_fail_status.value;
|
status = _innov_check_fail_status.value;
|
||||||
// return the largest magnetometer innovation test ratio
|
// return the largest magnetometer innovation test ratio
|
||||||
mag = sqrtf(math::max(_yaw_test_ratio, math::max(math::max(_mag_test_ratio[0], _mag_test_ratio[1]), _mag_test_ratio[2])));
|
mag = sqrtf(math::max(_yaw_test_ratio,_mag_test_ratio.max()));
|
||||||
// return the largest velocity innovation test ratio
|
// return the largest velocity innovation test ratio
|
||||||
vel = math::max(sqrtf(math::max(_gps_vel_test_ratio(0), _gps_vel_test_ratio(1))),
|
vel = math::max(sqrtf(math::max(_gps_vel_test_ratio(0), _gps_vel_test_ratio(1))),
|
||||||
sqrtf(math::max(_ev_vel_test_ratio(0), _ev_vel_test_ratio(1))));
|
sqrtf(math::max(_ev_vel_test_ratio(0), _ev_vel_test_ratio(1))));
|
||||||
@@ -1139,7 +1139,7 @@ void Ekf::get_ekf_soln_status(uint16_t *status)
|
|||||||
soln_status.flags.pred_pos_horiz_abs = soln_status.flags.pos_horiz_abs;
|
soln_status.flags.pred_pos_horiz_abs = soln_status.flags.pos_horiz_abs;
|
||||||
bool gps_vel_innov_bad = (_gps_vel_test_ratio(0) > 1.0f) || (_gps_vel_test_ratio(1) > 1.0f);
|
bool gps_vel_innov_bad = (_gps_vel_test_ratio(0) > 1.0f) || (_gps_vel_test_ratio(1) > 1.0f);
|
||||||
bool gps_pos_innov_bad = (_gps_pos_test_ratio(0) > 1.0f);
|
bool gps_pos_innov_bad = (_gps_pos_test_ratio(0) > 1.0f);
|
||||||
bool mag_innov_good = (_mag_test_ratio[0] < 1.0f) && (_mag_test_ratio[1] < 1.0f) && (_mag_test_ratio[2] < 1.0f) && (_yaw_test_ratio < 1.0f);
|
bool mag_innov_good = (_mag_test_ratio.max() < 1.0f) && (_yaw_test_ratio < 1.0f);
|
||||||
soln_status.flags.gps_glitch = (gps_vel_innov_bad || gps_pos_innov_bad) && mag_innov_good;
|
soln_status.flags.gps_glitch = (gps_vel_innov_bad || gps_pos_innov_bad) && mag_innov_good;
|
||||||
soln_status.flags.accel_error = _bad_vert_accel_detected;
|
soln_status.flags.accel_error = _bad_vert_accel_detected;
|
||||||
*status = soln_status.value;
|
*status = soln_status.value;
|
||||||
|
|||||||
@@ -479,7 +479,7 @@ protected:
|
|||||||
|
|
||||||
// innovation consistency check monitoring ratios
|
// innovation consistency check monitoring ratios
|
||||||
float _yaw_test_ratio{}; // yaw innovation consistency check ratio
|
float _yaw_test_ratio{}; // yaw innovation consistency check ratio
|
||||||
float _mag_test_ratio[3] {}; // magnetometer XYZ innovation consistency check ratios
|
Vector3f _mag_test_ratio; // magnetometer XYZ innovation consistency check ratios
|
||||||
Vector2f _gps_vel_test_ratio; // GPS velocity innovation consistency check ratios
|
Vector2f _gps_vel_test_ratio; // GPS velocity innovation consistency check ratios
|
||||||
Vector2f _gps_pos_test_ratio; // GPS position innovation consistency check ratios
|
Vector2f _gps_pos_test_ratio; // GPS position innovation consistency check ratios
|
||||||
Vector2f _ev_vel_test_ratio; // EV velocity innovation consistency check ratios
|
Vector2f _ev_vel_test_ratio; // EV velocity innovation consistency check ratios
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ void Ekf::fuseGpsAntYaw()
|
|||||||
_yaw_test_ratio = sq(_heading_innov) / (sq(innov_gate) * _heading_innov_var);
|
_yaw_test_ratio = sq(_heading_innov) / (sq(innov_gate) * _heading_innov_var);
|
||||||
|
|
||||||
// we are no longer using 3-axis fusion so set the reported test levels to zero
|
// we are no longer using 3-axis fusion so set the reported test levels to zero
|
||||||
memset(_mag_test_ratio, 0, sizeof(_mag_test_ratio));
|
_mag_test_ratio.setZero();
|
||||||
|
|
||||||
if (_yaw_test_ratio > 1.0f) {
|
if (_yaw_test_ratio > 1.0f) {
|
||||||
_innov_check_fail_status.flags.reject_yaw = true;
|
_innov_check_fail_status.flags.reject_yaw = true;
|
||||||
|
|||||||
+17
-19
@@ -77,25 +77,23 @@ void Ekf::fuseMag()
|
|||||||
const Vector3f mag_I_rot = R_to_body * _state.mag_I;
|
const Vector3f mag_I_rot = R_to_body * _state.mag_I;
|
||||||
|
|
||||||
// compute magnetometer innovations
|
// compute magnetometer innovations
|
||||||
_mag_innov[0] = (mag_I_rot(0) + _state.mag_B(0)) - _mag_sample_delayed.mag(0);
|
_mag_innov = mag_I_rot + _state.mag_B - _mag_sample_delayed.mag;
|
||||||
_mag_innov[1] = (mag_I_rot(1) + _state.mag_B(1)) - _mag_sample_delayed.mag(1);
|
|
||||||
|
|
||||||
// do not use the synthesized measurement for the magnetomter Z component for 3D fusion
|
// do not use the synthesized measurement for the magnetomter Z component for 3D fusion
|
||||||
if (_control_status.flags.synthetic_mag_z) {
|
if (_control_status.flags.synthetic_mag_z) {
|
||||||
_mag_innov[2] = 0.0f;
|
_mag_innov(2) = 0.0f;
|
||||||
} else {
|
|
||||||
_mag_innov[2] = (mag_I_rot(2) + _state.mag_B(2)) - _mag_sample_delayed.mag(2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Observation jacobian and Kalman gain vectors
|
// Observation jacobian and Kalman gain vectors
|
||||||
float H_MAG[24];
|
float H_MAG[24];
|
||||||
float Kfusion[24];
|
float Kfusion[24];
|
||||||
|
|
||||||
// X axis innovation variance
|
// X axis innovation variance
|
||||||
_mag_innov_var[0] = (P(19,19) + R_MAG + P(1,19)*SH_MAG[0] - P(2,19)*SH_MAG[1] + P(3,19)*SH_MAG[2] - P(16,19)*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) + (2.0f*q0*q3 + 2.0f*q1*q2)*(P(19,17) + P(1,17)*SH_MAG[0] - P(2,17)*SH_MAG[1] + P(3,17)*SH_MAG[2] - P(16,17)*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) + P(17,17)*(2.0f*q0*q3 + 2.0f*q1*q2) - P(18,17)*(2.0f*q0*q2 - 2.0f*q1*q3) + P(0,17)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) - (2.0f*q0*q2 - 2.0f*q1*q3)*(P(19,18) + P(1,18)*SH_MAG[0] - P(2,18)*SH_MAG[1] + P(3,18)*SH_MAG[2] - P(16,18)*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) + P(17,18)*(2.0f*q0*q3 + 2.0f*q1*q2) - P(18,18)*(2.0f*q0*q2 - 2.0f*q1*q3) + P(0,18)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + (SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)*(P(19,0) + P(1,0)*SH_MAG[0] - P(2,0)*SH_MAG[1] + P(3,0)*SH_MAG[2] - P(16,0)*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) + P(17,0)*(2.0f*q0*q3 + 2.0f*q1*q2) - P(18,0)*(2.0f*q0*q2 - 2.0f*q1*q3) + P(0,0)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + P(17,19)*(2.0f*q0*q3 + 2.0f*q1*q2) - P(18,19)*(2.0f*q0*q2 - 2.0f*q1*q3) + SH_MAG[0]*(P(19,1) + P(1,1)*SH_MAG[0] - P(2,1)*SH_MAG[1] + P(3,1)*SH_MAG[2] - P(16,1)*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) + P(17,1)*(2.0f*q0*q3 + 2.0f*q1*q2) - P(18,1)*(2.0f*q0*q2 - 2.0f*q1*q3) + P(0,1)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) - SH_MAG[1]*(P(19,2) + P(1,2)*SH_MAG[0] - P(2,2)*SH_MAG[1] + P(3,2)*SH_MAG[2] - P(16,2)*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) + P(17,2)*(2.0f*q0*q3 + 2.0f*q1*q2) - P(18,2)*(2.0f*q0*q2 - 2.0f*q1*q3) + P(0,2)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + SH_MAG[2]*(P(19,3) + P(1,3)*SH_MAG[0] - P(2,3)*SH_MAG[1] + P(3,3)*SH_MAG[2] - P(16,3)*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) + P(17,3)*(2.0f*q0*q3 + 2.0f*q1*q2) - P(18,3)*(2.0f*q0*q2 - 2.0f*q1*q3) + P(0,3)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) - (SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6])*(P(19,16) + P(1,16)*SH_MAG[0] - P(2,16)*SH_MAG[1] + P(3,16)*SH_MAG[2] - P(16,16)*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) + P(17,16)*(2.0f*q0*q3 + 2.0f*q1*q2) - P(18,16)*(2.0f*q0*q2 - 2.0f*q1*q3) + P(0,16)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + P(0,19)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2));
|
_mag_innov_var(0) = (P(19,19) + R_MAG + P(1,19)*SH_MAG[0] - P(2,19)*SH_MAG[1] + P(3,19)*SH_MAG[2] - P(16,19)*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) + (2.0f*q0*q3 + 2.0f*q1*q2)*(P(19,17) + P(1,17)*SH_MAG[0] - P(2,17)*SH_MAG[1] + P(3,17)*SH_MAG[2] - P(16,17)*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) + P(17,17)*(2.0f*q0*q3 + 2.0f*q1*q2) - P(18,17)*(2.0f*q0*q2 - 2.0f*q1*q3) + P(0,17)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) - (2.0f*q0*q2 - 2.0f*q1*q3)*(P(19,18) + P(1,18)*SH_MAG[0] - P(2,18)*SH_MAG[1] + P(3,18)*SH_MAG[2] - P(16,18)*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) + P(17,18)*(2.0f*q0*q3 + 2.0f*q1*q2) - P(18,18)*(2.0f*q0*q2 - 2.0f*q1*q3) + P(0,18)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + (SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)*(P(19,0) + P(1,0)*SH_MAG[0] - P(2,0)*SH_MAG[1] + P(3,0)*SH_MAG[2] - P(16,0)*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) + P(17,0)*(2.0f*q0*q3 + 2.0f*q1*q2) - P(18,0)*(2.0f*q0*q2 - 2.0f*q1*q3) + P(0,0)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + P(17,19)*(2.0f*q0*q3 + 2.0f*q1*q2) - P(18,19)*(2.0f*q0*q2 - 2.0f*q1*q3) + SH_MAG[0]*(P(19,1) + P(1,1)*SH_MAG[0] - P(2,1)*SH_MAG[1] + P(3,1)*SH_MAG[2] - P(16,1)*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) + P(17,1)*(2.0f*q0*q3 + 2.0f*q1*q2) - P(18,1)*(2.0f*q0*q2 - 2.0f*q1*q3) + P(0,1)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) - SH_MAG[1]*(P(19,2) + P(1,2)*SH_MAG[0] - P(2,2)*SH_MAG[1] + P(3,2)*SH_MAG[2] - P(16,2)*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) + P(17,2)*(2.0f*q0*q3 + 2.0f*q1*q2) - P(18,2)*(2.0f*q0*q2 - 2.0f*q1*q3) + P(0,2)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + SH_MAG[2]*(P(19,3) + P(1,3)*SH_MAG[0] - P(2,3)*SH_MAG[1] + P(3,3)*SH_MAG[2] - P(16,3)*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) + P(17,3)*(2.0f*q0*q3 + 2.0f*q1*q2) - P(18,3)*(2.0f*q0*q2 - 2.0f*q1*q3) + P(0,3)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) - (SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6])*(P(19,16) + P(1,16)*SH_MAG[0] - P(2,16)*SH_MAG[1] + P(3,16)*SH_MAG[2] - P(16,16)*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) + P(17,16)*(2.0f*q0*q3 + 2.0f*q1*q2) - P(18,16)*(2.0f*q0*q2 - 2.0f*q1*q3) + P(0,16)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + P(0,19)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2));
|
||||||
// check for a badly conditioned covariance matrix
|
// check for a badly conditioned covariance matrix
|
||||||
const char* numerical_error_covariance_reset_string = "numerical error - covariance reset";
|
const char* numerical_error_covariance_reset_string = "numerical error - covariance reset";
|
||||||
|
|
||||||
if (_mag_innov_var[0] >= R_MAG) {
|
if (_mag_innov_var(0) >= R_MAG) {
|
||||||
// the innovation variance contribution from the state covariances is non-negative - no fault
|
// the innovation variance contribution from the state covariances is non-negative - no fault
|
||||||
_fault_status.flags.bad_mag_x = false;
|
_fault_status.flags.bad_mag_x = false;
|
||||||
|
|
||||||
@@ -111,10 +109,10 @@ void Ekf::fuseMag()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Y axis innovation variance
|
// Y axis innovation variance
|
||||||
_mag_innov_var[1] = (P(20,20) + R_MAG + P(0,20)*SH_MAG[2] + P(1,20)*SH_MAG[1] + P(2,20)*SH_MAG[0] - P(17,20)*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) - (2.0f*q0*q3 - 2.0f*q1*q2)*(P(20,16) + P(0,16)*SH_MAG[2] + P(1,16)*SH_MAG[1] + P(2,16)*SH_MAG[0] - P(17,16)*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) - P(16,16)*(2.0f*q0*q3 - 2.0f*q1*q2) + P(18,16)*(2.0f*q0*q1 + 2.0f*q2*q3) - P(3,16)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + (2.0f*q0*q1 + 2.0f*q2*q3)*(P(20,18) + P(0,18)*SH_MAG[2] + P(1,18)*SH_MAG[1] + P(2,18)*SH_MAG[0] - P(17,18)*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) - P(16,18)*(2.0f*q0*q3 - 2.0f*q1*q2) + P(18,18)*(2.0f*q0*q1 + 2.0f*q2*q3) - P(3,18)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) - (SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)*(P(20,3) + P(0,3)*SH_MAG[2] + P(1,3)*SH_MAG[1] + P(2,3)*SH_MAG[0] - P(17,3)*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) - P(16,3)*(2.0f*q0*q3 - 2.0f*q1*q2) + P(18,3)*(2.0f*q0*q1 + 2.0f*q2*q3) - P(3,3)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) - P(16,20)*(2.0f*q0*q3 - 2.0f*q1*q2) + P(18,20)*(2.0f*q0*q1 + 2.0f*q2*q3) + SH_MAG[2]*(P(20,0) + P(0,0)*SH_MAG[2] + P(1,0)*SH_MAG[1] + P(2,0)*SH_MAG[0] - P(17,0)*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) - P(16,0)*(2.0f*q0*q3 - 2.0f*q1*q2) + P(18,0)*(2.0f*q0*q1 + 2.0f*q2*q3) - P(3,0)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + SH_MAG[1]*(P(20,1) + P(0,1)*SH_MAG[2] + P(1,1)*SH_MAG[1] + P(2,1)*SH_MAG[0] - P(17,1)*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) - P(16,1)*(2.0f*q0*q3 - 2.0f*q1*q2) + P(18,1)*(2.0f*q0*q1 + 2.0f*q2*q3) - P(3,1)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + SH_MAG[0]*(P(20,2) + P(0,2)*SH_MAG[2] + P(1,2)*SH_MAG[1] + P(2,2)*SH_MAG[0] - P(17,2)*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) - P(16,2)*(2.0f*q0*q3 - 2.0f*q1*q2) + P(18,2)*(2.0f*q0*q1 + 2.0f*q2*q3) - P(3,2)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) - (SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6])*(P(20,17) + P(0,17)*SH_MAG[2] + P(1,17)*SH_MAG[1] + P(2,17)*SH_MAG[0] - P(17,17)*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) - P(16,17)*(2.0f*q0*q3 - 2.0f*q1*q2) + P(18,17)*(2.0f*q0*q1 + 2.0f*q2*q3) - P(3,17)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) - P(3,20)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2));
|
_mag_innov_var(1) = (P(20,20) + R_MAG + P(0,20)*SH_MAG[2] + P(1,20)*SH_MAG[1] + P(2,20)*SH_MAG[0] - P(17,20)*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) - (2.0f*q0*q3 - 2.0f*q1*q2)*(P(20,16) + P(0,16)*SH_MAG[2] + P(1,16)*SH_MAG[1] + P(2,16)*SH_MAG[0] - P(17,16)*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) - P(16,16)*(2.0f*q0*q3 - 2.0f*q1*q2) + P(18,16)*(2.0f*q0*q1 + 2.0f*q2*q3) - P(3,16)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + (2.0f*q0*q1 + 2.0f*q2*q3)*(P(20,18) + P(0,18)*SH_MAG[2] + P(1,18)*SH_MAG[1] + P(2,18)*SH_MAG[0] - P(17,18)*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) - P(16,18)*(2.0f*q0*q3 - 2.0f*q1*q2) + P(18,18)*(2.0f*q0*q1 + 2.0f*q2*q3) - P(3,18)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) - (SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)*(P(20,3) + P(0,3)*SH_MAG[2] + P(1,3)*SH_MAG[1] + P(2,3)*SH_MAG[0] - P(17,3)*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) - P(16,3)*(2.0f*q0*q3 - 2.0f*q1*q2) + P(18,3)*(2.0f*q0*q1 + 2.0f*q2*q3) - P(3,3)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) - P(16,20)*(2.0f*q0*q3 - 2.0f*q1*q2) + P(18,20)*(2.0f*q0*q1 + 2.0f*q2*q3) + SH_MAG[2]*(P(20,0) + P(0,0)*SH_MAG[2] + P(1,0)*SH_MAG[1] + P(2,0)*SH_MAG[0] - P(17,0)*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) - P(16,0)*(2.0f*q0*q3 - 2.0f*q1*q2) + P(18,0)*(2.0f*q0*q1 + 2.0f*q2*q3) - P(3,0)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + SH_MAG[1]*(P(20,1) + P(0,1)*SH_MAG[2] + P(1,1)*SH_MAG[1] + P(2,1)*SH_MAG[0] - P(17,1)*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) - P(16,1)*(2.0f*q0*q3 - 2.0f*q1*q2) + P(18,1)*(2.0f*q0*q1 + 2.0f*q2*q3) - P(3,1)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + SH_MAG[0]*(P(20,2) + P(0,2)*SH_MAG[2] + P(1,2)*SH_MAG[1] + P(2,2)*SH_MAG[0] - P(17,2)*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) - P(16,2)*(2.0f*q0*q3 - 2.0f*q1*q2) + P(18,2)*(2.0f*q0*q1 + 2.0f*q2*q3) - P(3,2)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) - (SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6])*(P(20,17) + P(0,17)*SH_MAG[2] + P(1,17)*SH_MAG[1] + P(2,17)*SH_MAG[0] - P(17,17)*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) - P(16,17)*(2.0f*q0*q3 - 2.0f*q1*q2) + P(18,17)*(2.0f*q0*q1 + 2.0f*q2*q3) - P(3,17)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) - P(3,20)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2));
|
||||||
|
|
||||||
// check for a badly conditioned covariance matrix
|
// check for a badly conditioned covariance matrix
|
||||||
if (_mag_innov_var[1] >= R_MAG) {
|
if (_mag_innov_var(1) >= R_MAG) {
|
||||||
// the innovation variance contribution from the state covariances is non-negative - no fault
|
// the innovation variance contribution from the state covariances is non-negative - no fault
|
||||||
_fault_status.flags.bad_mag_y = false;
|
_fault_status.flags.bad_mag_y = false;
|
||||||
|
|
||||||
@@ -130,14 +128,14 @@ void Ekf::fuseMag()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Z axis innovation variance
|
// Z axis innovation variance
|
||||||
_mag_innov_var[2] = (P(21,21) + R_MAG + P(0,21)*SH_MAG[1] - P(1,21)*SH_MAG[2] + P(3,21)*SH_MAG[0] + P(18,21)*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) + (2.0f*q0*q2 + 2.0f*q1*q3)*(P(21,16) + P(0,16)*SH_MAG[1] - P(1,16)*SH_MAG[2] + P(3,16)*SH_MAG[0] + P(18,16)*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) + P(16,16)*(2.0f*q0*q2 + 2.0f*q1*q3) - P(17,16)*(2.0f*q0*q1 - 2.0f*q2*q3) + P(2,16)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) - (2.0f*q0*q1 - 2.0f*q2*q3)*(P(21,17) + P(0,17)*SH_MAG[1] - P(1,17)*SH_MAG[2] + P(3,17)*SH_MAG[0] + P(18,17)*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) + P(16,17)*(2.0f*q0*q2 + 2.0f*q1*q3) - P(17,17)*(2.0f*q0*q1 - 2.0f*q2*q3) + P(2,17)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + (SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)*(P(21,2) + P(0,2)*SH_MAG[1] - P(1,2)*SH_MAG[2] + P(3,2)*SH_MAG[0] + P(18,2)*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) + P(16,2)*(2.0f*q0*q2 + 2.0f*q1*q3) - P(17,2)*(2.0f*q0*q1 - 2.0f*q2*q3) + P(2,2)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + P(16,21)*(2.0f*q0*q2 + 2.0f*q1*q3) - P(17,21)*(2.0f*q0*q1 - 2.0f*q2*q3) + SH_MAG[1]*(P(21,0) + P(0,0)*SH_MAG[1] - P(1,0)*SH_MAG[2] + P(3,0)*SH_MAG[0] + P(18,0)*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) + P(16,0)*(2.0f*q0*q2 + 2.0f*q1*q3) - P(17,0)*(2.0f*q0*q1 - 2.0f*q2*q3) + P(2,0)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) - SH_MAG[2]*(P(21,1) + P(0,1)*SH_MAG[1] - P(1,1)*SH_MAG[2] + P(3,1)*SH_MAG[0] + P(18,1)*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) + P(16,1)*(2.0f*q0*q2 + 2.0f*q1*q3) - P(17,1)*(2.0f*q0*q1 - 2.0f*q2*q3) + P(2,1)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + SH_MAG[0]*(P(21,3) + P(0,3)*SH_MAG[1] - P(1,3)*SH_MAG[2] + P(3,3)*SH_MAG[0] + P(18,3)*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) + P(16,3)*(2.0f*q0*q2 + 2.0f*q1*q3) - P(17,3)*(2.0f*q0*q1 - 2.0f*q2*q3) + P(2,3)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + (SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6])*(P(21,18) + P(0,18)*SH_MAG[1] - P(1,18)*SH_MAG[2] + P(3,18)*SH_MAG[0] + P(18,18)*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) + P(16,18)*(2.0f*q0*q2 + 2.0f*q1*q3) - P(17,18)*(2.0f*q0*q1 - 2.0f*q2*q3) + P(2,18)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + P(2,21)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2));
|
_mag_innov_var(2) = (P(21,21) + R_MAG + P(0,21)*SH_MAG[1] - P(1,21)*SH_MAG[2] + P(3,21)*SH_MAG[0] + P(18,21)*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) + (2.0f*q0*q2 + 2.0f*q1*q3)*(P(21,16) + P(0,16)*SH_MAG[1] - P(1,16)*SH_MAG[2] + P(3,16)*SH_MAG[0] + P(18,16)*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) + P(16,16)*(2.0f*q0*q2 + 2.0f*q1*q3) - P(17,16)*(2.0f*q0*q1 - 2.0f*q2*q3) + P(2,16)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) - (2.0f*q0*q1 - 2.0f*q2*q3)*(P(21,17) + P(0,17)*SH_MAG[1] - P(1,17)*SH_MAG[2] + P(3,17)*SH_MAG[0] + P(18,17)*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) + P(16,17)*(2.0f*q0*q2 + 2.0f*q1*q3) - P(17,17)*(2.0f*q0*q1 - 2.0f*q2*q3) + P(2,17)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + (SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)*(P(21,2) + P(0,2)*SH_MAG[1] - P(1,2)*SH_MAG[2] + P(3,2)*SH_MAG[0] + P(18,2)*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) + P(16,2)*(2.0f*q0*q2 + 2.0f*q1*q3) - P(17,2)*(2.0f*q0*q1 - 2.0f*q2*q3) + P(2,2)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + P(16,21)*(2.0f*q0*q2 + 2.0f*q1*q3) - P(17,21)*(2.0f*q0*q1 - 2.0f*q2*q3) + SH_MAG[1]*(P(21,0) + P(0,0)*SH_MAG[1] - P(1,0)*SH_MAG[2] + P(3,0)*SH_MAG[0] + P(18,0)*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) + P(16,0)*(2.0f*q0*q2 + 2.0f*q1*q3) - P(17,0)*(2.0f*q0*q1 - 2.0f*q2*q3) + P(2,0)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) - SH_MAG[2]*(P(21,1) + P(0,1)*SH_MAG[1] - P(1,1)*SH_MAG[2] + P(3,1)*SH_MAG[0] + P(18,1)*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) + P(16,1)*(2.0f*q0*q2 + 2.0f*q1*q3) - P(17,1)*(2.0f*q0*q1 - 2.0f*q2*q3) + P(2,1)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + SH_MAG[0]*(P(21,3) + P(0,3)*SH_MAG[1] - P(1,3)*SH_MAG[2] + P(3,3)*SH_MAG[0] + P(18,3)*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) + P(16,3)*(2.0f*q0*q2 + 2.0f*q1*q3) - P(17,3)*(2.0f*q0*q1 - 2.0f*q2*q3) + P(2,3)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + (SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6])*(P(21,18) + P(0,18)*SH_MAG[1] - P(1,18)*SH_MAG[2] + P(3,18)*SH_MAG[0] + P(18,18)*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) + P(16,18)*(2.0f*q0*q2 + 2.0f*q1*q3) - P(17,18)*(2.0f*q0*q1 - 2.0f*q2*q3) + P(2,18)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2)) + P(2,21)*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2));
|
||||||
|
|
||||||
// check for a badly conditioned covariance matrix
|
// check for a badly conditioned covariance matrix
|
||||||
if (_mag_innov_var[2] >= R_MAG) {
|
if (_mag_innov_var(2) >= R_MAG) {
|
||||||
// the innovation variance contribution from the state covariances is non-negative - no fault
|
// the innovation variance contribution from the state covariances is non-negative - no fault
|
||||||
_fault_status.flags.bad_mag_z = false;
|
_fault_status.flags.bad_mag_z = false;
|
||||||
|
|
||||||
} else if (_mag_innov_var[2] > 0.0f) {
|
} else {
|
||||||
// the innovation variance contribution from the state covariances is negative which means the covariance matrix is badly conditioned
|
// the innovation variance contribution from the state covariances is negative which means the covariance matrix is badly conditioned
|
||||||
_fault_status.flags.bad_mag_z = true;
|
_fault_status.flags.bad_mag_z = true;
|
||||||
|
|
||||||
@@ -152,9 +150,9 @@ void Ekf::fuseMag()
|
|||||||
bool healthy = true;
|
bool healthy = true;
|
||||||
|
|
||||||
for (uint8_t index = 0; index <= 2; index++) {
|
for (uint8_t index = 0; index <= 2; index++) {
|
||||||
_mag_test_ratio[index] = sq(_mag_innov[index]) / (sq(math::max(_params.mag_innov_gate, 1.0f)) * _mag_innov_var[index]);
|
_mag_test_ratio(index) = sq(_mag_innov(index)) / (sq(math::max(_params.mag_innov_gate, 1.0f)) * _mag_innov_var(index));
|
||||||
|
|
||||||
if (_mag_test_ratio[index] > 1.0f) {
|
if (_mag_test_ratio(index) > 1.0f) {
|
||||||
healthy = false;
|
healthy = false;
|
||||||
_innov_check_fail_status.value |= (1 << (index + 3));
|
_innov_check_fail_status.value |= (1 << (index + 3));
|
||||||
|
|
||||||
@@ -193,7 +191,7 @@ void Ekf::fuseMag()
|
|||||||
|
|
||||||
// Calculate X axis Kalman gains
|
// Calculate X axis Kalman gains
|
||||||
float SK_MX[5];
|
float SK_MX[5];
|
||||||
SK_MX[0] = 1.0f / _mag_innov_var[0];
|
SK_MX[0] = 1.0f / _mag_innov_var(0);
|
||||||
SK_MX[1] = SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6];
|
SK_MX[1] = SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6];
|
||||||
SK_MX[2] = SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2;
|
SK_MX[2] = SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2;
|
||||||
SK_MX[3] = 2.0f*q0*q2 - 2.0f*q1*q3;
|
SK_MX[3] = 2.0f*q0*q2 - 2.0f*q1*q3;
|
||||||
@@ -248,7 +246,7 @@ void Ekf::fuseMag()
|
|||||||
|
|
||||||
// Calculate Y axis Kalman gains
|
// Calculate Y axis Kalman gains
|
||||||
float SK_MY[5];
|
float SK_MY[5];
|
||||||
SK_MY[0] = 1.0f / _mag_innov_var[1];
|
SK_MY[0] = 1.0f / _mag_innov_var(1);
|
||||||
SK_MY[1] = SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6];
|
SK_MY[1] = SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6];
|
||||||
SK_MY[2] = SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2;
|
SK_MY[2] = SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2;
|
||||||
SK_MY[3] = 2.0f*q0*q3 - 2.0f*q1*q2;
|
SK_MY[3] = 2.0f*q0*q3 - 2.0f*q1*q2;
|
||||||
@@ -309,7 +307,7 @@ void Ekf::fuseMag()
|
|||||||
|
|
||||||
// Calculate Z axis Kalman gains
|
// Calculate Z axis Kalman gains
|
||||||
float SK_MZ[5];
|
float SK_MZ[5];
|
||||||
SK_MZ[0] = 1.0f / _mag_innov_var[2];
|
SK_MZ[0] = 1.0f / _mag_innov_var(2);
|
||||||
SK_MZ[1] = SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6];
|
SK_MZ[1] = SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6];
|
||||||
SK_MZ[2] = SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2;
|
SK_MZ[2] = SH_MAG[7] + SH_MAG[8] - 2.0f*magD*q2;
|
||||||
SK_MZ[3] = 2.0f*q0*q1 - 2.0f*q2*q3;
|
SK_MZ[3] = 2.0f*q0*q1 - 2.0f*q2*q3;
|
||||||
@@ -428,7 +426,7 @@ void Ekf::fuseMag()
|
|||||||
fixCovarianceErrors(true);
|
fixCovarianceErrors(true);
|
||||||
|
|
||||||
// apply the state corrections
|
// apply the state corrections
|
||||||
fuse(Kfusion, _mag_innov[index]);
|
fuse(Kfusion, _mag_innov(index));
|
||||||
|
|
||||||
// constrain the declination of the earth field states
|
// constrain the declination of the earth field states
|
||||||
limitDeclination();
|
limitDeclination();
|
||||||
@@ -688,7 +686,7 @@ void Ekf::updateQuaternion(const float innovation, const float variance, const f
|
|||||||
_yaw_test_ratio = sq(innovation) / (sq(gate_sigma) * _heading_innov_var);
|
_yaw_test_ratio = sq(innovation) / (sq(gate_sigma) * _heading_innov_var);
|
||||||
|
|
||||||
// we are no longer using 3-axis fusion so set the reported test levels to zero
|
// we are no longer using 3-axis fusion so set the reported test levels to zero
|
||||||
memset(_mag_test_ratio, 0, sizeof(_mag_test_ratio));
|
_mag_test_ratio.setZero();
|
||||||
|
|
||||||
// set the magnetometer unhealthy if the test fails
|
// set the magnetometer unhealthy if the test fails
|
||||||
if (_yaw_test_ratio > 1.0f) {
|
if (_yaw_test_ratio > 1.0f) {
|
||||||
|
|||||||
Reference in New Issue
Block a user