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
Improve EKF core IMU failover logic - WIP #11139
Conversation
small issue. Resetting the biases means if we get a single-frame bad health on an IMU we lose all biases when we recover. |
Actually, at the moment, it wouldn't "recover". The core would stay with the IMU we switched to, provided it remains healthy. The EKF core could potentially store the current estimated gyro bias for each IMU and switch them rather than resetting. |
0f2bb24
to
9b7169f
Compare
if (ekf_type() != 0) { | ||
return get_primary_IMU_index(); | ||
int8_t imu = -1; | ||
switch (ekf_type()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this be active_EKF_type() ? ie. if we are failed onto DCM in plane, then I think we shouldn't be asking the failed EKF which IMU to use
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe, I didn't modify the function I copied.
@@ -1464,6 +1464,10 @@ void AP_InertialSensor::wait_for_sample(void) | |||
*/ | |||
bool AP_InertialSensor::get_delta_angle(uint8_t i, Vector3f &delta_angle) const | |||
{ | |||
if (i >= INS_MAX_INSTANCES) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be get_gyro_count() not INS_MAX_INSTANCES I think
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds wrong to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a minimum change as it moves the i < INS_MAX_INSTANCES check from the EKF into AP_InertialSensor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, never mind, it was checking get_accel_count. Are you sure that is correct? Why would get_accel_count and get_gyro_count be different? In the case where they are different, are the gyros and accels guaranteed to be assigned contiguous indices?
@@ -1481,6 +1485,10 @@ bool AP_InertialSensor::get_delta_angle(uint8_t i, Vector3f &delta_angle) const | |||
*/ | |||
bool AP_InertialSensor::get_delta_velocity(uint8_t i, Vector3f &delta_velocity) const | |||
{ | |||
if (i >= INS_MAX_INSTANCES) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be get_accel_count()
@@ -1497,7 +1505,7 @@ bool AP_InertialSensor::get_delta_velocity(uint8_t i, Vector3f &delta_velocity) | |||
float AP_InertialSensor::get_delta_velocity_dt(uint8_t i) const | |||
{ | |||
float ret; | |||
if (_delta_velocity_valid[i]) { | |||
if (i < INS_MAX_INSTANCES && _delta_velocity_valid[i]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get_accel_count()
@@ -1512,7 +1520,7 @@ float AP_InertialSensor::get_delta_velocity_dt(uint8_t i) const | |||
float AP_InertialSensor::get_delta_angle_dt(uint8_t i) const | |||
{ | |||
float ret; | |||
if (_delta_angle_valid[i] && _delta_angle_dt[i] > 0) { | |||
if (i < INS_MAX_INSTANCES && _delta_angle_valid[i] && _delta_angle_dt[i] > 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get_gyro_count()
const AP_InertialSensor &ins = AP::ins(); | ||
|
||
if (ins_index < ins.get_gyro_count()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
keep bool return here
@@ -42,10 +42,11 @@ NavEKF2_core::NavEKF2_core(void) : | |||
} | |||
|
|||
// setup this core backend | |||
bool NavEKF2_core::setup_core(NavEKF2 *_frontend, uint8_t _imu_index, uint8_t _core_index) | |||
bool NavEKF2_core::setup_core(NavEKF2 *_frontend, uint8_t _gyro_index, uint8_t _accel_index, uint8_t _core_index) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i don't think changing setup_core() API is needed? the selections get overwritten anyway
{ | ||
if (gyro_index != _new_gyro_index) { | ||
// NOTE: theoretically, we should wait until we reach the end of the IMU buffer prior to resetting these | ||
stateStruct.gyro_bias.zero(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm concerned about a very short IMU outage (1 ms timeout for example) causing biases to reset
P[13][13] = P[12][12]; | ||
P[14][14] = P[12][12]; | ||
|
||
gcs().send_text(MAV_SEVERITY_ERROR, "EKF2 %u (g%u a%u) switched to gyro %u", (unsigned)core_index, (unsigned)gyro_index, (unsigned)accel_index, _new_gyro_index); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we need to rate limit this msg I think
// Z delta velocity bias | ||
P[15][15] = sq(INIT_ACCEL_BIAS_UNCERTAINTY * dtEkfAvg); | ||
|
||
gcs().send_text(MAV_SEVERITY_ERROR, "EKF2 %u (g%u a%u) switched to accel %u", (unsigned)core_index, (unsigned)gyro_index, (unsigned)accel_index, _new_accel_index); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should zero accel biases, and we should rate limit the msg
…if they have been healthy in the past
I have pushed changes to switch EKF cores back to their original IMU if the original IMU becomes healthy. This required a change to AP_InertialSensor to remove latching of IMU health to false. Biases are now preserved (bias covariance is not). |
do you need Feal to test fly this? If so, can you please send him a
firmware?
…On Fri, Apr 19, 2019 at 3:52 AM jschall ***@***.***> wrote:
I have pushed changes to switch EKF cores back to their original IMU if
the original IMU becomes healthy. This required a change to
AP_InertialSensor to remove latching of IMU health to false. Biases are now
preserved (bias covariance is not).
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#11139 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABDJ7Q4VKSSEYIBEIMVCISDPRDGPHANCNFSM4HGY5WGA>
.
|
This has ended up modifying more lines of code inside the estimator than I originally envisioned would be necessary, so will need a bit longer to review the changes properly. It does however raise the question as to how this is going to be tested, otherwise we could be swapping an unknown bug for a known one. |
@@ -485,4 +493,9 @@ class NavEKF2 { | |||
// new_primary - index of the ekf instance that we are about to switch to as the primary | |||
// old_primary - index of the ekf instance that we are currently using as the primary | |||
void updateLaneSwitchPosDownResetData(uint8_t new_primary, uint8_t old_primary); | |||
|
|||
uint8_t core_initial_imu[8]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we please make sure when adding new class variables that there is s description in the comments as per the rest of the code. As a minimum it should indicate what that block of variable is used for.
I think the work in here could still be merged with some work between Paul and Jon, marked as WIP |
this has been obsoleted by other changes to master to address the same issue |
This patch
TODO: