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"
36 OpenConfiguredTextFile(const TCHAR
*profile_key
, ConvertLineReader::charset cs
)
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));
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()");
78 // Test LoadFromFile()
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));
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
{
108 bool check_best_LD_speed
;
109 fixed best_LD_speed
; // km/h
111 fixed min_sink
; // m/s
112 bool check_min_sink_speed
;
113 fixed min_sink_speed
; // km/h
116 static const PerformanceItem performanceData
[] = {
118 { 0, true, fixed(38), true, fixed(103), true, fixed(0.6), true, fixed( 74) },
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) },
126 { 45, true, fixed(30), true, fixed( 85), true, fixed(0.65), true, fixed( 72) },
128 { 46, true, fixed(25), true, fixed( 75), false, fixed(0), true, fixed( 62) },
130 { 52, true, fixed(40.5), false, fixed( 0), true, fixed(0.60), false, fixed( 0) },
132 { 79, true, fixed(38.5), false, fixed( 0), true, fixed(0.6), false, fixed( 0) },
134 { 157, true, fixed(38.2), false, fixed( 0), true, fixed(0.64), false, fixed( 0) },
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
;
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
);
168 fprintf(stderr
, " LD: ");
169 ok(!performanceData
[i
].check_best_LD
||
170 ValuePlausible(performanceData
[i
].best_LD
, gp
.GetBestLD()),
172 fprintf(stderr
, "VLD: ");
173 ok(!performanceData
[i
].check_best_LD_speed
||
174 ValuePlausible(performanceData
[i
].best_LD_speed
, gp
.GetVBestLD() * fixed(3.6)),
176 fprintf(stderr
, " MS: ");
177 ok(!performanceData
[i
].check_min_sink
||
178 ValuePlausible(performanceData
[i
].min_sink
, gp
.GetSMin()),
180 fprintf(stderr
, "VMS: ");
181 ok(!performanceData
[i
].check_min_sink_speed
||
182 ValuePlausible(performanceData
[i
].min_sink_speed
, gp
.GetVMin() * fixed(3.6)),
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
193 num_tests
+= ARRAY_SIZE(performanceData
) * 5;
195 plan_tests(num_tests
);
201 // NOTE: Plausibility tests disabled for now since many fail
203 TestBuiltInPolarsPlausibility();
205 return exit_status();