使用c++提取GPS全球定位系统定位数据

来源:期刊VIP网所属分类:软件开发发布时间:2012-10-29浏览:

  摘 要:本文主要针对GPS导航定位系统,对其卫星定位信息的接收及其定位参数提取的实现方法予以介绍,并使用C++可视化编程技术得以实现。

  关键字:c++;GPS全球定位系统定位;GPS数据提取

  Abstract: This paper is focused on GPS navigation and positioning system, introduced the receiving and positioning parameters of the satellite positioning information extraction method, and use C + + programming techniques of visualization can be achieved.

  Key words: C + +; the positioning of the GPS global positioning system; GPS data extraction

  中图分类号:P28 文献标识码:A 文章编号:2095-2104(2012)

  1.引言

  近年来,卫星导航技术飞速发展,已逐渐取代了传统导航技术,逐渐成为一种普遍采用的导航定位技术,并在测量精度、实时性、全天候等方面取得了长足进步。经常性应用于物理勘探、电离层测量和航天器导航等诸多民用领域,在军事领域也取得了广泛的应用,在导弹发射、野战指挥系统、弹道测量以及军用电子地图快速测绘等领域均采用了卫星导航定位技术。由于卫星导航技术在民用和军事领域的重要意义,使其得到了许多国家的关注。我国现在也正在建立自己的卫星导航定位系统"北斗导航系统",已经在汶川地震中得到使用。目前在我国应用最多的还是美国的GPS系统和俄罗斯的GLONASS体统。

  2.定位信息的接收

  GPS定位信息接收系统主要由GPS接收天线、变频器、信号通道、微处理器、存储器以及电源等部分组成。由于GPS定位信息内容不多,数据量不大,因此多用RS-232串口将定位信息(NEMA0183语句)从GPS接收机传送到计算机中进行信息提取处理。从串口读取数据有多种方法,我在此直接使用Win32API函数对其进行编程处理。在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);

  }

  3.定位数据的提取

  GPS接收机只要处于工作状态就会持续地把接收并计算出的GPS导航定位信息通过串口传送到计算机中。前面所写的代码只负责从串口接收数据并将其放置于缓存中,在没有进一步处理之前缓存中是一长串字节流,这些信息在没有经过分类提取之前是无法利用的。因此,必须写程序将各个字段的信息从缓存字节流中提取出来,将其转化成有实际意义的、可供决策使用的定位信息数据。这同通讯协议类似,对GPS进行信息提取必须首先明确其帧结构,然后才能根据其结构完成对各定位信息的提取。对于本文所使用的GARMINGPS天线板,其发送到计算机的数据主要由帧头、帧尾和帧内数据组成,根据数据帧的不同,帧头也不相同,主要有"$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(inti=0;iBR>if(Data[i]=='$')file://帧头,SectionID为逗号计

  数器SectionID=0;

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

  }

  if(Data[i]==',')file://逗号计数

  SectionID++;

  else{

  switch(SectionID){

  case1:file://提取出时间

  m_sTime+=Data[i];

  break;

  case2:file://判断数据是否可信(当GPS天线能接收到有3

  颗GPS卫星时为A,可信)

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

  GPSParam[m_nNumber].m_bValid=true;

  break;

  case3:file://提取出纬度

  m_sPositionY+=Data[i];

  break;

  case5:file://提取出经度

  m_sPositionX+=Data[i];

  break;

  case9: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中的各个变量中去,后续的处理和高层决策可根据该结构中存储的数据作出相应的判断处理。

  4.小结

  本文对GPS全球定位系统的定位导航信息的接收和参数数据的提取进行了讨论并结合主要的在VC++相关程序代码进行提取实现,同时也对基于串口的VC++程序设计作了简要的介绍。通过本文的设计方法可以将GPS定位导航信息从GPS接收机完整接收,通过对定位参数的提取,可将其应用于各种GIS、RS系统等。本文程序在WindowsXP下,由MicrosoftVisualC++6.0编译通过。

  参考文献:

  [1] Chansarkar,M. and L. J. Garin (2000). Acquisition of GPS Signals at Very Low Signal to Noise Ratio [J]. In Proceedings of the Institute of Navigation ION National Technical Meeting-2000 (January 26-28,2000, Anaheim, California), pages 731-737.

  [2] Kuusniemi, H., and G. Lachapelle. GNSS Signal Reliability Testing in Urban and Indoor Environments [J]. Proceedings of NTM 2004(San Diego, January 24-28), 210-224.

  [3] 王晓明, 殷耀国, 杨自明. 全球导航卫星系统的现代化进展[J]. 全球定位系统, 2006, 31(4): 39- 42.

  [4] 曾庆化, 刘建业, 彭文明等. 我国卫星导航系统相关技术发展分析[J]. 航天控制, 2006, 24 ( 4) : 91- 96.

期刊VIP网,您身边的高端学术顾问

文章名称: 使用c++提取GPS全球定位系统定位数据

文章地址: http://www.qikanvip.com/ruanjiankaifa/5067.html