gis
gis
管理员
管理员
  • 注册日期2003-07-16
  • 发帖数15947
  • QQ554730525
  • 铜币25339枚
  • 威望15364点
  • 贡献值0点
  • 银元0个
  • GIS帝国居民
  • 帝国沙发管家
  • GIS帝国明星
  • GIS帝国铁杆
阅读:3845回复:9

全球定位系统(GPS)定位数据的提取

楼主#
更多 发布于:2004-09-29 14:13
<P><B>引言</B></P>


<P>随着卫星导航技术的飞速发展,现已基本取代了无线电导航、天文导航等传统导航技术,已成为一种普遍采用的导航定位技术,并在精度、实时性、全天候等方面取得了长足进步。现不仅应用于物

<TABLE height=315 cellSpacing=0 cellPadding=0 width=370 align=left border=0>

<TR>
<TD vAlign=center></TD></TR></TABLE>理勘探、电离层测量和航天器导航等诸多民用领域,在军事领域更是取得了广泛的应用——在弹道导弹、野战指挥系统、精确弹道测量以及军用地图快速测绘等领域均大量采用了卫星导航定位技术。有鉴于卫星导航技术在民用和军事领域的重要意义,使其得到了许多国家的关注。应用最广的是美国的GPS全球定位系统,以前由于美军人为施加了SA干扰,使美军之外的用户只能得到位置精度100米,授时精度340纳秒的服务。但随着1995年俄罗斯GLONASS全球导航卫星系统的组建完毕和欧洲GALILEO导航卫星系统计划、日本区域性导航卫星系统计划的启动,使美国政府迫于竞争压力于2000年5月1日午夜撤销对GPS的SA干扰,使位置精度提升到20米,授时精度提高到40纳秒,并承诺加速星座改善,增加两个民用频率。尽管GLONASS系统没有进行SA干扰,但由于其目前不能独立组网,须与GPS联用,故应用远没有GPS普及。此外尽管我国也于2000年10月31日和12月21日成功发射了第一颗和第二颗导航定位试验卫星并建立了我国第一代卫星导航定位系统——“北斗导航系统”,但由于起步晚也没有得到广泛应用。目前在我国应用最多的还是美国的GPS系统,仅渔船就有10万余条装备了GPS接收机,占全部渔船的1/3。本文就针对当前比较普及的GPS系统,对其卫星定位信息的接收及其定位参数的提取的实现方法予以介绍。</P>
<p>
<P><B>1 定位信息的接收</B></P>
<p>
<P>通常GPS定位信息接收系统主要由GPS接收天线、变频器、信号通道、微处理器、存储器以及电源等部分组成。由于GPS定位信息内容较少,因此多用RS-232串口将定位信息(NEMA0183语句)从GPS接收机传送到计算机中进行信息提取处理。从串口读取数据有多种方法,在此直接使用 Win32 API函数对其进行编程处理。在Windows下不允许直接对硬件端口进行控制操作,所有的端口均被视为“文件”,因此在对串口进行侦听之前需要通过打开文件来打开串口,并对其进行相关参数配置:</P>
<p>
<P>m_hCom=CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING, FILE_FLAG_OVERLAPPED,NULL); //以异步方式打开COM1口</P>
<P>SetCommMask (m_hCom, EV_RXCHAR ) ; //添加或修改Windows所报告的事件列表</P>
<P>SetupComm (m_hCom,READBUFLEN/*读缓冲*/,WRITEBUFLEN/*写缓冲*/); // 初始化通讯设备参数 </P>
<P>// 清除缓冲信息</P>
<P>PurgeComm (m_hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR) ;</P>
<P>// 对异步I/O进行设置</P>
<P>CommTimeOuts.ReadIntervalTimeout = MAXDWORD ; //接收两连续字节的最大时间间隔</P>
<P>CommTimeOuts.ReadTotalTimeoutMultiplier =0; //接收每字节的平均允许时间 </P>
<P>CommTimeOuts.ReadTotalTimeoutConstant = 0 ; //接收时间常数</P>
<P>SetCommTimeouts (m_hCom , ;CommTimeOuts) ;</P>
<P>//获取并设置串口</P>
<P>GetCommState ( m_hCom, ;dcb) ;</P>
<P>dcb.BaudRate = CBR_4800;</P>
<P>dcb.ByteSize = 8;</P>
<P>dcb.Parity = ODDPARITY;</P>
<P>dcb.StopBits = ONESTOPBIT ; </P>
<P>SetCommState( m_hCom, ;dcb);</P>
<p>
<P>在成功打开并设置通讯口后,可采取轮询串口和事件触发两种方式对数据进行接收处理,本文在此采取效率比较高的事件触发方式进行接收处理,通过等待EV_RXCHAR事件的发生来启动ReadFile函数完成对GPS定位信息的接收:</P>
<p>
<P>while(true){</P>
<P>WaitCommEvent (m_hCom,;dwEvtMask,NULL); </P>
<P>if (dwEvtMask;EV_RXCHAR == EV_RXCHAR)</P>
<P>if(ComStat.cbInQue>0) </P>
<P>ReadFile(m_hCom,m_readbuf,ComStat.cbInQue,;nLength,;olRead);</P>
<P>}</P>
<p>
<P><B>2 提取定位数据</B></P>
<p>
<P>GPS接收机只要处于工作状态就会源源不断地把接收并计算出的GPS导航定位信息通过串口传送到计算机中。前面的代码只负责从串口接收数据并将其放置于缓存,在没有进一步处理之前缓存中是一长串字节流,这些信息在没有经过分类提取之前是无法加以利用的。因此,必须通过程序将各个字段的信息从缓存字节流中提取出来,将其转化成有实际意义的,可供高层决策使用的定位信息数据。同其他通讯协议类似,对GPS进行信息提取必须首先明确其帧结构,然后才能根据其结构完成对各定位信息的提取。对于本文所使用的GARMIN GPS天线板,其发送到计算机的数据主要由帧头、帧尾和帧内数据组成,根据数据帧的不同,帧头也不相同,主要有“$GPGGA”、“$GPGSA”、“$GPGSV”以及“$GPRMC”等。这些帧头标识了后续帧内数据的组成结构,各帧均以回车符和换行符作为帧尾标识一帧的结束。对于通常的情况,我们所关心的定位数据如经纬度、速度、时间等均可以从“$GPRMC”帧中获取得到,该帧的结构及各字段释义如下:</P>
<p>
<P>$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>*hh<CR><LF></P>
<p>
<P><1> 当前位置的格林尼治时间,格式为hhmmss</P>
<P><2> 状态, A 为有效位置, V为非有效接收警告,即当前天线视野上方的卫星个数少于3颗。</P>
<P><3> 纬度, 格式为ddmm.mmmm</P>
<P><4> 标明南北半球, N 为北半球、S为南半球</P>
<P><5> 径度,格式为dddmm.mmmm </P>
<P><6> 标明东西半球,E为东半球、W为西半球</P>
<P><7> 地面上的速度,范围为0.0到999.9</P>
<P><8> 方位角,范围为000.0到 359.9 度</P>
<P><9> 日期, 格式为ddmmyy </P>
<P><10> 地磁变化,从000.0到 180.0 度</P>
<P><11> 地磁变化方向,为E 或 W</P>
<p>
<P>至于其他几种帧格式,除了特殊用途外,平时并不常用,虽然接收机也在源源不断地向主机发送各种数据帧,但在处理时一般先通过对帧头的判断而只对“$GPRMC”帧进行数据的提取处理。如果情况特殊,需要从其他帧获取数据,处理方法与之也是完全类似的。由于帧内各数据段由逗号分割,因此在处理缓存数据时一般是通过搜寻ASCII码“$”来判断是否是帧头,在对帧头的类别进行识别后再通过对所经历逗号个数的计数来判断出当前正在处理的是哪一种定位导航参数,并作出相应的处理。下面就是对缓存Data中的数据进行解帧处理的主要代码,本文在此只关心时间(日期和时间)和地理坐标(经、纬度):</P>
<p>
<P>for(int i=0;i<DataLength;i++){</P>
<P>if(Data=='$') //帧头,SectionID为逗号计数器</P>
<P>SectionID=0;</P>
<P>if(Data==10){ //帧尾</P>
<P>}</P>
<P>if(Data==',') //逗号计数</P>
<P>SectionID++;</P>
<P>else {</P>
<P>switch(SectionID){</P>
<P>case 1: //提取出时间</P>
<P>m_sTime+=Data;</P>
<P>break;</P>
<P>case 2: //判断数据是否可信(当GPS天线能接收到有3颗GPS卫星时为A,可信)</P>
<P>if(Data=='A')</P>
<P>GPSParam[m_nNumber].m_bValid=true;</P>
<P>break;</P>
<P>case 3: //提取出纬度</P>
<P>m_sPositionY+=Data;</P>
<P>break;</P>
<P>case 5: //提取出经度</P>
<P>m_sPositionX+=Data;</P>
<P>break;</P>
<P>case 9: //提取出日期</P>
<P>m_sDate+=Data;</P>
<P>break;</P>
<P>default:</P>
<P>break;</P>
<P>}</P>
<P>}</P>
<P>}</P>
<p>
<P>现在已将所需信息提取到内存,即时间、日期以及经纬度分别保存在CString型变量 m_sTime、m_Data、m_sPositionY和m_sPositionX中。在实际应用中往往要根据需要对其做进一步的运算处理,比如从GPS接收机中获得的时间信息为格林尼治时间,因此需要在获取时间上加8小时才为我国标准时间。而且GPS使用的WGS-84坐标系也与我国采用的坐标系不同,有时也要对此加以变换。而这些变换运算必须通过数值运算完成,因此需要将前面获取的字符型变量转化为数值型变量,这部分工作可放在检测到帧尾完成:</P>
<p>
<P>::strcpy(buf,m_sTime); </P>
<P>str.Format("%c%c",buf[0],buf[1]);</P>
<P>GPSParam[m_nNumber].m_nHour=(atoi(str)+8)%24; //提取出小时并转化为24小时制北京时间</P>
<P>//buf第2、3字节为分钟,4、5字节为秒,提取方法同上</P>
<P>……</P>
<P>::strcpy(buf,m_sDate);</P>
<P>str.Format("%c%c",buf[0],buf[1]); //提取出月份</P>
<P>//buf第2、3字节为天,4、5字节为年,提取方法同上</P>
<P>……</P>
<P>::strcpy(buf,m_sPositionY);</P>
<P>str.Format("%c%c",buf[0],buf[1]);</P>
<P>PositionValue=atoi(str); </P>
<P>str.Format("%c%c%c%c%c%c%c",buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],buf[8]);</P>
<P>GPSParam[m_nNumber].m_dPositionY=PositionValue*60+atof(str); //提取出纬度</P>
<P>……</P>
<P>::strcpy(buf,m_sPositionX);</P>
<P>if(m_sPositionX.GetLength()==10) //经度超过90度(如东经125度)</P>
<P>{</P>
<P>str.Format("%c%c%c",buf[0],buf[1],buf[2]);</P>
<P>PositionValue=atoi(str);</P>
<P>str.Format("%c%c%c%c%c%c%c",buf[3],buf[4],buf[5],buf[6],buf[7],buf[8],buf[9]);</P>
<P>GPSParam[m_nNumber].m_dPositionX=PositionValue*60+atof(str); //提取出经度(单位为分)</P>
<P>}</P>
<P>if(m_sPositionX.GetLength()==9) //经度未超过90度(如东经89度)</P>
<P>{</P>
<P>//处理方法同上,只是buf的第0、1字节为度数,2~9为分数。</P>
<P>}</P>
<p>
<P>到此为止,已将时间和经纬度信息提取到GPS结构数组GPSParam中的各个变量中去,后续的处理和高层决策可根据该结构中存储的数据作出相应的处理。</P>
<p>
<P><B>3 小结</B></P>
<p>
<P>本文结合主要的相关程序代码对GPS全球定位系统的定位导航信息的接收和参数数据的提取进行了讨论,同时也对串口的程序设计作了简要的讲述。通过本文的设计方法可以将GPS定位导航信息从GPS接收机完整接收,通过对定位参数的提取可将其应用于其他高层应用决策如各种GIS、RS系统等。本文程序在Windows 98下,由Microsoft Visual C++ 6.0编译通过。</P>
[此贴子已经被作者于2004-9-29 14:13:38编辑过]
喜欢0 评分0
eeleo_Lion
论坛版主
论坛版主
  • 注册日期2003-11-29
  • 发帖数1798
  • QQ
  • 铜币551枚
  • 威望0点
  • 贡献值0点
  • 银元0个
