Ref T773, use "on ground" cached elevations for situations in simulator and airspace monitor

This commit is contained in:
Klaus Basan
2020-02-18 03:10:31 +01:00
committed by Mat Sutcliffe
parent 55b28e24a6
commit 4120a2c77d
2 changed files with 94 additions and 51 deletions

View File

@@ -1358,8 +1358,9 @@ namespace BlackCore
if (callsign.isEmpty()) { return situation; } if (callsign.isEmpty()) { return situation; }
CAircraftSituation correctedSituation(allowTestOffset ? this->addTestAltitudeOffsetToSituation(situation) : situation); CAircraftSituation correctedSituation(allowTestOffset ? this->addTestAltitudeOffsetToSituation(situation) : situation);
bool haveRequestedElevation = false; bool canLikelySkipNearGround = correctedSituation.canLikelySkipNearGroundInterpolation();
const bool canLikelySkipNearGround = correctedSituation.canLikelySkipNearGroundInterpolation(); bool needToRequestElevation = false;
if (!correctedSituation.hasGroundElevation()) if (!correctedSituation.hasGroundElevation())
{ {
// set a defined state // set a defined state
@@ -1368,20 +1369,35 @@ namespace BlackCore
if (!canLikelySkipNearGround) if (!canLikelySkipNearGround)
{ {
// fetch from cache or request // fetch from cache or request
const CAircraftSituationList situations = this->remoteAircraftSituations(callsign); const CAircraftSituationChange changesBeforeStoring = this->remoteAircraftSituationChanges(callsign).frontOrDefault();
const CAircraftSituation situationWithElv = situations.findCLosestElevationWithinRange(correctedSituation, correctedSituation.getDistancePerTime(100, CElevationPlane::singlePointRadius()));
if (!situationWithElv.getGroundElevation().isNull()) // Check if we can bail out and ignore all elevation handling
//
// rational:
// a) elevation handling is expensive, and might even requests elevation from sim.
// b) elevations not needed pollute the cache with "useless" values
//
if (!changesBeforeStoring.isNull())
{ {
// from nearby situations of own aircraft canLikelySkipNearGround = changesBeforeStoring.isConstAscending();
correctedSituation.transferGroundElevation(situationWithElv); }
if (!canLikelySkipNearGround)
{
const CAircraftSituationList situationsBeforeStoring = this->remoteAircraftSituations(callsign);
const CAircraftSituation situationWithElvBeforeStoring = situationsBeforeStoring.findClosestElevationWithinRange(correctedSituation, correctedSituation.getDistancePerTime(100, CElevationPlane::singlePointRadius()));
if (!situationWithElvBeforeStoring.getGroundElevation().isNull())
{
// from nearby situations of own aircraft, data was transferred above
// we use transfer first as it is slightly faster as cache
} }
else else
{ {
// from cache // from cache
const CLength distance(correctedSituation.getDistancePerTime250ms(CElevationPlane::singlePointRadius())); // distance per ms const CLength distance(correctedSituation.getDistancePerTime250ms(CElevationPlane::singlePointRadius())); // distance per ms
const CElevationPlane ep = this->findClosestElevationWithinRangeOrRequest(correctedSituation, distance, callsign); const CElevationPlane ep = this->findClosestElevationWithinRange(correctedSituation, distance);
haveRequestedElevation = ep.isNull(); // NULL means we requested needToRequestElevation = ep.isNull();
Q_ASSERT_X(haveRequestedElevation || !ep.getRadius().isNull(), Q_FUNC_INFO, "null radius"); Q_ASSERT_X(needToRequestElevation || !ep.getRadius().isNull(), Q_FUNC_INFO, "null radius");
// also can handle NULL elevations // also can handle NULL elevations
correctedSituation.setGroundElevation(ep, CAircraftSituation::FromCache); correctedSituation.setGroundElevation(ep, CAircraftSituation::FromCache);
@@ -1389,14 +1405,28 @@ namespace BlackCore
// we have a new situation, so we try to get the elevation // we have a new situation, so we try to get the elevation
// so far we have requested it, but we set it upfront either by // so far we have requested it, but we set it upfront either by
// a) average value from other planes in the vicinity or //
// a) average value from other planes in the vicinity (cache, not moving) or
// b) by extrapolating // b) by extrapolating
// //
// if we would NOT preset it, we could end up with oscillation // if we would NOT preset it, we could end up with oscillation
// //
if (!correctedSituation.hasGroundElevation()) if (!correctedSituation.hasGroundElevation())
{ {
const CElevationPlane averagePlane = this->averageElevationOfNonMovingAircraft(situation, CElevationPlane::majorAirportRadius(), 2); // average elevation
// 1) from cache
// 2) from planes on ground not moving
bool fromNonMoving = false;
bool triedExtrapolation = false;
bool couldNotExtrapolate = false;
CElevationPlane averagePlane = this->averageElevationOfOnGroundAircraft(situation, CElevationPlane::majorAirportRadius(), 2, 3);
if (averagePlane.isNull())
{
averagePlane = this->averageElevationOfNonMovingAircraft(situation, CElevationPlane::majorAirportRadius(), 2);
}
// do we have a elevation yet?
if (!averagePlane.isNull()) if (!averagePlane.isNull())
{ {
correctedSituation.setGroundElevation(averagePlane, CAircraftSituation::Average); correctedSituation.setGroundElevation(averagePlane, CAircraftSituation::Average);
@@ -1404,18 +1434,30 @@ namespace BlackCore
else else
{ {
// values before updating (i.e. "storing") so the new situation is not yet considered // values before updating (i.e. "storing") so the new situation is not yet considered
const CAircraftSituationList oldSituations = this->remoteAircraftSituations(callsign); if (situationsBeforeStoring.size() > 1)
const CAircraftSituationChangeList oldChanges = this->remoteAircraftSituationChanges(callsign);
if (oldSituations.size() > 1)
{ {
const bool extrapolated = correctedSituation.extrapolateElevation(oldSituations[0], oldSituations[1], oldChanges.frontOrDefault()); const bool extrapolated = correctedSituation.extrapolateElevation(situationsBeforeStoring[0], situationsBeforeStoring[1], changesBeforeStoring);
Q_UNUSED(extrapolated) triedExtrapolation = true;
couldNotExtrapolate = !extrapolated;
// extrapolation only works if there is a provider and already data
// BLACK_AUDIT_X(extrapolated, Q_FUNC_INFO, "Cannot extrapolate");
} }
} }
// still no elevation
if (!correctedSituation.hasGroundElevation())
{
if (CBuildConfig::isLocalDeveloperDebugBuild())
{
// experimental, could become ASSERT
BLACK_VERIFY_X(needToRequestElevation, Q_FUNC_INFO, "Request should already be set");
}
needToRequestElevation = true; // should be the true already
Q_UNUSED(triedExtrapolation)
Q_UNUSED(couldNotExtrapolate)
}
} // gnd. elevation } // gnd. elevation
} // can skip?
} // can skip? } // can skip?
} // have already elevation? } // have already elevation?
@@ -1442,18 +1484,18 @@ namespace BlackCore
// store corrected situation // store corrected situation
correctedSituation = CRemoteAircraftProvider::storeAircraftSituation(correctedSituation, false); // we already added offset if any correctedSituation = CRemoteAircraftProvider::storeAircraftSituation(correctedSituation, false); // we already added offset if any
// check if we STILL want to request // check if we need want to request
if (!haveRequestedElevation && !canLikelySkipNearGround) if (needToRequestElevation && !canLikelySkipNearGround)
{ {
// we have not requested so far, but we are NEAR ground // we have not requested so far, but we are NEAR ground
// we expect at least not transferred cache or we are moving and have no provider elevation yet // we expect at least not transferred cache or we are moving and have no provider elevation yet
if (correctedSituation.isOtherElevationInfoBetter(CAircraftSituation::FromCache, false) || (correctedSituation.isMoving() && correctedSituation.isOtherElevationInfoBetter(CAircraftSituation::FromProvider, false))) if (correctedSituation.isOtherElevationInfoBetter(CAircraftSituation::FromCache, false) || (correctedSituation.isMoving() && correctedSituation.isOtherElevationInfoBetter(CAircraftSituation::FromProvider, false)))
{ {
haveRequestedElevation = this->requestElevation(correctedSituation); needToRequestElevation = this->requestElevation(correctedSituation);
} }
} }
Q_UNUSED(haveRequestedElevation) Q_UNUSED(needToRequestElevation)
return correctedSituation; return correctedSituation;
} }

View File

@@ -365,12 +365,13 @@ namespace BlackCore
if (this->isShuttingDown()) { return; } if (this->isShuttingDown()) { return; }
if (plane.isNull()) { return; } if (plane.isNull()) { return; }
// update in simulator // Update in remote aircraft for given callsign
ISimulationEnvironmentProvider::rememberGroundElevation(callsign, plane); // in simulator bool updatedForOnGroundPosition = false;
const int updated = CRemoteAircraftAware::updateAircraftGroundElevation(callsign, plane, CAircraftSituation::FromProvider, &updatedForOnGroundPosition);
// and in remote aircraft for given callsign // update in simulator
const int updated = CRemoteAircraftAware::updateAircraftGroundElevation(callsign, plane, CAircraftSituation::FromProvider); const bool likelyOnGroundElevation = updated > 0 && updatedForOnGroundPosition;
Q_UNUSED(updated) ISimulationEnvironmentProvider::rememberGroundElevation(callsign, likelyOnGroundElevation, plane); // in simulator
// signal we have received the elevation // signal we have received the elevation
// used by log display // used by log display
@@ -877,7 +878,7 @@ namespace BlackCore
{ {
const int aircraftCount = this->getAircraftInRangeCount(); const int aircraftCount = this->getAircraftInRangeCount();
this->setMaxElevationsRemembered(aircraftCount * 3); // at least 3 elevations per aircraft, even better as not all are requesting elevations this->setMaxElevationsRemembered(aircraftCount * 3); // at least 3 elevations per aircraft, even better as not all are requesting elevations
this->rememberGroundElevation(callsign, elevation); this->rememberGroundElevation(callsign, false, elevation);
} }
const QString modelString = model.getModelString(); const QString modelString = model.getModelString();
@@ -1192,7 +1193,7 @@ namespace BlackCore
const CCallsign cs = situation.hasCallsign() ? situation.getCallsign() : ownAircraft.getCallsign(); const CCallsign cs = situation.hasCallsign() ? situation.getCallsign() : ownAircraft.getCallsign();
const CLength radius = settings.getRecordedGndRadius().isNull() ? CElevationPlane::singlePointRadius() : settings.getRecordedGndRadius(); const CLength radius = settings.getRecordedGndRadius().isNull() ? CElevationPlane::singlePointRadius() : settings.getRecordedGndRadius();
const CElevationPlane ep(situation, radius); const CElevationPlane ep(situation, radius);
const bool remembered = this->rememberGroundElevation(cs, ep, radius); const bool remembered = this->rememberGroundElevation(cs, situation.isOnGround(), ep, radius);
Q_UNUSED(remembered) // false means it was already in that cache, or something else is wrong Q_UNUSED(remembered) // false means it was already in that cache, or something else is wrong
} }
} }