From 053f0cb6891cee538d689d4e43f442ad9e71009d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 4 Jul 2019 20:18:14 +1000 Subject: [PATCH] AP_InertialSensor: try much harder to get all IMU samples this we ensures we get new data for all active IMUs on each loop, rather than sometimes returning with some IMUs not having data. This matters as not having a sample on an IMU for a single loop can cause an EKF IMU failover, which will degrade the learned bias variances The issue is usually only seen under high load, such as requesting a loop rate beyond what the hardware is capable of --- .../AP_InertialSensor/AP_InertialSensor.cpp | 59 +++++++++++++++---- .../AP_InertialSensor/AP_InertialSensor.h | 5 ++ 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/libraries/AP_InertialSensor/AP_InertialSensor.cpp b/libraries/AP_InertialSensor/AP_InertialSensor.cpp index 53d200f650..2178cc582e 100644 --- a/libraries/AP_InertialSensor/AP_InertialSensor.cpp +++ b/libraries/AP_InertialSensor/AP_InertialSensor.cpp @@ -1401,25 +1401,64 @@ void AP_InertialSensor::wait_for_sample(void) check_sample: if (!_hil_mode) { - // we also wait for at least one backend to have a sample of both - // accel and gyro. This normally completes immediately. - bool gyro_available = false; - bool accel_available = false; + // now we wait until we have the gyro and accel samples we need + uint8_t gyro_available_mask = 0; + uint8_t accel_available_mask = 0; + uint32_t wait_counter = 0; + while (true) { for (uint8_t i=0; i<_backend_count; i++) { + // this is normally a nop, but can be used by backends + // that don't accumulate samples on a timer _backends[i]->accumulate(); } - for (uint8_t i=0; idelay_microseconds(100); + hal.scheduler->delay_microseconds_boost(100); + wait_counter++; } } diff --git a/libraries/AP_InertialSensor/AP_InertialSensor.h b/libraries/AP_InertialSensor/AP_InertialSensor.h index 315714243a..25736a35c7 100644 --- a/libraries/AP_InertialSensor/AP_InertialSensor.h +++ b/libraries/AP_InertialSensor/AP_InertialSensor.h @@ -495,6 +495,11 @@ private: uint8_t _primary_gyro; uint8_t _primary_accel; + // mask of accels and gyros which we will be actively using + // and this should wait for in wait_for_sample() + uint8_t _gyro_wait_mask; + uint8_t _accel_wait_mask; + // bitmask bit which indicates if we should log raw accel and gyro data uint32_t _log_raw_bit;