GPS应用开发

来源:互联网 发布:新浪博客加js代码 编辑:程序博客网 时间:2024/05/01 11:25
作者:vcbear 文章来源:本站原创 点击数 更新时间:2006-4-27 文章录入:admin 责任编辑:admin -------------------------------------------------------------------------------- 关键字:GPS:Global Position System, 全球定位系统NMEA:National Marine Electronics Association 全国海洋电子协会SiFR:u-blox公司的GPS模块二进制数据协议WGS 84:World Geodetic System 1984LLA: Longitude/Latitude/Altitude经纬度和海拔 简述:本文介绍采用GPS接受模块,GIS控件开发GPS/GIS应用软件的一些要点。不涉及复杂的地理信息理论,主要是针对协议和接口的应用开发 一:GPS 模块应用 GPS(全球定位系统)接受硬件上已经模块化,这里主要基于我使用过的u-blox TIM GPS(以下简称TimGPS)来介绍。TimGPS模块如图(几乎是1:1比例):此模块提供和GPS卫星通信的功能,对外提供FFC20接口,可以给它增加电源,接口板,串口模块,使之可以通过串口和计算机连接。如何开发串口程序在本文中不再介绍,无论在windows/linux下开发串口串口程序都是很简单的事情。 TimGPS对外提供标准NMEA协议和厂家自己的SiRF二进制协议。1.1 NMEA(National Marine Electronics Association) 0183协议NMEA 0183是一种航海、海运方面有关于数字信号传递的标准,此标准定义了电子信号所需要的传输协议,传输数据时间。这个协议是文本格式的。大致如下Start Sequence Payload Checksum End Sequence 消息头 消息体,具体数据和NMEA消息字相关,数据之间用逗号(,)间隔。2243.4976,N,11414.7289,E,091828.819,A 校验码,格式为*[16进制数]如*2C 回车换行 4 协议头,格式为输出:$GPxxx,xxx为输出消息字如GLL.输入:$PSRFMID为输入消息字.1.1.1NMEA协议输出和输入消息NMEA协议有以下输出消息消息字 内容 GGA 时间,位置,定位数据 GLL 经纬度,UTC格式时间,位置和状态数据 GSA 接收机模式和卫星工作数据,包括位置和水平/竖直稀释精度等。稀释精度(Dilution of Precision)是个地理定位术语.一个接收器可以在同一时间得到许多颗卫星定位信息,但在精密定位上,只要四颗卫星讯号即已足够了 GSV 接收机能接收到的卫星信息,包括卫星ID,海拔,方位角,信噪比等 MSS 信号比(SNR),信号强度,频率,比特率 RMC 日期,时间,位置,方向,速度数据。是最常用的一个消息 VTG 相对地面的方向和速度数据 ZDA 时间和日期数据。 和地理信息密切的相关的消息如下,各消息之间包含的信息字段有出入也有重复,在一轮消息循环里,各消息相同的字段中包含相同的地理数据。可以综合多个消息,来获取完整的数据。  日期 时间 纬度 经度 海拔 定位状态 卫星数 地面速度 方向角 GGA   √ √ √ √ √ √     GLL   √ √ √   √       RMC √ √ √ √   √   √ √ VTG               √ √ ZDA √ √               以下为u-lox厂商扩充的输出消息PSRF150 OK-to-send指令,在节电模式中表示进入工作状态 PSRF161 硬件状态报告 工作在NMEA模式时,TimGPS可以有以下输入消息.输入消息一般是用于控制GPS的运行的。消息字 内容 100 设置串口参数和协议 101 XYZ导航坐标初始化。输入参数按 WGS84坐标系确定 102 设置DGPS端口 103 设置或查询数据输出频率。可以设置每个NMEA消息的是否输出和输出频率 104 输入当前经纬度和海拔来初始化模块 105 开发调试数据开关 106 (u-blox)可以改变大地基准坐标系,默认是WGS-84坐标系 107 (u-blox)配置节电模式 108 (u-blox)进入下载模式,更新Flash MSK 设置MSK信号接收机参数 每个协议的具体格式,可以到网上下载具体的NMEA协议。 1.1.2 NMEA消息的接收和解析当接收机工作在NMEA协议时,以一定的速率向外输出数据。如$GPGGA,140144.000,2232.2513,N,11401.6763,E,1,04,,20.3,M,,M,,0000*58$GPGLL,2232.2513,N,11401.6763,E,140144.000,A*35$GPRMC,140144.000,A,2232.2513,N,11401.6763,E,9.17,,140703,,*12$GPVTG,,T,,M,9.17,N,17.0,K*47$GPGGA,140148.000,2232.2654,N,11401.6738,E,1,04,,36.1,M,,M,,0000*5F$GPGLL,2232.2654,N,11401.6738,E,140148.000,A*37$GPRMC,140148.000,A,2232.2654,N,11401.6738,E,12.95,,140703,,*20$GPVTG,,T,,M,12.95,N,24.0,K*77 最好将所有的消息输出速率设置为相同的(使用输入指令103),或者根据具体情况打开或关闭一些不不需要的消息。消息里各字段的格式都不复杂,以下几个稍微注意:l 经纬度的表示法为ddmm.mmmm和方向指示,以纬度举例:当纬度为9730.765,方向指示为N,则表示为北半球的97度30.765分.有的地理信息组件使用经纬度的时候不用度分秒表示法,而是用浮点数表示法,那么97度30.765分就约等于97.5(97+30.765/60)度。l 方向角以正北向为0度,正东向为90度,也就是顺时针方向从0度增加到359度l 校验码为一个消息包(包括消息头和体)里每个ASCII字符的值依次进行异或得到,算法(c++代码)如下 unsigned char CheckSum(string s) { unsigned char c = 0; for(int o=1;oLLA转换问题在分析其日志的过程中,遇到一个问题,就是TimGPS二进制日志保存的坐标数据是以WGS84大地坐标系为准的,大地坐标系的XYZ轴如下: 要得到经纬度和海拔(LLA:Longitude/Latitude/Altitude)坐标,需要一些椭球体、基准面及地图投影的知识。后来从网上找到一个Fortune77写的WGS84->GLL换算函数,将其转成C/C++的函数:void wgsxyz2lla(double x,double y,double z,double *lat,double *lon,double *alt){ double pi = 3.14159265357; longA_EARTH = 6378137; double flattening = 1/298.257223563; double NAV_E2 = (2-flattening)*flattening; // also e^2 double rad2deg = 180/pi; double wlon,wlat,walt,rhosqrd,rho,templat,tempalt,rhoerror,zerror; double slat,clat,q,r_n,drdl,invdet,aa,bb,cc,dd; if ((x == 0.0) & (y == 0.0)) wlon = 0.0; else wlon = atan2(y, x)*rad2deg; if ((x == 0.0) & (y == 0.0) & (z == 0.0)) { printf("WGS xyz at center of earth"); wlon = 360; wlat = 360; walt = 6378137; } else { rhosqrd = x*x + y*y; rho = sqrt(rhosqrd); templat = atan2(z, rho); tempalt = sqrt(rhosqrd + z*z) - A_EARTH; rhoerror = 1000.0; zerror = 1000.0; while ((Dabs(rhoerror) > 1e-6) | (Dabs(zerror) > 1e-6)) { slat = sin(templat); clat = cos(templat); q = 1 - NAV_E2*slat*slat; r_n = A_EARTH/sqrt(q); drdl = r_n*NAV_E2*slat*clat/q; // d(r_n)/d(latitutde) rhoerror = (r_n + tempalt)*clat - rho; zerror = (r_n*(1 - NAV_E2) + tempalt)*slat - z; aa = drdl*clat - (r_n + tempalt)*slat; bb = clat; cc = (1 - NAV_E2)*(drdl*slat + r_n*clat); dd = slat; invdet = 1.0/(aa*dd - bb*cc); templat = templat - invdet*(+dd*rhoerror -bb*zerror); tempalt = tempalt - invdet*(-cc*rhoerror +aa*zerror); } wlat = templat*rad2deg; walt = tempalt; } if(lon )*lon = wlon; if(lat )*lat = wlat; if(alt )*alt = walt;} 结语:开发GPS应用软件的要点在于理解相关的协议和接口,仔细处理协议字段。 《基础GIS系统应用开发》 Comming soon....来源: < href="http://doc.4kiki.net" target="_blank">http://doc.4kiki.net  
原创粉丝点击