Esempio n. 1
0
/**
 * Saves the calculated values to the persistent memory file
 * @param gps_info The basic data
 * @param Calculated The calculated data
 */
void
SaveCalculationsPersist(const NMEA_INFO &gps_info,
                        const DERIVED_INFO &Calculated,
                        const ProtectedTaskManager &protected_task_manager,
                        const GlideComputer &glide_computer,
                        Logger &logger)
{
  unsigned size;

  logger.LoggerClearFreeSpace(gps_info);

  if (FindFreeSpace(szCalculationsPersistDirectory) < MINFREESTORAGE) {
    if (!logger.LoggerClearFreeSpace(gps_info)) {
      LogStartUp(_T("SaveCalculationsPersist insufficient storage"));
      return;
    } else {
      LogStartUp(_T("SaveCalculationsPersist cleared logs to free storage"));
    }
  }

  LogStartUp(_T("SaveCalculationsPersist"));

  FILE *file = _tfopen(szCalculationsPersistFileName, _T("wb"));

  if (file == NULL) {
    LogStartUp(_T("SaveCalculationsPersist can't create file"));
    return;
  }

  size = sizeof(DERIVED_INFO);
  fwrite(&size, sizeof(size), 1, file);
  fwrite(&Calculated, size, 1, file);

  size = sizeof(FlightStatistics);
  fwrite(&size, sizeof(size), 1, file);
  fwrite(&glide_computer.GetFlightStats(), size, 1, file);

  /// @todo persistence for OLC data

  GlidePolar polar = glide_computer.SettingsComputer().glide_polar_task;
  double MACCREADY = polar.get_mc();
  double BUGS = polar.get_bugs();
  double BALLAST = polar.get_ballast();

  size = sizeof(double)*4;
  fwrite(&size, sizeof(size), 1, file);
  fwrite(&MACCREADY, sizeof(MACCREADY), 1, file);
  fwrite(&BUGS, sizeof(BUGS), 1, file);
  fwrite(&BALLAST, sizeof(BALLAST), 1, file);
  fwrite(&CuSonde::maxGroundTemperature,
      sizeof(CuSonde::maxGroundTemperature), 1, file);

  //    WriteFile(hFile,&CRUISE_EFFICIENCY,
  //              size,&dwBytesWritten,(OVERLAPPED*)NULL);

  LogStartUp(_T("SaveCalculationsPersist ok"));

  fclose(file);
}
bool
ConditionMonitorLandableReachable::CheckCondition(const GlideComputer& cmp)
{
  if (!cmp.Calculated().flight.flying)
    return false;

  now_reachable = cmp.Calculated().common_stats.landable_reachable;

  // warn when becoming unreachable
  return (!now_reachable && last_reachable);
}
bool
ConditionMonitorGlideTerrain::CheckCondition(const GlideComputer& cmp)
{
  if (!cmp.Calculated().flight.flying ||
      !cmp.Calculated().task_stats.task_valid)
    return false;

  const GlideResult& res = cmp.Calculated().task_stats.total.solution_remaining;
  if (!res.IsFinalGlide())
    // only give message about terrain warnings if above final glide
    return false;

  return cmp.Calculated().terrain_warning;
}
bool
ConditionMonitorStartRules::CheckCondition(const GlideComputer& cmp)
{
#ifdef OLD_TASK // start condition warnings
  if (!task.Valid()
      || !cmp.Basic().flying
      || (task.getActiveIndex() > 0)
      || !task.ValidTaskPoint(task.getActiveIndex() + 1))
    return false;

  if (cmp.Calculated().LegDistanceToGo > task.getSettings().StartRadius)
    return false;

  if (cmp.ValidStartSpeed(task.getSettings().StartMaxSpeedMargin)
      && cmp.InsideStartHeight(task.getSettings().StartMaxHeightMargin))
    withinMargin = true;
  else
    withinMargin = false;
  }
Esempio n. 5
0
void
ConditionMonitor::Update(const GlideComputer& cmp)
{
  if (!cmp.Calculated().flight.flying)
    return;

  bool restart = false;
  const fixed Time = cmp.Basic().time;
  if (Ready_Time_Check(Time, &restart)) {
    LastTime_Check = Time;
    if (CheckCondition(cmp)) {
      if (Ready_Time_Notification(Time) && !restart) {
        LastTime_Notification = Time;
        Notify();
        SaveLast();
      }
    }

    if (restart)
      SaveLast();
  }
}
bool
ConditionMonitorFinalGlide::CheckCondition(const GlideComputer& cmp)
{
  if (!cmp.Calculated().flight.flying || !cmp.Calculated().task_stats.task_valid)
    return false;

  const GlideResult& res = cmp.Calculated().task_stats.total.solution_remaining;

  // TODO: use low pass filter
  tad = res.altitude_difference * fixed(0.2) + fixed(0.8) * tad;

  bool BeforeFinalGlide = !res.IsFinalGlide();

  if (BeforeFinalGlide) {
    Interval_Notification = fixed(60 * 5);
    if ((tad > fixed(50)) && (last_tad < fixed(-50)))
      // report above final glide early
      return true;
    else if (tad < fixed(-50))
      last_tad = tad;
  } else {
    Interval_Notification = fixed(60);
    if (res.IsFinalGlide()) {
      if ((last_tad < fixed(-50)) && (tad > fixed_one))
        // just reached final glide, previously well below
        return true;

      if ((last_tad > fixed_one) && (tad < fixed(-50))) {
        // dropped well below final glide, previously above
        last_tad = tad;
        return true; // JMW this was true before
      }
    }
  }
  return false;
}
Esempio n. 7
0
static void
LoadReplay(DebugReplay *replay, GlideComputer &glide_computer,
           InterfaceBlackboard &blackboard)
{
  unsigned i = 0;
  while (replay->Next()) {
    const MoreData &basic = replay->Basic();

    glide_computer.ReadBlackboard(basic);
    glide_computer.ProcessGPS();

    if (++i == 8) {
      i = 0;
      glide_computer.ProcessIdle();
    }
  }

  glide_computer.ProcessExhaustive();

  blackboard.ReadBlackboardBasic(glide_computer.Basic());
  blackboard.ReadBlackboardCalculated(glide_computer.Calculated());
}
Esempio n. 8
0
/**
 * "Boots" up XCSoar
 * @param hInstance Instance handle
 * @param lpCmdLine Command line string
 * @return True if bootup successful, False otherwise
 */
bool XCSoarInterface::Startup(HINSTANCE hInstance, LPTSTR lpCmdLine)
{
  // The title bar text
  TCHAR szTitle[MAX_LOADSTRING];

  // Store instance handle in our global variable
  hInst = hInstance;

  // IDS_APP_TITLE = XCSoar (see XCSoar.rc)
  LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);

  //If it is already running, then focus on the window
  if (MainWindow::find(szTitle))
    return false;

  // Send the SettingsMap to the DeviceBlackboard
  SendSettingsMap();

  // Register window classes
  PaintWindow::register_class(hInst);
  MainWindow::register_class(hInst);
  MapWindow::register_class(hInst);

  // Fill the fast(co)sine table
  InitSineTable();

  PreloadInitialisation(true);

  // Send the SettingsMap to the DeviceBlackboard
  SendSettingsMap();

  // Creates the main window
  StartupStore(TEXT("Create main window\n"));
  RECT WindowSize = SystemWindowSize();
  main_window.set(szTitle,
		  WindowSize.left, WindowSize.top,
		  WindowSize.right, WindowSize.bottom);

  if (!main_window.defined()) {
    return false;
  }
  main_window.install_timer();

  // Initialize DeviceBlackboard
  device_blackboard.Initialise();

  // Initialize Marks
  marks = new Marks("xcsoar-marks");
  topology = new TopologyStore(marks->GetTopology());

  // Show the main and map windows
  StartupStore(TEXT("Create map window\n"));
  main_window.show();
  main_window.map.show();

