mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-24 06:25:37 +08:00
Ref T436, underflow detection for FSX
* utility functions * force gnd flag to avoid underflow
This commit is contained in:
@@ -233,6 +233,9 @@ namespace BlackCore
|
|||||||
//! \sa ISimulator::callbackReceivedRequestedElevation
|
//! \sa ISimulator::callbackReceivedRequestedElevation
|
||||||
virtual bool requestElevation(const BlackMisc::Geo::ICoordinateGeodetic &reference, const BlackMisc::Aviation::CCallsign &callsign) override;
|
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
|
//! A requested elevation has been received
|
||||||
//! \remark public for testing purposes
|
//! \remark public for testing purposes
|
||||||
virtual void callbackReceivedRequestedElevation(const BlackMisc::Geo::CElevationPlane &plane, const BlackMisc::Aviation::CCallsign &callsign);
|
virtual void callbackReceivedRequestedElevation(const BlackMisc::Geo::CElevationPlane &plane, const BlackMisc::Aviation::CCallsign &callsign);
|
||||||
|
|||||||
@@ -149,6 +149,21 @@ namespace BlackMisc
|
|||||||
return unknown;
|
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)
|
const QString &CAircraftSituation::gndElevationInfoToString(GndElevationInfo details)
|
||||||
{
|
{
|
||||||
static const QString noDetails("no details");
|
static const QString noDetails("no details");
|
||||||
|
|||||||
@@ -499,6 +499,9 @@ namespace BlackMisc
|
|||||||
//! Enum to string
|
//! Enum to string
|
||||||
static const QString &altitudeCorrectionToString(AltitudeCorrection correction);
|
static const QString &altitudeCorrectionToString(AltitudeCorrection correction);
|
||||||
|
|
||||||
|
//! Means corrected altitude?
|
||||||
|
static bool isCorrectedAltitude(AltitudeCorrection correction);
|
||||||
|
|
||||||
//! Enum to string
|
//! Enum to string
|
||||||
static const QString &gndElevationInfoToString(GndElevationInfo details);
|
static const QString &gndElevationInfoToString(GndElevationInfo details);
|
||||||
|
|
||||||
|
|||||||
@@ -1400,6 +1400,7 @@ namespace BlackSimPlugin
|
|||||||
// reset timer
|
// reset timer
|
||||||
m_simObjectTimer.start(AddPendingAircraftIntervalMs); // restart
|
m_simObjectTimer.start(AddPendingAircraftIntervalMs); // restart
|
||||||
|
|
||||||
|
// remove outdated objects
|
||||||
const CSimConnectObjects outdatedAdded = m_simConnectObjects.removeOutdatedPendingAdded(CSimConnectObject::AllTypes);
|
const CSimConnectObjects outdatedAdded = m_simConnectObjects.removeOutdatedPendingAdded(CSimConnectObject::AllTypes);
|
||||||
if (!outdatedAdded.isEmpty())
|
if (!outdatedAdded.isEmpty())
|
||||||
{
|
{
|
||||||
@@ -1509,7 +1510,14 @@ namespace BlackSimPlugin
|
|||||||
// FSX/P3D adding
|
// FSX/P3D adding
|
||||||
bool adding = false; // will be added flag
|
bool adding = false; // will be added flag
|
||||||
const SIMCONNECT_DATA_REQUEST_ID requestId = probe ? this->obtainRequestIdForSimObjTerrainProbe() : this->obtainRequestIdForSimObjAircraft();
|
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());
|
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))); }
|
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_AICreateSimulatedObject(m_hSimConnect, modelStringBa.constData(), initialPosition, requestId) :
|
||||||
SimConnect_AICreateNonATCAircraft(m_hSimConnect, modelStringBa.constData(), csBa.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))
|
if (isFailure(hr))
|
||||||
{
|
{
|
||||||
const CStatusMessage msg = CStatusMessage(this).error("SimConnect, can not create AI traffic: '%1' '%2'") << callsign.toQString() << modelString;
|
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.isGeodeticHeightNull(), Q_FUNC_INFO, "Missing height (altitude)");
|
||||||
Q_ASSERT_X(!situation.isPositionNull(), Q_FUNC_INFO, "Missing position");
|
Q_ASSERT_X(!situation.isPositionNull(), Q_FUNC_INFO, "Missing position");
|
||||||
|
|
||||||
// lat/Lng, NO PBH
|
// lat/Lng, NO PBH
|
||||||
|
CAircraftSituation::AltitudeCorrection altCorrection = CAircraftSituation::UnknownCorrection;
|
||||||
SIMCONNECT_DATA_INITPOSITION position = CSimulatorFsxCommon::coordinateToFsxPosition(situation);
|
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
|
// MSFS has inverted pitch and bank angles
|
||||||
position.Pitch = -situation.getPitch().value(CAngleUnit::deg());
|
position.Pitch = -situation.getPitch().value(CAngleUnit::deg());
|
||||||
@@ -2042,12 +2060,30 @@ namespace BlackSimPlugin
|
|||||||
position.Airspeed = static_cast<DWORD>(qRound(gsKts));
|
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);
|
const bool onGround = (situation.getOnGround() == CAircraftSituation::OnGround);
|
||||||
position.OnGround = onGround ? 1U : 0U;
|
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
|
// crosscheck
|
||||||
if (CBuildConfig::isLocalDeveloperDebugBuild())
|
if (CBuildConfig::isLocalDeveloperDebugBuild())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -294,7 +294,9 @@ namespace BlackSimPlugin
|
|||||||
|
|
||||||
//! Format conversion
|
//! Format conversion
|
||||||
//! \note must be valid situation
|
//! \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
|
//! Format conversion
|
||||||
//! \note must be valid situation
|
//! \note must be valid situation
|
||||||
|
|||||||
Reference in New Issue
Block a user