Ref T773, cache ground elevations for "on ground" planes separately

Rational:

* Those values represent taxiways and runways
* we cache those longer and keep more

It is much more likely we need/can use these values
This commit is contained in:
Klaus Basan
2020-02-18 00:45:47 +01:00
committed by Mat Sutcliffe
parent b128d40342
commit 33b1e26460
8 changed files with 113 additions and 43 deletions

View File

@@ -551,7 +551,7 @@ namespace BlackMisc
return c;
}
int CRemoteAircraftProvider::updateAircraftGroundElevation(const CCallsign &callsign, const CElevationPlane &elevation, CAircraftSituation::GndElevationInfo info)
int CRemoteAircraftProvider::updateAircraftGroundElevation(const CCallsign &callsign, const CElevationPlane &elevation, CAircraftSituation::GndElevationInfo info, bool *setForOnGroundPosition)
{
if (!this->isAircraftInRange(callsign)) { return 0; }
@@ -559,12 +559,14 @@ namespace BlackMisc
const qint64 now = QDateTime::currentMSecsSinceEpoch();
const CAircraftModel model = this->getAircraftInRangeModelForCallsign(callsign);
CAircraftSituationChange change;
bool setForOnGndPosition = false;
int updated = 0;
{
QWriteLocker l(&m_lockSituations);
CAircraftSituationList &situations = m_situationsByCallsign[callsign];
if (situations.isEmpty()) { return 0; }
updated = situations.setGroundElevationCheckedAndGuessGround(elevation, info, model, &change);
updated = situations.setGroundElevationCheckedAndGuessGround(elevation, info, model, &change, &setForOnGndPosition);
if (updated < 1) { return 0; }
m_situationsLastModified[callsign] = now;
const CAircraftSituation latestSituation = situations.front();
@@ -587,6 +589,7 @@ namespace BlackMisc
m_aircraftInRange[callsign].setGroundElevationChecked(elevation, info);
}
if (setForOnGroundPosition) { *setForOnGroundPosition = setForOnGndPosition; }
return updated; // updated situations
}
@@ -981,10 +984,10 @@ namespace BlackMisc
return this->provider()->updateMultipleAircraftRendered(callsigns, rendered);
}
int CRemoteAircraftAware::updateAircraftGroundElevation(const CCallsign &callsign, const CElevationPlane &elevation, CAircraftSituation::GndElevationInfo info)
int CRemoteAircraftAware::updateAircraftGroundElevation(const CCallsign &callsign, const CElevationPlane &elevation, CAircraftSituation::GndElevationInfo info, bool *updatedAircraftGroundElevation)
{
Q_ASSERT_X(this->provider(), Q_FUNC_INFO, "No object available");
return this->provider()->updateAircraftGroundElevation(callsign, elevation, info);
return this->provider()->updateAircraftGroundElevation(callsign, elevation, info, updatedAircraftGroundElevation);
}
bool CRemoteAircraftAware::updateCG(const CCallsign &callsign, const CLength &cg)

View File

