//protected override void SetProperties() //{ // this.EntityType = typeof(FcbOfUpd); // Properties = new List<System.Reflection.PropertyInfo>(); // Properties.Add(typeof(Time).); // StringBuilder sb = new StringBuilder(); // foreach (var item in Properties.) // { // Properties.Add(EntityType.GetProperty(item.Trim())); // } //} /// <summary> /// "Epoch", "BasePrn", "Count", "WnMarker", /// "G01", "G02", "G03", "G04", "G05", "G06", "G07", "G08", "G09", ///"G10", "G11", "G12", "G13", "G14", "G15", "G16", "G17", "G18", "G19", ///"G20", "G21", "G22", "G23", "G24", "G25", "G26", "G27", "G28", "G29", ///"G30", "G31", "G32", /// </summary> /// <param name="obj"></param> /// <returns></returns> public override string EntityToLine(FcbOfUpd obj) { StringBuilder sb = new StringBuilder(); sb.Append(obj.Epoch.ToString()); sb.Append(ItemSpliter); sb.Append(obj.WnMarker); sb.Append(ItemSpliter); sb.Append(obj.BasePrn.ToString()); sb.Append(ItemSpliter); sb.Append(obj.Count.ToString()); //sb.Append(ItemSpliter); //sb.Append(obj.PrnsString.ToString()); var prns = SatelliteNumber.GpsPrns; foreach (var item in prns) { sb.Append(ItemSpliter); var val = obj.Get(item); if (RmsedNumeral.IsValid(val)) { sb.Append(val.ToString("0.0000")); } else { sb.Append(val); } } return(sb.ToString()); }
/// <summary> /// 将所有产品归算到一个卫星上面。取平均。 /// </summary> /// <param name="basePrn"></param> /// <returns></returns> public FcbOfUpd GetWideLaneFcb(SatelliteNumber basePrn) { Dictionary <SatelliteNumber, RmsedNumeral> result = GetFinalFcbOfBsd(basePrn); result[basePrn] = new RmsedNumeral(0, 0); var prns = result.Keys.ToList(); prns.Sort(); //生成产品 FcbOfUpd fcb = new FcbOfUpd(); fcb.BasePrn = basePrn; fcb.WnMarker = FcbOfUpd.WideLaneMaker; fcb.Count = 32;// result.Count; fcb.Epoch = this.First.First.FirstKey.Start; //fcb.Prns = prns; int i = 0; foreach (var prn in prns) { i++; if (i > 32) { break; } fcb.Add(prn, result[prn]); } return(fcb); }
/// <summary> /// 构造函数 /// </summary> /// <param name="obs"></param> /// <param name="PrevAdjustment"></param> public OneDimAdjustMatrixBuilder(RmsedNumeral obs, AdjustResultMatrix PrevAdjustment = null) { this.PrevAdjustment = PrevAdjustment; this.ObsValue = obs; this.ParamNames = new List <string>() { "Value" }; }
/// <summary> /// 构造函数 /// </summary> /// <param name="table"></param> public ParamValueService(ObjectTableStorage table) : base(table) { Data = new Dictionary <string, RmsedNumeral>(); foreach (var item in table.BufferedValues) { var name = item["Name"].ToString(); var val = (double)item["Value"]; var rms = (double)item["Rms"]; Data[name] = new RmsedNumeral(val, rms); } }
/// <summary> /// 计算平滑的伪距,最快的迭代,带电离层的递推平滑算法,可以大大加快速度。 /// 算法已验证,和窗口单独迭代相同,需要注意的式如果正式平滑时,则不需要加权了。 /// 2018.06.20, czs, 这是推导了好几天才出的结果,并得到了验证,具体公式请参看本人发表的文章:**平滑伪距***。 /// </summary> /// <returns></returns> public RmsedNumeral GetSmoothValueByFastUpdate() { int count = this.Count; RmsedNumeral result = null; double extraP = 0;//外推的结果 double deltaTail = 0; if (this.Count <= 1) { result = GetFirstOrDefault(); extraP = result.Value; } else //采用窗口内的数据进行平滑 { //所谓的推估表达式,即不采用当前的伪距观测数据, P0 + (L1 - L0) + 2DI extraP = LastSmoothedRange + (this.CurrentData.IonoFittedPhaseRange - PrevData.IonoFittedPhaseRange) ; double sP = extraP; if (IsWeighted)//加权,表示采用当前的伪距观测数据 { if (this.LastRemovedItem.Value != null)//当大于指定的窗口,将扣除窗口外的数据(包括电离层延迟)影响。 { double ionoDiffer = CurrentData.FittedIonoAndAmbiValue - this.LastRemovedPair.FittedIonoAndAmbiValue; deltaTail = 1.0 / (this.Count) * (CurrentData.RangeMinusPhase - this.LastRemovedPair.RangeMinusPhase - 2.0 * ionoDiffer); sP = extraP + deltaTail; } else //原始Hatch滤波 { double weight = GetWeight(this.LastKey, count); sP = weight * this.CurrentData.PseudoRange + (1 - weight) * extraP; } } double stdDev = this.RawRangeStdDev * 0.1 / Math.Sqrt(count); result = new RmsedNumeral(sP, stdDev); //验证算法,2018.06.20, czs, //var result3 = GetSmoothValueByWholeWindowRecursionAk(); //double ionoDiff; //double Ak = GetAk(out ionoDiff); //double akDelta = Ak - PrevAk; //double differOfAkDelta = akDelta - deltaTail; ////var result2 = this.CurrentRaw.PhaseRange + Ak; ////double differ = result2 - result.Value; ////double differ2 = result2 - result3.Value; ////int oo = 0; //PrevAk = Ak; } this.PrevData = this.CurrentData; this.LastSmoothedRange = result.Value; return result; }
private static RmsedNumeral ParseRmedNumeral(string strVal) { var items = strVal.Split(' '); var val = Geo.Utils.StringUtil.ParseDouble(items[0]); double rms = 0; if (items.Length > 1) { rms = Geo.Utils.StringUtil.ParseDouble(items[1]); } var rmsedVal = new RmsedNumeral(val, rms); return(rmsedVal); }
/// <summary> /// 获取FCB /// </summary> /// <param name="time"></param> /// <param name="prn"></param> /// <param name="basePrn">基准卫星</param> /// <returns></returns> public RmsedNumeral GetNLFcbOfBsdValue(Time time, SatelliteNumber prn, SatelliteNumber basePrn) { string fileName = CheckFileLoaded(time); RmsedNumeral result = null; if (Files.ContainsKey(fileName)) { var file = Files[fileName]; if (file == null) { return(null); } result = file.GetFcbOfBsdValue(time, prn, basePrn); } return(result); }
/// <summary> /// 计算窄巷模糊度浮点解 /// </summary> /// <param name="FloatAmbiguityDiffer"></param> /// <param name="wideLaneInteger"></param> /// <returns></returns> public RmsedNumeral GetNarrowLaneValue(RmsedNumeral FloatAmbiguityDiffer, RmsedNumeral wideLaneInteger) { //求乘数因子 RmsedNumeral narrowLane = RmsedNumeral.Zero; if (IsPppAmbiInCycleOrLen) { narrowLane = (FloatAmbiguityL1CycleMultiFactor * FloatAmbiguityDiffer - WideLaneMultiFactor * wideLaneInteger); } else { narrowLane = (FloatAmbiguityLenMultiFactor * FloatAmbiguityDiffer - WideLaneMultiFactor * wideLaneInteger); } return(narrowLane); }
public override FcbOfUpd Parse(string[] items) { if (CurrentIndex <= 0) { Time time; if (!Time.TryParse(items[0], out time)) { return(null); } } var item = new FcbOfUpd(); int i = 0; item.Epoch = Time.Parse(items[i++]); item.WnMarker = (items[i++]); item.BasePrn = SatelliteNumber.Parse(items[i++]); item.Count = int.Parse(items[i++]); //item.PrnsString = (items[i++]); int length = items.Length; for (int j = i; j < length; j++) { var prn = new SatelliteNumber(j - i + 1, SatelliteType.G); var val = RmsedNumeral.Parse(items[j]); //double rms = 0.0001; //int rmsIndex = j + FcbOfUpdFile.TotalGpsSatCount; //if(items.Length > rmsIndex) //{ // rms = Double.Parse(items[rmsIndex]); //} item.Data.Add(prn, val);// new RmsedNumeral(val,rms)); } //foreach (var prn in item.Prns) //{ // item.Data.Add(prn, Double.Parse(items[i++])); //} return(item); }
private NameRmsedNumeralVector GetIntMwDoubleDiffers(ParamValueService paramValueService, GroupedValueService wmValues) { NameRmsedNumeralVector wideLaneVector = new NameRmsedNumeralVector(); // RmsedVector wideLaneVector = new RmsedVector(); var paramNames = paramValueService.ParamNames; foreach (var item in paramNames) { if (!NetDoubleDifferName.IsDifferParam(item)) { continue; } var paramName = NetDoubleDifferName.Parse(item); CurrentBasePrn = paramName.RefPrn; if (!paramName.IsValid) { continue; } var floatWideAmbi = wmValues.GetFirstDoubleDiffer(paramName); if (floatWideAmbi == null) { continue; } var wideAmbi = new RmsedNumeral(Math.Round(floatWideAmbi.Value), 1e-10); var differ = (floatWideAmbi.Value - wideAmbi.Value); if (Math.Abs(differ) > 0.3) { log.Info(item + " 宽项(MW)整数偏差为 " + differ + "取消固定。"); continue; } wideLaneVector[item] = wideAmbi; } return(wideLaneVector); }
/// <summary> /// 1. 处理一颗卫星的宽项值,包含和基准卫星的差分值。 /// </summary> /// <param name="tableRow"></param> /// <param name="sat"></param> private void SolveAndUpdateWideLane(EpochSatellite sat) { var prn = sat.Prn; var prnKey = prn.ToString(); var smoothKey = BuildWideLaneKey(prnKey); var mwCycle = sat.Combinations.MwPhaseCombinationValue; // MW 值 var filter = this.WideLaneFilterManager.GetOrCreate(prnKey); filter.Buffers = GetMwValues(prn); var rms = IsSetWeightWithSat ? SatWeightProvider.GetStdDev(sat) : 1; var input = new RmsedNumeral(mwCycle, rms); var smoothAligned = filter.Filter(input); LatestEpochSatWmValues[sat.Prn] = new EpochSatDifferValue() { Index = sat.EpochInfo.EpochIndexOfDay, Prn = sat.Prn, RawValue = mwCycle - filter.IntegerPart, SmoothValue = smoothAligned.Value }; }
/// <summary> /// 计算差分产品,小数部分,区间[-0.5, 0.5] /// </summary> /// <param name="basePrn">基准卫星</param> /// <returns>正小数的产品</returns> public Dictionary <SatelliteNumber, RmsedNumeral> GetDifferFractionProduct(SatelliteNumber basePrn) { var rawDiffer = this.GetRawDiffer(basePrn); //首先获取各站内的卫星差分 var fractions = rawDiffer.GetAverageRoundFractionTable(); //计算小数部分的平均,以表格返回,列名为卫星,行索引为测站 //字典法 var dic = new Dictionary <SatelliteNumber, RmsedNumeral>(); var results = fractions.GetAveragesWithRms(); //所有卫星差分值求平均 foreach (var item in results) { var prn = SatelliteNumber.Parse(item.Key); if (prn == SatelliteNumber.Default) { continue; } var frac = Geo.Utils.DoubleUtil.GetRoundFraction(item.Value.Value); //产品为 [-0.5, 0.5] 区间的小数 dic[prn] = new RmsedNumeral(frac, item.Value.Rms); } return(dic); }
/// <summary> /// 双频无电离层组合校正 /// </summary> /// <param name="obj"></param> private void ReviseDualIonoFree(EpochInformation obj) { foreach (var sat in obj) { double correction = 0; double rawRange = 0; double rawPhase = 0; RmsedNumeral corredRange = RmsedNumeral.Zero; var PS = PhaseSmoothedRangeBuilderManager.GetOrCreate(sat.Prn); rawRange = sat.Combinations.IonoFreeRange.Value; rawPhase = sat.Combinations.IonoFreePhaseRange.Value; corredRange = PS.SetReset(sat.IsUnstable) .SetRawValue(obj.ReceiverTime, rawRange, rawPhase, 0) .Build(); correction = corredRange.Value - rawRange; //规定:非原生观测量改正到近似值上【在观测方程的右边,因此符号相反】。 //2018.05.29, czs, int hmx sat.RangeOnlyCorrection.AddCorrection("IonFreePhaseSmoothRangeOfAB", -1.0 * correction); sat.StdDevOfRange = corredRange.StdDev; } }
/// <summary> /// 遍历每一个历元 /// </summary> /// <param name="epochInfo"></param> /// <returns></returns> public override bool Revise(ref EpochInformation epochInfo) { //如果没有基准卫星,则不可计算 if (!epochInfo.EnabledPrns.Contains(BasePrn)) { return(false); } //1.计算宽项滤波值,并存储 foreach (var sat in epochInfo) { SolveAndUpdateWideLane(sat); } //2.计算平滑宽项星间差分值 var baseMwValue = this.LatestEpochSatWmValues[BasePrn]; foreach (var sat in epochInfo) //只处理本历元具有的卫星 { var val = this.LatestEpochSatWmValues[sat.Prn]; //计算差分值 SovleAndUpdateDifferValue(val, baseMwValue); } //3.提取PPP计算结果,模糊度差分结果,先不做平滑 foreach (var prn in epochInfo.EnabledPrns) { var floatVal = PppResult.GetFloatAmbiguityCycle(prn); LatestEpochFloatAmbiguityValues[prn] = new EpochSatDifferValue() { Index = epochInfo.EpochIndexOfDay, Prn = prn, RawValue = floatVal, SmoothValue = floatVal, }; } //3.1 星间单差值,更新到结果 var baseFloat = this.LatestEpochFloatAmbiguityValues[BasePrn]; foreach (var prn in epochInfo.EnabledPrns) { var val = LatestEpochFloatAmbiguityValues[prn]; val.DifferValue = val.SmoothValue - baseFloat.SmoothValue; } //4.计算窄巷值 foreach (var sat in epochInfo.EnabledSats) { var prn = sat.Prn; var prnKey = prn.ToString(); var val = LatestEpochFloatAmbiguityValues[prn]; var wideLane = this.LatestEpochSatWmValues[sat.Prn]; double fcbOfWideLaneDiffer = 0; var differkey = BuildDifferKey(prn); if (DifferFcbManager != null && DifferFcbManager.Contains(differkey)) { var dcb = DifferFcbManager.Get(differkey).Last; fcbOfWideLaneDiffer = dcb.WideLaneValue; if (Math.Abs(dcb.Time - sat.ReceiverTime) > 7 * 3600 * 24) { log.Warn("提供的宽项星间单差已经超过一周!"); } } var intWideLane = wideLane.DifferValue - fcbOfWideLaneDiffer; //此处应该减去星间单差的小数部分。2016.10.20. var wideLaneInt = (int)Math.Round(intWideLane); var narrowValue = GetNarrowLaneValue(sat, val.DifferValue, wideLaneInt); //此处应该固定模糊度,不应该直接取整。 this.LatestEpochNarrowLaneValues[prn] = new EpochSatValue() { Index = epochInfo.EpochIndexOfDay, Prn = prn, RawValue = narrowValue, Tag = wideLaneInt // 存储整型宽项模糊度 }; //获取小数部分 var narrowBuffer = NarrowBufferManager.GetOrCreate(prnKey); if (narrowBuffer.IsFull) { var filter = this.NarrowLaneFilterManager.GetOrCreate(prnKey); filter.Buffers = narrowBuffer; var rms = IsSetWeightWithSat ? SatWeightProvider.GetStdDev(sat) : 1; var input = new RmsedNumeral(narrowValue, rms); var smoothAligned = filter.Filter(input); this.LatestEpochNarrowLaneValues[prn].SmoothValue = smoothAligned.Value; } narrowBuffer.Add(narrowValue); } //3.输出 if (IsOutputDetails) { TableStorage.NewRow(); TableStorage.AddItem("Epoch", epochInfo.ReceiverTime.ToShortTimeString()); foreach (var sat in epochInfo.EnabledSats) //只处理本历元具有的卫星 { var val = this.LatestEpochSatWmValues[sat.Prn]; var prnKey = val.Prn.ToString(); var wideLaneKey = BuildWideLaneKey(prnKey); //宽项 TableStorage.AddItem(wideLaneKey + "_Raw", val.RawValue); TableStorage.AddItem(wideLaneKey + "_Smooth", val.SmoothValue); TableStorage.AddItem(wideLaneKey + "_MwDiffer", val.DifferValue); //浮点解 var floatVal = this.LatestEpochFloatAmbiguityValues[sat.Prn]; var floatKey = prnKey; var differKey = BuildDifferKey(prnKey); TableStorage.AddItem(floatKey + "_FloatAmbi_Raw", floatVal.RawValue); //TableStorage.AddItem(floatKey + "_Smooth", floatVal.SmoothValue); TableStorage.AddItem(differKey, floatVal.DifferValue); //窄巷 var narrowVal = this.LatestEpochNarrowLaneValues[sat.Prn]; var narrowLaneKey = BuildNarrowLaneKey(prnKey); TableStorage.AddItem(narrowLaneKey + "_Raw", narrowVal.RawValue); TableStorage.AddItem(narrowLaneKey + "_WideLaneInt", narrowVal.Tag); TableStorage.AddItem(narrowLaneKey + "_Smooth", narrowVal.SmoothValue); //TableStorage.AddItem(narrowLaneKey + "_MwDiffer", narrowVal.DifferValue); } } return(true); }
/// <summary> /// 计算平滑的伪距,最快的迭代,带电离层的递推平滑算法,可以大大加快速度。 /// 算法已验证,和窗口单独迭代相同,需要注意的式如果正式平滑时,则不需要加权了。 /// 2018.06.20, czs, 这是推导了好几天才出的结果,并得到了验证,具体公式请参看本人发表的文章:**平滑伪距***。 /// </summary> /// <returns></returns> public RmsedNumeral GetSmoothValueByFastUpdate() { int count = this.Count; RmsedNumeral result = null; double extraP = 0;//外推的结果 double deltaTail = 0; if (this.Count <= 1) { result = GetFirstOrDefault(); extraP = result.Value; CurrentData.FittedIonoAndAmbiValue = CurrentData.GetRawIonoAndHalfAmbiValue(); } else //采用窗口内的数据进行平滑 { double ionDiffer = 0; if (IsDeltaIonoCorrect)//电离层改正赋值 { //var fit = IonoWindow.GetPolyFitValue(CurrentData.Time, OrderOfDeltaIonoPolyFit, IonoFitDataCount); //if (fit != null) //{ // CurrentData.FittedIonoAndAmbiValue = fit.Value; //} //else //{ // CurrentData.FittedIonoAndAmbiValue = CurrentData.GetRawIonoAndHalfAmbiValue(); //} ionDiffer = (CurrentData.FittedIonoAndAmbiValue - PrevData.FittedIonoAndAmbiValue); } //所谓的推估表达式,即不采用当前的伪距观测数据, P0 + (L1 - L0) + 2DI extraP = LastSmoothedRange + (this.CurrentData.PhaseRange - PrevData.PhaseRange) + 2 * ionDiffer; double sP = extraP; if (IsWeighted) //加权,表示采用当前的伪距观测数据 { if (this.LastRemovedItem.Value != null) //当大于指定的窗口,将扣除窗口外的数据(包括电离层延迟)影响。 { double ionoDiffer = 0; if (IsDeltaIonoCorrect) { ionoDiffer = CurrentData.FittedIonoAndAmbiValue - this.LastRemovedPair.FittedIonoAndAmbiValue; //var bigFit = BigIonoWindow.GetTimedLsPolyFit(1); //ionoDiffer = bigFit.GetY( CurrentData.Time) - bigFit.GetY(LastRemovedPair.Time); } deltaTail = 1.0 / (this.Count) * (CurrentData.RangeMinusPhase - this.LastRemovedPair.RangeMinusPhase - 2.0 * ionoDiffer); sP = extraP + deltaTail; } else //原始Hatch滤波 { double weight = GetWeight(this.LastKey, count); sP = weight * this.CurrentData.PseudoRange + (1 - weight) * extraP; } } double stdDev = this.RawRangeStdDev * 0.1 / Math.Sqrt(count); result = new RmsedNumeral(sP, stdDev); //验证算法,2018.06.20, czs, //var result3 = GetSmoothValueByWholeWindowRecursionAk(); //double ionoDiff; //double Ak = GetAk(out ionoDiff); //double akDelta = Ak - PrevAk; //double differOfAkDelta = akDelta - deltaTail; ////var result2 = this.CurrentRaw.PhaseRange + Ak; ////double differ = result2 - result.Value; ////double differ2 = result2 - result3.Value; ////int oo = 0; //PrevAk = Ak; } this.PrevData = this.CurrentData; this.LastSmoothedRange = result.Value; return(result); }
/// <summary> /// 构造函数 /// </summary> /// <param name="count"></param> public SphericalHarmonicsItem(int count) { C = new RmsedNumeral[count]; S = new RmsedNumeral[count]; S[0] = RmsedNumeral.Zero;//第一个始终为0. }
private void button_combine_Click(object sender, EventArgs e) { var fcbPathes = fileOpenControl_fcbPathes.FilePathes; var basePrn = this.baseSatSelectingControl1.SelectedPrn; log.Info("即将转换FCB文件基准到 " + basePrn); //文件读取 Dictionary <string, FcbOfUpdFile> data = new Dictionary <string, FcbOfUpdFile>(); FcbOfUpdFile baseFile = null; foreach (var path in fcbPathes) { var file = new FcbOfUpdReader(path).ReadToFile(); if (file.Count == 0) { continue; } var target = file.ToFile(basePrn);//基准转换到统一的卫星 if (target == null || target.Count == 0) { continue; } var fileName = Path.GetFileName(path); data[fileName] = target; if (baseFile == null) { baseFile = target; } } log.Info("文件读取完毕,数量: " + fcbPathes.Length); //汇集 log.Info("即将汇集各文件到一个对象,然后方便进行平均,这个过程比较耗时。。。 "); EpochSatSiteValueList valList = new EpochSatSiteValueList("多基准FCB合成"); foreach (var epochProduct in baseFile) { var epoch = epochProduct.Epoch; valList.GetOrCreate(epoch).GetOrCreate(basePrn).Add("BasePrn", RmsedNumeral.Zero); //基准卫星和数据不用计算。 foreach (var kv in data) { var epochVal = kv.Value.Get(epoch); if (epochVal == null) { continue; } foreach (var item in epochVal.Data.KeyValues) { if (item.Key == basePrn) { continue; } if (RmsedNumeral.IsValid(item.Value)) { valList.GetOrCreate(epoch).GetOrCreate(item.Key).Add(kv.Key, item.Value); } } } } log.Info("各文件汇集转换完成,即将求平均 "); //求平均 var ave = valList.GetAverage(0, 3); //生成窄巷FCB 产品,并写入文件 var FcbOfUpds = ave.GetFcbProduct(basePrn); //写入文件 //写入文件 var outpath = FcbOfUpdWriter.WriteEpochProducts(FcbOfUpds, basePrn + "_CombiedEpochNLFcbOfDcb"); log.Info("执行完毕! "); Geo.Utils.FormUtil.ShowOkAndOpenDirectory(Path.GetDirectoryName(outpath)); }
/// <summary> /// 校正其中一个。 /// </summary> /// <param name="sat"></param> /// <param name="freq"></param> /// <param name="obsFreq"></param> private void ReviseOneFreq(EpochSatellite sat, FrequenceType freq, FreqenceObservation obsFreq) { double correction = 0; RmsedNumeral corredRange = RmsedNumeral.Zero; var rangeObservation = obsFreq.PseudoRange; double rawRange = rangeObservation.Value; double rawPhase = obsFreq.PhaseRange.Value; var PS = PhaseSmoothedRangeBuilderManager.GetOrCreate(BuildSatFreqName(sat, freq)); double ionoDiffer = 0; switch (this.PhaseSmoothedRangeBuilderManager.IonoDifferCorrectionType) { case IonoDifferCorrectionType.No: break; case IonoDifferCorrectionType.DualFreqCarrier: ionoDiffer = sat.GetIonoLenByDifferPhase(freq); break; case IonoDifferCorrectionType.WindowPolyfit: break; case IonoDifferCorrectionType.WindowWeightedAverage: break; case IonoDifferCorrectionType.IndicatedFile: if (IonoDeltaTable == null) { log.Warn("电离层延迟变化表格为NULL!无法改正"); } else { var dat = InputedIonoDelta.Get(sat.Prn.ToString()); if (dat != null) { var win = dat.GetNumeralWindowData(sat.ReceiverTime); if (win != null) { ionoDiffer = win.GetPolyFitValue(sat.ReceiverTime, 1, 2).Value; } } } break; default: break; } corredRange = PS.SetReset(sat.IsUnstable) .SetRawValue(sat.ReceiverTime, rawRange, rawPhase, ionoDiffer) .Build(); correction = corredRange.Value - rawRange; //规定:原生观测量改正到观测值上【在观测方程的左边,因此符号不变】。 //2018.05.29, czs, int hmx CorrectionNames name = CorrectionNames.PhaseSmoothRange; switch (freq) { case FrequenceType.A: name = CorrectionNames.PhaseSmoothRangeA; break; case FrequenceType.B: name = CorrectionNames.PhaseSmoothRangeB; break; case FrequenceType.C: name = CorrectionNames.PhaseSmoothRangeC; break; default: name = CorrectionNames.PhaseSmoothRange; break; } rangeObservation.SetCorrection(name, correction); sat.StdDevOfRange = corredRange.StdDev; //检查更新电离层改正 if (PS is GnsserWindowedPhaseSmoothedRangeBuilder) { obsFreq.TempAmbiguityAndIonoLength = ((GnsserWindowedPhaseSmoothedRangeBuilder)PS).SmoothRangeWindow.CurrentIonoAndHalfLambdaLen; } }
public void Add(string name, RmsedNumeral val) { this.Add(val.Value, name); this.rmsVecror.Add(val.Rms); }
/// <summary> /// 读取RINEX文件的头文件。 /// </summary> /// <param name="reader">数据流</param> /// <returns></returns> public IonoHarmonicHeader ReadHeader(StreamReader reader) { //if (!Geo.Utils.FileUtil.IsValid(path)) { return null; } IonoHarmonicHeader header = new IonoHarmonicHeader(); //header.FileName = Path.GetFileName(path); int lineIndex = 0; string line = null; while ((line = ReadNextNoNullLine(reader)) != null) { lineIndex++; if (line.StartsWith(IonoHarmonicHeaderLabel.COEFFICIENTS)) { break; } if (line.StartsWith(IonoHarmonicHeaderLabel.DEGREE)) { break; } string strVal = GetValueString(line); if (line.StartsWith(IonoHarmonicHeaderLabel.MODEL_NUMBER_STATION_NAME)) { header.ModelNumberStationName = strVal; continue; } if (line.StartsWith(IonoHarmonicHeaderLabel.MODEL_TYPE)) { header.ModelType = strVal; continue; } if (line.StartsWith(IonoHarmonicHeaderLabel.MAXIMUM_DEGREE_OF_SPHERICAL_HARMONICS)) { header.MaxDegree = Geo.Utils.StringUtil.ParseInt(strVal); continue; } if (line.StartsWith(IonoHarmonicHeaderLabel.MAXIMUM_ORDER)) { header.MaxOrder = Geo.Utils.StringUtil.ParseInt(strVal); continue; } if (line.StartsWith(IonoHarmonicHeaderLabel.EVELOPMENT_WITH_RESPECT_TO)) { line = ReadNextNoNullLine(reader); strVal = GetValueString(line); header.IsGeographicalOrGeomeagnetic = Geo.Utils.StringUtil.ParseInt(strVal) == 1; line = ReadNextNoNullLine(reader); strVal = GetValueString(line); header.IsMeanOrTruePosOfTheSun = Geo.Utils.StringUtil.ParseInt(strVal) == 1; continue; } if (line.StartsWith(IonoHarmonicHeaderLabel.MAPPING_FUNCTION)) { header.MappingFunction = (IonoMappingFunction)Geo.Utils.StringUtil.ParseInt(strVal); continue; } if (line.StartsWith(IonoHarmonicHeaderLabel.HEIGHT_OF_SINGLE_LAYER_AND_ITS_RMS_ERROR)) { RmsedNumeral rmsedVal = ParseRmedNumeral(strVal); header.LayerHeight = rmsedVal; continue; } if (line.StartsWith(IonoHarmonicHeaderLabel.COORDINATES_OF_EARTH_CENTERED_DIPOLE_AXIS)) { line = ReadNextNoNullLine(reader); strVal = GetValueString(line); line = ReadNextNoNullLine(reader); strVal = GetValueString(line); continue; } if (line.StartsWith(IonoHarmonicHeaderLabel.PERIOD_OF_VALIDITY)) { line = ReadNextNoNullLine(reader); strVal = GetValueString(line); var start = Time.Parse(strVal); line = ReadNextNoNullLine(reader); strVal = GetValueString(line); var end = start; if (!String.IsNullOrWhiteSpace(strVal)) { end = Time.Parse(strVal); } header.ValidPeroid = new TimePeriod(start, end); continue; } if (line.StartsWith(IonoHarmonicHeaderLabel.LATITUDE_BAND_COVERED)) { line = ReadNextNoNullLine(reader); strVal = GetValueString(line); var min = Geo.Utils.StringUtil.ParseDouble(strVal); line = ReadNextNoNullLine(reader); strVal = GetValueString(line); var max = Geo.Utils.StringUtil.ParseDouble(strVal); header.LatSpan = new NumerialSegment(min, max); continue; } if (line.StartsWith(IonoHarmonicHeaderLabel.ADDITIONAL_INFORMATION)) { while ((line = ReadNextNoNullLine(reader)) != null) { if (line.StartsWith(IonoHarmonicHeaderLabel.COEFFICIENTS)) { break; } if (line.StartsWith(IonoHarmonicHeaderLabel.DEGREE)) { break; } strVal = GetValueString(line); if (line.StartsWith(IonoHarmonicHeaderLabel.NUMBER_OF_CONTRIBUTING_STATIONS)) { header.NumOfStations = Geo.Utils.StringUtil.ParseInt(strVal); continue; } if (line.StartsWith(IonoHarmonicHeaderLabel.NUMBER_OF_CONTRIBUTING_SATELLITES)) { header.NumOfSatellites = Geo.Utils.StringUtil.ParseInt(strVal); continue; } if (line.StartsWith(IonoHarmonicHeaderLabel.ELEVATION_CUT_OFF_ANGLE)) { header.ElevationCutOff = Geo.Utils.StringUtil.ParseDouble(strVal); continue; } if (line.StartsWith(IonoHarmonicHeaderLabel.MAXIMUM_TEC_AND_ITS_RMS)) { header.MaxTec = ParseRmedNumeral(strVal); continue; } } if (line.StartsWith(IonoHarmonicHeaderLabel.COEFFICIENTS)) { break; } if (line.StartsWith(IonoHarmonicHeaderLabel.DEGREE)) { break; } } } return(header); }
/// <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); }
/// <summary> /// 读取RINEX文件的头文件。 /// </summary> /// <param name="path">文件路径</param> /// <returns></returns> public IonoHeader ReadHeader(string path) { if (!Geo.Utils.FileUtil.IsValid(path)) { return(null); } IonoHeader header = new IonoHeader(); header.FileName = Path.GetFileName(path); using (StreamReader r = new StreamReader(path, true)) { int lineIndex = 0; string line = null; while ((line = ReadNextNoNullLine(r)) != null) { lineIndex++; //中文字符支持 int nonAscCount = StringUtil.GetNonAscCount(line.Substring(0, 60 > line.Length ? line.Length : 60)); string headerLabel = line.Substring(60 - nonAscCount).TrimEnd();//header label 61-80 if (headerLabel.Contains(RinexHeaderLabel.END_OF_HEADER)) { break; } string content = line.Substring(0, 60); if (String.IsNullOrWhiteSpace(content)) { continue; } //没有内容 switch (headerLabel) { case RinexHeaderLabel.IONEX_VERSION_TYPE: header.Version = double.Parse(line.Substring(0, 8)); header.FileType = line.Substring(20, 1); header.SatSysOrTheoModel = line.Substring(40, 3); break; case RinexHeaderLabel.PGM_RUN_BY_DATE: header.FileInfo.CreationProgram = line.Substring(0, 20).TrimEnd(); header.FileInfo.CreationAgence = line.Substring(20, 20).Trim(); header.FileInfo.CreationDate = line.Substring(40, 20).TrimEnd(); break; case RinexHeaderLabel.COMMENT: if (header.Comments == null) { header.Comments = new List <string>(); } header.Comments.Add(line.Substring(0, 60 - nonAscCount).Trim()); break; case RinexHeaderLabel.DESCRIPTION: header.Description = (line.Substring(0, 60 - nonAscCount).Trim()); break; case RinexHeaderLabel.EPOCH_OF_FIRST_MAP: header.EpochOfFirstMap = Time.Parse(line.Substring(0, 60 - nonAscCount).Trim()); break; case RinexHeaderLabel.EPOCH_OF_LAST_MAP: header.EpochOfLastMap = Time.Parse(line.Substring(0, 60 - nonAscCount).Trim()); break; case RinexHeaderLabel.INTERVAL: header.Interval = double.Parse(line.Substring(0, 10)); break; case RinexHeaderLabel.OF_MAPS_IN_FILE: var str = line.Substring(0, 60); if (String.IsNullOrWhiteSpace(str)) { break; } header.NumOfTotalMaps = IntUtil.TryParse(str); break; case RinexHeaderLabel.MAPPING_FUNCTION: header.Description = (line.Substring(0, 60 - nonAscCount).Trim()); break; case RinexHeaderLabel.ELEVATION_CUTOFF: header.ElevatonCutOff = StringUtil.ParseDouble(line.Substring(0, 10)); break; case RinexHeaderLabel.OBSERVABLES_USED: header.ObservablesUsed = (line.Substring(0, 60 - nonAscCount).Trim()); break; case RinexHeaderLabel.OF_STATIONS: var str2 = line.Substring(0, 6); if (String.IsNullOrWhiteSpace(str2)) { break; } header.NumOfStations = IntUtil.TryParse(str2); break; case RinexHeaderLabel.OF_SATELLITES: var str3 = line.Substring(0, 6); if (String.IsNullOrWhiteSpace(str3)) { break; } header.NumOfSatellites = IntUtil.TryParse(str3); break; case RinexHeaderLabel.BASE_RADIUS: header.MeanEarthRadius = double.Parse(line.Substring(0, 10)); break; case RinexHeaderLabel.MAP_DIMENSION: var str4 = line.Substring(0, 6); if (String.IsNullOrWhiteSpace(str4)) { break; } header.MapDimension = IntUtil.TryParse(str4); break; case RinexHeaderLabel.HGT1_HGT2_DHGT: header.HeightRange = ParseIncreaseValue(line); break; case RinexHeaderLabel.LON1_LON2_DLON: header.HeightRange = ParseIncreaseValue(line); break; case RinexHeaderLabel.LAT1_LAT2_DLAT: header.HeightRange = ParseIncreaseValue(line); break; case RinexHeaderLabel.EXPONENT: header.Exponent = int.Parse(line.Substring(0, 6)); break; case RinexHeaderLabel.START_OF_AUX_DATA: header.StartOfAuxData = line.Substring(0, 60).Trim(); break; case RinexHeaderLabel.END_OF_AUX_DATA: header.EndOfAuxData = line.Substring(0, 60).Trim(); break; case RinexHeaderLabel.STATION_BIAS_RMS: var satFlag = line.Substring(3, 1); //GNSS系统标识 如 G var siteName = satFlag + "_" + line.Substring(6, 4).Trim().ToLower(); //IGS code var val = new RmsedNumeral() { Value = Double.Parse(line.Substring(26, 10)), Rms = Double.Parse(line.Substring(36, 10)), }; header.StationsWithBiasRms[siteName] = val; break; case RinexHeaderLabel.PRN_BIAS_RMS: var Name = SatelliteNumber.Parse(line.Substring(0, 6).Trim()); var val2 = new RmsedNumeral() { Value = Double.Parse(line.Substring(6, 10)), Rms = Double.Parse(line.Substring(16, 10)), }; header.SatellitesWithBiasRms[Name] = val2; break; case RinexHeaderLabel.END_OF_HEADER: return(header); default: break; } header.LineNumber = lineIndex + 1; } } return(header); }