mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 23:05:36 +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 double elvFt = elevationCoordinate.geodeticHeight().value(CLengthUnit::ft());
|
||||
|
||||
CCoordinateGeodetic alreadyInRange;
|
||||
CCoordinateGeodetic alreadyInRangeGnd;
|
||||
{
|
||||
QReadLocker l(&m_lockElvCoordinates);
|
||||
if (!m_enableElevation) { return false; }
|
||||
|
||||
// check if we have already an elevation within range
|
||||
CCoordinateGeodetic alreadyInRange = m_elvCoordinatesGnd.findFirstWithinRangeOrDefault(elevationCoordinate, minRange);
|
||||
constexpr double maxDistFt = 30.0;
|
||||
|
||||
if (!alreadyInRange.isNull())
|
||||
{
|
||||
// found
|
||||
const double distFt = qAbs(alreadyInRange.geodeticHeight().value(CLengthUnit::ft()) - elevationCoordinate.geodeticHeight().value(CLengthUnit::ft()));
|
||||
if (distFt > maxDistFt)
|
||||
{
|
||||
// we such a huge distance to existing value
|
||||
CLogMessage(this).debug(u"Suspicious gnd. elevation distance '%1': %2ft") << requestedForCallsign.asString() << distFt;
|
||||
BLACK_VERIFY_X(!CBuildConfig::isLocalDeveloperDebugBuild(), Q_FUNC_INFO, "Suspicious gnd. elevation distance");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
alreadyInRange = m_elvCoordinates.findFirstWithinRangeOrDefault(elevationCoordinate, minRange);
|
||||
if (!alreadyInRange.isNull())
|
||||
{
|
||||
// found
|
||||
const double distFt = qAbs(alreadyInRange.geodeticHeight().value(CLengthUnit::ft()) - elevationCoordinate.geodeticHeight().value(CLengthUnit::ft()));
|
||||
if (distFt > maxDistFt)
|
||||
{
|
||||
// we such a huge distance to existing value
|
||||
CLogMessage(this).debug(u"Suspicious elevation distance '%1': %2ft") << requestedForCallsign.asString() << distFt;
|
||||
BLACK_VERIFY_X(!CBuildConfig::isLocalDeveloperDebugBuild(), Q_FUNC_INFO, "Suspicious elevation distance");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
alreadyInRangeGnd = m_elvCoordinatesGnd.findFirstWithinRangeOrDefault(elevationCoordinate, minRange);
|
||||
alreadyInRange = m_elvCoordinates.findFirstWithinRangeOrDefault(elevationCoordinate, minRange);
|
||||
}
|
||||
|
||||
constexpr double maxDistFt = 30.0;
|
||||
|
||||
// here we deal with gnd situation and do not expect a lot of variance
|
||||
if (!alreadyInRangeGnd.isNull())
|
||||
{
|
||||
// found
|
||||
const double distFt = qAbs(alreadyInRangeGnd.geodeticHeight().value(CLengthUnit::ft()) - elvFt);
|
||||
if (distFt > maxDistFt)
|
||||
{
|
||||
// such a huge distance to existing value
|
||||
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");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// here we deal with all kind of values, so it can be that
|
||||
// values vary in a much larger range
|
||||
if (!alreadyInRange.isNull())
|
||||
{
|
||||
// found
|
||||
const double distFt = qAbs(alreadyInRange.geodeticHeight().value(CLengthUnit::ft()) - elvFt);
|
||||
if (distFt > maxDistFt)
|
||||
{
|
||||
// such a huge distance to existing value
|
||||
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");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const qint64 now = QDateTime::currentMSecsSinceEpoch();
|
||||
{
|
||||
// we keep latest at front
|
||||
// * we assume we find them faster
|
||||
// * and need them more frequently (the recent ones)
|
||||
const qint64 now = QDateTime::currentMSecsSinceEpoch();
|
||||
|
||||
QWriteLocker l(&m_lockElvCoordinates);
|
||||
if (likelyOnGroundElevation)
|
||||
{
|
||||
if (m_elvCoordinatesGnd.size() > m_maxElevationsGnd) { m_elvCoordinatesGnd.pop_back(); }
|
||||
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
|
||||
{
|
||||
|
||||
@@ -182,10 +182,66 @@ namespace BlackSimPlugin
|
||||
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()
|
||||
{
|
||||
m_aircraftAddedFailed.clear();
|
||||
CSimulatorPluginCommon::clearAllRemoteAircraftData();
|
||||
m_minSuspicousTerrainProbe.setNull();
|
||||
}
|
||||
|
||||
bool CSimulatorXPlane::requestElevation(const ICoordinateGeodetic &reference, const CCallsign &callsign)
|
||||
@@ -197,6 +253,13 @@ namespace BlackSimPlugin
|
||||
if (callsign.isEmpty()) { 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);
|
||||
if (!pos.hasMSLGeodeticHeight())
|
||||
{
|
||||
@@ -344,7 +407,6 @@ namespace BlackSimPlugin
|
||||
};
|
||||
|
||||
this->updateOwnParts(parts);
|
||||
this->requestRemoteAircraftDataFromXPlane();
|
||||
|
||||
CCallsignSet invalid;
|
||||
for (CXPlaneMPAircraft &xplaneAircraft : m_xplaneAircraftObjects)
|
||||
@@ -369,6 +431,14 @@ namespace BlackSimPlugin
|
||||
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
|
||||
if ((m_slowTimerCalls % 5u) == 0u)
|
||||
{
|
||||
@@ -494,10 +564,10 @@ namespace BlackSimPlugin
|
||||
QColor color = "cyan";
|
||||
/* switch (message.getSeverity())
|
||||
{
|
||||
case CStatusMessage::SeverityDebug: color = "teal"; break;
|
||||
case CStatusMessage::SeverityInfo: color = "cyan"; break;
|
||||
case CStatusMessage::SeverityDebug: color = "teal"; break;
|
||||
case CStatusMessage::SeverityInfo: color = "cyan"; break;
|
||||
case CStatusMessage::SeverityWarning: color = "orange"; break;
|
||||
case CStatusMessage::SeverityError: color = "red"; break;
|
||||
case CStatusMessage::SeverityError: color = "red"; break;
|
||||
} */
|
||||
|
||||
m_serviceProxy->addTextMessage("swift: " + message.getMessage(), color.redF(), color.greenF(), color.blueF());
|
||||
@@ -1052,6 +1122,7 @@ namespace BlackSimPlugin
|
||||
}
|
||||
|
||||
const CCallsignSet logCallsigns = this->getLogCallsigns();
|
||||
static const QString hint("remote acft.");
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
const bool emptyCs = callsigns[i].isEmpty();
|
||||
@@ -1077,7 +1148,10 @@ namespace BlackSimPlugin
|
||||
CLength(cgValue, CLengthUnit::m(), CLengthUnit::ft());
|
||||
|
||||
// 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
|
||||
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()
|
||||
{
|
||||
if (this->isConnected()) { m_serviceProxy->updateAirportsInRange(); }
|
||||
|
||||
@@ -144,6 +144,7 @@ namespace BlackSimPlugin
|
||||
virtual void resetAircraftStatistics() 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 void callbackReceivedRequestedElevation(const BlackMisc::Geo::CElevationPlane &plane, const BlackMisc::Aviation::CCallsign &callsign) override;
|
||||
//! @}
|
||||
|
||||
//! \copydoc BlackMisc::Simulation::ISimulationEnvironmentProvider::requestElevation
|
||||
@@ -235,6 +236,15 @@ namespace BlackSimPlugin
|
||||
//! Settings have changed
|
||||
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;
|
||||
BlackMisc::CSetting<BlackMisc::Simulation::Settings::TXSwiftBusSettings> m_xSwiftBusServerSettings { this, &CSimulatorXPlane::onXSwiftBusSettingsChanged };
|
||||
static constexpr qint64 TimeoutAdding = 10000;
|
||||
@@ -253,9 +263,10 @@ namespace BlackSimPlugin
|
||||
BlackMisc::Aviation::CAirportList m_airportsInRange; //!< aiports in range of own aircraft
|
||||
CXPlaneMPAircraftObjects m_xplaneAircraftObjects; //!< XPlane multiplayer aircraft
|
||||
|
||||
BlackMisc::Simulation::CSimulatedAircraftList m_pendingToBeAddedAircraft; //!< aircraft to be added
|
||||
QHash<BlackMisc::Aviation::CCallsign, qint64> m_addingInProgressAircraft; //!< aircraft just adding
|
||||
BlackMisc::Simulation::CSimulatedAircraftList m_aircraftAddedFailed; //!< aircraft for which adding failed
|
||||
BlackMisc::Simulation::CSimulatedAircraftList m_pendingToBeAddedAircraft; //!< aircraft to be added
|
||||
QHash<BlackMisc::Aviation::CCallsign, qint64> m_addingInProgressAircraft; //!< aircraft just adding
|
||||
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
|
||||
|
||||
// statistics
|
||||
|
||||
Reference in New Issue
Block a user