AP_NavEKF: Allow user to select preflight GPS checks
This commit is contained in:
parent
cdae84aec1
commit
21e4910149
@ -384,6 +384,12 @@ const AP_Param::GroupInfo NavEKF::var_info[] PROGMEM = {
|
||||
// @User: Advanced
|
||||
AP_GROUPINFO("ALT_SOURCE", 32, NavEKF, _altSource, 1),
|
||||
|
||||
// @Param: GPS_CHECK
|
||||
// @DisplayName: GPS preflight check
|
||||
// @Description: 1 byte bitmap of GPS preflight checks to perform. Set to 0 to bypass all checks. Set to 255 perform all checks. Set to 1 to check just the number of satellites and HDoP. Set to 10 for the best checking that will still allow checks to pass when the copter is moving, eg launch from a boat.
|
||||
// @Bitmask: 0:NSats,1:HDoP,2:speed error,3:horiz pos error,4:yaw error,5:pos drift,6:vert speed,7:horiz speed
|
||||
// @User: Advanced
|
||||
AP_GROUPINFO("GPS_CHECK", 33, NavEKF, _gpsCheck, 10),
|
||||
AP_GROUPEND
|
||||
};
|
||||
|
||||
@ -5211,7 +5217,7 @@ bool NavEKF::calcGpsGoodToAlign(void)
|
||||
}
|
||||
|
||||
// fail if velocity difference or reported speed accuracy greater than threshold
|
||||
bool gpsVelFail = (velDiffAbs > 1.0f) || (gpsSpdAccuracy > 1.0f);
|
||||
bool gpsVelFail = ((velDiffAbs > 1.0f) || (gpsSpdAccuracy > 1.0f)) && (_gpsCheck & MASK_GPS_SPD_ERR);
|
||||
|
||||
if (velDiffAbs > 1.0f) {
|
||||
hal.util->snprintf(prearm_fail_string,
|
||||
@ -5225,14 +5231,14 @@ bool NavEKF::calcGpsGoodToAlign(void)
|
||||
}
|
||||
|
||||
// fail if not enough sats
|
||||
bool numSatsFail = _ahrs->get_gps().num_sats() < 6;
|
||||
bool numSatsFail = (_ahrs->get_gps().num_sats() < 6) && (_gpsCheck & MASK_GPS_NSATS);
|
||||
if (numSatsFail) {
|
||||
hal.util->snprintf(prearm_fail_string, sizeof(prearm_fail_string),
|
||||
"GPS numsats %u (needs 6)", _ahrs->get_gps().num_sats());
|
||||
}
|
||||
|
||||
// fail if satellite geometry is poor
|
||||
bool hdopFail = _ahrs->get_gps().get_hdop() > 250;
|
||||
bool hdopFail = (_ahrs->get_gps().get_hdop() > 250) && (_gpsCheck & MASK_GPS_HDOP);
|
||||
if (hdopFail) {
|
||||
hal.util->snprintf(prearm_fail_string, sizeof(prearm_fail_string),
|
||||
"GPS HDOP %.1f (needs 2.5)", (double)(0.01f * _ahrs->get_gps().get_hdop()));
|
||||
@ -5242,7 +5248,7 @@ bool NavEKF::calcGpsGoodToAlign(void)
|
||||
float hAcc = 0.0f;
|
||||
bool hAccFail;
|
||||
if (_ahrs->get_gps().horizontal_accuracy(hAcc)) {
|
||||
hAccFail = hAcc > 5.0f;
|
||||
hAccFail = (hAcc > 5.0f) && (_gpsCheck & MASK_GPS_POS_ERR);
|
||||
} else {
|
||||
hAccFail = false;
|
||||
}
|
||||
@ -5269,7 +5275,7 @@ bool NavEKF::calcGpsGoodToAlign(void)
|
||||
// fail if magnetometer innovations are outside limits indicating bad yaw
|
||||
// with bad yaw we are unable to use GPS
|
||||
bool yawFail;
|
||||
if (magTestRatio.x > 1.0f || magTestRatio.y > 1.0f) {
|
||||
if ((magTestRatio.x > 1.0f || magTestRatio.y > 1.0f) && (_gpsCheck & MASK_GPS_YAW_ERR)) {
|
||||
yawFail = true;
|
||||
} else {
|
||||
yawFail = false;
|
||||
@ -5297,7 +5303,7 @@ bool NavEKF::calcGpsGoodToAlign(void)
|
||||
gpsDriftNE = min(gpsDriftNE,10.0f);
|
||||
// Fail if more than 3 metres drift after filtering whilst pre-armed when the vehicle is supposed to be stationary
|
||||
// This corresponds to a maximum acceptable average drift rate of 0.3 m/s or single glitch event of 3m
|
||||
bool gpsDriftFail = gpsDriftNE > 3.0f && !vehicleArmed;
|
||||
bool gpsDriftFail = (gpsDriftNE > 3.0f) && !vehicleArmed && (_gpsCheck & MASK_GPS_POS_DRIFT);
|
||||
if (gpsDriftFail) {
|
||||
hal.util->snprintf(prearm_fail_string,
|
||||
sizeof(prearm_fail_string),
|
||||
@ -5310,7 +5316,7 @@ bool NavEKF::calcGpsGoodToAlign(void)
|
||||
// check that the average vertical GPS velocity is close to zero
|
||||
gpsVertVelFilt = 0.1f * velNED.z + 0.9f * gpsVertVelFilt;
|
||||
gpsVertVelFilt = constrain_float(gpsVertVelFilt,-10.0f,10.0f);
|
||||
gpsVertVelFail = (fabsf(gpsVertVelFilt) > 0.3f);
|
||||
gpsVertVelFail = (fabsf(gpsVertVelFilt) > 0.3f) && (_gpsCheck & MASK_GPS_VERT_SPD);
|
||||
} else if ((_fusionModeGPS == 0) && !_ahrs->get_gps().have_vertical_velocity()) {
|
||||
// If the EKF settings require vertical GPS velocity and the receiver is not outputting it, then fail
|
||||
gpsVertVelFail = true;
|
||||
@ -5328,7 +5334,7 @@ bool NavEKF::calcGpsGoodToAlign(void)
|
||||
if (!vehicleArmed) {
|
||||
gpsHorizVelFilt = 0.1f * pythagorous2(velNED.x,velNED.y) + 0.9f * gpsHorizVelFilt;
|
||||
gpsHorizVelFilt = constrain_float(gpsHorizVelFilt,-10.0f,10.0f);
|
||||
gpsHorizVelFail = (fabsf(gpsHorizVelFilt) > 0.3f);
|
||||
gpsHorizVelFail = (fabsf(gpsHorizVelFilt) > 0.3f) && (_gpsCheck & MASK_GPS_HORIZ_SPD);
|
||||
} else {
|
||||
gpsHorizVelFail = false;
|
||||
}
|
||||
|
@ -39,6 +39,15 @@
|
||||
#include <systemlib/perf_counter.h>
|
||||
#endif
|
||||
|
||||
// GPS pre-flight check bit locations
|
||||
#define MASK_GPS_NSATS (1<<0)
|
||||
#define MASK_GPS_HDOP (1<<1)
|
||||
#define MASK_GPS_SPD_ERR (1<<2)
|
||||
#define MASK_GPS_POS_ERR (1<<3)
|
||||
#define MASK_GPS_YAW_ERR (1<<4)
|
||||
#define MASK_GPS_POS_DRIFT (1<<5)
|
||||
#define MASK_GPS_VERT_SPD (1<<6)
|
||||
#define MASK_GPS_HORIZ_SPD (1<<7)
|
||||
|
||||
class AP_AHRS;
|
||||
|
||||
@ -503,6 +512,7 @@ private:
|
||||
AP_Float _maxFlowRate; // Maximum flow rate magnitude that will be accepted by the filter
|
||||
AP_Int8 _fallback; // EKF-to-DCM fallback strictness. 0 = trust EKF more, 1 = fallback more conservatively.
|
||||
AP_Int8 _altSource; // Primary alt source during optical flow navigation. 0 = use Baro, 1 = use range finder.
|
||||
AP_Int8 _gpsCheck; // Bitmask controlling which preflight GPS checks are bypassed
|
||||
|
||||
// Tuning parameters
|
||||
const float gpsNEVelVarAccScale; // Scale factor applied to NE velocity measurement variance due to manoeuvre acceleration
|
||||
|
Loading…
Reference in New Issue
Block a user