国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

不同格式ASCII數(shù)據(jù)流解析方法研究

2014-08-21 08:22范娟利章傳銀方書山
全球定位系統(tǒng) 2014年1期
關(guān)鍵詞:數(shù)據(jù)格式羅盤數(shù)據(jù)流

張 超 ,范娟利 ,章傳銀 ,方書山

(1.中國測繪科學(xué)研究院,北京 100830; 2.山東科技大學(xué),山東 青島266510;3.中測新圖(北京)遙感技術(shù)有限責(zé)任公司,北京 100039)

0 引 言

隨著計算機通信技術(shù)的發(fā)展,越來越多的新技術(shù)被用到測繪行業(yè)獲取高質(zhì)量的測量數(shù)據(jù),但正確的獲取觀測數(shù)據(jù)是測量的根本,也是避免誤差的重要措施之一。全球?qū)Ш蕉ㄎ幌到y(tǒng)的數(shù)據(jù)格式遵循NEMA-0183協(xié)議,目前關(guān)于解析該類的文獻很多,但是這些文獻有的是簡單介紹一下單行數(shù)據(jù)的解析,有的是基于后處理的數(shù)據(jù)解析,有的是沒有結(jié)合讀取串口或者網(wǎng)口數(shù)據(jù)流來分析,而基于ASCII的無地址格式數(shù)據(jù)的解析更是少之又少。

在實際應(yīng)用中,GPS接收機、羅經(jīng)方位系統(tǒng)、數(shù)字羅盤等儀器輸出的數(shù)據(jù)都是NEMA-0183格式的數(shù)據(jù)[1]。另外,一些硬件廠商為了產(chǎn)品需求,方便數(shù)據(jù)收發(fā)而自定義各自的數(shù)據(jù)通信格式(用戶層面的通訊協(xié)議)的數(shù)據(jù)。

基于上述情況,本文以NEMA-0183格式數(shù)據(jù)與U型激光傳感器所示的基于ASCII碼的無地址格式數(shù)據(jù)為基礎(chǔ),詳細(xì)介紹基于串口 NEMA-0183 格式和ASCII無地址實時數(shù)據(jù)流的解析。

1 NEMA-0183 格式與基于ASCII無地址格式數(shù)據(jù)流說明

NEMA 0183是美國國家海洋電子協(xié)會(NMEA )為海用電子設(shè)備制定的標(biāo)準(zhǔn)格式。目前已成了GPS導(dǎo)航設(shè)備統(tǒng)一的國際海運事業(yè)無線電技術(shù)委員會(RTCM)標(biāo)準(zhǔn)協(xié)議。NEMA-0183 格式數(shù)據(jù)串的所有數(shù)據(jù)都采用 ASCII文本字符表示,數(shù)據(jù)傳輸以“$”開頭,后面是語句頭。語句頭由五個字母組成,分兩部分,前兩個字母表示“系統(tǒng)ID”,即表示該語句是屬于哪種系統(tǒng),后面三個字母表示“語句ID”,表示該語句是關(guān)于哪方面的數(shù)據(jù)。語句頭后是數(shù)據(jù)體,包含不同的數(shù)據(jù)體字段,語句末尾為校驗碼(可選,由十六進制組成),以回車換行符結(jié)束,單句數(shù)據(jù)結(jié)束前還有一個標(biāo)示字符“*”。數(shù)據(jù)字段以逗號分隔識別,空字段保留逗號。其通用格式如:$AABBB,<1>,<2> ,…,<12>*hh.一般NEMA-0183 格式數(shù)據(jù)以串口數(shù)據(jù)流形式輸出,其含有多條 NEMA-0183格式數(shù)據(jù),數(shù)據(jù)流形式如“…$AABBB,<1>,<2>,…,<12>*hh…$AABBB,<1>,<2>,…,<12>*hh…”的一大串多條語句一起連續(xù)輸出,其中每條語句最多包括82個字符(包括回車換行符和“$”符)[2]。

NEMA-0183協(xié)議是GPS接收機應(yīng)當(dāng)遵守的標(biāo)準(zhǔn)協(xié)議,也是目前GPS 接收機上使用最廣泛的協(xié)議,大多數(shù)常見的GPS接收機、GPS數(shù)據(jù)處理軟件、導(dǎo)航軟件都遵守或者至少兼容這個協(xié)議。本文中使用的是 NovAtel 的GPS-OEMV4板接收機。其輸出的數(shù)據(jù)格式$GPGLL,5106.9802869,N,11402.3037325,W,182147.00,A*1C。其中$GPGLL 為語句頭,5106.9802869表示51°06.9802869分,N表示緯度,11402.3037325表示 114°02.3037325 s,W表示經(jīng)度,182147.00表示18點21分47.00秒,A表示數(shù)據(jù)可用,如果是V表示數(shù)據(jù)不可用,*標(biāo)示此句馬上結(jié)束,1C為校驗和。

導(dǎo)航用的三維數(shù)字羅盤也輸出 NEMA-0183格式數(shù)據(jù),數(shù)字羅盤主要輸出姿態(tài)(航向、橫滾、俯仰)數(shù)據(jù),本文以型號為XW_EC1730的電子羅盤為例,其串口輸出的 NEMA-0183 數(shù)據(jù)格式舉例:$C220.6,P4.5,R0.3,X-8.20,Y-10.74,Z-20.33,T15.0*49.其中$:數(shù)據(jù)包幀頭,C220.6:航向角,值為220.6°,P4.5:俯仰角,值為4.5°,R0.3:橫滾角,值為0.3°,X-8.20:X軸磁場強度,值為-8.20,Y-10.74:Y軸磁場強度,值為-10.74,Z-20.33,Z軸磁場強度,值為-20.33,T15.0:傳感器溫度,值為15.0,*49,校驗和。

基于ASCII無地址格式數(shù)據(jù)是廠商根據(jù)串口通信用戶層協(xié)議編制原則:1) 數(shù)據(jù)包必須有包頭;2) 非定長數(shù)據(jù)包必須有包尾;3) 一般應(yīng)對數(shù)據(jù)進行檢校;4) 要求便于觀察的數(shù)據(jù)應(yīng)該在結(jié)尾加入換行等符號;5) 要求更新快的數(shù)據(jù),應(yīng)盡量簡短[3]自定義通信協(xié)議的典型。其數(shù)據(jù)格式是$<1>,<2>,<3>…$<1>,<2>,<3>…$<1>,<2>,<3>…,……,該數(shù)據(jù)格式與NEMA-0183數(shù)據(jù)格式最大的區(qū)別:1) 沒有類似于符號“*”的數(shù)據(jù)結(jié)束標(biāo)示符;2) “$”符號后的字段數(shù)不固定;3)每個字段長度也不固定。例如:A.如果現(xiàn)在只需要測量距離信息和激光反射強度,通過串口寫數(shù)據(jù)函數(shù),設(shè)置好后其數(shù)據(jù)流為$BM10.841,22348$BM10.842,22355$BM10.840,22991……,說明所測距離為10.841 m、10.842 m和10.840 m,分別對應(yīng)的激光反射強度為22348B、22355B、22991B.如果僅需要測量距離信息,同樣通過串口寫數(shù)據(jù)函數(shù),設(shè)置好后其數(shù)據(jù)流為$BM20.882$BM21,235$BM20.013……,其中所測距離分別為20.882 m、21,235 m、20.013 m.

2 NEMA-0183 格式與基于ASCII無地址格式數(shù)據(jù)流解析

將GPS串口、數(shù)字羅盤串口、U型傳感器串口分別與電腦連接,利用串口調(diào)試工具查找各自對應(yīng)串口號。將GPS串口波特率設(shè)置為115 200,羅盤串口波特率設(shè)置為192 00,U型激光傳感器的波特率設(shè)置為115 200.GPS 串口輸出的數(shù)據(jù)類型為 NEMA-0183 格式的 GPGLL 數(shù)據(jù),其包含測站位置數(shù)據(jù)(測站經(jīng)緯度、 對應(yīng)時間、狀態(tài)及檢校位)。數(shù)字羅盤的數(shù)據(jù)流包含姿態(tài)數(shù)據(jù)(俯仰角、方位角及翻滾角)。U型傳感器數(shù)據(jù)流包含測距數(shù)據(jù)或激光反射強度信息。連接本文設(shè)計的程序,設(shè)置好各自串口號及波特率,連接成功后通過串口采集兩種格式的ASCII數(shù)據(jù),將所需數(shù)據(jù)解析提取并存儲。

串行口的本質(zhì)功能是作為CPU和串行設(shè)備間的編碼轉(zhuǎn)換器,當(dāng)數(shù)據(jù)從CPU經(jīng)過串口發(fā)送出去時,字節(jié)數(shù)據(jù)轉(zhuǎn)換為串行位。在接收數(shù)據(jù)時,串口的位被轉(zhuǎn)換為字節(jié)數(shù)據(jù)。在Windows環(huán)境下,串口是系統(tǒng)資源的一部分,應(yīng)用程序要使用串口進行通信,必須在使用之前向操作系統(tǒng)提出資源申請(打開串口),通信完成后必須釋放資源(關(guān)閉串口)[4-7]。那么按照上節(jié)兩種格式的ASCII數(shù)據(jù)流的規(guī)律及區(qū)別,對串口數(shù)據(jù)流的讀取,采用如圖1所示的思路設(shè)計串口類。

圖1 串口數(shù)據(jù)流解析流程圖

2.1 串口類設(shè)計

本文串口類的設(shè)計以多線程串口類CSerialPort為基礎(chǔ),需要用到的主要函數(shù)有:打開關(guān)閉串口函數(shù)、串口參數(shù)設(shè)置和初始化函數(shù)、串口讀寫函數(shù)。

本文中,串口類名為:CSerialCom.定義如下:

class CSerialCom

{

……

public:

HANDLE m_hComm; //串口句柄

BOOL CreateComEvent();//建立串口通訊事件

BOOL OpenPort(int port); //打開串口,即通知其他程序禁用此串口

BOOL ConfigurePort(int baud, int timeout); //串口參數(shù)的設(shè)置和初始化

ReadFile(m_hComm, unsigned char*data, DWORD len, DWORD &read, NULL);//讀串口數(shù)據(jù)

WriteFile(m_hComm, unsigned void*data, DWORD len, DWORD &read, NULL); //寫串口數(shù)據(jù)

BOOL ClosePort(int port);//關(guān)閉使用的串口,即釋放串口以供其他程序使用

……

};

根據(jù)所需數(shù)據(jù)的類型,設(shè)計該類時只用了簡單的同步I/O數(shù)據(jù)讀寫方式。其中所用函數(shù)為Windows API函數(shù),具體使用說明可查閱相關(guān)資料。

2.2 解析NEMA-0183格式數(shù)據(jù)流與基于ASCII無地址格式數(shù)據(jù)流類的設(shè)計

由于GPS-OEM板卡輸出的數(shù)據(jù)格式與羅盤XW_EC1730輸出的數(shù)據(jù)格式都是NEMA-0183格式數(shù)據(jù),是特殊數(shù)據(jù)格式。U型激光傳感器輸出的數(shù)據(jù)格式為基于ASCII的無地址格式數(shù)據(jù),是以串口通訊標(biāo)準(zhǔn)的最基本形式。所以以U型激光傳感器輸出的基于ASCII無地址格式數(shù)據(jù)流為例。NEMA-0183數(shù)據(jù)流的解析只需在此基礎(chǔ)上稍作修改即可。

設(shè)計U型激光傳感器的基于ASCCII無地址格式數(shù)據(jù)解析類,命名為CLaserThread。利用多線程函數(shù)的功能,設(shè)計虛成員函數(shù)為Run函數(shù)。Run函數(shù)的功能就是從串口中讀取數(shù)據(jù)、解析并存儲數(shù)據(jù)。

CLaserThread的定義如下:

class CLaserThread:public CWinThread,public CSerialCom

{

public:

virtual int Run();//接收并解析串口數(shù)據(jù)

bool StoreData();//數(shù)據(jù)存儲函數(shù)

}

其中CWinThread為系統(tǒng)自帶類,具體功能可查閱相關(guān)資料。

由第1節(jié)U型激光傳感器的基于ASCII無地址格式數(shù)據(jù)流的規(guī)律,通過串口數(shù)據(jù)解析的方法為:先讀取緩存中的所有數(shù)據(jù),再對數(shù)據(jù)進行解析。由于該數(shù)據(jù)只有數(shù)據(jù)頭標(biāo)示符“$”,沒有結(jié)束符標(biāo)志,就需要特殊的方法來解析緩存區(qū)的數(shù)據(jù),指針首先找到“$”字符,然后下移直到再次遇到“$”字符,去掉最后一個“$”字符后就可以提取出第一組數(shù)據(jù),按照事先測試的每個逗號前的數(shù)據(jù)內(nèi)容,以“,”為標(biāo)志提取相關(guān)數(shù)據(jù),而“$”前的最后一個數(shù)據(jù)可通過用該組數(shù)據(jù)的總長度減去截止最后一個逗號的字符串長度來獲取,關(guān)鍵在提取第二組數(shù)據(jù)時,指針起始位置需向上移動一位,這樣再按照第一組數(shù)據(jù)提取的方式進行解析就可以得到第二組數(shù)據(jù)。如此反復(fù),就可以將讀入緩存區(qū)的數(shù)據(jù)解析完。其實現(xiàn)過程如圖2所示。

