swift
interpolatorlinearpbh.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2018 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #include "config/buildconfig.h"
8 #include "misc/verify.h"
9 
10 using namespace swift::config;
11 using namespace swift::misc::aviation;
12 using namespace swift::misc::physical_quantities;
13 
14 namespace swift::misc::simulation
15 {
16  CInterpolatorLinearPbh::CInterpolatorLinearPbh(double simulationTimeFraction,
17  const aviation::CAircraftSituation &start,
19  : m_simulationTimeFraction(simulationTimeFraction), m_startSituation(start), m_endSituation(end)
20  {
21  if (CBuildConfig::isLocalDeveloperDebugBuild())
22  {
23  SWIFT_VERIFY_X(isValidTimeFraction(m_simulationTimeFraction), Q_FUNC_INFO,
24  "Time fraction needs to be within [0;1]");
25  }
26  }
27 
28  CAngle CInterpolatorLinearPbh::interpolateAngle(const CAngle &begin, const CAngle &end, double timeFraction0to1)
29  {
30  // determine the right direction (to left, to right) we interpolate towards to
31  // -30 -> 30 => 60 (via 0)
32  // 30 -> -30 => -60 (via 0)
33  // 170 -> -170 => -340 (via 180)
34  // -170 -> 170 => 340 (via 180)
35  double deltaDeg = (end - begin).value(CAngleUnit::deg());
36  if (deltaDeg > 180.0) { deltaDeg -= 360; }
37  else if (deltaDeg < -180.0) { deltaDeg += 360; }
38 
39  if (CBuildConfig::isLocalDeveloperDebugBuild())
40  {
41  SWIFT_VERIFY_X(isAcceptableTimeFraction(timeFraction0to1), Q_FUNC_INFO, "0..1 fraction needed");
42  }
43 
45  if (timeFraction0to1 >= 1.0) { return begin + CAngle(deltaDeg, CAngleUnit::deg()); }
46  if (timeFraction0to1 <= 0.0) { return begin; }
47  return begin + CAngle(timeFraction0to1 * deltaDeg, CAngleUnit::deg());
48  }
49 
51  {
52  // HINT: VTOL aircraft can change pitch/bank without changing position, planes cannot
53  // Interpolate heading: HDG = (HdgB - HdgA) * t + HdgA
54  const CHeading headingStart = m_startSituation.getHeading();
55  const CHeading headingEnd = m_endSituation.getHeading();
56 
57  if (CBuildConfig::isLocalDeveloperDebugBuild())
58  {
59  SWIFT_VERIFY_X(headingStart.getReferenceNorth() == headingEnd.getReferenceNorth(), Q_FUNC_INFO,
60  "Need same reference");
61  }
62  return CHeading(interpolateAngle(headingStart, headingEnd, m_simulationTimeFraction),
63  headingEnd.getReferenceNorth());
64  }
65 
67  {
68  // Interpolate Pitch: Pitch = (PitchB - PitchA) * t + PitchA
69  return interpolateAngle(m_startSituation.getPitch(), m_endSituation.getPitch(), m_simulationTimeFraction);
70  }
71 
73  {
74  // Interpolate bank: Bank = (BankB - BankA) * t + BankA
75  return interpolateAngle(m_startSituation.getBank(), m_endSituation.getBank(), m_simulationTimeFraction);
76  }
77 
79  {
80  return (m_endSituation.getGroundSpeed() - m_startSituation.getGroundSpeed()) * m_simulationTimeFraction +
81  m_startSituation.getGroundSpeed();
82  }
83 
85  {
86  if (CBuildConfig::isLocalDeveloperDebugBuild())
87  {
88  SWIFT_VERIFY_X(isValidTimeFraction(tf), Q_FUNC_INFO, "Time fraction needs to be 0-1");
89  }
90  m_simulationTimeFraction = clampValidTimeFraction(tf);
91  }
92 } // namespace swift::misc::simulation
Value object encapsulating information of an aircraft's situation.
const CHeading & getHeading() const
Get heading.
const physical_quantities::CSpeed & getGroundSpeed() const
Get ground speed.
const physical_quantities::CAngle & getBank() const
Get bank (angle)
const physical_quantities::CAngle & getPitch() const
Get pitch.
Heading as used in aviation, can be true or magnetic heading.
Definition: heading.h:41
ReferenceNorth getReferenceNorth() const
Get reference north (magnetic or true)
Definition: heading.h:84
Physical unit angle (radians, degrees)
Definition: angle.h:23
physical_quantities::CAngle getBank() const
Getter.
physical_quantities::CSpeed getGroundSpeed() const
Getter.
physical_quantities::CAngle getPitch() const
Getter.
void setTimeFraction(double tf)
Change time fraction.
bool isValidTimeFraction(double timeFraction)
Valid time fraction [0,1].
double clampValidTimeFraction(double timeFraction)
Clamp time fraction [0,1].
T::const_iterator begin(const LockFreeReader< T > &reader)
Non-member begin() and end() for so LockFree containers can be used in ranged for loops.
Definition: lockfree.h:332
T::const_iterator end(const LockFreeReader< T > &reader)
Non-member begin() and end() for so LockFree containers can be used in ranged for loops.
Definition: lockfree.h:338
#define SWIFT_VERIFY_X(COND, WHERE, WHAT)
A weaker kind of assert.
Definition: verify.h:26