Browse Source

AP_NavEKF3: added checkLaneSwitch()

this allows the vehicle code to ask the EKF to change lanes if it is
about to do an EKF failsafe
master
Andrew Tridgell 6 years ago
parent
commit
60831c2878
  1. 40
      libraries/AP_NavEKF3/AP_NavEKF3.cpp
  2. 11
      libraries/AP_NavEKF3/AP_NavEKF3.h

40
libraries/AP_NavEKF3/AP_NavEKF3.cpp

@ -789,12 +789,52 @@ void NavEKF3::UpdateFilter(void)
updateLaneSwitchPosResetData(newPrimaryIndex, primary); updateLaneSwitchPosResetData(newPrimaryIndex, primary);
updateLaneSwitchPosDownResetData(newPrimaryIndex, primary); updateLaneSwitchPosDownResetData(newPrimaryIndex, primary);
primary = newPrimaryIndex; primary = newPrimaryIndex;
lastLaneSwitch_ms = AP_HAL::millis();
} }
} }
check_log_write(); check_log_write();
} }
/*
check if switching lanes will reduce the normalised
innovations. This is called when the vehicle code is about to
trigger an EKF failsafe, and it would like to avoid that by
using a different EKF lane
*/
void NavEKF3::checkLaneSwitch(void)
{
uint32_t now = AP_HAL::millis();
if (lastLaneSwitch_ms != 0 && now - lastLaneSwitch_ms < 5000) {
// don't switch twice in 5 seconds
return;
}
float primaryErrorScore = core[primary].errorScore();
float lowestErrorScore = primaryErrorScore;
uint8_t newPrimaryIndex = primary;
for (uint8_t coreIndex=0; coreIndex<num_cores; coreIndex++) {
if (coreIndex != primary) {
// an alternative core is available for selection only if healthy and if states have been updated on this time step
bool altCoreAvailable = core[coreIndex].healthy();
float altErrorScore = core[coreIndex].errorScore();
if (altCoreAvailable && altErrorScore < lowestErrorScore && altErrorScore < 0.9) {
newPrimaryIndex = coreIndex;
lowestErrorScore = altErrorScore;
}
}
}
// update the yaw and position reset data to capture changes due to the lane switch
if (newPrimaryIndex != primary) {
updateLaneSwitchYawResetData(newPrimaryIndex, primary);
updateLaneSwitchPosResetData(newPrimaryIndex, primary);
updateLaneSwitchPosDownResetData(newPrimaryIndex, primary);
primary = newPrimaryIndex;
lastLaneSwitch_ms = now;
gcs().send_text(MAV_SEVERITY_CRITICAL, "NavEKF3: lane switch %u", primary);
}
}
// Check basic filter health metrics and return a consolidated health status // Check basic filter health metrics and return a consolidated health status
bool NavEKF3::healthy(void) const bool NavEKF3::healthy(void) const
{ {

11
libraries/AP_NavEKF3/AP_NavEKF3.h

@ -359,6 +359,14 @@ public:
// get timing statistics structure // get timing statistics structure
void getTimingStatistics(int8_t instance, struct ekf_timing &timing) const; void getTimingStatistics(int8_t instance, struct ekf_timing &timing) const;
/*
check if switching lanes will reduce the normalised
innovations. This is called when the vehicle code is about to
trigger an EKF failsafe, and it would like to avoid that by
using a different EKF lane
*/
void checkLaneSwitch(void);
private: private:
uint8_t num_cores; // number of allocated cores uint8_t num_cores; // number of allocated cores
uint8_t primary; // current primary core uint8_t primary; // current primary core
@ -469,6 +477,9 @@ private:
// time at start of current filter update // time at start of current filter update
uint64_t imuSampleTime_us; uint64_t imuSampleTime_us;
// time of last lane switch
uint32_t lastLaneSwitch_ms;
struct { struct {
uint32_t last_function_call; // last time getLastYawYawResetAngle was called uint32_t last_function_call; // last time getLastYawYawResetAngle was called
bool core_changed; // true when a core change happened and hasn't been consumed, false otherwise bool core_changed; // true when a core change happened and hasn't been consumed, false otherwise

Loading…
Cancel
Save