#ifdef HAVE_ACTIVATE_INFO
  SHSetAppKeyWndAssoc(VK_APP1, main_window);
  SHSetAppKeyWndAssoc(VK_APP2, main_window);
  SHSetAppKeyWndAssoc(VK_APP3, main_window);
  SHSetAppKeyWndAssoc(VK_APP4, main_window);
  // Typical Record Button
  //	Why you can't always get this to work
  //	http://forums.devbuzz.com/m_1185/mpage_1/key_/tm.htm
  //	To do with the fact it is a global hotkey, but you can with code above
  //	Also APPA is record key on some systems
  SHSetAppKeyWndAssoc(VK_APP5, main_window);
  SHSetAppKeyWndAssoc(VK_APP6, main_window);
#endif

  // Initialize main blackboard data
  task.ClearTask();
  glide_computer.Initialise();
  logger.LinkGRecordDLL(); // try to link DLL if it exists

  // Load the EGM96 geoid data
  OpenGeoid();

  PreloadInitialisation(false);

  Profile::LoadWindFromRegistry();

  // TODO TB: seems to be out of date?!
  CalculateNewPolarCoef();

  // Calculate polar-related data and saves it to the cache
  StartupStore(TEXT("GlidePolar::UpdatePolar\n"));
  GlidePolar::UpdatePolar(false, SettingsComputer());

  // Show startup info depending on device
  StartupInfo();

  // Read the topology file(s)
  topology->Open();

  // Read the terrain file
  terrain.OpenTerrain();

  // Read the waypoint files
  ReadWayPoints(way_points, terrain);

  // Read and parse the airfield info file
  ReadAirfieldFile();

  // Set the home waypoint
  SetHome(way_points, terrain, SetSettingsComputer(), false, true);

  // ReSynchronise the blackboards here since SetHome touches them
  ReadBlackboardBasic(device_blackboard.Basic());

  terrain.ServiceFullReload(Basic().Location);

  // Scan for weather forecast
  CreateProgressDialog(gettext(TEXT("Scanning weather forecast")));
  StartupStore(TEXT("RASP load\n"));
  RASP.ScanAll(Basic().Location);

  // Reads the airspace files
  ReadAirspace();
  // Sorts the airspaces by priority
  SortAirspace();

  // Read the FLARM details file
  OpenFLARMDetails();

#ifndef DISABLEAUDIOVARIO
  /*
  VarioSound_Init();
  VarioSound_EnableSound(EnableSoundVario);
  VarioSound_SetVdead(SoundDeadband);
  VarioSound_SetV(0);
  VarioSound_SetSoundVolume(SoundVolume);
  */
#endif

  // Start the device thread(s)
  CreateProgressDialog(gettext(TEXT("Starting devices")));
  devStartup(lpCmdLine);

  // Reset polar in case devices need the data
  StartupStore(TEXT("GlidePolar::UpdatePolar\n"));
  GlidePolar::UpdatePolar(true, SettingsComputer());

  CreateProgressDialog(gettext(TEXT("Initialising display")));

  // Finally ready to go.. all structures must be present before this.

  // Create the drawing thread
  StartupStore(TEXT("CreateDrawingThread\n"));
  draw_thread = new DrawThread(main_window.map, main_window.flarm);
  draw_thread->start();

  // Show the infoboxes
  StartupStore(TEXT("ShowInfoBoxes\n"));
  InfoBoxManager::Show();

  // Create the calculation thread
  StartupStore(TEXT("CreateCalculationThread\n"));
  CreateCalculationThread();

#ifdef NEWTASK  
  { // NEWTASK
    PeriodClock t;
    t.reset(); t.update();
    CreateProgressDialog(gettext(TEXT("Running test 0")));
    test_newtask(0);
    StartupStore(TEXT("test 0 %d\n"),t.elapsed());

    /*
    t.update();
    CreateProgressDialog(gettext(TEXT("Running test 1")));
    test_newtask(1);
    StartupStore(TEXT("test 1 %d\n"),t.elapsed());

    t.update();
    CreateProgressDialog(gettext(TEXT("Running test 2")));
    test_newtask(2);
    StartupStore(TEXT("test 2 %d\n"),t.elapsed());

    t.update();
    CreateProgressDialog(gettext(TEXT("Running test 3")));
    test_newtask(3);
    StartupStore(TEXT("test 3 %d\n"),t.elapsed());

    t.update();
    CreateProgressDialog(gettext(TEXT("Running test 4")));
    test_newtask(4);
    StartupStore(TEXT("test 4 %d\n"),t.elapsed());
    */
    CreateProgressDialog(gettext(TEXT("test complete")));
  }
