mirror of https://github.com/ArduPilot/ardupilot
AP_NavEKF3: make external navigation optional
This commit is contained in:
parent
8da511f039
commit
1ccda938cb
|
@ -373,6 +373,7 @@ void NavEKF3_core::setAidingMode()
|
|||
GCS_SEND_TEXT(MAV_SEVERITY_INFO, "EKF3 IMU%u is using range beacons",(unsigned)imu_index);
|
||||
GCS_SEND_TEXT(MAV_SEVERITY_INFO, "EKF3 IMU%u initial pos NE = %3.1f,%3.1f (m)",(unsigned)imu_index,(double)receiverPos.x,(double)receiverPos.y);
|
||||
GCS_SEND_TEXT(MAV_SEVERITY_INFO, "EKF3 IMU%u initial beacon pos D offset = %3.1f (m)",(unsigned)imu_index,(double)bcnPosOffsetNED.z);
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
} else if (readyToUseExtNav()) {
|
||||
// we are commencing aiding using external nav
|
||||
posResetSource = resetDataSource::EXTNAV;
|
||||
|
@ -386,6 +387,7 @@ void NavEKF3_core::setAidingMode()
|
|||
hgtMea = -extNavDataDelayed.pos.z;
|
||||
posDownObsNoise = sq(constrain_float(extNavDataDelayed.posErr, 0.1f, 10.0f));
|
||||
ResetHeight();
|
||||
#endif // EK3_FEATURE_EXTERNAL_NAV
|
||||
}
|
||||
|
||||
// clear timeout flags as a precaution to avoid triggering any additional transitions
|
||||
|
@ -505,11 +507,15 @@ bool NavEKF3_core::readyToUseRangeBeacon(void) const
|
|||
// return true if the filter is ready to use external nav data
|
||||
bool NavEKF3_core::readyToUseExtNav(void) const
|
||||
{
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
if (frontend->sources.getPosXYSource() != AP_NavEKF_Source::SourceXY::EXTNAV) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return tiltAlignComplete && extNavDataToFuse;
|
||||
#else
|
||||
return false;
|
||||
#endif // EK3_FEATURE_EXTERNAL_NAV
|
||||
}
|
||||
|
||||
// return true if we should use the compass
|
||||
|
@ -531,6 +537,7 @@ bool NavEKF3_core::use_compass(void) const
|
|||
// are we using a yaw source other than the magnetomer?
|
||||
bool NavEKF3_core::using_external_yaw(void) const
|
||||
{
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
const AP_NavEKF_Source::SourceYaw yaw_source = frontend->sources.getYawSource();
|
||||
if (yaw_source == AP_NavEKF_Source::SourceYaw::GPS || yaw_source == AP_NavEKF_Source::SourceYaw::GPS_COMPASS_FALLBACK ||
|
||||
yaw_source == AP_NavEKF_Source::SourceYaw::GSF || !use_compass()) {
|
||||
|
@ -539,6 +546,7 @@ bool NavEKF3_core::using_external_yaw(void) const
|
|||
if (yaw_source == AP_NavEKF_Source::SourceYaw::EXTNAV) {
|
||||
return ((imuSampleTime_ms - last_extnav_yaw_fusion_ms < 5000) || (imuSampleTime_ms - lastSynthYawTime_ms < 5000));
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -326,6 +326,7 @@ void NavEKF3_core::SelectMagFusion()
|
|||
// fall through to magnetometer fusion
|
||||
}
|
||||
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
// Handle case where we are using an external nav for yaw
|
||||
const bool extNavYawDataToFuse = storedExtNavYawAng.recall(extNavYawAngDataDelayed, imuDataDelayed.time_ms);
|
||||
if (yaw_source == AP_NavEKF_Source::SourceYaw::EXTNAV) {
|
||||
|
@ -353,6 +354,7 @@ void NavEKF3_core::SelectMagFusion()
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif // EK3_FEATURE_EXTERNAL_NAV
|
||||
|
||||
// If we are using the compass and the magnetometer has been unhealthy for too long we declare a timeout
|
||||
if (magHealth) {
|
||||
|
@ -905,9 +907,11 @@ bool NavEKF3_core::fuseEulerYaw(yawFusionMethod method)
|
|||
R_YAW = sq(frontend->_yawNoise);
|
||||
break;
|
||||
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
case yawFusionMethod::EXTNAV:
|
||||
R_YAW = sq(MAX(extNavYawAngDataDelayed.yawAngErr, 0.05f));
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
// determine if a 321 or 312 Euler sequence is best
|
||||
|
@ -929,9 +933,11 @@ bool NavEKF3_core::fuseEulerYaw(yawFusionMethod method)
|
|||
order = (fabsf(prevTnb[0][2]) < fabsf(prevTnb[1][2])) ? rotationOrder::TAIT_BRYAN_321 : rotationOrder::TAIT_BRYAN_312;
|
||||
break;
|
||||
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
case yawFusionMethod::EXTNAV:
|
||||
order = extNavYawAngDataDelayed.order;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
// calculate observation jacobian, predicted yaw and zero yaw body to earth rotation matrix
|
||||
|
@ -1091,9 +1097,11 @@ bool NavEKF3_core::fuseEulerYaw(yawFusionMethod method)
|
|||
innovYaw = 0.0f;
|
||||
break;
|
||||
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
case yawFusionMethod::EXTNAV:
|
||||
innovYaw = wrap_PI(yawAngPredicted - extNavYawAngDataDelayed.yawAng);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Calculate innovation variance and Kalman gains, taking advantage of the fact that only the first 4 elements in H are non zero
|
||||
|
|
|
@ -990,6 +990,7 @@ void NavEKF3_core::writeDefaultAirSpeed(float airspeed)
|
|||
|
||||
void NavEKF3_core::writeExtNavData(const Vector3f &pos, const Quaternion &quat, float posErr, float angErr, uint32_t timeStamp_ms, uint16_t delay_ms, uint32_t resetTime_ms)
|
||||
{
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
// protect against NaN
|
||||
if (pos.is_nan() || isnan(posErr)) {
|
||||
return;
|
||||
|
@ -1038,10 +1039,12 @@ void NavEKF3_core::writeExtNavData(const Vector3f &pos, const Quaternion &quat,
|
|||
extNavYawAngDataNew.time_ms = timeStamp_ms;
|
||||
storedExtNavYawAng.push(extNavYawAngDataNew);
|
||||
}
|
||||
#endif // EK3_FEATURE_EXTERNAL_NAV
|
||||
}
|
||||
|
||||
void NavEKF3_core::writeExtNavVelData(const Vector3f &vel, float err, uint32_t timeStamp_ms, uint16_t delay_ms)
|
||||
{
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
// sanity check for NaNs
|
||||
if (vel.is_nan() || isnan(err)) {
|
||||
return;
|
||||
|
@ -1067,6 +1070,7 @@ void NavEKF3_core::writeExtNavVelData(const Vector3f &vel, float err, uint32_t t
|
|||
extNavVelNew.corrected = false;
|
||||
|
||||
storedExtNavVel.push(extNavVelNew);
|
||||
#endif // EK3_FEATURE_EXTERNAL_NAV
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -474,6 +474,7 @@ bool NavEKF3_core::getVelInnovationsAndVariancesForSource(AP_NavEKF_Source::Sour
|
|||
innovations = gpsVelInnov;
|
||||
variances = gpsVelVarInnov;
|
||||
return true;
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
case AP_NavEKF_Source::SourceXY::EXTNAV:
|
||||
// check for timeouts
|
||||
if (AP_HAL::millis() - extNavVelInnovTime_ms > 500) {
|
||||
|
@ -482,6 +483,7 @@ bool NavEKF3_core::getVelInnovationsAndVariancesForSource(AP_NavEKF_Source::Sour
|
|||
innovations = extNavVelInnov;
|
||||
variances = extNavVelVarInnov;
|
||||
return true;
|
||||
#endif // EK3_FEATURE_EXTERNAL_NAV
|
||||
default:
|
||||
// variances are not available for this source
|
||||
return false;
|
||||
|
|
|
@ -35,12 +35,14 @@ void NavEKF3_core::ResetVelocity(resetDataSource velResetSource)
|
|||
stateStruct.velocity.y = gps_corrected.vel.y;
|
||||
// set the variances using the reported GPS speed accuracy
|
||||
P[5][5] = P[4][4] = sq(MAX(frontend->_gpsHorizVelNoise,gpsSpdAccuracy));
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
} else if ((imuSampleTime_ms - extNavVelMeasTime_ms < 250 && velResetSource == resetDataSource::DEFAULT) || velResetSource == resetDataSource::EXTNAV) {
|
||||
// use external nav data as the 2nd preference
|
||||
// already corrected for sensor position
|
||||
stateStruct.velocity.x = extNavVelDelayed.vel.x;
|
||||
stateStruct.velocity.y = extNavVelDelayed.vel.y;
|
||||
P[5][5] = P[4][4] = sq(extNavVelDelayed.err);
|
||||
#endif // EK3_FEATURE_EXTERNAL_NAV
|
||||
} else {
|
||||
stateStruct.velocity.x = 0.0f;
|
||||
stateStruct.velocity.y = 0.0f;
|
||||
|
@ -111,6 +113,7 @@ void NavEKF3_core::ResetPosition(resetDataSource posResetSource)
|
|||
// clear the timeout flags and counters
|
||||
rngBcnTimeout = false;
|
||||
lastRngBcnPassTime_ms = imuSampleTime_ms;
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
} else if ((imuSampleTime_ms - extNavDataDelayed.time_ms < 250 && posResetSource == resetDataSource::DEFAULT) || posResetSource == resetDataSource::EXTNAV) {
|
||||
// use external nav data as the third preference
|
||||
stateStruct.position.x = extNavDataDelayed.pos.x;
|
||||
|
@ -120,6 +123,7 @@ void NavEKF3_core::ResetPosition(resetDataSource posResetSource)
|
|||
// clear the timeout flags and counters
|
||||
posTimeout = false;
|
||||
lastPosPassTime_ms = imuSampleTime_ms;
|
||||
#endif // EK3_FEATURE_EXTERNAL_NAV
|
||||
}
|
||||
}
|
||||
for (uint8_t i=0; i<imu_buffer_length; i++) {
|
||||
|
@ -243,8 +247,10 @@ void NavEKF3_core::ResetHeight(void)
|
|||
if (inFlight && !gpsNotAvailable && frontend->sources.useVelZSource(AP_NavEKF_Source::SourceZ::GPS) &&
|
||||
gpsDataNew.have_vz) {
|
||||
stateStruct.velocity.z = gpsDataNew.vel.z;
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
} else if (inFlight && useExtNavVel && (activeHgtSource == AP_NavEKF_Source::SourceZ::EXTNAV)) {
|
||||
stateStruct.velocity.z = extNavVelDelayed.vel.z;
|
||||
#endif
|
||||
} else if (onGround) {
|
||||
stateStruct.velocity.z = 0.0f;
|
||||
}
|
||||
|
@ -260,9 +266,12 @@ void NavEKF3_core::ResetHeight(void)
|
|||
zeroCols(P,6,6);
|
||||
|
||||
// set the variances to the measurement variance
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
if (useExtNavVel) {
|
||||
P[6][6] = sq(extNavVelDelayed.err);
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
P[6][6] = sq(frontend->_gpsVertVelNoise);
|
||||
}
|
||||
}
|
||||
|
@ -414,6 +423,7 @@ void NavEKF3_core::SelectVelPosFusion()
|
|||
posVelFusionDelayed = false;
|
||||
}
|
||||
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
// Check for data at the fusion time horizon
|
||||
extNavDataToFuse = storedExtNav.recall(extNavDataDelayed, imuDataDelayed.time_ms);
|
||||
if (extNavDataToFuse) {
|
||||
|
@ -429,6 +439,7 @@ void NavEKF3_core::SelectVelPosFusion()
|
|||
// record time innovations were calculated (for timeout checks)
|
||||
extNavVelInnovTime_ms = AP_HAL::millis();
|
||||
}
|
||||
#endif // EK3_FEATURE_EXTERNAL_NAV
|
||||
|
||||
// Read GPS data from the sensor
|
||||
readGpsData();
|
||||
|
@ -460,8 +471,9 @@ void NavEKF3_core::SelectVelPosFusion()
|
|||
// Don't fuse velocity data if GPS doesn't support it
|
||||
fuseVelData = frontend->sources.useVelXYSource(AP_NavEKF_Source::SourceXY::GPS);
|
||||
fusePosData = true;
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
extNavUsedForPos = false;
|
||||
|
||||
#endif
|
||||
|
||||
// copy corrected GPS data to observation vector
|
||||
if (fuseVelData) {
|
||||
|
@ -471,14 +483,17 @@ void NavEKF3_core::SelectVelPosFusion()
|
|||
}
|
||||
velPosObs[3] = gpsDataDelayed.pos.x;
|
||||
velPosObs[4] = gpsDataDelayed.pos.y;
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
} else if (extNavDataToFuse && (PV_AidingMode == AID_ABSOLUTE) && (posxy_source == AP_NavEKF_Source::SourceXY::EXTNAV)) {
|
||||
// use external nav system for horizontal position
|
||||
extNavUsedForPos = true;
|
||||
fusePosData = true;
|
||||
velPosObs[3] = extNavDataDelayed.pos.x;
|
||||
velPosObs[4] = extNavDataDelayed.pos.y;
|
||||
#endif // EK3_FEATURE_EXTERNAL_NAV
|
||||
}
|
||||
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
// fuse external navigation velocity data if available
|
||||
// extNavVelDelayed is already corrected for sensor position
|
||||
if (extNavVelToFuse && frontend->sources.useVelXYSource(AP_NavEKF_Source::SourceXY::EXTNAV)) {
|
||||
|
@ -487,6 +502,7 @@ void NavEKF3_core::SelectVelPosFusion()
|
|||
velPosObs[1] = extNavVelDelayed.vel.y;
|
||||
velPosObs[2] = extNavVelDelayed.vel.z;
|
||||
}
|
||||
#endif
|
||||
|
||||
// we have GPS data to fuse and a request to align the yaw using the GPS course
|
||||
if (gpsYawResetRequest) {
|
||||
|
@ -513,6 +529,7 @@ void NavEKF3_core::SelectVelPosFusion()
|
|||
}
|
||||
}
|
||||
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
// check for external nav position reset
|
||||
if (extNavDataToFuse && (PV_AidingMode == AID_ABSOLUTE) && (posxy_source == AP_NavEKF_Source::SourceXY::EXTNAV) && (extNavDataDelayed.posReset || posxy_source_reset)) {
|
||||
// mark a source reset as consumed
|
||||
|
@ -522,6 +539,7 @@ void NavEKF3_core::SelectVelPosFusion()
|
|||
ResetPositionD(-hgtMea);
|
||||
}
|
||||
}
|
||||
#endif // EK3_FEATURE_EXTERNAL_NAV
|
||||
|
||||
// If we are operating without any aiding, fuse in constant position of constant
|
||||
// velocity measurements to constrain tilt drift. This assumes a non-manoeuvring
|
||||
|
@ -620,8 +638,10 @@ void NavEKF3_core::FuseVelPosNED()
|
|||
// 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[2] = sq(constrain_float(gpsSpdAccuracy, frontend->_gpsVertVelNoise, 50.0f));
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
} else if (extNavVelToFuse) {
|
||||
R_OBS[2] = R_OBS[0] = sq(constrain_float(extNavVelDelayed.err, 0.05f, 5.0f));
|
||||
#endif
|
||||
} else {
|
||||
// calculate additional error in GPS velocity caused by manoeuvring
|
||||
R_OBS[0] = sq(constrain_float(frontend->_gpsHorizVelNoise, 0.05f, 5.0f)) + sq(frontend->gpsNEVelVarAccScale * accNavMag);
|
||||
|
@ -631,8 +651,10 @@ void NavEKF3_core::FuseVelPosNED()
|
|||
// 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));
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
} else if (extNavUsedForPos) {
|
||||
R_OBS[3] = sq(constrain_float(extNavDataDelayed.posErr, 0.01f, 10.0f));
|
||||
#endif
|
||||
} else {
|
||||
R_OBS[3] = sq(constrain_float(frontend->_gpsHorizPosNoise, 0.1f, 10.0f)) + sq(posErr);
|
||||
}
|
||||
|
@ -641,9 +663,12 @@ void NavEKF3_core::FuseVelPosNED()
|
|||
// 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 performance
|
||||
// plus a margin for manoeuvres. It is better to reject GPS horizontal velocity errors early
|
||||
float obs_data_chk;
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
if (extNavVelToFuse) {
|
||||
obs_data_chk = sq(constrain_float(extNavVelDelayed.err, 0.05f, 5.0f)) + sq(frontend->extNavVelVarAccScale * accNavMag);
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
obs_data_chk = sq(constrain_float(frontend->_gpsHorizVelNoise, 0.05f, 5.0f)) + sq(frontend->gpsNEVelVarAccScale * accNavMag);
|
||||
}
|
||||
R_OBS_DATA_CHECKS[0] = R_OBS_DATA_CHECKS[1] = R_OBS_DATA_CHECKS[2] = obs_data_chk;
|
||||
|
@ -984,7 +1009,9 @@ void NavEKF3_core::selectHeightForFusion()
|
|||
baroDataToFuse = storedBaro.recall(baroDataDelayed, imuDataDelayed.time_ms);
|
||||
|
||||
bool rangeFinderDataIsFresh = (imuSampleTime_ms - rngValidMeaTime_ms < 500);
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
const bool extNavDataIsFresh = (imuSampleTime_ms - extNavMeasTime_ms < 500);
|
||||
#endif
|
||||
// select height source
|
||||
if ((frontend->sources.getPosZSource() == AP_NavEKF_Source::SourceZ::RANGEFINDER) && _rng && rangeFinderDataIsFresh) {
|
||||
// user has specified the range finder as a primary height source
|
||||
|
@ -1033,16 +1060,22 @@ void NavEKF3_core::selectHeightForFusion()
|
|||
activeHgtSource = AP_NavEKF_Source::SourceZ::GPS;
|
||||
} else if ((frontend->sources.getPosZSource() == AP_NavEKF_Source::SourceZ::BEACON) && validOrigin && rngBcnGoodToAlign) {
|
||||
activeHgtSource = AP_NavEKF_Source::SourceZ::BEACON;
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
} else if ((frontend->sources.getPosZSource() == AP_NavEKF_Source::SourceZ::EXTNAV) && extNavDataIsFresh) {
|
||||
activeHgtSource = AP_NavEKF_Source::SourceZ::EXTNAV;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Use Baro alt as a fallback if we lose range finder, GPS, external nav or Beacon
|
||||
bool lostRngHgt = ((activeHgtSource == AP_NavEKF_Source::SourceZ::RANGEFINDER) && !rangeFinderDataIsFresh);
|
||||
bool lostGpsHgt = ((activeHgtSource == AP_NavEKF_Source::SourceZ::GPS) && ((imuSampleTime_ms - lastTimeGpsReceived_ms) > 2000));
|
||||
bool lostExtNavHgt = ((activeHgtSource == AP_NavEKF_Source::SourceZ::EXTNAV) && !extNavDataIsFresh);
|
||||
bool lostRngBcnHgt = ((activeHgtSource == AP_NavEKF_Source::SourceZ::BEACON) && ((imuSampleTime_ms - rngBcnDataDelayed.time_ms) > 2000));
|
||||
if (lostRngHgt || lostGpsHgt || lostExtNavHgt || lostRngBcnHgt) {
|
||||
bool fallback_to_baro = lostRngHgt || lostGpsHgt || lostRngBcnHgt;
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
bool lostExtNavHgt = ((activeHgtSource == AP_NavEKF_Source::SourceZ::EXTNAV) && !extNavDataIsFresh);
|
||||
fallback_to_baro |= lostExtNavHgt;
|
||||
#endif
|
||||
if (fallback_to_baro) {
|
||||
activeHgtSource = AP_NavEKF_Source::SourceZ::BARO;
|
||||
}
|
||||
|
||||
|
@ -1073,12 +1106,15 @@ void NavEKF3_core::selectHeightForFusion()
|
|||
}
|
||||
|
||||
// Select the height measurement source
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
if (extNavDataToFuse && (activeHgtSource == AP_NavEKF_Source::SourceZ::EXTNAV)) {
|
||||
hgtMea = -extNavDataDelayed.pos.z;
|
||||
velPosObs[5] = -hgtMea;
|
||||
posDownObsNoise = sq(constrain_float(extNavDataDelayed.posErr, 0.1f, 10.0f));
|
||||
fuseHgtData = true;
|
||||
} else if (rangeDataToFuse && (activeHgtSource == AP_NavEKF_Source::SourceZ::RANGEFINDER)) {
|
||||
} else
|
||||
#endif // EK3_FEATURE_EXTERNAL_NAV
|
||||
if (rangeDataToFuse && (activeHgtSource == AP_NavEKF_Source::SourceZ::RANGEFINDER)) {
|
||||
// using range finder data
|
||||
// correct for tilt using a flat earth model
|
||||
if (prevTnb.c.z >= 0.7) {
|
||||
|
|
|
@ -136,6 +136,7 @@ bool NavEKF3_core::setup_core(uint8_t _imu_index, uint8_t _core_index)
|
|||
if(dal.beacon() && !storedRangeBeacon.init(imu_buffer_length+1)) {
|
||||
return false;
|
||||
}
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
if (frontend->sources.ext_nav_enabled() && !storedExtNav.init(extnav_buffer_length)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -145,6 +146,7 @@ bool NavEKF3_core::setup_core(uint8_t _imu_index, uint8_t _core_index)
|
|||
if(frontend->sources.ext_nav_enabled() && !storedExtNavYawAng.init(extnav_buffer_length)) {
|
||||
return false;
|
||||
}
|
||||
#endif // EK3_FEATURE_EXTERNAL_NAV
|
||||
if(!storedIMU.init(imu_buffer_length)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -393,6 +395,7 @@ void NavEKF3_core::InitialiseVariables()
|
|||
memset(&yawAngDataNew, 0, sizeof(yawAngDataNew));
|
||||
memset(&yawAngDataDelayed, 0, sizeof(yawAngDataDelayed));
|
||||
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
// external nav data fusion
|
||||
extNavDataDelayed = {};
|
||||
extNavMeasTime_ms = 0;
|
||||
|
@ -403,6 +406,7 @@ void NavEKF3_core::InitialiseVariables()
|
|||
extNavVelToFuse = false;
|
||||
useExtNavVel = false;
|
||||
extNavVelMeasTime_ms = 0;
|
||||
#endif
|
||||
|
||||
// zero data buffers
|
||||
storedIMU.reset();
|
||||
|
@ -416,8 +420,10 @@ void NavEKF3_core::InitialiseVariables()
|
|||
storedBodyOdm.reset();
|
||||
storedWheelOdm.reset();
|
||||
#endif
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
storedExtNav.reset();
|
||||
storedExtNavVel.reset();
|
||||
#endif
|
||||
|
||||
// initialise pre-arm message
|
||||
dal.snprintf(prearm_fail_string, sizeof(prearm_fail_string), "EKF3 still initialising");
|
||||
|
@ -458,7 +464,9 @@ void NavEKF3_core::InitialiseVariablesMag()
|
|||
magFieldLearned = false;
|
||||
storedMag.reset();
|
||||
storedYawAng.reset();
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
storedExtNavYawAng.reset();
|
||||
#endif
|
||||
needMagBodyVarReset = false;
|
||||
needEarthBodyVarReset = false;
|
||||
}
|
||||
|
|
|
@ -1316,6 +1316,7 @@ private:
|
|||
bool onGroundNotMoving; // true when on the ground and not moving
|
||||
uint32_t lastMoveCheckLogTime_ms; // last time the movement check data was logged (msec)
|
||||
|
||||
#if EK3_FEATURE_EXTERNAL_NAV
|
||||
// external navigation fusion
|
||||
EKF_obs_buffer_t<ext_nav_elements> storedExtNav; // external navigation data buffer
|
||||
ext_nav_elements extNavDataDelayed; // External nav at the fusion time horizon
|
||||
|
@ -1327,13 +1328,14 @@ private:
|
|||
ext_nav_vel_elements extNavVelDelayed; // external navigation velocity data at the fusion time horizon. Already corrected for sensor position
|
||||
uint32_t extNavVelMeasTime_ms; // time external navigation velocity measurements were accepted for input to the data buffer (msec)
|
||||
bool extNavVelToFuse; // true when there is new external navigation velocity to fuse
|
||||
bool useExtNavVel; // true if external nav velocity should be used
|
||||
Vector3f extNavVelInnov; // external nav velocity innovations
|
||||
Vector3f extNavVelVarInnov; // external nav velocity innovation variances
|
||||
uint32_t extNavVelInnovTime_ms; // system time that external nav velocity innovations were recorded (to detect timeouts)
|
||||
EKF_obs_buffer_t<yaw_elements> storedExtNavYawAng; // external navigation yaw angle buffer
|
||||
yaw_elements extNavYawAngDataDelayed; // external navigation yaw angle at the fusion time horizon
|
||||
uint32_t last_extnav_yaw_fusion_ms; // system time that external nav yaw was last fused
|
||||
#endif // EK3_FEATURE_EXTERNAL_NAV
|
||||
bool useExtNavVel; // true if external nav velocity should be used
|
||||
|
||||
// flags indicating severe numerical errors in innovation variance calculation for different fusion operations
|
||||
struct {
|
||||
|
|
|
@ -10,4 +10,12 @@
|
|||
#define EK3_FEATURE_ALL APM_BUILD_TYPE(APM_BUILD_AP_DAL_Standalone) || APM_BUILD_TYPE(APM_BUILD_Replay)
|
||||
|
||||
// body odomotry (which includes wheel encoding) on rover or 2M boards
|
||||
#ifndef EK3_FEATURE_BODY_ODOM
|
||||
#define EK3_FEATURE_BODY_ODOM EK3_FEATURE_ALL || APM_BUILD_TYPE(APM_BUILD_Rover) || BOARD_FLASH_SIZE > 1024
|
||||
#endif
|
||||
|
||||
// external navigation on 2M boards
|
||||
#ifndef EK3_FEATURE_EXTERNAL_NAV
|
||||
#define EK3_FEATURE_EXTERNAL_NAV EK3_FEATURE_ALL || BOARD_FLASH_SIZE > 1024
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue