Exemplo n.º 1
0
bool GiveBatteryWarnings(void)
{
  static bool toomany=false;
  static double last_time=0;

  // If last warning was issued more than 60 minutes ago, reset toomany.
  if (GPS_INFO.Time>(last_time+3600)) {
	#if TESTBENCH
	if (last_time>0 && numwarn>0) 
		StartupStore(_T("... GiveBatteryWarnings resetting at %s\n"),WhatTimeIsIt(),NEWLINE);
	#endif
	toomany=false;
	numwarn=0;
  }

  if (toomany) return false;

  numwarn++;

  if (numwarn>MAXBATTWARN) {
	// LKTOKEN _@M1357_ "BATTERY WARNINGS DISABLED"
	DoStatusMessage(gettext(TEXT("_@M1357_")));
	StartupStore(_T("... Too many battery warnings, disabling Battery Manager at %s%s"),WhatTimeIsIt(),NEWLINE);
	toomany=true;
	return false;
  }
  last_time=GPS_INFO.Time;
  return true;
}
Exemplo n.º 2
0
void SystemConfiguration(short mode) {
  if (!SIMMODE) {
	if (LockSettingsInFlight && CALCULATED_INFO.Flying) {
		DoStatusMessage(TEXT("Settings locked in flight"));
		return;
	}
  }

  #if TESTBENCH
  StartupStore(_T("... SETTINGS enter @%s\n"),WhatTimeIsIt());
  #endif
  SettingsEnter();
  dlgConfigurationShowModal(mode);
  #if TESTBENCH
  StartupStore(_T("... SETTINGS leave @%s\n"),WhatTimeIsIt());
  #endif
  SettingsLeave();
}
Exemplo n.º 3
0
//
// Master Time Reset
// This function is called when a valid GPS time (or a time taken from an IGC replay log)
// is verified to be gone back in time, or more than 2 hours have passed since last GPS
// fix was received.
// This is normally happening when the device was switched off and back on some time later.
// What we might do, is disable logging, resetting some functions etc.
// But this is happening also after switching ON a PNA with no time battery, and thus a full reset.
// Time is appearing as 1/1/2000 12:00am , some times. So we only log the event.
//
void MasterTimeReset(void) {

  StartupStore(_T("... Master Time Reset %s%s"), WhatTimeIsIt(),NEWLINE);
  #if TESTBENCH
  DoStatusMessage(_T("MASTER TIME RESET")); // no translation please
  #endif

  // Remember to lock anything needed to be locked

}
Exemplo n.º 4
0
//
// Master Time Reset -- only for diagnostics in TESTBENCH mode
//
// This function is called when a valid GPS time (or a time taken from an IGC replay log)
// is verified to be gone back in time.
// This was normally happening when the device was switched off and back on some time later, until 3.1f.
// Now the time in LK is advancing also considering the date through a full year, 
// so it is unlikely to happen after a valid fix.
//
// But this can also happen  after switching ON a PNA with no time battery, and thus a full reset.
// Time is appearing as 1/1/2000 12:00am , some times. So we only log the event.
//
// It can also happen when two gps feed are mixed through a multiplexer providing two gps fix at the same time,
// one of them 1 second late. Very bad indeed.
//
// What we might do, is disable logging, resetting some functions etc.
//
void MasterTimeReset(void) {
#if TESTBENCH
  static bool silent=false;

  //
  // We want to avoid the single situation: no gps fix, PNA awaken with old time,
  // and still no gps fix. In this case, we would get several resets, and we only
  // give one until the fix is received again. At that time, time will advance normally
  // and we shall not remain stuck in mastertimereset state.
  //

  // No fix, and silent = no warning.
  if (GPS_INFO.NAVWarning && silent) {
	StartupStore(_T("... (silent!) Master Time Reset %s%s"), WhatTimeIsIt(),NEWLINE);
	return;
  }

  if (GPS_INFO.NAVWarning && !silent) {
	StartupStore(_T("... Master Time Reset going silent, no fix! %s%s"), WhatTimeIsIt(),NEWLINE);
	silent=true;
  } else
	silent=false; // arm it 

  StartupStore(_T("... Master Time Reset %s%s"), WhatTimeIsIt(),NEWLINE);
  DoStatusMessage(_T("MASTER TIME RESET")); // no translation please

  // Future possible handlings of this exception:
  // . Battery manager
  // . Trip computer

  // Remember to lock anything needed to be locked
#else
  static unsigned short count=0;
  if (count>9) return;
  if (GPS_INFO.NAVWarning) return;
  count++;
  StartupStore(_T("... Master Time Reset %s%s"), WhatTimeIsIt(),NEWLINE);
  DoStatusMessage(_T("MASTER TIME RESET")); // no translation please
#endif // MasterTimeReset
}
Exemplo n.º 5
0
BOOL PVCOMInstall(PDeviceDescriptor_t d){

  _tcscpy(d->Name, TEXT("PVCOM"));
  d->IsRadio = PVCOMIsRadio;
  d->PutVolume = PVCOMPutVolume;
  d->PutSquelch = PVCOMPutSquelch;
  d->PutFreqActive = PVCOMPutFreqActive;
  d->PutFreqStandby = PVCOMPutFreqStandby;
  d->StationSwap = PVCOMStationSwap;
  d->ParseNMEA    = PVCOMParseString;
  d->PutRadioMode    = PVCOMRadioMode;
  StartupStore(_T(". PVCOMInstall %s%s"), WhatTimeIsIt(),NEWLINE);
  return(TRUE);

}
Exemplo n.º 6
0
void WndMain::OnTimer() {
    // WM_TIMER is run at about 2hz.
    LKHearthBeats++; // 100213
    if (ProgramStarted > psInitInProgress) {
        if (SIMMODE) {
            SIMProcessTimer();
        } else {
            ProcessTimer();
        }
        if (ProgramStarted == psFirstDrawDone) {
            AfterStartup();
            ProgramStarted = psNormalOp;
            StartupStore(_T(". ProgramStarted=NormalOp %s%s"), WhatTimeIsIt(), NEWLINE);
            StartupLogFreeRamAndStorage();
        }
    }
}
Exemplo n.º 7
0
void Shutdown(void) {
  int i;

  // LKTOKEN _@M1219_ "Shutdown, please wait..."
  CreateProgressDialog(gettext(TEXT("_@M1219_")));

  LKSound(_T("LK_DISCONNECT.WAV")); Poco::Thread::sleep(500); // real WAV length is 410+ms
  if (!GlobalRunning) { // shutdown on startup (before sim/fly or clicking on the window X)
	StartupStore(_T(". Quick shutdown requested before terminating startup%s"),NEWLINE);
	// force exit mode for the case of being in welcome screen: OnTimerNotify will catch it
	RUN_MODE=RUN_SHUTDOWN;
	CloseCalculations();
	CloseGeoid();
	DeInitCustomHardware();
	LKRunStartEnd(false);
	return;
  }

  StartupStore(_T(". Entering shutdown %s%s"), WhatTimeIsIt(),NEWLINE);
  MapWindow::Event_Pan(0);  // return from PAN restores the Task in case of Turnpoint moving
  #if TESTBENCH
  StartupLogFreeRamAndStorage();
  #endif

  // turn off all displays
  GlobalRunning = false;

  // LKTOKEN _@M1220_ "Shutdown, saving logs..."
  CreateProgressDialog(gettext(TEXT("_@M1220_")));

  // In case we quit while are still flying
  UpdateLogBook(false); // false=only log if still flying
  // stop logger
  guiStopLogger(true);

  // LKTOKEN _@M1221_ "Shutdown, saving profile..."
  CreateProgressDialog(gettext(TEXT("_@M1221_")));
  extern void LKAircraftSave(const TCHAR *szFile);
  extern void LKPilotSave(const TCHAR *szFile);
  extern void LKDeviceSave(const TCHAR *szFile);
  LKPilotSave(defaultPilotFile);
  LKAircraftSave(defaultAircraftFile);
  LKProfileSave(defaultProfileFile);
  LKDeviceSave(defaultDeviceFile);

  #if TESTBENCH
  StartupStore(TEXT(". Save_Recent_WP_history%s"),NEWLINE);
  #endif
  SaveRecentList();
  // Stop sound

  // Stop drawing
  // LKTOKEN _@M1219_ "Shutdown, please wait..."
  CreateProgressDialog(gettext(TEXT("_@M1219_")));
 
  // 100526 this is creating problem in SIM mode when quit is called from X button, and we are in waypoint details
  // or probably in other menu related screens. However it cannot happen from real PNA or PDA because we don't have
  // that X button.
  MapWindow::CloseDrawingThread();

  // Stop calculating too (wake up)
  dataTriggerEvent.set();
  drawTriggerEvent.set();

  // Clear data
  // LKTOKEN _@M1222_ "Shutdown, saving task..."
  CreateProgressDialog(gettext(TEXT("_@M1222_")));

  #if TESTBENCH
  StartupStore(TEXT(".... Save default task%s"),NEWLINE);
  #endif

  SaveDefaultTask();

  #if TESTBENCH
  StartupStore(TEXT(".... Clear task data%s"),NEWLINE);
  #endif

  LockTaskData();
  Task[0].Index = -1;  ActiveWayPoint = -1; 
  AATEnabled = FALSE;
  CloseWayPoints();
  UnlockTaskData();

  // LKTOKEN _@M1219_ "Shutdown, please wait..."
  CreateProgressDialog(gettext(TEXT("_@M1219_")));
  #if TESTBENCH
  StartupStore(TEXT(".... CloseTerrainTopology%s"),NEWLINE);
  #endif

  RasterTerrain::CloseTerrain();

  CloseTopology();
  #if USETOPOMARKS
  TopologyCloseMarks();
  #endif
  CloseTerrainRenderer();

  LiveTrackerShutdown();

#ifndef NO_DATARECORDER
  CloseFlightDataRecorder();
#endif  
  // Stop COM devices
  StartupStore(TEXT(". Stop COM devices%s"),NEWLINE);
  devCloseAll();

  CloseFLARMDetails();

  ProgramStarted = psInitInProgress;

  // Kill windows
  #if TESTBENCH
  StartupStore(TEXT(".... Close Messages%s"),NEWLINE);
  #endif
  Message::Destroy();
  #if TESTBENCH 
  StartupStore(TEXT(".... Destroy Button Labels%s"),NEWLINE);
  #endif
  ButtonLabel::Destroy();

  #if TESTBENCH
  StartupStore(TEXT(".... Delete Objects%s"),NEWLINE);
  #endif
  
  // Kill graphics objects

  #ifdef LXMINIMAP
  hBrushButtonHasFocus.Release();
  #endif

  CAirspaceManager::Instance().CloseAirspaces();
  #if TESTBENCH
  StartupStore(TEXT(".... Delete Critical Sections%s"),NEWLINE);
  #endif

  // Wait end of Calculation thread before deinit critical section.
  WaitThreadCalculation();

  #if TESTBENCH
  StartupStore(TEXT(".... Close Progress Dialog%s"),NEWLINE);
  #endif
  CloseProgressDialog();
  #if TESTBENCH
  StartupStore(TEXT(".... Close Calculations%s"),NEWLINE);
  #endif
  CloseCalculations();

  CloseGeoid();
  DeInitCustomHardware();

  #if TESTBENCH
  StartupStore(TEXT(".... Close Windows%s"),NEWLINE);
  #endif

  #if TESTBENCH
  StartupLogFreeRamAndStorage();
  #endif
  for (i=0;i<NUMDEV;i++) {
	if (ComPortStatus[i]!=0) {
		StartupStore(_T(". ComPort %d: status=%d Rx=%ld Tx=%ld ErrRx=%ld + ErrTx=%ld (==%ld)%s"), i,
		ComPortStatus[i], ComPortRx[i],ComPortTx[i], ComPortErrRx[i],ComPortErrTx[i],ComPortErrors[i],NEWLINE);
	}
  }
  StartupStore(_T(". Finished shutdown %s%s"), WhatTimeIsIt(),NEWLINE);
  LKRunStartEnd(false);

#ifdef DEBUG
  TCHAR foop[80];
  TASK_POINT wp;
  TASK_POINT *wpr = &wp;
  _stprintf(foop,TEXT(". Sizes %d %d %d%s"),
	    sizeof(TASK_POINT), 
	    ((long)&wpr->AATTargetLocked)-((long)wpr),
	    ((long)&wpr->Target)-((long)wpr), NEWLINE
	    );
  StartupStore(foop);
#endif
  StartupStore(_T("Destroy MainWindow" NEWLINE));
  MainWindow.Destroy();
}
Exemplo n.º 8
0
void Turning(NMEA_INFO *Basic, DERIVED_INFO *Calculated)
{
  static double LastTrack = 0;
  static double StartTime  = 0;
  static double StartLong = 0;
  static double StartLat = 0;
  static double StartAlt = 0;
  static double StartEnergyHeight = 0;
  static double LastTime = 0;
  static int MODE = CRUISE;
  static bool LEFT = FALSE;
  double Rate;
  static double LastRate=0;
  double dRate;
  double dT;

  if (!Calculated->Flying) {
	if (MODE!=CRUISE) {
		#if TESTBENCH
		StartupStore(_T(".... Not flying, still circling -> Cruise forced!\n"));
		#endif
		goto _forcereset;
	}
	return;
  }

  // Back in time in IGC replay mode?
  if(Basic->Time <= LastTime) {
    #if TESTBENCH
    StartupStore(_T("...... Turning check is back in time. Now=%f Last=%f: reset %s\n"),Basic->Time, LastTime,WhatTimeIsIt());
    #endif
_forcereset:
    LastTime = Basic->Time; // 101216 PV not sure of this.. 
    LastTrack = 0;
    StartTime  = 0;
    StartLong = 0;
    StartLat = 0;
    StartAlt = 0;
    StartEnergyHeight = 0;
    LastTime = 0;
    LEFT = FALSE;
    if (MODE!=CRUISE) {
	MODE = CRUISE;
        // Finally do the transition to cruise
        Calculated->Circling = false;
        SwitchZoomClimb(Basic, Calculated, false, LEFT);
        InputEvents::processGlideComputer(GCE_FLIGHTMODE_CRUISE);
    }
    return;
  }
  dT = Basic->Time - LastTime;
  LastTime = Basic->Time;

  #if BUGSTOP
  LKASSERT(dT!=0);
  #else
  if (dT==0) dT=1;
  #endif

  Rate = AngleLimit180(Basic->TrackBearing-LastTrack)/dT;

  #if DEBUGTURN
  StartupStore(_T("... Rate=%f  in time=%f\n"),Rate,dT);
  #endif

  if (dT<2.0 && dT!=0) {
    // time step ok

    // calculate acceleration
    dRate = (Rate-LastRate)/dT;

    double dtlead=0.3;
    // integrate assuming constant acceleration, for one second
    Calculated->NextTrackBearing = Basic->TrackBearing
      + dtlead*(Rate+0.5*dtlead*dRate);
    // s = u.t+ 0.5*a*t*t

    Calculated->NextTrackBearing = 
      AngleLimit360(Calculated->NextTrackBearing);
    
  } else {
    // time step too big, so just take it at last measurement
    Calculated->NextTrackBearing = Basic->TrackBearing;
  }

  Calculated->TurnRate = Rate;

  // JMW limit rate to 50 deg per second otherwise a big spike
  // will cause spurious lock on circling for a long time
  if (Rate>50) {
    Rate = 50;
  } 
  if (Rate<-50) {
    Rate = -50;
  }

  // average rate, to detect essing
  static double rate_history[60];
  double rate_ave=0;
  for (int i=59; i>0; i--) {
    rate_history[i] = rate_history[i-1];
    rate_ave += rate_history[i];
  }
  rate_history[0] = Rate;
  rate_ave /= 60;
 
  // THIS IS UNUSED in 4.0 
  Calculated->Essing = fabs(rate_ave)*100/MinTurnRate;

  if (MODE==CLIMB||MODE==WAITCRUISE)
	Rate = LowPassFilter(LastRate,Rate,0.9);
  else
	Rate = LowPassFilter(LastRate,Rate,0.3);

  LastRate = Rate;

  if(Rate <0)
    {
      if (LEFT) {
        // OK, already going left
      } else {
        LEFT = true;
      }
      Rate *= -1;
    } else {
    if (!LEFT) {
      // OK, already going right
    } else {
      LEFT = false;
    }
  }

  PercentCircling(Basic, Calculated, Rate);

  LastTrack = Basic->TrackBearing;

  bool forcecruise = false;
  bool forcecircling = false;

  #if 1 // UNUSED, EnableExternalTriggerCruise not configurable, set to false since ever
  if (EnableExternalTriggerCruise ) {
    if (ExternalTriggerCruise && ExternalTriggerCircling) {
      // this should never happen
      ExternalTriggerCircling = false;
    }
    forcecruise = ExternalTriggerCruise;
    forcecircling = ExternalTriggerCircling;
  }
  #endif

  switch(MODE) {
  case CRUISE:

    double cruise_turnthreshold;
    if (ISPARAGLIDER)
	cruise_turnthreshold=5;
    else
	cruise_turnthreshold=4;

    if((Rate >= cruise_turnthreshold)||(forcecircling)) {
      // This is initialising the potential thermalling start
      // We still dont know if we are really circling for thermal
      StartTime = Basic->Time;
      StartLong = Basic->Longitude;
      StartLat  = Basic->Latitude;
      StartAlt  = Calculated->NavAltitude;
      StartEnergyHeight  = Calculated->EnergyHeight;
      #if DEBUGTURN
      StartupStore(_T("... CRUISE -> WAITCLIMB\n"));
      #endif
      MODE = WAITCLIMB;
    }
    if (forcecircling) {
      MODE = WAITCLIMB;
    } else {
      break;
    }
  case WAITCLIMB:
    if (forcecruise) {
      MODE = CRUISE;
      break;
    }

    double waitclimb_turnthreshold;
    double cruiseclimbswitch;
    if (ISPARAGLIDER) {
	waitclimb_turnthreshold=5;
        cruiseclimbswitch=15; // this should be finetuned for PGs
    } else {
	waitclimb_turnthreshold=4;
        cruiseclimbswitch=15; // this is ok for gliders
    }

    if((Rate >= waitclimb_turnthreshold)||(forcecircling)) {
      // WE CANNOT do this, because we also may need Circling mode to detect FF!!
      // if( (Calculated->FreeFlying && ((Basic->Time  - StartTime) > cruiseclimbswitch))|| forcecircling) {
       if( (!ISCAR && !ISGAAIRCRAFT && ((Basic->Time  - StartTime) > cruiseclimbswitch))|| forcecircling) { 

         #ifdef TOW_CRUISE
         // If free flight (FF) hasn�t yet been detected, then we may
         // still be on tow.  The following prevents climb mode from
         // engaging due to normal on-aerotow turns.

         if (!Calculated->FreeFlying && (fabs(Calculated->TurnRate) < 12))
           break;
         #endif

         #if DEBUGTURN
         StartupStore(_T("... WAITCLIMB -> CLIMB\n"));
         #endif
       Calculated->Circling = true;
        // JMW Transition to climb
        MODE = CLIMB;
	// Probably a replay flight, with fast forward with no cruise init
	if (StartTime==0) {
	      StartTime = Basic->Time;
	      StartLong = Basic->Longitude;
	      StartLat  = Basic->Latitude;
	      StartAlt  = Calculated->NavAltitude;
	      StartEnergyHeight  = Calculated->EnergyHeight;
	}
        Calculated->ClimbStartLat = StartLat;
        Calculated->ClimbStartLong = StartLong;
        Calculated->ClimbStartAlt = StartAlt+StartEnergyHeight;
        Calculated->ClimbStartTime = StartTime;
        
        if (flightstats.Altitude_Ceiling.sum_n>0) {
          // only update base if have already climbed, otherwise
          // we will catch the takeoff height as the base.

          flightstats.Altitude_Base.
            least_squares_update(max(0.0, Calculated->ClimbStartTime
                                     - Calculated->TakeOffTime)/3600.0,
                                 StartAlt);
        }
        
        SwitchZoomClimb(Basic, Calculated, true, LEFT);
        InputEvents::processGlideComputer(GCE_FLIGHTMODE_CLIMB);
      }
    } else {
      // nope, not turning, so go back to cruise
      #if DEBUGTURN
      StartupStore(_T("... WAITCLIMB -> CRUISE\n"));
      #endif
      MODE = CRUISE;
    }
    break;
  case CLIMB:
    if ( (AutoWindMode == D_AUTOWIND_CIRCLING) || (AutoWindMode==D_AUTOWIND_BOTHCIRCZAG) ) {
      LockFlightData();
      windanalyser->slot_newSample(Basic, Calculated);
      UnlockFlightData();
    }

    double climb_turnthreshold;
    if (ISPARAGLIDER)
	climb_turnthreshold=10;
    else
	climb_turnthreshold=4;
    
    if((Rate < climb_turnthreshold)||(forcecruise)) {
      StartTime = Basic->Time;
      StartLong = Basic->Longitude;
      StartLat  = Basic->Latitude;
      StartAlt  = Calculated->NavAltitude;
      StartEnergyHeight  = Calculated->EnergyHeight;
      // JMW Transition to cruise, due to not properly turning
      MODE = WAITCRUISE;
      #if DEBUGTURN
      StartupStore(_T("... CLIMB -> WAITCRUISE\n"));
      #endif
    }
    if (forcecruise) {
      MODE = WAITCRUISE;
    } else {
      break;
    }
  case WAITCRUISE:

    if (forcecircling) {
      MODE = CLIMB;
      break;
    }

    double waitcruise_turnthreshold;
    double climbcruiseswitch;
    if (ISPARAGLIDER) {
	waitcruise_turnthreshold=10;
        climbcruiseswitch=15;
    } else {
	waitcruise_turnthreshold=4;
        climbcruiseswitch=9; // ok for gliders
    }
    //
    // Exiting climb mode?
    //
    if((Rate < waitcruise_turnthreshold) || forcecruise) {

      if( ((Basic->Time  - StartTime) > climbcruiseswitch) || forcecruise) {

	// We are no more in climb mode

        if (StartTime==0) {
          StartTime = Basic->Time;
          StartLong = Basic->Longitude;
          StartLat  = Basic->Latitude;
          StartAlt  = Calculated->NavAltitude;
          StartEnergyHeight  = Calculated->EnergyHeight;
        }
        Calculated->CruiseStartLat  = StartLat;
        Calculated->CruiseStartLong = StartLong;
        Calculated->CruiseStartAlt  = StartAlt;
        Calculated->CruiseStartTime = StartTime;

	// Here we assign automatically this last thermal to the L> multitarget
	if (Calculated->ThermalGain >100) {

		// Force immediate calculation of average thermal, it would be made
		// during next cycle, but we need it here immediately
		AverageThermal(Basic,Calculated);

		if (EnableThermalLocator) {
			InsertThermalHistory(Calculated->ClimbStartTime, 
				Calculated->ThermalEstimate_Latitude, Calculated->ThermalEstimate_Longitude,
				Calculated->ClimbStartAlt, Calculated->NavAltitude, Calculated->AverageThermal);
		} else {
			InsertThermalHistory(Calculated->ClimbStartTime, 
				Calculated->ClimbStartLat, Calculated->ClimbStartLong, 
				Calculated->ClimbStartAlt, Calculated->NavAltitude, Calculated->AverageThermal);
		}

	}

	InitLDRotary(&rotaryLD);
	InitWindRotary(&rotaryWind);
        
        flightstats.Altitude_Ceiling.
          least_squares_update(max(0.0, Calculated->CruiseStartTime
                                   - Calculated->TakeOffTime)/3600.0,
                               Calculated->CruiseStartAlt);
        
        // Finally do the transition to cruise
        Calculated->Circling = false;
        MODE = CRUISE;
        #if DEBUGTURN
        StartupStore(_T("... WAITCRUISE -> CRUISE\n"));
        #endif
        SwitchZoomClimb(Basic, Calculated, false, LEFT);
        InputEvents::processGlideComputer(GCE_FLIGHTMODE_CRUISE);

      } // climbcruiseswitch time in range

    } else { // Rate>Minturnrate, back to climb, turning again
      #if DEBUGTURN
      StartupStore(_T("... WAITCRUISE -> CLIMB\n"));
      #endif
      MODE = CLIMB;
    }
    break;
  default:
    // error, go to cruise
    MODE = CRUISE;
  }
  // generate new wind vector if altitude changes or a new
  // estimate is available
  if (AutoWindMode>D_AUTOWIND_MANUAL && AutoWindMode <D_AUTOWIND_EXTERNAL) {
    LockFlightData();
    windanalyser->slot_Altitude(Basic, Calculated);
    UnlockFlightData();
  }

  if (EnableThermalLocator) {
    if (Calculated->Circling) {
      thermallocator.AddPoint(Basic->Time, Basic->Longitude, Basic->Latitude,
			      Calculated->NettoVario);
      thermallocator.Update(Basic->Time, Basic->Longitude, Basic->Latitude,
			    Calculated->WindSpeed, Calculated->WindBearing,
			    Basic->TrackBearing,
			    &Calculated->ThermalEstimate_Longitude,
			    &Calculated->ThermalEstimate_Latitude,
			    &Calculated->ThermalEstimate_W,
			    &Calculated->ThermalEstimate_R);
    } else {
      Calculated->ThermalEstimate_W = 0;
      Calculated->ThermalEstimate_R = -1;
      thermallocator.Reset();
    }
  }

  // update atmospheric model
  CuSonde::updateMeasurements(Basic, Calculated);

}
Exemplo n.º 9
0
//
// Called by LD  in Calc thread
//
void InsertLDRotary(ldrotary_s *buf, double distance, NMEA_INFO *Basic, DERIVED_INFO *Calculated) {
static unsigned short errs=0;
#ifdef TESTBENCH
static bool zeroerrs=true;
#endif
#ifdef DEBUG_ROTARY
char ventabuffer[200];
FILE *fp;
#endif
	if (LKSW_ResetLDRotary) {
		#if TESTBENCH
		StartupStore(_T("... LD ROTARY SWITCH RESET @%s%s"),WhatTimeIsIt(),NEWLINE);
		#endif
		LKSW_ResetLDRotary=false;
		InitLDRotary(&rotaryLD);
	}

        // For IGC Replay, we are never OnGround, see Calc/TakeoffLanding.cpp
	if (Calculated->OnGround) {
#ifdef DEBUG_ROTARY
		sprintf(ventabuffer,"OnGround, ignore LDrotary\r\n");
		if ((fp=fopen("DEBUG.TXT","a"))!= NULL)
			    {;fprintf(fp,"%s\n",ventabuffer);fclose(fp);}
#endif
		return;
	}

	if (ISCAR) {
		goto _noautoreset;
	}

	if (Calculated->Circling) {
#ifdef DEBUG_ROTARY
		sprintf(ventabuffer,"Circling, ignore LDrotary\r\n");
		if ((fp=fopen("DEBUG.TXT","a"))!= NULL)
			    {;fprintf(fp,"%s\n",ventabuffer);fclose(fp);}
#endif
		return;
	}

	if (distance<3 || distance>150) { // just ignore, no need to reset rotary
                #ifdef TESTBENCH
                if (distance==0 && zeroerrs) {
                   StartupStore(_T("... InsertLDRotary distance error=%f @%s%s"),distance,WhatTimeIsIt(),NEWLINE);
                   zeroerrs=false;
                }
                #endif
		if (errs==9) {
#ifdef DEBUG_ROTARY
			sprintf(ventabuffer,"Rotary reset after exceeding errors\r\n");
			if ((fp=fopen("DEBUG.TXT","a"))!= NULL)
				    {;fprintf(fp,"%s\n",ventabuffer);fclose(fp);}
#endif
			#if TESTBENCH
			StartupStore(_T("... LDROTARY RESET, distance errors%s"),NEWLINE);
			#endif
			InitLDRotary(&rotaryLD);
			errs=10; // an no more here until errs reset with valid data
			return;

		}
		if (errs<9) errs++;  // make it up to 9
#ifdef DEBUG_ROTARY
		sprintf(ventabuffer,"(errs=%d) IGNORE INVALID distance=%d altitude=%d\r\n",errs,(int)(distance),(int)(Calculated->NavAltitude));
		if ((fp=fopen("DEBUG.TXT","a"))!= NULL)
			    {;fprintf(fp,"%s\n",ventabuffer);fclose(fp);}
#endif
		return;
	}
	errs=0;
        #ifdef TESTBENCH
        zeroerrs=true;
        #endif

_noautoreset:

    if((buf->start) < -1) {
        #if BUGSTOP
        LKASSERT(buf->start==-2);
        #endif
        // this is the first run after reset,
        // save NavAltitude for calculate in AltDiff next run
        // and return;
        buf->start=-1;
        buf->prevaltitude = iround(Calculated->NavAltitude*100);
        return;
    }

    int diffAlt = buf->prevaltitude - iround(Calculated->NavAltitude*100);
    buf->prevaltitude = iround(Calculated->NavAltitude*100);

	if (++buf->start >=buf->size) {
#ifdef DEBUG_ROTARY
		sprintf(ventabuffer,"*** rotary reset and VALID=TRUE ++bufstart=%d >=bufsize=%d\r\n",buf->start, buf->size);
		if ((fp=fopen("DEBUG.TXT","a"))!= NULL)
			    {;fprintf(fp,"%s\n",ventabuffer);fclose(fp);}
#endif
		buf->start=0;
		buf->valid=true; // flag for a full usable buffer
	}
        LKASSERT(buf->start>=0 && buf->start<MAXLDROTARYSIZE);
        if (buf->start<0 ||buf->start>=MAXLDROTARYSIZE) buf->start=0; // UNMANAGED RECOVERY!
	// need to fill up buffer before starting to empty it
	if ( buf->valid == true) {
		buf->totaldistance-=buf->distance[buf->start];
		buf->totalaltitude-=buf->altitude[buf->start];

		buf->totalias-=buf->ias[buf->start];
	}
	buf->totaldistance+=iround(distance*100);
	buf->distance[buf->start]=iround(distance*100);

    buf->totalaltitude+=diffAlt;
	buf->altitude[buf->start]=diffAlt;

	// insert IAS in the rotary buffer, either real or estimated
	if (Basic->AirspeedAvailable) {
                buf->totalias += (int)(Basic->IndicatedAirspeed*100);
                buf->ias[buf->start] = (int)(Basic->IndicatedAirspeed*100);
	} else {
		if (ISCAR) {
			buf->totalias += (int)(Basic->Speed*100);
			buf->ias[buf->start] = (int)(Basic->Speed*100);
		} else {
			buf->totalias += (int)(Calculated->IndicatedAirspeedEstimated*100);
			buf->ias[buf->start] = (int)(Calculated->IndicatedAirspeedEstimated*100);
		}
	}
#ifdef DEBUG_ROTARY
	sprintf(ventabuffer,"insert buf[%d/%d], distance=%d totdist=%d\r\n",buf->start, buf->size-1, buf->distance[buf->start], buf->totaldistance);
	if ((fp=fopen("DEBUG.TXT","a"))!= NULL)
		    {;fprintf(fp,"%s\n",ventabuffer);fclose(fp);}
#endif
}
Exemplo n.º 10
0
//
// Run every 5 seconds, approx.
// This is the hearth of LK. Questions? Ask Paolo..
// THIS IS RUNNING WITH LockComm  from ConnectionProcessTimer .
//
void NMEAParser::UpdateMonitor(void) 
{
  short active=0; // active port number for gps
  static short lastactive=0;
  static bool  lastvalidBaro=false;
  static bool wasSilent[2]={false,false};
  short invalidGps=0;
  short invalidBaro=0;
  short validBaro=0; 

  // does anyone have GPS?
  if (nmeaParser1.gpsValid || nmeaParser2.gpsValid) {
	if (nmeaParser1.gpsValid && nmeaParser2.gpsValid) {
		// both valid, just use first
		nmeaParser2.activeGPS = false;
		nmeaParser1.activeGPS = true;
		active=1;
	} else {
		// only one valid, pick it up
		nmeaParser1.activeGPS = nmeaParser1.gpsValid;
		nmeaParser2.activeGPS = nmeaParser2.gpsValid;
		active= nmeaParser1.activeGPS ? 1 : 2;
	}
  } else {
	// No valid fix on any port. We use the first port with at least some data going through!
	// This will keep probably at least the time updated since the gps may still be receiving a 
	// valid time, good for us.
	if ( (LKHearthBeats-ComPortHB[0])<10 ) {
		// It is not granted that devA is really a GPS source.
		// Very unlikely, but possible..
		if (devIsGPSSource(devA())) active=1;
	} else {
		if ( (LKHearthBeats-ComPortHB[1])<10 ) {
			// portB is really active, although there is no valid fix on it.
			// Before electing it to gps, lets be sure it really has one!
			// LKEXT1 and other instruments do not provide GPS source in fact.
			if (devIsGPSSource(devB())) active=2;
		} else {
			// nothing coming in from any port, recently.
			if (devIsGPSSource(devA())) active=1;	// lets keep waiting for the first port
		}
	}

	switch(active) {
		case 0:
			nmeaParser1.activeGPS = false;
			nmeaParser2.activeGPS = false;
			break;
		case 1:
			nmeaParser1.activeGPS = true;
			nmeaParser2.activeGPS = false;
			break;
		case 2:
			nmeaParser1.activeGPS = false;
			nmeaParser2.activeGPS = true;
			break;
		default:
			nmeaParser1.activeGPS = false;
			nmeaParser2.activeGPS = false;
			LKASSERT(0);
			break;
	}
  }


  if (nmeaParser2.activeGPS==true && active==1) {
	StartupStore(_T(".... GPS Update error: port 1 and 2 are active! %s%s"),WhatTimeIsIt(),NEWLINE);
	nmeaParser2.activeGPS=false; // force it off
	active=1; 
  }

  // wait for some seconds before monitoring, after startup
  if (LKHearthBeats<20) return;

  /* check if Flarm disappeared after 30 seconds no activity */
  if (GPS_INFO.FLARM_Available && ((GPS_INFO.Time -LastFlarmCommandTime)> 30) )
  {
	static unsigned short MessageCnt =0;
	if(MessageCnt <10)
	{
		MessageCnt++;
		StartupStore(_T(". FLARM lost! Disable FLARM functions !%s"),NEWLINE);
		DoStatusMessage(gettext(TEXT("_@M947_"))); // _@M947_ "FLARM SIGNAL LOST"
	}
	GPS_INFO.FLARM_Available = false;
	GPS_INFO.FLARM_HW_Version =0.0;
	GPS_INFO.FLARM_SW_Version =0.0;
  }

  // Check Port 1 with no serial activity in last seconds
  if ( (LKHearthBeats-ComPortHB[0])>10 ) {
	#ifdef DEBUGNPM
	StartupStore(_T("... GPS Port 1 : no activity LKHB=%u CBHB=%u %s"),LKHearthBeats, ComPortHB[0],NEWLINE);
	#endif
	// if this is active and supposed to have a valid fix.., but no HB..
	if ( (active==1) && (nmeaParser1.gpsValid) ) {
		StartupStore(_T("... GPS Port 1 no hearthbeats, but still gpsValid: forced invalid  %s%s"),WhatTimeIsIt(),NEWLINE);
	}
	nmeaParser1.gpsValid=false;
	invalidGps=1;
	// We want to be sure that if this device is silent, and it was providing Baro altitude,
	// now it is set to off.
	if (GPS_INFO.BaroAltitudeAvailable==TRUE) {
		if ( devA() == pDevPrimaryBaroSource || nmeaParser1.RMZAvailable 
		  || nmeaParser1.TASAvailable ) {
			invalidBaro=1;
		}
	}
	nmeaParser1._Reset();
	nmeaParser1.activeGPS=false; // because Reset is setting it to true
	// We reset some flags globally only once in case of device gone silent 
	if (!devIsDisabled(0) && !wasSilent[0]) {
		GPS_INFO.AirspeedAvailable=false;
		GPS_INFO.VarioAvailable=false;
		GPS_INFO.NettoVarioAvailable=false;
		GPS_INFO.AccelerationAvailable = false;
		EnableExternalTriggerCruise = false;
		wasSilent[0]=true;
	}
  } else {
	wasSilent[0]=false;
	// We have hearth beats, is baro available?
	if ( devIsBaroSource(devA()) || nmeaParser1.RMZAvailable || nmeaParser1.TASAvailable ) // 100411
		validBaro++;
  }
  // now check also port 2
  if ( (LKHearthBeats-ComPortHB[1])>10 ) {
	#ifdef DEBUGNPM
	StartupStore(_T("... GPS Port 2 : no activity LKHB=%u CBHB=%u %s"),LKHearthBeats, ComPortHB[1],NEWLINE);
	#endif
	if ( (active==2) && (nmeaParser2.gpsValid) ) {
		StartupStore(_T("... GPS port 2 no hearthbeats, but still gpsValid: forced invalid  %s%s"),WhatTimeIsIt(),NEWLINE);
	}
	nmeaParser2.gpsValid=false;
	invalidGps++;
	if (GPS_INFO.BaroAltitudeAvailable==TRUE) {
		if ( devB() == pDevPrimaryBaroSource || nmeaParser2.RMZAvailable 
		  || nmeaParser2.TASAvailable ) {
			invalidBaro++;
		}
	}
	nmeaParser2._Reset();
	nmeaParser2.activeGPS=false; // because Reset is setting it to true
	if (!devIsDisabled(1) && !wasSilent[1]) {
		GPS_INFO.AirspeedAvailable=false;
		GPS_INFO.VarioAvailable=false;
		GPS_INFO.NettoVarioAvailable=false;
		GPS_INFO.AccelerationAvailable = false;
		EnableExternalTriggerCruise = false;
		wasSilent[1]=true;
	}
  } else {
	wasSilent[1]=false;
	// We have hearth beats, is baro available?
	if ( devIsBaroSource(devB()) || nmeaParser2.RMZAvailable || nmeaParser2.TASAvailable   )  // 100411
		validBaro++;
  }

  #ifdef DEBUGNPM
  if (invalidGps==2) {
	StartupStore(_T("... GPS no gpsValid available on port 1 and 2, active=%d @%s%s"),active,WhatTimeIsIt(),NEWLINE);
  }
  if (invalidBaro>0) {
	StartupStore(_T("... Baro altitude just lost, current status=%d @%s%s"),GPS_INFO.BaroAltitudeAvailable,WhatTimeIsIt(),NEWLINE);
  }
  #endif


  // do we really still have a baro altitude available?
  // If some baro source disappeared, let's reset it for safety. Parser will re-enable them immediately if available.
  // Assuming here that if no Baro is available, no airdata is available also
  //
  if (validBaro==0) {
	if ( GPS_INFO.BaroAltitudeAvailable ) {
		StartupStore(_T("... GPS no active baro source, and still BaroAltitudeAvailable, forced off  %s%s"),WhatTimeIsIt(),NEWLINE);
		if (EnableNavBaroAltitude && active) {
			// LKTOKEN  _@M122_ = "BARO ALTITUDE NOT AVAILABLE, USING GPS ALTITUDE" 
			DoStatusMessage(MsgToken(122));
			PortMonitorMessages++;
		} else {
			// LKTOKEN  _@M121_ = "BARO ALTITUDE NOT AVAILABLE" 
			DoStatusMessage(MsgToken(121));
		}
		GPS_INFO.BaroAltitudeAvailable=FALSE;
		// We alse reset these values, just in case we are through a mux
		GPS_INFO.AirspeedAvailable=false;
		GPS_INFO.VarioAvailable=false;
		GPS_INFO.NettoVarioAvailable=false;
		GPS_INFO.AccelerationAvailable = false;
		EnableExternalTriggerCruise = false;
		nmeaParser1._Reset();
		nmeaParser2._Reset();
		// 120824 Check this situation better> Reset is setting activeGPS true for both devices!
		lastvalidBaro=false;
	}
  } else {
	if ( lastvalidBaro==false) {
		#if DEBUGBARO
		TCHAR devname[50];
		if (pDevPrimaryBaroSource) {
			LK_tcsncpy(devname,pDevPrimaryBaroSource->Name,49);
		} else {
			_tcscpy(devname,_T("unknown"));
		}
		StartupStore(_T("... GPS baro source back available from <%s>%s"),devname,NEWLINE);
		#endif

		if (GotFirstBaroAltitude) {
			if (EnableNavBaroAltitude) {
				DoStatusMessage(MsgToken(1796)); // USING BARO ALTITUDE
			} else {
				DoStatusMessage(MsgToken(1795)); // BARO ALTITUDE IS AVAILABLE
			}
			StartupStore(_T("... GPS baro source back available %s%s"),WhatTimeIsIt(),NEWLINE);
			lastvalidBaro=true;
		} else {
			static bool said=false;
			if (!said) {
				StartupStore(_T("... GPS BARO SOURCE PROBLEM, umnanaged port activity. Wrong device? %s%s"),WhatTimeIsIt(),NEWLINE);
				said=true;
			}
		}
	} 
	else {
		// last baro was Ok, currently we still have a validbaro, but no HBs...
		// Probably it is a special case when no gps fix was found on the secondary baro source.
		if (invalidBaro||!GotFirstBaroAltitude) {
			GPS_INFO.BaroAltitudeAvailable=FALSE;
			#ifdef DEBUGNPM
			StartupStore(_T(".... We still have valid baro, resetting BaroAltitude OFF %s\n"),WhatTimeIsIt());
			#endif
		}
	}
  }

  // Very important check for multiplexers: if RMZ did not get through in the past seconds, we want to
  // be very sure that there still is one incoming, otherwise we shall be UpdatingBaroSource using the old one,
  // never really updated!! This is because GGA and RMC are using RMZAvailable to UpdateBaroSource, no matter if
  // there was a real RMZ in the NMEA stream lately.
  // Normally RMZAvailable, RMCAvailable, GGA etc.etc. are reset to false when the com port is silent.
  // But RMZ is special, because it can be sent through the multiplexer from a flarm box.
  if ( (nmeaParser1.RMZAvailable || nmeaParser2.RMZAvailable) && (LKHearthBeats > (LastRMZHB+5))) {
	#if DEBUGBARO
	StartupStore(_T(".... RMZ not updated recently, resetting HB\n"));
	#endif
	nmeaParser1.RMZAvailable = FALSE;
	nmeaParser2.RMZAvailable = FALSE;
  }

  // Check baro altitude problems. This can happen for several reasons: mixed input on baro on same port,
  // faulty device, etc. The important thing is that we shall not be using baro altitude for navigation in such cases.
  // So we do this check only for the case we are actually using baro altitude.
  // A typical case is: mixed devices on same port, baro altitude disappearing because of mechanical switch,
  // but other traffic still incoming, so hearthbeats are ok. 
  static double	lastBaroAltitude=-1, lastGPSAltitude=-1;
  static unsigned int	counterSameBaro=0, counterSameHGPS=0;
  static unsigned short firstrecovery=0;
  if (GPS_INFO.BaroAltitudeAvailable && EnableNavBaroAltitude && !GPS_INFO.NAVWarning) {
	if (GPS_INFO.BaroAltitude==lastBaroAltitude) {
		counterSameBaro++;
	} else {
		lastBaroAltitude=GPS_INFO.BaroAltitude;
		counterSameBaro=0;
	}
	if (GPS_INFO.Altitude==lastGPSAltitude) {
		counterSameHGPS++;
	} else {
		lastGPSAltitude=GPS_INFO.Altitude;
		counterSameHGPS=0;
	}

	// This is suspicious enough, because the baro altitude is a floating value, should not be the same..
	// but ok, lets assume it is filtered.
	// if HBAR is steady for some time ... and HGPS is not steady 
	unsigned short timethreshold=15; // first three times,  timeout at about 1 minute
	if (firstrecovery>=3) timethreshold=40; // then about every 3 minutes
		
	if ( ((counterSameBaro > timethreshold) && (counterSameHGPS<2)) && (fabs(GPS_INFO.Altitude-GPS_INFO.BaroAltitude)>100.0) && !CALCULATED_INFO.OnGround ) {
			DoStatusMessage(MsgToken(122)); // Baro not available, Using GPS ALTITUDE
			EnableNavBaroAltitude=false;
			StartupStore(_T("... WARNING, NavBaroAltitude DISABLED due to possible fault: baro steady at %f, HGPS=%f @%s%s"),
			GPS_INFO.BaroAltitude, GPS_INFO.Altitude,WhatTimeIsIt(),NEWLINE);
			lastBaroAltitude=-1;
			lastGPSAltitude=-1;
			counterSameBaro=0;
			counterSameHGPS=0;
			// We do only ONE attempt to recover a faulty device, to avoid flipflopping.
			// In case of big problems, we shall have disabled the use of the faulty baro altitude, and keep it
			// incoming sporadically.
			if (firstrecovery<3) {
				GPS_INFO.BaroAltitudeAvailable=FALSE;
				// We alse reset these values, just in case we are through a mux
				GPS_INFO.AirspeedAvailable=false;
				GPS_INFO.VarioAvailable=false;
				GPS_INFO.NettoVarioAvailable=false;
				GPS_INFO.AccelerationAvailable = false;
				EnableExternalTriggerCruise = false;
				nmeaParser1._Reset();
				nmeaParser2._Reset();
				// 120824 Check this situation better> Reset is setting activeGPS true for both devices!
				lastvalidBaro=false;
				GotFirstBaroAltitude=false;
				firstrecovery++;
			}
	}
  }


  // Set some fine tuning parameters here, depending on device/situation/mode
  if (ISCAR)
	trackbearingminspeed=0; // trekking mode/car mode, min speed >0
  else
	trackbearingminspeed=1; // flymode,  min speed >1 knot

  //
  // Following is for diagnostics only
  //

  // Nothing has changed? No need to give new alerts. We might have no active gps at all, also.
  // In this case, active and lastactive are 0, nothing we can do about it.
  if (active == lastactive) return;

  if (active!=0)
	StartupStore(_T(". GPS NMEA source changed to port %d  %s%s"),active,WhatTimeIsIt(),NEWLINE);
  else
	StartupStore(_T("... GPS NMEA source PROBLEM, no active GPS!  %s%s"),WhatTimeIsIt(),NEWLINE);


  if (PortMonitorMessages<15) { // do not overload pilot with messages!
	// do not say anything if we never got the first port, on startup essentially
	if ((lastactive!=0) && (nmeaParser1.gpsValid || nmeaParser2.gpsValid)){
		TCHAR vbuf[100];
		_stprintf(vbuf,_T("%s %d"), MsgToken(277),active); // FALLBACK USING GPS ON PORT ..
		DoStatusMessage(vbuf);
		PortMonitorMessages++;
	} 
  } else {
	if (PortMonitorMessages==15) { 
		StartupStore(_T("... GOING SILENT on too many Com reportings.  %s%s"),WhatTimeIsIt(),NEWLINE);
		DoStatusMessage(MsgToken(317)); // GOING SILENT ON COM REPORTING
		PortMonitorMessages++;	// we go to 16, and never be back here
	}
  }

  lastactive=active;

}
Exemplo n.º 11
0
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  long wdata;

  switch (message)
    {

    case WM_ERASEBKGND:
      return TRUE; // JMW trying to reduce screen flicker
      break;
    case WM_COMMAND:
      return MainMenu(hWnd, message, wParam, lParam);
      break;
    case WM_CTLCOLORSTATIC:
      wdata = GetWindowLong((HWND)lParam, GWL_USERDATA);
      switch(wdata) {
      case 0:
        SetBkColor((HDC)wParam, ColorUnselected);
        SetTextColor((HDC)wParam, RGB(0x00,0x00,0x00));
        return (LRESULT)hBrushUnselected;
      case 1:
        SetBkColor((HDC)wParam, ColorSelected);
        SetTextColor((HDC)wParam, RGB(0x00,0x00,0x00));
        return (LRESULT)hBrushSelected;
      case 2:
	SetBkColor((HDC)wParam, ColorUnselected);
        SetTextColor((HDC)wParam, ColorWarning);
	return (LRESULT)hBrushUnselected;
      case 3:
	SetBkColor((HDC)wParam, ColorUnselected);
        SetTextColor((HDC)wParam, ColorOK);
	return (LRESULT)hBrushUnselected;
      case 4:
	// black on light green
        SetTextColor((HDC)wParam, RGB_BLACK); 
	SetBkColor((HDC)wParam, ColorButton);
	return (LRESULT)hBrushButton;
      case 5:
	// grey on light green
	SetBkColor((HDC)wParam, ColorButton);
        SetTextColor((HDC)wParam, RGB(0x80,0x80,0x80));
	return (LRESULT)hBrushButton;
#ifdef LXMINIMAP
      case 6:
        // black on dark yellow
        SetTextColor((HDC)wParam, RGB_BLACK);
        SetBkColor((HDC)wParam, ColorButtonHasFocus);
        return (LRESULT)hBrushButtonHasFocus;
      case 7:
        // grey on dark yellow
        SetTextColor((HDC)wParam, RGB(0x80,0x80,0x80));
        SetBkColor((HDC)wParam, ColorButtonHasFocus);
        return (LRESULT)hBrushButtonHasFocus;
#endif

      }
      break;
    case WM_CREATE:
#ifdef HAVE_ACTIVATE_INFO
      memset (&s_sai, 0, sizeof (s_sai));
      s_sai.cbSize = sizeof (s_sai);
#endif
      if (iTimerID == 0) {
        iTimerID = SetTimer(hWnd,1000,500,NULL); // 500ms  2 times per second
      }

      break;

    case WM_ACTIVATE:

      if(LOWORD(wParam) != WA_INACTIVE)
        {
          SetWindowPos(hWndMainWindow,HWND_TOP,
                 0, 0, 0, 0,
                 SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOSIZE);

#ifdef HAVE_ACTIVATE_INFO
         SHFullScreen(hWndMainWindow,SHFS_HIDETASKBAR|SHFS_HIDESIPBUTTON|SHFS_HIDESTARTICON);
#endif

        }
#ifdef HAVE_ACTIVATE_INFO
      if (api_has_SHHandleWMActivate) {
        SHHandleWMActivate(hWnd, wParam, lParam, &s_sai, FALSE);
      } else {
        #ifdef TESTBENCH
        StartupStore(TEXT("... SHHandleWMActivate not available%s"),NEWLINE);
        #endif
        return DefWindowProc(hWnd, message, wParam, lParam);
      }
#endif
      break;

    case WM_SETTINGCHANGE:
#ifdef HAVE_ACTIVATE_INFO
      if (api_has_SHHandleWMSettingChange) {
        SHHandleWMSettingChange(hWnd, wParam, lParam, &s_sai);
      } else {
        #ifdef TESTBENCH
        StartupStore(TEXT("... SHHandleWMSettingChange not available%s"),NEWLINE);
        #endif
        return DefWindowProc(hWnd, message, wParam, lParam);
      }
#endif
      break;

	#if DEBUG_FOCUS
    case WM_KILLFOCUS:
	// This is happening when focus is given to another window, either internally inside LK
	// or externally, for example to explorer..
	// SO: if we select MapWindow, we get here a KILLFOCUS from it.
	// When we select another process/program, or click on the desktop, the old window having focus is
	// receiving KILLFOCUS. So in case MapWindow was working, the signal will be sent over there, not here.
	// 
	StartupStore(_T("............ WNDPROC LOST FOCUS (KILLFOCUS)\n"));
	break;
	#endif

    case WM_SETFOCUS:
	// When explorer/desktop is giving focus to LK, this is where we get the signal.
	// But we must return focus to previous windows otherwise keys will not be working.
	// Mouse is another story, because mouse click is pertinent to a screen area which is mapped.
	// A mouse click will be sent to the window in the background, whose handler will receive the event.
	//
	// Each event handler receiving focus has to save it in hWndWithFocus, in LK.
	// Each event handler must thus handle SETFOCUS!
	//
	#if DEBUG_FOCUS
	StartupStore(_T("............ WNDPROC HAS FOCUS  (SETFOCUS)\n"));
	if (hWndWithFocus==NULL)
		StartupStore(_T(".....(no Wnd to give focus to)\n"));
	else
		StartupStore(_T(".....(passing focus to other window)\n"));
	#endif
	if (hWndWithFocus!=NULL) SetFocus(hWndWithFocus);
      break;

    case WM_KEYUP:
      break;

    case WM_TIMER:
	// WM_TIMER is run at about 2hz.
	LKHearthBeats++; // 100213
      //      ASSERT(hWnd==hWndMainWindow);
      if (ProgramStarted > psInitInProgress) {
	if (SIMMODE)
		SIMProcessTimer();
	else
		ProcessTimer();
	if (ProgramStarted==psFirstDrawDone) {
	  AfterStartup();
	  ProgramStarted = psNormalOp;
          StartupStore(_T(". ProgramStarted=NormalOp %s%s"), WhatTimeIsIt(),NEWLINE);
          StartupLogFreeRamAndStorage();

	}
      }
      break;

    case WM_INITMENUPOPUP:
      if (ProgramStarted > psInitInProgress) {
	  CheckMenuItem((HMENU) wParam,IDM_FILE_LOCK,MF_CHECKED|MF_BYCOMMAND);
	
	if(LoggerActive)
	  CheckMenuItem((HMENU) wParam,IDM_FILE_LOGGER,MF_CHECKED|MF_BYCOMMAND);
	else
	  CheckMenuItem((HMENU) wParam,IDM_FILE_LOGGER,MF_UNCHECKED|MF_BYCOMMAND);
      }
      break;

    case WM_CLOSE:

      LKASSERT(hWnd==hWndMainWindow);
      if((hWnd==hWndMainWindow) && 
         (MessageBoxX(hWndMainWindow,
		// LKTOKEN  _@M198_ = "Confirm Exit?"
               	gettext(TEXT("_@M198_")),
                      TEXT("LK8000"),
                      MB_YESNO|MB_ICONQUESTION) == IDYES)) 
        {
          if(iTimerID) {
            KillTimer(hWnd,iTimerID);
            iTimerID = 0;
          }

          Shutdown();
        }
      break;

    case WM_DESTROY:
      if (hWnd==hWndMainWindow) {
        PostQuitMessage(0);
      }
      break;

#ifdef PNA
#if TESTBENCH
    case WM_DEVICECHANGE:
	 TCHAR serr[50];
	 static WPARAM oldwparam=0;
	 StartupStore(_T("DEVICE CHANGE DETECTED, CODE=0x%x%s"),wParam,NEWLINE);

	 if (wParam!=oldwparam) {
		 oldwparam=wParam;
	 	wsprintf(serr,_T("DEVICE CHANGE DETECTED\nCODE=0x%x"),wParam);
		DoStatusMessage(serr);
        	 // MessageBoxX(hWndMainWindow, serr, TEXT("LK8000"), MB_OK|MB_ICONQUESTION, true);
		 oldwparam=0;
	 }
	 return TRUE; // acknowledge
	 break;
#endif
#endif

    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
    }
  return 0;
}
Exemplo n.º 12
0
BOOL NMEAParser::RMC(TCHAR *String, TCHAR **params, size_t nparams, NMEA_INFO *pGPS)
{
  TCHAR *Stop;
  static bool logbaddate=true;
  double speed=0;

  gpsValid = !NAVWarn(params[1][0]);

  GPSCONNECT = TRUE;    
  RMCAvailable=true; // 100409

  #ifdef PNA
  if (DeviceIsGM130) {

	double ps = GM130BarPressure();
	RMZAltitude = (1 - pow(fabs(ps / QNH),  0.190284)) * 44307.69;
	// StartupStore(_T("....... Pressure=%.0f QNH=%.2f Altitude=%.1f\n"),ps,QNH,RMZAltitude);

	RMZAvailable = TRUE;

	UpdateBaroSource(pGPS, BARO__GM130, NULL,   RMZAltitude);
  }
  if (DeviceIsRoyaltek3200) {
	if (Royaltek3200_ReadBarData()) {
		double ps = Royaltek3200_GetPressure();
		RMZAltitude = (1 - pow(fabs(ps / QNH),  0.190284)) * 44307.69;

		#if 0
		pGPS->TemperatureAvailable=true;
		pGPS->OutsideAirTemperature = Royaltek3200_GetTemperature();
		#endif
	}

	RMZAvailable = TRUE;

	UpdateBaroSource(pGPS, BARO__ROYALTEK3200,  NULL,  RMZAltitude);

  }
  #endif // PNA

  if (!activeGPS) {
	// Before ignoring anything else, commit RMZ altitude otherwise it will be ignored!
	if(RMZAvailable) {
		UpdateBaroSource(pGPS, isFlarm? BARO__RMZ_FLARM:BARO__RMZ, NULL, RMZAltitude);
	}
	return TRUE;
  }

  // if no valid fix, we dont get speed either!
  if (gpsValid)
  {
	// speed is in knots, 2 = 3.7kmh
	speed = StrToDouble(params[6], NULL);
  }
  
  pGPS->NAVWarning = !gpsValid;

  // say we are updated every time we get this,
  // so infoboxes get refreshed if GPS connected
  // the RMC sentence marks the start of a new fix, so we force the old data to be saved for calculations
        // note that Condor sends no date..
        if ((_tcslen(params[8]) <6) && !DevIsCondor) {
		#if TESTBENCH
		StartupStore(_T(".... RMC date field empty, skip sentence!\n"));
		#endif
		return TRUE;
	}

	// Even with no valid position, we let RMC set the time and date if valid
	long gy, gm, gd;
	gy = _tcstol(&params[8][4], &Stop, 10) + 2000;   
	params[8][4] = '\0';
	gm = _tcstol(&params[8][2], &Stop, 10); 
	params[8][2] = '\0';
	gd = _tcstol(&params[8][0], &Stop, 10); 

	// SeeYou PC is sending NMEA sentences with RMC date 2072-02-27
	if ( ((gy > 1980) && (gy <2100) ) && (gm != 0) && (gd != 0) ) { 
		pGPS->Year = gy;
		pGPS->Month = gm;
		pGPS->Day = gd;

force_advance:
		RMCtime = StrToDouble(params[0],NULL);
#ifndef OLD_TIME_MODIFY
		double ThisTime = TimeModify(params[0], pGPS, StartDay);
#else
		double ThisTime = TimeModify(RMCtime, pGPS);
#endif
		// RMC time has priority on GGA and GLL etc. so if we have it we use it at once
		if (!TimeHasAdvanced(ThisTime, pGPS)) {
			#if DEBUGSEQ
			StartupStore(_T("..... RMC time not advanced, skipping \n")); // 31C
			#endif
			return FALSE;
		}
			
	}  else {
		if (DevIsCondor) {
			#if DEBUGSEQ
			StartupStore(_T(".. Condor not sending valid date, using 1.1.2012%s"),NEWLINE);
			#endif
			gy=2012; gm=1; gd=1;
			goto force_advance;
		}

		if (gpsValid && logbaddate) { // 091115
			StartupStore(_T("------ NMEAParser:RMC Receiving an invalid or null DATE from GPS%s"),NEWLINE);
			StartupStore(_T("------ NMEAParser: Date received is y=%ld m=%ld d=%ld%s"),gy,gm,gd,NEWLINE); // 100422
			StartupStore(_T("------ This message will NOT be repeated. %s%s"),WhatTimeIsIt(),NEWLINE);
			DoStatusMessage(MsgToken(875));
			logbaddate=false;
		}
		gy=2012; gm=2; gd=30;	// an impossible date!
		goto force_advance;
		 
	}

  if (gpsValid) { 
	double tmplat;
	double tmplon;

	tmplat = MixedFormatToDegrees(StrToDouble(params[2], NULL));
	tmplat = NorthOrSouth(tmplat, params[3][0]);
	  
	tmplon = MixedFormatToDegrees(StrToDouble(params[4], NULL));
	tmplon = EastOrWest(tmplon,params[5][0]);
  
	if (!((tmplat == 0.0) && (tmplon == 0.0))) {
		pGPS->Latitude = tmplat;
		pGPS->Longitude = tmplon;
	}
  
	pGPS->Speed = KNOTSTOMETRESSECONDS * speed;
  
	if (pGPS->Speed>trackbearingminspeed) {
		pGPS->TrackBearing = AngleLimit360(StrToDouble(params[7], NULL));
	}
  } // gpsvalid 091108

#ifdef WIN32
  // As soon as we get a fix for the first time, set the
  // system clock to the GPS time.
  static bool sysTimeInitialised = false;
  
  if (!pGPS->NAVWarning && (gpsValid)) {
	if (SetSystemTimeFromGPS) {
		if (!sysTimeInitialised) {
			if ( ( pGPS->Year > 1980 && pGPS->Year<2100) && ( pGPS->Month > 0) && ( pGPS->Hour > 0)) {
        
				sysTimeInitialised =true; // Attempting only once
				SYSTEMTIME sysTime;
				// ::GetSystemTime(&sysTime);
				int hours = (int)pGPS->Hour;
				int mins = (int)pGPS->Minute;
				int secs = (int)pGPS->Second;
				sysTime.wYear = (unsigned short)pGPS->Year;
				sysTime.wMonth = (unsigned short)pGPS->Month;
				sysTime.wDay = (unsigned short)pGPS->Day;
				sysTime.wHour = (unsigned short)hours;
				sysTime.wMinute = (unsigned short)mins;
				sysTime.wSecond = (unsigned short)secs;
				sysTime.wMilliseconds = 0;
				::SetSystemTime(&sysTime);
			}
		}
	}
  }
#else
#warning "Set system clock to the GPS time not implemented."
#endif

  if(RMZAvailable) {
	UpdateBaroSource(pGPS, BARO__RMZ, NULL,  RMZAltitude);
  }
  if (!GGAAvailable) {
	// update SatInUse, some GPS receiver dont emmit GGA sentance
	if (!gpsValid) { 
		pGPS->SatellitesUsed = 0;
	} else {
		pGPS->SatellitesUsed = -1;
	}
  }
  
  if ( !GGAAvailable || (GGAtime == RMCtime)  )  {
	#if DEBUGSEQ
	StartupStore(_T("... RMC trigger gps, GGAtime==RMCtime\n")); // 31C
	#endif
	TriggerGPSUpdate(); 
  }

  return TRUE;

} // END RMC
Exemplo n.º 13
0
bool NMEAParser::TimeHasAdvanced(double ThisTime, NMEA_INFO *pGPS) {

  // If simulating, we might be in the future already.
  // We CANNOT check for <= because this check may be done by several GGA RMC GLL etc. sentences
  // among the same quantum time
  if(ThisTime< LastTime) {
    #if TESTBENCH
    StartupStore(_T("... TimeHasAdvanced BACK in time: Last=%f This=%f   %s\n"), LastTime, ThisTime,WhatTimeIsIt());
    #endif
    LastTime = ThisTime;
    StartDay = -1; // reset search for the first day
    MasterTimeReset();
    return false;
  } else {
    pGPS->Time = ThisTime;
    LastTime = ThisTime;
    return true;
  }
}
Exemplo n.º 14
0
double TimeModify(NMEA_INFO* pGPS, int& StartDay) {
  static int day_difference = 0, previous_months_day_difference = 0;

  double FixTime = (double) (pGPS->Second + (pGPS->Minute * 60) + (pGPS->Hour * 3600));
#endif
  if ((StartDay== -1) && (pGPS->Day != 0)) {
    StartupStore(_T(". First GPS DATE: %d-%d-%d  %s%s"), pGPS->Year, pGPS->Month, pGPS->Day,WhatTimeIsIt(),NEWLINE);
    StartDay = pGPS->Day;
    day_difference=0;
    previous_months_day_difference=0;
  }
  if (StartDay != -1) {
    if (pGPS->Day < StartDay) {
      // detect change of month (e.g. day=1, startday=26)
      previous_months_day_difference=day_difference+1;
      day_difference=0;
      StartDay = pGPS->Day;
      StartupStore(_T(". Change GPS DATE to NEW MONTH: %d-%d-%d  (%d days running)%s"), 
	pGPS->Year, pGPS->Month, pGPS->Day,previous_months_day_difference,NEWLINE);
    }
    if ( (pGPS->Day-StartDay)!=day_difference) {
      StartupStore(_T(". Change GPS DATE: %d-%d-%d  %s%s"), pGPS->Year, pGPS->Month, pGPS->Day,WhatTimeIsIt(),NEWLINE);
    }

    day_difference = pGPS->Day-StartDay;
    if ((day_difference+previous_months_day_difference)>0) {
      // Add seconds to fix time so time doesn't wrap around when
      // going past midnight in UTC
      FixTime += (day_difference+previous_months_day_difference) * 86400;
    }
  }
  return FixTime;
}
Exemplo n.º 15
0
void SettingsLeave() {
  if (!GlobalRunning) return; 

  SwitchToMapWindow();

  // Locking everything here prevents the calculation thread from running,
  // while shared data is potentially reloaded.
 
  LockFlightData();
  LockTaskData();

  MenuActive = false;

  // 101020 LKmaps contain only topology , so no need to force total reload!
  if(MAPFILECHANGED) {
	#if TESTBENCH
	StartupStore(_T(".... MAPFILECHANGED from configuration\n"));
	#endif
	if (LKTopo==0) {
		AIRSPACEFILECHANGED = TRUE;
		AIRFIELDFILECHANGED = TRUE;
		WAYPOINTFILECHANGED = TRUE;
		TERRAINFILECHANGED  = TRUE;
	}
	TOPOLOGYFILECHANGED = TRUE;
  } 

  if (TERRAINFILECHANGED) {
	#if TESTBENCH
	StartupStore(_T(".... TERRAINFILECHANGED from configuration\n"));
	#endif
	RasterTerrain::CloseTerrain();
	RasterTerrain::OpenTerrain();
	// NO! We dont reload waypoints on terrain change.
	// SetHome(WAYPOINTFILECHANGED==TRUE);
	MapWindow::ForceVisibilityScan = true;
  }

  if((WAYPOINTFILECHANGED) || (AIRFIELDFILECHANGED)) {
	#if TESTBENCH
	StartupStore(_T(".... WAYPOINT OR AIRFIELD CHANGED from configuration\n"));
	#endif
	SaveDefaultTask(); //@ 101020 BUGFIX
	ClearTask();
	ReadWayPoints();
	StartupStore(_T(". RELOADED %d WAYPOINTS + %d virtuals%s"),WayPointList.size()-NUMRESWP,NUMRESWP,NEWLINE);
	SetHome(true); // force home reload

	if (WAYPOINTFILECHANGED) {
		#if TESTBENCH
		StartupStore(_T(".... WAYPOINTFILECHANGED from configuration\n"));
		#endif
		SaveRecentList();
		LoadRecentList();
		RangeLandableNumber=0;
		RangeAirportNumber=0;
		RangeTurnpointNumber=0;
		CommonNumber=0;
		SortedNumber=0;
		// SortedTurnpointNumber=0; 101222
		LastDoRangeWaypointListTime=0;
		LKForceDoCommon=true;
		LKForceDoNearest=true;
		LKForceDoRecent=true;
		// LKForceDoNearestTurnpoint=true; 101222
	}
	InputEvents::eventTaskLoad(_T(LKF_DEFAULTASK)); //@ BUGFIX 101020
  } 

  if (TOPOLOGYFILECHANGED) {
	#if TESTBENCH
	StartupStore(_T(".... TOPOLOGYFILECHANGED from configuration\n"));
	#endif
	CloseTopology();
	OpenTopology();
	MapWindow::ForceVisibilityScan = true;
  }
  
  if(AIRSPACEFILECHANGED) {
	#if TESTBENCH
	StartupStore(_T(".... AIRSPACEFILECHANGED from configuration\n"));
	#endif
	CAirspaceManager::Instance().CloseAirspaces();
	CAirspaceManager::Instance().ReadAirspaces();
	CAirspaceManager::Instance().SortAirspaces();
	MapWindow::ForceVisibilityScan = true;
  }  
  
  if (POLARFILECHANGED) {
	#if TESTBENCH
	StartupStore(_T(".... POLARFILECHANGED from configuration\n"));
	#endif
	CalculateNewPolarCoef();
	GlidePolar::SetBallast();
  }
  
  if (AIRFIELDFILECHANGED
      || AIRSPACEFILECHANGED
      || WAYPOINTFILECHANGED
      || TERRAINFILECHANGED
      || TOPOLOGYFILECHANGED
      ) {
	CloseProgressDialog();
	MainWindow.SetFocus();
  }

  extern void ReinitScreen(void);
  if (FONTSCHANGED) {
      ReinitScreen();
  }
  
  UnlockTaskData();
  UnlockFlightData();

  if(!SIMMODE && COMPORTCHANGED) {
      #if TESTBENCH
      StartupStore(_T(".... COMPORTCHANGED from configuration.  ForceComPortReset @%s\n"),WhatTimeIsIt());
      #endif
      LKForceComPortReset=true;
      // RestartCommPorts(); 110605
  }

  MapWindow::ResumeDrawingThread();
  // allow map and calculations threads to continue on their merry way
}
Exemplo n.º 16
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)));
  }
}
Exemplo n.º 17
0
void StartLogger()
{
  HANDLE hFile;
  int i;
  TCHAR path[MAX_PATH+1];
  TCHAR cAsset[3];

  // strAsset is initialized with DUM.
  if (_tcslen(PilotName_Config)>0) {
	strAssetNumber[0]= IsAlphaNum(PilotName_Config[0]) ? PilotName_Config[0] : _T('A');
	strAssetNumber[1]= IsAlphaNum(PilotName_Config[1]) ? PilotName_Config[1] : _T('A');
  } else {
	strAssetNumber[0]= _T('D');
	strAssetNumber[1]= _T('U');
  }
  if (_tcslen(AircraftType_Config)>0) {
	strAssetNumber[2]= IsAlphaNum(AircraftType_Config[0]) ? AircraftType_Config[0] : _T('A');
  } else {
	strAssetNumber[2]= _T('M');
  }
  strAssetNumber[0]= towupper(strAssetNumber[0]);
  strAssetNumber[1]= towupper(strAssetNumber[1]);
  strAssetNumber[2]= towupper(strAssetNumber[2]);
  strAssetNumber[3]= _T('\0');

  for (i=0; i < 3; i++) { // chars must be legal in file names
    cAsset[i] = IsAlphaNum(strAssetNumber[i]) ? strAssetNumber[i] : _T('A');
  }

  LocalPath(path,TEXT(LKD_LOGS));

  if (TaskModified) {
    SaveDefaultTask();
  }
  wsprintf(szLoggerFileName, TEXT("%s\\LOGGER_TMP.IGC"), path);

  wsprintf(szSLoggerFileName, TEXT("%s\\LOGGER_SIG.IGC"), path);
  TCHAR newfile[MAX_PATH+20];
  if (GetFileAttributes(szLoggerFileName) != 0xffffffff) {
	StartupStore(_T("---- Logger recovery: Existing LOGGER_TMP.IGC found, renamed to LOST%s"),NEWLINE);
	wsprintf(newfile, TEXT("%s\\LOST_%02d%02d%02d.IGC"), path, GPS_INFO.Hour, GPS_INFO.Minute, GPS_INFO.Second);
	CopyFile(szLoggerFileName,newfile,TRUE);
	DeleteFile(szLoggerFileName);
  }
  if (GetFileAttributes(szSLoggerFileName) != 0xffffffff) {
	StartupStore(_T("---- Logger recovery (G): Existing LOGGER_SIG.IGC found, renamed to LOSTG%s"),NEWLINE);
	wsprintf(newfile, TEXT("%s\\LOSTG_%02d%02d%02d.IGC"), path, GPS_INFO.Hour, GPS_INFO.Minute, GPS_INFO.Second);
	CopyFile(szSLoggerFileName,newfile,TRUE);
	DeleteFile(szSLoggerFileName);
  }

  
  for(i=1;i<99;i++)
    {
      // 2003-12-31-XXX-987-01.IGC
      // long filename form of IGC file.
      // XXX represents manufacturer code

      if (!LoggerShortName) {
        // Long file name
        wsprintf(szFLoggerFileName,
                 TEXT("%s\\%04d-%02d-%02d-%s-%c%c%c-%02d.IGC"),
                 path,
                 GPS_INFO.Year,
                 GPS_INFO.Month,
                 GPS_INFO.Day,
		 _T(LOGGER_MANUFACTURER),
                 cAsset[0],
                 cAsset[1],
                 cAsset[2],
                 i);
 
        wsprintf(szFLoggerFileNameRoot,
                 TEXT("%s\\%04d-%02d-%02d-%s-%c%c%c-%02d.IGC"),
                 TEXT(""), // this creates it in root if MoveFile() fails
                 GPS_INFO.Year,
                 GPS_INFO.Month,
                 GPS_INFO.Day,
		 _T(LOGGER_MANUFACTURER),
                 cAsset[0],
                 cAsset[1],
                 cAsset[2],
                 i);
      } else {
        // Short file name
        TCHAR cyear, cmonth, cday, cflight;
        cyear = NumToIGCChar((int)GPS_INFO.Year % 10);
        cmonth = NumToIGCChar(GPS_INFO.Month);
        cday = NumToIGCChar(GPS_INFO.Day);
        cflight = NumToIGCChar(i);
        wsprintf(szFLoggerFileName,
                 TEXT("%s\\%c%c%cX%c%c%c%c.IGC"),
                 path,
                 cyear,
                 cmonth,
                 cday,
                 cAsset[0],
                 cAsset[1],
                 cAsset[2],
                 cflight);

        wsprintf(szFLoggerFileNameRoot,
                 TEXT("%s\\%c%c%cX%c%c%c%c.IGC"),
                 TEXT(""), // this creates it in root if MoveFile() fails
                 cyear,
                 cmonth,
                 cday,
                 cAsset[0],
                 cAsset[1],
                 cAsset[2],
                 cflight);
      } // end if

      hFile = CreateFile(szFLoggerFileName, GENERIC_WRITE,
			 FILE_SHARE_WRITE, NULL, CREATE_NEW,
			 FILE_ATTRIBUTE_NORMAL, 0);
      if(hFile!=INVALID_HANDLE_VALUE )
	{
          // file already exists
      CloseHandle(hFile);
      DeleteFile(szFLoggerFileName);
      break;
	}
  } // end while

  StartupStore(_T(". Logger Started %s  File <%s>%s"),
	WhatTimeIsIt(), szFLoggerFileName,NEWLINE);


  return;
}
Exemplo n.º 18
0
bool DetectFreeFlying(NMEA_INFO *Basic, DERIVED_INFO *Calculated) {

  static bool   ffDetected=false;
  static int    lastMaxAltitude=-1000;
  static double gndAltitude=0;
  static double vario[8];
  static bool   winchdetected=false;
  static short  wlaunch=0;
  static int    altLoss=0;
  static bool   safeTakeoffDetected=false;
  static bool   nowGearWarning = true; // init with true to prevent gear warning just after free flight detect
  static unsigned short noMessages =0;

  bool forcereset=LKSW_ForceFreeFlightRestart;

  if (DoInit[MDI_DETECTFREEFLYING]) {
    for (int i=0; i<8; i++) vario[i]=0;
    gndAltitude=0;
    winchdetected=false;
    wlaunch=0;
    altLoss=0;
    ffDetected=false;
    lastMaxAltitude=-1000;
    safeTakeoffDetected=false;
    nowGearWarning=true; // we are here before freeflight!
    noMessages=0;	// after a new takeoff we can give warnings again!
    DoInit[MDI_DETECTFREEFLYING]=false;
  }

  // reset on ground
  if (Calculated->Flying == false) {
    Calculated->FreeFlying=false;
    ffDetected=false;
    lastMaxAltitude=-1000;
    // For winch launches and also for quick taekoffs do not update gndAltitude when the plane
    // is already moving, probably towed or winched already. Threshold is at 4m/s, = 14kmh
    if (Basic->Speed<=4.0) gndAltitude=Basic->Altitude;
    winchdetected=false;
    wlaunch=0;
    altLoss=FF_TOWING_ALTLOSS;
    safeTakeoffDetected=false;
    LKSW_ForceFreeFlightRestart=false;
    return false;
  }

  if (forcereset) {
	LKSW_ForceFreeFlightRestart=false;
	#if TESTBENCH
	StartupStore(_T("... Forced FreeFlight Restart!\n"));
	#endif
	DoStatusMessage(MsgToken(1452),NULL,false);  // LKTOKEN  _@M1452_ = "Free flight detected"
	goto confirmbacktrue;
  }

  //  If we have a takeoff alarm, and  it is still pending!
  //  The AlarmTakeoffSafety is saved multiplied by 1000, so conversion between feet and meters will always be
  //  accurate and possible with no safety concerns about loosing accuracy on this issue!
  if ( (AlarmTakeoffSafety>0) && !safeTakeoffDetected ) {
	// Only if not in SIMMODE, or in SIM but replaying a flight
	if ( !(SIMMODE && !ReplayLogger::IsEnabled()) ) {
		if ( (Basic->Altitude - gndAltitude)>=(AlarmTakeoffSafety/1000)) {
			LKSound(_T("LK_SAFETAKEOFF.WAV"));
			safeTakeoffDetected=true;
		}
	}
  }

#ifdef  GEAR_WARNING
  if ( (GearWarningMode>0) && ffDetected) {
	// Only if not in SIMMODE, or in SIM but replaying a flight
//	if ( !(SIMMODE && !ReplayLogger::IsEnabled()) )
	  {

		double AltitudeAGL = Calculated->AltitudeAGL;

	    double dist = 0;
	    if(GearWarningMode ==1){
	      if( ValidWayPoint(BestAlternate))
	      {
	         AltitudeAGL = Basic->Altitude - WayPointList[BestAlternate].Altitude; // AGL = height above landable
	         if( AltitudeAGL <= (GearWarningAltitude/1000))
	            DistanceBearing(Basic->Latitude, Basic->Longitude, WayPointList[BestAlternate].Latitude, WayPointList[BestAlternate].Longitude, &dist, NULL);
	      }else{
	    	dist = 9999; // set to far away if best alternate  not valid
	      }
	    }

		if (( AltitudeAGL  <=(GearWarningAltitude/1000)) && (noMessages < MAX_NO_GEAR_WARN))
		{
		  if(!nowGearWarning)
		  {
		    if(dist < 3700) // show gear warning if 2Nautical Miles close to landable
		    {
			  LKSound(_T("LK_GEARWARNING.WAV"));
			  DoStatusMessage(gettext(TEXT("_@M1834_")),NULL,false);  // LKTOKEN _@M1834_ "Prepare for landing !"
			  nowGearWarning=true;
			  noMessages++;

#if TESTBENCH
			  if(GearWarningMode ==2)
			    StartupStore(_T("... %i. Gear warning at %im = %im [%im] AGL%s"),noMessages,(int)Basic->Altitude,(int)AltitudeAGL,(int)GearWarningAltitude/1000,NEWLINE);
			  else
				 StartupStore(_T("...%i. Gear warning at %im = %im [%im] over landable %s (%im)%s"),noMessages,(int)Basic->Altitude,(int)AltitudeAGL,(int)GearWarningAltitude/1000,WayPointList[BestAlternate].Name,(int)WayPointList[BestAlternate].Altitude,NEWLINE);
#endif

		    }
			if (noMessages==MAX_NO_GEAR_WARN) {
				StartupStore(_T("... GOING SILENT on too many Gear warnings.  %s%s"),WhatTimeIsIt(),NEWLINE);

				DoStatusMessage(MsgToken(2304)); // GOING SILENT ON GEAR REPORTING
				noMessages++;	// we go to 11, and never be back here		  }
			}
		  }
		}
		else
		{
		  if(( AltitudeAGL)> ((GearWarningAltitude/1000)+100))  // re-enable warning if higher that 100m above Gear altitude
		  {
            if( nowGearWarning )
            {
#if TESTBENCH
			  if(GearWarningMode ==2)
			    StartupStore(_T("...rearmed %i. Gear warning at %im = %im AGL %s"),noMessages,(int)Basic->Altitude,(int)AltitudeAGL,NEWLINE);
			  else
				 StartupStore(_T("..rearmed %i. Gear warning at %im = %im over landable %s (%im)%s"),noMessages,(int)Basic->Altitude,(int)AltitudeAGL,WayPointList[BestAlternate].Name,(int)WayPointList[BestAlternate].Altitude,NEWLINE);
#endif
	  		  nowGearWarning = false;
            }
		  }
		}
	}
  }
#endif

  if (ISPARAGLIDER) {
    Calculated->FreeFlying=true;
    return true; 
  }
  if (ISGAAIRCRAFT||ISCAR) {
    return false; 
  }

  // do something special for other situations
  if (SIMMODE && !ReplayLogger::IsEnabled()) {
    Calculated->FreeFlying=true;
    ffDetected=true;
    return true; 
  }

  // If flying, and start was already detected, assume valid freeflight.
  // Put here in the future the Engine Noise Detection for motorplanes
  if (ffDetected)
    return true;

  // Here we are flying, and the start of free flight must still be detected

  // In any case, after this time, force a start. This is to avoid that for any reason, no FF is ever detected.
  if ((int)Basic->Time > ( Calculated->TakeOffTime + FF_MAXTOWTIME)) {
    #if DEBUG_DFF
    DoStatusMessage(_T("DFF:  TIMEOUT"));
    #endif
    goto backtrue;	// unconditionally force start FF
  }

 
  // A loss of altitude will trigger FF 
  lastMaxAltitude = std::max(lastMaxAltitude, (int)Basic->Altitude);
  if ((int)Basic->Altitude <= ( lastMaxAltitude - altLoss)) {
    #if DEBUG_DFF
    if ( (winchdetected) || ((Basic->Altitude - gndAltitude)>=400) 
      && ((Basic->Time - Calculated->TakeOffTime) >= 150))
      DoStatusMessage(_T("DFF:  ALTITUDE LOSS"));
    #endif
    goto lastcheck;
  }

#ifdef TOW_CRUISE
  // If circling, we assume that we're in free flight and use the
  // start-of-circling time and position.  Turning.cpp makes sure
  // we aren't circling while on tow by imposing a 12 deg/sec turn
  // rate limit for on-tow turning.
#else
  // If circling we assume that we are in free flight already, using the start of circling time and position.
  // But we must be sure that we are not circling.. while towed. A 12 deg/sec turn rate will make it quite sure.
  // Of course nobody can circle while winchlaunched, so in this case FF is immediately detected.
#endif

#ifdef TOW_CRUISE
  // The 12 deg/sec check is now done in Turning.cpp, so there's no
  // need to do it here, too.  Doing it here, too, could allow the
  // possibility of climb mode engaging without FF detection, if the
  // climb rate goes above 12 deg/sec for just a split second.
  //if (Calculated->Circling && (winchdetected ||
  //   (fabs(Calculated->TurnRate) >= 12))) {

  if (Calculated->Circling) {
#else
  if (Calculated->Circling && ( winchdetected || ( fabs(Calculated->TurnRate) >=12 ) ) ) {
#endif

    if (UseContestEngine()) {
      CContestMgr::Instance().Add(new CPointGPS(static_cast<unsigned>(Calculated->ClimbStartTime),
	Calculated->ClimbStartLat, Calculated->ClimbStartLong,
	static_cast<unsigned>(Calculated->ClimbStartAlt)));
    }

    #if DEBUG_DFF
    DoStatusMessage(_T("DFF:  THERMALLING"));
    #endif
    goto backtrue;
  }

  vario[7]=vario[6];
  vario[6]=vario[5];
  vario[5]=vario[4];
  vario[4]=vario[3];
  vario[3]=vario[2];
  vario[2]=vario[1];
  vario[1]=Calculated->Vario;

  double newavervario;
  double oldavervario;

  newavervario=(vario[1]+vario[2]+vario[3])/3;

  if (newavervario>=10) {
    wlaunch++;
  } else {
    wlaunch=0;
  }
  // After (6+2) 8 seconds of consecutive fast climbing (AFTER TAKEOFF DETECTED!), winch launch is detected
  if (wlaunch==6) {
    #if DEBUG_DFF
    DoStatusMessage(_T("DFF:  WINCH LAUNCH"));
    #endif
    altLoss=FF_WINCHIN_ALTLOSS;
    winchdetected=true;
  }
    
  if (newavervario>0.3)
    return false;

  if (newavervario<=0) {
    #if DEBUG_DFF
    if ( (winchdetected) || ((Basic->Altitude - gndAltitude)>=400) 
      && ((Basic->Time - Calculated->TakeOffTime) >= 150))
      DoStatusMessage(_T("DFF:  VARIO SINK"));
    #endif
    goto lastcheck;
  }

  oldavervario=(vario[4]+vario[5]+vario[6]+vario[7])/4;
  // current avervario between 0.0 and 0.3: uncertain situation,  we check what we had in the previous time
  // Windy situations during towing may lead to false positives if delta is too low. This is the most
  // difficult part which could lead to false positives or negatives.
  if ( oldavervario >=4.5 ) {
    #if DEBUG_DFF
    StartupStore(_T("..... oldavervario=%.1f newavervario=%.1f current=%.1f\n"),oldavervario,newavervario,Calculated->Vario);
    if ( (winchdetected) || ((Basic->Altitude - gndAltitude)>=400) 
      && ((Basic->Time - Calculated->TakeOffTime) >= 150))
      DoStatusMessage(_T("DFF:  DELTA VARIO"));
    #endif
    goto lastcheck;
  }

  // No free flight detected
  return false;

  lastcheck: 

  // Unless under a winch launch, we shall not consider anything below 400m gain, 
  // and before 2.5minutes have passed since takeoff
  // Anybody releasing tow before 3 minutes will be below 500m QFE, and won't go much around
  // until a thermal is found. So no problems. 

  if (!winchdetected) {
    if ( (Basic->Altitude - gndAltitude)<400)
      return false;
    if ( (Basic->Time - Calculated->TakeOffTime) < 150)
      return false;
  }

  backtrue:
  // In real flight on a fly device (assuming a windowsPC is NOT a fly device)
  // give no messages during critical phases of flight
  #if ( !defined(WINDOWSPC) || WINDOWSPC==0 )
  if (SIMMODE)
  #endif
  DoStatusMessage(gettext(TEXT("_@M1452_")),NULL,false);  // LKTOKEN  _@M1452_ = "Free flight detected"

  confirmbacktrue:
  // Always sound
  if (EnableSoundModes) {
	LKSound(_T("LK_FREEFLIGHT.WAV"));
  }

  StartupStore(_T(". Free Flight started %s%s"), WhatTimeIsIt(),NEWLINE);

  ffDetected=true;
  Calculated->FreeFlying=true;
  Calculated->FreeFlightStartTime=Basic->Time;
  Calculated->FreeFlightStartQNH=Basic->Altitude;
  Calculated->FreeFlightStartQFE=gndAltitude;

  WayPointList[RESWP_FREEFLY].Latitude=Basic->Latitude;
  WayPointList[RESWP_FREEFLY].Longitude=Basic->Longitude;
  WayPointList[RESWP_FREEFLY].Altitude=Basic->Altitude;
  if (WayPointList[RESWP_FREEFLY].Altitude==0) WayPointList[RESWP_FREEFLY].Altitude=0.001;
  WayPointList[RESWP_FREEFLY].Reachable=TRUE;
  WayPointList[RESWP_FREEFLY].Visible=TRUE;
  WayPointList[RESWP_FREEFLY].Format = LKW_VIRTUAL;

  TCHAR Temp[30];
  Units::TimeToTextS(Temp, (int)TimeLocal((long)Calculated->FreeFlightStartTime));

  LKASSERT(WayPointList[RESWP_FREEFLY].Comment!=NULL);

  WayPointList[RESWP_FREEFLY].Comment[99]='\0'; // for safety
  _stprintf(WayPointList[RESWP_FREEFLY].Comment,_T("%s: %s  @%.0f%s QNH"),
	gettext(_T("_@M1754_")), 	// Free flight start
	Temp,
	ALTITUDEMODIFY*Calculated->FreeFlightStartQNH,
	Units::GetAltitudeName());

  ResetFreeFlightStats(Calculated);
  return true;

}




//
// Upon FF detection, we reset some calculations, ONLY SOME.
// Most things are pertinent to flying, not to freeflying.
//
// Notice 1:  we cannot do oldstyle reset, because it would reset also takeoff time.
//            For FF, we need new stuff doing new things.
// Notice 2:  GA and CAR mode will not ever use FF stuff
//
// Notice 3:  since FF is not (still) affecting tasks, we shall not reset task values now
//
void ResetFreeFlightStats(DERIVED_INFO *Calculated) {

  int i;

  CContestMgr::Instance().Reset(Handicap);
  flightstats.Reset();

  Calculated->timeCruising = 0;
  Calculated->timeCircling = 0;

  // Calculated->TotalHeightClimb = 0;
  // Calculated->CruiseStartTime = -1;
  // 
  // ClimbStartTime CANNOT be reset here: it is a loop! We use themal start to detect freeflight!
  // We have a conflict here!
  // Calculated->ClimbStartTime = -1;  
  // Calculated->AverageThermal = 0;

  for (i=0; i<200; i++) {
     Calculated->AverageClimbRate[i]= 0;
     Calculated->AverageClimbRateN[i]= 0;
  }
  Calculated->MaxThermalHeight = 0;
  for (i=0; i<NUMTHERMALBUCKETS; i++) {
    Calculated->ThermalProfileN[i]=0;
    Calculated->ThermalProfileW[i]=0;
  }

  // clear thermal sources for first time.
  for (i=0; i<MAX_THERMAL_SOURCES; i++) {
    Calculated->ThermalSources[i].LiftRate= -1.0;
  }

  // The MaxHeightGain function wait for FF in flight and will update
  // considering 0 as a no-altitude-set-yet .
  Calculated->MinAltitude = 0;
  Calculated->MaxAltitude = 0;
  Calculated->MaxHeightGain = 0;


}
Exemplo n.º 19
0
void StopLogger(void) {
  TCHAR szMessage[(MAX_PATH*2)+1] = TEXT("\0");
  int iLoggerError=0;  // see switch statement for error handler
  TCHAR sztmplogfile[MAX_PATH+1] = TEXT("\0");
  int retval=0;

  _tcscpy(sztmplogfile,szLoggerFileName); // use LOGGER_TMP, unsigned

  if (LoggerActive) {
    LoggerActive = false;
    if (LoggerClearFreeSpace()) {

    #if (TESTBENCH && DEBUG_LOGGER)
    if (LoggerGActive())
    #else
    if (!SIMMODE && LoggerGActive())
    #endif
	{

	extern int RunSignature();
	retval = RunSignature();
	if (retval!=0) {
		StartupStore(_T(".... LOGGER SIGNATURE ERROR, CODE=%d%s"),retval,NEWLINE);
		switch(retval) {
			case -1:
				StartupStore(_T(".... (EXEQ DEBUG FAILURE)%s"),NEWLINE);
				break;
			case 1:
				StartupStore(_T(".... (SOURCE FILE DISAPPEARED)%s"),NEWLINE);
				break;
			case 3:
				StartupStore(_T(".... (EXEQ WITH WRONG ARGUMENTS)%s"),NEWLINE);
				break;
			case 4:
				StartupStore(_T(".... (BAD ENVIRONMENT)%s"),NEWLINE);
				break;
			case 11:
				StartupStore(_T(".... (LOGGER_TMP DISAPPEARED)%s"),NEWLINE);
				break;
			case 12:
				StartupStore(_T(".... (LOGGER_SIG ALREADY EXISTING)%s"),NEWLINE);
				break;
			case 21:
				StartupStore(_T(".... (MUTEX FAILURE=)%s"),NEWLINE);
				break;
			case 259:
				StartupStore(_T(".... (PROCESS DID NOT TERMINATE!)%s"),NEWLINE);
				break;
			default:
				break;
		}
		// we shall be moving LOGGER_TMP, and leave LOGGER_SIG untouched. In fact we do not know
		// if LOGGER_SIG is or will be available.
	} else {
		// RunSig ok, change logfile to new logger_sig
		StartupStore(_T(". Logger OK, IGC signed with G-Record%s"),NEWLINE);
		DeleteFile(szLoggerFileName);	// remove old LOGGER_TMP
		_tcscpy(sztmplogfile,szSLoggerFileName); // use LOGGER_SIG, signed
	}

	} // logger active

      int imCount=0;
      const int imMax=3;
      for (imCount=0; imCount < imMax; imCount++) {
        // MoveFile() nonzero==Success
        if (0 != MoveFile( sztmplogfile, szFLoggerFileName)) {
          iLoggerError=0;
          break; // success
        }
        Sleep(750); // wait for file system cache to fix itself?
      }
      if (imCount == imMax) { // MoveFile() failed all attempts

        if (0 == MoveFile( sztmplogfile, szFLoggerFileNameRoot)) { // try rename it and leave in root
          iLoggerError=1; //Fail.  NoMoveNoRename
        }
        else {
          iLoggerError=2; //NoMoveYesRename
        }
      }

    } // logger clearfreespace
    else { // Insufficient disk space.  // MoveFile() nonzero==Success
      if (0 == MoveFile( sztmplogfile, szFLoggerFileNameRoot)) { // try rename it and leave in root
        iLoggerError=3; //Fail.  Insufficient Disk Space, NoRename
      }
      else {
        iLoggerError=4; //Success.  Insufficient Disk Space, YesRename
      }
    }

    switch (iLoggerError) { //0=Success 1=NoMoveNoRename 2=NoMoveYesRename 3=NoSpaceNoRename 4=NoSpaceYesRename
    case 0:
      StartupStore(TEXT(". Logger: File saved %s%s"),WhatTimeIsIt(),NEWLINE);
      break;

    case 1: // NoMoveNoRename
      LK_tcsncpy(szMessage,TEXT("--- Logger file not copied.  It is in the root folder of your device and called "),MAX_PATH);
      _tcsncat(szMessage,sztmplogfile,MAX_PATH);

      MessageBoxX(hWndMapWindow,
		gettext(szMessage),
	// LKTOKEN  _@M404_ = "Logger Error" 
		gettext(TEXT("_@M404_")), MB_OK| MB_ICONERROR);
      _tcsncat(szMessage,TEXT(SNEWLINE),MAX_PATH);
      StartupStore(szMessage);
      break;

    case 2: // NoMoveYesRename
      LK_tcsncpy(szMessage,TEXT("--- Logger file not copied.  It is in the root folder of your device"),MAX_PATH);

      MessageBoxX(hWndMapWindow,
		gettext(szMessage),
	// LKTOKEN  _@M404_ = "Logger Error" 
		gettext(TEXT("_@M404_")), MB_OK| MB_ICONERROR);
      _tcsncat(szMessage,TEXT(SNEWLINE),MAX_PATH);
      StartupStore(szMessage);
      break;

    case 3: // Insufficient Storage.  NoRename
      LK_tcsncpy(szMessage,TEXT("++++++ Insuff. storage. Logger file in device's root folder, called "),MAX_PATH);
      _tcsncat(szMessage,sztmplogfile,MAX_PATH);

      MessageBoxX(hWndMapWindow,
		gettext(szMessage),
	// LKTOKEN  _@M404_ = "Logger Error" 
		gettext(TEXT("_@M404_")), MB_OK| MB_ICONERROR);
      _tcsncat(szMessage,TEXT(SNEWLINE),MAX_PATH);
      StartupStore(szMessage);
      break;

    case 4: // Insufficient Storage.  YesRename
      LK_tcsncpy(szMessage,TEXT("++++++ Insufficient storage.  Logger file is in the root folder of your device"),MAX_PATH);

      MessageBoxX(hWndMapWindow,
		gettext(szMessage),
	// LKTOKEN  _@M404_ = "Logger Error" 
		gettext(TEXT("_@M404_")), MB_OK| MB_ICONERROR);
      _tcsncat(szMessage,TEXT(SNEWLINE),MAX_PATH);
      StartupStore(szMessage);
      break;
} // error handler

    NumLoggerBuffered = 0;
  }
}
Exemplo n.º 20
0
BOOL NMEAParser::PFLAU(TCHAR *String, TCHAR **params, size_t nparams, NMEA_INFO *pGPS)
{
  static int old_flarm_rx = 0;
  static bool sayflarmavailable=true; // 100325
  static bool conflict=false;

  // It can happen that both port auto/exclude themselves, or one will succeed to survive.
  // In either cases, there is a bad problem going on. Recovery should not be a choice.
  if (conflict) return FALSE;

  //
  // We want to be sure that we are not going to elect as Flarm two simultaneous ports.
  // We let it happen once, and give warning. Then only one of the two will remain.
  // It is a real borderline situation, due to conflict on comm ports, normally virtual com ports.
  if (nmeaParser1.gpsValid && nmeaParser2.gpsValid) {
	if (nmeaParser1.isFlarm && nmeaParser2.isFlarm) {
		DoStatusMessage(_T("FLARM DETECTED ON TWO COM PORTS! AUTO-EXCLUDING."));
		StartupStore(_T("......... WARNING! FLARM DETECTED ON TWO COM PORTS! %s\n"), WhatTimeIsIt());
		pGPS->FLARM_Available = false;
		isFlarm = false;
		conflict=true;
		return FALSE;
	}
  }

  if(!pGPS->FLARM_Available)
	sayflarmavailable = true;

  pGPS->FLARM_Available = true;
  LastFlarmCommandTime = pGPS->Time;
  isFlarm = true;

  if ( sayflarmavailable ) {
	pGPS->FLARM_SW_Version =0.0;
	pGPS->FLARM_HW_Version =0.0;
	static int MessageCnt =0;
	if(MessageCnt < 10)
	{
	  MessageCnt++;
	  DoStatusMessage(gettext(TEXT("_@M279_"))); // FLARM DETECTED
	}
	sayflarmavailable=false;
	if(nmeaParser1.isFlarm) {
		devRequestFlarmVersion(devA());
	} else {
		if(nmeaParser2.isFlarm)
			devRequestFlarmVersion(devB());
	}
  }

  // calculate relative east and north projection to lat/lon

  double delta_lat = 0.01;
  double delta_lon = 0.01;

  double dlat;
  DistanceBearing(pGPS->Latitude, pGPS->Longitude,
                  pGPS->Latitude+delta_lat, pGPS->Longitude,
                  &dlat, NULL);
  double dlon;
  DistanceBearing(pGPS->Latitude, pGPS->Longitude,
                  pGPS->Latitude, pGPS->Longitude+delta_lon,
                  &dlon, NULL);

  if ((fabs(dlat)>0.0)&&(fabs(dlon)>0.0)) {
    FLARM_NorthingToLatitude = delta_lat / dlat;
    FLARM_EastingToLongitude = delta_lon / dlon;
  } else {
    FLARM_NorthingToLatitude=0.0;
    FLARM_EastingToLongitude=0.0;
  }

  swscanf(String,
	  TEXT("%hu,%hu,%hu,%hu"),
	  &pGPS->FLARM_RX, // number of received FLARM devices
	  &pGPS->FLARM_TX, // Transmit status
	  &pGPS->FLARM_GPS, // GPS status
	  &pGPS->FLARM_AlarmLevel); // Alarm level of FLARM (0-3)

  // process flarm updates

  if ((pGPS->FLARM_RX) && (old_flarm_rx==0)) {
    // traffic has appeared..
    InputEvents::processGlideComputer(GCE_FLARM_TRAFFIC);
  }
  if (pGPS->FLARM_RX > old_flarm_rx) {
    // re-set suppression of gauge, as new traffic has arrived
    //    GaugeFLARM::Suppress = false;
  }
  if ((pGPS->FLARM_RX==0) && (old_flarm_rx)) {
    // traffic has disappeared..
    InputEvents::processGlideComputer(GCE_FLARM_NOTRAFFIC);
  }
  // TODO feature: add another event for new traffic.

  old_flarm_rx = pGPS->FLARM_RX;

  return FALSE;
}
Exemplo n.º 21
0
bool InitLDRotary(ldrotary_s *buf) {
short i, bsize;
#ifdef DEBUG_ROTARY
char ventabuffer[200];
FILE *fp;
#endif
	#if TESTBENCH
	StartupStore(_T("... Init LDRotary @%s%s"),WhatTimeIsIt(),NEWLINE);
	#endif

	switch (AverEffTime) {
		case ae3seconds:
			bsize=3;
			break;
		case ae5seconds:
			bsize=5;
			break;
		case ae10seconds:
			bsize=10;
			break;
		case ae15seconds:
			bsize=15;	// useless, LDinst already there
			break;
		case ae30seconds:
			bsize=30;	// limited useful
			break;
		case ae45seconds:
			bsize=45;	// limited useful
			break;
		case ae60seconds:
			bsize=60;	// starting to be valuable
			break;
		case ae90seconds:
			bsize=90;	// good interval
			break;
		case ae2minutes:
			bsize=120;	// other software's interval
			break;
		case ae3minutes:
			bsize=180;	// probably too long interval
			break;
		default:
			bsize=3; // make it evident
			break;
	}
	//if (bsize <3 || bsize>MAXLDROTARYSIZE) return false;
	for (i=0; i<MAXLDROTARYSIZE; i++) {
		buf->distance[i]=0;
		buf->altitude[i]=0;
		buf->ias[i]=0;
	}
	buf->totaldistance=0;
    buf->totalaltitude=0;
	buf->totalias=0;
	buf->start=-2;
	buf->size=bsize;
	buf->valid=false;
#ifdef DEBUG_ROTARY
	sprintf(ventabuffer,"InitLdRotary size=%d\r\n",buf->size);
	if ((fp=fopen("DEBUG.TXT","a"))!= NULL)
                    {;fprintf(fp,"%s\n",ventabuffer);fclose(fp);}
#endif

	Rotary_Speed=0;
	Rotary_Distance=0;
  return false;
}