Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prearm check to validate backend read rates against scheduler loop rate #28672

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions libraries/AP_Arming/AP_Arming.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,12 @@ bool AP_Arming::ins_checks(bool report)
}
#endif

// check if IMU gyro updates are greater than or equal to Ardupilot Loop rate
char fail_msg[MAVLINK_MSG_STATUSTEXT_FIELD_TEXT_LEN+1];
if (!ins.pre_arm_check_gyro_backend_rate_hz(fail_msg, ARRAY_SIZE(fail_msg))) {
check_failed(ARMING_CHECK_INS, report, "%s", fail_msg);
return false;
}
}

#if HAL_GYROFFT_ENABLED
Expand Down
19 changes: 19 additions & 0 deletions libraries/AP_InertialSensor/AP_InertialSensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "AP_InertialSensor_Invensensev3.h"
#include "AP_InertialSensor_NONE.h"
#include "AP_InertialSensor_SCHA63T.h"
#include <AP_Scheduler/AP_Scheduler.h>

/* Define INS_TIMING_DEBUG to track down scheduling issues with the main loop.
* Output is on the debug console. */
Expand Down Expand Up @@ -1492,6 +1493,24 @@ 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; i<get_gyro_count(); i++) {
if (!_use(i) || _backends[i] == nullptr) {
continue;
}
if (_backends[i]->get_gyro_backend_rate_hz() < (2*_loop_rate)) {
hal.util->snprintf(fail_msg, fail_msg_len, "Gyro %d backend rate %dHz < sched loop ratex2 %dHz",
i, _backends[i]->get_gyro_backend_rate_hz(), 2 * _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
{
Expand Down
3 changes: 3 additions & 0 deletions libraries/AP_InertialSensor/AP_InertialSensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,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]; }
Expand Down
6 changes: 6 additions & 0 deletions libraries/AP_InertialSensor/AP_InertialSensor_Backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,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
// if the backend polling rate is the same as the sample rate or higher, return raw sample rate
// override and return the backend rate in Hz if it is lower than the sample rate
virtual uint16_t get_gyro_backend_rate_hz() const {
return _gyro_raw_sample_rate(gyro_instance);
}

/*
device driver IDs. These are used to fill in the devtype field
Expand Down
5 changes: 5 additions & 0 deletions libraries/AP_InertialSensor/AP_InertialSensor_Invensense.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
5 changes: 5 additions & 0 deletions libraries/AP_InertialSensor/AP_InertialSensor_Invensensev2.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
5 changes: 5 additions & 0 deletions libraries/AP_InertialSensor/AP_InertialSensor_Invensensev3.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should take the opportunity to come up with a better name than "backend". Perhaps "get_gyro_read_rate_hz()" at least conveys what is going on and why it might be important.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That needs to be much larger and a separate change, I don't want to widen the scope of this PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could just remove the word "backend" from the method name maybe?

return backend_rate_hz;
}

// reset FIFO configure1 register
uint8_t fifo_config1;

Expand Down
2 changes: 1 addition & 1 deletion libraries/AP_InertialSensor/AP_InertialSensor_SITL.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

// simulated sensor rates in Hz. This matches a pixhawk1
const uint16_t INS_SITL_SENSOR_A[] = { 1000, 1000 };
const uint16_t INS_SITL_SENSOR_B[] = { 760, 800 };
const uint16_t INS_SITL_SENSOR_B[] = { 840, 900 };

#include <SITL/SITL.h>

Expand Down
Loading