圖2 基于ASCII無格式數(shù)據(jù)流解析過程

按照上述方法設(shè)計Run函數(shù),如下:

int ClaserThread::Run()

{

unsigned char szBuffer[2048];//設(shè)置數(shù)據(jù)緩沖區(qū)大小

DWORD nReadLen = 0;//緩沖區(qū)中被讀取的字節(jié)數(shù)

int nLeftLen = 0; //未解析剩余的字節(jié)數(shù)

DWORD nOffset = 0; //每次解析完的字節(jié)數(shù)

DWORD nIndexEnd = 0; //結(jié)束符索引值

//讀取羅盤串口數(shù)據(jù)

ReadData(szBuffer + nLeftLen, sizeof(szBuffer) -nLeftLen -1, nReadLen); nLeftLen += nReadLen;

nOffset = 0;

while(nLeftLen>0){

while(nLeftLen>0){

if(szBuffer[nOffset] == '$')break;//找到數(shù)據(jù)包的幀頭

nOffset += 1;nLeftLen -= 1;}

while(int(nIndexEnd -nOffset) <= nLeftLen && nIndexEnd < (sizeof szBuffer))

{

switch(szBuffer[nIndexEnd])

{case '$':isFind=1;//是否找到數(shù)據(jù)包幀頭標(biāo)志$

break;

default:isFind=0;break;}

if (isFind){break; } else{nIndexEnd+=1; continue; }}

//如果數(shù)據(jù)包不完整情況就舍棄

if(int(nIndexEnd -nOffset) > nLeftLen|| szBuffer[nIndexEnd] == 0)

{

memmove(szBuffer, szBuffer + nOffset, nLeftLen);break;}

nLeftLen -= (nIndexEnd -nOffset + 1);

…………

while(nOffset < nIndexEnd)

{

for(int i=2;lastData;i++){

if(*(szBuffer+i)==44){

L=atof((const char*)(szBuffer+2+nOffset));//距離值

S=atof((const char*)(szBuffer+i+nOffset));//激光強度大小

lastData=false;//判斷是否到數(shù)據(jù)包結(jié)尾

StoreData();//將提取的測量數(shù)據(jù)存儲起來

}}

if (szBuffer[nIndexEnd]==_T('$')) //查找下一個字段的開始標(biāo)示符$

{nLeftLen-=nIndexEnd+1;

nOffset=nIndexEnd;}}}

::PostThreadMessage(m_nThreadID, WM_QUIT, 0, 0);

return CWinThread::Run();

}

由于篇幅限制,Run函數(shù)中部分內(nèi)容省去,僅留關(guān)鍵部分。

對于NEMA-0183格式數(shù)據(jù)流的解析,以數(shù)字電子羅盤數(shù)據(jù)為例。其解析方法為:先讀取緩存中的所有數(shù)據(jù),然后再對數(shù)據(jù)進行解析。針對NEMA-0183格式數(shù)據(jù)每句都是以“$”開頭,以“*”符號標(biāo)示結(jié)尾,他們之間的數(shù)據(jù)就是我們所需要的姿態(tài)數(shù)據(jù)。將這之間按“P”“C”“R”的標(biāo)志將三個姿態(tài)數(shù)據(jù)提取出來。解析完該句后,指針繼續(xù)下移,分別找到“$”字符和“*”字符。又解析出下組數(shù)據(jù),如此反復(fù)直到解析完該緩存區(qū)中的所有數(shù)據(jù)。等下一時刻緩存區(qū)存儲數(shù)據(jù)后再次進行解析,重復(fù)以上步驟就可實時獲取所需數(shù)據(jù)。其實現(xiàn)過程如圖3所示。

圖3 NEMA-0183格式數(shù)據(jù)流解析過程

NEMA-0183數(shù)據(jù)流解析的實現(xiàn)過程可在基于ASCII無地址格式數(shù)據(jù)流解析過程基礎(chǔ)上將代碼稍作調(diào)整即可。

