Android GNSS 通过原始数据计算伪距

Android GNSS 通过原始数据计算伪距

伪距是GNSS定位中最重要的基本参数之一,而智能终端一般不显式地提供伪距,需要通过GNSS原始数据进行计算。关于GNSS原始数据如何获取,请参考上一篇博客:Android获取GNSS原始数据

一、理论部分

伪距计算公式如下:
ρ = ( t R X − t T X ) × c × 1 0 9 \rho= (t_{RX}-t_{TX})\times c\times10^9 ρ=(tRXtTX)×c×109
其中:tRX为智能手机接收到信号的时间,tTX为卫星发射信号的时间(从当前GNSS周开始),c为光速。
tTX可以直接通过GnssTime.ReceivedSvTimeNanos()获取;而tRX则无法直接获取,需要经过计算,由于卫星系统的时间基准不同,采用不同的方法。

Android GNSS 通过原始数据计算伪距_第1张图片

tRX的计算

1、首先定义在完整GNSS时间中测得的时间tRX_GNSS
t R X g n s s = T i m e N a n o s − ( F u l l B i a s N a n o s + B i a s N a n o s ) t_{RXgnss}= TimeNanos-(FullBiasNanos+BiasNanos) tRXgnss=TimeNanos(FullBiasNanos+BiasNanos)
2、将其化为GNSS周内秒(取值范围在0~604800s),即将其与604800取模
t R X g p s = t R X g n s s m o d    ( w e e k s e c N a n o s ) t_{RXgps}= t_{RXgnss}\mod (weeksecNanos) tRXgps=tRXgnssmod(weeksecNanos)
上面计算的值是GPS时间下的tRX,接下来只需要将BDS、GLONASS 和 Galileo 系统的时间转换到 GPStime 中即可。

3、分系统计算tRX

  1. 对BDS系统: t R X = t R X g p s − 14 s t_{RX}=t_{RXgps}-14s tRX=tRXgps14s

  2. 对 Galileo系统:该系统不使用周内秒,而是使用(0~100ms内的部分)
    t R X = t R X g n s s m o d    ( m i l l i S e c o n d s N a n o s ) t_{RX}=t_{RXgnss}\mod (milliSecondsNanos) tRX=tRXgnssmod(milliSecondsNanos)

  3. 对 GLONASS系统:该系统采用日内秒(0~86400s内的部分)
    t R X = t R X g n s s m o d    ( d a y s e c N a n o s ) + 3 h − l e a p s e c o n d t_{RX}=t_{RXgnss}\mod (daysecNanos) +3h-leapsecond tRX=tRXgnssmod(daysecNanos)+3hleapsecond

二、代码部分

1、建立一个类,定义需要用到的常量,并设置构造函数传入GNSS原始数据

public class GNSSData {
    private GnssMeasurement gnssMeasurement;
    private GnssClock gnssClock;
    private double Pseudorange;//伪距
    private double TRxGnssNanos;//Gnss完整测量时
    private int PRN;
    private int SVType;//卫星类型
    private static final double c=299792458E-9;//光速 单位:m/ns
    private static final double WEEK_SEC = 604800;//周化秒
    private static final double DAY_SEC=86400;//日化秒

    public GNSSData(GnssMeasurement gnssMeasurement, GnssClock gnssClock) {
        this.gnssMeasurement = gnssMeasurement;
        this.gnssClock = gnssClock;
    }
}

2、计算tTX

 double tTx=gnssMeasurement.getReceivedSvTimeNanos()+gnssMeasurement.getTimeOffsetNanos();

3、计算tRx_GNSS

public double getTRxGnssNanos() {
        double bias=0;
        if (gnssClock.hasBiasNanos())
            bias+=gnssClock.getBiasNanos();
        if (gnssClock.hasFullBiasNanos())
            bias+=gnssClock.getFullBiasNanos();
        if (gnssClock.hasLeapSecond())
            bias+=gnssClock.getLeapSecond()*1000_000_000;
        TRxGnssNanos =gnssClock.getTimeNanos()-bias;
        return TRxGnssNanos;
    }

4、获取当前卫星类型,并计算tRX和伪距

因为涉及大数取余,使用BigDecimal避免计算出错

public double getPseudorange() {
	BigDecimal tRx;
	int SvType=gnssMeasurement.getConstellationType();//获取当前卫星类型
	BigDecimal decimal_tRxGnssNanos=BigDecimal.valueOf(getTRxGnssNanos());
	BigDecimal decimal_weekNanos=BigDecimal.valueOf(WEEK_SEC*1e9);
	BigDecimal decimal_dayNanos=BigDecimal.valueOf(DAY_SEC*1e9);
    switch(SvType){
            case GnssStatus.CONSTELLATION_GPS:
                tRx=decimal_tRxGnssNanos.remainder(decimal_weekNanos);//GPS系统
                break;
            case GnssStatus.CONSTELLATION_GLONASS:
                tRx=decimal_tRxGnssNanos.remainder(decimal_dayNanos).add(BigDecimal.valueOf((3*3600)*1E9));//GLONASS系统
                break;
            case GnssStatus.CONSTELLATION_BEIDOU:
                tRx=decimal_tRxGnssNanos.remainder(decimal_weekNanos).subtract(BigDecimal.valueOf(14E9));//BeiDou系统
                break;
            default:tRx=BigDecimal.valueOf(-1);//未定义的卫星类型
        }

	BigDecimal decimal_deltaTime=tRx.subtract(BigDecimal.valueOf(tTx));
	Pseudorange=decimal_deltaTime.abs().multiply(BigDecimal.valueOf(c)).doubleValue();
	if (Pseudorange<1e8 && Pseudorange>1e6)return Pseudorange;//单位:米
	else return -1;
	}

你可能感兴趣的:(android,java,gnss,定位)