diff --git a/libraries/AP_InertialSensor/AP_InertialSensor.cpp b/libraries/AP_InertialSensor/AP_InertialSensor.cpp index 8c6f05fd1e6789..5dea0189e53f7a 100644 --- a/libraries/AP_InertialSensor/AP_InertialSensor.cpp +++ b/libraries/AP_InertialSensor/AP_InertialSensor.cpp @@ -39,6 +39,7 @@ #include "AP_InertialSensor_Invensensev3.h" #include "AP_InertialSensor_NONE.h" #include "AP_InertialSensor_SCHA63T.h" +#include /* Define INS_TIMING_DEBUG to track down scheduling issues with the main loop. * Output is on the debug console. */ @@ -1492,6 +1493,31 @@ bool AP_InertialSensor::gyro_calibrated_ok_all() const return (get_gyro_count() > 0); } +// Prearm check to verify that we have sane sched loop rates set based on Gyro backend rates +bool AP_InertialSensor::pre_arm_check_gyro_backend_rate_hz(char* fail_msg, uint16_t fail_msg_len) const +{ +#if AP_SCHEDULER_ENABLED + for (uint8_t i=0; iget_gyro_backend_rate_hz() == 0) { + if (_gyro_raw_sample_rates[i] < _loop_rate) { + hal.util->snprintf(fail_msg, fail_msg_len, "Gyro %d sample rate %dHz < sched loop rate %fHz", + i, _backends[i]->get_gyro_backend_rate_hz(), _loop_rate); + return false; + } + } else if (_backends[i]->get_gyro_backend_rate_hz() < _loop_rate) { + hal.util->snprintf(fail_msg, fail_msg_len, "Gyro %d backend rate %dHz < sched loop rate %dHz", + i, _backends[i]->get_gyro_backend_rate_hz(), _loop_rate); + return false; + } + } +#endif + return true; +} + // return true if gyro instance should be used (must be healthy and have it's use parameter set to 1) bool AP_InertialSensor::use_gyro(uint8_t instance) const { diff --git a/libraries/AP_InertialSensor/AP_InertialSensor.h b/libraries/AP_InertialSensor/AP_InertialSensor.h index 30e60bec6c2313..5e9af64cfe8742 100644 --- a/libraries/AP_InertialSensor/AP_InertialSensor.h +++ b/libraries/AP_InertialSensor/AP_InertialSensor.h @@ -156,6 +156,9 @@ class AP_InertialSensor : AP_AccelCal_Client uint16_t get_gyro_rate_hz(uint8_t instance) const { return uint16_t(_gyro_raw_sample_rates[instance] * _gyro_over_sampling[instance]); } uint16_t get_accel_rate_hz(uint8_t instance) const { return uint16_t(_accel_raw_sample_rates[instance] * _accel_over_sampling[instance]); } + // validate backend sample rates + bool pre_arm_check_gyro_backend_rate_hz(char* fail_msg, uint16_t fail_msg_len) const; + // FFT support access #if HAL_GYROFFT_ENABLED const Vector3f& get_gyro_for_fft(void) const { return _gyro_for_fft[_first_usable_gyro]; } diff --git a/libraries/AP_InertialSensor/AP_InertialSensor_Backend.h b/libraries/AP_InertialSensor/AP_InertialSensor_Backend.h index 817cb2e947c858..553a1120c8fb2a 100644 --- a/libraries/AP_InertialSensor/AP_InertialSensor_Backend.h +++ b/libraries/AP_InertialSensor/AP_InertialSensor_Backend.h @@ -91,6 +91,12 @@ class AP_InertialSensor_Backend bool has_been_killed(uint8_t instance) const { return false; } #endif + // get the backend update rate for the gyro in Hz + // return 0 if the backend polling rate is the same as the sample rate or higher + // override return the backend rate in Hz if it is lower than the sample rate + virtual uint16_t get_gyro_backend_rate_hz() const { + return 0; + } /* device driver IDs. These are used to fill in the devtype field diff --git a/libraries/AP_InertialSensor/AP_InertialSensor_Invensense.h b/libraries/AP_InertialSensor/AP_InertialSensor_Invensense.h index 7ba132f3a309a7..223e2d59b5f39b 100644 --- a/libraries/AP_InertialSensor/AP_InertialSensor_Invensense.h +++ b/libraries/AP_InertialSensor/AP_InertialSensor_Invensense.h @@ -58,6 +58,11 @@ class AP_InertialSensor_Invensense : public AP_InertialSensor_Backend // get a startup banner to output to the GCS bool get_output_banner(char* banner, uint8_t banner_len) override; + // get the gyro backend rate in Hz at which the FIFO is being read + uint16_t get_gyro_backend_rate_hz() const override { + return _gyro_backend_rate_hz; + } + enum Invensense_Type { Invensense_MPU6000=0, Invensense_MPU6500, diff --git a/libraries/AP_InertialSensor/AP_InertialSensor_Invensensev2.h b/libraries/AP_InertialSensor/AP_InertialSensor_Invensensev2.h index 1b14062863a29e..98fbad8d9818b3 100644 --- a/libraries/AP_InertialSensor/AP_InertialSensor_Invensensev2.h +++ b/libraries/AP_InertialSensor/AP_InertialSensor_Invensensev2.h @@ -55,6 +55,11 @@ class AP_InertialSensor_Invensensev2 : public AP_InertialSensor_Backend // get a startup banner to output to the GCS bool get_output_banner(char* banner, uint8_t banner_len) override; + // get the gyro backend rate in Hz at which the FIFO is being read + uint16_t get_gyro_backend_rate_hz() const override { + return _gyro_backend_rate_hz; + } + enum Invensensev2_Type { Invensensev2_ICM20948 = 0, Invensensev2_ICM20648, diff --git a/libraries/AP_InertialSensor/AP_InertialSensor_Invensensev3.h b/libraries/AP_InertialSensor/AP_InertialSensor_Invensensev3.h index 6b4fc49a8c5c49..012f2e615aac38 100644 --- a/libraries/AP_InertialSensor/AP_InertialSensor_Invensensev3.h +++ b/libraries/AP_InertialSensor/AP_InertialSensor_Invensensev3.h @@ -75,6 +75,11 @@ class AP_InertialSensor_Invensensev3 : public AP_InertialSensor_Backend bool accumulate_samples(const struct FIFOData *data, uint8_t n_samples); bool accumulate_highres_samples(const struct FIFODataHighRes *data, uint8_t n_samples); + // get the gyro backend rate in Hz at which the FIFO is being read + uint16_t get_gyro_backend_rate_hz() const override { + return backend_rate_hz; + } + // reset FIFO configure1 register uint8_t fifo_config1;