Renderer, ...: use PixelRect::GetCenter()
[xcsoar.git] / test / src / test_route.cpp
blob554aaaa217321650f188777c51df1f8cef0d121d
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 "Printing.hpp"
24 #define DO_PRINT
25 #include "test_debug.hpp"
26 #include "harness_airspace.hpp"
27 #include "Route/AirspaceRoute.hpp"
28 #include "Engine/Airspace/AirspaceAircraftPerformance.hpp"
29 #include "Geo/SpeedVector.hpp"
30 #include "Geo/GeoVector.hpp"
31 #include "GlideSolvers/GlideSettings.hpp"
32 #include "GlideSolvers/GlidePolar.hpp"
33 #include "Terrain/RasterMap.hpp"
34 #include "OS/ConvertPathName.hpp"
35 #include "OS/FileUtil.hpp"
36 #include "Compatibility/path.h"
37 #include "Operation/Operation.hpp"
39 #include <string.h>
41 #define NUM_SOL 15
43 static bool
44 test_route(const unsigned n_airspaces, const RasterMap& map)
46 Airspaces airspaces;
47 setup_airspaces(airspaces, map.GetMapCenter(), n_airspaces);
50 Directory::Create(_T("output/results"));
51 std::ofstream fout("output/results/terrain.txt");
53 unsigned nx = 100;
54 unsigned ny = 100;
55 GeoPoint origin(map.GetMapCenter());
57 for (unsigned i = 0; i < nx; ++i) {
58 for (unsigned j = 0; j < ny; ++j) {
59 fixed fx = (fixed)i / (nx - 1) * 2 - fixed(1);
60 fixed fy = (fixed)j / (ny - 1) * 2 - fixed(1);
61 GeoPoint x(origin.longitude + Angle::Degrees(fixed(0.2) + fixed(0.7) * fx),
62 origin.latitude + Angle::Degrees(fixed(0.9) * fy));
63 short h = map.GetInterpolatedHeight(x);
64 fout << x.longitude.Degrees() << " " << x.latitude.Degrees()
65 << " " << h << "\n";
68 fout << "\n";
71 fout << "\n";
75 // local scope, see what happens when we go out of scope
76 GeoPoint p_start(Angle::Degrees(-0.3), Angle::Degrees(0.0));
77 p_start += map.GetMapCenter();
79 GeoPoint p_dest(Angle::Degrees(0.8), Angle::Degrees(-0.7));
80 p_dest += map.GetMapCenter();
82 AGeoPoint loc_start(p_start, RoughAltitude(map.GetHeight(p_start) + 100));
83 AGeoPoint loc_end(p_dest, RoughAltitude(map.GetHeight(p_dest) + 100));
85 AircraftState state;
86 GlidePolar glide_polar(fixed(0.1));
87 const AirspaceAircraftPerformance perf(glide_polar);
89 GeoVector vec(loc_start, loc_end);
90 fixed range = fixed(10000) + vec.distance / 2;
92 state.location = loc_start;
93 state.altitude = loc_start.altitude;
96 Airspaces as_route(airspaces, false);
97 // dummy
99 // real one, see if items changed
100 as_route.SynchroniseInRange(airspaces, vec.MidPoint(loc_start), range);
101 int size_1 = as_route.size();
102 if (verbose)
103 printf("# route airspace size %d\n", size_1);
105 as_route.SynchroniseInRange(airspaces, vec.MidPoint(loc_start), fixed(1));
106 int size_2 = as_route.size();
107 if (verbose)
108 printf("# route airspace size %d\n", size_2);
110 ok(size_2 < size_1, "shrink as", 0);
112 // go back
113 as_route.SynchroniseInRange(airspaces, vec.MidPoint(loc_end), range);
114 int size_3 = as_route.size();
115 if (verbose)
116 printf("# route airspace size %d\n", size_3);
118 ok(size_3 >= size_2, "grow as", 0);
120 // and again
121 as_route.SynchroniseInRange(airspaces, vec.MidPoint(loc_start), range);
122 int size_4 = as_route.size();
123 if (verbose)
124 printf("# route airspace size %d\n", size_4);
126 ok(size_4 >= size_3, "grow as", 0);
128 scan_airspaces(state, as_route, perf, true, loc_end);
131 // try the solver
132 SpeedVector wind(Angle::Degrees(0), fixed(0));
133 GlidePolar polar(fixed(1));
135 GlideSettings settings;
136 settings.SetDefaults();
137 AirspaceRoute route(airspaces);
138 route.UpdatePolar(settings, polar, polar, wind);
139 route.SetTerrain(&map);
140 RoutePlannerConfig config;
141 config.mode = RoutePlannerConfig::Mode::BOTH;
143 bool sol = false;
144 for (int i = 0; i < NUM_SOL; i++) {
145 loc_end.latitude += Angle::Degrees(0.1);
146 loc_end.altitude = map.GetHeight(loc_end) + 100;
147 route.Synchronise(airspaces, loc_start, loc_end);
148 if (route.Solve(loc_start, loc_end, config)) {
149 sol = true;
150 if (verbose) {
151 PrintHelper::print_route(route);
153 } else {
154 if (verbose) {
155 printf("# fail\n");
157 sol = false;
159 char buffer[80];
160 sprintf(buffer, "route %d solution", i);
161 ok(sol, buffer, 0);
165 return true;
169 main(int argc, char** argv)
171 const char hc_path[] = "tmp/terrain";
173 TCHAR jp2_path[4096];
174 _tcscpy(jp2_path, PathName(hc_path));
175 _tcscat(jp2_path, _T(DIR_SEPARATOR_S) _T("terrain.jp2"));
177 TCHAR j2w_path[4096];
178 _tcscpy(j2w_path, PathName(hc_path));
179 _tcscat(j2w_path, _T(DIR_SEPARATOR_S) _T("terrain.j2w"));
181 NullOperationEnvironment operation;
182 RasterMap map(jp2_path, j2w_path, NULL, operation);
183 do {
184 map.SetViewCenter(map.GetMapCenter(), fixed(100000));
185 } while (map.IsDirty());
187 plan_tests(4 + NUM_SOL);
188 ok(test_route(28, map), "route 28", 0);
189 return exit_status();