摘 要: 為了提高船舶試航測試系統定位數據的精確性與可靠性,同時適應現代試航測試系統的整體性能要求,開發了一種基于GPS的船舶試航數據提取與存儲系統。建立了總體架構,提出了基于多線程的GPS串口通信和SQL數據存儲的數據處理改進技術,開發了軟件系統。通過測試,證明新技術在提高試航定位數據性能方面效果顯著,同時精度符合實際需求。
關鍵詞: 全球定位系統;串口通信;多線程;微軟基礎類編程;應用程序編程接口
船舶試航是新船出廠前的一個重要測試過程,其目的在于測試船舶的航行性能,并對船舶設計方的設計做出評價,同時這些船舶實際航行的測試資料,可以為設計方設計新船舶時提供參考。
船舶試航大部分采用GPS獲取船舶的定位數據,由計程儀、羅經等相關設備記錄參數,然后通過計算和繪制航跡曲線獲得船舶性能。傳統試航作業中,一般通過手工和計算機輔助設備獲得數據,人工干預度高,難以有效獲得精確度高的數據,已無法滿足現代試航系統的數據性能要求。
目前船廠所用的船舶試航系統軟件大多工作在DOS界面上,存在穩定性差、數據安全性弱、移植性差以及人機交互不夠友好等問題。為克服DOS系統帶來的不便,2001年華南理工大學開發了一套基于VB開發的GPS船舶測試系統,整個系統雖然結構較為清晰,但由于VB本身特點,對數據處理性能以及系統穩定性有著一定的局限性。2006年,上海海事大學發表了一篇題為《基于GPS的船舶航行試驗系統研究》的論文,在VC++平臺上,應用GPS技術、計算機處理技術設計了一套完整的試航測試系統,增強了系統穩定性,但仍然存在數據接收和不能進行同步處理的問題。
為改善已有試航數據系統功能,有效提高數據穩定性與可靠性,本文在VC++平臺上,通過多線程技術以及數據提取方式的優化,提出一個新的GPS船舶試航數據處理系統。系統的主要優勢在于實時有效地接收處理GPS定位數據,提高數據精度,并結合SQL數據庫技術安全存儲。
1 系統組成
GPS船舶試航數據提取與存儲系統是GPS船舶試航系統的數據接收、處理、存儲部分,主要由兩大部分組成,如圖1所示。其中,GPS串口通信部分主要是對GPS接收機中接收到的船舶的衛星定位數據進行提取處理;數據庫存儲部分將提取處理后的有用數據按照一定的格式存儲入數據庫以供后期使用。
2 GPS串口通信
GPS接收機通過串口與PC機相連,將GPS定位數據傳輸到PC機,作為整個系統的數據源。由于本系統工作在現場,需要滿足實時穩定的通信需求,并保證接收到的GPS數據的有效性與完整性。為此,本文采用基于多線程的串口通信技術,能做到在接收定位數據的同時,對其進行提取處理。
2.1 串口通信編程
GPS串口通信的開發模式通常有Windows API、串口通信組件MSComm及第三方串口通信類。
其中,MSComm控件雖然編程簡單,但是由于進行了大量封裝,其編程的靈活性、穩定性、可控性較差;第三方串口通信類是個介于WinAPI與MScomm控件之間的方式,有一定的封裝性,但相對靈活可控,唯一的缺陷在于移植性要遜于API函數。新船試航系統需要一個能滿足較高精度,工作在現場,并且可以根據需要適應各種設備的數據提取與存儲系統。同時API函數法作為與計算機底層設備聯系最為緊密的一種實現方法,與MSComm控件和第三方通信類相比,應用于多線程系統時有更好的穩定性。因而API函數法能更好滿足試航系統需求,故本文采用API函數法來實現串口通信。
2.2 多線程編程
Windows多線程編程可以使用兩種方法:直接使用Win32 API或MFC線程技術。其中MFC編程較為簡便,更方便實現界面線程。在MFC線程技術中,線程分為用戶界面線程和工作者線程。用戶界面線程有自己的消息隊列和消息循環來處理界面消息,用來與用戶進行交互;工作者線程沒有消息循環,一般用來完成后臺工作。
結合實際需要以及編程的難易程度,本文選擇MFC線程技術實現多線程。
2.3 多線程串口通信的實現
串口通信部分分為數據處理與數據接收兩大部分。數據處理主線程CDataFlow,用于對接收到的數據提取處理;數據接收工作線程CThreadCom,用于監視串口狀態以及對GPS數據的接收。其中用WaitCommEvent函數對串口進行監視,一旦有數據到達,即可讀取進緩存區,從而增加了數據的實時性。數據接收與數據處理兩個線程的流程如圖2所示。
從圖中可以看到,接收到的數據將從緩沖區中讀出并存儲在緩存數據文件中,這樣既可以不必考慮數據處理速度對于數據接收所造成的影響,也不會造成丟失數據幀,在數據實時接收的同時,保證了數據接收的完整性。下面分別說明數據處理主線程與數據接收線程的具體實現。
(1)GPS數據格式
在說明如何實現數據接收之前,本文先討論一下GPS接收機的數據接收格式。GPS數據遵循NMEA0183協議,該協議主要用來傳輸GPS定位信息,衛星信息、經緯度信息、速度、時間等信息,輸出標準ASCII碼形式的數據信息,協議包括GPGGA、GPGSA、GPRMC、GPGLL等多種數據格式,數據格式都以“$”開頭,到*表示校驗碼開始,hh表示語句校驗碼,本文需要提取GPGGA與GPRMC中的信息。
(2)數據接收
針對實時接收數據的要求,本文使用WaitCommEvent()對串口數據進行接收。在API函數中,WaitCommEvent()、WaitForMultipleObject()和GetOverlappedResult()等函數均可以檢測到串口是否有數據。其中waitforMultipleobjects()作用為等待多個被監測內核對象的結果,getoverlappedresult()為返回最后重疊操作結果。相比之下,waitcommevent()是一個特指的通信設備等待一個事件發生,并監控與該設備句柄相關聯的一系列事件。用該函數接收數據時,一旦數據到達串口,系統將會馬上檢測到,并做好接收的準備,其關鍵實現代碼如下:
While(m_hcom!=INVALID_HANDLE_VALUE)
{dwEvent=0
WaitCommEvent(m_hCom,&dwEvent,Null);
//檢查串口事件
If((dwEvent&EV_RXCHAR)==EV_RXCHAR)
//如果發現有串口數據接收事件,接收數據
{do//循環接收串口數據
{if(nLength=ReceiveData((LPSTR)rBuf,
MAX_COM_IN_LENGTH))//
{if(dwEVENT&~EV_RXCHAR)
//如果串口數據中有字符接收事件,
//則將事件傳送CDataFlow進行處理
{if(m_pWndData)
{m_pWndData->SendMessage(m_dwMsgToData,dwEvent,0);}}}
If(nLength)//接收到數據傳給CDataFlow處理
{if(m_pWndData)
{m_pWndData->SengMessage(m_dwMsgToData,(DWORD)rBuf,nLength);}}
}while(nLength>0);}sleep(1);}sleep(1);}
(3)GPS數據處理
作為串口通信的主線程,數據處理主要功能是在緩存區中將GPGGA與GPRMC數據取出,通過數據提取函數DealFlow提取數據包,進行校驗處理后,發送消息給解碼函數OnDecodeMsg進行協議解析:先將有用NMEA數據提取,分割成數組,隨后對數組進行操作,得到需要的數據信息。這種先檢驗后分割再提取的處理方法有助于提高數據質量。流程圖如圖2所示,下面以GPGGA解碼為例,給出關鍵代碼與說明:
for(itemCount=1;itemCount<total;itemCount++)
{iLen=0//設置每項從數據的第一個字符開始處理
CString*item=m_dataArray.GetAt(itemCount);//
Switch(itemCount)//
{case1:itemLen=2;
CGPSPublic::ConverToInt((int&)pack-
>GPS_NMEA_GPGGA.body.time.hour,
item->Mid(iLen,itemLen));//
CGPSPublic::ConverToInt((int&)pack->
GPS_NMEA_GPGGA.body.time.minute,
item->Mid(iLen,itemLen));//
CGPSPublic::ConverToInt((int&)pack->
GPS_NMEA_GPGGA.body.time.second,
item->Mid(iLen,itemLen));//break;
case2:CGPSPublic::ConverToLatitudeHavePoint(
(double&)pack->GPS_NMEA_GPGGA.body.latitude.lati
tude,*item);//break;
case3:itemLen=1;
CGPSPublic::ConverToChar((char&)pack->
GPS_NMEA_GPGGA.bady.latitudetype,
*item->Mid(iLen,itemLen),itemLen);break;
……
值得一提的是,在數據提取與校驗實現算法中,對字符串操作的函數必不可少,本文主要通過使用以下幾個主要函數對字符串操作:
(1)Find()函數
該函數用于查找指定目標第一次出現在字符串中位置,如果不存在即返回值-1。Find函數在數據截取算法中主要用于查找回車符,以及NMEA-0183協議中的逗號,返回的位置參數對后面Delete函數的應用起到重要的作用。
(2)Delete()函數
該函數用于刪除字符串中無用的內容,Delete()函數包括2個基本參數,即起始位置和終點位置,函數將刪除之間的內容。
(3)Compare()函數
該函數用于比較字符串與目標字符串之間區別,可以有效地在包含大量信息的字符串中篩選出有用信息。如果字符串與目標字符串相同,則返回值為0,不相同則返回值不為0。
3 數據庫存儲
船舶試航定位信息數據庫作為后臺數據庫,不僅要提供一種可靠的數據存儲,作為定位數據信息的容器,同時還需有效地管理其中數據信息,并提供高效的數據訪問和恢復機制。下面將通過數據表的設計與ODBC數據庫互聯兩個部分來說明如何實現高效可靠的數據存儲。
(1)SQL Server數據庫配置與數據表設計
在安裝和完成SQL Server本地配置之后,需要新建一個數據庫,并添加一張表用于儲存數據。本系統需要儲存的參數是經度、緯度、速率、航向這4個數據,因此在數據庫的列設置中,需要添加這4個名稱,并且設置字符類型。由于速率和航向在位移很小時,不會顯示數據,為了避免之后編譯中出錯,應允許數據為NULL值。由于GPS接收機接收到的經緯度坐標最大長度不超過10位,因而字符類型設置為nchar(10)。
(2)ODBC數據庫互聯
開放數據庫互聯是微軟公司開放服務結構中有關數據庫的一個組成部分,它建立了一組規范,并提供了一組對數據庫訪問的標準API。這些API利用SQL來完成其大部分任務。ODBC本身也提供了對SQL語言的支持,用戶可以直接將SQL語句送給ODBC。
定位信息數據庫需要完成的主要任務是:數據動態存儲、數據表操作和數據調用,其中用到的VC++中MFC基類庫定義了3個數據庫類,CDatabase(數據庫類):對象提供數據源連接、CRecordSet(記錄集類):對象提供數據源動態行集方式的記錄集以及CRecordView(可視記錄集類):對象以控制的形式顯示數據庫記錄。
在VS2010中關聯數據庫需要添加MFCODBC使用者這個類,在設置完成類MFCODBC使用者之后,程序會自動添加兩個文件,分別是Table_1.h和Table_1.cpp(Table_1是數據庫中設置的表的名稱),并生成一個CTable_1的類,通過這個類,可以定義數據庫指針,即:Ctable_1 m_pSet。在VC++中,通過這個指針可以實現對數據庫的數據添加、刪除、查找等功能,也可以通過“.”運算代碼進行定位和賦值。在添加新記錄后,需要使用Updata()函數將緩存中保存的數據寫入數據庫中,從而完成數據庫的儲存。同樣,數據讀取功能也可以通過對指針的操作完成。圖3為數據存入情況。
本文在VC++6.0環境下,結合SQL Server技術,對GPS定位數據進行接收與提取,并存入數據庫中,以供GPS船舶試航作為基礎數據。其中,串口通信部分不僅利用了多線程技術,將數據接收與數據處理分開,有效地提高了數據的處理能力;同時在數據處理時,還通過對數據包進行預處理,剔除接收中可能產生的掉幀數據,繼而將NMEA語句分割,存入數組,并對數組進行相應解碼,實現了在提高效率的同時減少出錯的幾率。最后將解析后的數據自動存入數據庫,供GPS船舶試航系統作為基礎數據。
作為GPS新船舶試航系統的數據源,本系統已通過測試,其精度符合船廠要求,操作界面友好,現場運行效果良好。
參考文獻
[1] 徐志京,許開宇,胡文燁.基于GPS的船舶航行試驗系統研究[C].大連:中國航海學會通信導航專業委員會2006年學術年會論文集,大連海事大學出版社,2006.
[2] 李莉.GPS接收機串口通信的MSComm和API實現[J].中國新通信,2010(6):81-84.
[3] 陳凱,鄧明,張啟升,等.Windows CE下多線程串口通信[J].微計算機信息,2007,23(10-2).
[4] 劉書智.Visual C++串口通信與工程應用實踐[M].北京:中國鐵道出版社,2011.
[5] 劉夏.基于VB的GPS定位算法與軟件實現[J].計算機與數字工程,2013(2):208-211.
[6] 劉巖,汪劍云,吳北平,等.基于VB.NET的GPs接收機串口通信的實現[J].地理空間信息,2012,10(2):47-49.
[7] 李冰,曾連蓀.GPS定位信息提取及應用[J].電子設計工程,2012,20(12):72-74.
[8] 沈振漢,黃華燦.PC機與GPS接收機的通訊程序設計與實現[J].華僑大學學報(自然科學版),2011.32(1):118-120.
[9] 王靖,紀元法,孫希延,等.高動態GPS信號模擬器中串口通信的實現[J].桂林電子科技大學學報,2010,30(1):30-32.
[10] 陽世榮.基于Keil與VSPD軟件仿真的串口通信調試技術[J].艦船電子工程,2010,30(1):30-32.