Ref T436, underflow detection for FSX

* utility functions
* force gnd flag to avoid underflow
This commit is contained in:
Klaus Basan
2018-11-22 01:17:33 +01:00
parent f6e04d4488
commit 7f7cf2e031
5 changed files with 63 additions and 4 deletions

View File

@@ -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);

View File

@@ -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");

View File

@@ -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);

View File

@@ -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<DWORD>(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())
{

View File

@@ -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