c编写gps定位信息的接收.docx

上传人:b****5 文档编号:30100128 上传时间:2023-08-05 格式:DOCX 页数:14 大小:22.87KB
下载 相关 举报
c编写gps定位信息的接收.docx_第1页
第1页 / 共14页
c编写gps定位信息的接收.docx_第2页
第2页 / 共14页
c编写gps定位信息的接收.docx_第3页
第3页 / 共14页
c编写gps定位信息的接收.docx_第4页
第4页 / 共14页
c编写gps定位信息的接收.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

c编写gps定位信息的接收.docx

《c编写gps定位信息的接收.docx》由会员分享,可在线阅读,更多相关《c编写gps定位信息的接收.docx(14页珍藏版)》请在冰豆网上搜索。

c编写gps定位信息的接收.docx

c编写gps定位信息的接收

定位信息的接收

通常GPS定位信息接收系统主要由GPS接收天线、变频器、信号通道、微处理器、存储器以及电源等部分组成。

由于GPS定位信息内容较少,因此多用RS-232串口将定位信息(NEMA0183语句)从GPS接收机传送到计算机中进行信息提取处理。

从串口读取数据有多种方法,在此直接使用 Win32 API函数对其进行编程处理。

在Windows下不允许直接对硬件端口进行控制操作,所有的端口均被视为"文件",因此在对串口进行侦听之前需要通过打开文件来打开串口,并对其进行相关参数配置:

 

m_hCom=CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING, FILE_FLAG_OVERLAPPED,NULL);file:

//以异步方式打开COM1口 

SetCommMask(m_hCom,EV_RXCHAR);file:

//添加或修改Windows所报告的事件列表 

 SetupComm(m_hCom,READBUFLEN/*读缓冲*/,WRITEBUFLEN/*写缓冲*/);// 初始化通讯设备参数  

 // 清除缓冲信息 

PurgeComm(m_hCom,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR); // 对异步I/O进行设置 

 CommTimeOuts.ReadIntervalTimeout=MAXDWORD;file:

//接收两连续字节的最大时间间隔 

 CommTimeOuts.ReadTotalTimeoutMultiplier=0;file:

//接收每字节的平均允许时间  

 CommTimeOuts.ReadTotalTimeoutConstant=0;file:

//接收时间常数 

SetCommTimeouts(m_hCom,&CommTimeOuts) ;file:

//获取并设置串口 

GetCommState(m_hCom,&dcb); 

dcb.BaudRate=CBR_4800; 

dcb.ByteSize=8; 

dcb.Parity=ODDPARITY; 

dcb.StopBits=ONESTOPBIT ;  

SetCommState(m_hCom,&dcb);   

   在成功打开并设置通讯口后,可采取轮询串口和事件触发两种方式对数据进行接收处理,本文在此采取效率比较高的事件触发方式进行接收处理,通过等待EV_RXCHAR事件的发生来启动ReadFile函数完成对GPS定位信息的接收:

 

 while(true){ 

  WaitCommEvent (m_hCom,&dwEvtMask,NULL);  

  if (dwEvtMask&EV_RXCHAR == EV_RXCHAR) 

   if(ComStat.cbInQue>0)  

    ReadFile(m_hCom,m_readbuf,ComStat.cbInQue,&nLength,&olRead); 

 }  

  提取定位数据 

  

   GPS接收机只要处于工作状态就会源源不断地把接收并计算出的GPS导航定位信息通过串口传送到计算机中。

前面的代码只负责从串口接收数据并将其放置于缓存,在没有进一步处理之前缓存中是一长串字节流,这些信息在没有经过分类提取之前是无法加以利用的。

因此,必须通过程序将各个字段的信息从缓存字节流中提取出来,将其转化成有实际意义的,可供高层决策使用的定位信息数据。

同其他通讯协议类似,对GPS进行信息提取必须首先明确其帧结构,然后才能根据其结构完成对各定位信息的提取。

对于本文所使用的GARMIN GPS天线板,其发送到计算机的数据主要由帧头、帧尾和帧内数据组成,根据数据帧的不同,帧头也不相同,主要有"$GPGGA"、"$GPGSA"、"$GPGSV"以及"$GPRMC"等。

