1 #include "test_debug.hpp"
2 #include "harness_aircraft.hpp"
3 #include "Replay/IgcReplay.hpp"
4 #include "Computer/TraceComputer.hpp"
5 #include "Computer/FlyingComputer.hpp"
6 #include "Engine/Contest/ContestManager.hpp"
7 #include "Computer/Settings.hpp"
8 #include "OS/PathName.hpp"
9 #include "OS/FileUtil.hpp"
10 #include "IO/FileLineReader.hpp"
11 #include "Navigation/Aircraft.hpp"
12 #include "NMEA/MoreData.hpp"
13 #include "NMEA/Derived.hpp"
17 ContestResult official_score_classic
,
18 official_score_sprint
,
23 inline void output_score(const char* header
,
24 const ContestResult
& score
)
26 std::cout
<< header
<< "\n";
27 PrintHelper::print(score
);
30 inline bool compare_scores(const ContestResult
& official
,
31 const ContestResult
& estimated
)
34 output_score("# Official:", official
);
35 output_score("# Estimated:", estimated
);
37 if (!positive(official
.score
)) {
40 fixed e
= fabs((official
.score
-estimated
.score
)/official
.score
);
41 std::cout
<< "# Error (score) " << e
<< "\n";
42 if (positive(official
.score
)) {
43 return (e
<fixed(0.01));
45 // nothing to compare with
50 inline void load_score_file(std::ifstream
& fscore
,
54 fscore
>> tmp
; score
.score
= (fixed
)tmp
;
55 fscore
>> tmp
; score
.distance
= (fixed
)tmp
;
56 fscore
>> tmp
; fixed
speed(tmp
);
58 score
.time
= fixed(3600)*score
.distance
/speed
;
60 score
.time
= fixed(0);
62 score
.distance
*= fixed(1000);
66 inline void load_scores(unsigned &contest_handicap
) {
68 int index
= replay_file
.find_last_of(".");
69 std::string score_file
= replay_file
.substr(0, index
) + ".txt";
71 std::cout
<< "# replay file: " << replay_file
<< "\n";
72 std::cout
<< "# score file: " << score_file
<< "\n";
74 std::ifstream
fscore(score_file
.c_str());
76 fscore
>> tmp
; official_index
= (fixed
)tmp
;
77 load_score_file(fscore
, official_score_classic
);
78 load_score_file(fscore
, official_score_sprint
);
79 load_score_file(fscore
, official_score_fai
);
80 load_score_file(fscore
, official_score_plus
);
83 contest_handicap
= (unsigned)official_index
;
85 if (contest_handicap
==0) { // in case file load failed
86 contest_handicap
= 100;
91 class ReplayLoggerSim
: public IgcReplay
94 ReplayLoggerSim(NLineReader
*reader
)
100 void print(std::ostream
&f
) {
101 f
<< (double)state
.time
<< " "
102 << (double)state
.location
.longitude
.Degrees() << " "
103 << (double)state
.location
.latitude
.Degrees() << " "
104 << (double)state
.altitude
<< "\n";
109 virtual void OnReset() {}
111 void OnAdvance(const GeoPoint
&loc
,
112 const fixed speed
, const Angle bearing
,
113 const fixed alt
, const fixed baroalt
, const fixed t
) {
115 state
.location
= loc
;
116 state
.ground_speed
= speed
;
117 state
.track
= bearing
;
118 state
.altitude
= alt
;
119 state
.netto_vario
= fixed(0);
120 state
.vario
= fixed(0);
129 test_replay(const Contest olc_type
,
130 const ContestResult
&official_score
)
132 Directory::Create(_T("output/results"));
133 std::ofstream
f("output/results/res-sample.txt");
135 GlidePolar
glide_polar(fixed(2));
136 AircraftState state_last
;
138 FileLineReaderA
*reader
= new FileLineReaderA(replay_file
.c_str());
139 if (reader
->error()) {
144 ReplayLoggerSim
sim(reader
);
146 ComputerSettings settings_computer
;
147 settings_computer
.SetDefaults();
148 settings_computer
.contest
.enable
= true;
149 load_scores(settings_computer
.contest
.handicap
);
153 case Contest::OLC_LEAGUE
:
154 std::cout
<< "# OLC-League\n";
156 case Contest::OLC_SPRINT
:
157 std::cout
<< "# OLC-Sprint\n";
159 case Contest::OLC_FAI
:
160 std::cout
<< "# OLC-FAI\n";
162 case Contest::OLC_CLASSIC
:
163 std::cout
<< "# OLC-Classic\n";
165 case Contest::OLC_PLUS
:
166 std::cout
<< "# OLC-Plus\n";
169 std::cout
<< "# Unknown!\n";
174 bool do_print
= verbose
;
175 unsigned print_counter
=0;
180 while (sim
.Update(basic
) && !sim
.started
) {
182 state_last
= sim
.state
;
184 fixed time_last
= sim
.state
.time
;
186 FlyingComputer flying_computer
;
187 flying_computer
.Reset();
189 FlyingState flying_state
;
190 flying_state
.Reset();
192 TraceComputer trace_computer
;
194 ContestManager
contest_manager(olc_type
,
195 trace_computer
.GetFull(),
196 trace_computer
.GetFull(),
197 trace_computer
.GetSprint());
198 contest_manager
.SetHandicap(settings_computer
.contest
.handicap
);
200 DerivedInfo calculated
;
202 while (sim
.Update(basic
)) {
203 if (sim
.state
.time
>time_last
) {
207 flying_computer
.Compute(glide_polar
.GetVTakeoff(),
208 sim
.state
, sim
.state
.time
- time_last
,
211 calculated
.flight
.flying
= flying_state
.flying
;
213 trace_computer
.Update(settings_computer
, basic
, calculated
);
215 contest_manager
.UpdateIdle();
217 state_last
= sim
.state
;
224 PrintHelper::trace_print(trace_computer
.GetFull(), sim
.state
.location
);
226 do_print
= (++print_counter
% output_skip
==0) && verbose
;
228 time_last
= sim
.state
.time
;
231 contest_manager
.SolveExhaustive();
234 PrintDistanceCounts();
236 return compare_scores(official_score
,
237 contest_manager
.GetStats().GetResult(0));
241 int main(int argc
, char** argv
)
243 if (!ParseArgs(argc
,argv
)) {
249 ok(test_replay(Contest::OLC_LEAGUE
, official_score_sprint
),
251 ok(test_replay(Contest::OLC_FAI
, official_score_fai
),
253 ok(test_replay(Contest::OLC_CLASSIC
, official_score_classic
),
254 "replay classic", 0);
255 ok(test_replay(Contest::OLC_SPRINT
, official_score_sprint
),
257 ok(test_replay(Contest::OLC_PLUS
, official_score_plus
),
260 return exit_status();