TaskManager: remove GetStartState() and GetFinishState()
[xcsoar.git] / test / src / TestPolars.cpp
blob6a70d894ee512e3df916614abddee4de6c1e3eec
1 /* Copyright_License {
3 XCSoar Glide Computer - http://www.xcsoar.org/
4 Copyright (C) 2000-2013 The XCSoar Project
5 A detailed list of copyright holders can be found in the file "AUTHORS".
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include "TestUtil.hpp"
25 #include "GlideSolvers/GlidePolar.hpp"
26 #include "IO/ConfiguredFile.hpp"
27 #include "Profile/Profile.hpp"
28 #include "Polar/Polar.hpp"
29 #include "Polar/Parser.hpp"
30 #include "Polar/PolarFileGlue.hpp"
31 #include "Polar/PolarStore.hpp"
32 #include "Util/ConvertString.hpp"
33 #include "Util/Macros.hpp"
35 TLineReader*
36 OpenConfiguredTextFile(const TCHAR *profile_key, ConvertLineReader::charset cs)
38 return NULL;
41 static void
42 TestBasic()
44 // Test ReadString()
45 PolarInfo polar;
46 ParsePolar(polar, _T("318, 100, 80, -0.606, 120, -0.99, 160, -1.918"));
47 ok1(equals(fixed(polar.reference_mass), 318));
48 ok1(equals(fixed(polar.max_ballast), 100));
49 ok1(equals(fixed(polar.shape[0].v), 22.2222222));
50 ok1(equals(fixed(polar.shape[0].w), -0.606));
51 ok1(equals(fixed(polar.shape[1].v), 33.3333333));
52 ok1(equals(fixed(polar.shape[1].w), -0.99));
53 ok1(equals(fixed(polar.shape[2].v), 44.4444444));
54 ok1(equals(fixed(polar.shape[2].w), -1.918));
55 ok1(equals(fixed(polar.wing_area), 0.0));
57 ParsePolar(polar, _T("318, 100, 80, -0.606, 120, -0.99, 160, -1.918, 9.8"));
58 ok1(equals(fixed(polar.reference_mass), 318));
59 ok1(equals(fixed(polar.max_ballast), 100));
60 ok1(equals(fixed(polar.shape[0].v), 22.2222222));
61 ok1(equals(fixed(polar.shape[0].w), -0.606));
62 ok1(equals(fixed(polar.shape[1].v), 33.3333333));
63 ok1(equals(fixed(polar.shape[1].w), -0.99));
64 ok1(equals(fixed(polar.shape[2].v), 44.4444444));
65 ok1(equals(fixed(polar.shape[2].w), -1.918));
66 ok1(equals(fixed(polar.wing_area), 9.8));
68 // Test GetString()
69 TCHAR polar_string[255];
70 FormatPolar(polar, polar_string, 255);
71 ok(_tcscmp(_T("318,100,80.000,-0.606,120.000,-0.990,160.000,-1.918,9.800"),
72 polar_string) == 0, "GetString()");
75 static void
76 TestFileImport()
78 // Test LoadFromFile()
79 PolarInfo polar;
80 PolarGlue::LoadFromFile(polar, _T("test/data/test.plr"));
81 ok1(equals(fixed(polar.reference_mass), 318));
82 ok1(equals(fixed(polar.max_ballast), 100));
83 ok1(equals(fixed(polar.shape[0].v), 22.2222222));
84 ok1(equals(fixed(polar.shape[0].w), -0.606));
85 ok1(equals(fixed(polar.shape[1].v), 33.3333333));
86 ok1(equals(fixed(polar.shape[1].w), -0.99));
87 ok1(equals(fixed(polar.shape[2].v), 44.4444444));
88 ok1(equals(fixed(polar.shape[2].w), -1.918));
89 ok1(equals(fixed(polar.wing_area), 9.8));
92 static void
93 TestBuiltInPolars()
95 unsigned count = PolarStore::Count();
96 for(unsigned i = 0; i < count; i++) {
97 PolarInfo polar = PolarStore::GetItem(i).ToPolarInfo();
99 WideToUTF8Converter narrow(PolarStore::GetItem(i).name);
100 ok(polar.IsValid(), narrow);
104 struct PerformanceItem {
105 unsigned storeIndex;
106 bool check_best_LD;
107 fixed best_LD;
108 bool check_best_LD_speed;
109 fixed best_LD_speed; // km/h
110 bool check_min_sink;
111 fixed min_sink; // m/s
112 bool check_min_sink_speed;
113 fixed min_sink_speed; // km/h
116 static const PerformanceItem performanceData[] = {
117 /* 206 Hornet */
118 { 0, true, fixed(38), true, fixed(103), true, fixed(0.6), true, fixed( 74) },
119 /* Discus */
120 { 30, true, fixed(43), false, fixed( 0), true, fixed(0.59), false, fixed( 0) },
121 /* G-103 TWIN II (PIL)*/
122 { 37, true, fixed(38.5), true, fixed( 95), true, fixed(0.64), true, fixed( 80) },
123 /* H-201 Std. Libelle */
124 { 41, true, fixed(38), true, fixed( 90), true, fixed(0.6), true, fixed( 75) },
125 /* Ka6 CR */
126 { 45, true, fixed(30), true, fixed( 85), true, fixed(0.65), true, fixed( 72) },
127 /* K8 */
128 { 46, true, fixed(25), true, fixed( 75), false, fixed(0), true, fixed( 62) },
129 /* LS-4 */
130 { 52, true, fixed(40.5), false, fixed( 0), true, fixed(0.60), false, fixed( 0) },
131 /* Std. Cirrus */
132 { 79, true, fixed(38.5), false, fixed( 0), true, fixed(0.6), false, fixed( 0) },
133 /* LS-1f */
134 { 157, true, fixed(38.2), false, fixed( 0), true, fixed(0.64), false, fixed( 0) },
137 static bool
138 ValuePlausible(fixed ref, fixed used, fixed threshold = fixed(0.05))
140 fprintf(stderr, "%.2f %.2f %.2f %.2f -- ", (double) ref, (double) used,
141 (double) fabs(ref - used), (double) (ref * threshold));
142 return fabs(ref - used) < ref * threshold;
145 static void
146 TestBuiltInPolarsPlausibility()
148 for(unsigned i = 0; i < ARRAY_SIZE(performanceData); i++) {
149 assert(i < PolarStore::Count());
150 unsigned si = performanceData[i].storeIndex;
151 PolarInfo polar = PolarStore::GetItem(si).ToPolarInfo();
152 PolarCoefficients pc = polar.CalculateCoefficients();
154 WideToUTF8Converter polarName(PolarStore::GetItem(i).name);
156 ok(pc.IsValid(), polarName);
158 GlidePolar gp(fixed(0));
159 gp.SetCoefficients(pc, false);
161 // Glider empty weight
162 gp.SetReferenceMass(polar.reference_mass, false);
163 gp.SetBallastRatio(polar.max_ballast / polar.reference_mass);
164 gp.SetWingArea(polar.wing_area);
166 gp.Update();
168 fprintf(stderr, " LD: ");
169 ok(!performanceData[i].check_best_LD ||
170 ValuePlausible(performanceData[i].best_LD, gp.GetBestLD()),
171 polarName);
172 fprintf(stderr, "VLD: ");
173 ok(!performanceData[i].check_best_LD_speed ||
174 ValuePlausible(performanceData[i].best_LD_speed, gp.GetVBestLD() * fixed(3.6)),
175 polarName);
176 fprintf(stderr, " MS: ");
177 ok(!performanceData[i].check_min_sink ||
178 ValuePlausible(performanceData[i].min_sink, gp.GetSMin()),
179 polarName);
180 fprintf(stderr, "VMS: ");
181 ok(!performanceData[i].check_min_sink_speed ||
182 ValuePlausible(performanceData[i].min_sink_speed, gp.GetVMin() * fixed(3.6)),
183 polarName);
187 int main(int argc, char **argv)
189 unsigned num_tests = 19 + 9 + PolarStore::Count();
191 // NOTE: Plausibility tests disabled for now since many fail
192 if (0)
193 num_tests += ARRAY_SIZE(performanceData) * 5;
195 plan_tests(num_tests);
197 TestBasic();
198 TestFileImport();
199 TestBuiltInPolars();
201 // NOTE: Plausibility tests disabled for now since many fail
202 if (0)
203 TestBuiltInPolarsPlausibility();
205 return exit_status();