Gps.cpp
上传用户:pumpssky
上传日期:2007-12-07
资源大小:110k
文件大小:14k
源码类别:

MacOS编程

开发平台:

C/C++

  1. // Gps.cpp: implementation of the CGps class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "gmark.h"
  6. #include "define.h"
  7. #include "Gps.h"
  8. #include "GmarkDoc.h"
  9. #include "GmarkView.h"
  10. #ifdef _DEBUG
  11. #undef THIS_FILE
  12. static char THIS_FILE[]=__FILE__;
  13. #define new DEBUG_NEW
  14. #endif
  15. FILE *fpRinex;
  16. //////////////////////////////////////////////////////////////////////
  17. // Construction/Destruction
  18. //////////////////////////////////////////////////////////////////////
  19. CGps::CGps()
  20. {
  21. m_portA.SetGps( this );
  22. m_portA.m_bNoRead = FALSE;
  23. m_portB.m_bNoRead = TRUE;
  24. // Initialize the local variable
  25. for(int i=0; i<GPS_MAX_RECNUM; i++)
  26. {
  27. m_tCommData[i] = NULL;
  28. }
  29. m_CurrIndex = 0;
  30. m_bGpsMsgBusy = FALSE;
  31. }
  32. CGps::~CGps()
  33. {
  34. // Release the memory
  35. for(int i=0; i<GPS_MAX_RECNUM; i++)
  36. {
  37. if(m_tCommData[i] != NULL) delete m_tCommData[i];
  38. }
  39. }
  40. void CGps::OnReceived(unsigned char *buf, int nBytes)
  41. {
  42. m_pLog->Write((const char *)buf);
  43. /* char sTemp[256];
  44. memset(sTemp,0,sizeof(sTemp));
  45. sprintf(sTemp,"nBytes=%d, len=%d, buf[0]=%2X", nBytes, strlen((const char*)buf), buf[0]);
  46. m_pLog->Write((const char *)sTemp);*/
  47. ::SendMessage( m_hGmarkView, WM_GPSRECEIVED, (WORD)nBytes, (LONG)buf );
  48. }
  49. void CGps::AddChecksum(LPSTR cmd, LPSTR chksum)
  50. {
  51. int nIndex;
  52. int nLength;
  53. unsigned char cChkSum;
  54. unsigned char str[4];
  55. if(cmd == NULL || chksum == NULL) return;
  56. nLength =  strlen(cmd);
  57. if( nLength < 1 ) return; //empty command not need to add chksum
  58. memset( str, 0, sizeof(str) );
  59. cChkSum = 0;
  60. nIndex = 1;
  61. while( nIndex < nLength )
  62. {
  63. cChkSum = cChkSum^cmd[nIndex];
  64. nIndex++;
  65. }
  66. sprintf((char *)str, "*%02X", cChkSum);
  67. strcpy( chksum, cmd );
  68. chksum[nLength] = str[0];
  69. chksum[nLength+1] = str[1];
  70. chksum[nLength+2] = str[2];
  71. }
  72. void CGps::GetToken(LPSTR str, int n, LPSTR token)
  73. {
  74. int nLength =  strlen(str);
  75. int nCount = 0;
  76. int nTokenCount = 0;
  77. LPSTR szResult = new char[nLength+1];
  78. memset( szResult, 0,  nLength+1);
  79. while( nCount < nLength)
  80. {
  81. if( str[nCount] == ',' || str[nCount] == '*' )
  82. {
  83. if( nTokenCount == n )
  84. {
  85. break;
  86. }
  87. else
  88. {
  89. nTokenCount++;
  90. memset( szResult, 0,  nLength+1);
  91. }
  92. }
  93. else 
  94. {
  95. szResult[strlen(szResult)] = str[nCount]; 
  96. }
  97. nCount++;
  98. }
  99. strcpy( token, szResult );
  100. delete szResult;
  101. }
  102. void CGps::CompleteMsg(unsigned char *buf, int nBytes)
  103. {
  104. int nLen = nBytes;
  105. char *p = (char *)buf;
  106. char *CompMsg = new char[nLen + 1];
  107. int index = m_CurrIndex;
  108. int nIsCompleted;
  109. int nIsFoundPlace = 0;
  110. int nOrgLen = 0;
  111. int nCompLen= 0;
  112. nOrgLen = nBytes; 
  113. do
  114. {
  115. memset( CompMsg, 0, nLen + 1 );
  116. nIsCompleted = GetCompleteMsg( p, nOrgLen, CompMsg, nCompLen );
  117. //reset the offset in case anything left
  118. if( nIsCompleted == RET_OK) 
  119. {
  120. p = p + nCompLen + 2;
  121. nOrgLen = nOrgLen - nCompLen - 2;
  122. }
  123. // Find an index not completed to place the message
  124. index = m_CurrIndex;
  125. nIsFoundPlace = 0;
  126. do 
  127. {
  128. if( m_tCommData[index] == NULL ) 
  129. {
  130. m_tCommData[index] = new COMM_DATA;
  131. m_tCommData[index]->CompleteFlg = 0;
  132. memset( m_tCommData[index]->Message, 
  133. 0, 
  134. sizeof(m_tCommData[index]->Message) );
  135. nIsFoundPlace = 1;
  136. break;
  137. }
  138. else 
  139. {
  140. if( m_tCommData[index]->CompleteFlg == 1 )
  141. {
  142. index = IndexIncrease( index );
  143. continue;
  144. }
  145. nIsFoundPlace = 1;
  146. break;
  147. }
  148. } while(index != m_CurrIndex); //search only one round
  149. // append the message
  150. if(nIsFoundPlace == 1)
  151. {
  152. memcpy( m_tCommData[index]->Message + strlen(m_tCommData[index]->Message), 
  153. (const char *)CompMsg, nCompLen );
  154. }
  155. else 
  156. {
  157. memset( m_tCommData[index]->Message, 
  158. 0, 
  159. sizeof(m_tCommData[index]->Message) );
  160. memcpy( m_tCommData[index]->Message, 
  161. (const char *)CompMsg, nCompLen );
  162. }
  163. // set the flag
  164. if(nIsCompleted == RET_OK)
  165. {
  166. m_tCommData[index]->CompleteFlg = 1;
  167. // refresh the current index
  168. m_CurrIndex = IndexIncrease( index );
  169. }
  170. }while( (nIsCompleted == RET_OK) && (strlen(p) > 0) );
  171. delete CompMsg;
  172. }
  173. void CGps::CreateGPSData()
  174. {
  175. int index;
  176. char szCmdType[GPS_MAX_NEMASIZE+1];
  177. int nIsUpdate;
  178. index = m_CurrIndex;
  179. nIsUpdate = 0;
  180. do {
  181. if( m_tCommData[index] != NULL &&
  182. m_tCommData[index]->CompleteFlg == 1 ) 
  183. {
  184. // process message only when the checksum is right
  185. if( IsChecksumCorrect( m_tCommData[index]->Message) )
  186. {
  187. memset( szCmdType, 0, sizeof(szCmdType) );
  188. //according the command type do corresponding deal
  189. GetToken( m_tCommData[index]->Message, 0, szCmdType );
  190. if(strcmp(szCmdType, "$GPGGA") == 0)
  191. {
  192. ParseGGA( m_tCommData[index]->Message );
  193. // need to update gps data in the view
  194. nIsUpdate = 1;
  195. }
  196. else if(strcmp(szCmdType, "$GPGLL") == 0)
  197. {
  198. ParseGLL( m_tCommData[index]->Message );
  199. nIsUpdate = 1;
  200. }
  201. else if(strcmp(szCmdType, "$GPGSA") == 0)
  202. {
  203. ParseGSA( m_tCommData[index]->Message );
  204. nIsUpdate = 1;
  205. }
  206. else if(strcmp(szCmdType, "$PASHR") == 0)
  207. {
  208. GetToken( m_tCommData[index]->Message, 1, szCmdType );
  209. if(strcmp(szCmdType, "PBN") == 0) // PBN data
  210. {
  211. ParsePBN( m_tCommData[index]->Message );
  212. }
  213. if(strcmp(szCmdType, "MCA") == 0) // MCA data
  214. {
  215. ParseMCA( m_tCommData[index]->Message );
  216. }
  217. if(strcmp(szCmdType, "SNV") == 0) // SNV data
  218. {
  219. ParseSNV( m_tCommData[index]->Message );
  220. }
  221. else if(strcmp(szCmdType, "CRT") == 0)
  222. {
  223. ParseCRT( m_tCommData[index]->Message );
  224. }
  225. }
  226. }
  227. // release the record memory
  228. delete m_tCommData[index];
  229. m_tCommData[index] = NULL;
  230. }
  231. index = IndexIncrease( index );
  232. }
  233. while( index != m_CurrIndex );
  234. if( nIsUpdate == 1 )
  235. {
  236. // Notify the view to refresh the gps data
  237. ::PostMessage( m_hGmarkView, WM_GPSUPDATE, 0, 0 );
  238. }
  239. }
  240. int CGps::IndexIncrease(int index)
  241. {
  242. if( index >= GPS_MAX_RECNUM - 1 ) index = 0;
  243. else index++;
  244. return index;
  245. }
  246. int CGps::IndexDecrease(int index)
  247. {
  248. if( index <= 0 ) index = GPS_MAX_RECNUM - 1;
  249. else index--;
  250. return index;
  251. }
  252. void CGps::ParseGGA(char *Message)
  253. {
  254. char szToken[GPS_MAX_NEMASIZE+1];
  255. double c = 111352.0044; // = r*pai/180 = 6380000(m)*3.1415926/180
  256. GetToken( Message, 6, szToken );
  257. m_tGpsData.Status = atoi(szToken);
  258. GetToken( Message, 7, szToken );
  259. m_tGpsData.SatCount = atoi(szToken);
  260. GetToken( Message, 4, szToken );
  261. m_tGpsData.Longitude = DegToVal(szToken); //Jing du
  262. m_tGpsData.LonDeg = (int)m_tGpsData.Longitude;
  263. m_tGpsData.LonMin = (int)((m_tGpsData.Longitude - m_tGpsData.LonDeg)*60);
  264. m_tGpsData.LonSec = ((m_tGpsData.Longitude - m_tGpsData.LonDeg)*60 - m_tGpsData.LonMin)*60;
  265. GetToken( Message, 2, szToken );
  266. m_tGpsData.Latitude = DegToVal(szToken); //Wei du
  267. m_tGpsData.LatDeg = (int)m_tGpsData.Latitude;
  268. m_tGpsData.LatMin = (int)((m_tGpsData.Latitude - m_tGpsData.LatDeg)*60);
  269. m_tGpsData.LatSec = ((m_tGpsData.Latitude - m_tGpsData.LatDeg)*60 - m_tGpsData.LatMin)*60;
  270. // chang (longitude,latitude) to (x,y)
  271. // m_tGpsData.X =(m_tGpsData.Longitude - m_orig_lon)*c;
  272. // m_tGpsData.Y =(m_tGpsData.Latitude - m_orig_lat)*c;
  273. }
  274. void CGps::ParseGLL(char *Message)
  275. {
  276. char szToken[GPS_MAX_NEMASIZE+1];
  277. GetToken( Message, 1, szToken );
  278. m_tGpsData.Latitude = DegToVal(szToken);
  279. GetToken( Message, 3, szToken );
  280. m_tGpsData.Longitude = DegToVal(szToken);
  281. GetToken( Message, 6, szToken );
  282. // m_tGpsData.Status = atoi(szToken);
  283. }
  284. void CGps::ParseGSA(char *Message)
  285. {
  286. char szToken[GPS_MAX_NEMASIZE+1];
  287. GetToken( Message, 15, szToken );
  288. m_tGpsData.PDOP = atof(szToken);
  289. GetToken( Message, 16, szToken );
  290. m_tGpsData.HDOP = atof(szToken);
  291. GetToken( Message, 17, szToken );
  292. m_tGpsData.VDOP = atof(szToken);
  293. }
  294. void CGps::ParseCRT(char *Message)
  295. {
  296. char szToken[GPS_MAX_NEMASIZE+1];
  297. GetToken( Message, 2, szToken );
  298. m_tGpsData.Status = atoi(szToken);
  299. GetToken( Message, 3, szToken );
  300. m_tGpsData.SatCount = atoi(szToken);
  301. GetToken( Message, 5, szToken );
  302. m_tGpsData.X = atof(szToken);
  303. GetToken( Message, 6, szToken );
  304. m_tGpsData.Y = atof(szToken);
  305. GetToken( Message, 13, szToken );
  306. m_tGpsData.PDOP = atof(szToken);
  307. GetToken( Message, 14, szToken );
  308. m_tGpsData.HDOP = atof(szToken);
  309. GetToken( Message, 15, szToken );
  310. m_tGpsData.VDOP = atof(szToken);
  311. }
  312. void CGps::ParsePBN(char *Message)
  313. {
  314. #define PBN_DATA_SIZE 56
  315. char PbnData[PBN_DATA_SIZE];
  316. memcpy( PbnData, Message + 11, PBN_DATA_SIZE );
  317. if( !BinCheckSum(PbnData, PBN_DATA_SIZE) ) return;
  318. PBN_DATA *pbnData;
  319. // get PBN_DATA structure
  320. pbnData = (PBN_DATA *)PbnData;
  321. // write PBN_DATA to RINEX file
  322. fwrite(pbnData, 1, sizeof(PBN_DATA), fpRinex);
  323. }
  324. void CGps::ParseMCA(char *Message)
  325. {
  326. #define MCA_DATA_SIZE 37
  327. char McaData[MCA_DATA_SIZE];
  328. memcpy( McaData, Message + 11, MCA_DATA_SIZE );
  329. if( !BinCheckSum(McaData, MCA_DATA_SIZE, 1) ) return;
  330. MCA_DATA *mcaData;
  331. // get MCA_DATA structure
  332. mcaData = (MCA_DATA *)McaData;
  333. // write MCA_DATA to RINEX file
  334. fwrite(mcaData, 1, sizeof(MCA_DATA), fpRinex);
  335. }
  336. void CGps::ParseSNV(char *Message)
  337. {
  338. #define SNV_DATA_SIZE 132
  339. char SnvData[SNV_DATA_SIZE];
  340. memcpy( SnvData, Message + 11, SNV_DATA_SIZE );
  341. if( !BinCheckSum(SnvData, SNV_DATA_SIZE) ) return;
  342. SNV_DATA *snvData;
  343. // get SNV_DATA structure
  344. snvData = (SNV_DATA *)SnvData;
  345. // write SNV_DATA to RINEX file
  346. fwrite(snvData, 1, sizeof(SNV_DATA), fpRinex);
  347. }
  348. double CGps::DegToVal(char *deg)
  349. {
  350. double result;
  351. char *p=NULL;
  352. char d[4];
  353. char m[9];
  354. memset( d, 0, sizeof(d) );
  355. memset( m, 0, sizeof(m) );
  356. p = strstr( deg, "." );
  357. if(p)
  358. {
  359. int n = p-deg;
  360. strncpy( d, deg, n-2 );
  361. strncpy( m, deg+n-2, 8 );
  362. }
  363. else
  364. {
  365. strncpy( d, deg, sizeof(d)-1 );
  366. strcpy( m, "" );
  367. }
  368. result = atoi(d) + atof(m)/60;
  369. return result;
  370. }
  371. int CGps::SendCmd(LPSTR cmd)
  372. {
  373. LPSTR pSendCmd;
  374. char szCrLf[3] = {0x0d, 0x0a, 0};
  375. int nLength;
  376. int nRet;
  377. nLength =  strlen(cmd);
  378. pSendCmd = new char[nLength + 6];
  379. memset( pSendCmd, 0, nLength + 6 );
  380. // add checksum to command
  381. AddChecksum(cmd, pSendCmd);
  382. // add <cr>+<lf>
  383. strcpy( pSendCmd + strlen(pSendCmd), szCrLf );
  384. nRet = m_portA.SendData(pSendCmd, strlen(pSendCmd));
  385. if( (unsigned int)nRet != strlen(pSendCmd) ) nRet = RET_NG;
  386. else nRet = RET_OK;
  387. delete pSendCmd;
  388. return nRet;
  389. }
  390. int CGps::Initialize(int baudrate)
  391. {
  392. int nRet = RET_OK;
  393. //set the GGA message to be output automatically every 1 second.
  394. SendCmd("$PASHS,NME,GGA,A,ON,1");
  395. //Initialize the COM6 for port B of GPS module
  396. return nRet;
  397. }
  398. int CGps::Close()
  399. {
  400. int nRet = RET_OK;
  401. if(!m_portA.Close()) nRet = RET_NG;
  402. if(!m_portB.Close()) nRet = RET_NG;
  403. //close the raw data file
  404. fclose(fpRinex);
  405. return nRet;
  406. }
  407. void CGps::SetViewHandle(HWND hView)
  408. {
  409. m_hGmarkView = hView;
  410. }
  411. int CGps::Connect()
  412. {
  413. int nRet = RET_OK;
  414. //Initialize the COM2 for port A of GPS module
  415. while(1)
  416. {
  417. //the default bps of port A is 4800
  418. #ifndef _WIN32_WCE_CEPC
  419. if( m_portA.Open(2, 115200) == FALSE )
  420. #else
  421. if( m_portA.Open(1, 115200) == FALSE )
  422. #endif
  423. {
  424. nRet = RET_NG;
  425. break;
  426. }
  427. //the default bps of port B is 4800
  428. #ifndef _WIN32_WCE_CEPC
  429. if( m_portB.Open(6, 57600) == FALSE )
  430. #else
  431. if( m_portB.Open(0, 57600) == FALSE )
  432. #endif
  433. {
  434. nRet = RET_NG;
  435. break;
  436. }
  437. break;
  438. }
  439. //open file to write raw data
  440. char filename[MAX_PATH];
  441. memset( filename, 0, sizeof(filename) );
  442. this->m_GmarkView->CreateFilename(filename, FN_RAW);
  443. fpRinex = fopen( filename, "wb" );
  444. return nRet;
  445. }
  446. HWND CGps::GetViewHandle()
  447. {
  448. return m_hGmarkView;
  449. }
  450. int CGps::GetCompleteMsg(LPSTR OrgMsg, int nOrgLen, LPSTR CompMsg, int & nCompLen)
  451. {
  452. int nRet = RET_NG;
  453. char * p = NULL;
  454. for(int i = 0; i < nOrgLen-1; i++)
  455. {
  456. if( OrgMsg[i] == 0x0d &&
  457. OrgMsg[i+1] == 0x0a )
  458. {
  459. p = OrgMsg + i;
  460. break;
  461. }
  462. }
  463. if( p == NULL )
  464. {
  465. memcpy( CompMsg, OrgMsg, nOrgLen );
  466. nCompLen = nOrgLen;
  467. nRet = RET_NG;
  468. }
  469. else
  470. {
  471. nCompLen = p - OrgMsg;
  472. memcpy( CompMsg, OrgMsg, nCompLen );
  473. nRet = RET_OK;
  474. }
  475. return nRet;
  476. }
  477. void CGps::ClearGpsData()
  478. {
  479. m_tGpsData.Latitude = -1;
  480. m_tGpsData.Longitude = -1;
  481. m_tGpsData.SatCount = -1;
  482. m_tGpsData.Status = -1;
  483. // Notify the view to refresh the gps data
  484. ::PostMessage( m_hGmarkView, WM_GPSUPDATE, 0, 0 );
  485. }
  486. void CGps::WriteRTCM(char *rtcm)
  487. {
  488. m_portB.SendData( rtcm, strlen(rtcm) );
  489. }
  490. void CGps::SetOrigPosition(double orig_lon, double orig_lat)
  491. {
  492. m_orig_lon = orig_lon;
  493. m_orig_lat = orig_lat;
  494. }
  495. BOOL CGps::IsChecksumCorrect(char *message)
  496. {
  497. char szCmd[GPS_MAX_NEMASIZE+1];
  498. char szChecksum[GPS_MAX_NEMASIZE+1];
  499. char *p;
  500. memset(szCmd, 0, sizeof(szCmd));
  501. memset(szChecksum, 0, sizeof(szChecksum));
  502. if(strncmp(message, "$PASHR,PBN,", 11)==0)
  503. {
  504. return TRUE;
  505. }
  506. p = strstr( message, "*" );
  507. if(!p)
  508. {
  509. return FALSE;
  510. }
  511. strncpy( szCmd, message, p-message );
  512. AddChecksum( szCmd, szChecksum );
  513. if( strcmp( message, szChecksum ) != 0 )
  514. {
  515. return FALSE;
  516. }
  517. return TRUE;
  518. }
  519. void CGps::SetViewWnd(CWnd *pWnd)
  520. {
  521. m_GmarkView = (CGmarkView *)pWnd;
  522. }
  523. BOOL CGps::BinCheckSum(char *buf, int len, int BinType)
  524. {
  525. if(BinType == 0)
  526. {
  527. unsigned short chsum, checksum;
  528. unsigned short * p;
  529. p = (unsigned short *)buf;
  530. chsum = 0;
  531. for(int i=0; i<len-2; i+=2)
  532. {
  533. chsum += *p;
  534. p++;
  535. }
  536. checksum = *p;
  537. if(chsum == checksum) return TRUE;
  538. else return FALSE;
  539. }
  540. else
  541. {
  542. unsigned char chsum, checksum;
  543. unsigned char * p;
  544. p = (unsigned char *)buf;
  545. chsum = 0;
  546. for(int i=0; i<len-1; i++)
  547. {
  548. chsum = (*p)^chsum;
  549. p++;
  550. }
  551. checksum = *p;
  552. if(chsum == checksum) return TRUE;
  553. else return FALSE;
  554. }
  555. }