📄 gpsmonitorthread.cpp
字号:
/* * Roadnav * GPSMonitorThread.cpp * * Copyright (c) 2004 - 2007 Richard L. Lynch <rllynch@users.sourceforge.net> * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public License * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ ///////////////////////////////////////////////////////////////////////////////// \file////// Contains a thread that reads the current coordinates from a NMEA GPS /// unit and passes this to the update thread./////////////////////////////////////////////////////////////////////////////////#ifdef HAVE_CONFIG_H# include <config.h>#endif#ifdef _MSC_VER#pragma warning(disable: 4786)#endif#include <wx/wx.h>#include <wx/tokenzr.h>#if defined(__WINDOWS__)#include <windows.h>#endif#ifdef HAVE_SIGNAL_H#include <signal.h>#endif#include "App.h"#include "Frame.h"#include "SerialIO.h"#include "GPSMonitorThread.h"#include "libroadnav/MapSupport.h"#include "libroadnav/Debug.h"#ifdef HAVE_MATH_H#include <math.h>#endifusing namespace std;//////////////////////////////////////////////////////////////////////////////////// \brief GPS monitoring thread constructor/////////////////////////////////////////////////////////////////////////////////GPSMonitorThread::GPSMonitorThread(MapFrame * pFrame) : wxThread(wxTHREAD_JOINABLE){ m_pFrame = pFrame;}//////////////////////////////////////////////////////////////////////////////////// \brief Constructs the requested type of GPS interface object.////// \param eGPSType Requested type of GPS interface./// \return GPS interface object of requested type./////////////////////////////////////////////////////////////////////////////////IGPSInterface * GPSMonitorThread::CreateGPSObject(EGPSType eGPSType){ switch (eGPSType) {#ifdef ROADNAV_SERIAL_SUPPORT case GPSTypeSerial: return new GPSInterface_Serial();#endif#ifdef HAVE_LIBGPS case GPSTypeGPSD: return new GPSInterface_GPSD();#endif#ifdef HAVE_SIMULATED_GPS_SUPPORT case GPSTypeSimulated: return new GPSInterface_Simulated();#endif default: return new GPSInterface_None(); } wxASSERT(0); return NULL;}//////////////////////////////////////////////////////////////////////////////////// \brief Returns GPS type listed in registry./////////////////////////////////////////////////////////////////////////////////EGPSType GPSMonitorThread::GetGPSType(){ int iGPSType; g_pConfig->Read(wxT("GPSType"), &iGPSType, GPSTypeAutoDetect); return (EGPSType) iGPSType;}//////////////////////////////////////////////////////////////////////////////////// \brief Sets GPS type in registry./////////////////////////////////////////////////////////////////////////////////void GPSMonitorThread::SetGPSType(EGPSType eType){ g_pConfig->Write(wxT("GPSType"), (int) eType); g_pConfig->Flush();}//////////////////////////////////////////////////////////////////////////////////// \brief Returns the last type of GPS unit that was last autodetected./////////////////////////////////////////////////////////////////////////////////EGPSType GPSMonitorThread::GetLastSuccessfulAutoDetectGPSType(){ int iGPSType; g_pConfig->Read(wxT("LastSuccessfulAutoDetectGPSType"), &iGPSType, GPSTypeNone); return (EGPSType) iGPSType;}//////////////////////////////////////////////////////////////////////////////////// \brief Updates the last type of GPS unit that was autodetected./////////////////////////////////////////////////////////////////////////////////void GPSMonitorThread::SetLastSuccessfulAutoDetectGPSType(EGPSType eType){ g_pConfig->Write(wxT("LastSuccessfulAutoDetectGPSType"), (int) eType); g_pConfig->Flush();}///////////////////////////////////////////////////////////////////////////////// /// \brief GPS monitor worker thread.////// If autodetection is enabled, this will construct each type of GPS unit,/// ask it to autodetect, and keep cycling until one of them reports a/// locked gps unit.////// This will then call that GPS unit's GetData over and over again to/// retrieve GPS data and pass that up to MapFrame./////////////////////////////////////////////////////////////////////////////////void * GPSMonitorThread::Entry(){#if defined(__WINDOWS__) CoInitialize(NULL);#endif EGPSType eGPSType; IGPSInterface * pGPS = NULL; eGPSType = GetGPSType(); if (eGPSType == GPSTypeAutoDetectInProgress) { LibRoadnavDebug0(wxT("GPS"), wxT("Detected crash during GPS autodetect. Autodetect disabled.")); // crash occurred :( eGPSType = GPSTypeNone; SetGPSType(eGPSType); } if (eGPSType == GPSTypeAutoDetect) { bool bFound = false; bool bGPSDetected = false; LibRoadnavDebug0(wxT("GPS"), wxT("Beginning autodetection...")); // if autodetection somehow causes a crash, next time don't use it SetGPSType(GPSTypeAutoDetectInProgress); { // autodetect using last good GPS type eGPSType = GetLastSuccessfulAutoDetectGPSType(); LibRoadnavDebug1(wxT("GPS"), wxT("Autodetecting using last successful type %d"), (int) eGPSType); pGPS = CreateGPSObject(eGPSType); LibRoadnavDebug1(wxT("GPS"), wxT("Type is called %s"), pGPS->Name().c_str()); if (pGPS->AutoDetect(this) == IGPSInterface::GPSStatusOK) { LibRoadnavDebug0(wxT("GPS"), wxT("Autodetection success")); bFound = true; } else { LibRoadnavDebug1(wxT("GPS"), wxT("Autodetection error (%s)"), pGPS->GetLastError().c_str()); delete pGPS; pGPS = NULL; } } while (!TestDestroy() && !bFound) { int iGPSType; wxGPSEvent ev(true, bGPSDetected, false, Point(0, 0), 0, 0, wxT("None"), 0, NULL, 0, wxT("")); m_pFrame->AddPendingEvent(ev); bGPSDetected = false; for (iGPSType = 0; iGPSType <= ((int) GPSTYPE_MAX) && !TestDestroy() && !bFound; iGPSType++) { IGPSInterface::EGPSStatus eRtn; eGPSType = (EGPSType) iGPSType; LibRoadnavDebug1(wxT("GPS"), wxT("Autodetecting using type %d"), iGPSType); pGPS = CreateGPSObject(eGPSType); LibRoadnavDebug1(wxT("GPS"), wxT("Type is called %s"), pGPS->Name().c_str()); eRtn = pGPS->AutoDetect(this); if (eRtn == IGPSInterface::GPSStatusOK) { LibRoadnavDebug0(wxT("GPS"), wxT("Autodetection success")); bFound = true; } else { LibRoadnavDebug1(wxT("GPS"), wxT("Autodetection error (%s)"), pGPS->GetLastError().c_str()); delete pGPS; pGPS = NULL; } if (eRtn == IGPSInterface::GPSStatusAutoDetectionGPSDetectedButNoLock) bGPSDetected = true; } if (!bFound) { wxThread::Sleep(1000); } } eGPSType = GetGPSType(); // If it's still GPSTypeAutoDetectInProgress, then no one has changed it while we were // autodetecting and it should be set back to autodetect. // Otherwise, someone changed it, so leave it alone. if (eGPSType == GPSTypeAutoDetectInProgress) { SetGPSType(GPSTypeAutoDetect); } } else { pGPS = CreateGPSObject(eGPSType); } ////////////////////////////////////////////////////////////////// // Main loop ////////////////////////////////////////////////////////////////// while (!TestDestroy()) { wxGPSEvent ev; IGPSInterface::EGPSStatus rtn; rtn = pGPS->GetData(&ev); switch (rtn) { case IGPSInterface::GPSStatusOK: { m_pFrame->AddPendingEvent(ev); break; } case IGPSInterface::GPSStatusErrorDisableGPS: { wxString strError; strError = pGPS->GetLastError(); wxGPSEvent ev(false, false, false, Point(0, 0), 0, 0, wxT("None"), 0, NULL, 0, strError); m_pFrame->AddPendingEvent(ev); delete pGPS; SetGPSType(GPSTypeNone); pGPS = new GPSInterface_None(); break; } default: wxASSERT(0); break; } } if (pGPS) delete pGPS; ////////////////////////////////////////////////////////////////// // Clean up //////////////////////////////////////////////////////////////////#if defined(__WINDOWS__) CoUninitialize();#endif return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -