Browse Source

AP_NavEKF2: Fix timing jitter in airspeed fusion

The airspeed observation buffer was only being checked when new data arrived instead of every frame which introduced some timing jitter. The buffer is now checked every filer update step.
The duplication and inconsistent naming of booleans used to indicate availability f data has been fixed.
mission-4.1.18
Paul Riseborough 9 years ago
parent
commit
ddb7d92fc8
  1. 8
      libraries/AP_NavEKF2/AP_NavEKF2_AirDataFusion.cpp
  2. 10
      libraries/AP_NavEKF2/AP_NavEKF2_Measurements.cpp
  3. 3
      libraries/AP_NavEKF2/AP_NavEKF2_core.h

8
libraries/AP_NavEKF2/AP_NavEKF2_AirDataFusion.cpp

@ -195,7 +195,7 @@ void NavEKF2_core::SelectTasFusion()
{ {
// Check if the magnetometer has been fused on that time step and the filter is running at faster than 200 Hz // Check if the magnetometer has been fused on that time step and the filter is running at faster than 200 Hz
// If so, don't fuse measurements on this time step to reduce frame over-runs // If so, don't fuse measurements on this time step to reduce frame over-runs
// Only allow one time slip to prevent high rate magnetometer data preventing fusion of other measurements // Only allow one time slip to prevent high rate magnetometer data locking out fusion of other measurements
if (magFusePerformed && dtIMUavg < 0.005f && !airSpdFusionDelayed) { if (magFusePerformed && dtIMUavg < 0.005f && !airSpdFusionDelayed) {
airSpdFusionDelayed = true; airSpdFusionDelayed = true;
return; return;
@ -212,13 +212,9 @@ void NavEKF2_core::SelectTasFusion()
} }
// if the filter is initialised, wind states are not inhibited and we have data to fuse, then perform TAS fusion // if the filter is initialised, wind states are not inhibited and we have data to fuse, then perform TAS fusion
tasDataWaiting = (statesInitialised && !inhibitWindStates && newDataTas); if (tasDataToFuse && statesInitialised && !inhibitWindStates) {
if (tasDataWaiting)
{
FuseAirspeed(); FuseAirspeed();
prevTasStep_ms = imuSampleTime_ms; prevTasStep_ms = imuSampleTime_ms;
tasDataWaiting = false;
newDataTas = false;
} }
} }

10
libraries/AP_NavEKF2/AP_NavEKF2_Measurements.cpp

@ -544,6 +544,7 @@ void NavEKF2_core::calcFiltBaroOffset()
// Apply a first order LPF with spike protection // Apply a first order LPF with spike protection
baroHgtOffset += 0.1f * constrain_float(baroDataDelayed.hgt + stateStruct.position.z - baroHgtOffset, -5.0f, 5.0f); baroHgtOffset += 0.1f * constrain_float(baroDataDelayed.hgt + stateStruct.position.z - baroHgtOffset, -5.0f, 5.0f);
} }
/******************************************************** /********************************************************
* Air Speed Measurements * * Air Speed Measurements *
********************************************************/ ********************************************************/
@ -561,14 +562,15 @@ void NavEKF2_core::readAirSpdData()
tasDataNew.tas = aspeed->get_airspeed() * aspeed->get_EAS2TAS(); tasDataNew.tas = aspeed->get_airspeed() * aspeed->get_EAS2TAS();
timeTasReceived_ms = aspeed->last_update_ms(); timeTasReceived_ms = aspeed->last_update_ms();
tasDataNew.time_ms = timeTasReceived_ms - frontend->tasDelay_ms; tasDataNew.time_ms = timeTasReceived_ms - frontend->tasDelay_ms;
// Correct for the average intersampling delay due to the filter update rate // Correct for the average intersampling delay due to the filter update rate
tasDataNew.time_ms -= localFilterTimeStep_ms/2; tasDataNew.time_ms -= localFilterTimeStep_ms/2;
newDataTas = true;
// Save data into the buffer to be fused when the fusion time horizon catches up with it
storedTAS.push(tasDataNew); storedTAS.push(tasDataNew);
storedTAS.recall(tasDataDelayed,imuDataDelayed.time_ms);
} else {
newDataTas = false;
} }
// Check the buffer for measurements that have been overtaken by the fusion time horizon and need to be fused
tasDataToFuse = storedTAS.recall(tasDataDelayed,imuDataDelayed.time_ms);
} }
#endif // HAL_CPU_CLASS #endif // HAL_CPU_CLASS

3
libraries/AP_NavEKF2/AP_NavEKF2_core.h

@ -679,8 +679,7 @@ private:
Vector3f velDotNED; // rate of change of velocity in NED frame Vector3f velDotNED; // rate of change of velocity in NED frame
Vector3f velDotNEDfilt; // low pass filtered velDotNED Vector3f velDotNEDfilt; // low pass filtered velDotNED
uint32_t imuSampleTime_ms; // time that the last IMU value was taken uint32_t imuSampleTime_ms; // time that the last IMU value was taken
bool newDataTas; // true when new airspeed data has arrived bool tasDataToFuse; // true when new airspeed data is waiting to be fused
bool tasDataWaiting; // true when new airspeed data is waiting to be fused
uint32_t lastBaroReceived_ms; // time last time we received baro height data uint32_t lastBaroReceived_ms; // time last time we received baro height data
uint16_t hgtRetryTime_ms; // time allowed without use of height measurements before a height timeout is declared uint16_t hgtRetryTime_ms; // time allowed without use of height measurements before a height timeout is declared
uint32_t lastVelPassTime_ms; // time stamp when GPS velocity measurement last passed innovation consistency check (msec) uint32_t lastVelPassTime_ms; // time stamp when GPS velocity measurement last passed innovation consistency check (msec)

Loading…
Cancel
Save