mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 23:05:36 +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
|
||||
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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user