Ejemplo n.º 1
0
        public override void updateMeasurements(GnssMeasurementsEvent evento)
        {
            lock (this) {
                visibleButNotUsed = 0;
                observedSatellites.Clear();
                unusedSatellites.Clear();

                GnssClock gnssClock = evento.Clock;
                long      TimeNanos = gnssClock.TimeNanos;
                timeRefMsec = new Time(JavaSystem.CurrentTimeMillis());
                double BiasNanos = gnssClock.BiasNanos;
                double galileoTime, pseudorangeTOW, pseudorangeE1_2nd, tTxGalileo;

                // Use only the first instance of the FullBiasNanos (as done in gps-measurement-tools)
                if (!fullBiasNanosInitialized)
                {
                    FullBiasNanos            = gnssClock.FullBiasNanos;
                    fullBiasNanosInitialized = true;
                }

                // Start computing the pseudoranges using the raw data from the phone's GNSS receiver
                foreach (GnssMeasurement measurement in evento.Measurements)
                {
                    if (measurement.ConstellationType != constellationId)
                    {
                        continue;
                    }

                    if (measurement.HasCarrierFrequencyHz)
                    {
                        if (!approximateEqual(measurement.CarrierFrequencyHz, E1a_FREQUENCY, FREQUENCY_MATCH_RANGE))
                        {
                            continue;
                        }
                    }

                    long   ReceivedSvTimeNanos = measurement.ReceivedSvTimeNanos;
                    double TimeOffsetNanos     = measurement.TimeOffsetNanos;

                    // Galileo Time generation (GSA White Paper - page 20)
                    galileoTime = TimeNanos - (FullBiasNanos + BiasNanos);

                    // Compute the time of signal reception for when  GNSS_MEASUREMENT_STATE_TOW_KNOWN or GNSS_MEASUREMENT_STATE_TOW_DECODED are true
                    tRxGalileoTOW = galileoTime % Constants.NUMBER_NANO_SECONDS_PER_WEEK;

                    // Measurement time in full Galileo time without taking into account weekNumberNanos(the number of
                    // nanoseconds that have occurred from the beginning of GPS time to the current
                    // week number)
                    weekNumber = System.Math.Floor((-1.0 * FullBiasNanos) / Constants.NUMBER_NANO_SECONDS_PER_WEEK);

                    // Compute the signal reception for when GNSS_MEASUREMENT_STATE_GAL_E1C_2ND_CODE_LOCK is true
                    tRxGalileoE1_2nd = galileoTime % Constants.NumberNanoSeconds100Milli;

                    tTxGalileo = ReceivedSvTimeNanos + TimeOffsetNanos;

                    // Valid only if GNSS_MEASUREMENT_STATE_TOW_KNOWN or GNSS_MEASUREMENT_STATE_TOW_DECODED are true
                    pseudorangeTOW = (tRxGalileoTOW - tTxGalileo) * 1e-9 * Constants.SPEED_OF_LIGHT;

                    // Valid only if GNSS_MEASUREMENT_STATE_GAL_E1C_2ND_CODE_LOCK
                    pseudorangeE1_2nd = ((galileoTime - tTxGalileo) % Constants.NumberNanoSeconds100Milli) * 1e-9 * Constants.SPEED_OF_LIGHT;


                    /*
                     *
                     * According to https://developer.android.com/ and GSA White Paper (pg.20)
                     * the GnssMeasurements States required for GALILEO valid pseudoranges are:
                     *
                     * STATE_TOW_KNOWN                   = 16384                            (1 << 11)
                     * STATE_TOW_DECODED                 =     8                            (1 <<  3)
                     * STATE_GAL_E1C_2ND_CODE_LOCK       =  2048                            (1 << 11)
                     *
                     */

                    // Get the measurement state
                    GnssState measState = measurement.State;

                    // Bitwise AND to identify the states
                    bool towKnown = false;
                    if (Android.OS.Build.VERSION.SdkInt >= BuildVersionCodes.O)
                    {
                        towKnown = (measState & GnssState.TowKnown) != 0;
                    }

                    bool towDecoded = (measState & GnssState.TowDecoded) != 0;

                    bool codeLockE1BC = (measState & GnssState.GalE1bcCodeLock) != 0;
                    bool codeLockE1C  = (measState & GnssState.GalE1c2ndCodeLock) != 0;

                    // Variables for debugging
                    double prTOW    = pseudorangeTOW;
                    double prE1_2nd = pseudorangeE1_2nd;
                    double diffPR   = prTOW - prE1_2nd;
                    int    svID     = measurement.Svid;

                    if (towDecoded || towKnown)
                    {
                        SatelliteParameters satelliteParameters = new SatelliteParameters(
                            measurement.Svid,
                            new Pseudorange(pseudorangeTOW, 0.0));

                        satelliteParameters.setUniqueSatId("E" + satelliteParameters.getSatId() + "_E1");

                        satelliteParameters.setSignalStrength(measurement.Cn0DbHz);

                        satelliteParameters.setConstellationType(measurement.ConstellationType);

                        if (measurement.HasCarrierFrequencyHz)
                        {
                            satelliteParameters.setCarrierFrequency(measurement.CarrierFrequencyHz);
                        }

                        observedSatellites.Add(satelliteParameters);
                        Log.Debug(TAG, "updateConstellations(" + measurement.Svid + "): " + weekNumber + ", " + tRxGalileoTOW + ", " + pseudorangeTOW);
                        Log.Debug(TAG, "updateConstellations: Passed with measurement state: " + measState);
                    }
                    else if (codeLockE1C)
                    {
                        SatelliteParameters satelliteParameters = new SatelliteParameters(
                            measurement.Svid,
                            new Pseudorange(pseudorangeE1_2nd, 0.0)
                            );

                        satelliteParameters.setUniqueSatId("E" + satelliteParameters.getSatId() + "_E1");
                        satelliteParameters.setSignalStrength(measurement.Cn0DbHz);
                        satelliteParameters.setConstellationType(measurement.ConstellationType);


                        if (measurement.HasCarrierFrequencyHz)
                        {
                            satelliteParameters.setCarrierFrequency(measurement.CarrierFrequencyHz);
                        }
                        observedSatellites.Add(satelliteParameters);
                        Log.Debug(TAG, "updateConstellations(" + measurement.Svid + "): " + weekNumber + ", " + tRxGalileoTOW + ", " + pseudorangeE1_2nd);
                        Log.Debug(TAG, "updateConstellations: Passed with measurement state: " + measState);
                    }
                    else
                    {
                        SatelliteParameters satelliteParameters = new SatelliteParameters(
                            measurement.Svid,
                            null
                            );

                        satelliteParameters.setUniqueSatId("E" + satelliteParameters.getSatId() + "_E1");
                        satelliteParameters.setSignalStrength(measurement.Cn0DbHz);
                        satelliteParameters.setConstellationType(measurement.ConstellationType);

                        if (measurement.HasCarrierFrequencyHz)
                        {
                            satelliteParameters.setCarrierFrequency(measurement.CarrierFrequencyHz);
                        }

                        unusedSatellites.Add(satelliteParameters);
                        visibleButNotUsed++;
                    }
                }
            }
        }
