科技时代新浪首页 > 科技时代 > 学园 > 正文

VC++实现GPS全球定位系统定位数据的提取(2)


http://www.sina.com.cn 2006年01月16日 18:07 天极yesky

  提取定位数据

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

  小结

  本文结合主要的相关程序代码对GPS全球定位系统的定位导航信息的接收和参数数据的提取进行了讨论,同时也对串口的程序设计作了简要的讲述。通过本文的设计方法可以将GPS定位导航信息从GPS接收机完整接收,通过对定位参数的提取可将其应用于其他高层应用决策如各种GIS、RS系统等。本文程序在Windows 98下,由Microsoft Visual C++ 6.0编译通过。

[上一页] [1] [2]

发表评论

爱问(iAsk.com)



评论】【论坛】【收藏此页】【 】【多种方式看新闻】【下载点点通】【打印】【关闭




科技时代意见反馈留言板 电话:010-82628888-5595   欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

Copyright © 1996 - 2006 SINA Inc. All Rights Reserved

版权所有 新浪网