mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-05-01 14:45:42 +08:00
Ref T773, use "on ground" cached elevations for situations in simulator and airspace monitor
This commit is contained in:
committed by
Mat Sutcliffe
parent
55b28e24a6
commit
4120a2c77d
@@ -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,54 +1369,95 @@ 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())
|
|
||||||
{
|
|
||||||
// from nearby situations of own aircraft
|
|
||||||
correctedSituation.transferGroundElevation(situationWithElv);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// from cache
|
|
||||||
const CLength distance(correctedSituation.getDistancePerTime250ms(CElevationPlane::singlePointRadius())); // distance per ms
|
|
||||||
const CElevationPlane ep = this->findClosestElevationWithinRangeOrRequest(correctedSituation, distance, callsign);
|
|
||||||
haveRequestedElevation = ep.isNull(); // NULL means we requested
|
|
||||||
Q_ASSERT_X(haveRequestedElevation || !ep.getRadius().isNull(), Q_FUNC_INFO, "null radius");
|
|
||||||
|
|
||||||
// also can handle NULL elevations
|
// Check if we can bail out and ignore all elevation handling
|
||||||
correctedSituation.setGroundElevation(ep, CAircraftSituation::FromCache);
|
//
|
||||||
|
// 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())
|
||||||
|
{
|
||||||
|
canLikelySkipNearGround = changesBeforeStoring.isConstAscending();
|
||||||
}
|
}
|
||||||
|
|
||||||
// we have a new situation, so we try to get the elevation
|
if (!canLikelySkipNearGround)
|
||||||
// so far we have requested it, but we set it upfront either by
|
|
||||||
// a) average value from other planes in the vicinity or
|
|
||||||
// b) by extrapolating
|
|
||||||
//
|
|
||||||
// if we would NOT preset it, we could end up with oscillation
|
|
||||||
//
|
|
||||||
if (!correctedSituation.hasGroundElevation())
|
|
||||||
{
|
{
|
||||||
const CElevationPlane averagePlane = this->averageElevationOfNonMovingAircraft(situation, CElevationPlane::majorAirportRadius(), 2);
|
const CAircraftSituationList situationsBeforeStoring = this->remoteAircraftSituations(callsign);
|
||||||
if (!averagePlane.isNull())
|
const CAircraftSituation situationWithElvBeforeStoring = situationsBeforeStoring.findClosestElevationWithinRange(correctedSituation, correctedSituation.getDistancePerTime(100, CElevationPlane::singlePointRadius()));
|
||||||
|
if (!situationWithElvBeforeStoring.getGroundElevation().isNull())
|
||||||
{
|
{
|
||||||
correctedSituation.setGroundElevation(averagePlane, CAircraftSituation::Average);
|
// from nearby situations of own aircraft, data was transferred above
|
||||||
|
// we use transfer first as it is slightly faster as cache
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// values before updating (i.e. "storing") so the new situation is not yet considered
|
// from cache
|
||||||
const CAircraftSituationList oldSituations = this->remoteAircraftSituations(callsign);
|
const CLength distance(correctedSituation.getDistancePerTime250ms(CElevationPlane::singlePointRadius())); // distance per ms
|
||||||
const CAircraftSituationChangeList oldChanges = this->remoteAircraftSituationChanges(callsign);
|
const CElevationPlane ep = this->findClosestElevationWithinRange(correctedSituation, distance);
|
||||||
if (oldSituations.size() > 1)
|
needToRequestElevation = ep.isNull();
|
||||||
{
|
Q_ASSERT_X(needToRequestElevation || !ep.getRadius().isNull(), Q_FUNC_INFO, "null radius");
|
||||||
const bool extrapolated = correctedSituation.extrapolateElevation(oldSituations[0], oldSituations[1], oldChanges.frontOrDefault());
|
|
||||||
Q_UNUSED(extrapolated)
|
|
||||||
|
|
||||||
// extrapolation only works if there is a provider and already data
|
// also can handle NULL elevations
|
||||||
// BLACK_AUDIT_X(extrapolated, Q_FUNC_INFO, "Cannot extrapolate");
|
correctedSituation.setGroundElevation(ep, CAircraftSituation::FromCache);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} // gnd. 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
|
||||||
|
//
|
||||||
|
// a) average value from other planes in the vicinity (cache, not moving) or
|
||||||
|
// b) by extrapolating
|
||||||
|
//
|
||||||
|
// if we would NOT preset it, we could end up with oscillation
|
||||||
|
//
|
||||||
|
if (!correctedSituation.hasGroundElevation())
|
||||||
|
{
|
||||||
|
// 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())
|
||||||
|
{
|
||||||
|
correctedSituation.setGroundElevation(averagePlane, CAircraftSituation::Average);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// values before updating (i.e. "storing") so the new situation is not yet considered
|
||||||
|
if (situationsBeforeStoring.size() > 1)
|
||||||
|
{
|
||||||
|
const bool extrapolated = correctedSituation.extrapolateElevation(situationsBeforeStoring[0], situationsBeforeStoring[1], changesBeforeStoring);
|
||||||
|
triedExtrapolation = true;
|
||||||
|
couldNotExtrapolate = !extrapolated;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
} // 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user