swift
aircraftsituation.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_MISC_AVIATION_AIRCRAFTSITUATION_H
7 #define SWIFT_MISC_AVIATION_AIRCRAFTSITUATION_H
8 
9 #include <array>
10 
11 #include <QMetaType>
12 #include <QString>
13 #include <QVector3D>
14 
16 #include "misc/aviation/altitude.h"
17 #include "misc/aviation/callsign.h"
18 #include "misc/aviation/heading.h"
22 #include "misc/geo/latitude.h"
23 #include "misc/geo/longitude.h"
24 #include "misc/math/mathutils.h"
25 #include "misc/metaclass.h"
26 #include "misc/pq/angle.h"
27 #include "misc/pq/length.h"
28 #include "misc/pq/speed.h"
29 #include "misc/pq/time.h"
30 #include "misc/propertyindexref.h"
31 #include "misc/swiftmiscexport.h"
32 #include "misc/timestampbased.h"
33 #include "misc/valueobject.h"
34 
35 SWIFT_DECLARE_VALUEOBJECT_MIXINS(swift::misc::aviation, CAircraftSituation)
36 
37 namespace swift::misc
38 {
39  namespace geo
40  {
41  class CElevationPlane;
42  }
43  namespace aviation
44  {
45  class CAircraftParts;
46  class CAircraftPartsList;
47  class CAircraftLights;
48 
51  public CValueObject<CAircraftSituation>,
54  {
55  public:
58  {
59  IndexPosition = CPropertyIndexRef::GlobalIndexCAircraftSituation,
60  IndexLatitude,
61  IndexLongitude,
62  IndexAltitude,
63  IndexHeading,
64  IndexBank,
65  IndexIsOnGroundInfo,
66  IndexPitch,
67  IndexPBHInfo,
68  IndexVelocity,
69  IndexGroundSpeed,
70  IndexGroundElevationPlane,
71  IndexGroundElevationInfo,
72  IndexGroundElevationInfoTransferred,
73  IndexGroundElevationInfoString,
74  IndexGroundElevationPlusInfo,
75  IndexCallsign,
76  IndexCG,
77  IndexCanLikelySkipNearGroundInterpolation
78  };
79 
82  {
83  NoCorrection,
86  AGL,
88  UnknownCorrection
89  };
90 
93  {
94  // best info (most accurate) last
95  NoElevationInfo,
96  Test,
99  Average,
103  FromProvider
104  };
105 
107  CAircraftSituation() = default;
108 
110  CAircraftSituation(const CCallsign &correspondingCallsign);
111 
113  CAircraftSituation(const geo::CCoordinateGeodetic &position, const CHeading &heading = {},
114  const physical_quantities::CAngle &pitch = {},
115  const physical_quantities::CAngle &bank = {}, const physical_quantities::CSpeed &gs = {},
116  const geo::CElevationPlane &groundElevation = {});
117 
119  CAircraftSituation(const CCallsign &correspondingCallsign, const geo::CCoordinateGeodetic &position,
120  const CHeading &heading = {}, const physical_quantities::CAngle &pitch = {},
121  const physical_quantities::CAngle &bank = {}, const physical_quantities::CSpeed &gs = {},
122  const geo::CElevationPlane &groundElevation = {});
123 
125  QString convertToQString(bool i18n = false) const;
126 
128  QVariant propertyByIndex(CPropertyIndexRef index) const;
129 
131  void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant);
132 
134  int comparePropertyByIndex(CPropertyIndexRef index, const CAircraftSituation &compareValue) const;
135 
137  const geo::CCoordinateGeodetic &getPosition() const { return m_position; }
138 
140  bool isPositionNull() const { return m_position.isNull(); }
141 
143  bool isPositionOrAltitudeNull() const { return this->isPositionNull() || this->getAltitude().isNull(); }
144 
146  bool isNull() const override;
147 
149  bool isOtherElevationInfoBetter(GndElevationInfo otherInfo, bool transferred) const;
150 
153  bool equalPbh(const CAircraftSituation &other) const;
154 
157  bool equalPbhAndVector(const CAircraftSituation &other) const;
158 
161  bool equalPbhVectorAltitude(const CAircraftSituation &other) const;
162 
165  bool equalPbhVectorAltitudeElevation(const CAircraftSituation &other) const;
166 
168  void setNull();
169 
171  void setPosition(const geo::CCoordinateGeodetic &position) { m_position = position; }
172 
174  geo::CLatitude latitude() const override { return m_position.latitude(); }
175 
177  geo::CLongitude longitude() const override { return m_position.longitude(); }
178 
180  bool isOnGround() const { return m_onGroundInfo.getOnGround() == COnGroundInfo::OnGround; }
181 
183  bool isOnGroundFromParts() const;
184 
186  bool isOnGroundFromNetwork() const;
187 
189  bool isOnGroundInfoAvailable() const;
190 
192  bool shouldGuessOnGround() const;
193 
195  physical_quantities::CLength getGroundDistance(const physical_quantities::CLength &centerOfGravity) const;
196 
198  bool hasGroundDetailsForGndInterpolation() const;
199 
201  void setOnGroundDetails(COnGroundInfo::OnGroundDetails details);
202 
204  aviation::COnGroundInfo getOnGroundInfo() const;
205 
207  void setOnGroundInfo(const aviation::COnGroundInfo &info);
208 
210  const CAltitude &geodeticHeight() const override { return m_position.geodeticHeight(); }
211 
213  QVector3D normalVector() const override { return m_position.normalVector(); }
214 
216  std::array<double, 3> normalVectorDouble() const override { return m_position.normalVectorDouble(); }
217 
219  const CAltitude &getGroundElevation() const { return m_groundElevationPlane.getAltitude(); }
220 
222  const geo::CElevationPlane &getGroundElevationPlane() const { return m_groundElevationPlane; }
223 
225  GndElevationInfo getGroundElevationInfo() const;
226 
228  QString getGroundElevationInfoAsString() const;
229 
231  QString getGroundElevationAndInfo() const;
232 
234  bool isGroundElevationInfoTransferred() const { return m_isElvInfoTransferred; }
235 
237  void setGroundElevationInfo(GndElevationInfo details) { m_elvInfo = static_cast<int>(details); }
238 
240  bool canTransferGroundElevation(
241  const CAircraftSituation &transferToSituation,
243 
248  bool transferGroundElevationFromMe(
249  CAircraftSituation &transferToSituation,
251 
253  bool transferGroundElevationToMe(const CAircraftSituation &fromSituation,
254  const physical_quantities::CLength &radius, bool transferred);
255 
257  bool transferGroundElevationToMe(const CAircraftSituation &fromSituation, bool transferred);
258 
263  bool interpolateElevation(const aviation::CAircraftSituation &oldSituation,
264  const aviation::CAircraftSituation &newSituation);
265 
267  bool hasGroundElevation() const;
268 
270  bool hasInboundGroundDetails() const;
271 
273  bool setGroundElevation(const aviation::CAltitude &altitude, GndElevationInfo info,
274  bool transferred = false);
275 
277  bool setGroundElevation(const geo::CElevationPlane &elevationPlane, GndElevationInfo info,
278  bool transferred = false);
279 
282  bool setGroundElevationChecked(const geo::CElevationPlane &elevationPlane, GndElevationInfo info,
283  bool transferred = false);
284 
286  void resetGroundElevation();
287 
289  physical_quantities::CLength getHeightAboveGround() const;
290 
292  const CHeading &getHeading() const { return m_heading; }
293 
295  void setHeading(const CHeading &heading);
296 
298  const CAltitude &getAltitude() const { return m_position.geodeticHeight(); }
299 
301  physical_quantities::CLengthUnit getAltitudeUnit() const { return m_position.geodeticHeight().getUnit(); }
302 
304  physical_quantities::CLengthUnit getAltitudeOrDefaultUnit() const;
305 
309  CAltitude getCorrectedAltitude(bool enableDragToGround = true,
310  AltitudeCorrection *correction = nullptr) const;
311  CAltitude getCorrectedAltitude(const physical_quantities::CLength &centerOfGravity,
312  bool enableDragToGround = true,
313  AltitudeCorrection *correction = nullptr) const;
315 
318  AltitudeCorrection correctAltitude(bool enableDragToGround = true);
319  AltitudeCorrection
320  correctAltitude(const physical_quantities::CLength &centerOfGravity = physical_quantities::CLength::null(),
321  bool enableDragToGround = true);
323 
325  void setAltitude(const CAltitude &altitude);
326 
328  CAltitude addAltitudeOffset(const physical_quantities::CLength &offset);
329 
331  CAircraftSituation withAltitudeOffset(const physical_quantities::CLength &offset) const;
332 
334  const CAltitude &getPressureAltitude() const { return m_pressureAltitude; }
335 
337  void setPressureAltitude(const CAltitude &altitude);
338 
340  const physical_quantities::CAngle &getPitch() const { return m_pitch; }
341 
343  void setPitch(const physical_quantities::CAngle &pitch);
344 
346  const physical_quantities::CAngle &getBank() const { return m_bank; }
347 
349  void setBank(const physical_quantities::CAngle &bank);
350 
352  void setZeroPBH();
353 
355  void setZeroPBHandGs();
356 
358  QString getPBHInfo() const;
359 
361  void setVelocity(const CAircraftVelocity &velocity)
362  {
363  m_velocity = velocity;
364  m_hasVelocity = true;
365  }
366 
368  const CAircraftVelocity &getVelocity() const { return m_velocity; }
369 
371  bool hasVelocity() const { return m_hasVelocity; }
372 
374  const physical_quantities::CSpeed &getGroundSpeed() const { return m_groundSpeed; }
375 
377  void setGroundSpeed(const physical_quantities::CSpeed &groundspeed) { m_groundSpeed = groundspeed; }
378 
380  bool isMoving() const;
381 
383  bool canLikelySkipNearGroundInterpolation() const;
384 
387  getDistancePerTime(std::chrono::milliseconds,
389 
391  physical_quantities::CLength getDistancePerTime250ms(
393 
395  const CCallsign &getCallsign() const { return m_correspondingCallsign; }
396 
398  bool hasCallsign() const { return !this->getCallsign().isEmpty(); }
399 
401  void setCallsign(const CCallsign &callsign);
402 
404  const physical_quantities::CLength &getCG() const { return m_cg; }
405 
407  void setCG(const physical_quantities::CLength &cg);
408 
410  bool hasCG() const { return !m_cg.isNull(); }
411 
413  void setInterimFlag(bool flag) { m_isInterim = flag; }
414 
420  bool adjustGroundFlag(const CAircraftParts &parts, bool alwaysSetDetails, double timeDeviationFactor = 0.1,
421  qint64 *differenceMs = nullptr);
422 
428  bool adjustGroundFlag(const CAircraftPartsList &partsList, bool alwaysSetDetails,
429  double timeDeviationFactor = 0.1, qint64 *differenceMs = nullptr);
430 
432  bool isInterim() const { return m_isInterim; }
433 
435  static const QString &altitudeCorrectionToString(AltitudeCorrection correction);
436 
438  static bool isCorrectedAltitude(AltitudeCorrection correction);
439 
441  static const QString &gndElevationInfoToString(GndElevationInfo details);
442 
444  static const physical_quantities::CLength &deltaNearGround();
445 
447  static const CAircraftSituation &null();
448 
450  static const physical_quantities::CLength &defaultCG();
451 
454 
456  static bool isGfEqualOnGround(double oldGroundFactor, double newGroundFactor)
457  {
458  using namespace swift::misc::math;
459  return CMathUtils::epsilonEqualLimits(1.0, oldGroundFactor) &&
460  CMathUtils::epsilonEqualLimits(1.0, newGroundFactor);
461  }
462 
464  static bool isGfEqualAirborne(double oldGroundFactor, double newGroundFactor)
465  {
466  using namespace swift::misc::math;
467  return CMathUtils::epsilonEqualLimits(0.0, oldGroundFactor) &&
468  CMathUtils::epsilonEqualLimits(0.0, newGroundFactor);
469  }
470 
472  static bool isGfStarting(double oldGroundFactor, double newGroundFactor)
473  {
474  using namespace swift::misc::math;
475  return CMathUtils::epsilonEqualLimits(0.0, oldGroundFactor) &&
476  CMathUtils::epsilonEqualLimits(1.0, newGroundFactor);
477  }
478 
480  static bool isGfLanding(double oldGroundFactor, double newGroundFactor)
481  {
482  using namespace swift::misc::math;
483  return CMathUtils::epsilonEqualLimits(1.0, oldGroundFactor) &&
484  CMathUtils::epsilonEqualLimits(0.0, newGroundFactor);
485  }
487 
490  static geo::CElevationPlane
491  interpolatedElevation(const CAircraftSituation &situation, const CAircraftSituation &oldSituation,
492  const CAircraftSituation &newSituation,
494 
496  static constexpr double MaxDeltaElevationFt = 25.0;
497 
499  static const physical_quantities::CLength &allowedAltitudeDeviation();
500 
502  CAircraftLights guessLights() const;
503 
505  static void registerMetadata();
506 
507  private:
508  CCallsign m_correspondingCallsign;
509  geo::CCoordinateGeodetic m_position;
510  geo::CElevationPlane m_groundElevationPlane;
511  aviation::CAltitude m_pressureAltitude { 0, nullptr };
512  CHeading m_heading { 0, nullptr };
513  physical_quantities::CAngle m_pitch { 0, nullptr };
514  physical_quantities::CAngle m_bank { 0, nullptr };
515  physical_quantities::CSpeed m_groundSpeed { 0, nullptr };
516  physical_quantities::CLength m_cg { 0, nullptr };
517  bool m_hasVelocity = false;
518  CAircraftVelocity m_velocity;
519  bool m_isInterim = false;
520  bool m_isElvInfoTransferred = false;
521  int m_elvInfo = static_cast<int>(CAircraftSituation::NoElevationInfo);
522  aviation::COnGroundInfo m_onGroundInfo;
523 
525  CAircraftSituation,
526  SWIFT_METAMEMBER(correspondingCallsign),
527  SWIFT_METAMEMBER(position),
528  SWIFT_METAMEMBER(pressureAltitude),
529  SWIFT_METAMEMBER(heading),
530  SWIFT_METAMEMBER(pitch),
531  SWIFT_METAMEMBER(bank),
532  SWIFT_METAMEMBER(groundSpeed),
533  SWIFT_METAMEMBER(cg),
534  SWIFT_METAMEMBER(hasVelocity),
535  SWIFT_METAMEMBER(velocity),
536  SWIFT_METAMEMBER(groundElevationPlane),
537  SWIFT_METAMEMBER(onGroundInfo),
538  SWIFT_METAMEMBER(elvInfo),
539  SWIFT_METAMEMBER(isElvInfoTransferred),
540  SWIFT_METAMEMBER(timestampMSecsSinceEpoch),
541  SWIFT_METAMEMBER(timeOffsetMs),
542  SWIFT_METAMEMBER(isInterim));
543  };
544  } // namespace aviation
545 } // namespace swift::misc
546 
550 
551 #endif // SWIFT_MISC_AVIATION_AIRCRAFTSITUATION_H
Mix of the most commonly used mixin classes.
Definition: valueobject.h:114
Value object encapsulating information about aircraft's lights.
Value object encapsulating information of aircraft's parts.
Definition: aircraftparts.h:26
Value object encapsulating a list of aircraft parts.
Value object encapsulating information of an aircraft's situation.
const CAltitude & getGroundElevation() const
Elevation of the ground directly beneath.
static bool isGfLanding(double oldGroundFactor, double newGroundFactor)
Aircraft is landing.
void setGroundSpeed(const physical_quantities::CSpeed &groundspeed)
Set ground speed.
bool hasCallsign() const
Has corresponding callsign.
const CHeading & getHeading() const
Get heading.
std::array< double, 3 > normalVectorDouble() const
Normal vector with double precision.
CAircraftSituation()=default
Default constructor.
static bool isGfStarting(double oldGroundFactor, double newGroundFactor)
Aircraft is starting.
bool isPositionOrAltitudeNull() const
Position or altitude null?
const CAltitude & geodeticHeight() const
Height, ellipsoidal or geodetic height (used in GPS)
geo::CLongitude longitude() const
Longitude.
static bool isGfEqualAirborne(double oldGroundFactor, double newGroundFactor)
Both not on ground.
AltitudeCorrection
How was altitude corrected?
@ NoElevation
no correction as there is no elevation
@ DraggedToGround
other scenery too high, but on ground
physical_quantities::CLengthUnit getAltitudeUnit() const
Get altitude unit.
GndElevationInfo
Where did we get elevation from?
@ SituationChange
from swift::misc::aviation::CAircraftSituationChange
@ Interpolated
interpolated between 2 elevations
geo::CLatitude latitude() const
Latitude.
void setInterimFlag(bool flag)
Set flag indicating this is an interim position update.
bool hasVelocity() const
Is velocity non-zero?
void setGroundElevationInfo(GndElevationInfo details)
How we did get gnd.elevation.
const CCallsign & getCallsign() const
Corresponding callsign.
const physical_quantities::CSpeed & getGroundSpeed() const
Get ground speed.
const CAltitude & getAltitude() const
Get altitude.
const CAircraftVelocity & getVelocity() const
Get 6DOF velocity.
const CAltitude & getPressureAltitude() const
Get pressure altitude.
const physical_quantities::CAngle & getBank() const
Get bank (angle)
bool isGroundElevationInfoTransferred() const
Is the elv.info transferred?
QVector3D normalVector() const
Normal vector.
const physical_quantities::CAngle & getPitch() const
Get pitch.
void setVelocity(const CAircraftVelocity &velocity)
Set 6DOF velocity.
const physical_quantities::CLength & getCG() const
Get CG if any.
const geo::CCoordinateGeodetic & getPosition() const
Get position.
const geo::CElevationPlane & getGroundElevationPlane() const
Elevation of the ground directly beneath.
bool isInterim() const
Get flag indicating this is an interim position update.
static bool isGfEqualOnGround(double oldGroundFactor, double newGroundFactor)
Both on ground.
void setPosition(const geo::CCoordinateGeodetic &position)
Set position.
Velocity and angular velocity for 6DOF bodies.
Altitude as used in aviation, can be AGL or MSL altitude.
Definition: altitude.h:52
Value object encapsulating information of a callsign.
Definition: callsign.h:30
Heading as used in aviation, can be true or magnetic heading.
Definition: heading.h:41
Information about the ground status.
Definition: ongroundinfo.h:19
OnGroundDetails
Reliability of on ground information.
Definition: ongroundinfo.h:31
Plane of same elevation, can be a single point or larger area (e.g. airport)
static const physical_quantities::CLength & singlePointRadius()
Radius for single point.
Geodetic coordinate, a position in 3D space relative to the reference geoid.
Physical unit angle (radians, degrees)
Definition: angle.h:23
Physical unit length (length)
Definition: length.h:18
Specialized class for distance units (meter, foot, nautical miles).
Definition: units.h:95
#define SWIFT_METAMEMBER(MEMBER,...)
Macro to define an element within a metaclass.
Definition: metaclass.h:72
#define SWIFT_METACLASS(CLASS,...)
Macro to define a nested metaclass that describes the attributes of its enclosing class.
Definition: metaclass.h:52
Free functions in swift::misc.
void registerMetadata()
Register all relevant metadata in Misc.
#define SWIFT_MISC_EXPORT
Export a class or function from the library.
#define SWIFT_DECLARE_VALUEOBJECT_MIXINS(Namespace, Class)
Explicit template declaration of mixins for a CValueObject subclass to be placed near the top of the ...
Definition: valueobject.h:65