Example #1
0
void
IGCWriter::LogPoint(const NMEAInfo& gps_info)
{
    if (!last_valid_point_initialized &&
            ((gps_info.gps_altitude < fixed(-100))
             || (gps_info.baro_altitude < fixed(-100))
             || !gps_info.location_available))
        return;

    IGCFix fix;
    if (!gps_info.location_available) {
        fix = last_valid_point;
        fix.gps_valid = false;
    } else {
        fix.gps_valid = true;
        fix.location = gps_info.location;
        fix.gps_altitude = (int)gps_info.gps_altitude;

        // save last active fix location
        last_valid_point = fix;
        last_valid_point_initialized = true;
    }

    fix.time = gps_info.date_time_utc;
    fix.pressure_altitude =
        gps_info.baro_altitude_available ? (int)gps_info.baro_altitude :
        /* fall back to GPS altitude */
        fix.gps_altitude;

    LogPoint(fix, (int)GetEPE(gps_info.gps), GetSIU(gps_info.gps));
}
Example #2
0
void
IGCWriter::LogEvent(const NMEAInfo &gps_info, const char *event)
{
    LogEvent(gps_info.date_time_utc, event);

    // tech_spec_gnss.pdf says we need a B record immediately after an E record
    LogPoint(gps_info);
}
Example #3
0
void
IGCWriter::LogEvent(const IGCFix &fix, int epe, int satellites,
                    const char *event)
{
    LogEvent(fix.time, event);

    // tech_spec_gnss.pdf says we need a B record immediately after an E record
    LogPoint(fix, epe, satellites);
}
Example #4
0
void
IGCWriter::LogEvent(const NMEA_INFO &gps_info, const char *event)
{
  char szBRecord[30];
  sprintf(szBRecord,"E%02d%02d%02d%s",
          gps_info.DateTime.hour, gps_info.DateTime.minute,
          gps_info.DateTime.second, event);

  writeln(szBRecord);
  // tech_spec_gnss.pdf says we need a B record immediately after an E record
  LogPoint(gps_info);
}
Example #5
0
//
// Logger activity, and also add snailpoints
//
void DoLogging(NMEA_INFO *Basic, DERIVED_INFO *Calculated) {

  static double SnailLastTime=0;
  static double LogLastTime=0;
  static double StatsLastTime=0;
  static short maxerrlog=30;

  // prevent bad fixes from being logged or added to OLC store
  static double Time_last=0;
  static double Longitude_last = 10;
  static double Latitude_last = 10;
  static double Longitude_snailed = 10;
  static double Latitude_snailed = 10;

  double dtLog = 5.0;
  double dtSnail = 2.0;
  double dtStats = 60.0;

  #if LOGFRECORD
  double dtFRecord = 270; // 4.5 minutes (required minimum every 5)
  #endif

  if (DoInit[MDI_CALCLOGGING]) {
	SnailLastTime=0;
	LogLastTime=0;
	StatsLastTime=0;
	maxerrlog=30;
	Time_last=0;
	Longitude_last = 10;
	Latitude_last = 10;
	Longitude_snailed = 10;
	Latitude_snailed = 10;
	DoInit[MDI_CALCLOGGING]=false;
  }

  if (Basic->NAVWarning) return;

  if(Basic->Time <= LogLastTime) {
    LogLastTime = Basic->Time;
  }
  if(Basic->Time <= SnailLastTime)  {
    SnailLastTime = Basic->Time;
  }
  if(Basic->Time <= StatsLastTime) {
    StatsLastTime = Basic->Time;
  }
  #if LOGFRECORD
  if(Basic->Time <= GetFRecordLastTime()) {
    SetFRecordLastTime(Basic->Time);
  }
  #endif

  // draw snail points more often in circling mode
  if (Calculated->Circling) {
    dtLog = LoggerTimeStepCircling;
    dtSnail = 1.0;
  } else {
    dtLog = LoggerTimeStepCruise;
    dtSnail = 5.0;
  }
  if (FastLogNum) {
    dtLog = 1.0;
  }

  double distance;

  DistanceBearing(Basic->Latitude, Basic->Longitude, 
		  Latitude_last, Longitude_last,
		  &distance, NULL);

  // Do not log or add a snail point if in a single second we made more than 300m. (1000kmh)
  // This should allow loggin and snail logging also while using LK on a liner for fun.
  // This filter is necessary for managing wrong position fixes by the gps
  // Until 3.1f it was set to 200m
  double timepassed=Basic->Time - Time_last;
  if (Time_last==0) timepassed=0; // skip check

  // Now we can save values, because we want to compare fix after fix. If we really jumped away,
  // we shall accept this fact after the second fix far away.
  Latitude_last = Basic->Latitude;
  Longitude_last = Basic->Longitude;
  Time_last=Basic->Time;

  if (timepassed>0 && ((distance/timepassed)>300.0) ) {
	if (maxerrlog>0) {
		StartupStore(_T("... DoLogging: at %s distance jumped too much, %f in %fs!\n"),WhatTimeIsIt(),distance,timepassed);
		maxerrlog--;
	}
	return;
  }

  Latitude_last = Basic->Latitude;
  Longitude_last = Basic->Longitude;
  Time_last=Basic->Time;

  //
  // If time has advanced enough, add point to IGC
  //
  if (Basic->Time - LogLastTime >= dtLog) {
    double balt = -1;
    if (Basic->BaroAltitudeAvailable) {
      balt = AltitudeToQNEAltitude(Basic->BaroAltitude);
      // check for balt validity are NOT performed in logpoint functions anymore
      if (balt<-1000||balt>15000) balt=Basic->BaroAltitude;
    } else {
      balt = 0;
    }

    // 110723 this is not a solution, only a workaround.
    // Problem is that different threads are using indirectly IGCWrite in Logger.cpp
    // That function as an internal sort-of locking, which probably may be much better
    // to remove, resulting currently in data loss inside IGC.
    // Since at takeoff calculation and main thread are using IGCWrite, we want to be sure
    // that the initial declaration is completed before proceeding with F and B records here!
    if (IGCWriteLock) {
	unsigned short loop=0;
	while (++loop<50) {
		Sleep(10); //  500 ms delay max
		if (!IGCWriteLock) break;
	}
	if (IGCWriteLock) {
		if (maxerrlog>0) StartupStore(_T("..... LogPoint failed, IGCWriteLock %s!%s"),WhatTimeIsIt(),NEWLINE);
	} else {
		if (maxerrlog>0) StartupStore(_T("..... LogPoint delayed by IGCWriteLock, ok.%s"),NEWLINE);
		LogPoint(Basic->Latitude , Basic->Longitude , Basic->Altitude, balt);
	}
	maxerrlog--;
    } else
	LogPoint(Basic->Latitude , Basic->Longitude , Basic->Altitude, balt);

    // Remarks: LogPoint is also checking that there is a valid fix to proceed

    LogLastTime += dtLog;
    if (LogLastTime< Basic->Time-dtLog) {
      LogLastTime = Basic->Time-dtLog;
    }
    if (FastLogNum) FastLogNum--;
  } // time has advanced enough: >=dtLog

  #if LOGFRECORD
  if (Basic->Time - GetFRecordLastTime() >= dtFRecord) 
  { 
    if (LogFRecord(Basic->SatelliteIDs,false))
    {  // need F record every 5 minutes
       // so if write fails or constellation is invalid, don't update timer and try again next cycle
      SetFRecordLastTime(GetFRecordLastTime() + dtFRecord);  
      // the FRecordLastTime is reset when the logger restarts so it is always at the start of the file
      if (GetFRecordLastTime() < Basic->Time-dtFRecord)
        SetFRecordLastTime(Basic->Time-dtFRecord);
    }
  }
  #endif

  // 120812 For car/trekking mode, log snailpoint only if at least 5m were made in the dtSnail time
  if (ISCAR) {

	// if 5 seconds have passed.. (no circling mode in car mode)
	if ( (Basic->Time - SnailLastTime) >= dtSnail) {
		DistanceBearing(Basic->Latitude, Basic->Longitude, Latitude_snailed, Longitude_snailed, &distance, NULL);
		// and distance made is at least 5m (moving average 3.6kmh)
		if (distance>5) {
			AddSnailPoint(Basic, Calculated);
			SnailLastTime += dtSnail;
			if (SnailLastTime< Basic->Time-dtSnail) {
				SnailLastTime = Basic->Time-dtSnail;
			}
			Latitude_snailed = Basic->Latitude;
			Longitude_snailed = Basic->Longitude;
		}
	}
	// else do not log, and do not update snailtime, so we shall be here every second until at least 10m are made
	goto _afteriscar;
  }

  if (Basic->Time - SnailLastTime >= dtSnail) {
    AddSnailPoint(Basic, Calculated);
    SnailLastTime += dtSnail;
    if (SnailLastTime< Basic->Time-dtSnail) {
      SnailLastTime = Basic->Time-dtSnail;
    }
  }

_afteriscar:

  if (Calculated->Flying) {
    if (Basic->Time - StatsLastTime >= dtStats) {

      flightstats.Altitude_Terrain.
        least_squares_update(max(0.0,
                                 Basic->Time-Calculated->TakeOffTime)/3600.0, 
                             Calculated->TerrainAlt);

      flightstats.Altitude.
        least_squares_update(max(0.0,
                                 Basic->Time-Calculated->TakeOffTime)/3600.0, 
                             Calculated->NavAltitude);
      StatsLastTime += dtStats;
      if (StatsLastTime< Basic->Time-dtStats) {
        StatsLastTime = Basic->Time-dtStats;
      }
    }

    if(UseContestEngine() && Calculated->FreeFlying)
      CContestMgr::Instance().Add(new CPointGPS(static_cast<unsigned>(Basic->Time),
                                                Basic->Latitude, Basic->Longitude,
                                                static_cast<unsigned>(Basic->Altitude)));
  }
}