android/GlueIOIOPort: fix spurious errors after IOIO baud rate change
[xcsoar.git] / test / src / test_replay_olc.cpp
blobe903202e91150f4f31b01aabf229758213214e04
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"
15 #include <fstream>
17 ContestResult official_score_classic,
18 official_score_sprint,
19 official_score_fai,
20 official_score_plus;
21 fixed official_index;
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)
33 if (verbose) {
34 output_score("# Official:", official);
35 output_score("# Estimated:", estimated);
37 if (!positive(official.score)) {
38 return true;
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));
44 } else {
45 // nothing to compare with
46 return true;
50 inline void load_score_file(std::ifstream& fscore,
51 ContestResult& score)
53 double tmp;
54 fscore >> tmp; score.score = (fixed)tmp;
55 fscore >> tmp; score.distance = (fixed)tmp;
56 fscore >> tmp; fixed speed(tmp);
57 if (speed>fixed(0)) {
58 score.time = fixed(3600)*score.distance/speed;
59 } else {
60 score.time = fixed(0);
62 score.distance *= fixed(1000);
66 inline void load_scores(unsigned &contest_handicap) {
67 // replay_file
68 int index = replay_file.find_last_of(".");
69 std::string score_file = replay_file.substr(0, index) + ".txt";
70 if (verbose) {
71 std::cout << "# replay file: " << replay_file << "\n";
72 std::cout << "# score file: " << score_file << "\n";
74 std::ifstream fscore(score_file.c_str());
75 double tmp;
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);
81 fscore.close();
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
93 public:
94 ReplayLoggerSim(NLineReader *reader)
95 :IgcReplay(reader),
96 started(false) {}
98 AircraftState state;
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";
106 bool started;
108 protected:
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);
121 state.time = t;
122 if (positive(t)) {
123 started = true;
128 static bool
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()) {
140 delete reader;
141 return false;
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);
151 if (verbose) {
152 switch (olc_type) {
153 case Contest::OLC_LEAGUE:
154 std::cout << "# OLC-League\n";
155 break;
156 case Contest::OLC_SPRINT:
157 std::cout << "# OLC-Sprint\n";
158 break;
159 case Contest::OLC_FAI:
160 std::cout << "# OLC-FAI\n";
161 break;
162 case Contest::OLC_CLASSIC:
163 std::cout << "# OLC-Classic\n";
164 break;
165 case Contest::OLC_PLUS:
166 std::cout << "# OLC-Plus\n";
167 break;
168 default:
169 std::cout << "# Unknown!\n";
170 break;
174 bool do_print = verbose;
175 unsigned print_counter=0;
177 MoreData basic;
178 basic.Reset();
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) {
205 n_samples++;
207 flying_computer.Compute(glide_polar.GetVTakeoff(),
208 sim.state, sim.state.time - time_last,
209 flying_state);
211 calculated.flight.flying = flying_state.flying;
213 trace_computer.Update(settings_computer, basic, calculated);
215 contest_manager.UpdateIdle();
217 state_last = sim.state;
219 if (verbose>1) {
220 sim.print(f);
221 f.flush();
223 if (do_print) {
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();
233 if (verbose) {
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)) {
244 return 0;
247 plan_tests(5);
249 ok(test_replay(Contest::OLC_LEAGUE, official_score_sprint),
250 "replay league", 0);
251 ok(test_replay(Contest::OLC_FAI, official_score_fai),
252 "replay fai", 0);
253 ok(test_replay(Contest::OLC_CLASSIC, official_score_classic),
254 "replay classic", 0);
255 ok(test_replay(Contest::OLC_SPRINT, official_score_sprint),
256 "replay sprint", 0);
257 ok(test_replay(Contest::OLC_PLUS, official_score_plus),
258 "replay plus", 0);
260 return exit_status();