1楼#
发布于:2004-10-14 09:32
<img src="images/post/smile/dvbbs/em01.gif" /><img src="images/post/smile/dvbbs/em01.gif" /><img src="images/post/smile/dvbbs/em01.gif" />
人生得意须尽欢,莫使金樽空对月。 天生我材必有用,千金散尽还复来。
举报 回复(0) 喜欢(0)     评分
gissyb2002
路人甲
路人甲
  • 注册日期2004-06-22
  • 发帖数79
  • QQ
  • 铜币256枚
  • 威望0点
  • 贡献值0点
  • 银元0个
2楼#
发布于:2004-10-19 10:07
<P>GIS </P><img src="images/post/smile/dvbbs/em02.gif" /><img src="images/post/smile/dvbbs/em01.gif" />
☆偏偏喜欢你☆
举报 回复(0) 喜欢(0)     评分
zhuzhai
路人甲
路人甲
  • 注册日期2005-08-06
  • 发帖数12
  • QQ
  • 铜币130枚
  • 威望0点
  • 贡献值0点
  • 银元0个
3楼#
发布于:2005-08-12 23:32
举报 回复(0) 喜欢(0)     评分
langyanet
路人甲
路人甲
  • 注册日期2005-08-24
  • 发帖数18
  • QQ
  • 铜币144枚
  • 威望0点
  • 贡献值0点
  • 银元0个
