mirror of https://github.com/ArduPilot/ardupilot
AP_NavEKF3: fixed in-flight yaw reset
This commit is contained in:
parent
86d221708c
commit
197d31e9cc
|
@ -97,23 +97,8 @@ void NavEKF3_core::controlMagYawReset()
|
||||||
// update rotation matrix from body to NED frame
|
// update rotation matrix from body to NED frame
|
||||||
stateStruct.quat.inverse().rotation_matrix(prevTnb);
|
stateStruct.quat.inverse().rotation_matrix(prevTnb);
|
||||||
|
|
||||||
// read the magnetometer data
|
// set yaw from a single mag sample
|
||||||
readMagData();
|
setYawFromMag();
|
||||||
|
|
||||||
// rotate the magnetic field into NED axes
|
|
||||||
Vector3f initMagNED = prevTnb * magDataDelayed.mag;
|
|
||||||
|
|
||||||
// calculate heading of mag field rel to body heading
|
|
||||||
float magHeading = atan2f(initMagNED.y, initMagNED.x);
|
|
||||||
|
|
||||||
// get the magnetic declination
|
|
||||||
float magDecAng = MagDeclination();
|
|
||||||
|
|
||||||
// calculate yaw angle delta
|
|
||||||
float yaw_delta = magDecAng - magHeading;
|
|
||||||
|
|
||||||
// update quaternion states and covariances
|
|
||||||
resetQuatStateYawOnly(yaw_delta, sq(MAX(frontend->_yawNoise, 1.0e-2f)), true);
|
|
||||||
|
|
||||||
// send initial alignment status to console
|
// send initial alignment status to console
|
||||||
if (!yawAlignComplete) {
|
if (!yawAlignComplete) {
|
||||||
|
|
|
@ -1638,6 +1638,28 @@ void NavEKF3_core::calcEarthRateNED(Vector3f &omega, int32_t latitude) const
|
||||||
omega.z = -earthRate*sinf(lat_rad);
|
omega.z = -earthRate*sinf(lat_rad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set yaw from a single magnetometer sample
|
||||||
|
void NavEKF3_core::setYawFromMag()
|
||||||
|
{
|
||||||
|
// read the magnetometer data
|
||||||
|
readMagData();
|
||||||
|
|
||||||
|
// rotate the magnetic field into NED axes
|
||||||
|
Vector3f euler321;
|
||||||
|
stateStruct.quat.to_euler(euler321.x, euler321.y, euler321.z);
|
||||||
|
|
||||||
|
// set the yaw to zero and calculate the zero yaw rotation from body to earth frame
|
||||||
|
Matrix3f Tbn_zeroYaw;
|
||||||
|
Tbn_zeroYaw.from_euler(euler321.x, euler321.y, 0.0f);
|
||||||
|
|
||||||
|
//Vector3f magMeasNED = Tbn_zeroYaw * magDataDelayed.mag;
|
||||||
|
Vector3f magMeasNED = Tbn_zeroYaw * magDataDelayed.mag;
|
||||||
|
float yawAngMeasured = wrap_PI(-atan2f(magMeasNED.y, magMeasNED.x) + MagDeclination());
|
||||||
|
|
||||||
|
// update quaternion states and covariances
|
||||||
|
resetQuatStateYawOnly(yawAngMeasured, sq(MAX(frontend->_yawNoise, 1.0e-2f)), false);
|
||||||
|
}
|
||||||
|
|
||||||
// update quaternion, mag field states and associated variances using magnetomer and declination data
|
// update quaternion, mag field states and associated variances using magnetomer and declination data
|
||||||
void NavEKF3_core::calcQuatAndFieldStates()
|
void NavEKF3_core::calcQuatAndFieldStates()
|
||||||
{
|
{
|
||||||
|
@ -1648,23 +1670,8 @@ void NavEKF3_core::calcQuatAndFieldStates()
|
||||||
// update rotation matrix from body to NED frame
|
// update rotation matrix from body to NED frame
|
||||||
stateStruct.quat.inverse().rotation_matrix(prevTnb);
|
stateStruct.quat.inverse().rotation_matrix(prevTnb);
|
||||||
|
|
||||||
// read the magnetometer data
|
// set yaw from a single mag sample
|
||||||
readMagData();
|
setYawFromMag();
|
||||||
|
|
||||||
// rotate the magnetic field into NED axes
|
|
||||||
Vector3f initMagNED = prevTnb * magDataDelayed.mag;
|
|
||||||
|
|
||||||
// calculate heading of mag field rel to body heading
|
|
||||||
float magHeading = atan2f(initMagNED.y, initMagNED.x);
|
|
||||||
|
|
||||||
// get the magnetic declination
|
|
||||||
float magDecAng = MagDeclination();
|
|
||||||
|
|
||||||
// calculate yaw angle delta
|
|
||||||
float yaw_delta = magDecAng - magHeading;
|
|
||||||
|
|
||||||
// update quaternion states and covariances
|
|
||||||
resetQuatStateYawOnly(yaw_delta, sq(MAX(frontend->_yawNoise, 1.0e-2f)), true);
|
|
||||||
|
|
||||||
// Rotate Mag measurements into NED to set initial NED magnetic field states
|
// Rotate Mag measurements into NED to set initial NED magnetic field states
|
||||||
// Don't do this if the earth field has already been learned
|
// Don't do this if the earth field has already been learned
|
||||||
|
@ -1686,12 +1693,10 @@ void NavEKF3_core::calcQuatAndFieldStates()
|
||||||
P[19][19] = P[18][18];
|
P[19][19] = P[18][18];
|
||||||
P[20][20] = P[18][18];
|
P[20][20] = P[18][18];
|
||||||
P[21][21] = P[18][18];
|
P[21][21] = P[18][18];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// record the fact we have initialised the magnetic field states
|
// record the fact we have initialised the magnetic field states
|
||||||
recordMagReset();
|
recordMagReset();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// zero the attitude covariances, but preserve the variances
|
// zero the attitude covariances, but preserve the variances
|
||||||
|
|
|
@ -738,6 +738,9 @@ private:
|
||||||
// update quaternion, mag field states and associated variances using magnetomer and declination data
|
// update quaternion, mag field states and associated variances using magnetomer and declination data
|
||||||
void calcQuatAndFieldStates();
|
void calcQuatAndFieldStates();
|
||||||
|
|
||||||
|
// reset yaw based on magnetic field sample
|
||||||
|
void setYawFromMag();
|
||||||
|
|
||||||
// zero stored variables
|
// zero stored variables
|
||||||
void InitialiseVariables();
|
void InitialiseVariables();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue