public MultiPathSolver(SatelliteType SatelliteType) { this.SatelliteType = SatelliteType; FrequenceA = Frequence.GetFrequenceA(SatelliteType); FrequenceB = Frequence.GetFrequenceB(SatelliteType); CoeefOfIono = Math.Pow(FrequenceA.Value / FrequenceB.Value, 2.0); }
/// <summary> /// 提供便捷的AB频率无电离层组合。 /// </summary> /// <param name="rangeA">伪距或载波距离</param> /// <param name="rangeB">伪距或载波距离</param> /// <param name="prn"></param> /// <param name="receiverTime"></param> /// <returns></returns> public static double GetIonoFreeRangeValue(double rangeA, double rangeB, SatelliteNumber prn, Time receiverTime) { var A = Frequence.GetFrequenceA(prn, receiverTime); var B = Frequence.GetFrequenceB(prn, receiverTime); double[] facs = GetIonoFreeRangeCombFactors(A, B); double fac1 = facs[0]; double fac2 = facs[1]; double range = GetCombinationValue(fac1, rangeA, fac2, rangeB); return(range); }
/// <summary> /// 检查并初始化 /// </summary> /// <param name="prn"></param> /// <param name="time">用于计算频率,非GLO可以忽略</param> /// <param name="isCycleAmbi">模糊度单位是否为周</param> /// <param name="forceToInit">强制初始化,GLO系统适用,也可以手动指定</param> public void CheckOrInit(SatelliteNumber prn, Time time, bool isCycleAmbi, bool forceToInit = false) { if (prn.SatelliteType == SatelliteType.R) { forceToInit = true; } if (!IsInited || forceToInit) { this.Time = time; this.IsCycleOrMeterOfAmbiUnit = isCycleAmbi; var freq1 = Frequence.GetFrequenceA(prn, time); FreqA = freq1.Value; WaveLengthOfL1 = freq1.WaveLength; FreqB = Frequence.GetFrequenceB(prn, time).Value; WaveLenOfWideLane = Frequence.GetMwFrequence(prn, time).WaveLength; WaveLenOfNarrowLane = Frequence.GetNarrowLaneFrequence(prn, time).WaveLength; tempCoeef = FreqB / (FreqA + FreqB); //算法1 tempCoeef2 = (FreqA + FreqB) * 1e6 / GnssConst.LIGHT_SPEED; //算法2:单位转换,窄巷波长的倒数 tempCoeef3 = FreqB / (FreqA - FreqB); //算法2 IsInited = true; } }
private void button_calculate_Click(object sender, EventArgs e) { CheckAndReadObsFile(); double cutOff = namedFloatControl_satCutoff.GetValue(); SatelliteNumber prn = (SatelliteNumber)this.bindingSource_sat.Current; var F1 = Frequence.GetFrequence(prn, 1); var F2 = Frequence.GetFrequence(prn, 2); var f1 = F1.Value * 1e6;//恢复单位 var f2 = F2.Value * 1e6; double f1f1 = f1 * f1; double f2f2 = f2 * f2; double a = -40.28 * (f2f2 - f1f1) / (f1f1 * f2f2); int smoothWindow = this.namedIntControl_smoothWindow.GetValue(); GlobalIgsGridIonoService ionoService = GlobalIgsGridIonoService.Instance; GlobalIgsGridIonoDcbService ionoDcbService = GlobalIgsGridIonoDcbService.Instance; GlobalIgsEphemerisService ephemerisService = GlobalIgsEphemerisService.Instance; var PhaseSmoothRangeBulider = new NamedCarrierSmoothedRangeBuilderManager(true, smoothWindow, true, IonoDifferCorrectionType.DualFreqCarrier); List <TimedRinexSatObsData> records = ObsFile.GetEpochTimedObservations(prn); ObjectTableStorage table = new ObjectTableStorage(prn + "_硬件延迟"); var firtTime = records[0].Time; double P1_P2sat = ionoDcbService.GetDcb(firtTime, prn).Value *GnssConst.MeterPerNano; double P1_P2recMeter = ionoDcbService.GetDcbMeterForP1(firtTime, Path.GetFileName(ObsPath).Substring(0, 4).ToLower()); var siteXyz = ObsFile.Header.ApproxXyz; progressBarComponent1.InitProcess(records.Count); foreach (var record in records) { progressBarComponent1.PerformProcessStep(); var time = record.Time; var data = record.SatObsData; var waveLenL1 = Frequence.GetFrequenceA(prn, time).WaveLength; var waveLenL2 = Frequence.GetFrequenceB(prn, time).WaveLength; double L1 = data.PhaseA.Value * waveLenL1; double P1 = data.RangeA.Value; double L2 = data.PhaseB != null ? record.SatObsData.PhaseB.Value * waveLenL2 : 0; double P2 = data.RangeB != null ? record.SatObsData.RangeB.Value : 0; var smootherP1 = PhaseSmoothRangeBulider.GetOrCreate("P1"); var smootherP2 = PhaseSmoothRangeBulider.GetOrCreate("P2"); var P1s = smootherP1 .SetReset(data.PhaseA.IsLossLock) .SetRawValue(record.Time, P1, L1, 0) .Build(); var P2s = smootherP2 .SetReset(data.PhaseB.IsLossLock) .SetRawValue(record.Time, P2, L2, 0) .Build(); //var smNew = smoother.GetSmoothedRange(); var eph = ephemerisService.Get(prn, time); if (eph == null) { continue; } var satXyz = eph.XYZ; var polar = Geo.Coordinates.CoordTransformer.XyzToGeoPolar(satXyz, siteXyz, AngleUnit.Degree); if (polar.Elevation < cutOff) { continue; } var cTEC = ionoService.GetSlope(time, siteXyz, satXyz); double ionoRange = a * cTEC.Value * 1e16; // 单位是1e16 double rawDifferP = P1 - P2; double smDifferP = P1s.Value - P2s.Value; //电离层倾斜延迟 double ionoP1 = ionoService.GetSlopeDelayRange(time, siteXyz, satXyz, F1.Value); double ionoP2 = ionoService.GetSlopeDelayRange(time, siteXyz, satXyz, F2.Value); double rawDifferIonoP = ionoP1 - ionoP2; var rawRecDcb = rawDifferP - P1_P2sat - rawDifferIonoP; var smRecDcb = smDifferP - P1_P2sat - rawDifferIonoP; table.NewRow(); table.AddItem("Epoch", record.Time); //table.AddItem("L1", L1); //table.AddItem("L2", L2); //table.AddItem("P1", P1); //table.AddItem("P2", P2); //table.AddItem("P1S", P1s); //table.AddItem("P2S", P2s); table.AddItem("P1-P2", rawDifferP); table.AddItem("SmP1-P2", smDifferP); table.AddItem("IonoDiffer", rawDifferIonoP); table.AddItem("SatDcb", P1_P2sat); //table.AddItem("P1-P2_rec", P1_P2recMeter); table.AddItem("RawRecDcb", rawRecDcb); table.AddItem("SmRecDcb", smRecDcb); } progressBarComponent1.Full(); BindDataSource(table); }
/// <summary> /// 滤波计算 /// </summary> /// <param name="epochInfo"></param> /// <param name="lastResult"></param> /// <returns></returns> public override SingleSiteGnssResult CaculateKalmanFilter(EpochInformation epochInfo, SingleSiteGnssResult lastResult) { //极速模式。 if (Option.TopSpeedModel) { return(base.CaculateKalmanFilter(epochInfo, lastResult)); } epochInfo.RemoveIonoFreeUnavailable(); if (epochInfo.Count < 2) { log.Error("卫星可用数量不足:" + epochInfo.Count); return(null); } var result = base.CaculateKalmanFilter(epochInfo, lastResult) as PppResult; //外部模糊度文件直接固定 if (Option.IsFixingAmbiguity && Option.IsUseFixedParamDirectly && File.Exists(Option.AmbiguityFilePath) && Option.IsUsingAmbiguityFile) { return(result); } //var testBasePrn = new SatelliteNumber(12, SatelliteType.G); //平滑MW if (Option.IsFixingAmbiguity) { SmoothMwProvider.Add(epochInfo); } if (this.IsFixingAmbiguity //&& epochInfo.Contains(testBasePrn) && epochInfo.ReceiverTime.DateTime.TimeOfDay > TimeSpan.FromHours(2) ) { //this.CurrentBasePrn = testBasePrn; var time = epochInfo.ReceiverTime; var SD_MW = SmoothMwProvider.GetDifferMwValue(CurrentBasePrn); //周为单位 if (SD_MW.Count < 2) //MW精度不足 { return(result); } var wmFcb = WideLaneBiasService.Get(time).GetMwDiffer(CurrentBasePrn); //用于模糊度固定,精度要求不高,一次任务获取一次即可 SatWideNarrowValueManager wideNarrowValues = new SatWideNarrowValueManager(); //存储用于模糊度固定的宽窄项及对应的浮点产品 //基本参数定义 double maxMwRms = 0.3; //MW 至少的平滑精度 double maxDevOfInt = 0.2; //MW 取整时允许最大的偏差 var f1 = Frequence.GetFrequenceA(CurrentBasePrn, time).Value; // 1575.42; var f2 = Frequence.GetFrequenceB(CurrentBasePrn, time).Value; // 1227.60; var wideWaveLen = Frequence.GetMwFrequence(CurrentBasePrn, time).WaveLength; var narrowWaveLen = Frequence.GetNarrowLaneFrequence(CurrentBasePrn, time).WaveLength; #region 对MW值(宽巷模糊度)进行固定 foreach (var item in SD_MW) { //简单的质量控制 if (item.Value.Rms > maxMwRms && !Double.IsNaN(item.Value.Rms)) { continue; } var f = wmFcb[item.Key]; //已经归算为和WM的定义相同,在[0-1]区间,满足 B=N+f, N=B-f. if (f == double.NaN) { continue; } var B = item.Value.Value; var nearN = B - f; var N = (int)Math.Round(nearN); //直接进行取整数 if (Math.Abs(nearN - N) <= maxDevOfInt) //fixedSD_MW=0代表无效 { wideNarrowValues.GetOrCreate(item.Key).WideLane = new IntFractionNumber(f, N); //改正后的 WLFCB } } #endregion //提取浮点解星间单差 SetPppFloatAmbiguityLen(result, wideNarrowValues); #region 固定窄巷模糊度 //星间单差,窄巷模糊度 var tempCoeef = f2 / (f1 + f2); //算法1 var tempCoeef2 = (f1 + f2) * 1e6 / GnssConst.LIGHT_SPEED; //算法2:单位转换,窄巷波长的倒数 var tempCoeef3 = f2 / (f1 - f2); //算法2 foreach (var kv in wideNarrowValues.Data) { // var nFcb = SDNL_FCB[kv];//获取窄巷的产品 var prn = kv.Key; var satData = kv.Value; var f = NarrawLaneFcbService.GetBsdOfNarrowLane(prn, CurrentBasePrn, time); //获取窄巷的产品f, 符合B=N+f if (!RmsedNumeral.IsValid(f)) { continue; } var wideInt = satData.WideLane.Int;//只需要整数部分,小数部分化为窄巷小数部分,不影响整体 var floatPppAmbiLen = satData.FloatAmbiguityLength; var B = (floatPppAmbiLen - tempCoeef * wideWaveLen * wideInt) / narrowWaveLen;//算法1 #region 算法验证 var B2 = tempCoeef2 * floatPppAmbiLen - tempCoeef3 * wideInt; //算法2 var differ = B - B2; if (differ > 0.0001) { int ii = 0; throw new Exception("Error!"); } #endregion var nearN = B - f; var N = (int)Math.Round(nearN.Value); //直接进行取整数 if (Math.Abs(nearN.Value - N) <= maxDevOfInt) //fixedSD_MW=0代表无效 { satData.NarrowLane = new IntFractionNumber(f.Value, N); //改正后的 WLFCB } } #endregion //提取协方差,采用Lambda去相关后固定模糊度 #region LAMBDA固定窄巷模糊度 //提取已选择的模糊度协方差阵 //#region 星间单差窄巷模糊度协方差矩阵 //IMatrix B = new ArrayMatrix(this.Adjustment.ParamNames.Count - 6, this.Adjustment.ParamNames.Count - 5, 0.0); //将非差模糊度转换为星间单差模糊度的旋转矩阵 //int index = 0;//参考星的索引位置???,参考星不同,index不同 //for (int i = 5; i < this.Adjustment.ParamNames.Count; i++) //{ // SatelliteNumber sat = SatelliteNumber.Parse(this.Adjustment.ParamNames[i].Substring(0, 3)); // if (sat == MaxPrn) // { // break; // } // else // { // index++; // } //} //for (int i = 0; i < this.Adjustment.ParamNames.Count - 6; i++) //{ // if (i < index) // { // B[i, index] = -1; B[i, i] = 1; // } // if (i >= index) // { // B[i, index] = -1; B[i, i + 1] = 1; // } //} //IMatrix BT = B.Transposition; //IMatrix covaAmb = new ArrayMatrix(this.Adjustment.ParamNames.Count - 5, this.Adjustment.ParamNames.Count - 5, 0); //非差模糊度的协方差矩阵 //for (int i = 0; i < this.Adjustment.ParamNames.Count - 5; i++) //{ // for (int j = 0; j < this.Adjustment.ParamNames.Count - 5; j++) // { // covaAmb[i, j] = this.Adjustment.CovaOfEstimatedParam[i + 5, j + 5]; // } //} //IMatrix SD_covaAmb = B.Multiply(covaAmb).Multiply(BT); //星间单差模糊度的协方差矩阵 //IMatrix SDNL_covaAmb = new ArrayMatrix(this.Adjustment.ParamNames.Count - 6, this.Adjustment.ParamNames.Count - 6, 0.0); //星间单差窄巷模糊度的协方差矩阵 //for (int i = 0; i < this.Adjustment.ParamNames.Count - 6; i++) //{ // for (int j = 0; j < this.Adjustment.ParamNames.Count - 6; j++) // { // SDNL_covaAmb[i, j] = SD_covaAmb[i, j] * (1575.42 + 1227.60) / (1575.42 * GnssConst.GPS_L1_WAVELENGTH);//系数 // } //} //#endregion //#region 部分模糊度固定,先将可以固定的星间单差窄巷模糊度 及其 协方差矩阵挑出来 //List<string> old_ambpara = new List<string>(); //foreach (var item in SD_floatAmb.Keys) //{ // old_ambpara.Add(item.ToString());//所有的模糊度(除了参考星) //} //List<string> new_ambpara = new List<string>(); //foreach (var item in SDNL_floatAmb.Keys) //{ // new_ambpara.Add(item.ToString());//可以固定的模糊度(宽巷 < 0.25 && NLFCB != 0) //} //IMatrix newtrix = NamedMatrix.GetNewMatrix(new_ambpara, old_ambpara, SDNL_covaAmb.Array); //将可以固定的模糊度的协方差矩阵挑出来 //#endregion #endregion StringBuilder sb = new StringBuilder(); sb.Append("PPP模糊度固定," + time + ", BasePrn : " + CurrentBasePrn + ", 其它:" + wideNarrowValues.Count + ", " + Geo.Utils.StringUtil.ToString(wideNarrowValues.Keys)); log.Info(sb.ToString()); //计算固定后的模糊度距离 //已经固定的模糊度 var fixedPppAmbi = new Dictionary <SatelliteNumber, double>(); foreach (var kv in wideNarrowValues.Data) { if (!kv.Value.IsValid) { continue; } var prn = kv.Key; var satData = kv.Value; var wideInt = satData.WideLane.Int; //宽巷模糊度仍然采用整数 var floatNarrowAmbi = satData.NarrowLane.Value; //浮点部分包括在窄巷硬件延迟中 var fixedAmbiLen = tempCoeef * wideWaveLen * wideInt + narrowWaveLen * floatNarrowAmbi; satData.FixedAmbiguityLength = fixedAmbiLen; //简单质量控制 if (satData.DifferOfAmbiguityLength < 0.5) { fixedPppAmbi[prn] = fixedAmbiLen; } } #region 条件平差 模糊度固定 return(FixPppResult(result, fixedPppAmbi)); #endregion } return(result); }