mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-01-03 14:38:30 -04:00
AP_NavEKF2: use receiver estimated accuracy
Adjust the GPS observation noise based on receiver accuracy output if available.
This commit is contained in:
parent
dddc213836
commit
6be9eaa524
@ -371,8 +371,8 @@ void NavEKF2_core::readGpsData()
|
|||||||
// read the NED velocity from the GPS
|
// read the NED velocity from the GPS
|
||||||
gpsDataNew.vel = _ahrs->get_gps().velocity();
|
gpsDataNew.vel = _ahrs->get_gps().velocity();
|
||||||
|
|
||||||
// Use the speed accuracy from the GPS if available, otherwise set it to zero.
|
// Use the speed and position accuracy from the GPS if available, otherwise set it to zero.
|
||||||
// Apply a decaying envelope filter with a 5 second time constant to the raw speed accuracy data
|
// Apply a decaying envelope filter with a 5 second time constant to the raw accuracy data
|
||||||
float alpha = constrain_float(0.0002f * (lastTimeGpsReceived_ms - secondLastGpsTime_ms),0.0f,1.0f);
|
float alpha = constrain_float(0.0002f * (lastTimeGpsReceived_ms - secondLastGpsTime_ms),0.0f,1.0f);
|
||||||
gpsSpdAccuracy *= (1.0f - alpha);
|
gpsSpdAccuracy *= (1.0f - alpha);
|
||||||
float gpsSpdAccRaw;
|
float gpsSpdAccRaw;
|
||||||
@ -380,6 +380,15 @@ void NavEKF2_core::readGpsData()
|
|||||||
gpsSpdAccuracy = 0.0f;
|
gpsSpdAccuracy = 0.0f;
|
||||||
} else {
|
} else {
|
||||||
gpsSpdAccuracy = MAX(gpsSpdAccuracy,gpsSpdAccRaw);
|
gpsSpdAccuracy = MAX(gpsSpdAccuracy,gpsSpdAccRaw);
|
||||||
|
gpsSpdAccuracy = MIN(gpsSpdAccuracy,50.0f);
|
||||||
|
}
|
||||||
|
gpsPosAccuracy *= (1.0f - alpha);
|
||||||
|
float gpsPosAccRaw;
|
||||||
|
if (!_ahrs->get_gps().horizontal_accuracy(gpsPosAccRaw)) {
|
||||||
|
gpsPosAccuracy = 0.0f;
|
||||||
|
} else {
|
||||||
|
gpsPosAccuracy = MAX(gpsPosAccuracy,gpsPosAccRaw);
|
||||||
|
gpsPosAccuracy = MIN(gpsPosAccuracy,100.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if we have enough GPS satellites and increase the gps noise scaler if we don't
|
// check if we have enough GPS satellites and increase the gps noise scaler if we don't
|
||||||
|
@ -209,7 +209,6 @@ void NavEKF2_core::FuseVelPosNED()
|
|||||||
uint8_t obsIndex;
|
uint8_t obsIndex;
|
||||||
|
|
||||||
// declare variables used by state and covariance update calculations
|
// declare variables used by state and covariance update calculations
|
||||||
float posErr;
|
|
||||||
Vector6 R_OBS; // Measurement variances used for fusion
|
Vector6 R_OBS; // Measurement variances used for fusion
|
||||||
Vector6 R_OBS_DATA_CHECKS; // Measurement variances used for data checks only
|
Vector6 R_OBS_DATA_CHECKS; // Measurement variances used for data checks only
|
||||||
Vector6 observation;
|
Vector6 observation;
|
||||||
@ -236,7 +235,7 @@ void NavEKF2_core::FuseVelPosNED()
|
|||||||
observation[5] = -hgtMea;
|
observation[5] = -hgtMea;
|
||||||
|
|
||||||
// calculate additional error in GPS position caused by manoeuvring
|
// calculate additional error in GPS position caused by manoeuvring
|
||||||
posErr = frontend->gpsPosVarAccScale * accNavMag;
|
float posErr = frontend->gpsPosVarAccScale * accNavMag;
|
||||||
|
|
||||||
// estimate the GPS Velocity, GPS horiz position and height measurement variances.
|
// estimate the GPS Velocity, GPS horiz position and height measurement variances.
|
||||||
// Use different errors if operating without external aiding using an assumed position or velocity of zero
|
// Use different errors if operating without external aiding using an assumed position or velocity of zero
|
||||||
@ -255,7 +254,7 @@ void NavEKF2_core::FuseVelPosNED()
|
|||||||
for (uint8_t i=0; i<=2; i++) R_OBS_DATA_CHECKS[i] = R_OBS[i];
|
for (uint8_t i=0; i<=2; i++) R_OBS_DATA_CHECKS[i] = R_OBS[i];
|
||||||
} else {
|
} else {
|
||||||
if (gpsSpdAccuracy > 0.0f) {
|
if (gpsSpdAccuracy > 0.0f) {
|
||||||
// use GPS receivers reported speed accuracy if available and floor at value set by gps noise parameter
|
// use GPS receivers reported speed accuracy if available and floor at value set by GPS velocity noise parameter
|
||||||
R_OBS[0] = sq(constrain_float(gpsSpdAccuracy, frontend->_gpsHorizVelNoise, 50.0f));
|
R_OBS[0] = sq(constrain_float(gpsSpdAccuracy, frontend->_gpsHorizVelNoise, 50.0f));
|
||||||
R_OBS[2] = sq(constrain_float(gpsSpdAccuracy, frontend->_gpsVertVelNoise, 50.0f));
|
R_OBS[2] = sq(constrain_float(gpsSpdAccuracy, frontend->_gpsVertVelNoise, 50.0f));
|
||||||
} else {
|
} else {
|
||||||
@ -264,11 +263,16 @@ void NavEKF2_core::FuseVelPosNED()
|
|||||||
R_OBS[2] = sq(constrain_float(frontend->_gpsVertVelNoise, 0.05f, 5.0f)) + sq(frontend->gpsDVelVarAccScale * accNavMag);
|
R_OBS[2] = sq(constrain_float(frontend->_gpsVertVelNoise, 0.05f, 5.0f)) + sq(frontend->gpsDVelVarAccScale * accNavMag);
|
||||||
}
|
}
|
||||||
R_OBS[1] = R_OBS[0];
|
R_OBS[1] = R_OBS[0];
|
||||||
|
// Use GPS reported position accuracy if available and floor at value set by GPS position noise parameter
|
||||||
|
if (gpsPosAccuracy > 0.0f) {
|
||||||
|
R_OBS[3] = sq(constrain_float(gpsPosAccuracy, frontend->_gpsHorizPosNoise, 100.0f));
|
||||||
|
} else {
|
||||||
|
R_OBS[3] = sq(constrain_float(frontend->_gpsHorizPosNoise, 0.1f, 10.0f)) + sq(posErr);
|
||||||
|
}
|
||||||
|
R_OBS[4] = R_OBS[3];
|
||||||
// For data integrity checks we use the same measurement variances as used to calculate the Kalman gains for all measurements except GPS horizontal velocity
|
// For data integrity checks we use the same measurement variances as used to calculate the Kalman gains for all measurements except GPS horizontal velocity
|
||||||
// For horizontal GPs velocity we don't want the acceptance radius to increase with reported GPS accuracy so we use a value based on best GPs perfomrance
|
// For horizontal GPs velocity we don't want the acceptance radius to increase with reported GPS accuracy so we use a value based on best GPs perfomrance
|
||||||
// plus a margin for manoeuvres. It is better to reject GPS horizontal velocity errors early
|
// plus a margin for manoeuvres. It is better to reject GPS horizontal velocity errors early
|
||||||
R_OBS[3] = sq(constrain_float(frontend->_gpsHorizPosNoise, 0.1f, 10.0f)) + sq(posErr);
|
|
||||||
R_OBS[4] = R_OBS[3];
|
|
||||||
for (uint8_t i=0; i<=2; i++) R_OBS_DATA_CHECKS[i] = sq(constrain_float(frontend->_gpsHorizVelNoise, 0.05f, 5.0f)) + sq(frontend->gpsNEVelVarAccScale * accNavMag);
|
for (uint8_t i=0; i<=2; i++) R_OBS_DATA_CHECKS[i] = sq(constrain_float(frontend->_gpsHorizVelNoise, 0.05f, 5.0f)) + sq(frontend->gpsNEVelVarAccScale * accNavMag);
|
||||||
}
|
}
|
||||||
R_OBS[5] = posDownObsNoise;
|
R_OBS[5] = posDownObsNoise;
|
||||||
|
@ -197,6 +197,7 @@ void NavEKF2_core::InitialiseVariables()
|
|||||||
touchdownExpectedSet_ms = 0;
|
touchdownExpectedSet_ms = 0;
|
||||||
expectGndEffectTouchdown = false;
|
expectGndEffectTouchdown = false;
|
||||||
gpsSpdAccuracy = 0.0f;
|
gpsSpdAccuracy = 0.0f;
|
||||||
|
gpsPosAccuracy = 0.0f;
|
||||||
baroHgtOffset = 0.0f;
|
baroHgtOffset = 0.0f;
|
||||||
yawResetAngle = 0.0f;
|
yawResetAngle = 0.0f;
|
||||||
lastYawReset_ms = 0;
|
lastYawReset_ms = 0;
|
||||||
|
@ -708,7 +708,8 @@ private:
|
|||||||
bool prevIsAiding; // isAiding from previous frame
|
bool prevIsAiding; // isAiding from previous frame
|
||||||
struct Location EKF_origin; // LLH origin of the NED axis system - do not change unless filter is reset
|
struct Location EKF_origin; // LLH origin of the NED axis system - do not change unless filter is reset
|
||||||
bool validOrigin; // true when the EKF origin is valid
|
bool validOrigin; // true when the EKF origin is valid
|
||||||
float gpsSpdAccuracy; // estimated speed accuracy in m/s returned by the UBlox GPS receiver
|
float gpsSpdAccuracy; // estimated speed accuracy in m/s returned by the GPS receiver
|
||||||
|
float gpsPosAccuracy; // estimated position accuracy in m returned by the GPS receiver
|
||||||
uint32_t lastGpsVelFail_ms; // time of last GPS vertical velocity consistency check fail
|
uint32_t lastGpsVelFail_ms; // time of last GPS vertical velocity consistency check fail
|
||||||
uint32_t lastGpsAidBadTime_ms; // time in msec gps aiding was last detected to be bad
|
uint32_t lastGpsAidBadTime_ms; // time in msec gps aiding was last detected to be bad
|
||||||
float posDownAtTakeoff; // flight vehicle vertical position at arming used as a reference point
|
float posDownAtTakeoff; // flight vehicle vertical position at arming used as a reference point
|
||||||
|
Loading…
Reference in New Issue
Block a user