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 #include "Engine/Task/TaskManager.hpp"
25 #include "Task/Points/TaskPoint.hpp"
26 #include "Task/Points/SampledTaskPoint.hpp"
27 #include "Engine/Task/Ordered/OrderedTask.hpp"
28 #include "Engine/Task/Ordered/Points/OrderedTaskPoint.hpp"
29 #include "Engine/Task/Ordered/Points/AATPoint.hpp"
30 #include "Engine/Task/Ordered/AATIsolineSegment.hpp"
31 #include "Engine/Task/Unordered/GotoTask.hpp"
32 #include "Engine/Task/Unordered/AbortTask.hpp"
33 #include "Engine/Task/Stats/CommonStats.hpp"
34 #include "Engine/Task/ObservationZones/Boundary.hpp"
35 #include "Engine/GlideSolvers/GlideResult.hpp"
36 #include "Geo/Math.hpp"
37 #include "OS/FileUtil.hpp"
42 operator<<(std::ostream
&f
, const GlideResult
&gl
)
44 if (gl
.validity
!= GlideResult::Validity::OK
) {
45 f
<< "# Solution NOT OK\n";
47 f
<< "# Altitude Difference " << gl
.altitude_difference
<< " (m)\n";
48 f
<< "# Distance " << gl
.vector
.distance
<< " (m)\n";
49 f
<< "# TrackBearing " << gl
.vector
.bearing
<< " (deg)\n";
50 f
<< "# CruiseTrackBearing " << gl
.cruise_track_bearing
<< " (deg)\n";
51 f
<< "# VOpt " << gl
.v_opt
<< " (m/s)\n";
52 f
<< "# HeightClimb " << gl
.height_climb
<< " (m)\n";
53 f
<< "# HeightGlide " << gl
.height_glide
<< " (m)\n";
54 f
<< "# TimeElapsed " << gl
.time_elapsed
<< " (s)\n";
55 f
<< "# TimeVirtual " << gl
.time_virtual
<< " (s)\n";
56 if (positive(gl
.time_elapsed
)) {
57 f
<< "# Vave remaining " << gl
.vector
.distance
/gl
.time_elapsed
<< " (m/s)\n";
59 f
<< "# EffectiveWindSpeed " << gl
.effective_wind_speed
<< " (m/s)\n";
60 f
<< "# EffectiveWindAngle " << gl
.effective_wind_angle
<< " (deg)\n";
61 if (gl
.IsFinalGlide()) {
62 f
<< "# On final glide\n";
68 operator<<(std::ostream
&f
, const DistanceStat
&ds
)
70 f
<< "# Distance " << ds
.GetDistance() << " (m)\n";
71 f
<< "# Speed " << ds
.GetSpeed() << " (m/s)\n";
72 f
<< "# Speed incremental " << ds
.GetSpeedIncremental() << " (m/s)\n";
77 operator<<(std::ostream
&f
, const ElementStat
&es
)
79 f
<< "# Time started " << es
.time_started
<< " (s)\n";
80 f
<< "# Time elapsed " << es
.time_elapsed
<< " (s)\n";
81 f
<< "# Time remaining " << es
.time_remaining
<< " (s)\n";
82 f
<< "# Time planned " << es
.time_planned
<< " (s)\n";
83 f
<< "# Gradient " << es
.gradient
<< "\n";
84 f
<< "# Remaining: \n";
86 f
<< es
.solution_remaining
;
87 f
<< "# Remaining effective: \n";
88 f
<< es
.remaining_effective
;
89 f
<< "# Remaining mc0: \n";
93 f
<< es
.solution_planned
;
94 f
<< "# Travelled: \n";
96 f
<< es
.solution_travelled
;
98 f
<< es
.vario
.get_value();
103 #include "Task/Stats/TaskStats.hpp"
105 static std::ostream
&
106 operator<<(std::ostream
&f
, const TaskStats
&ts
)
108 f
<< "#### Task Stats\n";
109 f
<< "# dist nominal " << ts
.distance_nominal
<< " (m)\n";
110 f
<< "# min dist after achieving max " << ts
.distance_min
<< " (m)\n";
111 f
<< "# max dist after achieving max " << ts
.distance_max
<< " (m)\n";
112 f
<< "# dist scored " << ts
.distance_scored
<< " (m)\n";
113 f
<< "# mc best " << ts
.mc_best
<< " (m/s)\n";
114 f
<< "# cruise efficiency " << ts
.cruise_efficiency
<< "\n";
115 f
<< "# glide required " << ts
.glide_required
<< "\n";
117 f
<< "# Total -- \n";
125 PrintHelper::aatpoint_print(std::ostream
& f
,
127 const AircraftState
& state
,
128 const TaskProjection
&projection
,
133 orderedtaskpoint_print(f
, tp
, state
, item
);
134 f
<< "# Target " << tp
.GetTargetLocation().longitude
<< ","
135 << tp
.GetTargetLocation().latitude
<< "\n";
140 if (tp
.valid() && (tp
.GetActiveState() != OrderedTaskPoint::BEFORE_ACTIVE
)) {
141 assert(tp
.GetPrevious());
142 assert(tp
.GetNext());
143 // note in general this will only change if
144 // prev max or target changes
146 AATIsolineSegment
seg(tp
, projection
);
147 fixed tdist
= tp
.GetPrevious()->GetLocationRemaining().Distance(
148 tp
.GetLocationMin());
149 fixed rdist
= tp
.GetPrevious()->GetLocationRemaining().Distance(
150 tp
.GetTargetLocation());
152 bool filter_backtrack
= true;
154 for (double t
= 0.0; t
<=1.0; t
+= 1.0/20) {
155 GeoPoint ga
= seg
.Parametric(fixed(t
));
156 fixed dthis
= tp
.GetPrevious()->GetLocationRemaining().Distance(ga
);
157 if (!filter_backtrack
160 /// @todo unless double dist is better than current
161 f
<< ga
.longitude
<< " " << ga
.latitude
<< "\n";
165 GeoPoint ga
= seg
.Parametric(fixed(0));
166 f
<< ga
.longitude
<< " " << ga
.latitude
<< "\n";
177 PrintHelper::orderedtaskpoint_print(std::ostream
& f
,
178 const OrderedTaskPoint
& tp
,
179 const AircraftState
& state
,
183 taskpoint_print(f
,tp
,state
);
184 orderedtaskpoint_print_boundary(f
,tp
,state
);
185 f
<< "# Entered " << tp
.GetEnteredState().time
<< "\n";
186 f
<< "# Bearing travelled " << tp
.GetVectorTravelled().bearing
<< "\n";
187 f
<< "# Distance travelled " << tp
.GetVectorTravelled().distance
<< "\n";
188 f
<< "# Bearing remaining " << tp
.GetVectorRemaining(state
.location
).bearing
<< "\n";
189 f
<< "# Distance remaining " << tp
.GetVectorRemaining(state
.location
).distance
<< "\n";
190 f
<< "# Bearing planned " << tp
.GetVectorPlanned().bearing
<< "\n";
191 f
<< "# Distance planned " << tp
.GetVectorPlanned().distance
<< "\n";
197 PrintHelper::orderedtaskpoint_print_boundary(std::ostream
& f
,
198 const OrderedTaskPoint
& tp
,
199 const AircraftState
&state
)
201 f
<< "# Boundary points\n";
202 for (const auto &i
: tp
.GetBoundary())
203 f
<< " " << i
.longitude
<< " " << i
.latitude
<< "\n";
208 PrintHelper::sampledtaskpoint_print_samples(std::ostream
& f
,
209 const ScoredTaskPoint
&tp
,
210 const AircraftState
&state
)
212 const unsigned n
= tp
.GetSearchPoints().size();
213 f
<< "# Search points\n";
214 if (tp
.HasEntered()) {
215 for (unsigned i
=0; i
<n
; i
++) {
216 const GeoPoint loc
= tp
.GetSearchPoints()[i
].GetLocation();
217 f
<< " " << loc
.longitude
<< " " << loc
.latitude
<< "\n";
225 PrintHelper::taskpoint_print(std::ostream
& f
, const TaskPoint
& tp
,
226 const AircraftState
&state
)
228 f
<< "# Task point \n";
229 f
<< "# Location " << tp
.GetLocation().longitude
<< "," <<
230 tp
.GetLocation().latitude
<< "\n";
235 PrintHelper::abstracttask_print(const AbstractTask
&task
,
236 const AircraftState
&state
)
238 Directory::Create(_T("output/results"));
239 std::ofstream
fs("output/results/res-stats-all.txt");
241 const auto &stats
= task
.GetStats();
243 if (!stats
.task_valid
)
248 static std::ofstream
f6("output/results/res-stats.txt");
249 static bool first
= true;
253 f6
<< "# Time atp mc_best d_tot_rem_eff d_tot_rem ceff v_tot_rem v_tot_rem_inc v_tot_eff v_tot_eff_inc task_vario effective_mc v_pirker alt_diff\n";
256 f6
<< " " << task
.GetActiveTaskPointIndex()
257 << " " << stats
.mc_best
258 << " " << stats
.total
.remaining_effective
.GetDistance()
259 << " " << stats
.total
.remaining
.GetDistance()
260 << " " << stats
.cruise_efficiency
261 << " " << stats
.total
.remaining
.GetSpeed()
262 << " " << stats
.total
.remaining
.GetSpeedIncremental()
263 << " " << stats
.total
.remaining_effective
.GetSpeed()
264 << " " << stats
.total
.remaining_effective
.GetSpeedIncremental()
265 << " " << stats
.total
.vario
.get_value()
266 << " " << stats
.effective_mc
267 << " " << stats
.get_pirker_speed()
268 << " " << stats
.total
.solution_remaining
.altitude_difference
275 PrintHelper::gototask_print(const GotoTask
&task
,
276 const AircraftState
&state
)
278 abstracttask_print(task
, state
);
280 const TaskWaypoint
*tp
= task
.GetActiveTaskPoint();
282 std::ofstream
f1("output/results/res-goto.txt");
283 taskpoint_print(f1
, *tp
, state
);
288 PrintHelper::orderedtask_print(const OrderedTask
&task
,
289 const AircraftState
&state
)
291 abstracttask_print(task
, state
);
292 if (!task
.CheckTask())
295 std::ofstream
fi("output/results/res-isolines.txt");
296 for (unsigned i
= 0; i
< task
.TaskSize(); ++i
) {
297 const OrderedTaskPoint
&tp
= task
.GetPoint(i
);
298 fi
<< "## point " << i
<< "\n";
299 if (tp
.GetType() == TaskPointType::AAT
) {
300 aatpoint_print(fi
, (const AATPoint
&)tp
, state
,
301 task
.GetTaskProjection(), 1);
303 orderedtaskpoint_print(fi
, tp
, state
, 1);
308 std::ofstream
f1("output/results/res-task.txt");
310 f1
<< "#### Task points\n";
311 for (unsigned i
= 0; i
< task
.TaskSize(); ++i
) {
312 f1
<< "## point " << i
<< " ###################\n";
313 const OrderedTaskPoint
&tp
= task
.GetPoint(i
);
314 if (tp
.GetType() == TaskPointType::AAT
) {
315 aatpoint_print(f1
, (const AATPoint
&)tp
, state
,
316 task
.GetTaskProjection(), 0);
318 orderedtaskpoint_print(f1
, tp
, state
, 0);
323 std::ofstream
f5("output/results/res-ssample.txt");
324 f5
<< "#### Task sampled points\n";
325 for (unsigned i
=0 ; i
< task
.TaskSize(); ++i
) {
326 const OrderedTaskPoint
&tp
= task
.GetPoint(i
);
327 f5
<< "## point " << i
<< "\n";
328 sampledtaskpoint_print_samples(f5
, tp
, state
);
332 std::ofstream
f2("output/results/res-max.txt");
333 f2
<< "#### Max task\n";
334 for (unsigned i
= 0; i
< task
.TaskSize(); ++i
) {
335 const OrderedTaskPoint
&tp
= task
.GetPoint(i
);
336 f2
<< tp
.GetLocationMax().longitude
<< " "
337 << tp
.GetLocationMax().latitude
<< "\n";
340 std::ofstream
f3("output/results/res-min.txt");
341 f3
<< "#### Min task\n";
342 for (unsigned i
= 0; i
< task
.TaskSize(); ++i
) {
343 const OrderedTaskPoint
&tp
= task
.GetPoint(i
);
344 f3
<< tp
.GetLocationMin().longitude
<< " "
345 << tp
.GetLocationMin().latitude
<< "\n";
348 std::ofstream
f4("output/results/res-rem.txt");
349 f4
<< "#### Remaining task\n";
350 for (unsigned i
= 0; i
< task
.TaskSize(); ++i
) {
351 const OrderedTaskPoint
&tp
= task
.GetPoint(i
);
352 f4
<< tp
.GetLocationRemaining().longitude
<< " "
353 << tp
.GetLocationRemaining().latitude
<< "\n";
359 PrintHelper::aborttask_print(const AbortTask
&task
, const AircraftState
&state
)
361 abstracttask_print(task
, state
);
363 std::ofstream
f1("output/results/res-abort-task.txt");
364 f1
<< "#### Task points\n";
365 for (unsigned i
= 0; i
< task
.TaskSize(); ++i
) {
366 GeoPoint l
= task
.GetAlternate(i
).GetLocation();
367 f1
<< "## point " << i
<< " ###################\n";
368 if (i
== task
.GetActiveTaskPointIndex()) {
369 f1
<< state
.location
.longitude
<< " " << state
.location
.latitude
<< "\n";
371 f1
<< l
.longitude
<< " " << l
.latitude
<< "\n";
378 PrintHelper::taskmanager_print(const TaskManager
&task
,
379 const AircraftState
&state
)
381 switch (task
.GetMode()) {
385 case TaskType::ABORT
:
386 aborttask_print(*(const AbortTask
*)task
.GetActiveTask(), state
);
390 gototask_print(*(const GotoTask
*)task
.GetActiveTask(), state
);
393 case TaskType::ORDERED
:
394 orderedtask_print(task
.GetOrderedTask(), state
);
400 std::ostream& operator<< (std::ostream& o,
401 const TaskProjection& tp)
403 o << "# Task projection\n";
404 o << "# deg (" << tp.location_min.Longitude << ","
405 << tp.location_min.Latitude << "),("
406 << tp.location_max.Longitude << "," << tp.location_max.Latitude << ")\n";
408 FlatGeoPoint pll, pur;
409 pll = tp.project(tp.location_min);
410 pur = tp.project(tp.location_max);
412 o << "# flat (" << pll.Longitude << "," << pll.Latitude << "),("
413 << pur.Longitude << "," << pur.Latitude << "\n";