ekf2: resetMagHeading() split out simple init case

This commit is contained in:
Daniel Agar 2022-03-21 15:51:32 -04:00
parent 9efadad06a
commit a41a0e7e80
3 changed files with 46 additions and 37 deletions

View File

@ -196,7 +196,19 @@ bool Ekf::initialiseFilter()
// calculate the initial magnetic field and yaw alignment
// but do not mark the yaw alignement complete as it needs to be
// reset once the leveling phase is done
resetMagHeading(false, false);
if ((_params.mag_fusion_type <= MagFuseType::MAG_3D) && (_mag_counter != 0)) {
// rotate the magnetometer measurements into earth frame using a zero yaw angle
// the angle of the projection onto the horizontal gives the yaw angle
const Vector3f mag_earth_pred = updateYawInRotMat(0.f, _R_to_earth) * _mag_lpf.getState();
float yaw_new = -atan2f(mag_earth_pred(1), mag_earth_pred(0)) + getMagDeclination();
// update quaternion states and corresponding covarainces
resetQuatStateYaw(yaw_new, 0.f, false);
// set the earth magnetic field states using the updated rotation
_state.mag_I = _R_to_earth * _mag_lpf.getState();
_state.mag_B.zero();
}
// initialise the state covariance matrix now we have starting values for all the states
initialiseCovariance();

View File

@ -723,7 +723,7 @@ private:
// reset the heading and magnetic field states using the declination and magnetometer measurements
// return true if successful
bool resetMagHeading(bool increase_yaw_var = true, bool update_buffer = true);
bool resetMagHeading();
// reset the heading using the external vision measurements
// return true if successful

View File

@ -460,25 +460,24 @@ bool Ekf::realignYawGPS(const Vector3f &mag)
}
// Reset heading and magnetic field states
bool Ekf::resetMagHeading(bool increase_yaw_var, bool update_buffer)
bool Ekf::resetMagHeading()
{
// prevent a reset being performed more than once on the same frame
if (_imu_sample_delayed.time_us == _flt_mag_align_start_time) {
return true;
}
const Vector3f mag_init = _mag_lpf.getState();
const bool mag_available = (_mag_counter != 0) && isRecent(_time_last_mag, 500000)
&& !magFieldStrengthDisturbed(mag_init);
// low pass filtered mag required
if (_mag_counter == 0) {
if (!mag_available) {
return false;
}
const Vector3f mag_init = _mag_lpf.getState();
// calculate the observed yaw angle and yaw variance
float yaw_new;
float yaw_new_variance = 0.0f;
const bool heading_required_for_navigation = _control_status.flags.gps || _control_status.flags.ev_pos;
const bool heading_required_for_navigation = _control_status.flags.gps;
if ((_params.mag_fusion_type <= MagFuseType::MAG_3D) || ((_params.mag_fusion_type == MagFuseType::INDOOR) && heading_required_for_navigation)) {
@ -487,33 +486,26 @@ bool Ekf::resetMagHeading(bool increase_yaw_var, bool update_buffer)
// the angle of the projection onto the horizontal gives the yaw angle
const Vector3f mag_earth_pred = R_to_earth * mag_init;
yaw_new = -atan2f(mag_earth_pred(1), mag_earth_pred(0)) + getMagDeclination();
if (increase_yaw_var) {
yaw_new_variance = sq(fmaxf(_params.mag_heading_noise, 1.0e-2f));
}
// calculate the observed yaw angle and yaw variance
float yaw_new = -atan2f(mag_earth_pred(1), mag_earth_pred(0)) + getMagDeclination();
float yaw_new_variance = sq(fmaxf(_params.mag_heading_noise, 1.e-2f));
// update quaternion states and corresponding covarainces
resetQuatStateYaw(yaw_new, yaw_new_variance);
// set the earth magnetic field states using the updated rotation
_state.mag_I = _R_to_earth * mag_init;
resetMagCov();
// record the time for the magnetic field alignment event
_flt_mag_align_start_time = _imu_sample_delayed.time_us;
} else if (_params.mag_fusion_type == MagFuseType::INDOOR) {
// we are operating temporarily without knowing the earth frame yaw angle
return true;
} else {
// there is no magnetic yaw observation
return false;
}
// update quaternion states and corresponding covarainces
resetQuatStateYaw(yaw_new, yaw_new_variance, update_buffer);
// set the earth magnetic field states using the updated rotation
_state.mag_I = _R_to_earth * mag_init;
resetMagCov();
// record the time for the magnetic field alignment event
_flt_mag_align_start_time = _imu_sample_delayed.time_us;
return true;
return false;
}
bool Ekf::resetYawToEv()
@ -1277,8 +1269,11 @@ void Ekf::stopMagHdgFusion()
void Ekf::startMagHdgFusion()
{
stopMag3DFusion();
_control_status.flags.mag_hdg = true;
if (!_control_status.flags.mag_hdg) {
stopMag3DFusion();
ECL_INFO("starting mag heading fusion");
_control_status.flags.mag_hdg = true;
}
}
void Ekf::startMag3DFusion()
@ -1721,7 +1716,10 @@ void Ekf::stopEvVelFusion()
void Ekf::stopEvYawFusion()
{
_control_status.flags.ev_yaw = false;
if (_control_status.flags.ev_yaw) {
ECL_INFO("stopping EV yaw fusion");
_control_status.flags.ev_yaw = false;
}
}
void Ekf::stopAuxVelFusion()
@ -1776,7 +1774,6 @@ void Ekf::resetQuatStateYaw(float yaw, float yaw_variance, bool update_buffer)
// apply the change in attitude quaternion to our newest quaternion estimate
// which was already taken out from the output buffer
_output_new.quat_nominal = _state_reset_status.quat_change * _output_new.quat_nominal;
}
_last_static_yaw = NAN;