public override void Correct(EpochSatellite epochSatellite) { if (IonoParamService == null) { return; } IIonoParam ionParam = IonoParamService.Get(epochSatellite.ReceiverTime); if (ionParam == null) { return; } double correction = GetCorrectorInDistance(epochSatellite, ionParam); this.Correction = correction; if (IsCorrectionOnPhase) { this.Correction = -this.Correction; } // epochSatellite.SetCorrection(ErrorType, correction); }
/// <summary> /// 计算X,模型参数之一。phase (radians) /// </summary> /// <param name="ionParam"></param> /// <param name="ionMLat">电离层穿刺点平均纬度,单位:半周</param> /// <param name="tlocal"></param> /// <returns></returns> private static double GetX(IIonoParam ionParam, double ionMLat, double tlocal) { double per = GetPER(ionParam, ionMLat); double x = 2.0 * PI * (tlocal - 50400.0) / per; return(x); }
/// <summary> /// 计算PER,模型参数之一。period /// </summary> /// <param name="ionParam"></param> /// <param name="ionMLat">电离层穿刺点平均纬度,单位:半周</param> /// <returns></returns> private static double GetPER(IIonoParam ionParam, double ionMLat) { double per = ionParam.BetaB0 + ionParam.BetaB1 * ionMLat + ionParam.BetaB2 * ionMLat * ionMLat + ionParam.BetaB3 * ionMLat * ionMLat * ionMLat; if (per < 72000.0) { per = 72000.0; } return(per); }
/// <summary> /// 计算AMP,模型参数之一。amplitude /// </summary> /// <param name="ionParam"></param> /// <param name="ionMLat">电离层穿刺点平均纬度,单位:半周</param> /// <returns></returns> private static double GetAMP(IIonoParam ionParam, double ionMLat) { double amp = ionParam.AlfaA0 + ionParam.AlfaA1 * ionMLat + ionParam.AlfaA2 * ionMLat * ionMLat + ionParam.AlfaA3 * ionMLat * ionMLat * ionMLat; if (amp < 0.0) { //*******throw new Exception("amp limit="+amp); amp = 0.0; } return(amp); }
/// <summary> /// 电离层模型改正。返回改正距离。 单位:米 /// </summary> /// <param name="epochSatellite">卫星观测信息</param> /// <param name="ionParam">电离层参数</param> /// <returns></returns> public static double GetCorrectorInDistance(EpochSatellite epochSatellite, IIonoParam ionParam) { if (ionParam == null) { return(0); } double correction = GetCorrectorInDistance(epochSatellite.RecevingTime.SecondsOfWeek, epochSatellite.Ephemeris.XYZ, epochSatellite.SiteInfo.EstimatedXyz, ionParam); return(correction); }
/// <summary> /// 电离层模型改正。返回时间延迟,单位:秒。 /// broadcast iono (coeff.v. icd-200) /// input time: fraction of ut (or gps time of secondOfWeek) (machts nicht) /// </summary> /// <param name="weekSecond">周秒</param> /// <param name="satXyz">卫星位置</param> /// <param name="rcvXyz">接收机位置</param> /// <returns>time delay in fraction</returns> public static double IonoCorrection(double weekSecond, XYZ satXyz, XYZ rcvXyz, IIonoParam ionParam) { //*** divide by pi to funcKeyToDouble radians to semicircles Polar p = CoordTransformer.XyzToGeoPolar(satXyz, rcvXyz, AngleUnit.Radian); //myV.GetLocalPolar(rxPos); //azimuth angle between the user and satellite, measured clockwise positive from the true North (semi-circles) double A = p.Azimuth; // 只参与三角计算,故单位为弧度radians here //elevation angle between the user and satellite (semi-circles) double E = p.Elevation / PI; //半周 GeoCoord geo = CoordTransformer.XyzToGeoCoord(rcvXyz, AngleUnit.Radian); double rcvLat = geo.Lat / PI; //半周 double rcvLon = geo.Lon / PI; //半周 //earth's central angle between the user position and the earth projection of ionospheric intersection point (semi-circles) double psi = GetEarthsCentralAngle(E); double inoLat = GetIonLat(A, rcvLat, psi); double inoLon = GetIonLon(A, rcvLon, psi, inoLat); double ionMLat = GetMeanIonLat(inoLat, inoLon); //*** local time from gps or ut time double tlocal = GetLocalTime(weekSecond, inoLon); //*** magnification factor, amplitude, and period double f = GetF(E); double amp = GetAMP(ionParam, ionMLat); double x = GetX(ionParam, ionMLat, tlocal); return(GetTimeDelay(f, amp, x)); }
/// <summary> /// 电离层模型改正。返回改正距离。 单位:米 /// Tiono is referred to the L1 frequency; if the user is operating on the L2 frequency, /// the correction term must be multiplied by γ (reference paragraph 20.3.3.3.3.2), /// </summary> /// <param name="weekSecond">周秒</param> /// <param name="satXyz">卫星位置</param> /// <param name="receiverXyz">接收机位置</param> /// <param name="ionParam">电离层参数</param> /// <returns> </returns> public static double GetCorrectorInDistance(double weekSecond, XYZ satXyz, XYZ receiverXyz, IIonoParam ionParam) { if (ionParam == null) { return(0); } return(GnssConst.LIGHT_SPEED * IonoCorrection(weekSecond, satXyz, receiverXyz, ionParam)); }