From 7f7cf2e03160cd161878a5d8a5509007cc5d9e6d Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Thu, 22 Nov 2018 01:17:33 +0100 Subject: [PATCH] Ref T436, underflow detection for FSX * utility functions * force gnd flag to avoid underflow --- src/blackcore/simulator.h | 3 ++ src/blackmisc/aviation/aircraftsituation.cpp | 15 +++++++ src/blackmisc/aviation/aircraftsituation.h | 3 ++ .../fsxcommon/simulatorfsxcommon.cpp | 42 +++++++++++++++++-- .../simulator/fsxcommon/simulatorfsxcommon.h | 4 +- 5 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/blackcore/simulator.h b/src/blackcore/simulator.h index bc5c6e316..8457c664b 100644 --- a/src/blackcore/simulator.h +++ b/src/blackcore/simulator.h @@ -233,6 +233,9 @@ namespace BlackCore //! \sa ISimulator::callbackReceivedRequestedElevation virtual bool requestElevation(const BlackMisc::Geo::ICoordinateGeodetic &reference, const BlackMisc::Aviation::CCallsign &callsign) override; + //! \copydoc BlackMisc::Simulation::ISimulationEnvironmentProvider::requestElevation + bool requestElevation(const BlackMisc::Aviation::CAircraftSituation &situation) { return this->requestElevation(situation, situation.getCallsign()); } + //! A requested elevation has been received //! \remark public for testing purposes virtual void callbackReceivedRequestedElevation(const BlackMisc::Geo::CElevationPlane &plane, const BlackMisc::Aviation::CCallsign &callsign); diff --git a/src/blackmisc/aviation/aircraftsituation.cpp b/src/blackmisc/aviation/aircraftsituation.cpp index 96180bd1f..90fbb2a3d 100644 --- a/src/blackmisc/aviation/aircraftsituation.cpp +++ b/src/blackmisc/aviation/aircraftsituation.cpp @@ -149,6 +149,21 @@ namespace BlackMisc return unknown; } + bool CAircraftSituation::isCorrectedAltitude(CAircraftSituation::AltitudeCorrection correction) + { + switch (correction) + { + case Underflow: + case DraggedToGround: + return true; + case NoElevation: + case NoCorrection: + case AGL: + default: break; + } + return false; + } + const QString &CAircraftSituation::gndElevationInfoToString(GndElevationInfo details) { static const QString noDetails("no details"); diff --git a/src/blackmisc/aviation/aircraftsituation.h b/src/blackmisc/aviation/aircraftsituation.h index a2cdf5aac..ec04def0b 100644 --- a/src/blackmisc/aviation/aircraftsituation.h +++ b/src/blackmisc/aviation/aircraftsituation.h @@ -499,6 +499,9 @@ namespace BlackMisc //! Enum to string static const QString &altitudeCorrectionToString(AltitudeCorrection correction); + //! Means corrected altitude? + static bool isCorrectedAltitude(AltitudeCorrection correction); + //! Enum to string static const QString &gndElevationInfoToString(GndElevationInfo details); diff --git a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp index 76170eb5a..2314c46c9 100644 --- a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp +++ b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp @@ -1400,6 +1400,7 @@ namespace BlackSimPlugin // reset timer m_simObjectTimer.start(AddPendingAircraftIntervalMs); // restart + // remove outdated objects const CSimConnectObjects outdatedAdded = m_simConnectObjects.removeOutdatedPendingAdded(CSimConnectObject::AllTypes); if (!outdatedAdded.isEmpty()) { @@ -1509,7 +1510,14 @@ namespace BlackSimPlugin // FSX/P3D adding bool adding = false; // will be added flag const SIMCONNECT_DATA_REQUEST_ID requestId = probe ? this->obtainRequestIdForSimObjTerrainProbe() : this->obtainRequestIdForSimObjAircraft(); - const SIMCONNECT_DATA_INITPOSITION initialPosition = CSimulatorFsxCommon::aircraftSituationToFsxPosition(newRemoteAircraft.getSituation(), sendGround); + + // under flow can cause a model not to be added + // FSX: underflow and NO(!) gnd flag can cause adding/remove issue + // P3D: underflow did not cause such issue + CStatusMessage underflowStatus; + const CAircraftSituation initialSituation = newRemoteAircraft.getSituation(); + const SIMCONNECT_DATA_INITPOSITION initialPosition = CSimulatorFsxCommon::aircraftSituationToFsxPosition(initialSituation, sendGround, true, &underflowStatus); + const QString modelString(newRemoteAircraft.getModelString()); if (this->showDebugLogMessage()) { this->debugLogMessage(Q_FUNC_INFO, QString("CS: '%1' model: '%2' request: %3, init pos: %4").arg(callsign.toQString(), modelString).arg(requestId).arg(fsxPositionToString(initialPosition))); } @@ -1519,6 +1527,11 @@ namespace BlackSimPlugin SimConnect_AICreateSimulatedObject(m_hSimConnect, modelStringBa.constData(), initialPosition, requestId) : SimConnect_AICreateNonATCAircraft(m_hSimConnect, modelStringBa.constData(), csBa.constData(), initialPosition, requestId); + if (!underflowStatus.isEmpty()) + { + CStatusMessage(this).warning("Underflow detecion for '%1', details '%2'") << callsign.asString() << underflowStatus.getMessage(); + } + if (isFailure(hr)) { const CStatusMessage msg = CStatusMessage(this).error("SimConnect, can not create AI traffic: '%1' '%2'") << callsign.toQString() << modelString; @@ -2013,13 +2026,18 @@ namespace BlackSimPlugin }); } - SIMCONNECT_DATA_INITPOSITION CSimulatorFsxCommon::aircraftSituationToFsxPosition(const CAircraftSituation &situation, bool sendGnd) + SIMCONNECT_DATA_INITPOSITION CSimulatorFsxCommon::aircraftSituationToFsxPosition(const CAircraftSituation &situation, bool sendGnd, bool forceUnderflowDetection, CStatusMessage *details) { Q_ASSERT_X(!situation.isGeodeticHeightNull(), Q_FUNC_INFO, "Missing height (altitude)"); Q_ASSERT_X(!situation.isPositionNull(), Q_FUNC_INFO, "Missing position"); // lat/Lng, NO PBH + CAircraftSituation::AltitudeCorrection altCorrection = CAircraftSituation::UnknownCorrection; SIMCONNECT_DATA_INITPOSITION position = CSimulatorFsxCommon::coordinateToFsxPosition(situation); + if (forceUnderflowDetection) + { + position.Altitude = situation.getCorrectedAltitude(true, &altCorrection).value(CLengthUnit::ft()); + } // MSFS has inverted pitch and bank angles position.Pitch = -situation.getPitch().value(CAngleUnit::deg()); @@ -2042,12 +2060,30 @@ namespace BlackSimPlugin position.Airspeed = static_cast(qRound(gsKts)); } - if (sendGnd && situation.isOnGroundInfoAvailable()) + // send GND flag also when underflow detection is available + if ((sendGnd || forceUnderflowDetection) && situation.isOnGroundInfoAvailable()) { const bool onGround = (situation.getOnGround() == CAircraftSituation::OnGround); position.OnGround = onGround ? 1U : 0U; } + // if we have no GND flag yet (gnd flag prevents underflow) + if (forceUnderflowDetection && position.OnGround == 0 && !CAircraftSituation::isCorrectedAltitude(altCorrection)) + { + // logical resolution failed so far, likely we have no CG or elevantion + // primitive guessing + do + { + if (position.Airspeed < 2) + { + position.OnGround = 1U; + if (details) { *details = CStatusMessage(getLogCategories()).warning("Force GND flag for underflow protection"); } + break; + } + } + while (false); + } + // crosscheck if (CBuildConfig::isLocalDeveloperDebugBuild()) { diff --git a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.h b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.h index 810f13ecc..def41b8f1 100644 --- a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.h +++ b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.h @@ -294,7 +294,9 @@ namespace BlackSimPlugin //! Format conversion //! \note must be valid situation - static SIMCONNECT_DATA_INITPOSITION aircraftSituationToFsxPosition(const BlackMisc::Aviation::CAircraftSituation &situation, bool sendGnd = true); + static SIMCONNECT_DATA_INITPOSITION aircraftSituationToFsxPosition( + const BlackMisc::Aviation::CAircraftSituation &situation, bool sendGnd = true, + bool forceUnderflowDetection = false, BlackMisc::CStatusMessage *details = nullptr); //! Format conversion //! \note must be valid situation