您的当前位置:首 页 >> 信息中心

GPS国际协议NMEA,Android 关于定位中的那点事(GPS,GPGGA,NMEA

发布日期:2021-11-30 20:36:42 作者: 点击:
首先关于定位一些解释

一般在Android端地图相关用的最多的都是第三方的Sdkj进行二次开发,如百度,高德,World Wind ,arcgis等,对于手机自带的GPS芯片和国内的北斗芯片了解的相对较少,GPS在android中已经由android底层驱动封装好了,对于导航定位下面我先说基本的常识:java

GNSS NMEA协议 Rtcm协议 GPGGA数据 差分定位 GNSS:

通常指全球导航卫星系统,其实GNSS就是全部导航系统的统称。GNSS:Global Navigation Satellite System(全球卫星导航系统)GPS:Global Positioning System(全球定位系统)GPS是美国的卫星导航系统。俄罗斯的GLONASS欧盟的Galileo中国的北斗。这几大导航系通通称为GNSS。全球导航卫星系统定位是利用一组卫星的伪距、星历、卫星发射时间等观测量来是的,同时还必须知道用户钟差。全球导航卫星系统是能在地球表面或近地空间的任何地点为用户提供全天候的3维坐标和速度以及时间信息的空基无线电导航定位系统。所以,通俗一点说若是你除了要知道经纬度还想知道高度的话,那么,必须对收到4颗卫星才能准肯定位。android

NMEA协议

NMEA协议是为了在不一样的GPS导航设备中创建统一的RTCM(海事无线电技术委员会)标准,它最初是由美国国家海洋电子协会(NMEA—The NationalMarine Electronics Association)制定的。NMEA协议有0180、0182和0183这3种,0183能够认为是前两种的升级,也是目前使用最为普遍的一种。在实际使用中,若是只是接收GPS的输出.则只需两根信号线 GPS数据输出线和信号地线,能够直接将EIA-422输出通道两条信号线中的一条同计算机的Rs232C输入线相连。GPS(全球定位系统)接收机与手持机之间的数据交换格式通常都由生产厂商缺省定制,其定义内容普通用户很难知晓,且不一样品牌、不一样型号的GPS接收机所配置的控制应用程序也因生产厂家的不一样而不一样。因此,对于通用GPS应用软件,须要一个统一格式的数据标准,以解决与任意一台GPS的接口问题。NMEA-0183数据标准就是解决这类问题的方案之一。NMEA协议是为了在不一样的GPS导航设备中创建统一的RTCM(海事无线电技术委员会)标准,它最初是由美国国家海洋电子协会(NMEA—The NationalMarine Electronics Association)制定的。NMEA协议有0180、0182和0183这3种,0183能够认为是前两种的升级,也是目前使用最为普遍的一种,本文主要在0183下进行梳理git

GPGGA

GPGGA,GPS固定数据输出语句($GPGGA),这是一帧GPS定位的主要数据,也是使用最广的数据。$GPGGA 语句包括17个字段:语句标识头,世界时间,纬度,纬度半球,经度,经度半球,定位质量指示,使用卫星数量,HDOP-水平精度因子,椭球高,高度单位,大地水准面高度异常差值,高度单位,差分GPS数据期限,差分参考基站标号,校验和结束标记(用回车符和换行符),分别用14个逗号进行分隔。格式例子以下:$GPGGA,014434.70,3817.13334637,N,12139.72994196,E,4,07,1.5,6.571,M,8.942,M,0.7,0016*7B该数据帧的结构及各字段释义以下: GPGGA,,,,,,,,,,M,,M,,∗xx GPGGA:起始引导符及语句格式说明(本句为GPS定位数据); UTC时间,格式为hhmmss.sss; 纬度,格式为ddmm.mmmm(第一位是零也将传送); 纬度半球,N或S(北纬或南纬) 经度,格式为dddmm.mmmm(第一位零也将传送); 经度半球,E或W(东经或西经) GPS状态, 0初始化, 1单点定位, 2码差分, 3无效PPS, 4固定解, 5浮点解, 6正在估算 7,人工输入固定值, 8模拟模式, 9WAAS差分 使用卫星数量,从00到12(第一个零也将传送) HDOP-水平精度因子,0.5到99.9,通常认为HDOP越小,质量越好。 椭球高,-9999.9到9999.9米M 指单位米 大地水准面高度异常差值,-9999.9到9999.9米M 指单位米 差分GPS数据期限(RTCM SC-104),最后设立RTCM传送的秒数量,如不是差分定位则为空 差分参考基站标号,从0000到1023(首位0也将传送)。1. 语句结束标志符xx 从$开始到*之间的全部ASCII码的异或校验 回车符,结束标记 换行符,结束标记web

RTCM

TCM全名国际海运事业无线电技术委员会,是国际标准组织。NMEA 0183是美国国家海洋电子协会(National Marine Electronics Association )为海用电子设备制定的标准格式。目前业已成了GPS导航设备统一的RTCM(Radio Technical Commission for Maritime services)标准协议。也叫做差分站。算法

RTCM3.1数据格式及内容

CM3.1协议规范包括应用层、表示层、传输层、数据链路层和物理层。对于编解码最重要的是表示层和传输层。应用层描述了RTCM3.1协议中各种差分电文采用单向数据链广播给各种用户,用户如何利用差分电文实现高精度定位、测距以及各种拓展应用,如何提供高精度的定位和导航服务;阐述了普通定位系统与差分定位应用系统之间的精度差异,以及在测距、定位、导航等应用系统中发挥的明显优点。表示层表示层规定了差分的具体协议和电文格式,其数据架构包括两个主要方面,即数据字段和消息类型,包括消息、数据要素和数据定义。RTCM3.1中所涉及的实时动态定位消息分为若干个组,每一个组又含有不一样的子类,描述这些数据的是消息类型。传输层api

传输层定义了发送或接收RTCM3.1文电的帧结构,并详细介绍了差错控制算法(CRC校验算法)。差分电文是以二进制的形式进行传输的,定义该层是为了使RTCM10403.1的数据可以被正确解码。经过网络传输的差分电文是按电文帧的形式进行,电文帧格式定义在物理层上的传输格式,目的是保证在应用中能被正确的解码,在数据传输过程当中,差分电文提供者应把电文打包成一个个独立结构的帧,以使帧的传输最好适应这种传输方法。在传送到应用层以前,数据设置应该将这种帧的结构进行重建。基本的帧结构包含一个固定的前缀,一个电文长度定义,一组电文,和24比特循环冗余码校验(CRC),校验码是用于差错控制和保证每帧信息完整性的有效手段。帧格式的结构下图所示。数组

文件头 保留 电文长度 可变长度数据电文 CRC 8bits 6bits 10bits 电文字节的整数个数 24bits 11010011 未定义-设置为000000 按字节算的电文长度 0-1023字节 CRC-24Q

电文头是一个固定的8比特序列;接着的6个比特是保留的,设置成0;接着是可变长度电文的长度;接着是变长电文;最后是CRC校验码。若是数据连接须要短电文以保持一个连续的数据流,那么可变长度数据电文应该被设置为0,提供一个长度为48比特的填充电文。24比特的CRC奇偶性提供针对突发性错误和随机性错误的保护。CRC对连续字节的操做开始于文件头,直到可变长度电文域的结尾。24比特(p1,p2,…,p24)的顺序是按照信息比特(m1,m2, …,m8N)的顺序产生的,其中N是构成电文加上文件头和电文长度定义参数的序列的字节总数。网络

RTCM3.1解码解码即按照版本定义将各字段数据取出并解出原数据。以1004电文的解码为例介绍解码的思路和过程。1004是GPS RTK Message(1001-1004)的一种消息类型,它提供了卫星的载波、伪距和信噪比等信息,是观测文件的主要内容。GPS RTK Message在可变长度消息的开始有8个字节的消息头,其内容及字段定义在表4中列出。1004电文的内容如表5所示,与其余类型信息不一样,可变长度消息可能有N条1004电文,每条电文长度为125位,其长度不是字节位数的整数倍。为了提升利用率,每两条1004电文中间没有多余的位,如第一条电文的最后一个字节空余3位,则第二条电文补足,即最后3位是下一条电文开始的3位。这种排列为解码带来不便,由于数据是按字节读取,没法直接设循环解每条电文。注意到电文的排列仍是有必定规律,解码的核心是编制一种方法,可以在字节数组中,以任意位为起始,取出所需比特位,这样就能够根据报文结构,在字节数组中获取数据,重构报文内容,而后就能够根据报文条数设置循环,对报文逐条进行相应处理。架构

差分定位

差分定位也叫差分GPS技术,即将一台GPS接收机安置在基准站上进行观测。根据基准站已知精密坐标,计算出基准站到卫星的距离改正数,并由基准站实时将这一数据发送出去。用户接收机在进行GPS观测的同时,也接收到基准站发出的改正数,并对其定位结果进行改正,从而提升定位精度。差分定位(Differential positioning),也叫相对定位,是根据两台以上接收机的观测数据来肯定观测点之间的相对位置的方法,它既可采用伪距观测量也可采用相位观测量,大地测量或工程测量均应采用相位观测值进行相对定位。能够简单的理解为在已知坐标的点上安置一台GPS接收机(称为基准站),利用已知坐标和卫星星历计算出观测值的校订值,并经过无线电设备(称数据链)将校订值发送给运动中的GPS接收机(称为流动站),流动站应用接收到的校订值对本身的GPS观测值进行改正,以消除卫星钟差钟差、接收机钟差、大气电离层和对流层折射偏差的影响。这部分很专业,具体能够查资料ide

在Android中获取GPS中的NMEA-0183协议中的GPGGA数据,再获取经纬度 public class MainActivity extends AppCompatActivity {private TextView tvWGS84, tvNmea;private LocationListener gpsListener;private LocationManager mLocationManager;private GeomagneticField gmfield;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//显示wgs84数据tvWGS84 = (TextView) findViewById(R.id.tv_rgs84);//显示nmea协议中数据tvNmea = (TextView) findViewById(R.id.tv_nmea);mLocationManager = ((LocationManager) getSystemService(Context.LOCATION_SERVICE));if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {// TODO: Consider calling//ActivityCompat#requestPermissions// here to request the missing permissions, and then overriding// public void onRequestPermissionsResult(int requestCode, String[] permissions,//int[] grantResults)// to handle the case where the user grants the permission. See the documentation// for ActivityCompat#requestPermissions for more details.return;}mLocationManager.addNmeaListener(new GpsStatus.NmeaListener() {@Overridepublic void onNmeaReceived(long timestamp, String nmea) {tvNmea.invalidate();//此处以GPGGA为例//$GPGGA,232427.000,3751.1956,N,11231.1494,E,1,6,1.20,824.4,M,-23.0,M,,*7Eif (nmea.contains("GPGGA")) {String info[] = nmea.split(",");//GPGGA中altitude是MSL altitude(平均海平面)tvWGS84.setText(nmea);Log.i("GPGGA","获取的GPGGA数据是:"+nmea);Log.i("GPGGA","获取的GPGGA数据length:"+info.length);Log.i("GPGGA","GPS定位数据:"+info[0]);Log.i("GPGGA","UTC时间:"+info[1]);Log.i("GPGGA","纬度:"+info[2]);Log.i("GPGGA","纬度半球:"+info[3]);Log.i("GPGGA","经度:"+info[4]);Log.i("GPGGA","经度半球:"+info[5]);Log.i("GPGGA","GPS状态:"+info[6]);Log.i("GPGGA","使用卫星数量:"+info[7]);Log.i("GPGGA","HDOP-水平精度因子:"+info[8]);Log.i("GPGGA","椭球高:"+info[9]);Log.i("GPGGA","大地水准面高度异常差值:"+info[10]);Log.i("GPGGA","差分GPS数据期限:"+info[11]);Log.i("GPGGA","差分参考基站标号:"+info[12]);Log.i("GPGGA","ASCII码的异或校验:"+info[info.length-1]);//UTC + (+0800) = 本地(北京)时间int a= Integer.parseInt(info[1].substring(0,2));a+=8;a%=24;String time="";String time1="";if(a