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接收机解析器只需要从串行端口实时读取数据而并不需要