/** * 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; }
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; }
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()); }
/** * "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; }
/** * 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); }