コード例 #1
0
ファイル: TableObsFileReader.cs プロジェクト: yxw027/GNSSer
        /// <summary>
        /// 构建观测历元。
        /// </summary>
        /// <param name="row"></param>
        /// <param name="indexColName"></param>
        /// <returns></returns>
        public RinexEpochObservation BuildObs(Dictionary <String, object> row, string indexColName)
        {
            var obs = new RinexEpochObservation();

            obs.ReceiverTime = new Geo.Times.Time((DateTime)row[indexColName]);
            foreach (var item in row)
            {
                var name = item.Key;
                if (name == indexColName)
                {
                    continue;
                }

                var code = name.Substring(4);
                var prn  = SatelliteNumber.Parse(name);

                if (!obs.Contains(prn))
                {
                    obs[prn] = new RinexSatObsData(prn);
                }
                var obsValue = new RinexObsValue((double)item.Value, code);
                obs[prn].Add(code, obsValue);
            }
            return(obs);
        }
コード例 #2
0
        /// <summary>
        /// 转换
        /// </summary>
        /// <returns></returns>
        private RinexObsFile Convert()
        {
            InitProcess(RawTable.RowCount);

            TimeConverter    = null;
            CurrentEpochInfo = null;
            RinexOFile       = CreateRinexObsFile();
            int index = 0;//只有有效的观测历元才开始计数

            foreach (var item in RawTable.BufferedValues)
            {
                if (IsCancel)
                {
                    break;
                }

                if (RecordProcessed != null)
                {
                    RecordProcessed(index);
                }

                RinexSatObsData satData = ParseOneRecord(item);
                if (satData != null)
                {
                    CurrentEpochInfo.Add(satData);
                }
                index++;
                PerformProcessStep();
            }
            FullProcess();

            return(RinexOFile);
        }
コード例 #3
0
        /// <summary>
        /// 创建RINEX观测数据
        /// </summary>
        /// <param name="prn"></param>
        /// <param name="C1"></param>
        /// <param name="D1"></param>
        /// <param name="L1"></param>
        /// <param name="S1"></param>
        /// <returns></returns>
        private static RinexSatObsData BuildRinexSatObsData(SatelliteNumber prn, double C1, double L1, double S1, double D1)
        {
            RinexSatObsData satData = new RinexSatObsData(prn);

            satData.Add("C1", C1);
            satData.Add("L1", L1);
            satData.Add("S1", S1);
            satData.Add("D1", D1);//存储为距离递增量,方便调试
            return(satData);
        }
コード例 #4
0
        public RinexEpochObservation GetEpochObservation(GlonassEpochMessage EpochMessage)
        {
            RinexEpochObservation rinex = new RinexEpochObservation();

            rinex.ReceiverTime = EpochMessage.Header.Time;
            foreach (var item in EpochMessage)
            {
                var msg = item as GlonassNormalMessage1012;

                RinexSatObsData satData = GetSatObsData(msg);

                rinex.Add(satData.Prn, satData);
            }

            return(rinex);
        }
コード例 #5
0
        /// <summary>
        /// 对上面的函数重新编写
        /// </summary>
        /// <param name="msg1004"></param>
        /// <returns></returns>
        public RinexSatObsData GetSatObsData(NormalMessage1004 msg1004)
        {
            RinexSatObsData obsData = new RinexSatObsData();

            double L1Pseudorange = 0;
            double L1Phase       = 0;
            double L2Pseudorange = 0;
            double L2Phase       = 0;

            obsData.Prn = msg1004.Prn;

            L1Pseudorange = GetL1PseudoRange(msg1004.GpsL1Pseudorange, msg1004.GpsIntegerL1PseudorangeModulusAmbiguity);

            if (msg1004.GpsL1PhaseRangeMinusPseudorange != RtcmConst.MaxGpsL1PhaseRangeMinusPseudorange)
            {
                double L1PhaseMinusPseudorange = msg1004.GpsL1PhaseRangeMinusPseudorange * RtcmConst.PhaseRangeResolution / Frequence.GpsL1.WaveLength;
                L1PhaseMinusPseudorange = RevisePhaseRange(obsData.Prn, FrequenceType.A, L1PhaseMinusPseudorange);

                L1Phase = L1Pseudorange / Frequence.GpsL1.WaveLength + L1PhaseMinusPseudorange;
            }

            if (msg1004.GpsL2MinusL1PseudorangeDifference != RtcmConst.MaxL2MinusL1PseudorangeDifference)
            {
                L2Pseudorange = GetL2PseudoRange(L1Pseudorange, msg1004.GpsL2MinusL1PseudorangeDifference);
            }

            if (msg1004.GpsL2PhaseRangeMinusL1Pseudorange != RtcmConst.MaxGpsL1PhaseRangeMinusPseudorange)
            {
                double L2PhaseMinusL1Pseudorange = msg1004.GpsL2PhaseRangeMinusL1Pseudorange * RtcmConst.PhaseRangeResolution / Frequence.GpsL2.WaveLength;
                L2PhaseMinusL1Pseudorange = RevisePhaseRange(obsData.Prn, FrequenceType.B, L2PhaseMinusL1Pseudorange);
                L2Phase = L1Pseudorange / Frequence.GpsL2.WaveLength + L2PhaseMinusL1Pseudorange;
            }
            //obsData.

            //ObservationCode ObservationCodeOfC = new ObservationCode();
            //ObservationCode ObservationCodeOfL = new ObservationCode();
            //ObservationCode ObservationCodeOfS = new ObservationCode();
            //ObservationCode ObservationCodeOfD = new ObservationCode();
            obsData.Add("C1X", L1Pseudorange);
            obsData.Add("L1X", L1Phase);
            obsData.Add("P2X", L2Pseudorange);
            obsData.Add("L2X", L2Phase);

            return(obsData);
        }
コード例 #6
0
        /// <summary>
        /// 对上面的函数重新编写
        /// </summary>
        /// <param name="msg1012"></param>
        /// <returns></returns>
        public RinexSatObsData GetSatObsData(GlonassNormalMessage1012 msg1012)
        {
            RinexSatObsData obsData = new RinexSatObsData();

            double L1Pseudorange = 0;
            double L1Phase       = 0;
            double L2Pseudorange = 0;
            double L2Phase       = 0;

            obsData.Prn = msg1012.Prn;

            L1Pseudorange = GetL1PseudoRange(msg1012.GlonassL1Pseudorange, msg1012.GlonassIntegerL1PseudorangeModulusAmbiguity);

            if (msg1012.GlonassL1PhaseRangeMinusPseudorange < RtcmConst.MaxGpsL1PhaseRangeMinusPseudorange)
            {
                double L1PhaseMinusPseudorange = msg1012.GlonassL1PhaseRangeMinusPseudorange * RtcmConst.PhaseRangeResolution / Frequence.GpsL1.WaveLength;
                L1PhaseMinusPseudorange = RevisePhaseRange(obsData.Prn, FrequenceType.A, L1PhaseMinusPseudorange);

                L1Phase = L1Pseudorange / Frequence.GpsL1.WaveLength + L1PhaseMinusPseudorange;
            }

            if (msg1012.GlonassL2MinusL1PseudorangeDifference < RtcmConst.MaxL2MinusL1PseudorangeDifference)
            {
                L2Pseudorange = GetL2PseudoRange(L1Pseudorange, msg1012.GlonassL2MinusL1PseudorangeDifference);
            }

            if (msg1012.GlonassL2PhaseRangeMinusL1Pseudorange < RtcmConst.MaxGpsL1PhaseRangeMinusPseudorange)
            {
                double L2PhaseMinusL1Pseudorange = msg1012.GlonassL2PhaseRangeMinusL1Pseudorange * RtcmConst.PhaseRangeResolution / Frequence.GpsL2.WaveLength;
                L2PhaseMinusL1Pseudorange = RevisePhaseRange(obsData.Prn, FrequenceType.B, L2PhaseMinusL1Pseudorange);
                L2Phase = L1Pseudorange / Frequence.GpsL2.WaveLength + L2PhaseMinusL1Pseudorange;
            }
            //obsData.

            obsData.Add("C1X", L1Pseudorange);
            obsData.Add("L1X", L1Phase);
            obsData.Add("P2X", L2Pseudorange);
            obsData.Add("L2X", L2Phase);

            return(obsData);
        }
コード例 #7
0
        /// <summary>
        /// RTCM MSM文件信息转换为观测文件信息.此处返回的是RINEX3.0的数据类型。
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="HeaderOfMSM"></param>
        /// <returns></returns>
        public RinexEpochObservation GetRinexEpochObservation(BaseMSM msg, HeaderOfMSM HeaderOfMSM)
        {
            RinexEpochObservation RinexEpochObservation = new RinexEpochObservation();

            uint          messageNumber = HeaderOfMSM.MessageNumber;
            double        wavelength = 0;
            int           frequencyBand = 0;
            string        str = null;
            string        attribute = null;
            double        P = 0, L = 0, D = 0, S = 0;
            int           j       = 0;
            int           index   = 0;
            double        p       = 0;
            SatelliteType satType = SatelliteType.G;

            for (int i = 0; i < HeaderOfMSM.SatCount; i++)
            {
                RinexSatObsData SatObsData = new RinexSatObsData();
                for (int k = 0; k < HeaderOfMSM.Nsig; k++)
                {
                    if (HeaderOfMSM.CellMask[index++] == 0)
                    {
                        continue;
                    }
                    if (messageNumber >= 1071 && messageNumber <= 1077)//GPS
                    {
                        satType        = SatelliteType.G;
                        SatObsData.Prn = new SatelliteNumber(HeaderOfMSM.SatlliteMask[i], SatelliteType.G);
                        str            = msm_sig_gps[HeaderOfMSM.SignalMask[k] - 1];
                        frequencyBand  = int.Parse(str.Substring(0, 1));
                        attribute      = str.Substring(1, 1);
                        if (frequencyBand == 1)
                        {
                            wavelength = Frequence.GpsL1.WaveLength;
                        }
                        else if (frequencyBand == 2)
                        {
                            wavelength = Frequence.GpsL2.WaveLength;
                        }
                        else if (frequencyBand == 5)
                        {
                            wavelength = Frequence.GpsL5.WaveLength;
                        }
                    }
                    else if (messageNumber >= 1081 && messageNumber <= 1087)//GLONASS
                    {
                        satType        = SatelliteType.R;
                        SatObsData.Prn = new SatelliteNumber(HeaderOfMSM.SatlliteMask[i], SatelliteType.R);
                    }
                    else if (messageNumber >= 1091 && messageNumber <= 1097)//GALILEO
                    {
                        satType        = SatelliteType.E;
                        SatObsData.Prn = new SatelliteNumber(HeaderOfMSM.SatlliteMask[i], SatelliteType.E);
                    }
                    else if (messageNumber >= 1101 && messageNumber <= 1017)//SBS
                    {
                        satType        = SatelliteType.S;
                        SatObsData.Prn = new SatelliteNumber(HeaderOfMSM.SatlliteMask[i], SatelliteType.S);
                    }
                    else if (messageNumber >= 1111 && messageNumber <= 1117)//QZS
                    {
                        satType        = SatelliteType.J;
                        SatObsData.Prn = new SatelliteNumber(HeaderOfMSM.SatlliteMask[i], SatelliteType.J);
                    }
                    else if (messageNumber >= 1121 && messageNumber <= 1127)//BDS
                    {
                        satType        = SatelliteType.C;
                        SatObsData.Prn = new SatelliteNumber(HeaderOfMSM.SatlliteMask[i], SatelliteType.C);
                        str            = msm_sig_gps[HeaderOfMSM.SignalMask[k] - 1];
                        frequencyBand  = int.Parse(str.Substring(0, 1));
                        attribute      = str.Substring(1, 1);

                        if (frequencyBand == 2)
                        {
                            wavelength = Frequence.CompassB1.WaveLength;
                        }
                        else if (frequencyBand == 6)
                        {
                            wavelength = Frequence.CompassB3.WaveLength;
                        }
                        else if (frequencyBand == 7)
                        {
                            wavelength = Frequence.CompassB2.WaveLength;
                        }
                    }
                    var ObservationCodeOfC = new ObservationCode(ObservationType.C, frequencyBand, attribute);
                    var ObservationCodeOfL = new ObservationCode(ObservationType.L, frequencyBand, attribute);
                    var ObservationCodeOfS = new ObservationCode(ObservationType.S, frequencyBand, attribute);
                    var ObservationCodeOfD = new ObservationCode(ObservationType.D, frequencyBand, attribute);
                    if (msg.NumberOfIntegerMsInSatRoughRange.Count != 0)
                    {
                        p = msg.NumberOfIntegerMsInSatRoughRange[i] * 0.001 + msg.SatelliteRoughRangesModulo1ms[i] * Math.Pow(2, -13);
                    }
                    else
                    {
                        p = msg.SatelliteRoughRangesModulo1ms[i] * Math.Pow(2, -13);
                    }

                    if (msg.SignalFinePseudorange.Count != 0)
                    {
                        P = msg.SignalFinePseudorange[j] * Math.Pow(2, -24) + p;
                    }
                    else if (msg.SignalFinePseudorangeWithExtendedResolution.Count != 0)
                    {
                        P = msg.SignalFinePseudorangeWithExtendedResolution[j] * Math.Pow(2, -29) + p;
                    }
                    P = P * RtcmConst.LightSpeedPerMillisecond;

                    if (msg.SignalFinePhaseRange.Count != 0)
                    {
                        L = msg.SignalFinePhaseRange[j] * Math.Pow(2, -29) + p;
                    }
                    else if (msg.SignalFinePhaseRangeWithExtendedResolution.Count != 0)
                    {
                        L = msg.SignalFinePhaseRangeWithExtendedResolution[j] * Math.Pow(2, -31) + p;
                    }
                    L = L * RtcmConst.LightSpeedPerMillisecond / wavelength;

                    if (msg.PhaseRangeLockTimeIndicator.Count != 0)
                    {
                        S = msg.PhaseRangeLockTimeIndicator[j];
                    }
                    else if (msg.PhaseRangeLockTimeIndicatorWithExtendedRangeAndResolution[j] != 0)
                    {
                        S = msg.PhaseRangeLockTimeIndicatorWithExtendedRangeAndResolution[j];
                    }

                    if (messageNumber % 10 == 5 || messageNumber % 10 == 7 && msg.SatRoughPhaseRangeRate.Count != 0)
                    {
                        if (msg.SatRoughPhaseRangeRate[i] > -1638.4)
                        {
                            D = -(msg.SatRoughPhaseRangeRate[i] * 0.001 + msg.SignalFinePhaseRangeRate[j] * 0.0001) / wavelength;
                        }
                    }
                    SatObsData.Add(ObservationCodeOfC.ToString(), P);
                    SatObsData.Add(ObservationCodeOfL.ToString(), L);
                    SatObsData.Add(ObservationCodeOfS.ToString(), S);
                    SatObsData.Add(ObservationCodeOfD.ToString(), D);

                    //更新头部信息
                    var obsCodes = new List <string>();
                    obsCodes.Add(ObservationCodeOfC.ToString());
                    obsCodes.Add(ObservationCodeOfL.ToString());
                    obsCodes.Add(ObservationCodeOfS.ToString());
                    obsCodes.Add(ObservationCodeOfD.ToString());
                    if (ObsHeader != null)
                    {
                        ObsHeader.ObsCodes[satType] = obsCodes;
                    }

                    j++;
                }

                RinexEpochObservation.Add(SatObsData.Prn, SatObsData);
            }

            RinexEpochObservation.Header       = ObsHeader;
            RinexEpochObservation.ReceiverTime = HeaderOfMSM.EpochTime;

            return(RinexEpochObservation);
        }
コード例 #8
0
        /// <summary>
        /// 解析一行数据。
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        private RinexSatObsData ParseOneRecord(Dictionary <string, object> item)
        {
            RinexSatObsData satData = null;

            #region 赋值
            long timeNanos = ParseLong(item, TimeNanos);
            //当前时间到GPS起始时间的纳秒数,为负数。
            long   fullBiasNanos                   = ParseLong(item, FullBiasNanos);
            double biasNanos                       = ParseDouble(item, BiasNanos);
            double timeOffsetNanos                 = ParseDouble(item, TimeOffsetNanos);
            long   receivedSvTimeNanos             = ParseLong(item, ReceivedSvTimeNanos);
            long   receivedSvTimeUncertaintyNanos  = ParseLong(item, ReceivedSvTimeUncertaintyNanos);
            int    hardwareClockDiscontinuityCount = ParseInt(item, HardwareClockDiscontinuityCount);
            int    accumulatedDeltaRangeState      = ParseInt(item, AccumulatedDeltaRangeState);
            double cn0DbHz = ParseDouble(item, Cn0DbHz);
            double accumulatedDeltaRangeMeters = ParseDouble(item, AccumulatedDeltaRangeMeters);
            #endregion

            SatelliteNumber prn = ParsePrn(item);

            //伪距不确定度太大,本数据作废
            if (receivedSvTimeUncertaintyNanos > 1e8)
            {
                log.Debug(prn + " 卫星时间不确定度太大,忽略本数据 " + receivedSvTimeUncertaintyNanos);
                return(satData);
            }//简单判断伪距
            //如果钟跳发生了,或指定的被减伪距值无效,则重置被减伪距
            bool isClockDisCountChanged = (_prevHardwareClockDisCount != hardwareClockDiscontinuityCount);
            _prevHardwareClockDisCount = hardwareClockDiscontinuityCount;

            //决定是否新建时间计算器。
            if (TimeConverter == null || !TimeConverter.IsEpochValid)
            {
                TimeConverter = new AndroidGnssTimeConverter(fullBiasNanos, Option.IsFromFirstEpoch);//fullBiasNanos值并不准确,含有偏差,不能用于计算所有伪距。
                if (!TimeConverter.IsEpochValid)
                {
                    log.Debug("当前历元时间不合法," + TimeConverter.FirstEpochOfUtc + ",将重试。");
                    return(satData);
                }
            }
            TimeConverter.SetFullBias(fullBiasNanos)
            .SetTimeNanos(timeNanos)
            .SeBiasNanos(biasNanos)
            .SetTimeOffsetNanos(timeOffsetNanos);
            Time currentUtcTime = TimeConverter.GetReceiverUtcTime();

            TimeConverter.SetSatelliteType(prn.SatelliteType);

            //若是新历元
            if (IsNewEpoch(CurrentEpochInfo, _currentTimeNanos, timeNanos)) //新历元
            {
                _currentTimeNanos = timeNanos;                              //记录当接收机时间,用于判断是否是同一个历元

                CurrentEpochInfo = new RinexEpochObservation(currentUtcTime);
                RinexOFile.Add(CurrentEpochInfo);
            }
            //计算伪距
            double transTime = TimeConverter.GetTransmissionTime(receivedSvTimeNanos);
            double C1        = transTime * GnssConst.LIGHT_SPEED;

            bool isPassed = CheckPsuedorange(ref prn, C1);
            if (!isPassed)
            {
                C1 = 0;
            }

            if (C1 == 0 && Option.IsSkipZeroPseudorange)
            {
                log.Debug(currentUtcTime + ", " + prn + "伪距为0,忽略本数据 ");
                return(satData);
            }
            if (accumulatedDeltaRangeMeters == 0 && Option.IsSkipZeroPhase)
            {
                log.Debug(currentUtcTime + ", " + prn + "载波为 0,忽略本数据 ");
                return(satData);
            }

            //时间积累差,带来的近距离变化差
            double timeErrorDistance = TimeConverter.GetDifferDistance();
            var    phaseRange        = accumulatedDeltaRangeMeters - timeErrorDistance;//相位距离

            var aligner = NumericalAlignerManager.GetOrCreate(prn);

            if (isClockDisCountChanged) //如果钟跳发生,则将第一个差分伪距设置为当前伪距值。
            {
                aligner.IsReset = true;
            }

            phaseRange = aligner.GetAlignedValue(currentUtcTime, phaseRange, C1);
            double L1 = GetL1(phaseRange, prn, Option.IsToCylePhase);
            double S1 = cn0DbHz;
            double D1 = phaseRange; //test for range

            satData = BuildRinexSatObsData(prn, C1, L1, S1, D1);

            return(satData);
        }