mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-26 10:45:37 +08:00
refs #386, performance issues
* keep split per callsign map in IInterpolator (so it is available for all interpolators) * added signals to provider to add split situations / callsigns * adjustments to airspace / context for those signals * thread safe access to those from interpolator * renamed from rendered to remote aircraft as discussed * adjust samples * removed no longer required functions in timestampobjectlist
This commit is contained in:
@@ -126,16 +126,16 @@ namespace BlackCore
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
//--- signals for the provider, work locally only (not in DBus
|
//--- signals for the provider, work locally only (not in DBus)
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProviderReadOnly::addedRemoteAircraftSituation
|
//! \copydoc IRemoteAircraftProviderReadOnly::addedRemoteAircraftSituation
|
||||||
void addedRemoteAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation) override;
|
void addedRemoteAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation);
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProviderReadOnly::addedRemoteAircraftPart
|
//! \copydoc IRemoteAircraftProviderReadOnly::addedRemoteAircraftPart
|
||||||
void addedRemoteAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts) override;
|
void addedRemoteAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts);
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProviderReadOnly::removedAircraft
|
//! \copydoc IRemoteAircraftProviderReadOnly::removedAircraft
|
||||||
void removedAircraft(const BlackMisc::Aviation::CCallsign &callsign) override;
|
void removedRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign);
|
||||||
|
|
||||||
//! Online ATC stations were changed
|
//! Online ATC stations were changed
|
||||||
void changedAtcStationsOnline();
|
void changedAtcStationsOnline();
|
||||||
@@ -172,6 +172,7 @@ namespace BlackCore
|
|||||||
CVatsimDataFileReader *m_vatsimDataFileReader = nullptr;
|
CVatsimDataFileReader *m_vatsimDataFileReader = nullptr;
|
||||||
CAirspaceWatchdog m_atcWatchdog;
|
CAirspaceWatchdog m_atcWatchdog;
|
||||||
CAirspaceWatchdog m_aircraftWatchdog;
|
CAirspaceWatchdog m_aircraftWatchdog;
|
||||||
|
bool m_serverSupportsNameQuery = false; //!< not all servers support name query
|
||||||
|
|
||||||
// TODO FIXME (MS) should be in INetwork
|
// TODO FIXME (MS) should be in INetwork
|
||||||
void sendFsipiCustomPacket(const BlackMisc::Aviation::CCallsign &recipientCallsign) const;
|
void sendFsipiCustomPacket(const BlackMisc::Aviation::CCallsign &recipientCallsign) const;
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace BlackCore
|
|||||||
bool c = provider->connectRemoteAircraftProviderSignals(
|
bool c = provider->connectRemoteAircraftProviderSignals(
|
||||||
std::bind(&IInterpolator::ps_onAddedAircraftSituation, this, std::placeholders::_1),
|
std::bind(&IInterpolator::ps_onAddedAircraftSituation, this, std::placeholders::_1),
|
||||||
std::bind(&IInterpolator::ps_onAddedAircraftParts, this, std::placeholders::_1),
|
std::bind(&IInterpolator::ps_onAddedAircraftParts, this, std::placeholders::_1),
|
||||||
std::bind(&IInterpolator::ps_onRemoveAircraft, this, std::placeholders::_1)
|
std::bind(&IInterpolator::ps_onRemovedAircraft, this, std::placeholders::_1)
|
||||||
);
|
);
|
||||||
Q_ASSERT(c);
|
Q_ASSERT(c);
|
||||||
Q_UNUSED(c);
|
Q_UNUSED(c);
|
||||||
@@ -63,18 +63,19 @@ namespace BlackCore
|
|||||||
return partsList.latestValue();
|
return partsList.latestValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IInterpolator::requestSituationsCalculationsForAllCallsigns(int requestId)
|
void IInterpolator::syncRequestSituationsCalculationsForAllCallsigns(int requestId, qint64 currentTimeMsSinceEpoch)
|
||||||
{
|
{
|
||||||
QReadLocker l(&m_situationsLock);
|
QReadLocker l(&m_situationsLock);
|
||||||
Q_ASSERT(requestId >= 0);
|
Q_ASSERT(requestId >= 0);
|
||||||
const QHash<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftSituationList> situationsCopy = m_situationsByCallsign;
|
const QHash<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftSituationList> situationsCopy(m_situationsByCallsign);
|
||||||
l.unlock();
|
l.unlock();
|
||||||
|
|
||||||
CAircraftSituationList latestInterpolations;
|
CAircraftSituationList latestInterpolations;
|
||||||
|
if (currentTimeMsSinceEpoch < 0) { currentTimeMsSinceEpoch = QDateTime::currentMSecsSinceEpoch(); }
|
||||||
for (const CCallsign &cs : situationsCopy.keys())
|
for (const CCallsign &cs : situationsCopy.keys())
|
||||||
{
|
{
|
||||||
bool ok;
|
bool ok = false;
|
||||||
CAircraftSituation situation = getCurrentInterpolatedSituation(situationsCopy, cs, &ok);
|
CAircraftSituation situation = getCurrentInterpolatedSituation(situationsCopy, cs, currentTimeMsSinceEpoch, &ok);
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
latestInterpolations.push_back(situation);
|
latestInterpolations.push_back(situation);
|
||||||
@@ -92,15 +93,33 @@ namespace BlackCore
|
|||||||
m_requestedInterpolations.erase(--m_requestedInterpolations.end());
|
m_requestedInterpolations.erase(--m_requestedInterpolations.end());
|
||||||
}
|
}
|
||||||
m_requestedInterpolations.insert(requestId, latestInterpolations); // new to old
|
m_requestedInterpolations.insert(requestId, latestInterpolations); // new to old
|
||||||
|
if (m_withDebugMsg)
|
||||||
|
{
|
||||||
|
CLogMessage(this).debug() << "Added request" << requestId << "with" << latestInterpolations.size() << "interpolation(s)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IInterpolator::asyncRequestSituationsCalculationsForAllCallsigns(int requestId, qint64 currentTimeMsSinceEpoch)
|
||||||
|
{
|
||||||
|
Q_ASSERT(requestId >= 0);
|
||||||
|
QMetaObject::invokeMethod(this, "syncRequestSituationsCalculationsForAllCallsigns",
|
||||||
|
Qt::QueuedConnection, Q_ARG(int, requestId), Q_ARG(qint64, currentTimeMsSinceEpoch));
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<CCallsign, CAircraftSituationList> IInterpolator::getSituationsByCallsign() const
|
QHash<CCallsign, CAircraftSituationList> IInterpolator::getSituationsByCallsign() const
|
||||||
{
|
{
|
||||||
QReadLocker l(&m_requestedInterpolationsLock);
|
QReadLocker l(&m_situationsLock);
|
||||||
return m_situationsByCallsign;
|
return m_situationsByCallsign;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CAircraftSituationList IInterpolator::getSituationsForCallsign(const CCallsign &callsign) const
|
||||||
|
{
|
||||||
|
QReadLocker l(&m_situationsLock);
|
||||||
|
static const CAircraftSituationList empty;
|
||||||
|
if (!m_situationsByCallsign.contains(callsign)) { return empty; }
|
||||||
|
return m_situationsByCallsign[callsign];
|
||||||
|
}
|
||||||
|
|
||||||
int IInterpolator::latestFinishedRequestId() const
|
int IInterpolator::latestFinishedRequestId() const
|
||||||
{
|
{
|
||||||
QReadLocker l(&m_requestedInterpolationsLock);
|
QReadLocker l(&m_requestedInterpolationsLock);
|
||||||
@@ -132,41 +151,37 @@ namespace BlackCore
|
|||||||
void IInterpolator::ps_onAddedAircraftSituation(const CAircraftSituation &situation)
|
void IInterpolator::ps_onAddedAircraftSituation(const CAircraftSituation &situation)
|
||||||
{
|
{
|
||||||
QWriteLocker lock(&m_situationsLock);
|
QWriteLocker lock(&m_situationsLock);
|
||||||
Q_ASSERT(!situation.getCallsign().isEmpty());
|
const CCallsign callsign(situation.getCallsign());
|
||||||
if (this->m_withDebugMsg) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << situation; }
|
Q_ASSERT(!callsign.isEmpty());
|
||||||
|
if (callsign.isEmpty()) { return; }
|
||||||
|
if (this->m_withDebugMsg) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << situation.getCallsign() << situation.getMSecsSinceEpoch(); }
|
||||||
|
|
||||||
// list from new to old
|
// list from new to old
|
||||||
CAircraftSituationList &l = this->m_situationsByCallsign[situation.getCallsign()];
|
CAircraftSituationList &l = this->m_situationsByCallsign[callsign];
|
||||||
if (l.size() >= MaxSituationsPerCallsign - 1)
|
l.insertTimestampObject(situation, MaxSituationsPerCallsign);
|
||||||
{
|
|
||||||
l.truncate(MaxSituationsPerCallsign - 1);
|
|
||||||
}
|
|
||||||
l.insert(situation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void IInterpolator::ps_onAddedAircraftParts(const CAircraftParts &parts)
|
void IInterpolator::ps_onAddedAircraftParts(const CAircraftParts &parts)
|
||||||
{
|
{
|
||||||
QWriteLocker lock(&m_partsLock);
|
QWriteLocker lock(&m_partsLock);
|
||||||
Q_ASSERT(!parts.getCallsign().isEmpty());
|
const CCallsign callsign(parts.getCallsign());
|
||||||
if (this->m_withDebugMsg) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << parts; }
|
Q_ASSERT(!callsign.isEmpty());
|
||||||
|
if (callsign.isEmpty()) { return; }
|
||||||
|
if (this->m_withDebugMsg) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << parts.getCallsign() << parts.getMSecsSinceEpoch(); }
|
||||||
|
|
||||||
// list from new to old
|
// list from new to old
|
||||||
CAircraftPartsList &l = this->m_partsByCallsign[parts.getCallsign()];
|
CAircraftPartsList &l = this->m_partsByCallsign[callsign];
|
||||||
if (l.size() >= MaxPartsPerCallsign - 1)
|
l.insertTimestampObject(parts, MaxPartsPerCallsign);
|
||||||
{
|
|
||||||
l.truncate(MaxPartsPerCallsign - 1);
|
|
||||||
}
|
|
||||||
l.insert(parts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void IInterpolator::ps_onRemoveAircraft(const CCallsign &callsign)
|
void IInterpolator::ps_onRemovedAircraft(const CCallsign &callsign)
|
||||||
{
|
{
|
||||||
QWriteLocker ls(&m_situationsLock);
|
QWriteLocker ls(&m_situationsLock);
|
||||||
QWriteLocker lp(&m_partsLock);
|
QWriteLocker lp(&m_partsLock);
|
||||||
Q_ASSERT(!callsign.isEmpty());
|
Q_ASSERT(!callsign.isEmpty());
|
||||||
|
if (callsign.isEmpty()) { return; }
|
||||||
if (this->m_withDebugMsg) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign; }
|
if (this->m_withDebugMsg) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign; }
|
||||||
|
|
||||||
if (callsign.isEmpty()) { return; }
|
|
||||||
this->m_partsByCallsign.remove(callsign);
|
this->m_partsByCallsign.remove(callsign);
|
||||||
this->m_situationsByCallsign.remove(callsign);
|
this->m_situationsByCallsign.remove(callsign);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,28 +32,30 @@ namespace BlackCore
|
|||||||
//! Virtual destructor
|
//! Virtual destructor
|
||||||
virtual ~IInterpolator() {}
|
virtual ~IInterpolator() {}
|
||||||
|
|
||||||
|
//! Log category
|
||||||
|
static QString getMessageCategory() { return "swift.iinterpolator"; }
|
||||||
|
|
||||||
//! Has situations?
|
//! Has situations?
|
||||||
//! \deprecated Try no to use, it would be more efficient to directly getting the values and decide then
|
//! \deprecated Try not to use, it would be more efficient to directly getting the values and decide then
|
||||||
//! \threadsafe
|
//! \threadsafe
|
||||||
virtual bool hasEnoughAircraftSituations(const BlackMisc::Aviation::CCallsign &callsign) const;
|
virtual bool hasEnoughAircraftSituations(const BlackMisc::Aviation::CCallsign &callsign) const;
|
||||||
|
|
||||||
//! Current interpolated situation
|
//! Current interpolated situation
|
||||||
//! \threadsafe
|
//! \threadsafe
|
||||||
virtual BlackMisc::Aviation::CAircraftSituation getCurrentInterpolatedSituation(const QHash<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftSituationList> &allSituations, const BlackMisc::Aviation::CCallsign &callsign, bool *ok = nullptr) const = 0;
|
virtual BlackMisc::Aviation::CAircraftSituation getCurrentInterpolatedSituation(const QHash<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftSituationList> &allSituations, const BlackMisc::Aviation::CCallsign &callsign, qint64 currentTimeSinceEpoc = -1, bool *ok = nullptr) const = 0;
|
||||||
|
|
||||||
//! Latest parts before time - offset
|
//! Latest parts before time - offset
|
||||||
//! \threadsafe
|
//! \threadsafe
|
||||||
BlackMisc::Aviation::CAircraftParts getLatestPartsBeforeOffset(const BlackMisc::Aviation::CCallsign &callsign, qint64 timeOffset = TimeOffsetMs, bool *ok = nullptr) const;
|
BlackMisc::Aviation::CAircraftParts getLatestPartsBeforeOffset(const BlackMisc::Aviation::CCallsign &callsign, qint64 timeOffset = TimeOffsetMs, bool *ok = nullptr) const;
|
||||||
|
|
||||||
//! Do a complete calculation for all know callsigns in background.
|
|
||||||
//! Only use positive numbers.
|
|
||||||
//! \threadsafe
|
|
||||||
void requestSituationsCalculationsForAllCallsigns(int requestId);
|
|
||||||
|
|
||||||
//! The situations per callsign
|
//! The situations per callsign
|
||||||
//! \threadsafe
|
//! \threadsafe
|
||||||
QHash<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftSituationList> getSituationsByCallsign() const;
|
QHash<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftSituationList> getSituationsByCallsign() const;
|
||||||
|
|
||||||
|
//! Situations for given callsign
|
||||||
|
//! \threadsafe
|
||||||
|
BlackMisc::Aviation::CAircraftSituationList getSituationsForCallsign(const BlackMisc::Aviation::CCallsign &callsign) const;
|
||||||
|
|
||||||
//! Last finished request id, -1 means none
|
//! Last finished request id, -1 means none
|
||||||
//! \threadsafe
|
//! \threadsafe
|
||||||
int latestFinishedRequestId() const;
|
int latestFinishedRequestId() const;
|
||||||
@@ -66,11 +68,26 @@ namespace BlackCore
|
|||||||
//! \threadsafe
|
//! \threadsafe
|
||||||
BlackMisc::Aviation::CAircraftSituationList getRequest(int requestId, bool *ok = nullptr) const;
|
BlackMisc::Aviation::CAircraftSituationList getRequest(int requestId, bool *ok = nullptr) const;
|
||||||
|
|
||||||
|
//! Enable debug messages
|
||||||
|
void enableDebugMessages(bool enabled);
|
||||||
|
|
||||||
static const qint64 TimeOffsetMs = 6000; //!< offset for interpolation
|
static const qint64 TimeOffsetMs = 6000; //!< offset for interpolation
|
||||||
static const int MaxSituationsPerCallsign = 6; //!< How many situations per callsign
|
static const int MaxSituationsPerCallsign = 6; //!< How many situations per callsign
|
||||||
static const int MaxPartsPerCallsign = 3; //!< How many parts per callsign
|
static const int MaxPartsPerCallsign = 3; //!< How many parts per callsign
|
||||||
static const int MaxKeptInterpolationRequests = 3; //!< How many requests are stored
|
static const int MaxKeptInterpolationRequests = 3; //!< How many requests are stored
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
//! Do a complete calculation for all know callsigns in background.
|
||||||
|
//! Only use positive numbers.
|
||||||
|
//! \param currentTimeMsSinceEpoch if no value is passed current time is used
|
||||||
|
//! \threadsafe
|
||||||
|
void syncRequestSituationsCalculationsForAllCallsigns(int requestId, qint64 currentTimeMsSinceEpoch = -1);
|
||||||
|
|
||||||
|
//! Do a complete calculation for all know callsigns in background.
|
||||||
|
//! Non blocking call of \syncRequestSituationsCalculationsForAllCallsigns
|
||||||
|
//! \threadsafe
|
||||||
|
void asyncRequestSituationsCalculationsForAllCallsigns(int requestId, qint64 currentTimeMsSinceEpoch = -1);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
//! New situation got added
|
//! New situation got added
|
||||||
//! \threadsafe
|
//! \threadsafe
|
||||||
@@ -82,7 +99,7 @@ namespace BlackCore
|
|||||||
|
|
||||||
//! Removed aircraft
|
//! Removed aircraft
|
||||||
//! \threadsafe
|
//! \threadsafe
|
||||||
void ps_onRemoveAircraft(const BlackMisc::Aviation::CCallsign &callsign);
|
void ps_onRemovedAircraft(const BlackMisc::Aviation::CCallsign &callsign);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! Constructor
|
//! Constructor
|
||||||
@@ -94,7 +111,7 @@ namespace BlackCore
|
|||||||
//! \deprecated For first version
|
//! \deprecated For first version
|
||||||
QList<BlackMisc::Aviation::CAircraftSituationList> getSituationsTimeSplit(const BlackMisc::Aviation::CCallsign &callsign, qint64 splitTimeMsSinceEpoch) const;
|
QList<BlackMisc::Aviation::CAircraftSituationList> getSituationsTimeSplit(const BlackMisc::Aviation::CCallsign &callsign, qint64 splitTimeMsSinceEpoch) const;
|
||||||
|
|
||||||
bool m_withDebugMsg = true;
|
bool m_withDebugMsg = false; //!< allows to disable debug messages
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable QReadWriteLock m_situationsLock;
|
mutable QReadWriteLock m_situationsLock;
|
||||||
|
|||||||
@@ -9,8 +9,10 @@
|
|||||||
|
|
||||||
#include "interpolator_linear.h"
|
#include "interpolator_linear.h"
|
||||||
#include "blackmisc/avaircraftsituation.h"
|
#include "blackmisc/avaircraftsituation.h"
|
||||||
|
#include "blackmisc/logmessage.h"
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
|
||||||
|
using namespace BlackMisc;
|
||||||
using namespace BlackMisc::Geo;
|
using namespace BlackMisc::Geo;
|
||||||
using namespace BlackMisc::Math;
|
using namespace BlackMisc::Math;
|
||||||
using namespace BlackMisc::PhysicalQuantities;
|
using namespace BlackMisc::PhysicalQuantities;
|
||||||
@@ -18,64 +20,96 @@ using namespace BlackMisc::Aviation;
|
|||||||
|
|
||||||
namespace BlackCore
|
namespace BlackCore
|
||||||
{
|
{
|
||||||
CAircraftSituation CInterpolatorLinear::getCurrentInterpolatedSituation(const QHash<CCallsign, CAircraftSituationList> &allSituations, const CCallsign &callsign, bool *ok) const
|
CAircraftSituation CInterpolatorLinear::getCurrentInterpolatedSituation(const QHash<CCallsign, CAircraftSituationList> &allSituations, const CCallsign &callsign, qint64 currentTimeMsSinceEpoc, bool *ok) const
|
||||||
{
|
{
|
||||||
const static CAircraftSituation empty;
|
const static CAircraftSituation empty;
|
||||||
qint64 splitTimeMsSinceEpoch = QDateTime::currentMSecsSinceEpoch() - TimeOffsetMs;
|
|
||||||
QList<CAircraftSituationList> splitSituations = allSituations[callsign].splitByTime(splitTimeMsSinceEpoch);
|
|
||||||
CAircraftSituationList &situationsBefore = splitSituations[0];
|
|
||||||
CAircraftSituationList &situationsAfter = splitSituations[1];
|
|
||||||
if (situationsBefore.isEmpty())
|
|
||||||
{
|
|
||||||
if (ok) { *ok = false; }
|
if (ok) { *ok = false; }
|
||||||
return empty;
|
if (!allSituations.contains(callsign)) { return empty; }
|
||||||
}
|
if (allSituations[callsign].isEmpty()) { return empty; }
|
||||||
|
|
||||||
CAircraftSituation beginSituation;
|
if (currentTimeMsSinceEpoc < 0) { currentTimeMsSinceEpoc = QDateTime::currentMSecsSinceEpoch(); }
|
||||||
CAircraftSituation endSituation;
|
qint64 splitTimeMsSinceEpoch = currentTimeMsSinceEpoc - TimeOffsetMs;
|
||||||
|
QList<CAircraftSituationList> splitSituations = allSituations[callsign].splitByTime(splitTimeMsSinceEpoch);
|
||||||
|
CAircraftSituationList &situationsNewer = splitSituations[0]; // latest first
|
||||||
|
CAircraftSituationList &situationsOlder = splitSituations[1]; // latest first
|
||||||
|
|
||||||
// The first condition covers a situation, when there is now future packet.
|
// interpolation situations
|
||||||
// So we have to extrapolate.
|
CAircraftSituation oldSituation;
|
||||||
if (situationsAfter.isEmpty())
|
CAircraftSituation newSituation;
|
||||||
|
int situationsNewerNo = situationsNewer.size();
|
||||||
|
int situationsOlderNo = situationsOlder.size();
|
||||||
|
|
||||||
|
// latest first, now 00:26 -> 00:26 - 6000ms -> 00:20 split time
|
||||||
|
// time pos
|
||||||
|
// 00:25 10 newer
|
||||||
|
// 00:20 11 newer
|
||||||
|
// <----- split
|
||||||
|
// 00:15 12 older
|
||||||
|
// 00:10 13 older
|
||||||
|
// 00:05 14 older
|
||||||
|
|
||||||
|
// The first condition covers a situation, when there are no before / after situations.
|
||||||
|
// We just place at he last position until we get before / after situations
|
||||||
|
if (situationsOlderNo < 1 || situationsNewerNo < 1)
|
||||||
{
|
{
|
||||||
beginSituation = situationsBefore[situationsBefore.size() - 2];
|
if (ok) { *ok = true; }
|
||||||
endSituation = situationsBefore[situationsBefore.size() - 1];
|
// no after situations
|
||||||
|
if (situationsOlderNo < 1) { return situationsNewer.back(); } // oldest newest
|
||||||
|
|
||||||
|
// no before situations
|
||||||
|
if (situationsOlder.size() < 2) { return situationsOlder.front(); } // latest older
|
||||||
|
|
||||||
|
// this will lead to extrapolation
|
||||||
|
oldSituation = situationsOlder[1]; // before newest
|
||||||
|
newSituation = situationsOlder.front(); // newest
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
beginSituation = situationsBefore.back();
|
oldSituation = situationsOlder.front(); // first oldest
|
||||||
endSituation = situationsAfter.front();
|
newSituation = situationsNewer.back(); // latest newest
|
||||||
|
Q_ASSERT(oldSituation.getMSecsSinceEpoch() < newSituation.getMSecsSinceEpoch());
|
||||||
}
|
}
|
||||||
|
|
||||||
CAircraftSituation currentSituation;
|
CAircraftSituation currentSituation(oldSituation);
|
||||||
CCoordinateGeodetic currentPosition;
|
CCoordinateGeodetic currentPosition;
|
||||||
|
|
||||||
// Time between start and end packet
|
// Time between start and end packet
|
||||||
double deltaTime = beginSituation.msecsToAbs(endSituation);
|
double deltaTime = oldSituation.absMsecsTo(newSituation);
|
||||||
|
|
||||||
// Fraction of the deltaTime [0.0 - 1.0]
|
// Fraction of the deltaTime, ideally [0.0 - 1.0]
|
||||||
double simulationTimeFraction = (beginSituation.getMSecsSinceEpoch() - splitTimeMsSinceEpoch) / deltaTime;
|
// < 0 should not happen due to the split, > 1 can happen if new values are delayed beyond split time
|
||||||
|
// 1) values > 1 mean extrapolation
|
||||||
|
// 2) values > 2 mean no new situations coming in
|
||||||
|
double simulationTimeFraction = 1 - ((newSituation.getMSecsSinceEpoch() - splitTimeMsSinceEpoch) / deltaTime);
|
||||||
|
if (simulationTimeFraction > 1.5)
|
||||||
|
{
|
||||||
|
if (this->m_withDebugMsg)
|
||||||
|
{
|
||||||
|
CLogMessage(this).warning("Extrapolation, fraction > 1: %1 for callsign: %2") << simulationTimeFraction << callsign;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Interpolate latitude: Lat = (LatB - LatA) * t + LatA
|
// Interpolate latitude: Lat = (LatB - LatA) * t + LatA
|
||||||
currentPosition.setLatitude((endSituation.getPosition().latitude() - beginSituation.getPosition().latitude())
|
currentPosition.setLatitude((newSituation.getPosition().latitude() - oldSituation.getPosition().latitude())
|
||||||
* simulationTimeFraction
|
* simulationTimeFraction
|
||||||
+ beginSituation.getPosition().latitude());
|
+ oldSituation.getPosition().latitude());
|
||||||
|
|
||||||
// Interpolate latitude: Lon = (LonB - LonA) * t + LonA
|
// Interpolate latitude: Lon = (LonB - LonA) * t + LonA
|
||||||
currentPosition.setLongitude((endSituation.getPosition().longitude() - beginSituation.getPosition().longitude())
|
currentPosition.setLongitude((newSituation.getPosition().longitude() - oldSituation.getPosition().longitude())
|
||||||
* simulationTimeFraction
|
* simulationTimeFraction
|
||||||
+ beginSituation.getPosition().longitude());
|
+ oldSituation.getPosition().longitude());
|
||||||
currentSituation.setPosition(currentPosition);
|
currentSituation.setPosition(currentPosition);
|
||||||
|
|
||||||
// Interpolate altitude: Alt = (AltB - AltA) * t + AltA
|
// Interpolate altitude: Alt = (AltB - AltA) * t + AltA
|
||||||
currentSituation.setAltitude(CAltitude((endSituation.getAltitude() - beginSituation.getAltitude())
|
currentSituation.setAltitude(CAltitude((newSituation.getAltitude() - oldSituation.getAltitude())
|
||||||
* simulationTimeFraction
|
* simulationTimeFraction
|
||||||
+ beginSituation.getAltitude(),
|
+ oldSituation.getAltitude(),
|
||||||
beginSituation.getAltitude().getReferenceDatum()));
|
oldSituation.getAltitude().getReferenceDatum()));
|
||||||
|
|
||||||
// Interpolate heading: HDG = (HdgB - HdgA) * t + HdgA
|
// Interpolate heading: HDG = (HdgB - HdgA) * t + HdgA
|
||||||
CHeading headingBegin = beginSituation.getHeading();
|
CHeading headingBegin = oldSituation.getHeading();
|
||||||
CHeading headingEnd = endSituation.getHeading();
|
CHeading headingEnd = newSituation.getHeading();
|
||||||
|
|
||||||
if ((headingEnd - headingBegin).value(CAngleUnit::deg()) < -180)
|
if ((headingEnd - headingBegin).value(CAngleUnit::deg()) < -180)
|
||||||
{
|
{
|
||||||
@@ -93,8 +127,8 @@ namespace BlackCore
|
|||||||
headingBegin.getReferenceNorth()));
|
headingBegin.getReferenceNorth()));
|
||||||
|
|
||||||
// Interpolate Pitch: Pitch = (PitchB - PitchA) * t + PitchA
|
// Interpolate Pitch: Pitch = (PitchB - PitchA) * t + PitchA
|
||||||
CAngle pitchBegin = beginSituation.getPitch();
|
CAngle pitchBegin = oldSituation.getPitch();
|
||||||
CAngle pitchEnd = endSituation.getPitch();
|
CAngle pitchEnd = newSituation.getPitch();
|
||||||
CAngle pitch = (pitchEnd - pitchBegin) * simulationTimeFraction + pitchBegin;
|
CAngle pitch = (pitchEnd - pitchBegin) * simulationTimeFraction + pitchBegin;
|
||||||
|
|
||||||
// TODO: According to the specification, pitch above horizon should be negative.
|
// TODO: According to the specification, pitch above horizon should be negative.
|
||||||
@@ -103,8 +137,8 @@ namespace BlackCore
|
|||||||
currentSituation.setPitch(pitch);
|
currentSituation.setPitch(pitch);
|
||||||
|
|
||||||
// Interpolate bank: Bank = (BankB - BankA) * t + BankA
|
// Interpolate bank: Bank = (BankB - BankA) * t + BankA
|
||||||
CAngle bankBegin = beginSituation.getBank();
|
CAngle bankBegin = oldSituation.getBank();
|
||||||
CAngle bankEnd = endSituation.getBank();
|
CAngle bankEnd = newSituation.getBank();
|
||||||
CAngle bank = (bankEnd - bankBegin) * simulationTimeFraction + bankBegin;
|
CAngle bank = (bankEnd - bankBegin) * simulationTimeFraction + bankBegin;
|
||||||
|
|
||||||
// TODO: According to the specification, banks to the right should be negative.
|
// TODO: According to the specification, banks to the right should be negative.
|
||||||
@@ -112,10 +146,11 @@ namespace BlackCore
|
|||||||
bank *= -1;
|
bank *= -1;
|
||||||
currentSituation.setBank(bank);
|
currentSituation.setBank(bank);
|
||||||
|
|
||||||
currentSituation.setGroundspeed((endSituation.getGroundSpeed() - beginSituation.getGroundSpeed())
|
currentSituation.setGroundspeed((newSituation.getGroundSpeed() - oldSituation.getGroundSpeed())
|
||||||
* simulationTimeFraction
|
* simulationTimeFraction
|
||||||
+ beginSituation.getGroundSpeed());
|
+ oldSituation.getGroundSpeed());
|
||||||
if (ok) { *ok = true; }
|
if (ok) { *ok = true; }
|
||||||
|
Q_ASSERT(currentSituation.getCallsign() == callsign);
|
||||||
return currentSituation;
|
return currentSituation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,11 @@ namespace BlackCore
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
//! \copydoc IInterpolator::getCurrentInterpolatedSituation
|
//! \copydoc IInterpolator::getCurrentInterpolatedSituation
|
||||||
virtual BlackMisc::Aviation::CAircraftSituation getCurrentInterpolatedSituation(const QHash<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftSituationList> &allSituations, const BlackMisc::Aviation::CCallsign &callsign, bool *ok = nullptr) const override;
|
virtual BlackMisc::Aviation::CAircraftSituation getCurrentInterpolatedSituation(const QHash<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftSituationList> &allSituations, const BlackMisc::Aviation::CCallsign &callsign, qint64 currentTimeSinceEpoc = -1, bool *ok = nullptr) const override;
|
||||||
|
|
||||||
|
//! Log category
|
||||||
|
static QString getMessageCategory() { return "swift.interpolatorlinear"; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace BlackCore
|
} // namespace BlackCore
|
||||||
|
|||||||
@@ -49,13 +49,13 @@ namespace BlackMisc
|
|||||||
// those signals have to be implemented by classes using the interface.
|
// those signals have to be implemented by classes using the interface.
|
||||||
signals:
|
signals:
|
||||||
//! A new situation got added
|
//! A new situation got added
|
||||||
virtual void addedRemoteAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation) = 0;
|
void addedRemoteAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation);
|
||||||
|
|
||||||
//! New parts got added
|
//! New parts got added
|
||||||
virtual void addedRemoteAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts) = 0;
|
void addedRemoteAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts);
|
||||||
|
|
||||||
//! Aircraft was removed
|
//! Aircraft was removed
|
||||||
virtual void removedAircraft(const BlackMisc::Aviation::CCallsign &callsign) = 0;
|
void removedRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ namespace BlackMisc
|
|||||||
virtual BlackMisc::Aviation::CAircraftPartsList &remoteAircraftParts() = 0;
|
virtual BlackMisc::Aviation::CAircraftPartsList &remoteAircraftParts() = 0;
|
||||||
|
|
||||||
//! Enable/disable rendering
|
//! Enable/disable rendering
|
||||||
virtual bool updateAircraftEnabled(const BlackMisc::Aviation::CCallsign &callsign, bool enabledForRedering, const QString &originator) = 0;
|
virtual bool updateAircraftEnabled(const BlackMisc::Aviation::CCallsign &callsign, bool enabledForRendering, const QString &originator) = 0;
|
||||||
|
|
||||||
//! Change model string
|
//! Change model string
|
||||||
virtual bool updateAircraftModel(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Simulation::CAircraftModel &model, const QString &originator) = 0;
|
virtual bool updateAircraftModel(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Simulation::CAircraftModel &model, const QString &originator) = 0;
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ namespace BlackSimPlugin
|
|||||||
|
|
||||||
|
|
||||||
bool ok;
|
bool ok;
|
||||||
CAircraftSituation situation = this->m_interpolator->getCurrentInterpolatedSituation(this->m_interpolator->getSituationsByCallsign(), m_callsign, &ok);
|
CAircraftSituation situation = this->m_interpolator->getCurrentInterpolatedSituation(this->m_interpolator->getSituationsByCallsign(), m_callsign, -1, &ok);
|
||||||
if (!ok) { return; }
|
if (!ok) { return; }
|
||||||
MPPositionSlewMode positionSlewMode = aircraftSituationToFS9(situation);
|
MPPositionSlewMode positionSlewMode = aircraftSituationToFS9(situation);
|
||||||
|
|
||||||
|
|||||||
@@ -149,8 +149,8 @@ namespace BlackSimPlugin
|
|||||||
if (aircraftAlreadyExistsInSim)
|
if (aircraftAlreadyExistsInSim)
|
||||||
{
|
{
|
||||||
// remove first
|
// remove first
|
||||||
this->removeRenderedAircraft(callsign);
|
this->removeRemoteAircraft(callsign);
|
||||||
Q_ASSERT(false);
|
CLogMessage(this).warning("Have to remove aircraft %1 before I can add it") << callsign;
|
||||||
}
|
}
|
||||||
|
|
||||||
SIMCONNECT_DATA_INITPOSITION initialPosition = aircraftSituationToFsxInitPosition(newRemoteAircraft.getSituation());
|
SIMCONNECT_DATA_INITPOSITION initialPosition = aircraftSituationToFsxInitPosition(newRemoteAircraft.getSituation());
|
||||||
@@ -190,12 +190,6 @@ namespace BlackSimPlugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSimulatorFsx::removeRenderedAircraft(const CCallsign &callsign)
|
|
||||||
{
|
|
||||||
// only remove from sim
|
|
||||||
return removeRenderedAircraft(m_simConnectObjects.value(callsign));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CSimulatorFsx::updateOwnSimulatorCockpit(const CAircraft &ownAircraft, const QString &originator)
|
bool CSimulatorFsx::updateOwnSimulatorCockpit(const CAircraft &ownAircraft, const QString &originator)
|
||||||
{
|
{
|
||||||
if (originator == this->simulatorOriginator()) { return false; }
|
if (originator == this->simulatorOriginator()) { return false; }
|
||||||
@@ -352,7 +346,7 @@ namespace BlackSimPlugin
|
|||||||
|
|
||||||
void CSimulatorFsx::onSimFrame()
|
void CSimulatorFsx::onSimFrame()
|
||||||
{
|
{
|
||||||
updateOtherAircraft();
|
updateRemoteAircraft();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSimulatorFsx::onSimExit()
|
void CSimulatorFsx::onSimExit()
|
||||||
@@ -511,10 +505,17 @@ namespace BlackSimPlugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSimulatorFsx::removeRenderedAircraft(const CSimConnectObject &simObject)
|
bool CSimulatorFsx::removeRemoteAircraft(const CCallsign &callsign)
|
||||||
|
{
|
||||||
|
// only remove from sim
|
||||||
|
if (!m_simConnectObjects.contains(callsign)) { return false; }
|
||||||
|
return removeRemoteAircraft(m_simConnectObjects.value(callsign));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSimulatorFsx::removeRemoteAircraft(const CSimConnectObject &simObject)
|
||||||
{
|
{
|
||||||
SimConnect_AIRemoveObject(m_hSimConnect, simObject.getObjectId(), simObject.getRequestId());
|
|
||||||
m_simConnectObjects.remove(simObject.getCallsign());
|
m_simConnectObjects.remove(simObject.getCallsign());
|
||||||
|
SimConnect_AIRemoveObject(m_hSimConnect, simObject.getObjectId(), simObject.getRequestId());
|
||||||
remoteAircraft().applyIfCallsign(simObject.getCallsign(), CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(false)));
|
remoteAircraft().applyIfCallsign(simObject.getCallsign(), CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(false)));
|
||||||
CLogMessage(this).info("FSX: Removed aircraft %1") << simObject.getCallsign().toQString();
|
CLogMessage(this).info("FSX: Removed aircraft %1") << simObject.getCallsign().toQString();
|
||||||
return true;
|
return true;
|
||||||
@@ -594,29 +595,49 @@ namespace BlackSimPlugin
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSimulatorFsx::updateOtherAircraft()
|
void CSimulatorFsx::updateRemoteAircraft()
|
||||||
{
|
{
|
||||||
static_assert(sizeof(DataDefinitionRemoteAircraft) == 176, "DataDefinitionRemoteAircraft has an incorrect size.");
|
static_assert(sizeof(DataDefinitionRemoteAircraft) == 176, "DataDefinitionRemoteAircraft has an incorrect size.");
|
||||||
Q_ASSERT(this->m_interpolator);
|
Q_ASSERT(this->m_interpolator);
|
||||||
Q_ASSERT_X(this->m_interpolator->thread() != this->thread(), "updateOtherAircraft", "interpolator should run in its own thread");
|
Q_ASSERT_X(this->m_interpolator->thread() != this->thread(), "updateOtherAircraft", "interpolator should run in its own thread");
|
||||||
|
|
||||||
bool lastRequestAvailable;
|
// nothing to do, reset request id and exit
|
||||||
|
int remoteAircraftNo = this->remoteAircraft().size();
|
||||||
|
if (remoteAircraftNo < 1) { m_interpolationRequest = 0; return; }
|
||||||
|
|
||||||
|
// initial request, and bye. First time we have aircraft
|
||||||
|
if (m_interpolationRequest == 0)
|
||||||
|
{
|
||||||
|
m_interpolator->syncRequestSituationsCalculationsForAllCallsigns(++m_interpolationRequest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to get old request
|
||||||
|
bool lastRequestAvailable = false;
|
||||||
CAircraftSituationList interpolations = m_interpolator->getRequest(m_interpolationRequest, &lastRequestAvailable);
|
CAircraftSituationList interpolations = m_interpolator->getRequest(m_interpolationRequest, &lastRequestAvailable);
|
||||||
if (!lastRequestAvailable)
|
if (!lastRequestAvailable)
|
||||||
{
|
{
|
||||||
|
// warning the 1st and every 10th time
|
||||||
|
bool warning = m_interpolationsSkipped % 10;
|
||||||
m_interpolationsSkipped++;
|
m_interpolationsSkipped++;
|
||||||
|
if (warning)
|
||||||
|
{
|
||||||
|
CLogMessage(this).warning("Skipped interpolation %1 time(s)") << m_interpolationsSkipped;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// non blocking calculations in background
|
// non blocking calculations in background
|
||||||
m_interpolator->requestSituationsCalculationsForAllCallsigns(m_interpolationsSkipped);
|
m_interpolator->syncRequestSituationsCalculationsForAllCallsigns(++m_interpolationRequest);
|
||||||
|
|
||||||
// now send to sim
|
// now send to sim
|
||||||
for (const CAircraftSituation ¤tSituation : interpolations)
|
for (const CAircraftSituation ¤tSituation : interpolations)
|
||||||
{
|
{
|
||||||
bool hasParts;
|
|
||||||
const CCallsign callsign(currentSituation.getCallsign());
|
const CCallsign callsign(currentSituation.getCallsign());
|
||||||
|
if (!m_simConnectObjects.contains(callsign)) { continue; } // only if aircraft is already available
|
||||||
|
bool hasParts;
|
||||||
const CSimConnectObject &simObj = m_simConnectObjects[callsign];
|
const CSimConnectObject &simObj = m_simConnectObjects[callsign];
|
||||||
|
if (simObj.getObjectId() == 0) { continue; }
|
||||||
SIMCONNECT_DATA_INITPOSITION position = aircraftSituationToFsxInitPosition(currentSituation);
|
SIMCONNECT_DATA_INITPOSITION position = aircraftSituationToFsxInitPosition(currentSituation);
|
||||||
CAircraftParts parts = m_interpolator->getLatestPartsBeforeOffset(callsign, IInterpolator::TimeOffsetMs, &hasParts);
|
CAircraftParts parts = m_interpolator->getLatestPartsBeforeOffset(callsign, IInterpolator::TimeOffsetMs, &hasParts);
|
||||||
|
|
||||||
@@ -625,7 +646,6 @@ namespace BlackSimPlugin
|
|||||||
{
|
{
|
||||||
// we have parts
|
// we have parts
|
||||||
position.OnGround = parts.isOnGround() ? 1 : 0;
|
position.OnGround = parts.isOnGround() ? 1 : 0;
|
||||||
|
|
||||||
ddRemoteAircraft.position = position;
|
ddRemoteAircraft.position = position;
|
||||||
ddRemoteAircraft.lightStrobe = parts.getLights().isStrobeOn() ? 1.0 : 0.0;
|
ddRemoteAircraft.lightStrobe = parts.getLights().isStrobeOn() ? 1.0 : 0.0;
|
||||||
ddRemoteAircraft.lightLanding = parts.getLights().isLandingOn() ? 1.0 : 0.0;
|
ddRemoteAircraft.lightLanding = parts.getLights().isLandingOn() ? 1.0 : 0.0;
|
||||||
@@ -639,27 +659,49 @@ namespace BlackSimPlugin
|
|||||||
ddRemoteAircraft.flapsTrailingEdgeRightPercent = parts.getFlapsPercent() / 100.0;
|
ddRemoteAircraft.flapsTrailingEdgeRightPercent = parts.getFlapsPercent() / 100.0;
|
||||||
ddRemoteAircraft.spoilersHandlePosition = parts.isSpoilersOut() ? 1.0 : 0.0;
|
ddRemoteAircraft.spoilersHandlePosition = parts.isSpoilersOut() ? 1.0 : 0.0;
|
||||||
ddRemoteAircraft.gearHandlePosition = parts.isGearDown() ? 1 : 0;
|
ddRemoteAircraft.gearHandlePosition = parts.isGearDown() ? 1 : 0;
|
||||||
ddRemoteAircraft.engine1Combustion = parts.getEngines().findBy(&CAircraftEngine::getNumber, 1).frontOrDefault().isOn() ? 1 : 0;
|
ddRemoteAircraft.engine1Combustion = parts.isEngineOn(1) ? 1 : 0;
|
||||||
ddRemoteAircraft.engine2Combustion = parts.getEngines().findBy(&CAircraftEngine::getNumber, 2).frontOrDefault().isOn() ? 1 : 0;
|
ddRemoteAircraft.engine2Combustion = parts.isEngineOn(2) ? 1 : 0;;
|
||||||
ddRemoteAircraft.engine3Combustion = parts.getEngines().findBy(&CAircraftEngine::getNumber, 3).frontOrDefault().isOn() ? 1 : 0;
|
ddRemoteAircraft.engine3Combustion = parts.isEngineOn(3) ? 1 : 0;
|
||||||
ddRemoteAircraft.engine4Combustion = parts.getEngines().findBy(&CAircraftEngine::getNumber, 4).frontOrDefault().isOn() ? 1 : 0;
|
ddRemoteAircraft.engine4Combustion = parts.isEngineOn(4) ? 1 : 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//! \todo interpolator, set data without parts by educated guessing whatsoever
|
//! \todo interpolator, set data without parts by educated guessing whatsoever
|
||||||
position.OnGround = parts.isOnGround() ? 1 : 0;
|
bool onGround = currentSituation.isOnGroundGuessed();
|
||||||
|
position.OnGround = onGround ? 1 : 0;
|
||||||
|
ddRemoteAircraft.position = position;
|
||||||
|
ddRemoteAircraft.gearHandlePosition = onGround ? 1 : 0;
|
||||||
|
|
||||||
|
// when first detected moving, lights on
|
||||||
|
if (onGround && currentSituation.getGroundSpeed().value(CSpeedUnit::km_h()) > 15)
|
||||||
|
{
|
||||||
|
// ddRemoteAircraft.light = 1.0;
|
||||||
|
ddRemoteAircraft.lightBeacon = 1.0;
|
||||||
|
ddRemoteAircraft.lightNav = 1.0;
|
||||||
|
ddRemoteAircraft.lightLanding = 0.0;
|
||||||
|
}
|
||||||
|
else if (onGround)
|
||||||
|
{
|
||||||
|
// ddRemoteAircraft.lightTaxi = 0.0;
|
||||||
|
ddRemoteAircraft.lightBeacon = 1.0;
|
||||||
|
ddRemoteAircraft.lightNav = 1.0;
|
||||||
|
ddRemoteAircraft.lightLanding = 0.0;
|
||||||
|
}
|
||||||
|
else if (!onGround)
|
||||||
|
{
|
||||||
|
// ddRemoteAircraft.lightTaxi = 0.0;
|
||||||
|
ddRemoteAircraft.lightBeacon = 1.0;
|
||||||
|
ddRemoteAircraft.lightNav = 1.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (simObj.getObjectId() != 0)
|
|
||||||
{
|
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
hr += SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::DataRemoteAircraft,
|
hr += SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::DataRemoteAircraft,
|
||||||
simObj.getObjectId(), 0, 0,
|
simObj.getObjectId(), 0, 0,
|
||||||
sizeof(DataDefinitionRemoteAircraft), &ddRemoteAircraft);
|
sizeof(DataDefinitionRemoteAircraft), &ddRemoteAircraft);
|
||||||
|
|
||||||
if (hr != S_OK) { CLogMessage(this).warning("Failed so set data on SimObject"); }
|
if (hr != S_OK) { CLogMessage(this).warning("Failed so set data on SimObject"); }
|
||||||
}
|
} // all situations
|
||||||
} // ok, no parts
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SIMCONNECT_DATA_INITPOSITION CSimulatorFsx::aircraftSituationToFsxInitPosition(const CAircraftSituation &situation)
|
SIMCONNECT_DATA_INITPOSITION CSimulatorFsx::aircraftSituationToFsxInitPosition(const CAircraftSituation &situation)
|
||||||
|
|||||||
Reference in New Issue
Block a user