@@ -190,7 +190,7 @@ namespace BlackMisc
//! Update the ground elevation
//! \threadsafe
virtual int updateAircraftGroundElevation(const Aviation::CCallsign &callsign, const Geo::CElevationPlane &elevation, Aviation::CAircraftSituation::GndElevationInfo info) = 0;
virtual int updateAircraftGroundElevation(const Aviation::CCallsign &callsign, const Geo::CElevationPlane &elevation, Aviation::CAircraftSituation::GndElevationInfo info, bool *updateAircraftGroundElevation) = 0;
//! Update the CG
//! \threadsafe
@@ -248,7 +248,8 @@ namespace BlackMisc
//! \threadsafe
virtual qint64 partsLastModified(const Aviation::CCallsign &callsign) const = 0;
//! \copydoc BlackMisc::Aviation::CAircraftSituationList::averageElevationOfNonMovingAircraft
//! Average elevation of aircraft in given range, which are NOT moving
//! \remark can be used to anticipate field elevation
//! \threadsafe
virtual Geo::CElevationPlane averageElevationOfNonMovingAircraft(const Aviation::CAircraftSituation &reference, const PhysicalQuantities::CLength &range, int minValues = 1) const = 0;
@@ -328,7 +329,7 @@ namespace BlackMisc
virtual bool updateFastPositionEnabled(const Aviation::CCallsign &callsign, bool enableFastPositonUpdates) override;
virtual bool updateAircraftRendered(const Aviation::CCallsign &callsign, bool rendered) override;
virtual int updateMultipleAircraftRendered(const Aviation::CCallsignSet &callsigns, bool rendered) override;
virtual int updateAircraftGroundElevation(const Aviation::CCallsign &callsign, const Geo::CElevationPlane &elevation, Aviation::CAircraftSituation::GndElevationInfo info) override;
virtual int updateAircraftGroundElevation(const Aviation::CCallsign &callsign, const Geo::CElevationPlane &elevation, Aviation::CAircraftSituation::GndElevationInfo info, bool *setForOnGroundPosition) override;
virtual bool updateCG(const Aviation::CCallsign &callsign, const PhysicalQuantities::CLength &cg) override;
virtual bool updateCGAndModelString(const Aviation::CCallsign &callsign, const PhysicalQuantities::CLength &cg, const QString &modelString) override;
virtual PhysicalQuantities::CLength getCGFromDB(const Aviation::CCallsign &callsign) const override;
@@ -474,7 +475,7 @@ namespace BlackMisc
Aviation::CAircraftSituationListPerCallsign m_situationsByCallsign; //!< situations, for performance reasons per callsign, thread safe access required
Aviation::CAircraftSituationPerCallsign m_latestSituationByCallsign; //!< latest situations, for performance reasons per callsign, thread safe access required
Aviation::CAircraftSituationPerCallsign m_latestOnGroundProviderElevation; //!< situation on ground with elevation from provider
Aviation::CAircraftSituationPerCallsign m_latestOnGroundProviderElevation; //!< situations on ground with elevation from provider
Aviation::CAircraftPartsListPerCallsign m_partsByCallsign; //!< parts, for performance reasons per callsign, thread safe access required
Aviation::CAircraftSituationChangeListPerCallsign m_changesByCallsign; //!< changes, for performance reasons per callsign, thread safe access required (same timestamps as corresponding situations)
Aviation::CCallsignSet m_aircraftWithParts; //!< aircraft supporting parts, thread safe access required
@@ -588,7 +589,7 @@ namespace BlackMisc
bool updateMultipleAircraftRendered(const Aviation::CCallsignSet &callsigns, bool rendered);
//! \copydoc IRemoteAircraftProvider::updateAircraftGroundElevation
int updateAircraftGroundElevation(const Aviation::CCallsign &callsign, const Geo::CElevationPlane &elevation, Aviation::CAircraftSituation::GndElevationInfo info);
int updateAircraftGroundElevation(const Aviation::CCallsign &callsign, const Geo::CElevationPlane &elevation, Aviation::CAircraftSituation::GndElevationInfo info, bool *updateAircraftGroundElevation);
//! \copydoc IRemoteAircraftProvider::updateCG
bool updateCG(const Aviation::CCallsign &callsign, const PhysicalQuantities::CLength &cg);

View File

