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.
24 #include "Computer.hpp"
25 #include "Settings.hpp"
26 #include "NMEA/MoreData.hpp"
27 #include "NMEA/Derived.hpp"
32 last_circling
= false;
34 circling_wind
.Reset();
41 GetVTakeoffFallback(const GlidePolar
&glide_polar
)
43 return glide_polar
.IsValid()
44 ? glide_polar
.GetVTakeoff()
45 /* if there's no valid polar, assume 10 m/s (36 km/h); that's an
46 arbitrary value, but better than nothing */
51 WindComputer::Compute(const WindSettings
&settings
,
52 const GlidePolar
&glide_polar
,
53 const MoreData
&basic
, DerivedInfo
&calculated
)
55 if (settings
.CirclingWindEnabled() &&
56 calculated
.circling
!= last_circling
)
57 circling_wind
.NewFlightMode(calculated
);
59 last_circling
= calculated
.circling
;
61 if (!calculated
.flight
.flying
)
64 if (settings
.CirclingWindEnabled() &&
65 calculated
.turn_mode
== CirclingMode::CLIMB
) {
66 CirclingWind::Result result
= circling_wind
.NewSample(basic
);
68 wind_store
.SlotMeasurement(basic
, result
.wind
, result
.quality
);
71 if (settings
.ZigZagWindEnabled() &&
72 basic
.airspeed_available
&& basic
.airspeed_real
&&
73 basic
.true_airspeed
> GetVTakeoffFallback(glide_polar
)) {
74 WindEKFGlue::Result result
= wind_ekf
.Update(basic
, calculated
);
75 if (result
.quality
> 0) {
76 Vector v_wind
= Vector(result
.wind
);
77 wind_store
.SlotMeasurement(basic
, v_wind
, result
.quality
);
81 if (settings
.IsAutoWindEnabled())
82 wind_store
.SlotAltitude(basic
, calculated
);
86 WindComputer::ComputeHeadWind(const NMEAInfo
&basic
, DerivedInfo
&info
)
88 if (info
.wind_available
) {
89 // If any wind information available
90 // .. calculate headwind from given wind information
93 (info
.wind
.bearing
- basic
.attitude
.heading
).fastcosine()
95 info
.head_wind_available
.Update(basic
.clock
);
97 // No information available that let us calculate the head wind
98 info
.head_wind_available
.Clear();
103 WindComputer::Select(const WindSettings
&settings
,
104 const NMEAInfo
&basic
, DerivedInfo
&calculated
)
106 if (basic
.external_wind_available
&& settings
.use_external_wind
) {
107 // external wind available
108 calculated
.wind
= basic
.external_wind
;
109 calculated
.wind_available
= basic
.external_wind_available
;
110 calculated
.wind_source
= DerivedInfo::WindSource::EXTERNAL
;
112 } else if (settings
.manual_wind_available
&& !settings
.IsAutoWindEnabled()) {
113 // manual wind only if available and desired
114 calculated
.wind
= settings
.manual_wind
;
115 calculated
.wind_available
= settings
.manual_wind_available
;
116 calculated
.wind_source
= DerivedInfo::WindSource::MANUAL
;
118 } else if (calculated
.estimated_wind_available
.Modified(settings
.manual_wind_available
)
119 && settings
.IsAutoWindEnabled()) {
120 // auto wind when available and newer than manual wind
121 calculated
.wind
= calculated
.estimated_wind
;
122 calculated
.wind_available
= calculated
.estimated_wind_available
;
123 calculated
.wind_source
= DerivedInfo::WindSource::AUTO
;
125 } else if (settings
.manual_wind_available
126 && settings
.IsAutoWindEnabled()) {
127 // manual wind overrides auto wind if available
128 calculated
.wind
= settings
.manual_wind
;
129 calculated
.wind_available
= settings
.manual_wind_available
;
130 calculated
.wind_source
= DerivedInfo::WindSource::MANUAL
;
134 calculated
.wind_available
.Clear();
135 calculated
.wind_source
= DerivedInfo::WindSource::NONE
;