mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-24 18:04:14 +08:00
Move X-Plane interpolation into driver
ref T259
This commit is contained in:
committed by
Klaus Basan
parent
f3b48f75a1
commit
4db0b83310
@@ -79,7 +79,6 @@ namespace BlackSimPlugin
|
|||||||
{
|
{
|
||||||
namespace XPlane
|
namespace XPlane
|
||||||
{
|
{
|
||||||
|
|
||||||
CSimulatorXPlane::CSimulatorXPlane(const BlackMisc::Simulation::CSimulatorPluginInfo &info,
|
CSimulatorXPlane::CSimulatorXPlane(const BlackMisc::Simulation::CSimulatorPluginInfo &info,
|
||||||
IOwnAircraftProvider *ownAircraftProvider,
|
IOwnAircraftProvider *ownAircraftProvider,
|
||||||
IRemoteAircraftProvider *remoteAircraftProvider,
|
IRemoteAircraftProvider *remoteAircraftProvider,
|
||||||
@@ -247,6 +246,7 @@ namespace BlackSimPlugin
|
|||||||
connect(m_service, &CXSwiftBusServiceProxy::aircraftModelChanged, this, &CSimulatorXPlane::ps_emitOwnAircraftModelChanged);
|
connect(m_service, &CXSwiftBusServiceProxy::aircraftModelChanged, this, &CSimulatorXPlane::ps_emitOwnAircraftModelChanged);
|
||||||
connect(m_service, &CXSwiftBusServiceProxy::airportsInRangeUpdated, this, &CSimulatorXPlane::ps_setAirportsInRange);
|
connect(m_service, &CXSwiftBusServiceProxy::airportsInRangeUpdated, this, &CSimulatorXPlane::ps_setAirportsInRange);
|
||||||
m_service->updateAirportsInRange();
|
m_service->updateAirportsInRange();
|
||||||
|
connect(m_traffic, &CXSwiftBusTrafficProxy::simFrame, this, &CSimulatorXPlane::updateRemoteAircraft);
|
||||||
if (m_watcher) { m_watcher->setConnection(m_conn); }
|
if (m_watcher) { m_watcher->setConnection(m_conn); }
|
||||||
loadCslPackages();
|
loadCslPackages();
|
||||||
emitSimulatorCombinedStatus();
|
emitSimulatorCombinedStatus();
|
||||||
@@ -375,8 +375,25 @@ namespace BlackSimPlugin
|
|||||||
{
|
{
|
||||||
if (!isConnected()) { return false; }
|
if (!isConnected()) { return false; }
|
||||||
|
|
||||||
m_traffic->setInterpolatorMode(callsign.asString(), mode == CInterpolatorMulti::ModeSpline);
|
if(c_driverInterpolation)
|
||||||
return true;
|
{
|
||||||
|
if (mode == CInterpolatorMulti::ModeUnknown) { return false; }
|
||||||
|
if (callsign.isEmpty())
|
||||||
|
{
|
||||||
|
const int c = m_xplaneAircrafts.setInterpolatorModes(mode);
|
||||||
|
return c > 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!m_xplaneAircrafts.contains(callsign)) { return false; }
|
||||||
|
return m_xplaneAircrafts[callsign].setInterpolatorMode(mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_traffic->setInterpolatorMode(callsign.asString(), mode == CInterpolatorMulti::ModeSpline);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QDBusConnection CSimulatorXPlane::connectionFromString(const QString &str)
|
QDBusConnection CSimulatorXPlane::connectionFromString(const QString &str)
|
||||||
@@ -398,8 +415,15 @@ namespace BlackSimPlugin
|
|||||||
|
|
||||||
bool CSimulatorXPlane::isPhysicallyRenderedAircraft(const CCallsign &callsign) const
|
bool CSimulatorXPlane::isPhysicallyRenderedAircraft(const CCallsign &callsign) const
|
||||||
{
|
{
|
||||||
//! \todo XP implement isRenderedAircraft correctly. This is a workaround, but not telling me if a callsign is really(!) visible in simulator
|
if (c_driverInterpolation)
|
||||||
return getAircraftInRangeForCallsign(callsign).isRendered();
|
{
|
||||||
|
return m_xplaneAircrafts.contains(callsign);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//! \todo XP implement isRenderedAircraft correctly. This is a workaround, but not telling me if a callsign is really(!) visible in simulator
|
||||||
|
return getAircraftInRangeForCallsign(callsign).isRendered();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSimulatorXPlane::updateOwnSimulatorCockpit(const BlackMisc::Simulation::CSimulatedAircraft &aircraft, const CIdentifier &originator)
|
bool CSimulatorXPlane::updateOwnSimulatorCockpit(const BlackMisc::Simulation::CSimulatedAircraft &aircraft, const CIdentifier &originator)
|
||||||
@@ -487,90 +511,174 @@ namespace BlackSimPlugin
|
|||||||
bool CSimulatorXPlane::physicallyAddRemoteAircraft(const CSimulatedAircraft &newRemoteAircraft)
|
bool CSimulatorXPlane::physicallyAddRemoteAircraft(const CSimulatedAircraft &newRemoteAircraft)
|
||||||
{
|
{
|
||||||
Q_ASSERT(isConnected());
|
Q_ASSERT(isConnected());
|
||||||
//! \todo XPlane driver check if already exists, how?
|
if (c_driverInterpolation)
|
||||||
//! \todo XPlane driver set correct return value
|
{
|
||||||
|
// entry checks
|
||||||
|
Q_ASSERT_X(CThreadUtils::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "thread");
|
||||||
|
Q_ASSERT_X(!newRemoteAircraft.getCallsign().isEmpty(), Q_FUNC_INFO, "empty callsign");
|
||||||
|
Q_ASSERT_X(newRemoteAircraft.hasModelString(), Q_FUNC_INFO, "missing model string");
|
||||||
|
|
||||||
CAircraftModel aircraftModel = newRemoteAircraft.getModel();
|
m_xplaneAircrafts.insert(newRemoteAircraft.getCallsign(), CXPlaneMPAircraft(newRemoteAircraft, &m_interpolationLogger));
|
||||||
QString livery = aircraftModel.getLivery().getCombinedCode(); //! \todo livery resolution for XP
|
CAircraftModel aircraftModel = newRemoteAircraft.getModel();
|
||||||
m_traffic->addPlane(newRemoteAircraft.getCallsign().asString(), aircraftModel.getModelString(),
|
QString livery = aircraftModel.getLivery().getCombinedCode(); //! \todo livery resolution for XP
|
||||||
newRemoteAircraft.getAircraftIcaoCode().getDesignator(),
|
m_traffic->addPlane(newRemoteAircraft.getCallsign().asString(), aircraftModel.getModelString(),
|
||||||
newRemoteAircraft.getAirlineIcaoCode().getDesignator(),
|
newRemoteAircraft.getAircraftIcaoCode().getDesignator(),
|
||||||
livery);
|
newRemoteAircraft.getAirlineIcaoCode().getDesignator(),
|
||||||
|
livery);
|
||||||
|
|
||||||
CLogMessage(this).info("XP: Added aircraft %1") << newRemoteAircraft.getCallsign().toQString();
|
CLogMessage(this).info("XP: Added aircraft %1") << newRemoteAircraft.getCallsign().toQString();
|
||||||
|
|
||||||
bool rendered = true;
|
bool rendered = true;
|
||||||
updateAircraftRendered(newRemoteAircraft.getCallsign(), rendered);
|
updateAircraftRendered(newRemoteAircraft.getCallsign(), rendered);
|
||||||
|
|
||||||
CSimulatedAircraft remoteAircraftCopy(newRemoteAircraft);
|
CSimulatedAircraft remoteAircraftCopy(newRemoteAircraft);
|
||||||
remoteAircraftCopy.setRendered(rendered);
|
remoteAircraftCopy.setRendered(rendered);
|
||||||
emit aircraftRenderingChanged(remoteAircraftCopy);
|
emit aircraftRenderingChanged(remoteAircraftCopy);
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CAircraftModel aircraftModel = newRemoteAircraft.getModel();
|
||||||
|
QString livery = aircraftModel.getLivery().getCombinedCode(); //! \todo livery resolution for XP
|
||||||
|
m_traffic->addPlane(newRemoteAircraft.getCallsign().asString(), aircraftModel.getModelString(),
|
||||||
|
newRemoteAircraft.getAircraftIcaoCode().getDesignator(),
|
||||||
|
newRemoteAircraft.getAirlineIcaoCode().getDesignator(),
|
||||||
|
livery);
|
||||||
|
|
||||||
|
CLogMessage(this).info("XP: Added aircraft %1") << newRemoteAircraft.getCallsign().toQString();
|
||||||
|
|
||||||
|
bool rendered = true;
|
||||||
|
updateAircraftRendered(newRemoteAircraft.getCallsign(), rendered);
|
||||||
|
|
||||||
|
CSimulatedAircraft remoteAircraftCopy(newRemoteAircraft);
|
||||||
|
remoteAircraftCopy.setRendered(rendered);
|
||||||
|
emit aircraftRenderingChanged(remoteAircraftCopy);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSimulatorXPlane::onRemoteProviderAddedAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation)
|
void CSimulatorXPlane::onRemoteProviderAddedAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation)
|
||||||
{
|
{
|
||||||
Q_ASSERT(isConnected());
|
Q_ASSERT(isConnected());
|
||||||
using namespace BlackMisc::PhysicalQuantities;
|
if (c_driverInterpolation)
|
||||||
m_traffic->addPlanePosition(situation.getCallsign().asString(),
|
|
||||||
situation.latitude().value(CAngleUnit::deg()),
|
|
||||||
situation.longitude().value(CAngleUnit::deg()),
|
|
||||||
situation.getAltitude().value(CLengthUnit::ft()),
|
|
||||||
situation.getPitch().value(CAngleUnit::deg()),
|
|
||||||
situation.getBank().value(CAngleUnit::deg()),
|
|
||||||
situation.getHeading().value(CAngleUnit::deg()),
|
|
||||||
situation.getMSecsSinceEpoch() - QDateTime::currentMSecsSinceEpoch(),
|
|
||||||
situation.getTimeOffsetMs());
|
|
||||||
|
|
||||||
if (! isRemoteAircraftSupportingParts(situation.getCallsign()))
|
|
||||||
{
|
{
|
||||||
// if aircraft not supporting parts then guess the basics (onGround, gear, lights)
|
if (m_xplaneAircrafts.contains(situation.getCallsign()))
|
||||||
//! \todo not working for vtol
|
|
||||||
BlackMisc::Aviation::CAircraftParts parts;
|
|
||||||
parts.setMSecsSinceEpoch(situation.getMSecsSinceEpoch());
|
|
||||||
parts.setTimeOffsetMs(situation.getTimeOffsetMs());
|
|
||||||
if (situation.getGroundSpeed() < CSpeed(50, CSpeedUnit::kts()))
|
|
||||||
{
|
{
|
||||||
const auto nearestAirport = std::min_element(m_airportsInRange.cbegin(), m_airportsInRange.cend(), [&situation](auto &&a, auto &&b)
|
m_xplaneAircrafts[situation.getCallsign()].addAircraftSituation(situation);
|
||||||
{
|
|
||||||
return calculateEuclideanDistanceSquared(situation, a) < calculateEuclideanDistanceSquared(situation, b);
|
|
||||||
});
|
|
||||||
if (nearestAirport != m_airportsInRange.cend() && situation.getAltitude() - nearestAirport->getElevation() < CLength(50, CLengthUnit::ft()))
|
|
||||||
{
|
|
||||||
parts.setOnGround(true);
|
|
||||||
parts.setGearDown(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (situation.getAltitude() < CAltitude(10000, CLengthUnit::ft()))
|
|
||||||
{
|
|
||||||
parts.setLights({ true, true, true, true, true, true, true, true });
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
parts.setLights({ true, false, false, true, true, true, true, true });
|
|
||||||
}
|
|
||||||
onRemoteProviderAddedAircraftParts(situation.getCallsign(), parts);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
using namespace BlackMisc::PhysicalQuantities;
|
||||||
|
m_traffic->addPlanePosition(situation.getCallsign().asString(),
|
||||||
|
situation.latitude().value(CAngleUnit::deg()),
|
||||||
|
situation.longitude().value(CAngleUnit::deg()),
|
||||||
|
situation.getAltitude().value(CLengthUnit::ft()),
|
||||||
|
situation.getPitch().value(CAngleUnit::deg()),
|
||||||
|
situation.getBank().value(CAngleUnit::deg()),
|
||||||
|
situation.getHeading().value(CAngleUnit::deg()),
|
||||||
|
situation.getMSecsSinceEpoch() - QDateTime::currentMSecsSinceEpoch(),
|
||||||
|
situation.getTimeOffsetMs());
|
||||||
|
|
||||||
|
if (! isRemoteAircraftSupportingParts(situation.getCallsign()))
|
||||||
|
{
|
||||||
|
// if aircraft not supporting parts then guess the basics (onGround, gear, lights)
|
||||||
|
//! \todo not working for vtol
|
||||||
|
BlackMisc::Aviation::CAircraftParts parts;
|
||||||
|
parts.setMSecsSinceEpoch(situation.getMSecsSinceEpoch());
|
||||||
|
parts.setTimeOffsetMs(situation.getTimeOffsetMs());
|
||||||
|
if (situation.getGroundSpeed() < CSpeed(50, CSpeedUnit::kts()))
|
||||||
|
{
|
||||||
|
const auto nearestAirport = std::min_element(m_airportsInRange.cbegin(), m_airportsInRange.cend(), [&situation](auto &&a, auto &&b)
|
||||||
|
{
|
||||||
|
return calculateEuclideanDistanceSquared(situation, a) < calculateEuclideanDistanceSquared(situation, b);
|
||||||
|
});
|
||||||
|
if (nearestAirport != m_airportsInRange.cend() && situation.getAltitude() - nearestAirport->getElevation() < CLength(50, CLengthUnit::ft()))
|
||||||
|
{
|
||||||
|
parts.setOnGround(true);
|
||||||
|
parts.setGearDown(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (situation.getAltitude() < CAltitude(10000, CLengthUnit::ft()))
|
||||||
|
{
|
||||||
|
parts.setLights({ true, true, true, true, true, true, true, true });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parts.setLights({ true, false, false, true, true, true, true, true });
|
||||||
|
}
|
||||||
|
onRemoteProviderAddedAircraftParts(situation.getCallsign(), parts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSimulatorXPlane::onRemoteProviderAddedAircraftParts(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftParts &parts)
|
void CSimulatorXPlane::onRemoteProviderAddedAircraftParts(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftParts &parts)
|
||||||
{
|
{
|
||||||
Q_ASSERT(isConnected());
|
Q_ASSERT(isConnected());
|
||||||
m_traffic->addPlaneSurfaces(callsign.asString(), parts.isGearDown() ? 1 : 0,
|
|
||||||
parts.getFlapsPercent() / 100.0, parts.isSpoilersOut() ? 1 : 0, parts.isSpoilersOut() ? 1 : 0, parts.getFlapsPercent() / 100.0,
|
if (c_driverInterpolation)
|
||||||
0, parts.isAnyEngineOn() ? 0 : 0.75, 0, 0, 0,
|
{
|
||||||
parts.getLights().isLandingOn(), parts.getLights().isBeaconOn(), parts.getLights().isStrobeOn(), parts.getLights().isNavOn(),
|
if (m_xplaneAircrafts.contains(callsign))
|
||||||
0, parts.isOnGround(), parts.getMSecsSinceEpoch() - QDateTime::currentMSecsSinceEpoch(), parts.getTimeOffsetMs());
|
{
|
||||||
m_traffic->setPlaneTransponder(callsign.asString(), 2000, true, false);
|
m_xplaneAircrafts[callsign].addAircraftParts(parts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_traffic->addPlaneSurfaces(callsign.asString(), parts.isGearDown() ? 1 : 0,
|
||||||
|
parts.getFlapsPercent() / 100.0, parts.isSpoilersOut() ? 1 : 0, parts.isSpoilersOut() ? 1 : 0, parts.getFlapsPercent() / 100.0,
|
||||||
|
0, parts.isAnyEngineOn() ? 0 : 0.75, 0, 0, 0,
|
||||||
|
parts.getLights().isLandingOn(), parts.getLights().isBeaconOn(), parts.getLights().isStrobeOn(), parts.getLights().isNavOn(),
|
||||||
|
0, parts.isOnGround(), parts.getMSecsSinceEpoch() - QDateTime::currentMSecsSinceEpoch(), parts.getTimeOffsetMs());
|
||||||
|
m_traffic->setPlaneTransponder(callsign.asString(), 2000, true, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSimulatorXPlane::physicallyRemoveRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign)
|
bool CSimulatorXPlane::physicallyRemoveRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign)
|
||||||
{
|
{
|
||||||
Q_ASSERT(isConnected());
|
Q_ASSERT(isConnected());
|
||||||
m_traffic->removePlane(callsign.asString());
|
|
||||||
updateAircraftRendered(callsign, false);
|
if (c_driverInterpolation)
|
||||||
CLogMessage(this).info("XP: Removed aircraft %1") << callsign.toQString();
|
{
|
||||||
return true;
|
// only remove from sim
|
||||||
|
Q_ASSERT_X(CThreadUtils::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "wrong thread");
|
||||||
|
if (callsign.isEmpty()) { return false; } // can happen if an object is not an aircraft
|
||||||
|
|
||||||
|
// clean up anyway
|
||||||
|
m_hints.remove(callsign);
|
||||||
|
|
||||||
|
// really remove from simulator
|
||||||
|
if (!m_xplaneAircrafts.contains(callsign)) { return false; } // already fully removed or not yet added
|
||||||
|
CXPlaneMPAircraft &xplaneAircraft = m_xplaneAircrafts[callsign];
|
||||||
|
|
||||||
|
// avoid further data from simulator
|
||||||
|
// this->stopRequestingDataForSimObject(simObject);
|
||||||
|
|
||||||
|
m_traffic->removePlane(callsign.asString());
|
||||||
|
|
||||||
|
m_xplaneAircrafts.remove(callsign);
|
||||||
|
|
||||||
|
// mark in provider
|
||||||
|
const bool updated = this->updateAircraftRendered(callsign, false);
|
||||||
|
if (updated)
|
||||||
|
{
|
||||||
|
CSimulatedAircraft aircraft(xplaneAircraft.getAircraft());
|
||||||
|
aircraft.setRendered(false);
|
||||||
|
emit this->aircraftRenderingChanged(aircraft);
|
||||||
|
}
|
||||||
|
|
||||||
|
// bye
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_traffic->removePlane(callsign.asString());
|
||||||
|
updateAircraftRendered(callsign, false);
|
||||||
|
CLogMessage(this).info("XP: Removed aircraft %1") << callsign.toQString();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int CSimulatorXPlane::physicallyRemoveAllRemoteAircraft()
|
int CSimulatorXPlane::physicallyRemoveAllRemoteAircraft()
|
||||||
@@ -578,11 +686,26 @@ namespace BlackSimPlugin
|
|||||||
Q_ASSERT(isConnected());
|
Q_ASSERT(isConnected());
|
||||||
//! \todo XP driver obtain number of removed aircraft
|
//! \todo XP driver obtain number of removed aircraft
|
||||||
resetHighlighting();
|
resetHighlighting();
|
||||||
int r = getAircraftInRangeCount();
|
|
||||||
m_traffic->removeAllPlanes();
|
if (c_driverInterpolation)
|
||||||
updateMarkAllAsNotRendered();
|
{
|
||||||
CLogMessage(this).info("XP: Removed all aircraft");
|
// remove one by one
|
||||||
return r;
|
int r = 0;
|
||||||
|
const CCallsignSet callsigns = m_xplaneAircrafts.getAllCallsigns();
|
||||||
|
for (const CCallsign &cs : callsigns)
|
||||||
|
{
|
||||||
|
if (this->physicallyRemoveRemoteAircraft(cs)) { r++; }
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int r = getAircraftInRangeCount();
|
||||||
|
m_traffic->removeAllPlanes();
|
||||||
|
updateMarkAllAsNotRendered();
|
||||||
|
CLogMessage(this).info("XP: Removed all aircraft");
|
||||||
|
return r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CCallsignSet CSimulatorXPlane::physicallyRenderedAircraft() const
|
CCallsignSet CSimulatorXPlane::physicallyRenderedAircraft() const
|
||||||
@@ -701,6 +824,187 @@ namespace BlackSimPlugin
|
|||||||
m_weather->setThunderstormRatio(0.0);
|
m_weather->setThunderstormRatio(0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSimulatorXPlane::updateRemoteAircraft()
|
||||||
|
{
|
||||||
|
Q_ASSERT_X(CThreadUtils::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "thread");
|
||||||
|
|
||||||
|
const int remoteAircraftNo = this->getAircraftInRangeCount();
|
||||||
|
if (remoteAircraftNo < 1) { m_interpolationRequest = 0; return; }
|
||||||
|
|
||||||
|
// interpolate and send to simulator
|
||||||
|
m_interpolationRequest++;
|
||||||
|
const bool enableAircraftParts = m_interpolationRenderingSetup.isAircraftPartsEnabled();
|
||||||
|
const CCallsignSet aircraftWithParts = enableAircraftParts ? this->remoteAircraftSupportingParts() : CCallsignSet(); // optimization, fetch all parts supporting aircraft in one step (one lock)
|
||||||
|
|
||||||
|
// values used for position and parts
|
||||||
|
const qint64 currentTimestamp = QDateTime::currentMSecsSinceEpoch();
|
||||||
|
const CCallsignSet callsignsToLog(m_interpolationRenderingSetup.getLogCallsigns());
|
||||||
|
|
||||||
|
// interpolation for all remote aircraft
|
||||||
|
const QList<CXPlaneMPAircraft> xplaneAircrafts(m_xplaneAircrafts.values());
|
||||||
|
for (const CXPlaneMPAircraft &xplaneAircraft : xplaneAircrafts)
|
||||||
|
{
|
||||||
|
const CCallsign callsign(xplaneAircraft.getCallsign());
|
||||||
|
Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "missing callsign");
|
||||||
|
|
||||||
|
// fetch parts, as they are needed for ground interpolation
|
||||||
|
const bool useAircraftParts = enableAircraftParts && aircraftWithParts.contains(callsign);
|
||||||
|
const bool logInterpolationAndParts = callsignsToLog.contains(callsign);
|
||||||
|
const CInterpolationAndRenderingSetup setup(this->getInterpolationAndRenderingSetup());
|
||||||
|
CPartsStatus partsStatus(useAircraftParts);
|
||||||
|
const CAircraftParts parts = useAircraftParts ? xplaneAircraft.getInterpolatedParts(currentTimestamp, setup, partsStatus, logInterpolationAndParts) : CAircraftParts();
|
||||||
|
|
||||||
|
// get interpolated situation
|
||||||
|
CInterpolationStatus interpolatorStatus;
|
||||||
|
CInterpolationHints hints(m_hints[callsign]);
|
||||||
|
hints.setAircraftParts(useAircraftParts ? parts : CAircraftParts(), useAircraftParts);
|
||||||
|
hints.setLoggingInterpolation(logInterpolationAndParts);
|
||||||
|
const CAircraftSituation interpolatedSituation = xplaneAircraft.getInterpolatedSituation(currentTimestamp, setup, hints, interpolatorStatus);
|
||||||
|
|
||||||
|
if (interpolatorStatus.hasValidSituation())
|
||||||
|
{
|
||||||
|
// update situation
|
||||||
|
if (!xplaneAircraft.isSameAsSent(interpolatedSituation))
|
||||||
|
{
|
||||||
|
m_xplaneAircrafts[xplaneAircraft.getCallsign()].setPositionAsSent(interpolatedSituation);
|
||||||
|
m_traffic->setPlanePosition(interpolatedSituation.getCallsign().asString(),
|
||||||
|
interpolatedSituation.latitude().value(CAngleUnit::deg()),
|
||||||
|
interpolatedSituation.longitude().value(CAngleUnit::deg()),
|
||||||
|
interpolatedSituation.getAltitude().value(CLengthUnit::ft()),
|
||||||
|
interpolatedSituation.getPitch().value(CAngleUnit::deg()),
|
||||||
|
interpolatedSituation.getBank().value(CAngleUnit::deg()),
|
||||||
|
interpolatedSituation.getHeading().value(CAngleUnit::deg()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CLogMessage(this).warning("Invalid situation for callsign: '%1' info: '%2'")
|
||||||
|
<< callsign
|
||||||
|
<< interpolatorStatus.toQString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useAircraftParts)
|
||||||
|
{
|
||||||
|
this->updateRemoteAircraftParts(xplaneAircraft, parts, partsStatus);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// guess on position, but not every frame
|
||||||
|
if (m_interpolationRequest % GuessRemoteAircraftPartsCycle == 0)
|
||||||
|
{
|
||||||
|
this->guessAndUpdateRemoteAircraftParts(xplaneAircraft, interpolatedSituation, interpolatorStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // all callsigns
|
||||||
|
|
||||||
|
const qint64 dt = QDateTime::currentMSecsSinceEpoch() - currentTimestamp;
|
||||||
|
m_statsUpdateAircraftTimeTotalMs += dt;
|
||||||
|
m_statsUpdateAircraftCountMs++;
|
||||||
|
m_statsUpdateAircraftTimeAvgMs = m_statsUpdateAircraftTimeTotalMs / m_statsUpdateAircraftCountMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSimulatorXPlane::updateRemoteAircraftParts(const CXPlaneMPAircraft &xplaneAircraft, const CAircraftParts &parts, const CPartsStatus &partsStatus)
|
||||||
|
{
|
||||||
|
if (!partsStatus.isSupportingParts()) { return false; }
|
||||||
|
return this->sendRemoteAircraftPartsToSimulator(xplaneAircraft, parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSimulatorXPlane::guessAndUpdateRemoteAircraftParts(const CXPlaneMPAircraft &xplaneAircraft, const CAircraftSituation &interpolatedSituation, const CInterpolationStatus &interpolationStatus)
|
||||||
|
{
|
||||||
|
if (!interpolationStatus.isInterpolated()) { return false; }
|
||||||
|
|
||||||
|
CAircraftLights lights;
|
||||||
|
CAircraftParts parts; // init members
|
||||||
|
const bool isOnGround = interpolatedSituation.isOnGround() == CAircraftSituation::OnGround;
|
||||||
|
const double gsKts = interpolatedSituation.getGroundSpeed().value(CSpeedUnit::kts());
|
||||||
|
|
||||||
|
parts.setEngines({ true, true, true, true });
|
||||||
|
lights.setCabinOn(true);
|
||||||
|
lights.setRecognitionOn(true);
|
||||||
|
|
||||||
|
// when first detected moving, lights on
|
||||||
|
if (isOnGround)
|
||||||
|
{
|
||||||
|
parts.setGearDown(true);
|
||||||
|
lights.setTaxiOn(true);
|
||||||
|
lights.setBeaconOn(true);
|
||||||
|
lights.setNavOn(true);
|
||||||
|
|
||||||
|
if (gsKts > 5)
|
||||||
|
{
|
||||||
|
// mode taxi
|
||||||
|
lights.setTaxiOn(true);
|
||||||
|
lights.setLandingOn(false);
|
||||||
|
}
|
||||||
|
else if (gsKts > 30)
|
||||||
|
{
|
||||||
|
// mode accelaration for takeoff
|
||||||
|
lights.setTaxiOn(false);
|
||||||
|
lights.setLandingOn(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// slow movements or parking
|
||||||
|
lights.setTaxiOn(false);
|
||||||
|
lights.setLandingOn(false);
|
||||||
|
parts.setEngines({ false, false, false, false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// not on ground
|
||||||
|
parts.setGearDown(false);
|
||||||
|
lights.setTaxiOn(false);
|
||||||
|
lights.setBeaconOn(true);
|
||||||
|
lights.setNavOn(true);
|
||||||
|
// landing lights for < 10000ft (normally MSL, here ignored)
|
||||||
|
lights.setLandingOn(interpolatedSituation.getAltitude().value(CLengthUnit::ft()) < 10000);
|
||||||
|
|
||||||
|
if (!xplaneAircraft.isVtol() && interpolatedSituation.hasGroundElevation())
|
||||||
|
{
|
||||||
|
if (interpolatedSituation.getHeightAboveGround().value(CLengthUnit::ft()) < 1000)
|
||||||
|
{
|
||||||
|
parts.setGearDown(true);
|
||||||
|
parts.setFlapsPercent(25);
|
||||||
|
}
|
||||||
|
else if (interpolatedSituation.getHeightAboveGround().value(CLengthUnit::ft()) < 2000)
|
||||||
|
{
|
||||||
|
parts.setGearDown(true);
|
||||||
|
parts.setFlapsPercent(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parts.setLights(lights);
|
||||||
|
return this->sendRemoteAircraftPartsToSimulator(xplaneAircraft, parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSimulatorXPlane::sendRemoteAircraftPartsToSimulator(const CXPlaneMPAircraft &xplaneAircraft, const CAircraftParts &parts)
|
||||||
|
{
|
||||||
|
// same as in simulator or same as already send to simulator?
|
||||||
|
if (xplaneAircraft.getPartsAsSent() == parts)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_traffic->setPlaneSurfaces(xplaneAircraft.getCallsign().asString(),
|
||||||
|
parts.isGearDown() ? 1 : 0,
|
||||||
|
parts.getFlapsPercent() / 100.0,
|
||||||
|
parts.isSpoilersOut() ? 1 : 0,
|
||||||
|
parts.isSpoilersOut() ? 1 : 0,
|
||||||
|
parts.getFlapsPercent() / 100.0,
|
||||||
|
0, parts.isAnyEngineOn() ? 0 : 0.75,
|
||||||
|
0, 0, 0,
|
||||||
|
parts.getLights().isLandingOn(), parts.getLights().isBeaconOn(), parts.getLights().isStrobeOn(), parts.getLights().isNavOn(),
|
||||||
|
0, parts.isOnGround());
|
||||||
|
|
||||||
|
CAircraftLights lights = parts.getLights();
|
||||||
|
lights.setRecognitionOn(parts.isAnyEngineOn());
|
||||||
|
lights.setCabinOn(parts.isAnyEngineOn());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
BlackCore::ISimulator *CSimulatorXPlaneFactory::create(const CSimulatorPluginInfo &info,
|
BlackCore::ISimulator *CSimulatorXPlaneFactory::create(const CSimulatorPluginInfo &info,
|
||||||
IOwnAircraftProvider *ownAircraftProvider,
|
IOwnAircraftProvider *ownAircraftProvider,
|
||||||
IRemoteAircraftProvider *remoteAircraftProvider,
|
IRemoteAircraftProvider *remoteAircraftProvider,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#ifndef BLACKSIMPLUGIN_SIMULATOR_XPLANE_H
|
#ifndef BLACKSIMPLUGIN_SIMULATOR_XPLANE_H
|
||||||
#define BLACKSIMPLUGIN_SIMULATOR_XPLANE_H
|
#define BLACKSIMPLUGIN_SIMULATOR_XPLANE_H
|
||||||
|
|
||||||
|
#include "xplanempaircraft.h"
|
||||||
#include "blackcore/simulator.h"
|
#include "blackcore/simulator.h"
|
||||||
#include "blackcore/simulatorcommon.h"
|
#include "blackcore/simulatorcommon.h"
|
||||||
#include "plugins/simulator/xplaneconfig/simulatorxplaneconfig.h"
|
#include "plugins/simulator/xplaneconfig/simulatorxplaneconfig.h"
|
||||||
@@ -143,6 +144,25 @@ namespace BlackSimPlugin
|
|||||||
void loadCslPackages();
|
void loadCslPackages();
|
||||||
QString findCslPackage(const QString &modelFileName);
|
QString findCslPackage(const QString &modelFileName);
|
||||||
|
|
||||||
|
//! Update remote aircraft
|
||||||
|
//! \remark this is where the interpolated data are set
|
||||||
|
void updateRemoteAircraft();
|
||||||
|
|
||||||
|
//! Update remote aircraft parts (send to XSwiftBus)
|
||||||
|
bool updateRemoteAircraftParts(const CXPlaneMPAircraft &xplaneAircraft,
|
||||||
|
const BlackMisc::Aviation::CAircraftParts &parts, const BlackMisc::Simulation::CPartsStatus &partsStatus);
|
||||||
|
|
||||||
|
//! Update remote aircraft parts by guessing (send to XSwiftBus)
|
||||||
|
bool guessAndUpdateRemoteAircraftParts(const CXPlaneMPAircraft &xplaneAircraft,
|
||||||
|
const BlackMisc::Aviation::CAircraftSituation &interpolatedSituation, const BlackMisc::Simulation::CInterpolationStatus &interpolationStatus);
|
||||||
|
|
||||||
|
//! Send parts to simulator
|
||||||
|
bool sendRemoteAircraftPartsToSimulator(const CXPlaneMPAircraft &xplaneAircraft, const BlackMisc::Aviation::CAircraftParts &parts);
|
||||||
|
|
||||||
|
static constexpr bool c_driverInterpolation = true;
|
||||||
|
static constexpr int GuessRemoteAircraftPartsCycle = 20; //!< guess every n-th cycle
|
||||||
|
|
||||||
|
// XSwiftBus interpolation
|
||||||
QDBusConnection m_conn { "default" };
|
QDBusConnection m_conn { "default" };
|
||||||
QDBusServiceWatcher *m_watcher { nullptr };
|
QDBusServiceWatcher *m_watcher { nullptr };
|
||||||
CXSwiftBusServiceProxy *m_service { nullptr };
|
CXSwiftBusServiceProxy *m_service { nullptr };
|
||||||
@@ -153,6 +173,10 @@ namespace BlackSimPlugin
|
|||||||
BlackMisc::Aviation::CAirportList m_airportsInRange; //!< aiports in range of own aircraft
|
BlackMisc::Aviation::CAirportList m_airportsInRange; //!< aiports in range of own aircraft
|
||||||
BlackMisc::CData<BlackMisc::Simulation::Data::TModelSetCacheXP> m_modelSet { this };
|
BlackMisc::CData<BlackMisc::Simulation::Data::TModelSetCacheXP> m_modelSet { this };
|
||||||
|
|
||||||
|
// Driver Interpolation
|
||||||
|
CXPlaneMPAircrafts m_xplaneAircrafts; //!< XPlane multiplayer aircrafts
|
||||||
|
int m_interpolationRequest = 0; //!< current interpolation request
|
||||||
|
|
||||||
//! \todo Add units to members? pitchDeg?, altitudeFt?
|
//! \todo Add units to members? pitchDeg?, altitudeFt?
|
||||||
struct // data is written by DBus async method callbacks
|
struct // data is written by DBus async method callbacks
|
||||||
{
|
{
|
||||||
|
|||||||
124
src/plugins/simulator/xplane/xplanempaircraft.cpp
Normal file
124
src/plugins/simulator/xplane/xplanempaircraft.cpp
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
/* Copyright (C) 2018
|
||||||
|
* swift Project Community / Contributors
|
||||||
|
*
|
||||||
|
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||||
|
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
||||||
|
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
||||||
|
* contained in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "xplanempaircraft.h"
|
||||||
|
#include "blackmisc/simulation/interpolatormulti.h"
|
||||||
|
|
||||||
|
using namespace BlackMisc::Aviation;
|
||||||
|
using namespace BlackMisc::Simulation;
|
||||||
|
|
||||||
|
namespace BlackSimPlugin
|
||||||
|
{
|
||||||
|
namespace XPlane
|
||||||
|
{
|
||||||
|
CXPlaneMPAircraft::CXPlaneMPAircraft()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
CXPlaneMPAircraft::CXPlaneMPAircraft(const CSimulatedAircraft &aircraft,
|
||||||
|
CInterpolationLogger *logger) :
|
||||||
|
m_aircraft(aircraft),
|
||||||
|
m_interpolator(QSharedPointer<CInterpolatorMulti>::create(aircraft.getCallsign()))
|
||||||
|
{
|
||||||
|
m_interpolator->attachLogger(logger);
|
||||||
|
|
||||||
|
// if available set situation and parts
|
||||||
|
if (aircraft.isPartsSynchronized()) { this->addAircraftParts(aircraft.getParts()); }
|
||||||
|
if (aircraft.getSituation().hasValidTimestamp()) { this->addAircraftSituation(aircraft.getSituation()); }
|
||||||
|
}
|
||||||
|
|
||||||
|
CXPlaneMPAircraft::CXPlaneMPAircraft(const CAircraftSituation &situation) :
|
||||||
|
m_interpolator(QSharedPointer<CInterpolatorMulti>::create(situation.getCallsign()))
|
||||||
|
{
|
||||||
|
if (situation.hasValidTimestamp()) { this->addAircraftSituation(situation); }
|
||||||
|
}
|
||||||
|
|
||||||
|
CXPlaneMPAircraft::CXPlaneMPAircraft(const CAircraftParts &parts, const CCallsign &callsign) :
|
||||||
|
m_interpolator(QSharedPointer<CInterpolatorMulti>::create(callsign))
|
||||||
|
{
|
||||||
|
if (parts.hasValidTimestamp()) { this->addAircraftParts(parts); }
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXPlaneMPAircraft::addAircraftParts(const CAircraftParts &parts)
|
||||||
|
{
|
||||||
|
Q_ASSERT(m_interpolator);
|
||||||
|
Q_ASSERT(parts.hasValidTimestamp());
|
||||||
|
m_interpolator->addAircraftParts(parts);
|
||||||
|
m_aircraft.setParts(parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXPlaneMPAircraft::addAircraftSituation(const CAircraftSituation &situation)
|
||||||
|
{
|
||||||
|
Q_ASSERT(m_interpolator);
|
||||||
|
Q_ASSERT(situation.hasValidTimestamp());
|
||||||
|
m_interpolator->addAircraftSituation(situation);
|
||||||
|
m_aircraft.setSituation(situation); // update with last situation
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CXPlaneMPAircraft::isSameAsSent(const CAircraftSituation &position) const
|
||||||
|
{
|
||||||
|
return m_positionAsSent == position;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXPlaneMPAircraft::toggleInterpolatorMode()
|
||||||
|
{
|
||||||
|
Q_ASSERT(m_interpolator);
|
||||||
|
m_interpolator->toggleMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CXPlaneMPAircraft::setInterpolatorMode(CInterpolatorMulti::Mode mode)
|
||||||
|
{
|
||||||
|
Q_ASSERT(m_interpolator);
|
||||||
|
return m_interpolator->setMode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CXPlaneMPAircraft::getInterpolatorInfo() const
|
||||||
|
{
|
||||||
|
Q_ASSERT(m_interpolator);
|
||||||
|
return m_interpolator->getInterpolatorInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CXPlaneMPAircraft::attachInterpolatorLogger(CInterpolationLogger *logger)
|
||||||
|
{
|
||||||
|
Q_ASSERT(m_interpolator);
|
||||||
|
return m_interpolator->attachLogger(logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
CAircraftSituation CXPlaneMPAircraft::getInterpolatedSituation(
|
||||||
|
qint64 currentTimeSinceEpoc,
|
||||||
|
const CInterpolationAndRenderingSetup &setup,
|
||||||
|
const CInterpolationHints &hints, CInterpolationStatus &status) const
|
||||||
|
{
|
||||||
|
Q_ASSERT(m_interpolator);
|
||||||
|
return m_interpolator->getInterpolatedSituation(currentTimeSinceEpoc, setup, hints, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
CAircraftParts CXPlaneMPAircraft::getInterpolatedParts(
|
||||||
|
qint64 currentTimeSinceEpoc, const CInterpolationAndRenderingSetup &setup,
|
||||||
|
CPartsStatus &partsStatus, bool log) const
|
||||||
|
{
|
||||||
|
Q_ASSERT(m_interpolator);
|
||||||
|
return m_interpolator->getInterpolatedParts(currentTimeSinceEpoc, setup, partsStatus, log);
|
||||||
|
}
|
||||||
|
|
||||||
|
CCallsignSet CXPlaneMPAircrafts::getAllCallsigns() const
|
||||||
|
{
|
||||||
|
return CCallsignSet(this->keys());
|
||||||
|
}
|
||||||
|
|
||||||
|
int CXPlaneMPAircrafts::setInterpolatorModes(CInterpolatorMulti::Mode mode)
|
||||||
|
{
|
||||||
|
int c = 0;
|
||||||
|
for (const CCallsign &cs : this->keys())
|
||||||
|
{
|
||||||
|
if ((*this)[cs].setInterpolatorMode(mode)) c++;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
} // namespace
|
||||||
136
src/plugins/simulator/xplane/xplanempaircraft.h
Normal file
136
src/plugins/simulator/xplane/xplanempaircraft.h
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
/* Copyright (C) 2018
|
||||||
|
* swift project Community / Contributors
|
||||||
|
*
|
||||||
|
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||||
|
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
||||||
|
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
||||||
|
* contained in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \file
|
||||||
|
|
||||||
|
#ifndef BLACKSIMPLUGIN_XPLANE_XPLANEMPAIRCRAFT_H
|
||||||
|
#define BLACKSIMPLUGIN_XPLANE_XPLANEMPAIRCRAFT_H
|
||||||
|
|
||||||
|
#include "blackmisc/simulation/simulatedaircraft.h"
|
||||||
|
#include "blackmisc/simulation/interpolatormulti.h"
|
||||||
|
#include <QSharedPointer>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
namespace BlackSimPlugin
|
||||||
|
{
|
||||||
|
namespace XPlane
|
||||||
|
{
|
||||||
|
//! Class representing a X-Plane multiplayer aircraft
|
||||||
|
class CXPlaneMPAircraft
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Constructor
|
||||||
|
CXPlaneMPAircraft();
|
||||||
|
|
||||||
|
//! Constructor providing initial situation/parts
|
||||||
|
CXPlaneMPAircraft(const BlackMisc::Simulation::CSimulatedAircraft &aircraft,
|
||||||
|
BlackMisc::Simulation::CInterpolationLogger *logger);
|
||||||
|
|
||||||
|
//! Constructor providing initial situation
|
||||||
|
CXPlaneMPAircraft(const BlackMisc::Aviation::CAircraftSituation &situation);
|
||||||
|
|
||||||
|
//! Constructor providing initial parts
|
||||||
|
CXPlaneMPAircraft(const BlackMisc::Aviation::CAircraftParts &parts, const BlackMisc::Aviation::CCallsign &callsign);
|
||||||
|
|
||||||
|
//! Destructor
|
||||||
|
~CXPlaneMPAircraft() {}
|
||||||
|
|
||||||
|
//! Get callsign
|
||||||
|
const BlackMisc::Aviation::CCallsign &getCallsign() const { return m_aircraft.getCallsign(); }
|
||||||
|
|
||||||
|
//! Simulated aircraft (as added)
|
||||||
|
const BlackMisc::Simulation::CSimulatedAircraft &getAircraft() const { return m_aircraft; }
|
||||||
|
|
||||||
|
//! Simulated aircraft model string
|
||||||
|
const QString &getAircraftModelString() const { return m_aircraft.getModelString(); }
|
||||||
|
|
||||||
|
//! Set the aircraft
|
||||||
|
void setAircraft(const BlackMisc::Simulation::CSimulatedAircraft &aircraft) { m_aircraft = aircraft; }
|
||||||
|
|
||||||
|
//! Add parts for interpolator
|
||||||
|
void addAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts);
|
||||||
|
|
||||||
|
//! Add situation for interpolator
|
||||||
|
void addAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation);
|
||||||
|
|
||||||
|
//! Parts as sent to simulator
|
||||||
|
const BlackMisc::Aviation::CAircraftParts &getPartsAsSent() const { return m_partsAsSent; }
|
||||||
|
|
||||||
|
//! Parts as sent to simulator
|
||||||
|
void setPartsAsSent(const BlackMisc::Aviation::CAircraftParts &parts) { m_partsAsSent = parts; }
|
||||||
|
|
||||||
|
//! Position as sent
|
||||||
|
void setPositionAsSent(const BlackMisc::Aviation::CAircraftSituation &position) { m_positionAsSent = position; }
|
||||||
|
|
||||||
|
//! Same as sent
|
||||||
|
bool isSameAsSent(const BlackMisc::Aviation::CAircraftSituation &position) const;
|
||||||
|
|
||||||
|
//! VTOL?
|
||||||
|
bool isVtol() const { return m_aircraft.isVtol(); }
|
||||||
|
|
||||||
|
//! \copydoc BlackMisc::Simulation::CInterpolatorMulti::toggleMode
|
||||||
|
void toggleInterpolatorMode();
|
||||||
|
|
||||||
|
//! \copydoc BlackMisc::Simulation::CInterpolatorMulti::setMode
|
||||||
|
bool setInterpolatorMode(BlackMisc::Simulation::CInterpolatorMulti::Mode mode);
|
||||||
|
|
||||||
|
//! \copydoc BlackMisc::Simulation::CInterpolator::getInterpolatorInfo
|
||||||
|
QString getInterpolatorInfo() const;
|
||||||
|
|
||||||
|
//! \copydoc BlackMisc::Simulation::CInterpolator::attachLogger
|
||||||
|
void attachInterpolatorLogger(BlackMisc::Simulation::CInterpolationLogger *logger);
|
||||||
|
|
||||||
|
//! \copydoc BlackMisc::Simulation::CInterpolator::getInterpolatedSituation
|
||||||
|
BlackMisc::Aviation::CAircraftSituation getInterpolatedSituation(
|
||||||
|
qint64 currentTimeSinceEpoc,
|
||||||
|
const BlackMisc::Simulation::CInterpolationAndRenderingSetup &setup,
|
||||||
|
const BlackMisc::Simulation::CInterpolationHints &hints, BlackMisc::Simulation::CInterpolationStatus &status) const;
|
||||||
|
|
||||||
|
//! \copydoc BlackMisc::Simulation::CInterpolator::getInterpolatedParts
|
||||||
|
BlackMisc::Aviation::CAircraftParts getInterpolatedParts(
|
||||||
|
qint64 currentTimeSinceEpoc,
|
||||||
|
const BlackMisc::Simulation::CInterpolationAndRenderingSetup &setup,
|
||||||
|
BlackMisc::Simulation::CPartsStatus &partsStatus, bool log) const;
|
||||||
|
|
||||||
|
//! Interpolator
|
||||||
|
BlackMisc::Simulation::CInterpolatorMulti *getInterpolator() const { return m_interpolator.data(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
BlackMisc::Simulation::CSimulatedAircraft m_aircraft; //!< corresponding aircraft
|
||||||
|
QSharedPointer<BlackMisc::Simulation::CInterpolatorMulti> m_interpolator; //!< shared pointer because CSimConnectObject can be copied
|
||||||
|
BlackMisc::Aviation::CAircraftSituation m_positionAsSent;
|
||||||
|
BlackMisc::Aviation::CAircraftParts m_partsAsSent;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Simulator objects (aka AI aircraft)
|
||||||
|
class CXPlaneMPAircrafts : public QHash<BlackMisc::Aviation::CCallsign, CXPlaneMPAircraft>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Get all callsigns
|
||||||
|
BlackMisc::Aviation::CCallsignSet getAllCallsigns() const;
|
||||||
|
|
||||||
|
//! Get all callsign strings
|
||||||
|
QStringList getAllCallsignStrings(bool sorted = false) const;
|
||||||
|
|
||||||
|
//! Get all callsign strings as string
|
||||||
|
QString getAllCallsignStringsAsString(bool sorted = false, const QString &separator = ", ") const;
|
||||||
|
|
||||||
|
//! Toggle interpolator modes
|
||||||
|
void toggleInterpolatorModes();
|
||||||
|
|
||||||
|
//! Toggle interpolator modes
|
||||||
|
void toggleInterpolatorMode(const BlackMisc::Aviation::CCallsign &callsign);
|
||||||
|
|
||||||
|
//! Set interpolator modes
|
||||||
|
int setInterpolatorModes(BlackMisc::Simulation::CInterpolatorMulti::Mode mode);
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#endif // guard
|
||||||
@@ -86,6 +86,11 @@ namespace BlackSimPlugin
|
|||||||
m_dbusInterface->callDBus(QLatin1String("addPlanePosition"), callsign, latitude, longitude, altitude, pitch, roll, heading, relativeTime, timeOffset);
|
m_dbusInterface->callDBus(QLatin1String("addPlanePosition"), callsign, latitude, longitude, altitude, pitch, roll, heading, relativeTime, timeOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CXSwiftBusTrafficProxy::setPlanePosition(const QString &callsign, double latitude, double longitude, double altitude, double pitch, double roll, double heading)
|
||||||
|
{
|
||||||
|
m_dbusInterface->callDBus(QLatin1String("setPlanePosition"), callsign, latitude, longitude, altitude, pitch, roll, heading);
|
||||||
|
}
|
||||||
|
|
||||||
void CXSwiftBusTrafficProxy::addPlaneSurfaces(const QString &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust,
|
void CXSwiftBusTrafficProxy::addPlaneSurfaces(const QString &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust,
|
||||||
double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern, bool onGround, qint64 relativeTime, qint64 timeOffset)
|
double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern, bool onGround, qint64 relativeTime, qint64 timeOffset)
|
||||||
{
|
{
|
||||||
@@ -93,6 +98,13 @@ namespace BlackSimPlugin
|
|||||||
landLight, beaconLight, strobeLight, navLight, lightPattern, onGround, relativeTime, timeOffset);
|
landLight, beaconLight, strobeLight, navLight, lightPattern, onGround, relativeTime, timeOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CXSwiftBusTrafficProxy::setPlaneSurfaces(const QString &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust,
|
||||||
|
double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern, bool onGround)
|
||||||
|
{
|
||||||
|
m_dbusInterface->callDBus(QLatin1String("setPlaneSurfaces"), callsign, gear, flap, spoiler, speedBrake, slat, wingSweep, thrust, elevator, rudder, aileron,
|
||||||
|
landLight, beaconLight, strobeLight, navLight, lightPattern, onGround);
|
||||||
|
}
|
||||||
|
|
||||||
void CXSwiftBusTrafficProxy::setPlaneTransponder(const QString &callsign, int code, bool modeC, bool ident)
|
void CXSwiftBusTrafficProxy::setPlaneTransponder(const QString &callsign, int code, bool modeC, bool ident)
|
||||||
{
|
{
|
||||||
m_dbusInterface->callDBus(QLatin1String("setPlaneTransponder"), callsign, code, modeC, ident);
|
m_dbusInterface->callDBus(QLatin1String("setPlaneTransponder"), callsign, code, modeC, ident);
|
||||||
|
|||||||
@@ -61,6 +61,10 @@ namespace BlackSimPlugin
|
|||||||
private:
|
private:
|
||||||
BlackMisc::CGenericDBusInterface *m_dbusInterface = nullptr;
|
BlackMisc::CGenericDBusInterface *m_dbusInterface = nullptr;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
//! \copydoc XSwiftBus::CTraffic::simFrame
|
||||||
|
void simFrame();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
//! \copydoc XSwiftBus::CTraffic::initialize
|
//! \copydoc XSwiftBus::CTraffic::initialize
|
||||||
bool initialize();
|
bool initialize();
|
||||||
@@ -98,10 +102,17 @@ namespace BlackSimPlugin
|
|||||||
//! \copydoc XSwiftBus::CTraffic::addPlanePosition
|
//! \copydoc XSwiftBus::CTraffic::addPlanePosition
|
||||||
void addPlanePosition(const QString &callsign, double latitude, double longitude, double altitude, double pitch, double roll, double heading, qint64 relativeTime, qint64 timeOffset);
|
void addPlanePosition(const QString &callsign, double latitude, double longitude, double altitude, double pitch, double roll, double heading, qint64 relativeTime, qint64 timeOffset);
|
||||||
|
|
||||||
|
//! \copydoc XSwiftBus::CTraffic::setPlanePosition
|
||||||
|
void setPlanePosition(const QString &callsign, double latitude, double longitude, double altitude, double pitch, double roll, double heading);
|
||||||
|
|
||||||
//! \copydoc XSwiftBus::CTraffic::addPlaneSurfaces
|
//! \copydoc XSwiftBus::CTraffic::addPlaneSurfaces
|
||||||
void addPlaneSurfaces(const QString &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust,
|
void addPlaneSurfaces(const QString &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust,
|
||||||
double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern, bool onGround, qint64 relativeTime, qint64 timeOffset);
|
double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern, bool onGround, qint64 relativeTime, qint64 timeOffset);
|
||||||
|
|
||||||
|
//! \copydoc XSwiftBus::CTraffic::setPlaneSurfaces
|
||||||
|
void setPlaneSurfaces(const QString &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust,
|
||||||
|
double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern, bool onGround);
|
||||||
|
|
||||||
//! \copydoc XSwiftBus::CTraffic::setPlaneTransponder
|
//! \copydoc XSwiftBus::CTraffic::setPlaneTransponder
|
||||||
void setPlaneTransponder(const QString &callsign, int code, bool modeC, bool ident);
|
void setPlaneTransponder(const QString &callsign, int code, bool modeC, bool ident);
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <XPLM/XPLMProcessing.h>
|
#include <XPLM/XPLMProcessing.h>
|
||||||
#include <XPLM/XPLMUtilities.h>
|
#include <XPLM/XPLMUtilities.h>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
#include <QDebug>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
@@ -74,6 +75,7 @@ namespace XSwiftBus
|
|||||||
CTraffic::CTraffic(QObject *parent) :
|
CTraffic::CTraffic(QObject *parent) :
|
||||||
QObject(parent)
|
QObject(parent)
|
||||||
{
|
{
|
||||||
|
XPLMRegisterDrawCallback(CTraffic::drawCallback, xplm_Phase_Airplanes, 0, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
CTraffic::~CTraffic()
|
CTraffic::~CTraffic()
|
||||||
@@ -124,6 +126,21 @@ namespace XSwiftBus
|
|||||||
m_initialized = false;
|
m_initialized = false;
|
||||||
XPMPMultiplayerCleanup();
|
XPMPMultiplayerCleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XPLMUnregisterDrawCallback(CTraffic::drawCallback, xplm_Phase_Airplanes, 0, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTraffic::emitSimFrame()
|
||||||
|
{
|
||||||
|
qint64 currentMSecsSinceEpoch = QDateTime::currentMSecsSinceEpoch();
|
||||||
|
|
||||||
|
// The draw callback is called twice for unknown reasons each frame. We can filter the second one by
|
||||||
|
// requiring a minimum offset of 5 ms (equal to 200 fps).
|
||||||
|
if (currentMSecsSinceEpoch > m_timestampLastSimFrame + 5)
|
||||||
|
{
|
||||||
|
emit simFrame();
|
||||||
|
m_timestampLastSimFrame = currentMSecsSinceEpoch;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int g_maxPlanes = 100;
|
int g_maxPlanes = 100;
|
||||||
@@ -258,6 +275,17 @@ namespace XSwiftBus
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CTraffic::setPlanePosition(const QString &callsign, double latitude, double longitude, double altitude, double pitch, double roll, double heading)
|
||||||
|
{
|
||||||
|
const auto plane = m_planesByCallsign.value(callsign, nullptr);
|
||||||
|
plane->position.lat = latitude;
|
||||||
|
plane->position.lon = longitude;
|
||||||
|
plane->position.elevation = altitude;
|
||||||
|
plane->position.pitch = static_cast<float>(pitch);
|
||||||
|
plane->position.roll = static_cast<float>(roll);
|
||||||
|
plane->position.heading = static_cast<float>(heading);
|
||||||
|
}
|
||||||
|
|
||||||
void CTraffic::addPlaneSurfaces(const QString &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust,
|
void CTraffic::addPlaneSurfaces(const QString &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust,
|
||||||
double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern, bool onGround, qint64 relativeTime, qint64 timeOffset)
|
double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern, bool onGround, qint64 relativeTime, qint64 timeOffset)
|
||||||
{
|
{
|
||||||
@@ -295,6 +323,32 @@ namespace XSwiftBus
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CTraffic::setPlaneSurfaces(const QString &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust,
|
||||||
|
double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern, bool onGround)
|
||||||
|
{
|
||||||
|
Q_UNUSED(onGround);
|
||||||
|
const auto plane = m_planesByCallsign.value(callsign, nullptr);
|
||||||
|
if (plane)
|
||||||
|
{
|
||||||
|
plane->hasSurfaces = true;
|
||||||
|
plane->targetGearPosition = gear;
|
||||||
|
plane->surfaces.flapRatio = flap;
|
||||||
|
plane->surfaces.spoilerRatio = spoiler;
|
||||||
|
plane->surfaces.speedBrakeRatio = speedBrake;
|
||||||
|
plane->surfaces.slatRatio = slat;
|
||||||
|
plane->surfaces.wingSweep = wingSweep;
|
||||||
|
plane->surfaces.thrust = thrust;
|
||||||
|
plane->surfaces.yokePitch = elevator;
|
||||||
|
plane->surfaces.yokeHeading = rudder;
|
||||||
|
plane->surfaces.yokeRoll = aileron;
|
||||||
|
plane->surfaces.lights.landLights = landLight;
|
||||||
|
plane->surfaces.lights.bcnLights = beaconLight;
|
||||||
|
plane->surfaces.lights.strbLights = strobeLight;
|
||||||
|
plane->surfaces.lights.navLights = navLight;
|
||||||
|
plane->surfaces.lights.flashPattern = lightPattern;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CTraffic::setPlaneTransponder(const QString &callsign, int code, bool modeC, bool ident)
|
void CTraffic::setPlaneTransponder(const QString &callsign, int code, bool modeC, bool ident)
|
||||||
{
|
{
|
||||||
const auto plane = m_planesByCallsign.value(callsign, nullptr);
|
const auto plane = m_planesByCallsign.value(callsign, nullptr);
|
||||||
@@ -342,6 +396,20 @@ namespace XSwiftBus
|
|||||||
switch (dataType)
|
switch (dataType)
|
||||||
{
|
{
|
||||||
case xpmpDataType_Position:
|
case xpmpDataType_Position:
|
||||||
|
{
|
||||||
|
if (c_driverInterpolation)
|
||||||
|
{
|
||||||
|
const auto io_position = static_cast<XPMPPlanePosition_t *>(io_data);
|
||||||
|
io_position->lat = plane->position.lat;
|
||||||
|
io_position->lon = plane->position.lon;
|
||||||
|
io_position->elevation = plane->position.elevation;
|
||||||
|
io_position->pitch = plane->position.pitch;
|
||||||
|
io_position->roll = plane->position.roll;
|
||||||
|
io_position->heading = plane->position.heading;
|
||||||
|
std::strncpy(io_position->label, plane->label, sizeof(plane->label)); // fixme don't need to copy on every frame
|
||||||
|
return xpmpData_NewData;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
BlackMisc::Simulation::CInterpolationAndRenderingSetup setup;
|
BlackMisc::Simulation::CInterpolationAndRenderingSetup setup;
|
||||||
BlackMisc::Simulation::CInterpolationStatus status;
|
BlackMisc::Simulation::CInterpolationStatus status;
|
||||||
@@ -364,16 +432,23 @@ namespace XSwiftBus
|
|||||||
return xpmpData_NewData;
|
return xpmpData_NewData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
case xpmpDataType_Surfaces:
|
case xpmpDataType_Surfaces:
|
||||||
if (plane->hasSurfaces)
|
if (plane->hasSurfaces)
|
||||||
{
|
{
|
||||||
const auto currentTime = QDateTime::currentMSecsSinceEpoch();
|
const auto currentTime = QDateTime::currentMSecsSinceEpoch();
|
||||||
while (! plane->pendingSurfaces.isEmpty() && plane->pendingSurfaces.constFirst().first <= currentTime)
|
|
||||||
|
if (! c_driverInterpolation)
|
||||||
{
|
{
|
||||||
//! \todo if gear is currently retracted, look ahead and pull gear position from pendingSurfaces up to 5 seconds in the future
|
while (! plane->pendingSurfaces.isEmpty() && plane->pendingSurfaces.constFirst().first <= currentTime)
|
||||||
plane->pendingSurfaces.constFirst().second(plane);
|
{
|
||||||
plane->pendingSurfaces.pop_front();
|
//! \todo if gear is currently retracted, look ahead and pull gear position from pendingSurfaces up to 5 seconds in the future
|
||||||
|
plane->pendingSurfaces.constFirst().second(plane);
|
||||||
|
plane->pendingSurfaces.pop_front();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plane->surfaces.gearPosition != plane->targetGearPosition)
|
if (plane->surfaces.gearPosition != plane->targetGearPosition)
|
||||||
{
|
{
|
||||||
// interpolate gear position
|
// interpolate gear position
|
||||||
@@ -412,6 +487,15 @@ namespace XSwiftBus
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CTraffic::drawCallback(XPLMDrawingPhase phase, int isBefore, void *refcon)
|
||||||
|
{
|
||||||
|
Q_UNUSED(phase);
|
||||||
|
Q_UNUSED(isBefore);
|
||||||
|
CTraffic *traffic = static_cast<CTraffic *>(refcon);
|
||||||
|
traffic->emitSimFrame();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \endcond
|
//! \endcond
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include "XPMPMultiplayer.h"
|
#include "XPMPMultiplayer.h"
|
||||||
|
#include <XPLM/XPLMDisplay.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@@ -65,6 +66,10 @@ namespace XSwiftBus
|
|||||||
//! Called by XPluginStart
|
//! Called by XPluginStart
|
||||||
static void initLegacyData();
|
static void initLegacyData();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
//! Signal emitted for each simulator rendering frame
|
||||||
|
void simFrame();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
//! Initialize the multiplayer planes rendering and return true if successful
|
//! Initialize the multiplayer planes rendering and return true if successful
|
||||||
bool initialize();
|
bool initialize();
|
||||||
@@ -99,13 +104,20 @@ namespace XSwiftBus
|
|||||||
//! Remove all traffic aircraft
|
//! Remove all traffic aircraft
|
||||||
void removeAllPlanes();
|
void removeAllPlanes();
|
||||||
|
|
||||||
//! Set the position of a traffic aircraft
|
//! Add the position of a traffic aircraft
|
||||||
void addPlanePosition(const QString &callsign, double latitude, double longitude, double altitude, double pitch, double roll, double heading, qint64 relativeTime, qint64 timeOffset);
|
void addPlanePosition(const QString &callsign, double latitude, double longitude, double altitude, double pitch, double roll, double heading, qint64 relativeTime, qint64 timeOffset);
|
||||||
|
|
||||||
//! Set the flight control surfaces and lights of a traffic aircraft
|
//! Set the position of a traffic aircraft
|
||||||
|
void setPlanePosition(const QString &callsign, double latitude, double longitude, double altitude, double pitch, double roll, double heading);
|
||||||
|
|
||||||
|
//! Add the flight control surfaces and lights of a traffic aircraft
|
||||||
void addPlaneSurfaces(const QString &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust,
|
void addPlaneSurfaces(const QString &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust,
|
||||||
double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern, bool onGround, qint64 relativeTime, qint64 timeOffset);
|
double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern, bool onGround, qint64 relativeTime, qint64 timeOffset);
|
||||||
|
|
||||||
|
//! Set the flight control surfaces and lights of a traffic aircraft
|
||||||
|
void setPlaneSurfaces(const QString &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust,
|
||||||
|
double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern, bool onGround);
|
||||||
|
|
||||||
//! Set the transponder of a traffic aircraft
|
//! Set the transponder of a traffic aircraft
|
||||||
void setPlaneTransponder(const QString &callsign, int code, bool modeC, bool ident);
|
void setPlaneTransponder(const QString &callsign, int code, bool modeC, bool ident);
|
||||||
|
|
||||||
@@ -116,6 +128,10 @@ namespace XSwiftBus
|
|||||||
bool m_initialized = false;
|
bool m_initialized = false;
|
||||||
bool m_enabled = false;
|
bool m_enabled = false;
|
||||||
|
|
||||||
|
static constexpr bool c_driverInterpolation = true;
|
||||||
|
|
||||||
|
void emitSimFrame();
|
||||||
|
|
||||||
static int preferences(const char *section, const char *name, int def);
|
static int preferences(const char *section, const char *name, int def);
|
||||||
static float preferences(const char *section, const char *name, float def);
|
static float preferences(const char *section, const char *name, float def);
|
||||||
|
|
||||||
@@ -137,16 +153,20 @@ namespace XSwiftBus
|
|||||||
float targetGearPosition = 0;
|
float targetGearPosition = 0;
|
||||||
qint64 prevSurfacesLerpTime = 0;
|
qint64 prevSurfacesLerpTime = 0;
|
||||||
XPMPPlaneRadar_t xpdr;
|
XPMPPlaneRadar_t xpdr;
|
||||||
|
XPMPPlanePosition_t position;
|
||||||
Plane(void *id_, QString callsign_, QString aircraftIcao_, QString airlineIcao_, QString livery_);
|
Plane(void *id_, QString callsign_, QString aircraftIcao_, QString airlineIcao_, QString livery_);
|
||||||
};
|
};
|
||||||
QHash<QString, Plane *> m_planesByCallsign;
|
QHash<QString, Plane *> m_planesByCallsign;
|
||||||
QHash<void *, Plane *> m_planesById;
|
QHash<void *, Plane *> m_planesById;
|
||||||
|
qint64 m_timestampLastSimFrame = QDateTime::currentMSecsSinceEpoch();
|
||||||
|
|
||||||
int getPlaneData(void *id, int dataType, void *io_data);
|
int getPlaneData(void *id, int dataType, void *io_data);
|
||||||
static int getPlaneData(void *id, int dataType, void *io_data, void *self)
|
static int getPlaneData(void *id, int dataType, void *io_data, void *self)
|
||||||
{
|
{
|
||||||
return static_cast<CTraffic *>(self)->getPlaneData(id, dataType, io_data);
|
return static_cast<CTraffic *>(self)->getPlaneData(id, dataType, io_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int drawCallback(XPLMDrawingPhase phase, int isBefore, void *refcon);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user