mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-02-22 07:44:03 -04:00
AP_NavEKF2: Fix bug in use of corrected IMU data
IMU data was being corrected before being used by the co-variance prediction, whereas the delta angles and velocities in the derivation were supposed to be uncorrected. This patch creates separate variable for the corrected data
This commit is contained in:
parent
118d5b88b2
commit
191c34612d
@ -346,7 +346,7 @@ void NavEKF2_core::FuseMagnetometer()
|
||||
}
|
||||
|
||||
// scale magnetometer observation error with total angular rate to allow for timing errors
|
||||
R_MAG = sq(constrain_float(frontend->_magNoise, 0.01f, 0.5f)) + sq(frontend->magVarRateScale*imuDataDelayed.delAng.length() / imuDataDelayed.delAngDT);
|
||||
R_MAG = sq(constrain_float(frontend->_magNoise, 0.01f, 0.5f)) + sq(frontend->magVarRateScale*delAngCorrected.length() / imuDataDelayed.delAngDT);
|
||||
|
||||
// calculate common expressions used to calculate observation jacobians an innovation variance for each component
|
||||
SH_MAG[0] = sq(q0) - sq(q1) + sq(q2) - sq(q3);
|
||||
|
@ -282,12 +282,16 @@ void NavEKF2_core::readIMUData()
|
||||
// If 10msec has elapsed, and the frontend has allowed us to start a new predict cycle, then store the accumulated IMU data
|
||||
// to be used by the state prediction, ignoring the frontend permission if more than 20msec has lapsed
|
||||
if ((dtIMUavg*(float)framesSincePredict >= 0.01f && startPredictEnabled) || (dtIMUavg*(float)framesSincePredict >= 0.02f)) {
|
||||
|
||||
// convert the accumulated quaternion to an equivalent delta angle
|
||||
imuQuatDownSampleNew.to_axis_angle(imuDataDownSampledNew.delAng);
|
||||
|
||||
// Time stamp the data
|
||||
imuDataDownSampledNew.time_ms = imuSampleTime_ms;
|
||||
|
||||
// Write data to the FIFO IMU buffer
|
||||
storedIMU.push_youngest_element(imuDataDownSampledNew);
|
||||
|
||||
// zero the accumulated IMU data and quaternion
|
||||
imuDataDownSampledNew.delAng.zero();
|
||||
imuDataDownSampledNew.delVel.zero();
|
||||
@ -295,18 +299,28 @@ void NavEKF2_core::readIMUData()
|
||||
imuDataDownSampledNew.delVelDT = 0.0f;
|
||||
imuQuatDownSampleNew[0] = 1.0f;
|
||||
imuQuatDownSampleNew[3] = imuQuatDownSampleNew[2] = imuQuatDownSampleNew[1] = 0.0f;
|
||||
|
||||
// reset the counter used to let the frontend know how many frames have elapsed since we started a new update cycle
|
||||
framesSincePredict = 0;
|
||||
|
||||
// set the flag to let the filter know it has new IMU data nad needs to run
|
||||
runUpdates = true;
|
||||
|
||||
// extract the oldest available data from the FIFO buffer
|
||||
imuDataDelayed = storedIMU.pop_oldest_element();
|
||||
|
||||
// protect against delta time going to zero
|
||||
// TODO - check if calculations can tolerate 0
|
||||
float minDT = 0.1f*dtEkfAvg;
|
||||
imuDataDelayed.delAngDT = MAX(imuDataDelayed.delAngDT,minDT);
|
||||
imuDataDelayed.delVelDT = MAX(imuDataDelayed.delVelDT,minDT);
|
||||
|
||||
// correct the extracted IMU data for sensor errors
|
||||
correctDeltaAngle(imuDataDelayed.delAng, imuDataDelayed.delAngDT);
|
||||
correctDeltaVelocity(imuDataDelayed.delVel, imuDataDelayed.delVelDT);
|
||||
delAngCorrected = imuDataDelayed.delAng;
|
||||
delVelCorrected = imuDataDelayed.delVel;
|
||||
correctDeltaAngle(delAngCorrected, imuDataDelayed.delAngDT);
|
||||
correctDeltaVelocity(delVelCorrected, imuDataDelayed.delVelDT);
|
||||
|
||||
} else {
|
||||
// we don't have new IMU data in the buffer so don't run filter updates on this time step
|
||||
runUpdates = false;
|
||||
|
@ -493,13 +493,11 @@ void NavEKF2_core::correctDeltaVelocity(Vector3f &delVel, float delVelDT)
|
||||
*/
|
||||
void NavEKF2_core::UpdateStrapdownEquationsNED()
|
||||
{
|
||||
// apply correction for earth's rotation rate
|
||||
// % * - and + operators have been overloaded
|
||||
imuDataDelayed.delAng -= prevTnb * earthRateNED*imuDataDelayed.delAngDT;
|
||||
|
||||
// update the quaternion states by rotating from the previous attitude through
|
||||
// the delta angle rotation quaternion and normalise
|
||||
stateStruct.quat.rotate(imuDataDelayed.delAng);
|
||||
// apply correction for earth's rotation rate
|
||||
// % * - and + operators have been overloaded
|
||||
stateStruct.quat.rotate(delAngCorrected - prevTnb * earthRateNED*imuDataDelayed.delAngDT);
|
||||
stateStruct.quat.normalize();
|
||||
|
||||
// transform body delta velocities to delta velocities in the nav frame
|
||||
@ -507,7 +505,7 @@ void NavEKF2_core::UpdateStrapdownEquationsNED()
|
||||
// have been rotated into that frame
|
||||
// * and + operators have been overloaded
|
||||
Vector3f delVelNav; // delta velocity vector in earth axes
|
||||
delVelNav = prevTnb.mul_transpose(imuDataDelayed.delVel);
|
||||
delVelNav = prevTnb.mul_transpose(delVelCorrected);
|
||||
delVelNav.z += GRAVITY_MSS*imuDataDelayed.delVelDT;
|
||||
|
||||
// calculate the body to nav cosine matrix
|
||||
@ -542,7 +540,7 @@ void NavEKF2_core::UpdateStrapdownEquationsNED()
|
||||
stateStruct.position += (stateStruct.velocity + lastVelocity) * (imuDataDelayed.delVelDT*0.5f);
|
||||
|
||||
// accumulate the bias delta angle and time since last reset by an OF measurement arrival
|
||||
delAngBodyOF += imuDataDelayed.delAng - stateStruct.gyro_bias;
|
||||
delAngBodyOF += delAngCorrected;
|
||||
delTimeOF += imuDataDelayed.delAngDT;
|
||||
|
||||
// limit states to protect against divergence
|
||||
|
@ -787,6 +787,8 @@ private:
|
||||
bool startPredictEnabled; // boolean true when the frontend has given permission to start a new state prediciton cycele
|
||||
uint8_t localFilterTimeStep_ms; // average number of msec between filter updates
|
||||
float posDownObsNoise; // observation noise variance on the vertical position used by the state and covariance update step (m^2)
|
||||
Vector3f delAngCorrected; // corrected IMU delta angle vector at the EKF time horizon (rad)
|
||||
Vector3f delVelCorrected; // corrected IMU delta velocity vector at the EKF time horizon (m/s)
|
||||
|
||||
// variables used to calculate a vertical velocity that is kinematically consistent with the verical position
|
||||
float posDownDerivative; // Rate of chage of vertical position (dPosD/dt) in m/s. This is the first time derivative of PosD.
|
||||
|
Loading…
Reference in New Issue
Block a user