android/GlueIOIOPort: fix spurious errors after IOIO baud rate change
[xcsoar.git] / src / NMEA / Info.cpp
blob5bbf4898049abf72f447e2b0c2cab1583f76ecc1
1 /*
2 Copyright_License {
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 "NMEA/Info.hpp"
25 #include "OS/Clock.hpp"
26 #include "Atmosphere/AirDensity.hpp"
28 void
29 GPSState::Reset()
31 fix_quality = FixQuality::NO_FIX;
32 fix_quality_available.Clear();
33 real = false;
34 simulator = false;
35 #ifdef ANDROID
36 android_internal_gps = false;
37 #endif
38 satellites_used_available.Clear();
39 satellite_ids_available.Clear();
40 replay = false;
43 void
44 GPSState::Expire(fixed now)
46 if (fix_quality_available.Expire(now, fixed(5)))
47 fix_quality = FixQuality::NO_FIX;
49 satellites_used_available.Expire(now, fixed(5));
50 satellite_ids_available.Expire(now, fixed(60));
53 void
54 NMEAInfo::UpdateClock()
56 clock = fixed(MonotonicClockMS()) / 1000;
59 BrokenDateTime
60 NMEAInfo::GetDateTimeAt(fixed other_time) const
62 if (negative(other_time))
63 return BrokenDateTime::Invalid();
65 if (!time_available || !date_available)
66 return BrokenDateTime(BrokenDate::Invalid(),
67 BrokenTime::FromSecondOfDayChecked(int(other_time)));
69 return date_time_utc + int(other_time - time);
72 void
73 NMEAInfo::ProvideTime(fixed _time)
75 assert(!negative(_time));
77 time = _time;
78 time_available.Update(clock);
80 unsigned t = (unsigned)_time;
81 date_time_utc.second = t % 60;
82 t /= 60;
84 date_time_utc.minute = t % 60;
85 t /= 60;
87 date_time_utc.hour = t % 24;
90 void
91 NMEAInfo::ProvideDate(const BrokenDate &date)
93 assert(date.Plausible());
95 date_time_utc.year = date.year;
96 date_time_utc.month = date.month;
97 date_time_utc.day = date.day;
98 date_available = true;
101 void
102 NMEAInfo::ProvideTrueAirspeedWithAltitude(fixed tas, fixed altitude)
104 true_airspeed = tas;
105 indicated_airspeed = true_airspeed / AirDensityRatio(altitude);
106 airspeed_available.Update(clock);
107 airspeed_real = true;
110 void
111 NMEAInfo::ProvideIndicatedAirspeedWithAltitude(fixed ias, fixed altitude)
113 indicated_airspeed = ias;
114 true_airspeed = indicated_airspeed * AirDensityRatio(altitude);
115 airspeed_available.Update(clock);
116 airspeed_real = true;
119 void
120 NMEAInfo::ProvideTrueAirspeed(fixed tas)
122 auto any_altitude = GetAnyAltitude();
124 if (any_altitude.first)
125 ProvideTrueAirspeedWithAltitude(tas, any_altitude.second);
126 else
127 /* no altitude; dirty fallback */
128 ProvideBothAirspeeds(tas, tas);
131 void
132 NMEAInfo::ProvideIndicatedAirspeed(fixed ias)
134 auto any_altitude = GetAnyAltitude();
136 if (any_altitude.first)
137 ProvideIndicatedAirspeedWithAltitude(ias, any_altitude.second);
138 else
139 /* no altitude; dirty fallback */
140 ProvideBothAirspeeds(ias, ias);
143 void
144 NMEAInfo::Reset()
146 UpdateClock();
148 alive.Clear();
150 gps.Reset();
151 acceleration.Reset();
152 attitude.Reset();
154 location_available.Clear();
156 track = Angle::Zero();
157 track_available.Clear();
159 ground_speed_available.Clear();
160 airspeed_available.Clear();
161 ground_speed = true_airspeed = indicated_airspeed = fixed(0);
162 airspeed_real = false;
164 gps_altitude_available.Clear();
166 static_pressure_available.Clear();
167 dyn_pressure_available.Clear();
168 pitot_pressure_available.Clear();
169 sensor_calibration_available.Clear();
171 baro_altitude_available.Clear();
172 baro_altitude = fixed(0);
174 pressure_altitude_available.Clear();
175 pressure_altitude = fixed(0);
177 date_available = false;
179 time_available.Clear();
180 time = fixed(0);
181 date_time_utc.hour = date_time_utc.minute = date_time_utc.second = 0;
183 noncomp_vario_available.Clear();
184 total_energy_vario_available.Clear();
185 netto_vario_available.Clear();
187 settings.Clear();
189 external_wind_available.Clear();
191 temperature_available = false;
192 humidity_available = false;
194 engine_noise_level_available.Clear();
196 voltage_available.Clear();
197 battery_level_available.Clear();
199 switch_state.Reset();
201 stall_ratio_available.Clear();
203 // XXX StallRatio
205 device.Clear();
206 secondary_device.Clear();
207 flarm.Clear();
210 void
211 NMEAInfo::ExpireWallClock()
213 if (!alive)
214 return;
216 UpdateClock();
218 #ifdef ANDROID
219 if (gps.android_internal_gps)
220 /* the Android internal GPS does not expire */
221 return;
222 #endif
224 alive.Expire(clock, fixed(10));
225 if (!alive) {
226 time_available.Clear();
227 gps.Reset();
228 flarm.Clear();
229 } else {
230 time_available.Expire(clock, fixed(10));
234 void
235 NMEAInfo::Expire()
237 location_available.Expire(clock, fixed(10));
238 track_available.Expire(clock, fixed(10));
239 ground_speed_available.Expire(clock, fixed(10));
241 if (airspeed_available.Expire(clock, fixed(30)))
242 airspeed_real = false;
244 gps_altitude_available.Expire(clock, fixed(30));
245 static_pressure_available.Expire(clock, fixed(30));
246 dyn_pressure_available.Expire(clock, fixed(30));
247 pitot_pressure_available.Expire(clock, fixed(30));
248 sensor_calibration_available.Expire(clock, fixed(3600));
249 baro_altitude_available.Expire(clock, fixed(30));
250 pressure_altitude_available.Expire(clock, fixed(30));
251 noncomp_vario_available.Expire(clock, fixed(5));
252 total_energy_vario_available.Expire(clock, fixed(5));
253 netto_vario_available.Expire(clock, fixed(5));
254 settings.Expire(clock);
255 external_wind_available.Expire(clock, fixed(600));
256 engine_noise_level_available.Expire(clock, fixed(30));
257 voltage_available.Expire(clock, fixed(300));
258 battery_level_available.Expire(clock, fixed(300));
259 flarm.Expire(clock);
260 gps.Expire(clock);
261 attitude.Expire(clock);
264 void
265 NMEAInfo::Complement(const NMEAInfo &add)
267 if (!add.alive)
268 /* if there is no heartbeat on the other object, there cannot be
269 useful information */
270 return;
272 if (!alive) {
273 gps = add.gps;
276 alive.Complement(add.alive);
278 if (time_available.Complement(add.time_available)) {
279 time = add.time;
280 date_time_utc = add.date_time_utc;
281 date_available = add.date_available;
284 acceleration.Complement(add.acceleration);
285 attitude.Complement(add.attitude);
287 if (location_available.Complement(add.location_available))
288 location = add.location;
290 if (track_available.Complement(add.track_available))
291 track = add.track;
293 if (ground_speed_available.Complement(add.ground_speed_available))
294 ground_speed = add.ground_speed;
296 if ((add.airspeed_real || !airspeed_real) &&
297 airspeed_available.Complement(add.airspeed_available)) {
298 true_airspeed = add.true_airspeed;
299 indicated_airspeed = add.indicated_airspeed;
300 airspeed_real = add.airspeed_real;
303 if (gps_altitude_available.Complement(add.gps_altitude_available))
304 gps_altitude = add.gps_altitude;
306 if (static_pressure_available.Complement(add.static_pressure_available))
307 static_pressure = add.static_pressure;
309 if (dyn_pressure_available.Complement(add.dyn_pressure_available))
310 dyn_pressure = add.dyn_pressure;
312 if (pitot_pressure_available.Complement(add.pitot_pressure_available))
313 pitot_pressure = add.pitot_pressure;
315 if (sensor_calibration_available.Complement(add.sensor_calibration_available)) {
316 sensor_calibration_factor = add.sensor_calibration_factor;
317 sensor_calibration_offset = add.sensor_calibration_offset;
320 if (baro_altitude_available.Complement(add.baro_altitude_available))
321 baro_altitude = add.baro_altitude;
323 if (pressure_altitude_available.Complement(add.pressure_altitude_available))
324 pressure_altitude = add.pressure_altitude;
326 if (noncomp_vario_available.Complement(add.noncomp_vario_available))
327 noncomp_vario = add.noncomp_vario;
329 if (total_energy_vario_available.Complement(add.total_energy_vario_available))
330 total_energy_vario = add.total_energy_vario;
332 if (netto_vario_available.Complement(add.netto_vario_available))
333 netto_vario = add.netto_vario;
335 settings.Complement(add.settings);
337 if (external_wind_available.Complement(add.external_wind_available))
338 external_wind = add.external_wind;
340 if (!temperature_available && add.temperature_available) {
341 temperature = add.temperature;
342 temperature_available = add.temperature_available;
345 if (!humidity_available && add.humidity_available) {
346 humidity = add.humidity;
347 humidity_available = add.humidity_available;
350 if (voltage_available.Complement(add.voltage_available))
351 voltage = add.voltage;
353 if (battery_level_available.Complement(add.battery_level_available))
354 battery_level = add.battery_level;
356 switch_state.Complement(add.switch_state);
358 if (!stall_ratio_available && add.stall_ratio_available)
359 stall_ratio = add.stall_ratio;
361 flarm.Complement(add.flarm);