9 #include <QDBusServiceWatcher>
15 #include "dbus/dbus.h"
18 #include "qcompilerdetection.h"
57 using namespace swift::config;
59 using namespace swift::misc::aviation;
60 using namespace swift::misc::network;
61 using namespace swift::misc::physical_quantities;
62 using namespace swift::misc::simulation;
63 using namespace swift::misc::geo;
64 using namespace swift::misc::simulation;
65 using namespace swift::misc::weather;
70 inline const QString &fgswiftbusServiceName()
72 static const QString name(
"org.swift-project.fgswiftbus");
77 namespace swift::simplugin::flightgear
79 int FGSWIFTBUS_API_VERSION = -1;
85 : CSimulatorPluginCommon(info, ownAircraftProvider, remoteAircraftProvider, clientProvider, parent)
100 m_fastTimer.
start(100);
101 m_slowTimer.
start(1000);
102 m_pendingAddedTimer.
start(5000);
105 {
"FG c172p", CAircraftModel::TypeModelMatchingDefaultModel,
"C172",
CAircraftIcaoCode(
"C172",
"L1P") });
106 this->resetFlightgearData();
116 CSimulatorPluginCommon::unload();
123 return QStringLiteral(
"Add-time: %1ms/%2ms").
arg(m_statsAddCurrentTimeMs).
arg(m_statsAddMaxTimeMs);
128 m_statsAddMaxTimeMs = -1;
129 m_statsAddCurrentTimeMs = -1;
137 return m_flightgearAircraftObjects[callsign].getInterpolationMessages(setup.
getInterpolatorMode());
144 if (!m_trafficProxy) {
return false; }
145 if (!m_flightgearAircraftObjects.
contains(callsign)) {
return false; }
156 if (parts.
isNull() && flightgear::FGSWIFTBUS_API_VERSION >= 2)
168 m_aircraftAddedFailed.
clear();
169 CSimulatorPluginCommon::clearAllRemoteAircraftData();
175 if (ident) {
return CTransponder::StateIdent; }
176 if (transponderMode == 0 || transponderMode == 1 || transponderMode == 2) {
return CTransponder::StateStandby; }
177 return CTransponder::ModeC;
183 void CSimulatorFlightgear::fastTimerTimeout()
206 CAltitude::PressureAltitude, CLengthUnit::ft() });
209 situation.
setBank({ m_flightgearData.
rollDeg, CAngleUnit::deg() });
213 CAircraftSituation::FromProvider);
215 if (!m_simulatorPaused)
225 { 0.0, 0.0, 0.0, CSpeedUnit::m_s(), 0.0, 0.0, 0.0, CAngleUnit::rad(), CTimeUnit::s() });
242 com1.setVolumeReceive(qRound(m_flightgearData.
volumeCom1 * 100));
243 const bool changedCom1 = myAircraft.getCom1System() != com1;
247 com2.setVolumeReceive(qRound(m_flightgearData.
volumeCom2 * 100));
248 const bool changedCom2 = myAircraft.getCom2System() != com2;
250 transponder = CTransponder::getStandardTransponder(
252 const bool changedXpr = (myAircraft.getTransponder() != transponder);
254 if (changedCom1 || changedCom2 || changedXpr)
261 void CSimulatorFlightgear::slowTimerTimeout()
298 this->requestRemoteAircraftDataFromFlightgear();
301 for (CFlightgearMPAircraft &flightgearAircraft : m_flightgearAircraftObjects)
304 const CCallsign cs = flightgearAircraft.getCallsign();
311 flightgearAircraft.setSimulatedAircraft(simulatedAircraft);
316 for (
const CCallsign &cs : invalid) { this->triggerRemoveAircraft(cs, ++i * 100); }
327 if (CDBusServer::isSessionOrSystemAddress(dbusAddress))
330 m_dbusMode = Session;
332 else if (CDBusServer::isQtDBusAddress(dbusAddress))
335 if (!m_dBusConnection.
isConnected()) {
return false; }
342 const bool s = m_dBusConnection.
connect(
QString(), DBUS_PATH_LOCAL, DBUS_INTERFACE_LOCAL,
"Disconnected",
this,
343 SLOT(onDBusServiceUnregistered()));
357 &CSimulatorFlightgear::emitOwnAircraftModelChanged);
360 &CSimulatorFlightgear::onRemoteAircraftAdded);
362 &CSimulatorFlightgear::onRemoteAircraftAddingFailed);
363 if (m_watcher) { m_watcher->
setConnection(m_dBusConnection); }
374 this->disconnectFromDBus();
375 if (m_watcher) { m_watcher->
setConnection(m_dBusConnection); }
376 delete m_serviceProxy;
377 delete m_trafficProxy;
378 m_serviceProxy =
nullptr;
379 m_trafficProxy =
nullptr;
384 void CSimulatorFlightgear::onDBusServiceUnregistered()
386 if (!m_serviceProxy) {
return; }
391 if (m_watcher) { m_watcher->
setConnection(m_dBusConnection); }
392 delete m_serviceProxy;
393 delete m_trafficProxy;
394 m_serviceProxy =
nullptr;
395 m_trafficProxy =
nullptr;
399 void CSimulatorFlightgear::emitOwnAircraftModelChanged(
const QString &path,
const QString &filename,
404 CAircraftModel model(modelString, CAircraftModel::TypeOwnSimulatorModel, CSimulatorInfo::XPLANE, name,
406 if (!livery.
isEmpty()) { model.setModelString(model.getModelString()); }
407 model.setFileName(path +
"/" + filename);
418 static bool isInFunction =
false;
419 if (isInFunction) {
return; }
423 isInFunction =
false;
434 return m_flightgearAircraftObjects.contains(callsign);
440 if (originator == this->
identifier()) {
return false; }
443 auto com1 = CComSystem::getCom1System({ m_flightgearData.
com1ActiveKhz, CFrequencyUnit::kHz() },
445 auto com2 = CComSystem::getCom2System({ m_flightgearData.
com2ActiveKhz, CFrequencyUnit::kHz() },
447 auto xpdr = CTransponder::getStandardTransponder(
477 if (originator == this->
identifier()) {
return false; }
491 Q_ASSERT_X(CThreadUtils::isInThisThread(
this), Q_FUNC_INFO,
"thread");
492 Q_ASSERT_X(!newRemoteAircraft.
getCallsign().
isEmpty(), Q_FUNC_INFO,
"empty callsign");
493 Q_ASSERT_X(newRemoteAircraft.
hasModelString(), Q_FUNC_INFO,
"missing model string");
505 if (this->canAddAircraft())
515 CLogMessage(
this).
warning(u
"Model for '%1' has no callsign, maybe using a default model") << callsign;
526 if (flightgear::FGSWIFTBUS_API_VERSION >= 2)
536 m_pendingToBeAddedAircraft.
replaceOrAdd(newRemoteAircraft);
546 Q_ASSERT_X(CThreadUtils::isInThisThread(
this), Q_FUNC_INFO,
"wrong thread");
547 if (callsign.
isEmpty()) {
return false; }
550 if (!m_flightgearAircraftObjects.contains(callsign) && !m_pendingToBeAddedAircraft.
containsCallsign(callsign) &&
551 !m_addingInProgressAircraft.
contains(callsign))
561 if (m_flightgearAircraftObjects.contains(callsign))
576 if (m_addingInProgressAircraft.
contains(callsign))
581 if (!myself) {
return; }
582 m_addingInProgressAircraft.
remove(callsign);
589 m_flightgearAircraftObjects.remove(callsign);
593 return CSimulatorPluginCommon::physicallyRemoveRemoteAircraft(callsign);
599 m_pendingToBeAddedAircraft.
clear();
600 m_addingInProgressAircraft.
clear();
601 return CSimulatorPluginCommon::physicallyRemoveAllRemoteAircraft();
609 void CSimulatorFlightgear::updateRemoteAircraft()
611 Q_ASSERT_X(CThreadUtils::isInThisThread(
this), Q_FUNC_INFO,
"thread");
614 if (remoteAircraftNo < 1) {
return; }
621 PlanesPositions planesPositions;
622 PlanesSurfaces planesSurfaces;
623 PlanesTransponders planesTransponders;
625 uint32_t aircraftNumber = 0;
628 for (
const CFlightgearMPAircraft &flightgearAircraft : std::as_const(m_flightgearAircraftObjects))
630 const CCallsign callsign(flightgearAircraft.getCallsign());
631 const bool hasCallsign = !callsign.isEmpty();
640 if (!callsignsInRange.
contains(callsign)) {
continue; }
642 planesTransponders.callsigns.push_back(callsign.asString());
643 planesTransponders.codes.push_back(flightgearAircraft.getAircraft().getTransponderCode());
645 planesTransponders.idents.push_back(transponderMode == CTransponder::StateIdent);
646 planesTransponders.modeCs.push_back(transponderMode == CTransponder::ModeC);
654 flightgearAircraft.getInterpolation(currentTimestamp, setup, aircraftNumber++);
660 if (updateAllAircraft || !this->
isEqualLastSent(interpolatedSituation))
663 planesPositions.push_back(interpolatedSituation);
678 planesSurfaces.push_back(flightgearAircraft.getCallsign(), parts);
684 if (!planesTransponders.isEmpty() && flightgear::FGSWIFTBUS_API_VERSION >= 2)
689 if (!planesPositions.isEmpty())
691 if (CBuildConfig::isLocalDeveloperDebugBuild())
693 SWIFT_VERIFY_X(planesPositions.hasSameSizes(), Q_FUNC_INFO,
"Mismatching sizes");
698 if (!planesSurfaces.isEmpty() && flightgear::FGSWIFTBUS_API_VERSION >= 2)
707 void CSimulatorFlightgear::requestRemoteAircraftDataFromFlightgear()
715 CCallsignSet callsigns = m_flightgearAircraftObjects.getAllCallsigns();
718 if (!callsigns.
isEmpty()) { this->requestRemoteAircraftDataFromFlightgear(callsigns); }
721 void CSimulatorFlightgear::requestRemoteAircraftDataFromFlightgear(
const CCallsignSet &callsigns)
723 if (callsigns.
isEmpty()) {
return; }
729 [=](
const QStringList &callsigns,
const QDoubleList &latitudesDeg,
const QDoubleList &longitudesDeg,
730 const QDoubleList &elevationsMeters,
const QDoubleList &verticalOffsetsMeters) {
731 if (!myself) {
return; }
732 this->updateRemoteAircraftFromSimulator(callsigns, latitudesDeg, longitudesDeg, elevationsMeters,
733 verticalOffsetsMeters);
737 void CSimulatorFlightgear::triggerRequestRemoteAircraftDataFromFlightgear(
const CCallsignSet &callsigns)
739 if (callsigns.
isEmpty()) {
return; }
742 if (!myself) {
return; }
743 this->requestRemoteAircraftDataFromFlightgear(callsigns);
747 void CSimulatorFlightgear::updateRemoteAircraftFromSimulator(
const QStringList &callsigns,
748 const QDoubleList &latitudesDeg,
749 const QDoubleList &longitudesDeg,
750 const QDoubleList &elevationsMeters,
751 const QDoubleList &verticalOffsetsMeters)
753 const int size = callsigns.
size();
756 if (CBuildConfig::isLocalDeveloperDebugBuild())
758 Q_ASSERT_X(elevationsMeters.size() == size, Q_FUNC_INFO,
"Wrong elevations");
759 Q_ASSERT_X(latitudesDeg.size() == size, Q_FUNC_INFO,
"Wrong latitudesDeg");
760 Q_ASSERT_X(longitudesDeg.size() == size, Q_FUNC_INFO,
"Wrong longitudesDeg");
761 Q_ASSERT_X(verticalOffsetsMeters.size() == size, Q_FUNC_INFO,
"Wrong CG");
765 for (
int i = 0; i < size; i++)
767 const bool emptyCs = callsigns[i].
isEmpty();
769 if (emptyCs) {
continue; }
771 if (!m_flightgearAircraftObjects.contains(cs)) {
continue; }
772 const CFlightgearMPAircraft fgAircraft = m_flightgearAircraftObjects[cs];
773 SWIFT_VERIFY_X(fgAircraft.hasCallsign(), Q_FUNC_INFO,
"Need callsign");
774 if (!fgAircraft.hasCallsign()) {
continue; }
777 if (!std::isnan(elevationsMeters[i]))
779 const CAltitude elevationAlt =
CAltitude(elevationsMeters[i], CLengthUnit::m(), CLengthUnit::ft());
781 CLongitude(longitudesDeg[i], CAngleUnit::deg()), elevationAlt,
782 CElevationPlane::singlePointRadius());
785 const double cgValue = verticalOffsetsMeters[i];
797 void CSimulatorFlightgear::disconnectFromDBus()
801 if (m_trafficProxy) { m_trafficProxy->
cleanup(); }
809 void CSimulatorFlightgear::onRemoteAircraftAdded(
const QString &callsign)
812 if (callsign.
isEmpty()) {
return; }
817 bool wasPending =
false;
818 if (m_addingInProgressAircraft.
contains(cs))
821 const qint64 wasStartedMs = m_addingInProgressAircraft.
value(cs);
823 m_statsAddCurrentTimeMs = deltaTimeMs;
824 if (deltaTimeMs > m_statsAddMaxTimeMs) { m_statsAddMaxTimeMs = deltaTimeMs; }
825 m_addingInProgressAircraft.
remove(cs);
830 CLogMessage(
this).
warning(u
"Aircraft '%1' no longer in range, will be removed") << callsign;
831 this->triggerRemoveAircraft(cs, TimeoutAdding);
840 CLogMessage(
this).
warning(u
"Added callsign '%1' was not in progress anymore. Timeout?") << callsign;
843 const bool rendered =
true;
846 this->triggerRequestRemoteAircraftDataFromFlightgear(cs);
847 this->triggerAddNextPendingAircraft();
849 Q_ASSERT_X(addedRemoteAircraft.
hasCallsign(), Q_FUNC_INFO,
"No callsign");
850 Q_ASSERT_X(addedRemoteAircraft.
getCallsign() == cs, Q_FUNC_INFO,
"No callsign");
851 m_flightgearAircraftObjects.insert(cs,
860 if (reference.
isNull()) {
return false; }
870 static const CAltitude alt(0, CAltitude::MeanSeaLevel, CLengthUnit::ft());
874 using namespace std::placeholders;
878 m_trafficProxy->getElevationAtPosition(callsign, pos.
latitude().
value(CAngleUnit::deg()),
885 void CSimulatorFlightgear::onRemoteAircraftAddingFailed(
const QString &callsign)
888 if (callsign.
isEmpty()) {
return; }
899 CLogMessage(
this).
warning(u
"Adding '%1' failed, but aircraft no longer in range, will be removed")
903 const bool wasPending = (
static_cast<int>(m_addingInProgressAircraft.
remove(cs)) > 0);
908 m_aircraftAddedFailed.
push_back(failedRemoteAircraft);
909 m_pendingToBeAddedAircraft.
replaceOrAdd(failedRemoteAircraft);
911 this->triggerAddNextPendingAircraft();
914 void CSimulatorFlightgear::addNextPendingAircraft()
916 if (m_pendingToBeAddedAircraft.
isEmpty()) {
return; }
919 this->detectTimeoutAdding();
922 if (!this->canAddAircraft()) {
return; }
927 CLogMessage(
this).
info(u
"Adding next pending aircraft '%1', pending %2, in progress %3")
929 << m_addingInProgressAircraft.
size();
933 void CSimulatorFlightgear::triggerAddNextPendingAircraft()
937 if (!myself) {
return; }
938 this->addNextPendingAircraft();
942 int CSimulatorFlightgear::detectTimeoutAdding()
944 if (m_addingInProgressAircraft.
isEmpty()) {
return 0; }
948 for (
const CCallsign &cs : addingCallsigns)
950 if (m_addingInProgressAircraft.
value(cs) < timeout) {
continue; }
954 for (
const CCallsign &cs : std::as_const(timeoutCallsigns))
956 m_addingInProgressAircraft.
remove(cs);
960 return timeoutCallsigns.
size();
963 void CSimulatorFlightgear::triggerRemoveAircraft(
const CCallsign &callsign, qint64 deferMs)
967 if (!myself) {
return; }
972 QPair<qint64, qint64> CSimulatorFlightgear::minMaxTimestampsAddInProgress()
const
974 static const QPair<qint64, qint64> empty(-1, -1);
975 if (m_addingInProgressAircraft.
isEmpty()) {
return empty; }
978 return QPair<qint64, qint64>(*mm.first, *mm.second);
981 bool CSimulatorFlightgear::canAddAircraft()
const
983 if (this->
getModelSet().isEmpty()) {
return false; }
984 if (m_addingInProgressAircraft.
isEmpty()) {
return true; }
988 const QPair<qint64, qint64> tsMM = this->minMaxTimestampsAddInProgress();
989 const qint64 deltaLatest = now - tsMM.second;
990 const bool canAdd = (deltaLatest > TimeoutAdding);
999 return new CSimulatorFlightgear(info, ownAircraftProvider, remoteAircraftProvider, clientProvider,
this);
1005 constexpr
int QueryInterval = 5 * 1000;
1017 if (!m_timer.
isActive()) {
return; }
1023 if (!myself) {
return; }
1028 void CSimulatorFlightgearListener::checkConnection()
1031 Q_ASSERT_X(!CThreadUtils::thisIsMainThread(), Q_FUNC_INFO,
"Expect to run in background");
1034 if (CDBusServer::isSessionOrSystemAddress(dbusAddress)) { checkConnectionViaSessionBus(); }
1035 else if (CDBusServer::isQtDBusAddress(dbusAddress)) { checkConnectionViaPeer(dbusAddress); }
1038 void CSimulatorFlightgearListener::checkConnectionViaSessionBus()
1046 checkConnectionCommon();
1050 void CSimulatorFlightgearListener::checkConnectionViaPeer(
const QString &address)
1059 checkConnectionCommon();
1063 void CSimulatorFlightgearListener::checkConnectionCommon()
1065 CFGSwiftBusServiceProxy service(m_conn);
1066 CFGSwiftBusTrafficProxy traffic(m_conn);
1068 bool result = service.isValid() && traffic.isValid();
1069 if (!result) {
return; }
1071 flightgear::FGSWIFTBUS_API_VERSION = service.getVersionNumber();
1073 if (flightgear::incompatibleVersions.contains(flightgear::FGSWIFTBUS_API_VERSION))
1075 CLogMessage(
this).
error(u
"This version of swift is not compatible with this Flightgear version. For "
1076 u
"further information check http://wiki.flightgear.org/Swift.");
1079 if (!traffic.initialize())
1081 CLogMessage(
this).
error(u
"Connection to FGSwiftBus successful, but could not initialize FGSwiftBus.");
1085 const MultiplayerAcquireInfo info = traffic.acquireMultiplayerPlanes();
1086 if (!info.hasAcquired)
1089 info.owner.
trimmed().
isEmpty() ? QStringLiteral(
"Some/this plugin/application") : info.owner.trimmed();
1091 u
"Connection to FGSwiftBus successful, but could not acquire multiplayer planes. '%1' has acquired "
1092 u
"them already. Disable '%2' or remove it if not required and reload FGSwiftBus.")
1100 void CSimulatorFlightgearListener::serviceRegistered(
const QString &serviceName)
1106 void CSimulatorFlightgearListener::fgSwiftBusServerSettingChanged()
Interface to a simulator.
virtual void callbackReceivedRequestedElevation(const swift::misc::geo::CElevationPlane &plane, const swift::misc::aviation::CCallsign &callsign, bool isWater)
A requested elevation has been received.
bool addLoopbackSituation(const swift::misc::aviation::CAircraftSituation &situation)
Add a loopback situation if logging is enabled.
bool isEqualLastSent(const swift::misc::aviation::CAircraftSituation &compare) const
Equal to last sent situation.
bool updateOwnSituationAndGroundElevation(const swift::misc::aviation::CAircraftSituation &situation)
Update own aircraft position and if suitable use it to update ground elevation.
bool isUpdateAllRemoteAircraft(qint64 currentTimestamp=-1) const
Do update all remote aircraft?
virtual bool isShuttingDown() const
Is overall (swift) application shutting down.
void requestedElevation(const swift::misc::aviation::CCallsign &callsign)
Requested elevation, call pending.
bool m_updateRemoteAircraftInProgress
currently updating remote aircraft
void rememberElevationAndSimulatorCG(const swift::misc::aviation::CCallsign &callsign, const swift::misc::simulation::CAircraftModel &model, bool likelyOnGroundElevation, const swift::misc::geo::CElevationPlane &elevation, const swift::misc::physical_quantities::CLength &simulatorCG)
Set elevation and CG in the providers and for auto publishing.
bool isAircraftInRangeOrTestMode(const swift::misc::aviation::CCallsign &callsign) const
Test version aware version of isAircraftInRange.
void finishUpdateRemoteAircraftAndSetStatistics(qint64 startTime, bool limited=false)
Update stats and flags.
void reverseLookupAndUpdateOwnAircraftModel(const swift::misc::simulation::CAircraftModel &model)
Set own model.
swift::misc::aviation::CAircraftSituationList getLastSentCanLikelySkipNearGroundInterpolation() const
Last sent situations.
swift::misc::simulation::CAircraftModelList getModelSet() const
Get the model set.
void emitSimulatorCombinedStatus(SimulatorStatus oldStatus=Unspecified)
Emit the combined status.
void logAddingAircraftModel(const swift::misc::simulation::CSimulatedAircraft &aircraft) const
Unified qeeing aircraft message.
swift::misc::simulation::CInterpolationAndRenderingSetupPerCallsign getInterpolationSetupConsolidated(const swift::misc::aviation::CCallsign &callsign, bool forceFullUpdate) const
Consolidate setup with other data like from swift::misc::simulation::IRemoteAircraftProvider.
swift::misc::simulation::CInterpolationLogger m_interpolationLogger
log.interpolation
void aircraftRenderingChanged(const swift::misc::simulation::CSimulatedAircraft &aircraft)
Aircraft rendering changed.
virtual bool isShuttingDownOrDisconnected() const
Shutting down or disconnected?
virtual void initSimulatorInternals()
Init the internals info from the simulator.
QString getInvalidSituationLogMessage(const swift::misc::aviation::CCallsign &callsign, const swift::misc::simulation::CInterpolationStatus &status, const QString &details={}) const
Info about invalid situation.
void rememberLastSent(const swift::misc::aviation::CAircraftSituation &sent)
Remember as last sent.
Interface to a simulator listener.
const swift::misc::simulation::CSimulatorPluginInfo & getPluginInfo() const
Corresponding info.
void simulatorStarted(const swift::misc::simulation::CSimulatorPluginInfo &info)
Emitted when the listener discovers the simulator running.
virtual bool isShuttingDown() const
Overall (swift) application shutting down.
void start()
Start listening for the simulator to start.
void stop()
Stops listening.
const T & getThreadLocal() const
Read the current value.
size_type size() const
Returns number of elements in the collection.
void remove(const T &object)
Efficient remove using the find and erase of the implementation container. Typically O(log n).
iterator insert(const_iterator hint, const T &value)
For compatibility with std::inserter.
bool isEmpty() const
Synonym for empty.
iterator push_back(const T &value)
Synonym for insert.
const CIdentifier & identifier() const
Get identifier.
Value object encapsulating information identifying a component of a modular distributed swift process...
Class for emitting a log message.
Derived & warning(const char16_t(&format)[N])
Set the severity to warning, providing a format string.
Derived & error(const char16_t(&format)[N])
Set the severity to error, providing a format string.
Derived & info(const char16_t(&format)[N])
Set the severity to info, providing a format string.
bool contains(const T &object) const
Return true if there is an element equal to given object. Uses the most efficient implementation avai...
size_type size() const
Returns number of elements in the sequence.
void replaceOrAdd(const T &original, const T &replacement)
Replace elements matching the given element. If there is no match, push the new element on the end.
void push_back(const T &value)
Appends an element at the end of the sequence.
reference front()
Access the first element.
void clear()
Removes all elements in the sequence.
bool isEmpty() const
Synonym for empty.
void pop_front()
Removes an element at the front of the sequence.
Streamable status message, e.g.
QString getMessage() const
Message.
Status messages, e.g. from Core -> GUI.
Value object encapsulating information about aircraft's engines.
Value object encapsulating a list of aircraft engines.
Value object for ICAO classification.
const QString & getDesignator() const
Get ICAO designator, e.g. "B737".
Value object encapsulating information of aircraft's parts.
bool isNull() const
NULL parts object?
Value object encapsulating information of an aircraft's situation.
void setPressureAltitude(const CAltitude &altitude)
Set pressure altitude.
void setGroundSpeed(const physical_quantities::CSpeed &groundspeed)
Set ground speed.
bool setGroundElevation(const aviation::CAltitude &altitude, GndElevationInfo info, bool transferred=false)
Elevation of the ground directly beneath at the given situation.
void setBank(const physical_quantities::CAngle &bank)
Set bank (angle)
void setHeading(const CHeading &heading)
Set heading.
void setAltitude(const CAltitude &altitude)
Set altitude.
void setPitch(const physical_quantities::CAngle &pitch)
Set pitch.
virtual bool isNull() const
Null situation.
void setVelocity(const CAircraftVelocity &velocity)
Set 6DOF velocity.
void setPosition(const geo::CCoordinateGeodetic &position)
Set position.
const QString & getDesignator() const
Get airline, e.g. "DLH".
Altitude as used in aviation, can be AGL or MSL altitude.
Value object encapsulating information of a callsign.
const QString & asString() const
Get callsign (normalized)
bool isEmpty() const
Is empty?
Value object for a set of callsigns.
QStringList getCallsignStrings(bool sorted=false) const
The callsign strings.
const QString & getCombinedCode() const
Combined code.
swift::misc::physical_quantities::CFrequency getFrequencyStandby() const
Standby frequency.
swift::misc::physical_quantities::CFrequency getFrequencyActive() const
Active frequency.
TransponderMode
Transponder codes.
OBJ findFirstByCallsign(const CCallsign &callsign, const OBJ &ifNotFound={}) const
Find the first aircraft by callsign, if none return given one.
int removeByCallsign(const CCallsign &callsign)
Remove all objects with callsign.
swift::misc::aviation::CCallsignSet getCallsigns() const
All callsigns.
bool containsCallsign(const CCallsign &callsign) const
Contains callsign?
virtual CLatitude latitude() const
Latitude.
virtual const aviation::CAltitude & geodeticHeight() const
Height, ellipsoidal or geodetic height (used in GPS)
void setGeodeticHeight(const aviation::CAltitude &height)
Set height (ellipsoidal or geodetic height)
virtual CLongitude longitude() const
Longitude.
Plane of same elevation, can be a single point or larger area (e.g. airport)
Geodetic coordinate, a position in 3D space relative to the reference geoid.
bool hasMSLGeodeticHeight() const
Geodetic height not null and aviation::CAltitude::MeanSeaLevel.
virtual bool isNull() const
Is null, means vector x, y, z == 0.
QString toQString(bool i18n=false) const
Cast as QString.
Value object encapsulating information of a text message.
const QString & getMessage() const
Get message.
const aviation::CCallsign & getSenderCallsign() const
Get callsign (from)
Direct in memory access to client (network client) data.
Physical unit length (length)
Specialized class for distance units (meter, foot, nautical miles).
int valueInteger(MU unit) const
As integer value.
double value(MU unit) const
Value in given unit.
Aircraft model (used by another pilot, my models on disk)
const aviation::CCallsign & getCallsign() const
Corresponding callsign if applicable.
const aviation::CLivery & getLivery() const
Get livery.
void setCallsign(const aviation::CCallsign &callsign)
Corresponding callsign if applicable.
const QString & getFileName() const
File name (corresponding data for simulator, only available if representing simulator model.
InterpolatorMode getInterpolatorMode() const
Interpolator mode.
Value object for interpolator and rendering per callsign.
const CInterpolationStatus & getInterpolationStatus() const
Get status.
const CPartsStatus & getPartsStatus() const
Get status.
bool hasValidSituation() const
Is the corresponding position valid?
bool updateOwnParts(const aviation::CAircraftParts &parts)
Update own parts.
bool updateCockpit(const swift::misc::simulation::CSimulatedAircraft &aircraft, const swift::misc::CIdentifier &originator)
Update cockpit, but only send signals when applicable.
CSimulatedAircraft getOwnAircraft() const
Own aircraft.
bool isSupportingParts() const
Supporting parts.
aviation::CCallsignSet getAircraftInRangeCallsigns() const
Unique callsigns for aircraft in range.
CSimulatedAircraftList getAircraftInRange() const
All remote aircraft.
int getAircraftInRangeCount() const
Count remote aircraft.
CSimulatedAircraft getAircraftInRangeForCallsign(const aviation::CCallsign &callsign) const
Aircraft for callsign.
bool updateAircraftRendered(const aviation::CCallsign &callsign, bool rendered)
Set aircraft rendered.
Comprehensive information of an aircraft.
bool hasModelString() const
Has model string?
aviation::CTransponder::TransponderMode getTransponderMode() const
Get transponder mode.
const aviation::CAircraftSituation & getSituation() const
Get situation.
const aviation::CComSystem & getCom2System() const
Get COM2 system.
bool setRendered(bool rendered)
Rendered?
qint32 getTransponderCode() const
Get transponder code.
bool hasCallsign() const
Callsign not empty, no further checks.
const aviation::CCallsign & getCallsign() const
Get callsign.
const aviation::CAircraftIcaoCode & getAircraftIcaoCode() const
Get aircraft ICAO info.
bool hasChangedCockpitData(const aviation::CComSystem &com1, const aviation::CComSystem &com2, const aviation::CTransponder &transponder) const
Changed cockpit data?
const simulation::CAircraftModel & getModel() const
Get model (model used for mapping)
QString getCallsignAsString() const
Get callsign.
const aviation::CComSystem & getCom1System() const
Get COM1 system.
const aviation::CAirlineIcaoCode & getAirlineIcaoCode() const
Airline ICAO code if any.
const aviation::CAircraftParts & getParts() const
Get aircraft parts.
Q_REQUIRED_RESULT CSimulatedAircraftList findByRendered(bool rendered) const
Rendered / not rendered aircraft.
Describing a simulator plugin.
aviation::CCallsignSet getLogCallsigns() const
All callsigns marked to be logged.
Direct threadsafe in memory access to own aircraft.
Direct thread safe in memory access to remote aircraft.
void setSimulatorDetails(const QString &name, const QString &details, const QString &version)
Set version and simulator details from running simulator.
void setDefaultModel(const CAircraftModel &defaultModel)
Default model.
Proxy object connected to a real FGSwiftBus::CService object via DBus.
void getOwnAircraftSituationData(FlightgearData *o_flightgearData)
Get own aircraft situation data.
QString getAircraftModelFilename() const
Get base filename of current aircraft model.
void getGroundElevationAsync(double *o_groundElevation)
Get ground elevation [m] for current airplane position.
void cancelAllPendingAsyncCalls()
Cancel all current async slot calls.
void getAircraftModelPathAsync(QString *o_modelPath)
Get full path to current aircraft model.
void setCom2StandbyKhz(int freq)
Set the current COM2 standby frequency in kHz.
QString getAircraftModelString() const
Get canonical swift model string of current aircraft model.
QString getAircraftName() const
Get name of current aircraft model.
QString getAircraftIcaoCode() const
Get the ICAO code of the current aircraft model.
void getCom2StandbyKhzAsync(int *o_com2Standby)
Get the current COM2 standby frequency in kHz.
void getCom2VolumeAsync(double *o_com2Volume)
Get Com2 volume [0..1].
void setCom1StandbyKhz(int freq)
Set the current COM1 standby frequency in kHz.
void getStrobeLightsOnAsync(bool *o_strobeLightsOn)
Get whether strobe lights are on.
void getCom1VolumeAsync(double *o_com1Volume)
Get Com1 volume [0..1].
QString getAircraftLivery() const
Get current aircraft livery.
void getLandingLightsOnAsync(bool *o_landingLightsOn)
Get whether landing lights are on.
void getTaxiLightsOnAsync(bool *o_taxiLightsOn)
Get whether taxi lights are on.
void getTransponderModeAsync(int *o_xpdrMode)
Get the current transponder mode (depends on the aircraft, 0 and 1 usually mean standby,...
void getNavLightsOnAsync(bool *o_navLightsOn)
Get whether nav lights are on.
void getAllWheelsOnGroundAsync(bool *o_allWheels)
Get whether all wheels are on the ground.
void getCom2ActiveKhzAsync(int *o_com2Active)
Get the current COM2 active frequency in kHz.
QString getAircraftDescription() const
Get the description of the current aircraft model.
void getCom1ActiveKhzAsync(int *o_com1Active)
Get the current COM1 active frequency in kHz.
void setCom2ActiveKhz(int freq)
Set the current COM2 active frequency in kHz.
void isPausedAsync(bool *o_paused)
True if sim is paused.
void getAircraftIcaoCodeAsync(QString *o_icaoCode)
Get the ICAO code of the current aircraft model.
void getTransponderIdentAsync(bool *o_ident)
Get whether we are currently squawking ident.
void setTransponderCode(int code)
Set the current transponder code in decimal.
void getGearDeployRatioAsync(double *o_gearDeployRatio)
Get gear deploy ratio, where 0 is up and 1 is down.
void getSpeedBrakeRatioAsync(double *o_speedBrakeRatio)
Get the ratio how much the speedbrakes surfaces are extended (0.0 is fully retracted,...
void aircraftModelChanged(const QString &path, const QString &filename, const QString &livery, const QString &icao, const QString &modelString, const QString &name, const QString &description)
Own aircraft model changed.
void getBeaconLightsOnAsync(bool *o_beaconLightsOn)
Get whether beacon lights are on.
void getFlapsDeployRatioAsync(double *o_flapsDeployRatio)
Get flaps deploy ratio, where 0.0 is flaps fully retracted, and 1.0 is flaps fully extended.
void getTransponderCodeAsync(int *o_xpdrCode)
Get the current transponder code in decimal.
void getEngineN1PercentageAsync(QList< double > *o_engineN1Percentage)
Get the N1 speed as percent of max (per engine)
void getCom1StandbyKhzAsync(int *o_com1Standby)
Get the current COM1 standby frequency in kHz.
void setTransponderMode(int mode)
Set the current transponder mode (depends on the aircraft, 0 and 1 usually mean standby,...
QString getAircraftModelPath() const
Get full path to current aircraft model.
void setCom1ActiveKhz(int freq)
Set the current COM1 active frequency in kHz.
bool isValid() const
Does the remote object exist?
void getOwnAircraftVelocityData(FlightgearData *o_flightgearData)
Get own aircraft velocity data.
void addTextMessage(const QString &text)
Add a text message to the on-screen display.
Proxy object connected to a real FGSwiftBus::CTraffic object via DBus.
void remoteAircraftAdded(const QString &callsign)
Remote aircraft successfully added.
void setPlanesTransponders(const swift::simplugin::flightgear::PlanesTransponders &planesTransponders)
Set the transponders of multiple traffic aircrafts.
void setPlanesSurfaces(const swift::simplugin::flightgear::PlanesSurfaces &planesSurfaces)
Set the surfaces of multiple traffic aircrafts.
void cleanup()
Reverse the actions of initialize().
void remoteAircraftAddingFailed(const QString &callsign)
Remote aircraft adding failed.
void addPlane(const QString &callsign, const QString &modelName, const QString &aircraftIcao, const QString &airlineIcao, const QString &livery)
Introduce a new traffic aircraft.
bool isValid() const
Does the remote object exist?
void simFrame()
Simulator frame.
void getRemoteAircraftData(const QStringList &callsigns, const RemoteAircraftDataCallback &setter) const
Get remote aircrafts data (lat, lon, elevation and CG)
void removePlane(const QString &callsign)
Remove a traffic aircraft.
void setPlanesPositions(const swift::simplugin::flightgear::PlanesPositions &planesPositions)
Set the position of multiple traffic aircrafts.
void removeAllPlanes()
Remove all traffic aircraft.
Class representing a Flightgear multiplayer aircraft.
const swift::misc::simulation::CSimulatedAircraft & getAircraft() const
Simulated aircraft (as added)
virtual swift::core::ISimulator * create(const swift::misc::simulation::CSimulatorPluginInfo &info, swift::misc::simulation::IOwnAircraftProvider *ownAircraftProvider, swift::misc::simulation::IRemoteAircraftProvider *remoteAircraftProvider, swift::misc::network::IClientProvider *clientProvider)
Create a new instance of a driver.
virtual swift::misc::CStatusMessageList getInterpolationMessages(const swift::misc::aviation::CCallsign &callsign) const
Interpolation messages for callsign.
virtual bool updateOwnSimulatorSelcal(const swift::misc::aviation::CSelcal &selcal, const swift::misc::CIdentifier &originator)
Update own aircraft cockpit (usually from context)
virtual void displayTextMessage(const swift::misc::network::CTextMessage &message) const
Display a text message.
virtual bool physicallyAddRemoteAircraft(const swift::misc::simulation::CSimulatedAircraft &newRemoteAircraft)
Add new remote aircraft physically to the simulator.
virtual bool updateOwnSimulatorCockpit(const swift::misc::simulation::CSimulatedAircraft &aircraft, const swift::misc::CIdentifier &originator)
Update own aircraft cockpit (usually from context)
virtual int physicallyRemoveAllRemoteAircraft()
Remove all remote aircraft and their data via ISimulator::clearAllRemoteAircraftData.
virtual bool requestElevation(const swift::misc::geo::ICoordinateGeodetic &reference, const swift::misc::aviation::CCallsign &callsign)
Request elevation, there is no guarantee the requested elevation will be available in the provider.
virtual bool physicallyRemoveRemoteAircraft(const swift::misc::aviation::CCallsign &callsign)
Remove remote aircraft from simulator.
virtual bool isConnected() const
Are we connected to the simulator?
CSimulatorFlightgear(const swift::misc::simulation::CSimulatorPluginInfo &info, swift::misc::simulation::IOwnAircraftProvider *ownAircraftProvider, swift::misc::simulation::IRemoteAircraftProvider *remoteAircraftProvider, swift::misc::network::IClientProvider *clientProvider, QObject *parent=nullptr)
Constructor.
virtual swift::misc::aviation::CCallsignSet physicallyRenderedAircraft() const
Physically rendered (displayed in simulator) This shall only return aircraft handled in the simulator...
virtual void resetAircraftStatistics()
Reset the statistics.
virtual ~CSimulatorFlightgear()
Dtor.
virtual void displayStatusMessage(const swift::misc::CStatusMessage &message) const
Display a status message in the simulator.
virtual QString getStatisticsSimulatorSpecific() const
Allows to print out simulator specific statistics.
virtual bool disconnectFrom()
Disconnect from simulator.
virtual bool isPhysicallyRenderedAircraft(const swift::misc::aviation::CCallsign &callsign) const
Is the aircraft rendered (displayed in simulator)? This shall only return true if the aircraft is rea...
virtual bool connectTo()
Connect to simulator.
virtual void clearAllRemoteAircraftData()
Clear all aircraft related data, but do not physically remove the aircraft.
virtual void unload()
Driver will be unloaded.
virtual bool testSendSituationAndParts(const swift::misc::aviation::CCallsign &callsign, const swift::misc::aviation::CAircraftSituation &situation, const swift::misc::aviation::CAircraftParts &parts)
Send situation/parts for testing.
virtual void stopImpl()
Plugin specific implementation to stop listener.
CSimulatorFlightgearListener(const swift::misc::simulation::CSimulatorPluginInfo &info)
Constructor.
virtual void startImpl()
Plugin specific implementation to start listener.
virtual void checkImpl()
Plugin specific implementation to check.
Backend services of the swift project, like dealing with the network or the simulators.
Free functions in swift::misc.
qint64 currentMSecsSinceEpoch()
bool connect(const QString &service, const QString &path, const QString &interface, const QString &name, QObject *receiver, const char *slot)
QDBusConnection connectToPeer(const QString &address, const QString &name)
void disconnectFromBus(const QString &name)
void disconnectFromPeer(const QString &name)
bool isConnected() const const
QString name() const const
QDBusConnection sessionBus()
void addWatchedService(const QString &newService)
void serviceUnregistered(const QString &serviceName)
void setConnection(const QDBusConnection &connection)
void setWatchMode(QDBusServiceWatcher::WatchMode mode)
bool contains(const Key &key) const const
QHash< Key, T >::iterator insert(const Key &key, const T &value)
bool isEmpty() const const
QList< Key > keys() const const
bool remove(const Key &key)
qsizetype size() const const
T value(const Key &key) const const
QList< T > values() const const
QList< T >::const_reference at(qsizetype i) const const
QList< T >::const_iterator constBegin() const const
QList< T >::const_iterator constEnd() const const
bool isEmpty() const const
qsizetype size() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void setObjectName(QAnyStringView name)
QString arg(Args &&... args) const const
bool isEmpty() const const
QString toLower() const const
QString trimmed() const const
void setInterval(int msec)
bool isActive() const const
QString aircraftModelPath
Aircraft model path.
int com2StandbyKhz
COM2 standby [kHz].
double pressureAltitudeFt
Pressure altitude [inhg].
double pitchDeg
Pitch [deg].
QList< double > enginesN1Percentage
N1 per engine [%].
double longitudeDeg
Latitude [deg].
double latitudeDeg
Longitude [deg].
bool xpdrIdent
Is transponder in ident?
int com1StandbyKhz
COM1 standby [kHz].
int com1ActiveKhz
COM1 active [kHz].
double volumeCom1
Volume com1 [0..1].
double rollRateRadPerSec
Roll angular velocity [rad/s].
double groundElevation
Ground Elevation [m].
int xpdrCode
Transpondder code.
double velocityZMs
z velocity [m/s]
double pitchRateRadPerSec
Pitch angular velocity [rad/s].
double groundspeedKts
Ground speed [kts].
bool navLightsOn
NAV lights on?
bool taxiLightsOn
Taxi lights on?
double trueHeadingDeg
True heading [deg].
double gearReployRatio
Gear deployment ratio [%].
int xpdrMode
Transponder mode (off=0,stdby=1-2, >2 on)
bool landingLightsOn
Landing lights on?
bool onGroundAll
All wheels on ground?
double velocityYMs
y velocity [m/s]
QString aircraftIcaoCode
Aircraft ICAO code.
double velocityXMs
x velocity [m/s]
double speedBrakeRatio
Speed break ratio [%].
bool strobeLightsOn
Strobe lights on?
double yawRateRadPerSec
Yaw angular velocity [rad/s].
double volumeCom2
Volume com2 [0..1].
double rollDeg
Roll [deg].
int com2ActiveKhz
COM2 active [kHz].
double flapsReployRatio
Flaps deployment ratio [%].
bool beaconLightsOn
Beacon lights on?
double altitudeFt
Altitude [ft].
void push_back(const swift::misc::aviation::CAircraftSituation &situation)
Push back the latest situation.
void push_back(const swift::misc::aviation::CCallsign &callsign, const swift::misc::aviation::CAircraftParts &parts)
Push back the latest parts.
#define SWIFT_VERIFY_X(COND, WHERE, WHAT)
A weaker kind of assert.