3 測 試

由于實時數(shù)據(jù)流速率和大小的不確定性,作者基于vs2008sp1平臺上編寫了能夠同時接收多個串口數(shù)據(jù)的多線程程序,利用上述數(shù)據(jù)解析方法,通過自制控制板卡(串口轉(zhuǎn)USB接口控制),將連接好天線的NovAtel-OEM4板卡、數(shù)字羅盤和U型激光傳感器與PC連接,分別實現(xiàn)了NovAtel-OEM4板卡的GPS數(shù)據(jù)解析(需將存儲文件通過相應(yīng)轉(zhuǎn)換軟件分離出觀測文件、導(dǎo)航文件及氣象文件中的相關(guān)數(shù)據(jù)),數(shù)字羅盤數(shù)據(jù)解析和U型激光傳感器的基于ASCII碼的無地址數(shù)據(jù)解析。為方便查看和使用所獲數(shù)據(jù),電子羅盤數(shù)據(jù)和基于ASCII碼的無地址數(shù)據(jù)按照所需的設(shè)計格式進行存儲。如表1所示。

表1 解析結(jié)果示例

由于篇幅限制,對GPS數(shù)據(jù)的解析[8-9]不作列出。

4 結(jié)束語

通過對基于ASCII無地址格式與NEMA-0183格式實時數(shù)據(jù)流解析方法介紹與程序編寫,實現(xiàn)了相關(guān)數(shù)據(jù)的提取,驗證了上述解析方法的適用性。如果按照串口通信中用戶層協(xié)議一般編制原則,其他類似數(shù)據(jù)格式的ASCII數(shù)據(jù),就可以以NEMA-0183格式數(shù)據(jù)和基于ASCII碼無地址格式數(shù)據(jù)為基礎(chǔ),按照需求目的,在原有代碼基礎(chǔ)上,稍作改動,就可獲取所需測量信息。

[1] 袁德寶,崔希民,郎 博,等.基于VC++的GPS-0EM板卡串行通信關(guān)鍵算法的設(shè)計與實現(xiàn)[J].測繪科學(xué),2008,33(6):170-172.

[2] 龔建偉.Visual C++/Turbo C串口通信編程實踐[M].北京:電子工業(yè)出版社,2007.

[3] 汪 穎,孫華軍.基于VC++串口通信的設(shè)計與實現(xiàn)[J].現(xiàn)代電子技術(shù),2011,34(14):19-20.

[4] 唐新國.計算機串口數(shù)據(jù)采集與數(shù)據(jù)存儲的設(shè)計與應(yīng)用[J].西華師范大學(xué)學(xué)報·自然科學(xué)版,2004,25(2):213-218.

[5] 高振松,過靜珺,李冰皓,等.Windows CE下實現(xiàn)掌上機和GPS-OEM板的通信[J].測繪通報,2001(5):35-36.

[6] 汪 兵.Windows CE 嵌入式高級編程及其實例詳解[M].北京:水利水電出版社,2008.

[7] 申曉寧,趙毅強,張 進,等.多線程串口類在實時數(shù)據(jù)采集系統(tǒng)中的應(yīng)用[J].Computer Era,2010(1):28-30.

[8] 王曉東.基于VC++的GPS數(shù)據(jù)采集系統(tǒng)的設(shè)計與實現(xiàn)[J].湖北汽車工業(yè)學(xué)院學(xué)報,2006,20(2):46-49.

[9] 李洪濤,許國昌,薛鴻印,等.GPS應(yīng)用程序設(shè)計[M].北京:科學(xué)出版社,1999.

猜你喜歡
數(shù)據(jù)格式羅盤數(shù)據(jù)流
數(shù)據(jù)流計算研究進展與概述
基于FPGA的雙通道無線電羅盤激勵器的設(shè)計
汽車維修數(shù)據(jù)流基礎(chǔ)(上)
汽車維修數(shù)據(jù)流基礎(chǔ)(下)
基于磁阻傳感器的車載型磁電子羅盤的設(shè)計
AADL端對端數(shù)據(jù)流一致性驗證方法
MIT—BIH心率失常數(shù)據(jù)庫的識讀
基于RFID的戶外廣告監(jiān)管系統(tǒng)的設(shè)計與實現(xiàn)
不宜上課
一種融合多業(yè)務(wù)的信息化系統(tǒng)框架研究