swift
testinterpolatorlinearpbh.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
7 
8 #include <QTest>
9 
10 #include "test.h"
11 
13 #include "misc/aviation/heading.h"
14 #include "misc/math/mathutils.h"
16 
17 using namespace swift::misc;
18 using namespace swift::misc::aviation;
19 using namespace swift::misc::geo;
20 using namespace swift::misc::physical_quantities;
21 using namespace swift::misc::math;
22 using namespace swift::misc::simulation;
23 
24 namespace MiscTest
25 {
28  class CTestInterpolatorLinearPbh : public QObject
29  {
30  Q_OBJECT
31 
32  private slots:
34  static void pbhInterpolatorTestHeading0To120();
35 
37  static void pbhInterpolatorTestHeadingM90To30();
38 
40  static void pbhInterpolatorTestHeadingM90To170();
41 
43  static void pbhInterpolatorTestBank270To30();
44 
46  static void pbhInterpolatorTestBank170To190();
47 
49  static void pbhInterpolatorTestPitch30ToM30();
50 
52  static void pbhInterpolatorTestPitchM30To30();
53 
54  private:
55  static constexpr const int m_steps = 10;
56  static constexpr const double m_tfStep = 1.0 / m_steps;
57  };
58 
59  void CTestInterpolatorLinearPbh::pbhInterpolatorTestHeading0To120()
60  {
61  CAircraftSituation s1({}, CHeading(0, CHeading::True, CAngleUnit::deg()));
62  CAircraftSituation s2({}, CHeading(120, CHeading::True, CAngleUnit::deg()));
63  CInterpolatorLinearPbh pbh(s1, s2);
64 
65  double lastDeg = 0;
66 
67  for (int i = 0; i <= m_steps; i++)
68  {
69  pbh.setTimeFraction(m_tfStep * i);
70  const double h = pbh.getHeading().value(CAngleUnit::deg());
71 
72  if (i == 0) { QVERIFY2(CMathUtils::epsilonEqualLimits(h, 0.0), "Expect initial heading"); }
73  else if (i == m_steps) { QVERIFY2(CMathUtils::epsilonEqualLimits(h, 120.0), "Expect final heading"); }
74  else { QVERIFY2(h > lastDeg, "Expect increasing heading"); }
75  lastDeg = h;
76  }
77  }
78 
79  void CTestInterpolatorLinearPbh::pbhInterpolatorTestHeadingM90To30()
80  {
81  CAircraftSituation s1({}, CHeading(270, CHeading::True, CAngleUnit::deg())); // -90
82  CAircraftSituation s2({}, CHeading(30, CHeading::True, CAngleUnit::deg()));
83  CInterpolatorLinearPbh pbh(s1, s2);
84 
85  double lastDeg = 0;
86 
87  for (int i = 0; i <= m_steps; i++)
88  {
89  pbh.setTimeFraction(m_tfStep * i);
90  const double h = pbh.getHeading().value(CAngleUnit::deg());
91 
92  if (i == 0) { QVERIFY2(CMathUtils::epsilonEqualLimits(h, -90.0), "Expect initial heading"); }
93  else if (i == m_steps) { QVERIFY2(CMathUtils::epsilonEqualLimits(h, 30.0), "Expect final heading"); }
94  else { QVERIFY2(h > lastDeg, "Expect increasing heading"); }
95  lastDeg = h;
96  }
97  }
98 
99  void CTestInterpolatorLinearPbh::pbhInterpolatorTestHeadingM90To170()
100  {
101  CAircraftSituation s1({}, CHeading(270, CHeading::True, CAngleUnit::deg())); // -90
102  CAircraftSituation s2({}, CHeading(170, CHeading::True, CAngleUnit::deg()));
103  CInterpolatorLinearPbh pbh(s1, s2);
104 
105  double lastDeg = 0;
106 
107  for (int i = 0; i <= m_steps; i++)
108  {
109  pbh.setTimeFraction(m_tfStep * i);
110  const double h = CAngle::normalizeDegrees360(pbh.getHeading().value(CAngleUnit::deg()));
111 
112  if (i == 0) { QVERIFY2(CMathUtils::epsilonEqualLimits(h, 270.0), "Expect initial heading"); }
113  else if (i == m_steps) { QVERIFY2(CMathUtils::epsilonEqualLimits(h, 170.0), "Expect final heading"); }
114  else { QVERIFY2(h < lastDeg, "Expect decreasing heading"); }
115  lastDeg = h;
116  }
117  }
118 
119  void CTestInterpolatorLinearPbh::pbhInterpolatorTestBank270To30()
120  {
121  CAircraftSituation s1({}, CHeading {}, {}, CAngle(270, CAngleUnit::deg()));
122  CAircraftSituation s2({}, CHeading {}, {}, CAngle(30, CAngleUnit::deg()));
123  CInterpolatorLinearPbh pbh(s1, s2);
124 
125  double lastDeg = 0;
126 
127  for (int i = 0; i <= m_steps; i++)
128  {
129  pbh.setTimeFraction(m_tfStep * i);
130  const double b = pbh.getBank().value(CAngleUnit::deg());
131 
132  if (i == 0)
133  {
134  QVERIFY2(CMathUtils::epsilonEqualLimits(b, -90.0), "Expect initial bank"); // -90 as not normalized
135  }
136  else if (i == m_steps) { QVERIFY2(CMathUtils::epsilonEqualLimits(b, 30.0), "Expect final bank"); }
137  else { QVERIFY2(b > lastDeg, "Expect increasing bank"); }
138  lastDeg = b;
139  }
140  }
141 
142  void CTestInterpolatorLinearPbh::pbhInterpolatorTestBank170To190()
143  {
144  CAircraftSituation s1({}, CHeading {}, {}, CAngle(170, CAngleUnit::deg()));
145  CAircraftSituation s2({}, CHeading {}, {}, CAngle(190, CAngleUnit::deg()));
146  CInterpolatorLinearPbh pbh(s1, s2);
147 
148  double lastDeg = 0;
149 
150  for (int i = 0; i <= m_steps; i++)
151  {
152  pbh.setTimeFraction(m_tfStep * i);
153  const double b = CAngle::normalizeDegrees360(pbh.getBank().value(CAngleUnit::deg()));
154 
155  if (i == 0) { QVERIFY2(CMathUtils::epsilonEqualLimits(b, 170.0), "Expect initial bank"); }
156  else if (i == m_steps) { QVERIFY2(CMathUtils::epsilonEqualLimits(b, 190.0), "Expect final bank"); }
157  else { QVERIFY2(b > lastDeg, "Expect increasing bank"); }
158  lastDeg = b;
159  }
160  }
161 
162  void CTestInterpolatorLinearPbh::pbhInterpolatorTestPitch30ToM30()
163  {
164  CAircraftSituation s1({}, {}, CAngle(30, CAngleUnit::deg()));
165  CAircraftSituation s2({}, {}, CAngle(-30, CAngleUnit::deg()));
166  CInterpolatorLinearPbh pbh(s1, s2);
167 
168  double lastDeg = 0;
169 
170  for (int i = 0; i <= m_steps; i++)
171  {
172  pbh.setTimeFraction(m_tfStep * i);
173  const double p = pbh.getPitch().value(CAngleUnit::deg());
174 
175  if (i == 0) { QVERIFY2(CMathUtils::epsilonEqualLimits(p, 30.0), "Expect initial pitch"); }
176  else if (i == m_steps) { QVERIFY2(CMathUtils::epsilonEqualLimits(p, -30.0), "Expect final pitch"); }
177  else { QVERIFY2(p < lastDeg, "Expect decreasing pitch"); }
178  lastDeg = p;
179  }
180  }
181 
182  void CTestInterpolatorLinearPbh::pbhInterpolatorTestPitchM30To30()
183  {
184  CAircraftSituation s1({}, {}, CAngle(-30, CAngleUnit::deg()));
185  CAircraftSituation s2({}, {}, CAngle(30, CAngleUnit::deg()));
186  CInterpolatorLinearPbh pbh(s1, s2);
187 
188  double lastDeg = 0;
189 
190  for (int i = 0; i <= m_steps; i++)
191  {
192  pbh.setTimeFraction(m_tfStep * i);
193  const double p = pbh.getPitch().value(CAngleUnit::deg());
194 
195  if (i == 0) { QVERIFY2(CMathUtils::epsilonEqualLimits(p, -30.0), "Expect initial pitch"); }
196  else if (i == m_steps) { QVERIFY2(CMathUtils::epsilonEqualLimits(p, 30.0), "Expect final pitch"); }
197  else { QVERIFY2(p > lastDeg, "Expect increasing pitch"); }
198  lastDeg = p;
199  }
200  }
201 } // namespace MiscTest
202 
205 
206 #include "testinterpolatorlinearpbh.moc"
207 
InterpolatorPBH tests As the PBH interpolator works with time-fractions, the situations are time-inde...
Value object encapsulating information of an aircraft's situation.
Heading as used in aviation, can be true or magnetic heading.
Definition: heading.h:41
Physical unit angle (radians, degrees)
Definition: angle.h:23
Simple linear interpolator for pitch, bank, heading and groundspeed from start to end situation.
Free functions in swift::misc.
SWIFTTEST_MAIN(MiscTest::CTestInterpolatorLinearPbh)
main