mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-27 11:05:44 +08:00
Ref T778, special terrain probe value handling for XP
* only request terrain probe up to a max. distance * detect "isSuspiciousTerrainValue" * See also https://discordapp.com/channels/539048679160676382/539925070550794240/696786452855390218
This commit is contained in:
committed by
Mat Sutcliffe
parent
cfa96a3aeb
commit
8206fc6bb9
@@ -35,60 +35,60 @@ namespace BlackMisc
|
|||||||
}
|
}
|
||||||
|
|
||||||
const CLength minRange = ISimulationEnvironmentProvider::minRange(epsilon);
|
const CLength minRange = ISimulationEnvironmentProvider::minRange(epsilon);
|
||||||
|
const double elvFt = elevationCoordinate.geodeticHeight().value(CLengthUnit::ft());
|
||||||
|
|
||||||
|
CCoordinateGeodetic alreadyInRange;
|
||||||
|
CCoordinateGeodetic alreadyInRangeGnd;
|
||||||
{
|
{
|
||||||
QReadLocker l(&m_lockElvCoordinates);
|
QReadLocker l(&m_lockElvCoordinates);
|
||||||
if (!m_enableElevation) { return false; }
|
if (!m_enableElevation) { return false; }
|
||||||
|
|
||||||
// check if we have already an elevation within range
|
// check if we have already an elevation within range
|
||||||
CCoordinateGeodetic alreadyInRange = m_elvCoordinatesGnd.findFirstWithinRangeOrDefault(elevationCoordinate, minRange);
|
alreadyInRangeGnd = m_elvCoordinatesGnd.findFirstWithinRangeOrDefault(elevationCoordinate, minRange);
|
||||||
|
alreadyInRange = m_elvCoordinates.findFirstWithinRangeOrDefault(elevationCoordinate, minRange);
|
||||||
|
}
|
||||||
|
|
||||||
constexpr double maxDistFt = 30.0;
|
constexpr double maxDistFt = 30.0;
|
||||||
|
|
||||||
if (!alreadyInRange.isNull())
|
// here we deal with gnd situation and do not expect a lot of variance
|
||||||
|
if (!alreadyInRangeGnd.isNull())
|
||||||
{
|
{
|
||||||
// found
|
// found
|
||||||
const double distFt = qAbs(alreadyInRange.geodeticHeight().value(CLengthUnit::ft()) - elevationCoordinate.geodeticHeight().value(CLengthUnit::ft()));
|
const double distFt = qAbs(alreadyInRangeGnd.geodeticHeight().value(CLengthUnit::ft()) - elvFt);
|
||||||
if (distFt > maxDistFt)
|
if (distFt > maxDistFt)
|
||||||
{
|
{
|
||||||
// we such a huge distance to existing value
|
// such a huge distance to existing value
|
||||||
CLogMessage(this).debug(u"Suspicious gnd. elevation distance '%1': %2ft") << requestedForCallsign.asString() << distFt;
|
CLogMessage(this).debug(u"Suspicious GND elevation distance '%1': %2ft at %3") << requestedForCallsign.asString() << distFt << elevationCoordinate.geodeticHeight().valueRoundedAsString(CLengthUnit::ft(), 1);
|
||||||
BLACK_VERIFY_X(!CBuildConfig::isLocalDeveloperDebugBuild(), Q_FUNC_INFO, "Suspicious gnd. elevation distance");
|
BLACK_VERIFY_X(!CBuildConfig::isLocalDeveloperDebugBuild(), Q_FUNC_INFO, "Suspicious gnd. elevation distance");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
alreadyInRange = m_elvCoordinates.findFirstWithinRangeOrDefault(elevationCoordinate, minRange);
|
// here we deal with all kind of values, so it can be that
|
||||||
|
// values vary in a much larger range
|
||||||
if (!alreadyInRange.isNull())
|
if (!alreadyInRange.isNull())
|
||||||
{
|
{
|
||||||
// found
|
// found
|
||||||
const double distFt = qAbs(alreadyInRange.geodeticHeight().value(CLengthUnit::ft()) - elevationCoordinate.geodeticHeight().value(CLengthUnit::ft()));
|
const double distFt = qAbs(alreadyInRange.geodeticHeight().value(CLengthUnit::ft()) - elvFt);
|
||||||
if (distFt > maxDistFt)
|
if (distFt > maxDistFt)
|
||||||
{
|
{
|
||||||
// we such a huge distance to existing value
|
// such a huge distance to existing value
|
||||||
CLogMessage(this).debug(u"Suspicious elevation distance '%1': %2ft") << requestedForCallsign.asString() << distFt;
|
CLogMessage(this).debug(u"Suspicious NON GND elevation distance for '%1': %2ft at %3") << requestedForCallsign.asString() << distFt << elevationCoordinate.geodeticHeight().valueRoundedAsString(CLengthUnit::ft(), 1);
|
||||||
BLACK_VERIFY_X(!CBuildConfig::isLocalDeveloperDebugBuild(), Q_FUNC_INFO, "Suspicious elevation distance");
|
// BLACK_VERIFY_X(!CBuildConfig::isLocalDeveloperDebugBuild(), Q_FUNC_INFO, "Suspicious elevation distance");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
const qint64 now = QDateTime::currentMSecsSinceEpoch();
|
||||||
{
|
{
|
||||||
// we keep latest at front
|
// we keep latest at front
|
||||||
// * we assume we find them faster
|
// * we assume we find them faster
|
||||||
// * and need them more frequently (the recent ones)
|
// * and need them more frequently (the recent ones)
|
||||||
const qint64 now = QDateTime::currentMSecsSinceEpoch();
|
|
||||||
|
|
||||||
QWriteLocker l(&m_lockElvCoordinates);
|
QWriteLocker l(&m_lockElvCoordinates);
|
||||||
if (likelyOnGroundElevation)
|
if (likelyOnGroundElevation)
|
||||||
{
|
{
|
||||||
if (m_elvCoordinatesGnd.size() > m_maxElevationsGnd) { m_elvCoordinatesGnd.pop_back(); }
|
if (m_elvCoordinatesGnd.size() > m_maxElevationsGnd) { m_elvCoordinatesGnd.pop_back(); }
|
||||||
m_elvCoordinatesGnd.push_front(elevationCoordinate);
|
m_elvCoordinatesGnd.push_front(elevationCoordinate);
|
||||||
|
|
||||||
const bool valid = !elevationCoordinate.geodeticHeight().isNull() && !elevationCoordinate.geodeticHeight().isZeroEpsilonConsidered();
|
|
||||||
if (!valid)
|
|
||||||
{
|
|
||||||
BLACK_VERIFY_X(!CBuildConfig::isLocalDeveloperDebugBuild(), Q_FUNC_INFO, "Suspicious value");
|
|
||||||
CLogMessage(this).debug(u"Suspicious gnd.cache value: %1") << elevationCoordinate.convertToQString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -182,10 +182,66 @@ namespace BlackSimPlugin
|
|||||||
return u > 0;
|
return u > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CSimulatorXPlane::handleProbeValue(const CElevationPlane &plane, const CCallsign &callsign, const QString &hint, bool ignoreOutsideRange)
|
||||||
|
{
|
||||||
|
// XPlane specific checks for T778
|
||||||
|
// https://discordapp.com/channels/539048679160676382/577213275184562176/696780159969132626
|
||||||
|
if (!plane.hasMSLGeodeticHeight()) { return false; }
|
||||||
|
if (isSuspiciousTerrainValue(plane))
|
||||||
|
{
|
||||||
|
// ignore values up to +- 1.0meters, those most likely mean no scenery
|
||||||
|
const CLength distance = this->getDistanceToOwnAircraft(plane);
|
||||||
|
if (ignoreOutsideRange && distance > maxTerrainRequestDistance()) { return false; }
|
||||||
|
|
||||||
|
static const CLength threshold = maxTerrainRequestDistance() * 0.50;
|
||||||
|
if (distance > threshold)
|
||||||
|
{
|
||||||
|
// we expect scenery to be loaded within threshold range
|
||||||
|
// outside that range we assue a suspicous value "represents no scenery"
|
||||||
|
// of course this can be wrong, but in that case we would geth those values
|
||||||
|
// once we get inside range
|
||||||
|
this->setMinTerrainProbeDistance(distance);
|
||||||
|
CLogMessage(this).debug(u"Suspicous XPlane probe [%1] value %2 for '%3' ignored, distance: %4 min.disance: %5")
|
||||||
|
<< hint
|
||||||
|
<< plane.getAltitude().valueRoundedAsString(CLengthUnit::m(), 4)
|
||||||
|
<< callsign.asString()
|
||||||
|
<< distance.valueRoundedAsString(CLengthUnit::NM(), 2)
|
||||||
|
<< m_minSuspicousTerrainProbe.valueRoundedAsString(CLengthUnit::NM(), 2);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSimulatorXPlane::callbackReceivedRequestedElevation(const CElevationPlane &plane, const CCallsign &callsign)
|
||||||
|
{
|
||||||
|
static const QString hint("probe callback");
|
||||||
|
if (!this->handleProbeValue(plane, callsign, hint, false))
|
||||||
|
{
|
||||||
|
this->removePendingElevationRequest(callsign);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CSimulatorPluginCommon::callbackReceivedRequestedElevation(plane, callsign);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSimulatorXPlane::isSuspiciousTerrainValue(const CElevationPlane &elevation)
|
||||||
|
{
|
||||||
|
if (!elevation.hasMSLGeodeticHeight()) { return true; }
|
||||||
|
const double valueFt = qAbs(elevation.getAltitudeValue(CLengthUnit::ft()));
|
||||||
|
return valueFt < 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLength &CSimulatorXPlane::maxTerrainRequestDistance()
|
||||||
|
{
|
||||||
|
static const CLength d(70.0, CLengthUnit::NM());
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
void CSimulatorXPlane::clearAllRemoteAircraftData()
|
void CSimulatorXPlane::clearAllRemoteAircraftData()
|
||||||
{
|
{
|
||||||
m_aircraftAddedFailed.clear();
|
m_aircraftAddedFailed.clear();
|
||||||
CSimulatorPluginCommon::clearAllRemoteAircraftData();
|
CSimulatorPluginCommon::clearAllRemoteAircraftData();
|
||||||
|
m_minSuspicousTerrainProbe.setNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSimulatorXPlane::requestElevation(const ICoordinateGeodetic &reference, const CCallsign &callsign)
|
bool CSimulatorXPlane::requestElevation(const ICoordinateGeodetic &reference, const CCallsign &callsign)
|
||||||
@@ -197,6 +253,13 @@ namespace BlackSimPlugin
|
|||||||
if (callsign.isEmpty()) { return false; }
|
if (callsign.isEmpty()) { return false; }
|
||||||
if (!this->isAircraftInRange(callsign)) { return false; }
|
if (!this->isAircraftInRange(callsign)) { return false; }
|
||||||
|
|
||||||
|
const CLength d = this->getDistanceToOwnAircraft(reference);
|
||||||
|
if (!d.isNull() && d > maxTerrainRequestDistance())
|
||||||
|
{
|
||||||
|
// no request, too far away
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
CCoordinateGeodetic pos(reference);
|
CCoordinateGeodetic pos(reference);
|
||||||
if (!pos.hasMSLGeodeticHeight())
|
if (!pos.hasMSLGeodeticHeight())
|
||||||
{
|
{
|
||||||
@@ -344,7 +407,6 @@ namespace BlackSimPlugin
|
|||||||
};
|
};
|
||||||
|
|
||||||
this->updateOwnParts(parts);
|
this->updateOwnParts(parts);
|
||||||
this->requestRemoteAircraftDataFromXPlane();
|
|
||||||
|
|
||||||
CCallsignSet invalid;
|
CCallsignSet invalid;
|
||||||
for (CXPlaneMPAircraft &xplaneAircraft : m_xplaneAircraftObjects)
|
for (CXPlaneMPAircraft &xplaneAircraft : m_xplaneAircraftObjects)
|
||||||
@@ -369,6 +431,14 @@ namespace BlackSimPlugin
|
|||||||
this->triggerRemoveAircraft(cs, ++i * 100);
|
this->triggerRemoveAircraft(cs, ++i * 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// KB: IMHO those data are pretty useless for XPlane
|
||||||
|
// no need to request them all the times
|
||||||
|
if ((m_slowTimerCalls % 3u) == 0u)
|
||||||
|
{
|
||||||
|
this->requestRemoteAircraftDataFromXPlane();
|
||||||
|
}
|
||||||
|
|
||||||
// FPS
|
// FPS
|
||||||
if ((m_slowTimerCalls % 5u) == 0u)
|
if ((m_slowTimerCalls % 5u) == 0u)
|
||||||
{
|
{
|
||||||
@@ -1052,6 +1122,7 @@ namespace BlackSimPlugin
|
|||||||
}
|
}
|
||||||
|
|
||||||
const CCallsignSet logCallsigns = this->getLogCallsigns();
|
const CCallsignSet logCallsigns = this->getLogCallsigns();
|
||||||
|
static const QString hint("remote acft.");
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
const bool emptyCs = callsigns[i].isEmpty();
|
const bool emptyCs = callsigns[i].isEmpty();
|
||||||
@@ -1077,7 +1148,10 @@ namespace BlackSimPlugin
|
|||||||
CLength(cgValue, CLengthUnit::m(), CLengthUnit::ft());
|
CLength(cgValue, CLengthUnit::m(), CLengthUnit::ft());
|
||||||
|
|
||||||
// if we knew "on ground" here we could set it as parameter of rememberElevationAndSimulatorCG
|
// if we knew "on ground" here we could set it as parameter of rememberElevationAndSimulatorCG
|
||||||
this->rememberElevationAndSimulatorCG(cs, xpAircraft.getAircraftModel(), false, elevation, cg);
|
// this->rememberElevationAndSimulatorCG(cs, xpAircraft.getAircraftModel(), false, elevation, cg);
|
||||||
|
// with T778 we do NOT use this function for elevation here if "isSuspicious"
|
||||||
|
const bool useElevation = this->handleProbeValue(elevation, cs, hint, true);
|
||||||
|
this->rememberElevationAndSimulatorCG(cs, xpAircraft.getAircraftModel(), false, useElevation ? elevation : CElevationPlane::null(), cg);
|
||||||
|
|
||||||
// loopback
|
// loopback
|
||||||
if (logCallsigns.contains(cs))
|
if (logCallsigns.contains(cs))
|
||||||
@@ -1140,6 +1214,15 @@ namespace BlackSimPlugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSimulatorXPlane::setMinTerrainProbeDistance(const CLength &distance)
|
||||||
|
{
|
||||||
|
if (distance.isNull()) { return; }
|
||||||
|
if (m_minSuspicousTerrainProbe.isNull() || distance < m_minSuspicousTerrainProbe)
|
||||||
|
{
|
||||||
|
m_minSuspicousTerrainProbe = distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CSimulatorXPlane::updateAirportsInRange()
|
void CSimulatorXPlane::updateAirportsInRange()
|
||||||
{
|
{
|
||||||
if (this->isConnected()) { m_serviceProxy->updateAirportsInRange(); }
|
if (this->isConnected()) { m_serviceProxy->updateAirportsInRange(); }
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ namespace BlackSimPlugin
|
|||||||
virtual void resetAircraftStatistics() override;
|
virtual void resetAircraftStatistics() override;
|
||||||
virtual BlackMisc::CStatusMessageList getInterpolationMessages(const BlackMisc::Aviation::CCallsign &callsign) const override;
|
virtual BlackMisc::CStatusMessageList getInterpolationMessages(const BlackMisc::Aviation::CCallsign &callsign) const override;
|
||||||
virtual bool testSendSituationAndParts(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &situation, const BlackMisc::Aviation::CAircraftParts &parts) override;
|
virtual bool testSendSituationAndParts(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &situation, const BlackMisc::Aviation::CAircraftParts &parts) override;
|
||||||
|
virtual void callbackReceivedRequestedElevation(const BlackMisc::Geo::CElevationPlane &plane, const BlackMisc::Aviation::CCallsign &callsign) override;
|
||||||
//! @}
|
//! @}
|
||||||
|
|
||||||
//! \copydoc BlackMisc::Simulation::ISimulationEnvironmentProvider::requestElevation
|
//! \copydoc BlackMisc::Simulation::ISimulationEnvironmentProvider::requestElevation
|
||||||
@@ -235,6 +236,15 @@ namespace BlackSimPlugin
|
|||||||
//! Settings have changed
|
//! Settings have changed
|
||||||
void onXSwiftBusSettingsChanged();
|
void onXSwiftBusSettingsChanged();
|
||||||
|
|
||||||
|
//! Min.distance of "failed" (suspicious) terrain probe requests
|
||||||
|
void setMinTerrainProbeDistance(const BlackMisc::PhysicalQuantities::CLength &distance);
|
||||||
|
|
||||||
|
//! Handle a probe value
|
||||||
|
bool handleProbeValue(const BlackMisc::Geo::CElevationPlane &plane, const BlackMisc::Aviation::CCallsign &callsign, const QString &hint, bool ignoreOutsideRange);
|
||||||
|
|
||||||
|
static bool isSuspiciousTerrainValue(const BlackMisc::Geo::CElevationPlane &elevation);
|
||||||
|
static const BlackMisc::PhysicalQuantities::CLength &maxTerrainRequestDistance();
|
||||||
|
|
||||||
DBusMode m_dbusMode;
|
DBusMode m_dbusMode;
|
||||||
BlackMisc::CSetting<BlackMisc::Simulation::Settings::TXSwiftBusSettings> m_xSwiftBusServerSettings { this, &CSimulatorXPlane::onXSwiftBusSettingsChanged };
|
BlackMisc::CSetting<BlackMisc::Simulation::Settings::TXSwiftBusSettings> m_xSwiftBusServerSettings { this, &CSimulatorXPlane::onXSwiftBusSettingsChanged };
|
||||||
static constexpr qint64 TimeoutAdding = 10000;
|
static constexpr qint64 TimeoutAdding = 10000;
|
||||||
@@ -256,6 +266,7 @@ namespace BlackSimPlugin
|
|||||||
BlackMisc::Simulation::CSimulatedAircraftList m_pendingToBeAddedAircraft; //!< aircraft to be added
|
BlackMisc::Simulation::CSimulatedAircraftList m_pendingToBeAddedAircraft; //!< aircraft to be added
|
||||||
QHash<BlackMisc::Aviation::CCallsign, qint64> m_addingInProgressAircraft; //!< aircraft just adding
|
QHash<BlackMisc::Aviation::CCallsign, qint64> m_addingInProgressAircraft; //!< aircraft just adding
|
||||||
BlackMisc::Simulation::CSimulatedAircraftList m_aircraftAddedFailed; //!< aircraft for which adding failed
|
BlackMisc::Simulation::CSimulatedAircraftList m_aircraftAddedFailed; //!< aircraft for which adding failed
|
||||||
|
BlackMisc::PhysicalQuantities::CLength m_minSuspicousTerrainProbe { nullptr }; //!< min. distance of "failed" (suspicious) terrain probe requests
|
||||||
XPlaneData m_xplaneData; //!< XPlane data
|
XPlaneData m_xplaneData; //!< XPlane data
|
||||||
|
|
||||||
// statistics
|
// statistics
|
||||||
|
|||||||
Reference in New Issue
Block a user