这些帧头标识了后续帧内数据的组成结构,各帧均以回车符和换行符作为帧尾标识一帧的结束。

对于通常的情况,我们所关心的定位数据如经纬度、速度、时间等均可以从"$GPRMC"帧中获取得到,该帧的结构及各字段释义如下:

   $GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>*hh 

  

   <1> 当前位置的格林尼治时间,格式为hhmmss 

   <2> 状态, A 为有效位置, V为非有效接收警告,即当前天线视野上方的卫星个数少于3颗。

 

   <3> 纬度, 格式为ddmm.mmmm 

   <4> 标明南北半球, N 为北半球、S为南半球 

   <5> 径度,格式为dddmm.mmmm  

   <6> 标明东西半球,E为东半球、W为西半球 

   <7> 地面上的速度,范围为0.0到999.9 

   <8> 方位角,范围为000.0到 359.9 度 

   <9> 日期, 格式为ddmmyy  

   <10> 地磁变化,从000.0到 180.0 度 

   <11> 地磁变化方向,为E 或 W 

  

   至于其他几种帧格式,除了特殊用途外,平时并不常用,虽然接收机也在源源不断地向主机发送各种数据帧,但在处理时一般先通过对帧头的判断而只对"$GPRMC"帧进行数据的提取处理。

如果情况特殊,需要从其他帧获取数据,处理方法与之也是完全类似的。

由于帧内各数据段由逗号分割,因此在处理缓存数据时一般是通过搜寻ASCII码"$"来判断是否是帧头,在对帧头的类别进行识别后再通过对所经历逗号个数的计数来判断出当前正在处理的是哪一种定位导航参数,并作出相应的处理。

下面就是对缓存Data中的数据进行解帧处理的主要代码,本文在此只关心时间(日期和时间)和地理坐标(经、纬度):

 

 for(int i=0;i

  if(Data[i]=='$') file:

//帧头,SectionID为逗号计数器 

   SectionID=0; 

   if(Data[i]==10){ file:

//帧尾 

 } 

  if(Data[i]==',') file:

//逗号计数 

   SectionID++; 

  else { 

   switch(SectionID){ 

    case 1:

 file:

//提取出时间 

     m_sTime+=Data[i]; 

     break; 

    case 2:

 file:

//判断数据是否可信(当GPS天线能接收到有3颗GPS卫星时为A,可信) 

     if(Data[i]=='A') 

      GPSParam[m_nNumber].m_bValid=true; 

      break; 

    case 3:

 file:

//提取出纬度 

      m_sPositionY+=Data[i]; 

      break; 

    case 5:

 file:

//提取出经度 

      m_sPositionX+=Data[i]; 

      break; 

    case 9:

 file:

//提取出日期 

      m_sDate+=Data[i]; 

      break; 

      default:

 

      break; 

   } 

  } 

 }  

   现在已将所需信息提取到内存,即时间、日期以及经纬度分别保存在CString型变量 m_sTime、m_Data、m_sPositionY和m_sPositionX中。

在实际应用中往往要根据需要对其做进一步的运算处理,比如从GPS接收机中获得的时间信息为格林尼治时间,因此需要在获取时间上加8小时才为我国标准时间。

而且GPS使用的WGS-84坐标系也与我国采用的坐标系不同,有时也要对此加以变换。

而这些变换运算必须通过数值运算完成,因此需要将前面获取的字符型变量转化为数值型变量,这部分工作可放在检测到帧尾完成:

 

 :

:

strcpy(buf,m_sTime);  

 str.Format("%c%c",buf[0],buf[1]); 

 GPSParam[m_nNumber].m_nHour=(atoi(str)+8)%24; file:

//提取出小时并转化为24小时制北京时间 

 file:

//buf第2、3字节为分钟,4、5字节为秒,提取方法同上 

 …… 

 :

:

strcpy(buf,m_sDate); 

 str.Format("%c%c",buf[0],buf[1]); file:

//提取出月份 

 file:

//buf第2、3字节为天,4、5字节为年,提取方法同上 

 …… 

 :

:

strcpy(buf,m_sPositionY); 

 str.Format("%c%c",buf[0],buf[1]); 

 PositionValue=atoi(str);  

 str.Format("%c%c%c%c%c%c%c",buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],buf[8]); 

 GPSParam[m_nNumber].m_dPositionY=PositionValue*60+atof(str); file:

//提取出纬度 

 …… 

 :

:

strcpy(buf,m_sPositionX); 

 if(m_sPositionX.GetLength()==10) file:

//经度超过90度(如东经125度) 

 { 

  str.Format("%c%c%c",buf[0],buf[1],buf[2]); 

  PositionValue=atoi(str); 

  str.Format("%c%c%c%c%c%c%c",buf[3],buf[4],buf[5],buf[6],buf[7],buf[8],buf[9]); 

  GPSParam[m_nNumber].m_dPositionX=PositionValue*60+atof(str); file:

//提取出经度(单位为分) 

 } 

 if(m_sPositionX.GetLength()==9) file:

//经度未超过90度(如东经89度) 

 { 

  file:

//处理方法同上,只是buf的第0、1字节为度数,2~9为分数。

 

 }  

   到此为止,已将时间和经纬度信息提取到GPS结构数组GPSParam中的各个变量中去,后续的处理和高层决策可根据该结构中存储的数据作出相应的处理。

 

摘要]

本文介绍了一个基于Java的GPS接收机解析器。

这个Java类通过解析标准GPS接收机的输出信号,能够为导航与控制系统提供GPS时钟、经度、纬度、高程等一系列信息。

本类库使用标准Java语言编写,不需要任何第三方通讯类库(包括Sun公司的Java通讯API)的支持,稍加修改即可被广泛应用在各种便携式设备和嵌入式系统中。

[介绍]

全球定位系统(GlobalPositionSystem,简称GPS)是由美国研制的导航、授时和定位系统。

该系统包括空中卫星、地面跟踪监测站、地面卫星数据注入站、地面数据处理中心和数据通讯网络等部分。

这个系统通过24颗地球同步卫星全天候向地面发送授时和定位信号,其中高精度的信号仅供美国军方和北约盟军使用,普通用户只能够接收和解析低经度的民用信号。

如果对接收到的民用信号进行差分处理,也可以得到精度很高的定位数据。

目前一般的差分GPS接收机都可以得到1米精度的定位数据,在欧美市场上已经出现了厘米级的差分GPS接收机。

普通用户只需购买GPS接收机,就可享受免费的导航、授时和定位服务。

目前全球定位系统技术在农业、林业、水利、交通、航空、测绘、安全防范、军事、电力、通讯、城市管理等领域都有广泛应用。

在上述所述应用领域中,GPS接收机通常是某些便携式设备或者是嵌入式系统的外接输入设备。

一般的GPS接收机均通过串行通讯口主动向主机发送数据,其通讯参数为4800(波特率),8(数据位),1(停止位),0(奇偶校验位)。

由于Java语言的平台无关性,很多基于便携式设备和嵌入式系统的应用程序都采用Java语言进行开发。

因此,一个基于标准Java语言的GPS接收机解析器,无疑具有广泛的应用前景。

本文所介绍的基于Java的GPS接收机解析器从标准GPS接收机的GGA输出信息中解析标准时钟(UniversalTimeCoordinate,UTC)、纬度(Latitude)、经度(Longitude)和高程(Altitude)等基本授时和定位信息。

根据美国海军电子设备标准接口规定,该信息包含标准时间、经纬度、高程等数据,每个数据之间用逗号分隔,以一个回车符号结束,一般格式如下:

$–GGA,标准时间,纬度,南北,经度,东西,信号质量,卫星总数,水平精度,高程,米,地理间隔,米,差分数据龄期,差分基准站ID*hh

$–GGA—GGA信息标示符,根据接收机的不同,该标示符中的第二和第三个字节会有所不同。

标准时间—一个浮点数,数据格式hhmmss.ss。

纬度—数据格式ddmm.mm,其中dd为度(整数,0到90);mm.mm为分(浮点数,0到60)。

南北—南北半球标示符号,一个字节,S为南半球,N为北半球。

经度—数据格式dddmm.mm,其中ddd为度(整数,0到180);mm.mm为分(浮点数,0到60)。

东西—东西半球标示符号,一个字节,E为东半球,W为西半球。

信号质量—一个整数,从0到8。

卫星总数—一个整数,从0到24。

水平精度—一个浮点数。

高程—该地点在平均海平面以上的高程,一个浮点数。

米—长度单位标示符,一个字节,M。

地理间隔—WGS-84地球椭球表面与平均海平面表面之间的距离,一个浮点数。

米—长度单位标示符,一个字节,M。

差分数据龄期—上一次SC-104标定到当前的总秒数,一个浮点数。

查分基准站ID—一个整数,从0000到1023。

除了GGA信息以外,一般的GPS接收机还会输出其他类型的信息,例如AAM信息,ACK信息,GNS信息等等。

本文所介绍的Java类库持续的监听GPS接收机所在的串行通讯口,从其输出信息中截获GGA信息并进行解析,从而获得当前的时间和定位信息。

本类库包括三个Java模块以及一组测试数据:

GPS数据模块—实时保存当前数据(GpsInfo.java)。

GPS接收机模块—供外部程序调用(GpsReceiver.java)。

数据接收与解析模块—接收与解析GPS信息(GpsParser.java)。

测试模块—功能测试与范例(TestGps.java)。

测试数据—一组实际GPS测量数据(gps.dat)。

[GPS数据模块]

GPS数据模块用来保存经过解析的授时与定位数据,同时提供访问与更新这些数据的方法。

数据接收与解析模块通过数据更新方法SetXyz()实时更新授时与定位数据,用户应用程序通过数据访问方法GetXyz()使用授时与定位数据。

考虑到可能存在多个应用程序(线程)同时对GPS数据进行修改的情况,所有的数据更新方法都利用synchronized关键字和notifyAll()方法实现了数据同步。

在这个类中包含的数据访问与更新方法比较多,部分列举如下:

数据访问方法:

publicfloatGetTime()

此方法返回当前标准时间,其返回值是一个浮点数,数据格式hhmmss.ss。

publicfloatGetLatitude()

此方法返回当前纬度信息,数据格式ddmm.mm,其中dd为度(整数,0到90);mm.mm为分(浮点数,0到60)。

publicStringGetNS()

此方法返回南北半球标示符号,一个字节,S为南半球,N为北半球。

publicfloatGetLongitude()

此方法返回当前经度信息,数据格式dddmm.mm,其中ddd为度(整数,0到180);mm.mm为分(浮点数,0到60)。

publicStringGetEW()

此方法返回东西半球标示符号,一个字节,E为东半球,W为西半球。

publicfloatGetAltitude()

此方法返回当前平均海平面以上高程,一个浮点数。

数据更新方法:

publicvoidSetTime(floattime)

此方法更新当前标准时间,输入参数是一个浮点数,数据格式hhmmss.ss。

publicvoidSetLatitude(floatlatitude)

此方法更新当前纬度信息,参数格式ddmm.mm,其中dd为度(整数,0到90);mm.mm为分(浮点数,0到60)。

publicvoidSetNS(Stringns)

此方法更新南北半球标示符号,一个字节,S为南半球,N为北半球。

publicvoidSetLongitude(floatlongitude)

此方法更新当前经度信息,参数格式dddmm.mm,其中ddd为度(整数,0到180);mm.mm为分(浮点数,0到60)。

publicvoidSetEW(Stringew)

此方法更新东西半球标示符号,一个字节,E为东半球,W为西半球。

publicvoidSetAltitude(floataltitude)

此方法更新当前平均海平面以上高程,输入参数是一个浮点数。

[GPS接收机模块]

GPS接收接模块是本类库于其他应用程序的接口,本模块为其他应用程序提供了连接、启动、切断GPS接收机以及实时查询GPS数据的方法。

具体介绍如下:

构造方法:

publicGpsReceiver(StringGpsDevice,intFactor)

publicGpsReceiver(StringGpsDevice,intFactor,booleanRecord)

其中:

GpsDevice—即将使用的GPS设备名称。

如果GPS接收机与计算机的串口COM1或者是COM2相连接,则使用”COM1″或者是”COM2″作为设备名称,以此类推;如果使用GPS数据文件代替GPS接收机的输入,则使用该文件名作为设备名称,例如”gps.dat”。

Factor—如果使用GPS数据文件代替GPS接收机的输入,则可以利用此变量制定一个加速系数,用于快速回放等功能。

普通GPS接收机每秒钟更新一次数据,如果指定加速系数为5,则每秒钟回放5秒钟的实际测量数据。

如果从GPS接收机接收数据,则需要将该参数设定为0。

Record—如果使用了GPS接收机,则可以通过将该参数设定为true来记录GPS接收机的输出数据。

这些数据可以在程序测试中模拟GPS接收机的输入。

操作方法:

publicvoidStartReceiver()

此方法启动与GPS接收机的连接,并且开始更新授时与定位数据。

publicvoidStopReceiver()

此方法停止更新授时与定位数据,并且切断与GPS接收机的连接。

publicGpsInfoGetGpsData()

此方法返回当前的授时与定位数据。

用户在使用本类库的时候,通常是先声明一个GpsReceiver对象,然后利用上述StartReceiver()方法启动与GPS接收机的连接并且开始接收与解析授时与定位信息。

当用户不再需要使用来自GPS接收机的信息时,可以利用StopReceiver()方法切断与GPS接收机的连接并且释放所占用的系统资源。

[数据接收与解析模块]

数据接收与解析模块是本类库的核心部分,这个模块负责监听GPS设备输出的信号,从中截获并解析GGA信息,从而得到最新的授时与定位数据。

该模块可以使用实时和模拟两种方式工作,在实时模式下使用GPS接收机作为输入设备,在模拟模式下使用GPS数据文件模拟GPS接收机的输入。

此外,数据接收与解析模块还能够将GPS接收机的输出数据保存到数据文件中供程序测试等使用。

因此,数据接收与解析模块的构造方法与GPS接收机模块的构造方法是类似的。

构造方法:

publicGpsParser(StringGpsDevice,intFactor,booleanRecord,GpsInfoInfo)

其中:

GpsDevice—即将使用的GPS设备名称。

如果GPS接收机与计算机的串口COM1或者是COM2相连接,则使用”COM1″或者是”COM2″作为设备名称,以此类推;如果使用GPS数据文件代替GPS接收机的输入,则使用该文件名作为设备名称,例如”gps.dat”。

Factor—如果使用GPS数据文件代替GPS接收机的输入,则可以利用此变量制定一个加速系数,用于快速回放等功能。

普通GPS接收机每秒钟更新一次数据,如果指定加速系数为5,则每秒钟回放5秒钟的实际测量数据。

如果从GPS接收机接收数据,则需要将该参数设定为0。

Record—如果使用了GPS接收机,则可以通过将该参数设定为true来记录GPS接收机的输出数据。

这些数据可以在程序测试中模拟GPS接收机的输入。

Info—用来保存授时与定位信息的GPS数据对象。

数据接收与解析模块的核心部分是一个线程,该线程被设计成一个内置类,这样的设计是的外部程序能够通过该类自定义的start()和stop()方法来启动和终止该线程。

在start()方法中将一个名为DevOn的逻辑变量设置为真并且启动数据接收与解析线程,在stop()方法中则将DevOn设置为假。

数据接收与解析线程在运行过程中不断监测DevOn的值,如果DevOn为假,则终止自身的执行。

这个设计避免了已经不鼓励使用的(deprecated)的stop()方法来强制终止线程的执行,从而保证了该线程的安全终止。

在数据接收与解析模块中把GPS输入设备统一当作文件进行处理,因为大多数的操作系统均将串行端口设置为系统保留文件,应用程序只需要对该文件进行读写即可以通过串行端口与外界设备进行通讯。

一个GPS接收机解析器只需要从串行端口实时读取数据而并不需要

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1