Esempio n. 1
0
void Flight::Reduce(const BrokenDateTime start, const BrokenDateTime end,
                    const unsigned num_levels, const unsigned zoom_factor,
                    const double threshold, const bool force_endpoints,
                    const unsigned max_delta_time, const unsigned max_points) {
  // we need the whole flight, so read it now...
  if (!keep_flight) {
    ReadFlight();
    keep_flight = true;
  }

  DouglasPeuckerMod dp(num_levels, zoom_factor, threshold,
    force_endpoints, max_delta_time, max_points);

  unsigned start_index = 0,
           end_index = 0;

  int64_t start_time = start.ToUnixTimeUTC(),
          end_time = end.ToUnixTimeUTC();

  for (auto fix : *fixes) {
    if (BrokenDateTime(fix.date, fix.time).ToUnixTimeUTC() < start_time)
      start_index++;

    if (BrokenDateTime(fix.date, fix.time).ToUnixTimeUTC() < end_time)
      end_index++;
    else
      break;
  }

  end_index = std::min(end_index, unsigned(fixes->size()));
  start_index = std::min(start_index, end_index);

  dp.Encode(*fixes, start_index, end_index);
}
Esempio n. 2
0
bool
NMEALogger::Start()
{
  if (writer != nullptr)
    return true;

  BrokenDateTime dt = BrokenDateTime::NowUTC();
  assert(dt.IsPlausible());

  StaticString<64> name;
  name.Format(_T("%04u-%02u-%02u_%02u-%02u.nmea"),
              dt.year, dt.month, dt.day,
              dt.hour, dt.minute);

  const auto logs_path = MakeLocalPath(_T("logs"));

  const auto path = AllocatedPath::Build(logs_path, name);
  writer = new TextWriter(path, false);
  if (writer == nullptr)
    return false;

  if (!writer->IsOpen()) {
    delete writer;
    writer = nullptr;
    return false;
  }

  return true;
}
Esempio n. 3
0
  Result() {
    takeoff_time.Clear();
    landing_time.Clear();
    release_time.Clear();

    takeoff_location.SetInvalid();
    landing_location.SetInvalid();
    release_location.SetInvalid();
  }
Esempio n. 4
0
 /**
  * Reinitialize phase
  */
 void Clear() {
   phase_type = NO_PHASE;
   start_datetime.Clear();
   end_datetime.Clear();
   start_time = 0;
   end_time = 0;
   duration = 0;
   fraction = 0;
   circling_direction = NO_DIRECTION;
   alt_diff = 0;
   distance = 0;
   merges = 0;
 }
Esempio n. 5
0
static void
WriteEvent(JSON::ObjectWriter &object, const char *name,
           const BrokenDateTime &time, const GeoPoint &location)
{
  if (time.IsPlausible() || location.IsValid())
    object.WriteElement(name, WriteEventAttributes, time, location);
}
Esempio n. 6
0
fixed
SunEphemeris::FNday(const BrokenDateTime &date_time)
{
  assert(date_time.Plausible());

  long int luku = -7 * (date_time.year + (date_time.month + 9) / 12) / 4 +
                  275 * date_time.month / 9 + date_time.day +
                  (long int)date_time.year * 367;

  return fixed(luku) - fixed(730531.5) + fixed(date_time.hour % 24) / 24;
}
Esempio n. 7
0
static bool
RawLoggerStart()
{
  if (RawLoggerWriter != NULL)
    return true;

  BrokenDateTime dt = XCSoarInterface::Basic().DateTime;
  assert(dt.Plausible());

  TCHAR path[MAX_PATH];
  LocalPath(path, _T("logs"));
  unsigned len = _tcslen(path);
  _sntprintf(path+len, MAX_PATH-len,
             _T(DIR_SEPARATOR_S "%04u-%02u-%02u_%02u-%02u.nmea"),
             dt.year, dt.month, dt.day,
             dt.hour, dt.minute);

  RawLoggerWriter = new BatchTextWriter(path, false);
  return RawLoggerWriter != NULL;
}
Esempio n. 8
0
bool
NMEALogger::Start()
{
  if (writer != NULL)
    return true;

  BrokenDateTime dt = XCSoarInterface::Basic().date_time_utc;
  assert(dt.Plausible());

  StaticString<64> name;
  name.Format(_T("%04u-%02u-%02u_%02u-%02u.nmea"),
              dt.year, dt.month, dt.day,
              dt.hour, dt.minute);

  TCHAR path[MAX_PATH];
  LocalPath(path, _T("logs"));
  Directory::Create(path);

  LocalPath(path, _T("logs"), name);

  writer = new BatchTextWriter(path, false);
  return writer != NULL;
}
Esempio n. 9
0
void
IGCWriter::WriteHeader(const BrokenDateTime &date_time,
                       const TCHAR *pilot_name, const TCHAR *aircraft_model,
                       const TCHAR *aircraft_registration,
                       const TCHAR *competition_id,
                       const char *logger_id, const TCHAR *driver_name,
                       bool simulator)
{
    /*
     * HFDTE141203  <- should be UTC, same as time in filename
     * HFFXA100
     * HFPLTPILOT:JOHN WHARINGTON
     * HFGTYGLIDERTYPE:LS 3
     * HFGIDGLIDERID:VH-WUE
     * HFDTM100GPSDATUM:WGS84
     * HFRFWFIRMWAREVERSION:3.6
     * HFRHWHARDWAREVERSION:3.4
     * HFFTYFR TYPE:GARRECHT INGENIEURGESELLSCHAFT,VOLKSLOGGER 1.0
     * HFCIDCOMPETITIONID:WUE
     * HFCCLCOMPETITIONCLASS:FAI
     */

    assert(date_time.Plausible());
    assert(logger_id != NULL);
    assert(strlen(logger_id) == 3);

    char buffer[100];

    // Flight recorder ID number MUST go first..
    sprintf(buffer, "AXCS%s", logger_id);
    WriteLine(buffer);

    sprintf(buffer, "HFDTE%02u%02u%02u",
            date_time.day, date_time.month, date_time.year % 100);
    WriteLine(buffer);

    if (!simulator)
        WriteLine(GetHFFXARecord());

    WriteLine("HFPLTPILOT:", pilot_name);
    WriteLine("HFGTYGLIDERTYPE:", aircraft_model);
    WriteLine("HFGIDGLIDERID:", aircraft_registration);
    WriteLine("HFCIDCOMPETITIONID:", competition_id);
    WriteLine("HFFTYFRTYPE:XCSOAR,XCSOAR ", XCSoar_VersionStringOld);
    WriteLine("HFGPS:", driver_name);

    WriteLine("HFDTM100DATUM:WGS-84");

    WriteLine(GetIRecord());
}
Esempio n. 10
0
bool
NMEALogger::Start()
{
  if (writer != nullptr)
    return true;

  BrokenDateTime dt = BrokenDateTime::NowUTC();
  assert(dt.IsPlausible());

  StaticString<64> name;
  name.Format(_T("%04u-%02u-%02u_%02u-%02u.nmea"),
              dt.year, dt.month, dt.day,
              dt.hour, dt.minute);

  TCHAR path[MAX_PATH];
  LocalPath(path, _T("logs"));
  Directory::Create(path);

  LocalPath(path, _T("logs"), name);

  writer = new TextWriter(path, false);
  return writer != nullptr;
}
Esempio n. 11
0
static void
WriteEventAttributes(TextWriter &writer,
                     const BrokenDateTime &time, const GeoPoint &location)
{
  JSON::ObjectWriter object(writer);

  if (time.IsPlausible()) {
    NarrowString<64> buffer;
    FormatISO8601(buffer.buffer(), time);
    object.WriteElement("time", JSON::WriteString, buffer);
  }

  if (location.IsValid())
    JSON::WriteGeoPointAttributes(object, location);
}
Esempio n. 12
0
void
FormatIGCTaskTimestamp(char *buffer, const BrokenDateTime &date_time,
                       unsigned number_of_turnpoints)
{
  assert(date_time.IsPlausible());

  sprintf(buffer, "C%02u%02u%02u%02u%02u%02u0000000000%02u",
          // DD  MM  YY  HH  MM  SS  DD  MM  YY IIII TT
          date_time.day,
          date_time.month,
          date_time.year % 100,
          date_time.hour,
          date_time.minute,
          date_time.second,
          number_of_turnpoints - 2);
}
Esempio n. 13
0
Angle
SunEphemeris::CalcAzimuth(const GeoPoint &location,
                          const BrokenDateTime &date_time,
                          const fixed time_zone)
{
  assert(date_time.Plausible());

  fixed days_to_j2000 = FNday(date_time);

  Angle l = GetMeanSunLongitude(days_to_j2000);

  // Use GetEclipticLongitude to find the ecliptic longitude of the Sun
  Angle lambda = GetEclipticLongitude(days_to_j2000, l);

  // Obliquity of the ecliptic
  Angle obliquity = Angle::Degrees(fixed(23.439) - fixed(.0000004) * days_to_j2000);

  // Find the DEC of the Sun
  Angle delta = Angle::asin(obliquity.sin() * lambda.sin());

  return CalculateAzimuth(location, date_time, time_zone, delta);
}
Esempio n. 14
0
void
IGCWriter::StartDeclaration(const BrokenDateTime &date_time,
                            const int number_of_turnpoints)
{
    assert(date_time.Plausible());

    // IGC GNSS specification 3.6.1
    char buffer[100];
    sprintf(buffer, "C%02u%02u%02u%02u%02u%02u0000000000%02d",
            // DD  MM  YY  HH  MM  SS  DD  MM  YY IIII TT
            date_time.day,
            date_time.month,
            date_time.year % 100,
            date_time.hour,
            date_time.minute,
            date_time.second,
            number_of_turnpoints - 2);

    WriteLine(buffer);

    // takeoff line
    // IGC GNSS specification 3.6.3
    WriteLine("C0000000N00000000ETAKEOFF");
}
Esempio n. 15
0
int
BrokenDateTime::operator-(const BrokenDateTime &other) const
{
  return ToUnixTimeUTC() - other.ToUnixTimeUTC();
}
Esempio n. 16
0
SunEphemeris::Result
SunEphemeris::CalcSunTimes(const GeoPoint &location,
                           const BrokenDateTime &date_time,
                           const fixed time_zone)
{
  Result result;

  assert(date_time.Plausible());

  fixed days_to_j2000 = FNday(date_time);

  Angle l = GetMeanSunLongitude(days_to_j2000);

  // Use GetEclipticLongitude to find the ecliptic longitude of the Sun
  Angle lambda = GetEclipticLongitude(days_to_j2000, l);

  // Obliquity of the ecliptic
  Angle obliquity = Angle::Degrees(fixed(23.439) - fixed(.0000004) * days_to_j2000);

  // Find the RA and DEC of the Sun
  Angle alpha = Angle::FromXY(lambda.cos(), obliquity.cos() * lambda.sin());
  Angle delta = Angle::asin(obliquity.sin() * lambda.sin());

  // Find the Equation of Time in minutes
  // Correction suggested by David Smith
  fixed ll = (l - alpha).Radians();
  if (l.Radians() < fixed_pi)
    ll += fixed_two_pi;

  fixed equation = fixed(1440) * (fixed(1) - ll / fixed_two_pi);

  Angle hour_angle = GetHourAngle(location.latitude, delta);
  Angle hour_angle_twilight = GetHourAngleTwilight(location.latitude, delta);

  result.azimuth = CalculateAzimuth(location, date_time, time_zone, delta);

  // length of twilight in hours
  fixed twilight_hours = (hour_angle_twilight - hour_angle).Hours();

  // Conversion of angle to hours and minutes
  result.day_length = Double(hour_angle.Hours());

  if (result.day_length < fixed(0.0001))
    // arctic winter
    result.day_length = fixed(0);

  result.time_of_sunrise = fixed(12) - hour_angle.Hours() + time_zone
    - location.longitude.Degrees() / 15 + equation / 60;

  if (result.time_of_sunrise > fixed(24))
    result.time_of_sunrise -= fixed(24);

  result.time_of_sunset = result.time_of_sunrise + result.day_length;
  result.time_of_noon = result.time_of_sunrise + hour_angle.Hours();

  // morning twilight begin
  result.morning_twilight = result.time_of_sunrise - twilight_hours;
  // evening twilight end
  result.evening_twilight = result.time_of_sunset + twilight_hours;

  return result;
}
Esempio n. 17
0
void
Run(DebugReplay &replay, FlightPhaseDetector &flight_phase_detector,
    WindList &wind_list,
    const BrokenDateTime &takeoff_time,
    const BrokenDateTime &scoring_start_time,
    const BrokenDateTime &scoring_end_time,
    const BrokenDateTime &landing_time,
    Trace &full_trace, Trace &triangle_trace, Trace &sprint_trace,
    ComputerSettings &computer_settings)
{
    GeoPoint last_location = GeoPoint::Invalid();
    constexpr Angle max_longitude_change = Angle::Degrees(30);
    constexpr Angle max_latitude_change = Angle::Degrees(1);

    CirclingSettings circling_settings;
    circling_settings.SetDefaults();
    CirclingComputer circling_computer;
    circling_computer.Reset();

    GlidePolar glide_polar(0);

    WindSettings wind_settings;
    wind_settings.SetDefaults();

    WindComputer wind_computer;
    wind_computer.Reset();

    Validity last_wind;
    last_wind.Clear();

    const Waypoints waypoints;
    AutoQNH auto_qnh(5);
    auto_qnh.Reset();

    const int64_t takeoff_unix = takeoff_time.ToUnixTimeUTC();
    const int64_t landing_unix = landing_time.ToUnixTimeUTC();


    int64_t scoring_start_unix, scoring_end_unix;

    if (scoring_start_time.IsPlausible())
        scoring_start_unix = scoring_start_time.ToUnixTimeUTC();
    else
        scoring_start_unix = std::numeric_limits<int64_t>::max();

    if (scoring_end_time.IsPlausible())
        scoring_end_unix = scoring_end_time.ToUnixTimeUTC();
    else
        scoring_end_unix = 0;


    while (replay.Next()) {
        const MoreData &basic = replay.Basic();
        const int64_t date_time_utc = basic.date_time_utc.ToUnixTimeUTC();

        if (date_time_utc < takeoff_unix)
            continue;

        if (date_time_utc > landing_unix)
            break;

        circling_computer.TurnRate(replay.SetCalculated(),
                                   replay.Basic(),
                                   replay.Calculated().flight);
        circling_computer.Turning(replay.SetCalculated(),
                                  replay.Basic(),
                                  replay.Calculated().flight,
                                  circling_settings);

        flight_phase_detector.Update(replay.Basic(), replay.Calculated());

        wind_computer.Compute(wind_settings, glide_polar, basic,
                              replay.SetCalculated());

        if (replay.Calculated().estimated_wind_available.Modified(last_wind)) {
            wind_list.push_back(WindListItem(basic.date_time_utc, basic.gps_altitude,
                                             replay.Calculated().estimated_wind));
        }

        last_wind = replay.Calculated().estimated_wind_available;

        auto_qnh.Process(basic, replay.SetCalculated(), computer_settings, waypoints);

        if (!computer_settings.pressure_available && replay.Calculated().pressure_available) {
            computer_settings.pressure = replay.Calculated().pressure;
            computer_settings.pressure_available = replay.Calculated().pressure_available;
        }

        if (!basic.time_available || !basic.location_available ||
                !basic.NavAltitudeAvailable())
            continue;

        if (last_location.IsValid() &&
                ((last_location.latitude - basic.location.latitude).Absolute() > max_latitude_change ||
                 (last_location.longitude - basic.location.longitude).Absolute() > max_longitude_change))
            /* there was an implausible warp, which is usually triggered by
               an invalid point declared "valid" by a bugged logger; if that
               happens, we stop the analysis, because the IGC file is
               obviously broken */
            break;

        last_location = basic.location;

        if (date_time_utc >= scoring_start_unix && date_time_utc <= scoring_end_unix) {
            const TracePoint point(basic);
            full_trace.push_back(point);
            triangle_trace.push_back(point);
            sprint_trace.push_back(point);
        }
    }

    flight_phase_detector.Finish();
}