swift
simulatorxplane.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 2013 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #ifndef SWIFT_SIMPLUGIN_SIMULATOR_XPLANE_H
7 #define SWIFT_SIMPLUGIN_SIMULATOR_XPLANE_H
8 
9 #include <QDBusConnection>
10 #include <QHash>
11 #include <QList>
12 #include <QObject>
13 #include <QPair>
14 #include <QString>
15 #include <QStringList>
16 #include <QTimer>
17 
18 #include "xplanempaircraft.h"
19 
23 #include "misc/identifier.h"
24 #include "misc/pixmap.h"
25 #include "misc/pq/time.h"
26 #include "misc/pq/units.h"
27 #include "misc/sequence.h"
28 #include "misc/settingscache.h"
34 #include "misc/statusmessage.h"
37 
39 
40 namespace swift::misc
41 {
42  namespace aviation
43  {
44  class CAircraftParts;
45  class CAircraftSituation;
46  class CCallsign;
47  } // namespace aviation
48  namespace network
49  {
50  class CTextMessage;
51  }
52  namespace simulation
53  {
54  class CSimulatedAircraft;
55  class CSimulatorPluginInfo;
56  class IOwnAircraftProvider;
57  class IRemoteAircraftProvider;
58  } // namespace simulation
59 } // namespace swift::misc
60 
61 namespace swift::simplugin::xplane
62 {
63  class CXSwiftBusServiceProxy;
64  class CXSwiftBusTrafficProxy;
65 
67  struct XPlaneData
68  {
71  double latitudeDeg = 0;
72  double longitudeDeg = 0;
73  double altitudeM = 0;
74  double pressureAltitudeFt = 0;
75  double heightAglM = 0;
76  double groundspeedMs = 0;
77  double pitchDeg = 0;
78  double rollDeg = 0;
79  double trueHeadingDeg = 0;
80  double localXVelocityMs = 0;
81  double localYVelocityMs = 0;
82  double localZVelocityMs = 0;
83  double pitchRadPerSec = 0;
84  double rollRadPerSec = 0;
85  double headingRadPerSec = 0;
86  bool onGroundAll = false;
87  double groundElevation = 0;
88  int com1ActiveKhz = 122800;
89  int com1StandbyKhz = 122800;
90  bool isCom1Receiving = true;
91  bool isCom1Transmitting = true;
92  double com1Volume = 1;
93  int com2ActiveKhz = 122800;
94  int com2StandbyKhz = 122800;
95  bool isCom2Receiving = true;
96  bool isCom2Transmitting = true;
97  double com2Volume = 1;
98  int xpdrCode = 2000;
99  int xpdrMode = 0;
100  bool xpdrIdent = false;
101  bool beaconLightsOn = false;
102  bool landingLightsOn = false;
103  bool navLightsOn = false;
104  bool strobeLightsOn = false;
105  bool taxiLightsOn = false;
106  double flapsDeployRatio = 0;
107  double gearDeployRatio = 0;
109  double speedBrakeRatio = 0;
110  double seaLevelPressureInHg = 0;
111  };
112 
115  {
116  Q_OBJECT
117 
118  public:
122  swift::misc::simulation::IRemoteAircraftProvider *remoteAircraftProvider,
123  swift::misc::network::IClientProvider *clientProvider, QObject *parent = nullptr);
124 
126  ~CSimulatorXPlane() override;
127 
130  bool connectTo() override;
131  bool disconnectFrom() override;
133  const swift::misc::CIdentifier &originator) override;
135  const swift::misc::CIdentifier &originator) override;
136  void displayStatusMessage(const swift::misc::CStatusMessage &message) const override;
137  void displayTextMessage(const swift::misc::network::CTextMessage &message) const override;
138  bool isPhysicallyRenderedAircraft(const swift::misc::aviation::CCallsign &callsign) const override;
140  bool followAircraft(const swift::misc::aviation::CCallsign &callsign) override;
141  void unload() override;
142  QString getStatisticsSimulatorSpecific() const override;
143  void resetAircraftStatistics() override;
145  getInterpolationMessages(const swift::misc::aviation::CCallsign &callsign) const override;
148  const swift::misc::aviation::CAircraftParts &parts) override;
150  const swift::misc::aviation::CCallsign &callsign,
151  bool isWater) override;
152  void setFlightNetworkConnected(bool connected) override;
154 
157  const swift::misc::aviation::CCallsign &callsign) override;
158 
159  protected:
162  bool isConnected() const override;
163  bool physicallyAddRemoteAircraft(const swift::misc::simulation::CSimulatedAircraft &newRemoteAircraft) override;
165  int physicallyRemoveAllRemoteAircraft() override;
166  void clearAllRemoteAircraftData() override;
167  bool isPaused() const override
168  {
170  return false;
171  }
173 
174  private slots:
176  void onDBusServiceUnregistered();
177 
178  private:
180  enum DBusMode
181  {
182  Session,
183  P2P
184  };
185 
186  using QDoubleList = QList<double>;
187  using QBoolList = QList<bool>;
188 
189  void emitOwnAircraftModelChanged(const QString &path, const QString &filename, const QString &livery,
190  const QString &icao, const QString &modelString, const QString &name,
191  const QString &description);
192  void fastTimerTimeout();
193  void slowTimerTimeout();
194 
195  void loadCslPackages();
196  QString findCslPackage(const QString &modelFileName);
197 
200  void updateRemoteAircraft();
201 
204  void requestRemoteAircraftDataFromXPlane();
205  void requestRemoteAircraftDataFromXPlane(const swift::misc::aviation::CCallsignSet &callsigns);
206  void triggerRequestRemoteAircraftDataFromXPlane(const swift::misc::aviation::CCallsignSet &callsigns);
208 
211  void addNextPendingAircraft();
212  void triggerAddNextPendingAircraft();
214 
216  int detectTimeoutAdding();
217 
219  void triggerRemoveAircraft(const swift::misc::aviation::CCallsign &callsign, qint64 deferMs);
220 
222  QPair<qint64, qint64> minMaxTimestampsAddInProgress() const;
223 
225  bool canAddAircraft() const;
226 
229  void onRemoteAircraftAdded(const QString &callsign);
230  void onRemoteAircraftAddingFailed(const QString &callsign);
231  void updateRemoteAircraftFromSimulator(const QStringList &callsigns, const QDoubleList &latitudesDeg,
232  const QDoubleList &longitudesDeg, const QDoubleList &elevationsMeters,
233  const QBoolList &waterFlags, const QDoubleList &verticalOffsetsMeters);
235 
237  void disconnectFromDBus();
238 
241  bool sendXSwiftBusSettings();
242  swift::misc::simulation::settings::CXSwiftBusSettings receiveXSwiftBusSettings(bool &ok);
244 
246  void onXSwiftBusSettingsChanged();
247 
249  void setMinTerrainProbeDistance(const swift::misc::physical_quantities::CLength &distance);
250 
252  bool handleProbeValue(const swift::misc::geo::CElevationPlane &plane,
253  const swift::misc::aviation::CCallsign &callsign, bool waterFlag, const QString &hint,
254  bool ignoreOutsideRange);
255 
256  static bool isSuspiciousTerrainValue(const swift::misc::geo::CElevationPlane &elevation);
257  static const swift::misc::physical_quantities::CLength &maxTerrainRequestDistance();
258 
260  fixSimulatorCg(const swift::misc::physical_quantities::CLength &cg,
262 
263  DBusMode m_dbusMode;
265  this, &CSimulatorXPlane::onXSwiftBusSettingsChanged
266  };
267  static constexpr qint64 TimeoutAdding = 10000;
268  QDBusConnection m_dBusConnection { "default" };
269  QDBusServiceWatcher *m_watcher { nullptr };
270  CXSwiftBusServiceProxy *m_serviceProxy { nullptr };
271  CXSwiftBusTrafficProxy *m_trafficProxy { nullptr };
272  QTimer m_fastTimer;
273  QTimer m_slowTimer;
274  QTimer m_pendingAddedTimer;
275  unsigned int m_fastTimerCalls = 0;
276  unsigned int m_slowTimerCalls = 0;
277 
278  CXPlaneMPAircraftObjects m_xplaneAircraftObjects;
279 
280  swift::misc::simulation::CSimulatedAircraftList m_pendingToBeAddedAircraft;
281  QHash<swift::misc::aviation::CCallsign, qint64> m_addingInProgressAircraft;
283  swift::misc::physical_quantities::CLength m_minSuspicousTerrainProbe {
284  nullptr
285  };
286  XPlaneData m_xplaneData;
288  m_altitudeDelta;
289 
290  // statistics
291  qint64 m_statsAddMaxTimeMs = -1;
292  qint64 m_statsAddCurrentTimeMs = -1;
293 
295  void resetXPlaneData() { m_xplaneData = {}; }
296  };
297 
300  {
301  Q_OBJECT
302 
303  public:
306 
307  protected:
309  void startImpl() override;
310 
312  void stopImpl() override;
313 
315  void checkImpl() override;
316 
317  private:
318  void checkConnection();
319  void checkConnectionViaSessionBus();
320  void checkConnectionViaPeer(const QString &address);
321  void checkConnectionCommon();
322 
323  void serviceRegistered(const QString &serviceName);
324  void onXSwiftBusServerSettingChanged();
325 
326  QTimer m_timer { this };
327  QDBusConnection m_DBusConnection { "default" };
328  QString m_dBusServerAddress;
330  this, &CSimulatorXPlaneListener::onXSwiftBusServerSettingChanged
331  };
332  };
333 
336  {
337  Q_OBJECT
338  Q_PLUGIN_METADATA(IID "org.swift-project.swift_core.simulatorinterface" FILE "simulatorxplane.json")
340 
341  public:
345  swift::misc::simulation::IRemoteAircraftProvider *remoteAircraftProvider,
346  swift::misc::network::IClientProvider *clientProvider) override;
347 
351  {
352  return new CSimulatorXPlaneListener(info);
353  }
354  };
355 } // namespace swift::simplugin::xplane
356 
357 #endif // SWIFT_SIMPLUGIN_SIMULATOR_XPLANE_H
Factory pattern class to create instances of ISimulator.
Definition: simulator.h:691
Interface to a simulator.
Definition: simulator.h:59
Interface to a simulator listener.
Definition: simulator.h:630
Value object encapsulating information identifying a component of a modular distributed swift process...
Definition: identifier.h:29
Streamable status message, e.g.
Status messages, e.g. from Core -> GUI.
Value object encapsulating information of aircraft's parts.
Definition: aircraftparts.h:26
Value object encapsulating information of an aircraft's situation.
Value object encapsulating information of a callsign.
Definition: callsign.h:30
Value object for a set of callsigns.
Definition: callsignset.h:26
Value object for SELCAL.
Definition: selcal.h:31
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.
Value object encapsulating information of a text message.
Definition: textmessage.h:31
Direct in memory access to client (network client) data.
Physical unit length (length)
Definition: length.h:18
Aircraft model (used by another pilot, my models on disk)
Definition: aircraftmodel.h:71
Comprehensive information of an aircraft.
Value object encapsulating a list of aircraft.
Direct threadsafe in memory access to own aircraft.
Direct thread safe in memory access to remote aircraft.
Common base class for simulator plugins.
Factory for creating CSimulatorXPlane instance.
swift::core::ISimulatorListener * createListener(const swift::misc::simulation::CSimulatorPluginInfo &info)
Simulator listener instance.
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.
X-Plane ISimulator implementation.
int physicallyRemoveAllRemoteAircraft()
Remove all remote aircraft and their data via ISimulator::clearAllRemoteAircraftData.
bool followAircraft(const swift::misc::aviation::CCallsign &callsign)
Follow aircraft.
bool isConnected() const
Are we connected to the simulator?
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.
CSimulatorXPlane(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.
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.
void resetAircraftStatistics()
Reset the statistics.
bool updateOwnSimulatorSelcal(const swift::misc::aviation::CSelcal &selcal, const swift::misc::CIdentifier &originator)
Update own aircraft cockpit (usually from context)
void clearAllRemoteAircraftData()
Clear all aircraft related data, but do not physically remove the aircraft.
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...
void unload()
Driver will be unloaded.
bool updateOwnSimulatorCockpit(const swift::misc::simulation::CSimulatedAircraft &aircraft, const swift::misc::CIdentifier &originator)
Update own aircraft cockpit (usually from context)
swift::misc::aviation::CCallsignSet physicallyRenderedAircraft() const
Physically rendered (displayed in simulator) This shall only return aircraft handled in the simulator...
swift::misc::CStatusMessageList getInterpolationMessages(const swift::misc::aviation::CCallsign &callsign) const
Interpolation messages for callsign.
void setFlightNetworkConnected(bool connected)
Flight network has been connected.
bool physicallyAddRemoteAircraft(const swift::misc::simulation::CSimulatedAircraft &newRemoteAircraft)
Add new remote aircraft physically to the simulator.
bool physicallyRemoveRemoteAircraft(const swift::misc::aviation::CCallsign &callsign)
Remove remote aircraft from simulator.
QString getStatisticsSimulatorSpecific() const
Allows to print out simulator specific statistics.
void callbackReceivedRequestedElevation(const swift::misc::geo::CElevationPlane &plane, const swift::misc::aviation::CCallsign &callsign, bool isWater)
A requested elevation has been received.
void displayStatusMessage(const swift::misc::CStatusMessage &message) const
Display a status message in the simulator.
bool disconnectFrom()
Disconnect from simulator.
void displayTextMessage(const swift::misc::network::CTextMessage &message) const
Display a text message.
bool isPaused() const
Simulator paused?
Listener waits for xswiftbus service to show up.
CSimulatorXPlaneListener(const swift::misc::simulation::CSimulatorPluginInfo &info)
Constructor.
void checkImpl()
Plugin specific implementation to check.
void startImpl()
Plugin specific implementation to start listener.
void stopImpl()
Plugin specific implementation to stop listener.
Free functions in swift::misc.
Q_INTERFACES(...)
Q_OBJECTQ_OBJECT
QObject * parent() const const
int com2StandbyKhz
COM2 standby [kHz].
double headingRadPerSec
Heading angular velocity [rad/s].
double groundspeedMs
Ground speed [m/s].
double com2Volume
COM2 volume 0..1.
double groundElevation
Elevation of ground [m].
double com1Volume
COM1 volume 0..1.
double localXVelocityMs
Local x velocity [m/s].
int xpdrMode
Transponder mode (off=0,stdby=1,on=2,test=3)
bool isCom1Transmitting
COM1 transmittings.
QString aircraftModelPath
Aircraft model path.
double flapsDeployRatio
Flaps deployment ratio [%].
double localZVelocityMs
Local z velocity [m/s].
bool isCom2Transmitting
COM2 transmittings.
double rollRadPerSec
Roll angular velocity [rad/s].
double gearDeployRatio
Gear deployment ratio [%].
double trueHeadingDeg
True heading [deg].
bool xpdrIdent
Is transponder in ident?
QString aircraftIcaoCode
Aircraft ICAO code.
bool onGroundAll
All wheels on ground?
double latitudeDeg
Longitude [deg].
double pitchRadPerSec
Pitch angular velocity [rad/s].
QList< double > enginesN1Percentage
N1 per engine [%].
double speedBrakeRatio
Speed break ratio [%].
double seaLevelPressureInHg
Sea level pressure [inhg].
int com1StandbyKhz
COM1 standby [kHz].
double pressureAltitudeFt
Pressure altitude [ft, XP12].
bool landingLightsOn
Landing lights on?
double localYVelocityMs
Local y velocity [m/s].