mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-05-06 02:16:04 +08:00
refs #840, FSX driver: get ground elevation from simulator
* fixed wrong request id * made functions private where possible * added data definitions for simobject data
This commit is contained in:
committed by
Mathew Sutcliffe
parent
be297d8ccf
commit
93a18f433c
@@ -16,7 +16,6 @@ namespace BlackSimPlugin
|
|||||||
{
|
{
|
||||||
namespace Fsx
|
namespace Fsx
|
||||||
{
|
{
|
||||||
|
|
||||||
CSimConnectDefinitions::CSimConnectDefinitions() { }
|
CSimConnectDefinitions::CSimConnectDefinitions() { }
|
||||||
|
|
||||||
HRESULT CSimConnectDefinitions::initDataDefinitionsWhenConnected(const HANDLE hSimConnect)
|
HRESULT CSimConnectDefinitions::initDataDefinitionsWhenConnected(const HANDLE hSimConnect)
|
||||||
@@ -24,6 +23,7 @@ namespace BlackSimPlugin
|
|||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
hr += initOwnAircraft(hSimConnect);
|
hr += initOwnAircraft(hSimConnect);
|
||||||
hr += initRemoteAircraft(hSimConnect);
|
hr += initRemoteAircraft(hSimConnect);
|
||||||
|
hr += initRemoteAircraftSimData(hSimConnect);
|
||||||
hr += initSimulatorEnvironment(hSimConnect);
|
hr += initSimulatorEnvironment(hSimConnect);
|
||||||
hr += initSbDataArea(hSimConnect);
|
hr += initSbDataArea(hSimConnect);
|
||||||
return hr;
|
return hr;
|
||||||
@@ -32,14 +32,14 @@ namespace BlackSimPlugin
|
|||||||
HRESULT CSimConnectDefinitions::initOwnAircraft(const HANDLE hSimConnect)
|
HRESULT CSimConnectDefinitions::initOwnAircraft(const HANDLE hSimConnect)
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "Plane Latitude", "Degrees");
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "PLANE LATITUDE", "Degrees");
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "Plane Longitude", "Degrees");
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "PLANE LONGITUDE", "Degrees");
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "Plane Altitude", "Feet");
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "PLANE ALTITUDE", "Feet");
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "Plane Heading Degrees True", "Degrees");
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "PLANE HEADING DEGREES TRUE", "Degrees");
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "Plane Pitch Degrees", "Degrees");
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "PLANE PITCH DEGREES", "Degrees");
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "Plane Bank Degrees", "Degrees");
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "PLANE BANK DEGREES", "Degrees");
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "GROUND VELOCITY", "Knots");
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "GROUND VELOCITY", "Knots");
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "GROUND ALTITUDE", "Meters");
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "GROUND ALTITUDE", "Feet");
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "SIM ON GROUND", "Bool");
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "SIM ON GROUND", "Bool");
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "LIGHT STROBE", "Bool");
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "LIGHT STROBE", "Bool");
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "LIGHT LANDING", "Bool");
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "LIGHT LANDING", "Bool");
|
||||||
@@ -106,7 +106,21 @@ namespace BlackSimPlugin
|
|||||||
{
|
{
|
||||||
CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr)).error("SimConnect error: initRemoteAircraftSituation %1") << hr;
|
CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr)).error("SimConnect error: initRemoteAircraftSituation %1") << hr;
|
||||||
}
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CSimConnectDefinitions::initRemoteAircraftSimData(const HANDLE hSimConnect)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftSimData, "PLANE LATITUDE", "degrees");
|
||||||
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftSimData, "PLANE LONGITUDE", "degrees");
|
||||||
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftSimData, "PLANE ALTITUDE", "Feet");
|
||||||
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftSimData, "GROUND ALTITUDE", "Feet");
|
||||||
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftSimData, "STATIC CG TO GROUND", "Feet");
|
||||||
|
if (hr != S_OK)
|
||||||
|
{
|
||||||
|
CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr)).error("SimConnect error: initRemoteAircraftSimData %1") << hr;
|
||||||
|
}
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,6 +176,5 @@ namespace BlackSimPlugin
|
|||||||
}
|
}
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace BlackSimPlugin
|
|||||||
double pitch; //!< Pitch (deg)
|
double pitch; //!< Pitch (deg)
|
||||||
double bank; //!< Bank (deg)
|
double bank; //!< Bank (deg)
|
||||||
double velocity; //!< Ground velocity
|
double velocity; //!< Ground velocity
|
||||||
double elevation; //!< Elevation (m)
|
double elevation; //!< Elevation (ft)
|
||||||
double simOnGround; //!< Is aircraft on ground?
|
double simOnGround; //!< Is aircraft on ground?
|
||||||
|
|
||||||
double lightStrobe; //!< Is strobe light on?
|
double lightStrobe; //!< Is strobe light on?
|
||||||
@@ -92,6 +92,19 @@ namespace BlackSimPlugin
|
|||||||
double engine4Combustion; //!< Engine 4 combustion flag
|
double engine4Combustion; //!< Engine 4 combustion flag
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//! Data for AI object sent back from simulator
|
||||||
|
struct DataDefinitionRemoteAircraftSimData
|
||||||
|
{
|
||||||
|
double latitude; //!< Latitude (deg)
|
||||||
|
double longitude; //!< Longitude (deg)
|
||||||
|
double altitude; //!< Altitude (ft)
|
||||||
|
double elevation; //!< Elevation (ft)
|
||||||
|
double cgToGround; //!< CG to ground (ft)
|
||||||
|
|
||||||
|
//! Above ground ft
|
||||||
|
double aboveGround() const { return altitude - elevation; }
|
||||||
|
};
|
||||||
|
|
||||||
//! Data struct simulator environment
|
//! Data struct simulator environment
|
||||||
struct DataDefinitionSimEnvironment
|
struct DataDefinitionSimEnvironment
|
||||||
{
|
{
|
||||||
@@ -142,6 +155,7 @@ namespace BlackSimPlugin
|
|||||||
DataOwnAircraftTitle,
|
DataOwnAircraftTitle,
|
||||||
DataRemoteAircraftParts,
|
DataRemoteAircraftParts,
|
||||||
DataRemoteAircraftPosition,
|
DataRemoteAircraftPosition,
|
||||||
|
DataRemoteAircraftSimData,
|
||||||
DataSimEnvironment,
|
DataSimEnvironment,
|
||||||
DataClientAreaSb, //!< whole SB area
|
DataClientAreaSb, //!< whole SB area
|
||||||
DataClientAreaSbIdent, //!< ident single value
|
DataClientAreaSbIdent, //!< ident single value
|
||||||
@@ -156,6 +170,7 @@ namespace BlackSimPlugin
|
|||||||
RequestOwnAircraftTitle,
|
RequestOwnAircraftTitle,
|
||||||
RequestSimEnvironment,
|
RequestSimEnvironment,
|
||||||
RequestSbData, //!< SB client area / XPDR mode
|
RequestSbData, //!< SB client area / XPDR mode
|
||||||
|
RequestEndMarker //!< free request ids can start here
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Constructor
|
//! Constructor
|
||||||
@@ -171,9 +186,12 @@ namespace BlackSimPlugin
|
|||||||
//! Initialize data definition for our own aircraft
|
//! Initialize data definition for our own aircraft
|
||||||
static HRESULT initOwnAircraft(const HANDLE hSimConnect);
|
static HRESULT initOwnAircraft(const HANDLE hSimConnect);
|
||||||
|
|
||||||
//! Initialize data definition for remote aircrafts
|
//! Initialize data definition for remote aircraft
|
||||||
static HRESULT initRemoteAircraft(const HANDLE hSimConnect);
|
static HRESULT initRemoteAircraft(const HANDLE hSimConnect);
|
||||||
|
|
||||||
|
//! Initialize data for remote aircraft queried from simulator
|
||||||
|
static HRESULT initRemoteAircraftSimData(const HANDLE hSimConnect);
|
||||||
|
|
||||||
//! Initialize data definition for Simulator environment
|
//! Initialize data definition for Simulator environment
|
||||||
static HRESULT initSimulatorEnvironment(const HANDLE hSimConnect);
|
static HRESULT initSimulatorEnvironment(const HANDLE hSimConnect);
|
||||||
|
|
||||||
|
|||||||
@@ -75,6 +75,15 @@ namespace BlackSimPlugin
|
|||||||
return CSimConnectObject();
|
return CSimConnectObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CSimConnectObject CSimConnectObjects::getSimObjectForRequestId(DWORD requestId) const
|
||||||
|
{
|
||||||
|
for (const CSimConnectObject &simObject : this->values())
|
||||||
|
{
|
||||||
|
if (simObject.getRequestId() == requestId) { return simObject; }
|
||||||
|
}
|
||||||
|
return CSimConnectObject();
|
||||||
|
}
|
||||||
|
|
||||||
bool CSimConnectObjects::isKnownSimObjectId(DWORD objectId) const
|
bool CSimConnectObjects::isKnownSimObjectId(DWORD objectId) const
|
||||||
{
|
{
|
||||||
const CSimConnectObject simObject(getSimObjectForObjectId(objectId));
|
const CSimConnectObject simObject(getSimObjectForObjectId(objectId));
|
||||||
|
|||||||
@@ -16,8 +16,7 @@
|
|||||||
#include "simconnect/SimConnect.h"
|
#include "simconnect/SimConnect.h"
|
||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
|
|
||||||
namespace BlackMisc { class IInterpolator; }
|
namespace BlackMisc { namespace Simulation { class IInterpolator; } }
|
||||||
|
|
||||||
namespace BlackSimPlugin
|
namespace BlackSimPlugin
|
||||||
{
|
{
|
||||||
namespace Fsx
|
namespace Fsx
|
||||||
@@ -44,6 +43,12 @@ namespace BlackSimPlugin
|
|||||||
//! Simulated aircraft model string
|
//! Simulated aircraft model string
|
||||||
const QString &getAircraftModelString() const { return m_aircraft.getModelString(); }
|
const QString &getAircraftModelString() const { return m_aircraft.getModelString(); }
|
||||||
|
|
||||||
|
//! How often do we request data from simulator for this remote aircraft
|
||||||
|
SIMCONNECT_PERIOD getSimDataPeriod() const { return m_requestSimDataPeriod; }
|
||||||
|
|
||||||
|
//! How often do we request data from simulator for this remote aircraft
|
||||||
|
void setSimDataPeriod(SIMCONNECT_PERIOD period) { m_requestSimDataPeriod = period; }
|
||||||
|
|
||||||
//! Set Simconnect request id
|
//! Set Simconnect request id
|
||||||
void setRequestId(DWORD id) { m_requestId = id; m_validRequestId = true; }
|
void setRequestId(DWORD id) { m_requestId = id; m_validRequestId = true; }
|
||||||
|
|
||||||
@@ -87,6 +92,7 @@ namespace BlackSimPlugin
|
|||||||
BlackMisc::Simulation::CSimulatedAircraft m_aircraft;
|
BlackMisc::Simulation::CSimulatedAircraft m_aircraft;
|
||||||
DWORD m_requestId = 0;
|
DWORD m_requestId = 0;
|
||||||
DWORD m_objectId = 0;
|
DWORD m_objectId = 0;
|
||||||
|
SIMCONNECT_PERIOD m_requestSimDataPeriod = SIMCONNECT_PERIOD_NEVER; //!< how often do we query ground elevation
|
||||||
bool m_validRequestId = false;
|
bool m_validRequestId = false;
|
||||||
bool m_validObjectId = false;
|
bool m_validObjectId = false;
|
||||||
bool m_confirmedAdded = false;
|
bool m_confirmedAdded = false;
|
||||||
@@ -103,9 +109,12 @@ namespace BlackSimPlugin
|
|||||||
//! Find which callsign belongs to the object id
|
//! Find which callsign belongs to the object id
|
||||||
BlackMisc::Aviation::CCallsign getCallsignForObjectId(DWORD objectId) const;
|
BlackMisc::Aviation::CCallsign getCallsignForObjectId(DWORD objectId) const;
|
||||||
|
|
||||||
//! Find which callsign belongs to the object id
|
//! Get object per object id
|
||||||
CSimConnectObject getSimObjectForObjectId(DWORD objectId) const;
|
CSimConnectObject getSimObjectForObjectId(DWORD objectId) const;
|
||||||
|
|
||||||
|
//! Get object per request id
|
||||||
|
CSimConnectObject getSimObjectForRequestId(DWORD requestId) const;
|
||||||
|
|
||||||
//! Is the object id one of our AI objects?
|
//! Is the object id one of our AI objects?
|
||||||
bool isKnownSimObjectId(DWORD objectId) const;
|
bool isKnownSimObjectId(DWORD objectId) const;
|
||||||
|
|
||||||
|
|||||||
@@ -9,13 +9,15 @@
|
|||||||
|
|
||||||
#include "simulatorfsx.h"
|
#include "simulatorfsx.h"
|
||||||
#include "blackcore/application.h"
|
#include "blackcore/application.h"
|
||||||
#include "blackmisc/interpolatorlinear.h"
|
|
||||||
#include "blackmisc/network/textmessage.h"
|
#include "blackmisc/network/textmessage.h"
|
||||||
#include "blackmisc/simulation/fscommon/bcdconversions.h"
|
#include "blackmisc/simulation/fscommon/bcdconversions.h"
|
||||||
#include "blackmisc/simulation/fsx/simconnectutilities.h"
|
#include "blackmisc/simulation/fsx/simconnectutilities.h"
|
||||||
#include "blackmisc/simulation/simulatorplugininfo.h"
|
|
||||||
#include "blackmisc/simulation/aircraftmodel.h"
|
#include "blackmisc/simulation/aircraftmodel.h"
|
||||||
|
#include "blackmisc/simulation/interpolatorlinear.h"
|
||||||
|
#include "blackmisc/simulation/interpolationhints.h"
|
||||||
|
#include "blackmisc/simulation/simulatorplugininfo.h"
|
||||||
#include "blackmisc/aviation/airportlist.h"
|
#include "blackmisc/aviation/airportlist.h"
|
||||||
|
#include "blackmisc/geo/elevationplane.h"
|
||||||
#include "blackmisc/logmessage.h"
|
#include "blackmisc/logmessage.h"
|
||||||
#include "blackmisc/threadutils.h"
|
#include "blackmisc/threadutils.h"
|
||||||
#include "blackmisc/verify.h"
|
#include "blackmisc/verify.h"
|
||||||
@@ -49,11 +51,11 @@ namespace BlackSimPlugin
|
|||||||
Q_ASSERT_X(ownAircraftProvider, Q_FUNC_INFO, "Missing provider");
|
Q_ASSERT_X(ownAircraftProvider, Q_FUNC_INFO, "Missing provider");
|
||||||
Q_ASSERT_X(remoteAircraftProvider, Q_FUNC_INFO, "Missing provider");
|
Q_ASSERT_X(remoteAircraftProvider, Q_FUNC_INFO, "Missing provider");
|
||||||
Q_ASSERT_X(sApp, Q_FUNC_INFO, "Missing global object");
|
Q_ASSERT_X(sApp, Q_FUNC_INFO, "Missing global object");
|
||||||
this->m_realityBubbleTimer.setInterval(20 * 1000);
|
m_realityBubbleTimer.setInterval(20 * 1000);
|
||||||
connect(&m_realityBubbleTimer, &QTimer::timeout, this, &CSimulatorFsx::ps_addAircraftCurrentlyOutOfBubble);
|
connect(&m_realityBubbleTimer, &QTimer::timeout, this, &CSimulatorFsx::ps_addAircraftCurrentlyOutOfBubble);
|
||||||
|
|
||||||
m_useFsuipc = true; // Temporarily enabled until Simconnect Weather is implemented.
|
m_useFsuipc = true; // Temporarily enabled until Simconnect Weather is implemented.
|
||||||
this->m_interpolator = new CInterpolatorLinear(remoteAircraftProvider, this);
|
m_interpolator = new CInterpolatorLinear(remoteAircraftProvider, this);
|
||||||
m_defaultModel =
|
m_defaultModel =
|
||||||
{
|
{
|
||||||
"Boeing 737-800 Paint1",
|
"Boeing 737-800 Paint1",
|
||||||
@@ -155,8 +157,8 @@ namespace BlackSimPlugin
|
|||||||
// initial position if interpolator has data, otherwise do nothing
|
// initial position if interpolator has data, otherwise do nothing
|
||||||
setInitialAircraftSituation(addedAircraft); // set interpolated data/parts if available
|
setInitialAircraftSituation(addedAircraft); // set interpolated data/parts if available
|
||||||
|
|
||||||
const DWORD requestId = m_requestId++;
|
const DWORD requestId = obtainRequestId();
|
||||||
SIMCONNECT_DATA_INITPOSITION initialPosition = aircraftSituationToFsxPosition(addedAircraft.getSituation());
|
SIMCONNECT_DATA_INITPOSITION initialPosition = aircraftSituationToFsxPosition(addedAircraft.getSituation(), CInterpolationHints());
|
||||||
const QString modelString(addedAircraft.getModelString());
|
const QString modelString(addedAircraft.getModelString());
|
||||||
|
|
||||||
if (m_interpolationRenderingSetup.showSimulatorDebugMessages())
|
if (m_interpolationRenderingSetup.showSimulatorDebugMessages())
|
||||||
@@ -195,9 +197,9 @@ namespace BlackSimPlugin
|
|||||||
if (!this->isSimulating()) { return false; }
|
if (!this->isSimulating()) { return false; }
|
||||||
|
|
||||||
// actually those data should be the same as ownAircraft
|
// actually those data should be the same as ownAircraft
|
||||||
CComSystem newCom1 = ownAircraft.getCom1System();
|
const CComSystem newCom1 = ownAircraft.getCom1System();
|
||||||
CComSystem newCom2 = ownAircraft.getCom2System();
|
const CComSystem newCom2 = ownAircraft.getCom2System();
|
||||||
CTransponder newTransponder = ownAircraft.getTransponder();
|
const CTransponder newTransponder = ownAircraft.getTransponder();
|
||||||
|
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
if (newCom1.getFrequencyActive() != this->m_simCom1.getFrequencyActive())
|
if (newCom1.getFrequencyActive() != this->m_simCom1.getFrequencyActive())
|
||||||
@@ -356,7 +358,7 @@ namespace BlackSimPlugin
|
|||||||
|
|
||||||
void CSimulatorFsx::onSimStopped()
|
void CSimulatorFsx::onSimStopped()
|
||||||
{
|
{
|
||||||
int oldStatus = getSimulatorStatus();
|
const int oldStatus = getSimulatorStatus();
|
||||||
m_simSimulating = false;
|
m_simSimulating = false;
|
||||||
emitSimulatorCombinedStatus(oldStatus);
|
emitSimulatorCombinedStatus(oldStatus);
|
||||||
}
|
}
|
||||||
@@ -372,6 +374,18 @@ namespace BlackSimPlugin
|
|||||||
disconnectFrom();
|
disconnectFrom();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD CSimulatorFsx::obtainRequestId()
|
||||||
|
{
|
||||||
|
DWORD id = m_requestId++;
|
||||||
|
if (id < FirstRequestId)
|
||||||
|
{
|
||||||
|
// overflow, restart
|
||||||
|
id = FirstRequestId;
|
||||||
|
m_requestId = FirstRequestId + 1;
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
void CSimulatorFsx::updateOwnAircraftFromSimulator(const DataDefinitionOwnAircraft &simulatorOwnAircraft)
|
void CSimulatorFsx::updateOwnAircraftFromSimulator(const DataDefinitionOwnAircraft &simulatorOwnAircraft)
|
||||||
{
|
{
|
||||||
CSimulatedAircraft myAircraft(getOwnAircraft());
|
CSimulatedAircraft myAircraft(getOwnAircraft());
|
||||||
@@ -390,26 +404,29 @@ namespace BlackSimPlugin
|
|||||||
aircraftSituation.setBank(CAngle(-simulatorOwnAircraft.bank, CAngleUnit::deg()));
|
aircraftSituation.setBank(CAngle(-simulatorOwnAircraft.bank, CAngleUnit::deg()));
|
||||||
aircraftSituation.setHeading(CHeading(simulatorOwnAircraft.trueHeading, CHeading::True, CAngleUnit::deg()));
|
aircraftSituation.setHeading(CHeading(simulatorOwnAircraft.trueHeading, CHeading::True, CAngleUnit::deg()));
|
||||||
aircraftSituation.setGroundSpeed(CSpeed(simulatorOwnAircraft.velocity, CSpeedUnit::kts()));
|
aircraftSituation.setGroundSpeed(CSpeed(simulatorOwnAircraft.velocity, CSpeedUnit::kts()));
|
||||||
aircraftSituation.setGroundElevation(CAltitude(simulatorOwnAircraft.elevation, CAltitude::MeanSeaLevel, CLengthUnit::m()));
|
aircraftSituation.setGroundElevation(CAltitude(simulatorOwnAircraft.elevation, CAltitude::MeanSeaLevel, CLengthUnit::ft()));
|
||||||
aircraftSituation.setAltitude(CAltitude(simulatorOwnAircraft.altitude, CAltitude::MeanSeaLevel, CLengthUnit::ft()));
|
aircraftSituation.setAltitude(CAltitude(simulatorOwnAircraft.altitude, CAltitude::MeanSeaLevel, CLengthUnit::ft()));
|
||||||
|
|
||||||
CAircraftLights lights(simulatorOwnAircraft.lightStrobe,
|
const CAircraftLights lights(simulatorOwnAircraft.lightStrobe,
|
||||||
simulatorOwnAircraft.lightLanding,
|
simulatorOwnAircraft.lightLanding,
|
||||||
simulatorOwnAircraft.lightTaxi,
|
simulatorOwnAircraft.lightTaxi,
|
||||||
simulatorOwnAircraft.lightBeacon,
|
simulatorOwnAircraft.lightBeacon,
|
||||||
simulatorOwnAircraft.lightNav,
|
simulatorOwnAircraft.lightNav,
|
||||||
simulatorOwnAircraft.lightLogo);
|
simulatorOwnAircraft.lightLogo);
|
||||||
|
|
||||||
QList<bool> helperList {simulatorOwnAircraft.engine1Combustion != 0, simulatorOwnAircraft.engine2Combustion != 0,
|
|
||||||
simulatorOwnAircraft.engine3Combustion != 0, simulatorOwnAircraft.engine4Combustion != 0 };
|
|
||||||
|
|
||||||
CAircraftEngineList engines;
|
CAircraftEngineList engines;
|
||||||
|
const QList<bool> helperList
|
||||||
|
{
|
||||||
|
simulatorOwnAircraft.engine1Combustion != 0, simulatorOwnAircraft.engine2Combustion != 0,
|
||||||
|
simulatorOwnAircraft.engine3Combustion != 0, simulatorOwnAircraft.engine4Combustion != 0
|
||||||
|
};
|
||||||
|
|
||||||
for (int index = 0; index < simulatorOwnAircraft.numberOfEngines; ++index)
|
for (int index = 0; index < simulatorOwnAircraft.numberOfEngines; ++index)
|
||||||
{
|
{
|
||||||
engines.push_back(CAircraftEngine(index + 1, helperList.at(index)));
|
engines.push_back(CAircraftEngine(index + 1, helperList.at(index)));
|
||||||
}
|
}
|
||||||
|
|
||||||
CAircraftParts parts(lights, simulatorOwnAircraft.gearHandlePosition,
|
const CAircraftParts parts(lights, simulatorOwnAircraft.gearHandlePosition,
|
||||||
simulatorOwnAircraft.flapsHandlePosition * 100,
|
simulatorOwnAircraft.flapsHandlePosition * 100,
|
||||||
simulatorOwnAircraft.spoilersHandlePosition,
|
simulatorOwnAircraft.spoilersHandlePosition,
|
||||||
engines,
|
engines,
|
||||||
@@ -463,6 +480,39 @@ namespace BlackSimPlugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSimulatorFsx::updateRemoteAircraftFromSimulator(const CSimConnectObject &simObject, const DataDefinitionRemoteAircraftSimData &remoteAircraftData)
|
||||||
|
{
|
||||||
|
CInterpolationHints &hints = m_hints[simObject.getCallsign()];
|
||||||
|
|
||||||
|
// we only need elevation near ground, in other cases we ignore it
|
||||||
|
if (remoteAircraftData.aboveGround() <= 100.0)
|
||||||
|
{
|
||||||
|
CElevationPlane elevation(remoteAircraftData.latitude, remoteAircraftData.longitude, remoteAircraftData.elevation);
|
||||||
|
elevation.setSinglePointRadius();
|
||||||
|
|
||||||
|
// const QString debug(hints.debugInfo(elevation));
|
||||||
|
hints.setElevation(elevation); // update elevation
|
||||||
|
hints.setCGAboveGround({ remoteAircraftData.cgToGround, CLengthUnit::ft() });
|
||||||
|
|
||||||
|
// set it in the remote aircraft provider
|
||||||
|
this->updateAircraftGroundElevation(simObject.getCallsign(), elevation);
|
||||||
|
// switch to fast updates
|
||||||
|
if (simObject.getSimDataPeriod() != SIMCONNECT_PERIOD_VISUAL_FRAME)
|
||||||
|
{
|
||||||
|
this->requestDataForSimObject(simObject, SIMCONNECT_PERIOD_VISUAL_FRAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hints.resetElevation();
|
||||||
|
// switch to slow updates
|
||||||
|
if (simObject.getSimDataPeriod() != SIMCONNECT_PERIOD_SECOND)
|
||||||
|
{
|
||||||
|
this->requestDataForSimObject(simObject, SIMCONNECT_PERIOD_SECOND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CSimulatorFsx::updateOwnAircraftFromSimulator(const DataDefinitionClientAreaSb &sbDataArea)
|
void CSimulatorFsx::updateOwnAircraftFromSimulator(const DataDefinitionClientAreaSb &sbDataArea)
|
||||||
{
|
{
|
||||||
CTransponder::TransponderMode newMode;
|
CTransponder::TransponderMode newMode;
|
||||||
@@ -475,7 +525,7 @@ namespace BlackSimPlugin
|
|||||||
newMode = sbDataArea.isStandby() ? CTransponder::StateStandby : CTransponder::ModeC;
|
newMode = sbDataArea.isStandby() ? CTransponder::StateStandby : CTransponder::ModeC;
|
||||||
}
|
}
|
||||||
const CSimulatedAircraft myAircraft(this->getOwnAircraft());
|
const CSimulatedAircraft myAircraft(this->getOwnAircraft());
|
||||||
bool changed = (myAircraft.getTransponderMode() != newMode);
|
const bool changed = (myAircraft.getTransponderMode() != newMode);
|
||||||
if (!changed) { return; }
|
if (!changed) { return; }
|
||||||
CTransponder xpdr = myAircraft.getTransponder();
|
CTransponder xpdr = myAircraft.getTransponder();
|
||||||
xpdr.setTransponderMode(newMode);
|
xpdr.setTransponderMode(newMode);
|
||||||
@@ -511,7 +561,7 @@ namespace BlackSimPlugin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// P3D also has SimConnect_AIReleaseControlEx;
|
// P3D also has SimConnect_AIReleaseControlEx;
|
||||||
DWORD requestId = m_requestId++;
|
const DWORD requestId = obtainRequestId();
|
||||||
HRESULT hr = SimConnect_AIReleaseControl(m_hSimConnect, objectId, static_cast<SIMCONNECT_DATA_REQUEST_ID>(requestId));
|
HRESULT hr = SimConnect_AIReleaseControl(m_hSimConnect, objectId, static_cast<SIMCONNECT_DATA_REQUEST_ID>(requestId));
|
||||||
if (hr == S_OK)
|
if (hr == S_OK)
|
||||||
{
|
{
|
||||||
@@ -683,6 +733,7 @@ namespace BlackSimPlugin
|
|||||||
|
|
||||||
// call in SIM
|
// call in SIM
|
||||||
SimConnect_AIRemoveObject(m_hSimConnect, static_cast<SIMCONNECT_OBJECT_ID>(simObject.getObjectId()), static_cast<SIMCONNECT_DATA_REQUEST_ID>(m_requestId++));
|
SimConnect_AIRemoveObject(m_hSimConnect, static_cast<SIMCONNECT_OBJECT_ID>(simObject.getObjectId()), static_cast<SIMCONNECT_DATA_REQUEST_ID>(m_requestId++));
|
||||||
|
m_hints.remove(simObject.getCallsign());
|
||||||
|
|
||||||
// mark in provider
|
// mark in provider
|
||||||
bool updated = updateAircraftRendered(callsign, false);
|
bool updated = updateAircraftRendered(callsign, false);
|
||||||
@@ -809,7 +860,6 @@ namespace BlackSimPlugin
|
|||||||
// values used for position and parts
|
// values used for position and parts
|
||||||
bool isOnGround = false;
|
bool isOnGround = false;
|
||||||
const qint64 currentTimestamp = QDateTime::currentMSecsSinceEpoch();
|
const qint64 currentTimestamp = QDateTime::currentMSecsSinceEpoch();
|
||||||
const CCallsignSet aircraftWithParts(this->remoteAircraftSupportingParts()); // optimization, fetch all parts supporting aircraft in one step (one lock)
|
|
||||||
|
|
||||||
const QList<CSimConnectObject> simObjects(m_simConnectObjects.values());
|
const QList<CSimConnectObject> simObjects(m_simConnectObjects.values());
|
||||||
for (const CSimConnectObject &simObj : simObjects)
|
for (const CSimConnectObject &simObj : simObjects)
|
||||||
@@ -823,43 +873,13 @@ namespace BlackSimPlugin
|
|||||||
Q_ASSERT_X(simObj.hasValidRequestAndObjectId(), Q_FUNC_INFO, "Missing ids");
|
Q_ASSERT_X(simObj.hasValidRequestAndObjectId(), Q_FUNC_INFO, "Missing ids");
|
||||||
|
|
||||||
IInterpolator::InterpolationStatus interpolatorStatus;
|
IInterpolator::InterpolationStatus interpolatorStatus;
|
||||||
const CAircraftSituation interpolatedSituation = this->m_interpolator->getInterpolatedSituation(callsign, currentTimestamp, simObj.isVtol(), interpolatorStatus);
|
const CInterpolationHints hints(m_hints[simObj.getCallsign()]);
|
||||||
|
const CAircraftSituation interpolatedSituation = this->m_interpolator->getInterpolatedSituation(callsign, currentTimestamp, hints, interpolatorStatus);
|
||||||
// having the onGround flag in parts forces me to obtain parts here
|
|
||||||
// which is not the smartest thing regarding performance
|
|
||||||
IInterpolator::PartsStatus partsStatus;
|
|
||||||
partsStatus.setSupportsParts(enableAircraftParts && aircraftWithParts.contains(callsign));
|
|
||||||
CAircraftPartsList parts;
|
|
||||||
if (enableAircraftParts && partsStatus.allTrue())
|
|
||||||
{
|
|
||||||
parts = this->m_interpolator->getPartsBeforeTime(callsign, interpolatedSituation.getMSecsSinceEpoch(), partsStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interpolatorStatus.allTrue())
|
if (interpolatorStatus.allTrue())
|
||||||
{
|
{
|
||||||
// update situation
|
// update situation
|
||||||
SIMCONNECT_DATA_INITPOSITION position = aircraftSituationToFsxPosition(interpolatedSituation);
|
SIMCONNECT_DATA_INITPOSITION position = aircraftSituationToFsxPosition(interpolatedSituation, hints);
|
||||||
|
|
||||||
//! \fixme The onGround in parts is no ideal, as already mentioned in the discussion
|
|
||||||
// a) I am forced to read parts even if I just want to update position
|
|
||||||
// b) Unlike the other values it is not a fire and forget value, as I need it again in the next cycle
|
|
||||||
if (partsStatus.isSupportingParts() && !parts.isEmpty())
|
|
||||||
{
|
|
||||||
// we have parts, and use the closest ground
|
|
||||||
|
|
||||||
// \fixme onGround flag is not synchronized with positions and causes jumps during takeoff/landing.
|
|
||||||
// We need to find a better way to synchronize both. Until then, use it for a very small speed range only.
|
|
||||||
// This covers taxiing aircraft as well as a hovering helicopter.
|
|
||||||
double groundSpeedKnots = interpolatedSituation.getGroundSpeed().value(CSpeedUnit::kts());
|
|
||||||
if (groundSpeedKnots < 50) { isOnGround = parts.front().isOnGround(); }
|
|
||||||
else { isOnGround = interpolatedSituation.isOnGroundGuessed(); }
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
isOnGround = interpolatedSituation.isOnGroundGuessed();
|
|
||||||
}
|
|
||||||
|
|
||||||
position.OnGround = isOnGround ? 1U : 0U;
|
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
hr += SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPosition,
|
hr += SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPosition,
|
||||||
static_cast<SIMCONNECT_OBJECT_ID>(simObj.getObjectId()), 0, 0,
|
static_cast<SIMCONNECT_OBJECT_ID>(simObj.getObjectId()), 0, 0,
|
||||||
@@ -873,10 +893,16 @@ namespace BlackSimPlugin
|
|||||||
|
|
||||||
if (interpolatorStatus.didInterpolationSucceed())
|
if (interpolatorStatus.didInterpolationSucceed())
|
||||||
{
|
{
|
||||||
|
const CCallsignSet aircraftWithParts(this->remoteAircraftSupportingParts()); // optimization, fetch all parts supporting aircraft in one step (one lock)
|
||||||
|
IInterpolator::PartsStatus partsStatus;
|
||||||
|
partsStatus.setSupportsParts(enableAircraftParts && aircraftWithParts.contains(callsign));
|
||||||
|
|
||||||
// aircraft parts inside "interpolator if", as no parts can be set without situation
|
// aircraft parts inside "interpolator if", as no parts can be set without situation
|
||||||
// situation is used to anticipate parts if other client does not send them
|
// situation is used to anticipate parts if other client does not send them
|
||||||
if (enableAircraftParts)
|
if (enableAircraftParts)
|
||||||
{
|
{
|
||||||
|
CAircraftPartsList parts;
|
||||||
|
parts = this->m_interpolator->getPartsBeforeTime(callsign, interpolatedSituation.getMSecsSinceEpoch(), partsStatus);
|
||||||
updateRemoteAircraftParts(simObj, parts, partsStatus, interpolatedSituation, isOnGround); // update and retrieve parts in the same step
|
updateRemoteAircraftParts(simObj, parts, partsStatus, interpolatedSituation, isOnGround); // update and retrieve parts in the same step
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -971,22 +997,20 @@ namespace BlackSimPlugin
|
|||||||
return hr == S_OK;
|
return hr == S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SIMCONNECT_DATA_INITPOSITION CSimulatorFsx::aircraftSituationToFsxPosition(const CAircraftSituation &situation, bool guessOnGround)
|
SIMCONNECT_DATA_INITPOSITION CSimulatorFsx::aircraftSituationToFsxPosition(const CAircraftSituation &situation, const CInterpolationHints &hints)
|
||||||
{
|
{
|
||||||
SIMCONNECT_DATA_INITPOSITION position;
|
SIMCONNECT_DATA_INITPOSITION position;
|
||||||
position.Latitude = situation.latitude().value(CAngleUnit::deg());
|
position.Latitude = situation.latitude().value(CAngleUnit::deg());
|
||||||
position.Longitude = situation.longitude().value(CAngleUnit::deg());
|
position.Longitude = situation.longitude().value(CAngleUnit::deg());
|
||||||
position.Altitude = situation.getAltitude().value(CLengthUnit::ft());
|
position.Altitude = situation.getCorrectedAltitude(hints.getCGAboveGround()).value(CLengthUnit::ft());
|
||||||
|
position.Heading = situation.getHeading().value(CAngleUnit::deg());
|
||||||
|
position.Airspeed = situation.getGroundSpeed().value(CSpeedUnit::kts());
|
||||||
|
|
||||||
// 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());
|
||||||
position.Bank = -situation.getBank().value(CAngleUnit::deg());
|
position.Bank = -situation.getBank().value(CAngleUnit::deg());
|
||||||
position.Heading = situation.getHeading().value(CAngleUnit::deg());
|
|
||||||
position.Airspeed = situation.getGroundSpeed().value(CSpeedUnit::kts());
|
const bool onGround = situation.isOnGroundGuessed(hints.getCGAboveGround());
|
||||||
bool onGround = false;
|
|
||||||
if (guessOnGround)
|
|
||||||
{
|
|
||||||
onGround = situation.isOnGroundGuessed();
|
|
||||||
}
|
|
||||||
position.OnGround = onGround ? 1U : 0U;
|
position.OnGround = onGround ? 1U : 0U;
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
@@ -1047,6 +1071,21 @@ namespace BlackSimPlugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CSimulatorFsx::requestDataForSimObject(const CSimConnectObject &simObject, SIMCONNECT_PERIOD period)
|
||||||
|
{
|
||||||
|
if (!simObject.hasValidRequestAndObjectId()) { return false; }
|
||||||
|
if (simObject.getSimDataPeriod() == period) { return true; } // already queried like this
|
||||||
|
|
||||||
|
const HRESULT result = SimConnect_RequestDataOnSimObject(m_hSimConnect, simObject.getRequestId(), CSimConnectDefinitions::DataRemoteAircraftSimData, simObject.getObjectId(), period, SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED);
|
||||||
|
if (result == S_OK)
|
||||||
|
{
|
||||||
|
m_simConnectObjects[simObject.getCallsign()].setSimDataPeriod(period);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
CLogMessage(this).error("Cannot request data on object '%1'") << simObject.getObjectId();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void CSimulatorFsx::initInternalsObject()
|
void CSimulatorFsx::initInternalsObject()
|
||||||
{
|
{
|
||||||
CSimulatorFsCommon::initInternalsObject();
|
CSimulatorFsCommon::initInternalsObject();
|
||||||
@@ -1068,7 +1107,7 @@ namespace BlackSimPlugin
|
|||||||
m_syncDeferredCounter = 0;
|
m_syncDeferredCounter = 0;
|
||||||
m_skipCockpitUpdateCycles = 0;
|
m_skipCockpitUpdateCycles = 0;
|
||||||
m_interpolationRequest = 0;
|
m_interpolationRequest = 0;
|
||||||
m_requestId = 1;
|
m_requestId = FirstRequestId;
|
||||||
m_dispatchErrors = 0;
|
m_dispatchErrors = 0;
|
||||||
m_receiveExceptionCount = 0;
|
m_receiveExceptionCount = 0;
|
||||||
CSimulatorFsCommon::reset();
|
CSimulatorFsCommon::reset();
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
#include "simconnectobject.h"
|
#include "simconnectobject.h"
|
||||||
#include "../fscommon/simulatorfscommon.h"
|
#include "../fscommon/simulatorfscommon.h"
|
||||||
#include "blackcore/simulator.h"
|
#include "blackcore/simulator.h"
|
||||||
#include "blackmisc/interpolatorlinear.h"
|
#include "blackmisc/simulation/interpolatorlinear.h"
|
||||||
#include "blackmisc/simulation/simulatorplugininfo.h"
|
#include "blackmisc/simulation/simulatorplugininfo.h"
|
||||||
#include "blackmisc/simulation/simulatorsettings.h"
|
#include "blackmisc/simulation/simulatorsettings.h"
|
||||||
#include "blackmisc/simulation/aircraftmodel.h"
|
#include "blackmisc/simulation/aircraftmodel.h"
|
||||||
@@ -102,27 +102,6 @@ namespace BlackSimPlugin
|
|||||||
virtual BlackMisc::Aviation::CCallsignSet physicallyRenderedAircraft() const override;
|
virtual BlackMisc::Aviation::CCallsignSet physicallyRenderedAircraft() const override;
|
||||||
//! @}
|
//! @}
|
||||||
|
|
||||||
//! Display receive exceptions?
|
|
||||||
bool stillDisplayReceiveExceptions();
|
|
||||||
|
|
||||||
//! Called when data about our own aircraft are received
|
|
||||||
void updateOwnAircraftFromSimulator(const DataDefinitionOwnAircraft &simulatorOwnAircraft);
|
|
||||||
|
|
||||||
//! Update from SB client area
|
|
||||||
void updateOwnAircraftFromSimulator(const DataDefinitionClientAreaSb &sbDataArea);
|
|
||||||
|
|
||||||
//! An AI aircraft was added in the simulator
|
|
||||||
bool simulatorReportedObjectAdded(DWORD objectID);
|
|
||||||
|
|
||||||
//! Simulator reported that AI aircraft was removed
|
|
||||||
bool simulatorReportedObjectRemoved(DWORD objectID);
|
|
||||||
|
|
||||||
//! Set ID of a SimConnect object, so far we only have an request id in the object
|
|
||||||
bool setSimConnectObjectId(DWORD requestID, DWORD objectID);
|
|
||||||
|
|
||||||
//! The simconnect related objects
|
|
||||||
const CSimConnectObjects &getSimConnectObjects() const { return m_simConnectObjects; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \name Interface implementations
|
//! \name Interface implementations
|
||||||
//! @{
|
//! @{
|
||||||
@@ -149,7 +128,8 @@ namespace BlackSimPlugin
|
|||||||
//! \remark kind of cleanup function, in an ideal this should never need to cleanup something
|
//! \remark kind of cleanup function, in an ideal this should never need to cleanup something
|
||||||
BlackMisc::Aviation::CCallsignSet ps_physicallyRemoveAircraftNotInProvider();
|
BlackMisc::Aviation::CCallsignSet ps_physicallyRemoveAircraftNotInProvider();
|
||||||
|
|
||||||
//! Handle that an object has been added
|
//! Handle that an object has been added in simulator
|
||||||
|
//! \remark checks if the object was really added after an add request and not directly removed again
|
||||||
bool ps_deferredSimulatorReportedObjectAdded(const BlackMisc::Aviation::CCallsign &callsign);
|
bool ps_deferredSimulatorReportedObjectAdded(const BlackMisc::Aviation::CCallsign &callsign);
|
||||||
|
|
||||||
//! Try to add the aircraft currently out of bubble
|
//! Try to add the aircraft currently out of bubble
|
||||||
@@ -171,6 +151,9 @@ namespace BlackSimPlugin
|
|||||||
//! Simulator is going down
|
//! Simulator is going down
|
||||||
void onSimExit();
|
void onSimExit();
|
||||||
|
|
||||||
|
//! Get new request id, overflow safe
|
||||||
|
DWORD obtainRequestId();
|
||||||
|
|
||||||
//! Init when connected
|
//! Init when connected
|
||||||
HRESULT initWhenConnected();
|
HRESULT initWhenConnected();
|
||||||
|
|
||||||
@@ -185,10 +168,34 @@ namespace BlackSimPlugin
|
|||||||
|
|
||||||
//! Update remote airacraft parts (send to FSX)
|
//! Update remote airacraft parts (send to FSX)
|
||||||
bool updateRemoteAircraftParts(const CSimConnectObject &simObj, const BlackMisc::Aviation::CAircraftPartsList &parts,
|
bool updateRemoteAircraftParts(const CSimConnectObject &simObj, const BlackMisc::Aviation::CAircraftPartsList &parts,
|
||||||
BlackMisc::IInterpolator::PartsStatus partsStatus, const BlackMisc::Aviation::CAircraftSituation &interpolatedSituation, bool isOnGround) const;
|
BlackMisc::Simulation::IInterpolator::PartsStatus partsStatus, const BlackMisc::Aviation::CAircraftSituation &interpolatedSituation, bool isOnGround) const;
|
||||||
|
|
||||||
|
//! Called when data about our own aircraft are received
|
||||||
|
void updateOwnAircraftFromSimulator(const DataDefinitionOwnAircraft &simulatorOwnAircraft);
|
||||||
|
|
||||||
|
//! Remote aircraft data sent from simulator
|
||||||
|
void updateRemoteAircraftFromSimulator(const CSimConnectObject &simObject, const DataDefinitionRemoteAircraftSimData &remoteAircraftData);
|
||||||
|
|
||||||
|
//! Update from SB client area
|
||||||
|
void updateOwnAircraftFromSimulator(const DataDefinitionClientAreaSb &sbDataArea);
|
||||||
|
|
||||||
|
//! An AI aircraft was added in the simulator
|
||||||
|
bool simulatorReportedObjectAdded(DWORD objectID);
|
||||||
|
|
||||||
|
//! Simulator reported that AI aircraft was removed
|
||||||
|
bool simulatorReportedObjectRemoved(DWORD objectID);
|
||||||
|
|
||||||
|
//! Set ID of a SimConnect object, so far we only have an request id in the object
|
||||||
|
bool setSimConnectObjectId(DWORD requestID, DWORD objectID);
|
||||||
|
|
||||||
|
//! Display receive exceptions?
|
||||||
|
bool stillDisplayReceiveExceptions();
|
||||||
|
|
||||||
|
//! The simconnect related objects
|
||||||
|
const CSimConnectObjects &getSimConnectObjects() const { return m_simConnectObjects; }
|
||||||
|
|
||||||
//! Format conversion
|
//! Format conversion
|
||||||
SIMCONNECT_DATA_INITPOSITION aircraftSituationToFsxPosition(const BlackMisc::Aviation::CAircraftSituation &situation, bool guessOnGround = true);
|
SIMCONNECT_DATA_INITPOSITION aircraftSituationToFsxPosition(const BlackMisc::Aviation::CAircraftSituation &situation, const BlackMisc::Simulation::CInterpolationHints &hints);
|
||||||
|
|
||||||
//! Sync time with user's computer
|
//! Sync time with user's computer
|
||||||
void synchronizeTime(const BlackMisc::PhysicalQuantities::CTime &zuluTimeSim, const BlackMisc::PhysicalQuantities::CTime &localTimeSim);
|
void synchronizeTime(const BlackMisc::PhysicalQuantities::CTime &zuluTimeSim, const BlackMisc::PhysicalQuantities::CTime &localTimeSim);
|
||||||
@@ -199,6 +206,9 @@ namespace BlackSimPlugin
|
|||||||
//! Reload weather settings
|
//! Reload weather settings
|
||||||
void reloadWeatherSettings();
|
void reloadWeatherSettings();
|
||||||
|
|
||||||
|
//! Request data for a simObject (aka remote aircraft)
|
||||||
|
bool requestDataForSimObject(const CSimConnectObject &simObject, SIMCONNECT_PERIOD period = SIMCONNECT_PERIOD_SECOND);
|
||||||
|
|
||||||
//! FSX position as string
|
//! FSX position as string
|
||||||
static QString fsxPositionToString(const SIMCONNECT_DATA_INITPOSITION &position);
|
static QString fsxPositionToString(const SIMCONNECT_DATA_INITPOSITION &position);
|
||||||
|
|
||||||
@@ -207,17 +217,19 @@ namespace BlackSimPlugin
|
|||||||
|
|
||||||
static constexpr int SkipUpdateCyclesForCockpit = 10; //!< skip x cycles before updating cockpit again
|
static constexpr int SkipUpdateCyclesForCockpit = 10; //!< skip x cycles before updating cockpit again
|
||||||
static constexpr int IgnoreReceiveExceptions = 10; //!< skip exceptions when displayed more than x times
|
static constexpr int IgnoreReceiveExceptions = 10; //!< skip exceptions when displayed more than x times
|
||||||
|
static constexpr int FirstRequestId = static_cast<int>(CSimConnectDefinitions::RequestEndMarker);
|
||||||
|
|
||||||
QString m_simConnectVersion; //!< SimConnect version
|
QString m_simConnectVersion; //!< SimConnect version
|
||||||
bool m_simConnected = false; //!< Is simulator connected?
|
bool m_simConnected = false; //!< Is simulator connected?
|
||||||
bool m_simSimulating = false; //!< Simulator running?
|
bool m_simSimulating = false; //!< Simulator running?
|
||||||
bool m_useSbOffsets = true; //!< with SB offsets
|
bool m_useSbOffsets = true; //!< with SB offsets
|
||||||
int m_syncDeferredCounter = 0; //!< Set when synchronized, used to wait some time
|
int m_syncDeferredCounter = 0; //!< Set when synchronized, used to wait some time
|
||||||
int m_simConnectTimerId = -1; //!< Timer identifier
|
int m_simConnectTimerId = -1; //!< Timer identifier
|
||||||
int m_skipCockpitUpdateCycles = 0; //!< Skip some update cycles to allow changes in simulator cockpit to be set
|
int m_skipCockpitUpdateCycles = 0; //!< skip some update cycles to allow changes in simulator cockpit to be set
|
||||||
int m_interpolationRequest = 0; //!< current interpolation request
|
int m_interpolationRequest = 0; //!< current interpolation request
|
||||||
int m_dispatchErrors = 0; //!< number of dispatched failed, \sa ps_dispatch
|
int m_dispatchErrors = 0; //!< number of dispatched failed, \sa ps_dispatch
|
||||||
int m_receiveExceptionCount = 0; //!< exceptions
|
int m_receiveExceptionCount = 0; //!< exceptions
|
||||||
DWORD m_requestId = 1; //!< request id
|
DWORD m_requestId = FirstRequestId; //!< request id, use obtainRequestId() to get id
|
||||||
HANDLE m_hSimConnect = nullptr; //!< handle to SimConnect object
|
HANDLE m_hSimConnect = nullptr; //!< handle to SimConnect object
|
||||||
CSimConnectObjects m_simConnectObjects; //!< AI objects and their object / request ids
|
CSimConnectObjects m_simConnectObjects; //!< AI objects and their object / request ids
|
||||||
BlackMisc::Simulation::CSimulatedAircraftList m_outOfRealityBubble; //!< aircraft removed by FSX because they are out of reality bubble
|
BlackMisc::Simulation::CSimulatedAircraftList m_outOfRealityBubble; //!< aircraft removed by FSX because they are out of reality bubble
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ namespace BlackSimPlugin
|
|||||||
{
|
{
|
||||||
case SystemEventSimStatus:
|
case SystemEventSimStatus:
|
||||||
{
|
{
|
||||||
bool running = event->dwData ? true : false;
|
const bool running = event->dwData ? true : false;
|
||||||
if (running)
|
if (running)
|
||||||
{
|
{
|
||||||
simulatorFsx->onSimRunning();
|
simulatorFsx->onSimRunning();
|
||||||
@@ -95,7 +95,7 @@ namespace BlackSimPlugin
|
|||||||
}
|
}
|
||||||
case SystemEventPause:
|
case SystemEventPause:
|
||||||
{
|
{
|
||||||
bool p = event->dwData ? true : false;
|
const bool p = event->dwData ? true : false;
|
||||||
if (simulatorFsx->m_simPaused != p)
|
if (simulatorFsx->m_simPaused != p)
|
||||||
{
|
{
|
||||||
simulatorFsx->m_simPaused = p;
|
simulatorFsx->m_simPaused = p;
|
||||||
@@ -110,7 +110,7 @@ namespace BlackSimPlugin
|
|||||||
}
|
}
|
||||||
case SIMCONNECT_RECV_ID_EVENT_OBJECT_ADDREMOVE:
|
case SIMCONNECT_RECV_ID_EVENT_OBJECT_ADDREMOVE:
|
||||||
{
|
{
|
||||||
SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE *event = static_cast<SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE *>(pData);
|
const SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE *event = static_cast<SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE *>(pData);
|
||||||
const DWORD objectID = event->dwData;
|
const DWORD objectID = event->dwData;
|
||||||
const SIMCONNECT_SIMOBJECT_TYPE objectType = event->eObjType;
|
const SIMCONNECT_SIMOBJECT_TYPE objectType = event->eObjType;
|
||||||
if (objectType != SIMCONNECT_SIMOBJECT_TYPE_AIRCRAFT && objectType != SIMCONNECT_SIMOBJECT_TYPE_HELICOPTER)
|
if (objectType != SIMCONNECT_SIMOBJECT_TYPE_AIRCRAFT && objectType != SIMCONNECT_SIMOBJECT_TYPE_HELICOPTER)
|
||||||
@@ -151,25 +151,37 @@ namespace BlackSimPlugin
|
|||||||
case SIMCONNECT_RECV_ID_ASSIGNED_OBJECT_ID:
|
case SIMCONNECT_RECV_ID_ASSIGNED_OBJECT_ID:
|
||||||
{
|
{
|
||||||
SIMCONNECT_RECV_ASSIGNED_OBJECT_ID *event = static_cast<SIMCONNECT_RECV_ASSIGNED_OBJECT_ID *>(pData);
|
SIMCONNECT_RECV_ASSIGNED_OBJECT_ID *event = static_cast<SIMCONNECT_RECV_ASSIGNED_OBJECT_ID *>(pData);
|
||||||
const DWORD requestID = event->dwRequestID;
|
const DWORD requestId = event->dwRequestID;
|
||||||
const DWORD objectID = event->dwObjectID;
|
const DWORD objectId = event->dwObjectID;
|
||||||
bool success = simulatorFsx->setSimConnectObjectId(requestID, objectID);
|
bool success = simulatorFsx->setSimConnectObjectId(requestId, objectId);
|
||||||
if (!success) { break; } // not an request ID of ours
|
if (!success) { break; } // not an request ID of ours
|
||||||
|
|
||||||
success = simulatorFsx->simulatorReportedObjectAdded(objectID);
|
success = simulatorFsx->simulatorReportedObjectAdded(objectId);
|
||||||
if (!success)
|
if (success)
|
||||||
{
|
{
|
||||||
const CSimulatedAircraft remoteAircraft(simulatorFsx->getSimConnectObjects().getSimObjectForObjectId(objectID).getAircraft());
|
const CSimConnectObject simObject = simulatorFsx->getSimConnectObjects().getSimObjectForObjectId(objectId);
|
||||||
const CStatusMessage msg = CStatusMessage(simulatorFsx).error("Cannot add object %1") << objectID;
|
HRESULT result = simulatorFsx->requestDataForSimObject(simObject);
|
||||||
CLogMessage::preformatted(msg);
|
Q_UNUSED(result);
|
||||||
emit simulatorFsx->physicallyAddingRemoteModelFailed(remoteAircraft, msg);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const CSimulatedAircraft remoteAircraft(simulatorFsx->getSimConnectObjects().getSimObjectForObjectId(objectId).getAircraft());
|
||||||
|
const CStatusMessage msgAdd = CStatusMessage(simulatorFsx).error("Cannot add object %1") << objectId;
|
||||||
|
CLogMessage::preformatted(msgAdd);
|
||||||
|
emit simulatorFsx->physicallyAddingRemoteModelFailed(remoteAircraft, msgAdd);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SIMCONNECT_RECV_ID_SIMOBJECT_DATA_BYTYPE:
|
||||||
|
{
|
||||||
|
// SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE *pObjData = (SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE *)pData;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SIMCONNECT_RECV_ID_SIMOBJECT_DATA:
|
case SIMCONNECT_RECV_ID_SIMOBJECT_DATA:
|
||||||
{
|
{
|
||||||
SIMCONNECT_RECV_SIMOBJECT_DATA *pObjData = (SIMCONNECT_RECV_SIMOBJECT_DATA *) pData;
|
SIMCONNECT_RECV_SIMOBJECT_DATA *pObjData = (SIMCONNECT_RECV_SIMOBJECT_DATA *) pData;
|
||||||
switch (pObjData->dwRequestID)
|
const DWORD requestId = pObjData->dwRequestID;
|
||||||
|
switch (requestId)
|
||||||
{
|
{
|
||||||
case CSimConnectDefinitions::RequestOwnAircraft:
|
case CSimConnectDefinitions::RequestOwnAircraft:
|
||||||
{
|
{
|
||||||
@@ -203,6 +215,21 @@ namespace BlackSimPlugin
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
{
|
||||||
|
static_assert(sizeof(DataDefinitionRemoteAircraftSimData) == 5 * sizeof(double), "DataDefinitionRemoteAircraftSimData has an incorrect size.");
|
||||||
|
const CSimConnectObject simObj = simulatorFsx->getSimConnectObjects().getSimObjectForRequestId(requestId);
|
||||||
|
if (simObj.hasValidRequestAndObjectId())
|
||||||
|
{
|
||||||
|
const DWORD objectId = pObjData->dwObjectID;
|
||||||
|
const DataDefinitionRemoteAircraftSimData *remoteAircraftSimData = (DataDefinitionRemoteAircraftSimData *)&pObjData->dwData;
|
||||||
|
// extra check, but ids should be the same
|
||||||
|
if (objectId == simObj.getObjectId())
|
||||||
|
{
|
||||||
|
simulatorFsx->updateRemoteAircraftFromSimulator(simObj, *remoteAircraftSimData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user