Android 获取GNSS原始数据 您所在的位置:网站首页 谷歌公开安卓源代码于是华为 Android 获取GNSS原始数据

Android 获取GNSS原始数据

2024-07-16 00:40| 来源: 网络整理| 查看: 265

获取安卓设备的GNSS测量数据方法

2016 年 5 月,Google 在 I/O 开发者会议上宣布,将为 Android Nougat 操作系统中的应用程序提供原始 GNSS 观测数据。 API参考(Google中文官网)DEMO参考(GNSSLogger)

1. 用到的类

类注释LocationManager用于注册GNSSmeasurementGnssMeasurementsEvent.Callback用于从GNSS引擎接收GNSS卫星测量值GnssMeasurementsEvent一个包含测量值数据的容器GnssClock包含GPS时钟时间戳记的类Gnssmeasurement代表GNSS卫星测量的类,其中包含原始信息和计算信息

2.设置权限 必须先在Manifest文件中设置相应的权限,否则将无法获取测量的回调数据

3.注册GNSSmeasurement

private LocationManager mLocationManager; private GnssMeasurementsEvent.Callback gnssMeasurementEventListener = new GnssMeasurementsEvent.Callback() //这里先声明,重写方法将在下一步添加 public void RegisterMeasurements(){ @SuppressLint("MissingPermission") boolean is_register_success= mLocationManager.registerGnssMeasurementsCallback(gnssMeasurementEventListener); //注册GNSSmeasurement回调监听,返回是否注册成功的信息 //测量信息将在GnssMeasurementsEvent.Callback中接收 } //顺便把注销的方法也写了 public void unRegisterMeasurements(){ mLocationManager.unregisterGnssMeasurementsCallback(gnssMeasurementEventListener); }

4.重写GnssMeasurementsEvent.Callback里的两个方法

private GnssMeasurementsEvent.Callback gnssMeasurementEventListener = new GnssMeasurementsEvent.Callback() { @Override public void onGnssMeasurementsReceived(GnssMeasurementsEvent eventArgs) { super.onGnssMeasurementsReceived(eventArgs); //这里我们获取到了回调的测量数据容器:GnssMeasurementsEvent eventArgs //TODO: } @Override public void onStatusChanged(int status) { super.onStatusChanged(status); } };

5.将测量数据转换为字符串

把GnssMeasurementsEvent拆分为GnssClock和Gnssmeasurement //写一个接收测量信息的方法 public void onGnssMeasurementsReceived(GnssMeasurementsEvent event) { StringBuilder builder=new StringBuilder("GNSS测量数据:\n\n"); //这里的toStringClock和toStringMeasurement将写在下一步里 builder.append(toStringClock(event.getClock()));//写入gnss时钟的数据 builder.append("\n"); for (GnssMeasurement measurement : event.getMeasurements()) { builder.append(toStringMeasurement(measurement));//写入gnss测量数据 builder.append("\n"); } //这里可以写runOnUiThread(...),将builder打印在屏幕上 //也可以修改返回值 } 分别把GnssClock和Gnssmeasurement转化为字符串 private String toStringClock(GnssClock gnssClock){ //将GPS接收器时钟的值转换为字符串 final String format = " %-4s = %s\n";//定义数据显示格式,“%-4”表示左对齐、不足四位补足四位 StringBuilder builder=new StringBuilder("GNSS时钟:\n"); DecimalFormat numberFormat = new DecimalFormat("#0.000");//定义格式化数字 if (gnssClock.hasLeapSecond()) { //如果闰秒存在则显示闰秒 builder.append(String.format(format, "闰秒(LeapSecond)", gnssClock.getLeapSecond())); } builder.append(String.format(format, "硬件时钟(TimeNanos)", gnssClock.getTimeNanos()));//获取以毫秒为单位的GNSS接收器内部硬件时钟值 if (gnssClock.hasTimeUncertaintyNanos()) { //获取硬件时钟的误差估计(不确定度) builder.append(String.format(format, "时钟误差估计(TimeUncertaintyNanos)", gnssClock.getTimeUncertaintyNanos())); } if (gnssClock.hasFullBiasNanos()) { //如果存在接收机本地时钟总偏差,则显示 builder.append(String.format(format, "总时钟偏差(FullBiasNanos)", gnssClock.getFullBiasNanos())); } if (gnssClock.hasBiasNanos()) { //亚纳秒偏差 builder.append(String.format(format, "亚偏差(BiasNanos)", gnssClock.getBiasNanos())); } if (gnssClock.hasBiasUncertaintyNanos()) { //FullBiasNanos和BiasNanos的误差估计 builder.append(String.format(format, "时钟偏差估计(BiasUncertaintyNanos)", numberFormat.format(gnssClock.getBiasUncertaintyNanos()))); } /** * 注意:以上五个数据用于计算GPS时钟 * 具体计算方法为:local estimate of GPS time = TimeNanos - (FullBiasNanos + BiasNanos) * 世界标准时:UtcTimeNanos = TimeNanos - (FullBiasNanos + BiasNanos) - LeapSecond * 1,000,000,000 */ if (gnssClock.hasDriftNanosPerSecond()) { //以每秒纳秒为单位获取时钟的漂移 builder.append(String.format(format, "时钟漂移(DriftNanosPerSecond)", numberFormat.format(gnssClock.getDriftNanosPerSecond()))); } if (gnssClock.hasDriftUncertaintyNanosPerSecond()) { //时钟偏差的估计 builder.append(String.format(format, "时钟漂移估计(DriftUncertaintyNanosPerSecond)", numberFormat.format(gnssClock.getDriftUncertaintyNanosPerSecond()))); } //获取硬件时钟不连续的计数,即:每当gnssclock中断时,该值+1 builder.append(String.format(format, "中断计数(HardwareClockDiscontinuityCount)", gnssClock.getHardwareClockDiscontinuityCount())); return builder.toString(); } private String toStringMeasurement(GnssMeasurement measurement){ //将GNSS测量结果转换为字符串 //定义显示格式 final String format = " %-4s = %s\n"; StringBuilder builder = new StringBuilder("GNSS测量结果:\n"); DecimalFormat numberFormat = new DecimalFormat("#0.000"); DecimalFormat numberFormat1 = new DecimalFormat("#0.000E00"); //获取卫星ID /** * 取决于卫星类型 * GPS:1-32 * SBAS:120-151、183-192 * GLONASS:OSN或FCN + 100之一 * 1-24作为轨道槽号(OSN)(首选,如果知道) * 93-106作为频道号(FCN)(-7至+6)加100。即将-7的FCN编码为93,0编码为100,+ 6编码为106 * QZSS:193-200 * 伽利略:1-36 * 北斗:1-37 */ builder.append(String.format(format, "卫星ID", measurement.getSvid())); //获取卫星类型 /** * 1:CONSTELLATION_GPS 使用GPS定位 * 2:CONSTELLATION_SBAS 使用SBAS定位 * 3:CONSTELLATION_GLONASS 使用格洛纳斯定位 * 4:CONSTELLATION_QZSS 使用QZSS定位 * 5:CONSTELLATION_BEIDOU 使用北斗定位 (^-^)! * 6:CONSTELLATION_GALILEO 使用伽利略定位 * 7:CONSTELLATION_IRNSS 使用印度区域卫星定位 */ builder.append(String.format(format, "卫星类型", measurement.getConstellationType())); //获取进行测量的时间偏移量(以纳秒为单位) builder.append(String.format(format, "测量时间偏移量", measurement.getTimeOffsetNanos())); //获取每个卫星的同步状态 //具体数值含义请查表 builder.append(String.format(format, "同步状态", measurement.getState())); //获取时间戳的伪距速率,以m/s为单位 builder.append( String.format( format, "伪距速率", numberFormat.format(measurement.getPseudorangeRateMetersPerSecond()))); //获取伪距的速率不确定性(1-Sigma),以m/s为单位 builder.append( String.format( format, "伪距速率不确定度", numberFormat.format(measurement.getPseudorangeRateUncertaintyMetersPerSecond()))); // if (measurement.getAccumulatedDeltaRangeState() != 0) { // 获取“累积增量范围”状态 // 返回:MULTIPATH_INDICATOR_UNKNOWN(指示器不可用)=0 // notice 即:指示器可用时,收集数据 builder.append( String.format( format, "累积增量范围状态", measurement.getAccumulatedDeltaRangeState())); //获取自上次重置通道以来的累积增量范围,以米为单位. //该值仅在上面的state值为“可用”时有效 //notice 累积增量范围= -k * 载波相位(其中k为常数) builder.append( String.format( format, "累积增量范围", numberFormat.format(measurement.getAccumulatedDeltaRangeMeters()))); //获取以米为单位的累积增量范围的不确定性(1-Sigma) builder.append( String.format( format, "累积增量范围不确定度", numberFormat1.format(measurement.getAccumulatedDeltaRangeUncertaintyMeters()))); } if (measurement.hasCarrierFrequencyHz()) { //获取被跟踪信号的载波频率 builder.append( String.format(format, "信号载波频率", measurement.getCarrierFrequencyHz())); } if (measurement.hasCarrierCycles()) { //卫星和接收器之间的完整载波周期数 builder.append(String.format(format, "载波周期数", measurement.getCarrierCycles())); } if (measurement.hasCarrierPhase()) { //获取接收器检测到的RF相位 builder.append(String.format(format, "RF相位", measurement.getCarrierPhase())); } if (measurement.hasCarrierPhaseUncertainty()) { //误差估计 builder.append( String.format( format, "RF相位不确定度", measurement.getCarrierPhaseUncertainty())); } //获取一个值,该值指示事件的“多路径”状态,返回0或1或2 //MULTIPATH_INDICATOR_DETECTED = 1 测量显示有“多路径效应”迹象 // MULTIPATH_INDICATOR_NOT_DETECTED = 2 测量结果显示没有“多路径效应”迹象 builder.append(String.format(format, "多路经效应指示器", measurement.getMultipathIndicator())); // if (measurement.hasSnrInDb()) { //获取信噪比(SNR),以dB为单位 builder.append(String.format(format, "信噪比", measurement.getSnrInDb())); } if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { if (measurement.hasAutomaticGainControlLevelDb()) { //获取以dB为单位的自动增益控制级别 builder.append(String.format(format, "自动增益控制级别", measurement.getAutomaticGainControlLevelDb())); } if (measurement.hasCarrierFrequencyHz()) { builder.append(String.format(format, "载波频率", measurement.getCarrierFrequencyHz())); } } return builder.toString(); }

最后将这些方法整合起来即可,UI显示的部分就不再赘述了。 关于伪距如何计算见下一篇博客:通过GNSS原始数据计算伪距



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有