@@ -19,7 +19,7 @@ namespace BlackMisc
{
namespace Simulation
{
bool ISimulationEnvironmentProvider::rememberGroundElevation(const CCallsign &requestedForCallsign, const ICoordinateGeodetic &elevationCoordinate, const CLength &epsilon)
bool ISimulationEnvironmentProvider::rememberGroundElevation(const CCallsign &requestedForCallsign, bool likelyOnGroundElevation, const ICoordinateGeodetic &elevationCoordinate, const CLength &epsilon)
{
if (!elevationCoordinate.hasMSLGeodeticHeight())
{
@@ -27,11 +27,14 @@ namespace BlackMisc
return false;
}
const CLength minRange = ISimulationEnvironmentProvider::minRange(epsilon);
{
// no 2nd elevation nearby?
QReadLocker l(&m_lockElvCoordinates);
if (!m_enableElevation) { return false; }
if (m_elvCoordinates.containsObjectInRange(elevationCoordinate, minRange(epsilon))) { return false; }
// check if we have already an elevation within range
if (m_elvCoordinatesGnd.containsObjectInRange(elevationCoordinate, minRange)) { return false; }
if (m_elvCoordinates.containsObjectInRange(elevationCoordinate, minRange)) { return false; }
}
{
@@ -39,13 +42,24 @@ namespace BlackMisc
// * we assume we find them faster
// * and need them more frequently (the recent ones)
const qint64 now = QDateTime::currentMSecsSinceEpoch();
QWriteLocker l(&m_lockElvCoordinates);
if (m_elvCoordinates.size() > m_maxElevations) { m_elvCoordinates.pop_back(); }
m_elvCoordinates.push_front(elevationCoordinate);
if (likelyOnGroundElevation)
{
if (m_elvCoordinatesGnd.size() > m_maxElevationsGnd) { m_elvCoordinatesGnd.pop_back(); }
m_elvCoordinatesGnd.push_front(elevationCoordinate);
}
else
{
if (m_elvCoordinates.size() > m_maxElevations) { m_elvCoordinates.pop_back(); }
m_elvCoordinates.push_front(elevationCoordinate);
}
// statistics
if (m_pendingElevationRequests.contains(requestedForCallsign))
{
const qint64 startedMs = m_pendingElevationRequests.value(requestedForCallsign);
const qint64 deltaMs = now - startedMs;
const qint64 deltaMs = now - startedMs;
m_pendingElevationRequests.remove(requestedForCallsign);
m_statsCurrentElevRequestTimeMs = deltaMs;
if (m_statsMaxElevRequestTimeMs < deltaMs) { m_statsMaxElevRequestTimeMs = deltaMs; }
@@ -54,14 +68,14 @@ namespace BlackMisc
return true;
}
bool ISimulationEnvironmentProvider::rememberGroundElevation(const CCallsign &requestedForCallsign, const CElevationPlane &elevationPlane)
bool ISimulationEnvironmentProvider::rememberGroundElevation(const CCallsign &requestedForCallsign, bool likelyOnGroundElevation, const CElevationPlane &elevationPlane)
{
if (!elevationPlane.hasMSLGeodeticHeight())
{
BLACK_AUDIT_X(false, Q_FUNC_INFO, "Elevation plane needs to be MSL NON NULL");
return false;
}
return this->rememberGroundElevation(requestedForCallsign, elevationPlane, elevationPlane.getRadius());
return this->rememberGroundElevation(requestedForCallsign, likelyOnGroundElevation, elevationPlane, elevationPlane.getRadius());
}
bool ISimulationEnvironmentProvider::insertCG(const CLength &cg, const CCallsign &cs)
@@ -69,15 +83,10 @@ namespace BlackMisc
if (cs.isEmpty()) { return false; }
const bool remove = cg.isNull();
if (remove)
{
QWriteLocker l(&m_lockCG);
m_cgsPerCallsign.remove(cs);
}
else
{
QWriteLocker l(&m_lockCG);
m_cgsPerCallsign[cs] = cg;
if (remove) { m_cgsPerCallsign.remove(cs); }
else { m_cgsPerCallsign[cs] = cg; }
}
return true;
}
@@ -86,7 +95,7 @@ namespace BlackMisc
{
bool ok = false;
QWriteLocker l(&m_lockCG);
if (!m_enableCG) { return false; }
if (!m_enableCG) { return false; }
if (!cs.isEmpty()) { m_cgsPerCallsign[cs] = cg; ok = true; }
if (!modelString.isEmpty()) { m_cgsPerModel[modelString.toUpper()] = cg; ok = true; }
return ok;
@@ -95,6 +104,7 @@ namespace BlackMisc
bool ISimulationEnvironmentProvider::insertCGForModelString(const CLength &cg, const QString &modelString)
{
if (modelString.isEmpty()) { return false; }
QWriteLocker l(&m_lockCG);
if (!m_enableCG) { return false; }
if (cg.isNull())
@@ -141,23 +151,33 @@ namespace BlackMisc
range;
}
CCoordinateGeodeticList ISimulationEnvironmentProvider::getElevationCoordinates() const
CCoordinateGeodeticList ISimulationEnvironmentProvider::getAllElevationCoordinates() const
{
QReadLocker l(&m_lockElvCoordinates);
return m_elvCoordinates;
CCoordinateGeodeticList cl(m_elvCoordinatesGnd);
cl.push_back(m_elvCoordinates);
return cl;
}
CCoordinateGeodeticList ISimulationEnvironmentProvider::getElevationCoordinates(int &maxRemembered) const
CCoordinateGeodeticList ISimulationEnvironmentProvider::getElevationCoordinatesOnGround() const
{
QReadLocker l(&m_lockElvCoordinates);
return m_elvCoordinatesGnd;
}
CCoordinateGeodeticList ISimulationEnvironmentProvider::getAllElevationCoordinates(int &maxRemembered) const
{
QReadLocker l(&m_lockElvCoordinates);
maxRemembered = m_maxElevations;
return m_elvCoordinates;
CCoordinateGeodeticList cl(m_elvCoordinatesGnd);
cl.push_back(m_elvCoordinates);
return cl;
}
int ISimulationEnvironmentProvider::cleanUpElevations(const ICoordinateGeodetic &referenceCoordinate, int maxNumber)
{
int currentMax;
CCoordinateGeodeticList coordinates(this->getElevationCoordinates(currentMax));
CCoordinateGeodeticList coordinates(this->getAllElevationCoordinates(currentMax));
if (maxNumber < 0) { maxNumber = currentMax; }
const int size = coordinates.size();
if (size <= maxNumber) { return 0; }
@@ -177,10 +197,12 @@ namespace BlackMisc
// for single point we use a slightly optimized version
const bool singlePoint = (&range == &CElevationPlane::singlePointRadius() || range.isNull() || range <= CElevationPlane::singlePointRadius());
const CCoordinateGeodeticList elevations = this->getAllElevationCoordinates();
const CCoordinateGeodetic coordinate = singlePoint ?
this->getElevationCoordinates().findFirstWithinRangeOrDefault(reference, CElevationPlane::singlePointRadius()) :
this->getElevationCoordinates().findClosestWithinRange(reference, range);
elevations.findFirstWithinRangeOrDefault(reference, CElevationPlane::singlePointRadius()) :
elevations.findClosestWithinRange(reference, range);
const bool found = !coordinate.isNull();
{
QWriteLocker l{&m_lockElvCoordinates };
if (found)
@@ -455,6 +477,7 @@ namespace BlackMisc
{
QWriteLocker l(&m_lockElvCoordinates);
m_elvCoordinates.clear();
m_elvCoordinatesGnd.clear();
m_pendingElevationRequests.clear();
m_statsCurrentElevRequestTimeMs = -1;
m_statsMaxElevRequestTimeMs = -1;

View File

@@ -34,9 +34,13 @@ namespace BlackMisc
class BLACKMISC_EXPORT ISimulationEnvironmentProvider : public IProvider
{
public:
//! All remembered coordiantes
//! All remembered coordinates
//! \threadsafe
Geo::CCoordinateGeodeticList getElevationCoordinates() const;
Geo::CCoordinateGeodeticList getAllElevationCoordinates() const;
//! All remembered coordinates
//! \threadsafe
Geo::CCoordinateGeodeticList getElevationCoordinatesOnGround() const;
//! Find closest elevation (or return NULL)
//! \threadsafe
@@ -141,7 +145,7 @@ namespace BlackMisc
//! All remembered coordiantes plus max.remembered situations
//! \threadsafe
Geo::CCoordinateGeodeticList getElevationCoordinates(int &maxRemembered) const;
Geo::CCoordinateGeodeticList getAllElevationCoordinates(int &maxRemembered) const;
//! New plugin info and default model
//! \remark normally only used by emulated driver
@@ -196,11 +200,11 @@ namespace BlackMisc
//! Remember a given elevation
//! \threadsafe
bool rememberGroundElevation(const Aviation::CCallsign &requestedForCallsign, const Geo::ICoordinateGeodetic &elevationCoordinate, const PhysicalQuantities::CLength &epsilon = Geo::CElevationPlane::singlePointRadius());
bool rememberGroundElevation(const Aviation::CCallsign &requestedForCallsign, bool likelyOnGroundElevation, const Geo::ICoordinateGeodetic &elevationCoordinate, const PhysicalQuantities::CLength &epsilon = Geo::CElevationPlane::singlePointRadius());
//! Remember a given elevation
//! \threadsafe
bool rememberGroundElevation(const Aviation::CCallsign &requestedForCallsign, const Geo::CElevationPlane &elevationPlane) ;
bool rememberGroundElevation(const Aviation::CCallsign &requestedForCallsign, bool likelyOnGroundElevation, const Geo::CElevationPlane &elevationPlane);
//! Insert or replace a CG
//! \remark passing a NULL value will remove the CG
@@ -240,8 +244,13 @@ namespace BlackMisc
QString m_simulatorDetails; //!< describes version etc.
QString m_simulatorVersion; //!< simulator version
CAircraftModel m_defaultModel; //!< default model
int m_maxElevations = 100; //!< How many elevations we keep
Geo::CCoordinateGeodeticList m_elvCoordinates; //!< elevation cache
// idea: the elevations on gnd are likely taxiways and runways, so we keep those
int m_maxElevations = 100; //!< How many elevations we keep
int m_maxElevationsGnd = 400; //!< How many elevations we keep for elevations on gnd.
Geo::CCoordinateGeodeticList m_elvCoordinates; //!< elevation cache
Geo::CCoordinateGeodeticList m_elvCoordinatesGnd; //!< elevation cache for on ground situations
Aviation::CTimestampPerCallsign m_pendingElevationRequests; //!< pending elevation requests for aircraft callsign
Aviation::CLengthPerCallsign m_cgsPerCallsign; //!< CGs per callsign
QHash<QString, PhysicalQuantities::CLength> m_cgsPerModel; //!< CGs per model string
@@ -250,7 +259,7 @@ namespace BlackMisc
qint64 m_statsCurrentElevRequestTimeMs = -1;
bool m_enableElevation = true;
bool m_enableCG = true;
bool m_enableCG = true;
mutable int m_elvFound = 0; //!< statistics only
mutable int m_elvMissed = 0; //!< statistics only