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

EKF2 and EKF3 operation with no or bad compass data #13776

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
8eccc59
AP_NavEKF: Add yaw estimator class using Gaussian Sum Filter
Mar 10, 2020
c97e4e4
AP_NavEKF3: Enable use of EKF-GSF yaw estimate
Mar 10, 2020
21a1b94
AP_NavEKF3: Fix integration of GPS yaw options
Apr 11, 2020
f562253
AP_NavEKF2: Enable use of EKF-GSF yaw estimate
Mar 25, 2020
d7e222f
AP_AHRS: Enable EKF3 default airspeed to be set
Mar 10, 2020
b5a2a23
AP_AHRS: Add accessor function for EKF yaw reset request
Mar 11, 2020
c923e68
ArduPlane: Send default airspeed to estimators
Mar 10, 2020
0522af2
ArduCopter: rework ekf check to use separate yaw reset request
Mar 10, 2020
3a6ec09
RC_Channel: added lane switch RCn_OPTION=103
tridge Mar 2, 2020
be248b5
AP_AHRS: fix failure to arm when not using compass for yaw
Apr 13, 2020
c0b12b6
AP_NavEKF3: Update EK3_MAG_CAL parameter advice
Apr 17, 2020
58ac593
AP_NavEKF3: Eliminate unnecessary function call
Apr 18, 2020
735382a
AP_NavEKF: Use better type for array index
Apr 18, 2020
c5bbbc5
ArduCopter: Preserve original check criteria
Apr 18, 2020
8019cf9
AP_NavEKF3: Misc changes arising from review
Apr 18, 2020
277e284
AP_NavEKF2: Fix timer wrapping bugs
Apr 21, 2020
0dc23fe
AP_NavEKF3: Fix timer wrapping bug
Apr 21, 2020
ac645e7
AP_NavEKF2: Fix casting build error
Apr 21, 2020
c043f53
AP_NavEKF3: Restore bug fix lost during rebase
Apr 21, 2020
2fe3bab
AP_NavEKF2: removed 2nd set of imuSampleTime_ms
tridge Apr 23, 2020
5a77f9a
AP_NavEKF2: fixed typos
tridge Apr 23, 2020
151bd8a
AP_NavEKF2: fixed loss of GPS fusion
tridge Apr 23, 2020
d449028
AP_NavEKF3: fixed loss of GPS fusion
tridge Apr 23, 2020
f99dd69
AP_NavEKF2: Split GSF yaw estimator processing
Apr 23, 2020
4b7c66d
AP_NavEKF3: Split GSF yaw estimator processing
Apr 23, 2020
61cf7d3
AP_NavEKF2: rename GSF_RUN_MASK, GSF_USE_MASK, GSF_RST_MAX
rmackay9 Apr 23, 2020
4414a77
AP_NavEKF3: rename GSF_RUN_MASK, GSF_USE_MASK, GSF_RST_MAX
rmackay9 Apr 23, 2020
ab1cab6
AP_NavEKF2: minor format fix
rmackay9 Apr 23, 2020
47a247a
AP_NavEKF3: minor format fixes
rmackay9 Apr 23, 2020
2cd4a1a
AP_NavEKF: GSF getLogData and getYawData pass by reference
rmackay9 Apr 23, 2020
8de2170
AP_NavEKF2: getDataEKFGSF and getYawData pass by reference
rmackay9 Apr 23, 2020
85640aa
AP_NavEKF3: getDataEKFGSF and getYawData pass by reference
rmackay9 Apr 23, 2020
eb13b46
AP_NavEKF2: minor comment fixes
rmackay9 Apr 23, 2020
3e57b70
Copter: use static assert to simplify use of EKF_CHECK_ITERATIONS_MAX
rmackay9 Apr 23, 2020
eba70dc
AP_NavEKF: GSF white space fixes
rmackay9 Apr 23, 2020
59f4d01
AP_NavEKF2: more white space fixes
rmackay9 Apr 23, 2020
703af00
AP_NavEKF3: more white space fixes
rmackay9 Apr 23, 2020
b85465c
AP_NavEKF3: fixed in-flight yaw reset
tridge Apr 23, 2020
cd9120d
AP_NavEKF3: remove unused isDeltaYaw param from resetQuatStateYawOnly
tridge Apr 23, 2020
d3de714
AP_NavEKF2: Use unique names for EKF2 logging
Apr 23, 2020
1af9aaa
AP_NavEKF3: Use unique names for EKF2 logging
Apr 23, 2020
d2361a1
AP_NavEKF3: Add documentation for GSF logging
Apr 23, 2020
feb9c13
AP_NavEKF2: Add documentation for GSF logging
Apr 23, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 13 additions & 9 deletions ArduCopter/ekf_check.cpp
Expand Up @@ -28,6 +28,9 @@ static struct {
// should be called at 10hz
void Copter::ekf_check()
{
// ensure EKF_CHECK_ITERATIONS_MAX is at least 7
static_assert(EKF_CHECK_ITERATIONS_MAX >= 7, "EKF_CHECK_ITERATIONS_MAX must be at least 7");

// exit immediately if ekf has no origin yet - this assumes the origin can never become unset
Location temp_loc;
if (!ahrs.get_origin(temp_loc)) {
Expand All @@ -49,13 +52,16 @@ void Copter::ekf_check()
if (!ekf_check_state.bad_variance) {
// increase counter
ekf_check_state.fail_count++;
#if EKF_CHECK_ITERATIONS_MAX > 2
if (ekf_check_state.fail_count == EKF_CHECK_ITERATIONS_MAX-1) {
// we are just about to declare a EKF failsafe, ask the EKF if we can change lanes
// to resolve the issue
if (ekf_check_state.fail_count == (EKF_CHECK_ITERATIONS_MAX-2)) {
// we are two iterations away from declaring an EKF failsafe, ask the EKF if we can reset
// yaw to resolve the issue
ahrs.request_yaw_reset();
}
if (ekf_check_state.fail_count == (EKF_CHECK_ITERATIONS_MAX-1)) {
// we are just about to declare a EKF failsafe, ask the EKF if we can
// change lanes to resolve the issue
ahrs.check_lane_switch();
}
#endif
// if counter above max then trigger failsafe
if (ekf_check_state.fail_count >= EKF_CHECK_ITERATIONS_MAX) {
// limit count from climbing too high
Expand Down Expand Up @@ -112,6 +118,7 @@ bool Copter::ekf_over_threshold()
if (mag_max >= g.fs_ekf_thresh) {
over_thresh_count++;
}

bool optflow_healthy = false;
#if OPTFLOW == ENABLED
optflow_healthy = optflow.healthy();
Expand All @@ -121,11 +128,8 @@ bool Copter::ekf_over_threshold()
} else if (vel_variance >= g.fs_ekf_thresh) {
over_thresh_count++;
}
if (position_variance >= g.fs_ekf_thresh) {
over_thresh_count++;
}

if (over_thresh_count >= 2) {
if ((position_variance >= g.fs_ekf_thresh && over_thresh_count >= 1) || over_thresh_count >= 2) {
return true;
}

Expand Down
2 changes: 2 additions & 0 deletions ArduPlane/ArduPlane.cpp
Expand Up @@ -262,6 +262,8 @@ void Plane::one_second_loop()
adsb.set_stall_speed_cm(aparm.airspeed_min);
adsb.set_max_speed(aparm.airspeed_max);

ahrs.writeDefaultAirSpeed((float)((aparm.airspeed_min + aparm.airspeed_max)/2));

// sync MAVLink system ID
mavlink_system.sysid = g.sysid_this_mav;

Expand Down
3 changes: 3 additions & 0 deletions libraries/AP_AHRS/AP_AHRS.h
Expand Up @@ -186,6 +186,9 @@ class AP_AHRS

// check whether external navigation is providing yaw. Allows compass pre-arm checks to be bypassed
virtual bool is_ext_nav_used_for_yaw(void) const { return false; }

// request EKF yaw reset to try and avoid the need for an EKF lane switch or failsafe
virtual void request_yaw_reset(void) {}

// Euler angles (radians)
float roll;
Expand Down
37 changes: 37 additions & 0 deletions libraries/AP_AHRS/AP_AHRS_NavEKF.cpp
Expand Up @@ -1455,6 +1455,16 @@ void AP_AHRS_NavEKF::writeExtNavData(const Vector3f &pos, const Quaternion &quat
#endif
}

// Writes the default equivalent airspeed in m/s to be used in forward flight if a measured airspeed is required and not available.
void AP_AHRS_NavEKF::writeDefaultAirSpeed(float airspeed)
{
#if HAL_NAVEKF2_AVAILABLE
EKF2.writeDefaultAirSpeed(airspeed);
#endif
#if HAL_NAVEKF3_AVAILABLE
EKF3.writeDefaultAirSpeed(airspeed);
#endif
}

// inhibit GPS usage
uint8_t AP_AHRS_NavEKF::setInhibitGPS(void)
Expand Down Expand Up @@ -2186,6 +2196,32 @@ void AP_AHRS_NavEKF::check_lane_switch(void)
}
}

// request EKF yaw reset to try and avoid the need for an EKF lane switch or failsafe
void AP_AHRS_NavEKF::request_yaw_reset(void)
{
switch (active_EKF_type()) {
case EKFType::NONE:
break;

#if CONFIG_HAL_BOARD == HAL_BOARD_SITL
case EKFType::SITL:
break;
#endif

#if HAL_NAVEKF2_AVAILABLE
case EKFType::TWO:
EKF2.requestYawReset();
break;
#endif

#if HAL_NAVEKF3_AVAILABLE
case EKFType::THREE:
EKF3.requestYawReset();
break;
#endif
}
}

void AP_AHRS_NavEKF::Log_Write()
{
#if HAL_NAVEKF2_AVAILABLE
Expand All @@ -2212,6 +2248,7 @@ bool AP_AHRS_NavEKF::is_ext_nav_used_for_yaw(void) const
case EKFType::NONE:
#if HAL_NAVEKF3_AVAILABLE
case EKFType::THREE:
return EKF3.using_external_yaw();
#endif
#if CONFIG_HAL_BOARD == HAL_BOARD_SITL
case EKFType::SITL:
Expand Down
6 changes: 6 additions & 0 deletions libraries/AP_AHRS/AP_AHRS_NavEKF.h
Expand Up @@ -179,6 +179,9 @@ class AP_AHRS_NavEKF : public AP_AHRS_DCM {
// write body odometry measurements to the EKF
void writeBodyFrameOdom(float quality, const Vector3f &delPos, const Vector3f &delAng, float delTime, uint32_t timeStamp_ms, const Vector3f &posOffset);

// Writes the default equivalent airspeed in m/s to be used in forward flight if a measured airspeed is required and not available.
void writeDefaultAirSpeed(float airspeed);

// Write position and quaternion data from an external navigation system
void writeExtNavData(const Vector3f &pos, const Quaternion &quat, float posErr, float angErr, uint32_t timeStamp_ms, uint32_t resetTime_ms) override;

Expand Down Expand Up @@ -284,6 +287,9 @@ class AP_AHRS_NavEKF : public AP_AHRS_DCM {
// see if EKF lane switching is possible to avoid EKF failsafe
void check_lane_switch(void) override;

// request EKF yaw reset to try and avoid the need for an EKF lane switch or failsafe
void request_yaw_reset(void) override;

void Log_Write();

// check whether external navigation is providing yaw. Allows compass pre-arm checks to be bypassed
Expand Down
2 changes: 2 additions & 0 deletions libraries/AP_NavEKF/AP_Nav_Common.h
Expand Up @@ -77,3 +77,5 @@ struct ekf_timing {
float delVelDT_min;
};
void Log_EKF_Timing(const char *name, const uint8_t core, uint64_t time_us, const struct ekf_timing &timing);

#define N_MODELS_EKFGSF 5U