4楼#
发布于:2005-09-12 15:17
举报 回复(0) 喜欢(0)     评分
hlzhi
路人甲
路人甲
  • 注册日期2005-09-12
  • 发帖数19
  • QQ
  • 铜币155枚
  • 威望0点
  • 贡献值0点
  • 银元0个
5楼#
发布于:2005-09-25 11:33
好贴
举报 回复(0) 喜欢(0)     评分
xiaoye
路人甲
路人甲
  • 注册日期2004-07-28
  • 发帖数81
  • QQ
  • 铜币218枚
  • 威望0点
  • 贡献值0点
  • 银元0个
6楼#
发布于:2005-12-29 00:04
<P>高手!高手!之高高手!</P>
<img src="images/post/smile/dvbbs/em05.gif" /><img src="images/post/smile/dvbbs/em04.gif" />
举报 回复(0) 喜欢(0)     评分
sdlyxcg
路人甲
路人甲
  • 注册日期2006-11-29
  • 发帖数2
  • QQ
  • 铜币110枚
  • 威望0点
  • 贡献值0点
  • 银元0个
7楼#
发布于:2007-04-17 21:18
very good!!!<img src="images/post/smile/dvbbs/em03.gif" />
举报 回复(0) 喜欢(0)     评分
stree
路人甲
路人甲
  • 注册日期2004-12-09
  • 发帖数223
  • QQ
  • 铜币782枚
  • 威望0点
  • 贡献值0点
  • 银元0个
8楼#
发布于:2007-07-03 00:28
实用
举报 回复(0) 喜欢(0)     评分
steve1022
路人甲
路人甲
  • 注册日期2007-06-25
  • 发帖数13
  • QQ
  • 铜币130枚
  • 威望0点
  • 贡献值0点
  • 银元0个
9楼#
发布于:2007-07-17 19:50
hao hao <img src="images/post/smile/dvbbs/em01.gif" />
举报 回复(0) 喜欢(0)     评分
游客

返回顶部