Ejemplo n.º 2
0
        override public void updateMeasurements(GnssMeasurementsEvent evento)
        {
            lock (this) {
                visibleButNotUsed = 0;
                observedSatellites.Clear();
                unusedSatellites.Clear();
                GnssClock gnssClock = evento.Clock;
                long      TimeNanos = gnssClock.TimeNanos;
                timeRefMsec = new Time(JavaSystem.CurrentTimeMillis());
                double BiasNanos = gnssClock.BiasNanos;
                double gpsTime, pseudorange;

                // Use only the first instance of the FullBiasNanos (as done in gps-measurement-tools)
                if (!fullBiasNanosInitialized)
                {
                    FullBiasNanos            = gnssClock.FullBiasNanos;
                    fullBiasNanosInitialized = true;
                }


                // Start computing the pseudoranges using the raw data from the phone's GNSS receiver
                foreach (GnssMeasurement measurement in evento.Measurements)
                {
                    if (measurement.ConstellationType != constellationId) // si la senial no es de la gps, continue
                    {
                        continue;
                    }

                    if (measurement.HasCarrierFrequencyHz)
                    {
                        if (!approximateEqual(measurement.CarrierFrequencyHz, L1_FREQUENCY, FREQUENCY_MATCH_RANGE))
                        {
                            continue;
                        }
                    }

                    // excluding satellites which don't have the L5 component
                    //                if(measurement.getSvid() == 2 || measurement.getSvid() == 4
                    //                        || measurement.getSvid() == 5 || measurement.getSvid() == 7
                    //                        || measurement.getSvid() == 11 || measurement.getSvid() == 12
                    //                        || measurement.getSvid() == 13 || measurement.getSvid() == 14
                    //                        || measurement.getSvid() == 15 || measurement.getSvid() == 16
                    //                        || measurement.getSvid() == 17 || measurement.getSvid() == 18
                    //                        || measurement.getSvid() == 19 || measurement.getSvid() == 20
                    //                        || measurement.getSvid() == 21 || measurement.getSvid() == 22
                    //                        || measurement.getSvid() == 23 || measurement.getSvid() == 28
                    //                        || measurement.getSvid() == 29 || measurement.getSvid() == 31)
                    //                    continue;


                    long   ReceivedSvTimeNanos = measurement.ReceivedSvTimeNanos;
                    double TimeOffsetNanos     = measurement.TimeOffsetNanos;


                    // GPS Time generation (GSA White Paper - page 20)
                    gpsTime = TimeNanos - (FullBiasNanos + BiasNanos);     // TODO intersystem bias?

                    // Measurement time in full GPS time without taking into account weekNumberNanos(the number of
                    // nanoseconds that have occurred from the beginning of GPS time to the current
                    // week number)
                    tRxGPS =
                        gpsTime + TimeOffsetNanos;


                    weekNumberNanos =
                        System.Math.Floor((-1.0 * FullBiasNanos) / Constants.NUMBER_NANO_SECONDS_PER_WEEK)
                        * Constants.NUMBER_NANO_SECONDS_PER_WEEK;

                    // GPS pseudorange computation
                    pseudorange =
                        (tRxGPS - weekNumberNanos - ReceivedSvTimeNanos) / 1.0E9
                        * Constants.SPEED_OF_LIGHT;

                    // TODO Check that the measurement have a valid state such that valid pseudoranges are used in the PVT algorithm

                    /*
                     *
                     * According to https://developer.android.com/ the GnssMeasurements States required
                     * for GPS valid pseudoranges are:
                     *
                     * int STATE_CODE_LOCK         = 1      (1 << 0)
                     * int int STATE_TOW_DECODED   = 8      (1 << 3)
                     *
                     */

                    GnssState measState = measurement.State;

                    // Bitwise AND to identify the states
                    bool codeLock   = (measState & GnssState.CodeLock) != GnssState.Unknown;
                    bool towDecoded = (measState & GnssState.TowDecoded) != 0;
                    bool towKnown   = false;
                    if (Android.OS.Build.VERSION.SdkInt >= BuildVersionCodes.O)
                    {
                        towKnown = (measState & GnssState.TowKnown) != 0;
                    }
                    //                bool towUncertainty = measurement.getReceivedSvTimeUncertaintyNanos() <  MAXTOWUNCNS;


                    if (codeLock && (towDecoded || towKnown) && pseudorange < 1e9)
                    {     // && towUncertainty
                        SatelliteParameters satelliteParameters = new SatelliteParameters(
                            measurement.Svid,
                            new Pseudorange(pseudorange, 0.0));

                        satelliteParameters.setUniqueSatId("G" + satelliteParameters.getSatId() + "_L1");

                        satelliteParameters.setSignalStrength(measurement.Cn0DbHz);

                        satelliteParameters.setConstellationType(measurement.ConstellationType);

                        if (measurement.HasCarrierFrequencyHz)
                        {
                            satelliteParameters.setCarrierFrequency(measurement.CarrierFrequencyHz);
                        }

                        observedSatellites.Add(satelliteParameters);

                        //Log.d(TAG, "updateConstellations(" + measurement.Svid + "): " + weekNumberNanos + ", " + tRxGPS + ", " + pseudorange);
                        //Log.d(TAG, "updateConstellations: Passed with measurement state: " + measState);
                    }
                    else
                    {
                        SatelliteParameters satelliteParameters = new SatelliteParameters(
                            measurement.Svid,
                            null);

                        satelliteParameters.setUniqueSatId("G" + satelliteParameters.getSatId() + "_L1");

                        satelliteParameters.setSignalStrength(measurement.Cn0DbHz);

                        satelliteParameters.setConstellationType(measurement.ConstellationType);

                        if (measurement.HasCarrierFrequencyHz)
                        {
                            satelliteParameters.setCarrierFrequency(measurement.CarrierFrequencyHz);
                        }

                        unusedSatellites.Add(satelliteParameters);
                        visibleButNotUsed++;
                    }
                }
            }
        }