4 XCSoar Glide Computer - http://www.xcsoar.org/
5 Copyright (C) 2000-2013 The XCSoar Project
6 A detailed list of copyright holders can be found in the file "AUTHORS".
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 #include "StatsComputer.hpp"
26 #include "NMEA/MoreData.hpp"
27 #include "NMEA/Derived.hpp"
29 StatsComputer::StatsComputer()
30 :stats_clock(fixed(60)) {}
33 StatsComputer::ResetFlight(const bool full
)
35 last_location
= GeoPoint::Invalid();
36 last_climb_start_time
= fixed(-1);
37 last_cruise_start_time
= fixed(-1);
38 last_thermal_end_time
= fixed(-1);
45 StatsComputer::StartTask(const NMEAInfo
&basic
)
47 flightstats
.StartTask();
51 * Logs GPS fixes for stats
52 * @return True if valid fix (fix distance <= 200m), False otherwise
55 StatsComputer::DoLogging(const MoreData
&basic
,
56 const DerivedInfo
&calculated
)
58 /// @todo consider putting this sanity check inside Parser
59 bool location_jump
= basic
.location_available
&& last_location
.IsValid() &&
60 basic
.location
.Distance(last_location
) > fixed(200);
62 last_location
= basic
.location_available
63 ? basic
.location
: GeoPoint::Invalid();
65 if (location_jump
|| !basic
.location_available
)
66 // prevent bad fixes from being logged or added to OLC store
69 if (calculated
.flight
.flying
&&
70 stats_clock
.CheckAdvance(basic
.time
)) {
71 flightstats
.AddAltitudeTerrain(calculated
.flight
.flight_time
,
72 calculated
.terrain_altitude
);
74 if (basic
.NavAltitudeAvailable())
75 flightstats
.AddAltitude(calculated
.flight
.flight_time
,
78 if (calculated
.task_stats
.IsPirkerSpeedAvailable())
79 flightstats
.AddTaskSpeed(calculated
.flight
.flight_time
,
80 calculated
.task_stats
.get_pirker_speed());
87 StatsComputer::OnClimbBase(const DerivedInfo
&calculated
, fixed StartAlt
)
89 flightstats
.AddClimbBase(calculated
.climb_start_time
-
90 calculated
.flight
.takeoff_time
, StartAlt
);
94 StatsComputer::OnClimbCeiling(const DerivedInfo
&calculated
)
96 flightstats
.AddClimbCeiling(calculated
.cruise_start_time
-
97 calculated
.flight
.takeoff_time
,
98 calculated
.cruise_start_altitude
);
102 * This function is called when leaving a thermal and handles the
103 * calculation of all related statistics
106 StatsComputer::OnDepartedThermal(const DerivedInfo
&calculated
)
108 assert(calculated
.last_thermal
.IsDefined());
110 flightstats
.AddThermalAverage(calculated
.last_thermal
.lift_rate
);
114 StatsComputer::ProcessClimbEvents(const DerivedInfo
&calculated
)
116 switch (calculated
.turn_mode
) {
117 case CirclingMode::CLIMB
:
118 if (calculated
.climb_start_time
> last_climb_start_time
)
119 // set altitude for start of circling (as base of climb)
120 OnClimbBase(calculated
, calculated
.climb_start_altitude
);
123 case CirclingMode::CRUISE
:
124 if (calculated
.cruise_start_time
> last_cruise_start_time
)
125 OnClimbCeiling(calculated
);
132 if (calculated
.last_thermal
.IsDefined() &&
133 (negative(last_thermal_end_time
) ||
134 calculated
.last_thermal
.end_time
> last_thermal_end_time
))
135 OnDepartedThermal(calculated
);
137 last_climb_start_time
= calculated
.climb_start_time
;
138 last_cruise_start_time
= calculated
.cruise_start_time
;
139 last_thermal_end_time
= calculated
.last_thermal
.IsDefined()
140 ? calculated
.last_thermal
.end_time
: fixed(-1);