#endif

  // Initialise the airspace warning dialog
  StartupStore(TEXT("dlgAirspaceWarningInit\n"));
  dlgAirspaceWarningInit();

  // Find unique ID of this PDA
  ReadAssetNumber();

  StartupStore(TEXT("ProgramStarted\n"));

  // Give focus to the map
  main_window.map.set_focus();

  // Start calculation thread
  calculation_thread->start();

  // Start instrument thread
  instrument_thread->start();

  globalRunningEvent.trigger();

  return true;
}
Esempio n. 9
0
/**
 * Loads calculated values from the persistent memory file
 * @param Calculated DERIVED_INFO the values should be loaded into
 */
void
LoadCalculationsPersist(DERIVED_INFO *Calculated,
                        ProtectedTaskManager &protected_task_manager,
                        GlideComputer &glide_computer)
{

  return; // do nothing, this is broken for CommonStats

  // Get the persistent memory filename
  if (szCalculationsPersistFileName[0] == 0) {
    if (is_altair()) {
      LocalPath(szCalculationsPersistFileName, _T("persist/xcsoar-persist.log"));
      LocalPath(szCalculationsPersistDirectory, _T("persist"));
    } else {
      LocalPath(szCalculationsPersistFileName, _T("xcsoar-persist.log"));
      _tcscpy(szCalculationsPersistDirectory, GetPrimaryDataPath());
    }
  }

  // Debug Log
  LogStartUp(_T("LoadCalculationsPersist"));

  unsigned sizein;

  // Try to open the persistent memory file
  FILE *file = _tfopen(szCalculationsPersistFileName, _T("rb"));
  if (file == NULL) {
    LogStartUp(_T("LoadCalculationsPersist file not found"));
    return;
  }

  fread(&sizein, sizeof(sizein), 1, file);
  if (sizein != sizeof(*Calculated)) {
    fclose(file);
    return;
  }

  // Read persistent memory into Calculated
  fread(Calculated, sizeof(*Calculated), 1, file);

  fread(&sizein, sizeof(sizein), 1, file);
  if (sizein != sizeof(glide_computer.GetFlightStats())) {
    glide_computer.ResetFlight();
    fclose(file);
    return;
  }

  // Read persistent memory into FlightStats
  fread(&glide_computer.GetFlightStats(), sizeof(glide_computer.GetFlightStats()), 1, file);

  /// @todo persistence for OLC data

  fread(&sizein, sizeof(sizein), 1, file);
  if (sizein != 4 * sizeof(double)) {
    fclose(file);
    return;
  }
  GlidePolar polar = glide_computer.SettingsComputer().glide_polar_task;

  double MACCREADY = polar.get_mc();
  double BUGS = polar.get_bugs();
  double BALLAST = polar.get_ballast();

  // Read persistent memory into MacCready, QNH, bugs, ballast and temperature
  fread(&MACCREADY, sizeof(double), 1, file);
  fread(&BUGS, sizeof(double), 1, file);
  fread(&BALLAST, sizeof(double), 1, file);
  fread(&CuSonde::maxGroundTemperature,
      sizeof(CuSonde::maxGroundTemperature), 1, file);

  //    ReadFile(hFile,&CRUISE_EFFICIENCY,
  //             size,&dwBytesWritten,(OVERLAPPED*)NULL);

  MACCREADY = min(10.0, max(MACCREADY, 0.0));
  BUGS = min(1.0, max(BUGS, 0.0));
  BALLAST = min(1.0, max(BALLAST, 0.0));
  //   CRUISE_EFFICIENCY = min(1.5, max(CRUISE_EFFICIENCY,0.75));

  polar.set_mc(fixed(MACCREADY));
  polar.set_bugs(fixed(BUGS));
  polar.set_ballast(fixed(BALLAST));
  protected_task_manager.set_glide_polar(polar);

  LogStartUp(_T("LoadCalculationsPersist OK"));

  fclose(file);
}