private RinexSatFrequency GetSatFrequence() { if (enumRadioControl_frequenceTypes.IsReady && enumRadioControl_satelliteType.IsReady) { var satType = enumRadioControl_satelliteType.GetCurrent <SatelliteType>(); var freqType = enumRadioControl_frequenceTypes.GetCurrent <FrequenceType>(); RinexSatFrequency satelliteFrequency = new RinexSatFrequency(satType, (int)freqType); return(satelliteFrequency); } return(null); }
private void button_solve_Click(object sender, EventArgs e) { RinexSatFrequency satFreq = GetSatFrequence(); int n = namedIntControl_epochCount.GetValue(); double deltaL = satFreq.GetFrequence().WaveLength * 0.01;// 0.0019; double deltaP = this.namedFloatControl_deltaOfP.GetValue(); double deltaC = namedFloatControl_deltaOfC.GetValue(); double deltaLSquared = deltaL * deltaL; double deltaPSquared = deltaP * deltaP; double deltaCSquared = deltaC * deltaC; int i = n; double deltaPs = GetDeltaOfSmoothedRange(i, deltaP, deltaL); double deltaCs = GetDeltaOfSmoothedRange(i, deltaC, deltaL); double step = this.namedFloatControl_step.GetValue(); double stepWeight = (i - 1) * step; if (i >= 100) { stepWeight = 0.01; } double normalWeight = 1.0 / i; double deltaStepP = GetDeltaOfWeightedSmoothRange(i, stepWeight, deltaP, deltaL); double deltaStepC = GetDeltaOfWeightedSmoothRange(i, stepWeight, deltaC, deltaL); double deltaWeightedPs = GetDeltaOfWeightedSmoothRange(i, normalWeight, deltaP, deltaL); double deltaWeightedCs = GetDeltaOfWeightedSmoothRange(i, normalWeight, deltaC, deltaL); double timesOfP = deltaP / deltaPs; double timesOfC = deltaC / deltaCs; double timesOfWeightedP = deltaP / deltaWeightedPs; double timesOfWeightedC = deltaC / deltaWeightedCs; double timesOfStepWeightedP = deltaStepP / deltaWeightedPs; double timesOfStepWeightedC = deltaStepC / deltaWeightedCs; StringBuilder sb = new StringBuilder(); sb.AppendLine("deltaPs:\t" + deltaPs); sb.AppendLine("deltaCs:\t" + deltaCs); sb.AppendLine("deltaWeightedPs:\t" + deltaWeightedPs); sb.AppendLine("deltaWeightedCs:\t" + deltaWeightedCs); sb.AppendLine("deltaStepP:\t" + deltaStepP); sb.AppendLine("deltaStepC:\t" + deltaStepC); sb.AppendLine("timesOfP:\t" + timesOfP); sb.AppendLine("timesOfC:\t" + timesOfC); sb.AppendLine("timesOfWeightedP:\t" + timesOfWeightedP); sb.AppendLine("timesOfWeightedC:\t" + timesOfWeightedC); sb.AppendLine("timesOfStepWeightedP:\t" + timesOfStepWeightedP); sb.AppendLine("timesOfStepWeightedC:\t" + timesOfStepWeightedC); this.richTextBoxControl1.Text = sb.ToString(); }
/// <summary> /// 卫星天线相位中心改正,参照RTKLIB /// </summary> /// <param name="satelliteType"></param> /// <param name="satPos"></param> /// <param name="ReceiverPosition"></param> /// <param name="sunPosition"></param> /// <param name="svPCcorr"></param> /// <param name="antenna"></param> /// <returns></returns> private static double GetPhaseCorrection1(SatelliteNumber prn, XYZ satPos, XYZ ReceiverPosition, XYZ sunPosition, double svPCcorr, IAntenna antenna) { XYZ ru = ReceiverPosition - satPos; XYZ rz = -satPos; double[] eu = new double[3]; eu[0] = ru.X / ru.Length; eu[1] = ru.Y / ru.Length; eu[2] = ru.Z / ru.Length; double[] ez = new double[3]; ez[0] = rz.X / rz.Length; ez[1] = rz.Y / rz.Length; ez[2] = rz.Z / rz.Length; double cosa = eu[0] * ez[0] + eu[1] * ez[1] + eu[2] * ez[2]; cosa = cosa < -1.0 ? -1.0 : (cosa > 1.0 ? 1.0 : cosa); double nadir = Math.Acos(cosa) * CoordConsts.RadToDegMultiplier; //// The nadir angle should always smaller than 14.0 deg, // // but some times it's a bit bigger than 14.0 deg, we // // force it to 14.0 deg to stop throwing an exception. // // The Reference is available at: // // http://igscb.jpl.nasa.gov/igscb/resource/pubs/02_ott/session_8.pdf // nadir = (nadir > 14) ? 14.0 : nadir; double elev = 90.0 - nadir; // Get antenna eccentricity for frequency "G01" (L1), in // satellite reference system. // NOTE: It is NOT in ECEF, it is in UEN!!! RinexSatFrequency freq = new RinexSatFrequency(prn, 1); // NEU satAnt = antenna.GetAntennaEccentricity(AntennaFrequency.G01); NEU satAnt = antenna.GetPcoValue(freq); if (satAnt.Equals(NEU.Zero)) { return(0); } //Now, get the phase center variation. var var = antenna.GetPcvValue(freq, elev); //只有U方向有值 // Projection of "svAntenna" vector to line of sight vector rrho // svPCcorr = var.U; return(var); }
private void ShowFrequence() { RinexSatFrequency satelliteFrequency = GetSatFrequence(); if (satelliteFrequency == null) { return; } StringBuilder sb = new StringBuilder(); sb.AppendLine("当前选中了: " + satelliteFrequency.ToString()); if (satelliteFrequency.GetFrequence() != null) { sb.AppendLine("频率: " + satelliteFrequency.GetFrequence().ToString()); } log.Info(sb.ToString()); }
/// <summary> /// 解析主体数据部分 /// </summary> /// <param name="sr"></param> /// <param name="antenna"></param> /// <param name="line"></param> /// <returns></returns> private static string ParseFrequency(StreamReader sr, Antenna antenna, string line) { var freqString = line.Substring(3, 3).Trim(); var freq = RinexSatFrequency.Parse(freqString); // Read new line and extract label line = sr.ReadLine(); var label = line.Substring(60).Trim(); //Repeat until 'endOfFreq' line while (label != AntexLabel.END_OF_FREQUENCY) { //Eccentricities of the mean antenna phase center relative to the antenna reference point (ARP)(in millimeters). //平均天线相位中心相对于天线参考点(ARP)的偏心率(以毫米计)。 if (label == AntexLabel.NORTH_EAST_UP) { var neu = ParseNEU(line); antenna.SetAntennaEcc(freq, neu); } else { //Check if this line contains "NOAZI" pattern if (line.Substring(3, 5).Trim() == "NOAZI")//常常为第一行:表明不依赖方位角,如卫星 { StringUtil.TrimFirstWord(ref line); List <double> pcVec = ParseArrayLine(antenna, line); antenna.SetAntennaNoAziPattern(freq, pcVec); } else//依赖方位角,如测站 { double azi = Convert.ToDouble(StringUtil.TrimFirstWord(ref line)); List <double> pcVec = ParseArrayLine(antenna, line); antenna.SetAntennaPattern(freq, azi, pcVec); } } //Read new line and extract label line = sr.ReadLine(); label = line.Substring(60).Trim(); }//End of While(label != endOfFreq) return(label); }
/// <summary> /// The section includes the rms values of the phase center eccentricities and of the phase pattern values. /// </summary> /// <param name="sr"></param> /// <param name="antenna"></param> /// <param name="line"></param> /// <returns></returns> private static string ParseFrequencyRms(StreamReader sr, Antenna antenna, ref string line) { string label; string freqString = line.Substring(3, 3).Trim(); RinexSatFrequency freq = RinexSatFrequency.Parse(freqString); // Read new line and extract label line = sr.ReadLine(); label = line.Substring(60).Trim(); //Repeat until 'endOfFreqRMS' line while (label != AntexLabel.END_OF_FREQ_RMS) { //Process this line if (label == AntexLabel.NORTH_EAST_UP)//Rms of the eccentricities (in milli meters) { //Add antenna eccentricities RMS, as Meters antenna.SetAntennaRmsEcc(freq, ParseNEU(line)); } else { //Check if this line contains "NOAZI" pattern RMS if (line.Substring(3, 5).Trim() == "NOAZI") //表明不依赖方位角,如卫星 { StringUtil.TrimFirstWord(ref line); List <double> pcVec = ParseArrayLine(antenna, line); antenna.SetAntennaNoAziRms(freq, pcVec); } else//依赖方位角,如测站 { double azi = Convert.ToDouble(StringUtil.TrimFirstWord(ref line)); List <double> pcVec = ParseArrayLine(antenna, line); antenna.SetAntennaPatternRms(freq, azi, pcVec); } } //Read new line and extract label line = sr.ReadLine(); label = line.Substring(60).Trim(); } return(label); }
/// <summary> /// 计算卫星相位中心改正值。 /// </summary> /// <param name="prn">卫星编号</param> /// <param name="freq">频率</param> /// <param name="time">历元</param> /// <param name="satPos">卫星位置</param> /// <param name="sunPosition">太阳位置</param> /// <param name="ReceiverPosition">接收机位置</param> /// <param name="StationLonLatHeight">测站位置</param> /// <param name="satData">Name of "PRN_GPS"-like file containing satellite satData.</param> /// <returns></returns> public static double GetSatPhaseCenterCorectValue(SatelliteNumber prn, RinexSatFrequency freq, Time time, XYZ satPos, XYZ ReceiverPosition, GeoCoord StationLonLatHeight, XYZ sunPosition, SatInfoFile satData, IAntenna antenna = null) { if (antenna == null) { return(0); } // This variable that will hold the correction, 0.0 by default double svPCcorr = 0.0; // Check is Antex antenna information is available or not, and if // available, whether satellite phase center information is absolute or relative bool absoluteModel = false; if (antenna != null) { absoluteModel = antenna.Header.IsAbsolute; } if (absoluteModel) { //方法1:参考GPSTK // svPCcorr = GetPhaseCorrection(satelliteType,freq, satPos, ReceiverPosition, sunPosition, svPCcorr, antenna); //方法2:参考RTKLIB svPCcorr = GetPhaseCorrection1(prn, freq, satPos, ReceiverPosition, StationLonLatHeight, sunPosition, svPCcorr, antenna); } else// 采用一些默认的参数。 { svPCcorr = DefautSatPhaseCorrector(prn, time, satPos, ReceiverPosition, sunPosition, satData); } // This correction is interpreted as an "advance" in the signal, // instead of a delay. Therefore, it has negative sign return(svPCcorr); }
/// <summary> /// 卫星天线相位中心改正,参照GPSTK模块 /// </summary> /// <param name="satelliteType"></param> /// <param name="satPos"></param> /// <param name="ReceiverPosition"></param> /// <param name="sunPosition"></param> /// <param name="svPCcorr"></param> /// <param name="antenna"></param> /// <returns></returns> private static double GetPhaseCorrection(SatelliteNumber prn, XYZ satPos, XYZ ReceiverPosition, XYZ sunPosition, double svPCcorr, IAntenna antenna) { // Unitary vector from satellite to Earth mass center (ECEF) XYZ satToEarthUnit = (-1.0) * satPos.UnitVector(); // Unitary vector from Earth mass center to Sun (ECEF) XYZ earthToSunUnit = sunPosition.UnitVector(); // rj = rk x ri: Rotation axis of solar panels (ECEF) XYZ rj = satToEarthUnit.Cross(earthToSunUnit); // Redefine ri: ri = rj x rk (ECEF) earthToSunUnit = rj.Cross(satToEarthUnit); // Let's funcKeyToDouble ri to an unitary vector. (ECEF) earthToSunUnit = earthToSunUnit.UnitVector(); // Get vector from Earth mass center to receiver XYZ receiverPos = ReceiverPosition; // Compute unitary vector vector from satellite to RECEIVER XYZ satToReceverUnit = (receiverPos - satPos).UnitVector(); // When not using Antex information, if satellite belongs to block // "IIR" its correction is 0.0, else it will depend on satellite model. // We will need the elevation, in degrees. It is found using // dot product and the corresponding unitary angles double cosa = satToReceverUnit.Dot(satToEarthUnit); cosa = cosa < -1.0 ? -1.0 : (cosa > 1.0 ? 1.0 : cosa); double nadir = Math.Acos(cosa) * CoordConsts.RadToDegMultiplier; if (!DoubleUtil.IsValid(nadir)) { return(0); } // The nadir angle should always smaller than 14.0 deg, // but some times it's a bit bigger than 14.0 deg, we // force it to 14.0 deg to stop throwing an exception. // The Reference is available at: // http://igscb.jpl.nasa.gov/igscb/resource/pubs/02_ott/session_8.pdf nadir = (nadir > 14) ? 14.0 : nadir; double elev = 90.0 - nadir; // Get antenna eccentricity for frequency "G01" (L1), in // satellite reference system. // NOTE: It is NOT in ECEF, it is in UEN!!! RinexSatFrequency freq = new RinexSatFrequency(prn, 1); // NEU satAnt = antenna.GetAntennaEccentricity(AntennaFrequency.G01); NEU satAnt = antenna.GetPcoValue(freq); if (satAnt.Equals(NEU.Zero)) { return(0); } //Now, get the phase center variation. NEU var = new NEU(0, 0, antenna.GetPcvValue(freq, elev)); // We must substract them satAnt = satAnt - var; // Change to ECEF // 原 satAnt t is in UEN!!!,本satAnt为NEU,分量相对应 // satAnt[0] = U // Triple svAntenna( satAnt[2]*ri + satAnt[1]*rj + satAnt[0]*rk ); // XYZ svAntenna = satAnt.N * earthToSunUnit + satAnt.E * rj + satAnt.U * satToEarthUnit; XYZ svAntenna = -(var.N * earthToSunUnit + var.E * rj + var.U * satToEarthUnit); // Projection of "svAntenna" vector to line of sight vector rrho svPCcorr = (satToReceverUnit.Dot(svAntenna)); return(svPCcorr); }
/// <summary> /// 根据太阳计算卫星偏差 /// </summary> /// <param name="prn"></param> /// <param name="eph"></param> /// <param name="emissionTime"></param> /// <returns></returns> private XYZ GetSatAntOff(SatelliteNumber prn, RinexSatFrequency freq, IEphemeris eph, Time emissionTime) { ErpItem erpv = null; if (Context.ErpDataService != null) { erpv = Context.ErpDataService.Get(emissionTime); } if (erpv == null) { erpv = ErpItem.Zero; } XYZ rsun = new XYZ(); //sun position in ecef // rsun = EpochSat.EpochInfo.DataSouceProvider.UniverseObjectProvider.GetSunPosition(emissionTime); this.Context.UniverseObjectProvider.GetSunPosition(emissionTime, erpv, ref rsun); //unit vetcors of satellite fixed coordinates XYZ ez = -1 * eph.XYZ.UnitVector(); XYZ es = (rsun - eph.XYZ).UnitVector(); //outer product of 3D vectors XYZ r = new XYZ(); r.X = ez.Y * es.Z - ez.Z * es.Y; r.Y = ez.Z * es.X - ez.X * es.Z; r.Z = ez.X * es.Y - ez.Y * es.X; XYZ r0 = new XYZ(); r0.X = r.Y * ez.Z - r.Z * ez.Y; r0.Y = r.Z * ez.X - r.X * ez.Z; r0.Z = r.X * ez.Y - r.Y * ez.X; XYZ ex = r0.UnitVector(); XYZ ey = r.UnitVector(); //XYZ ex = new XYZ(); //ex.X = ey.Y * ez.Z - ey.Z * ez.Y; //ex.Y = ey.Z * ez.X - ey.X * ez.Z; //ex.Z = ey.X * ez.Y - ey.Y * ez.X; //use L1 value if (Context.AntennaDataSource == null) { return(new XYZ()); } IAntenna antenna = Context.AntennaDataSource.Get(prn.ToString(), emissionTime); //如果为空,则返回 0 坐标 if (antenna == null) { return(new XYZ()); } // Get antenna eccentricity for frequency "G01" (L1), in // satellite reference system. // NOTE: It is NOT in ECEF, it is in UEN!!! //lly注释 //SatelliteFrequency freq = new SatelliteFrequency(prn, 1); // NEU satAnt = antenna.GetAntennaEccentricity(AntennaFrequency.G01); NEU satAnt = antenna.GetPcoValue(freq); XYZ dant = new XYZ(); dant.X = satAnt.E * ex.X + satAnt.N * ey.X + satAnt.U * ez.X; dant.Y = satAnt.E * ex.Y + satAnt.N * ey.Y + satAnt.U * ez.Y; dant.Z = satAnt.E * ex.Z + satAnt.N * ey.Z + satAnt.U * ez.Z; // Unitary vector from satellite to Earth mass center (ECEF) XYZ satToEarthUnit = (-1.0) * eph.XYZ.UnitVector(); // Unitary vector from Earth mass center to Sun (ECEF) XYZ earthToSunUnit = rsun.UnitVector(); // rj = rk x ri: Rotation axis of solar panels (ECEF) XYZ rj = satToEarthUnit.Cross(earthToSunUnit); // Redefine ri: ri = rj x rk (ECEF) earthToSunUnit = rj.Cross(satToEarthUnit); // Let's funcKeyToDouble ri to an unitary vector. (ECEF) earthToSunUnit = earthToSunUnit.UnitVector(); XYZ dant1 = new XYZ(); dant1.X = satAnt.E * rj.X + satAnt.N * earthToSunUnit.X + satAnt.U * satToEarthUnit.X; dant1.Y = satAnt.E * rj.Y + satAnt.N * earthToSunUnit.Y + satAnt.U * satToEarthUnit.Y; dant1.Z = satAnt.E * rj.Z + satAnt.N * earthToSunUnit.Z + satAnt.U * satToEarthUnit.Z; return(dant1); }
private void button_multiDelta_Click(object sender, EventArgs e) { RinexSatFrequency satFreq = GetSatFrequence(); ObjectTableStorage table = new ObjectTableStorage(); bool isShowCA = checkBox_IsShowCA.Checked; double step = this.namedFloatControl_step.GetValue(); double n = namedIntControl_epochCount.GetValue(); var deltaL = satFreq.GetFrequence().WaveLength * 0.01;// 0.0019; double deltaP = this.namedFloatControl_deltaOfP.GetValue(); double deltaC = namedFloatControl_deltaOfC.GetValue(); var deltaLSquared = deltaL * deltaL; var deltaPSquared = deltaP * deltaP; var deltaCSquared = deltaC * deltaC; double stepCount = 1 / step; for (int i = 1; i < n; i++) { //原始 double deltaPs = GetDeltaOfSmoothedRange(i, deltaP, deltaL); double deltaCs = GetDeltaOfSmoothedRange(i, deltaC, deltaL); //加权平均 double normalWeight = 1.0 / i; double deltaWeightedPs = GetDeltaOfWeightedSmoothRange(i, normalWeight, deltaP, deltaL); double deltaWeightedCs = GetDeltaOfWeightedSmoothRange(i, normalWeight, deltaC, deltaL); //步长加权 double stepWeight = 1 - (i - 1) * step; // stepCount;// (i - 1) * step; if (i >= stepCount) { stepWeight = step; } double deltaStepP2 = GetDeltaOfStepWeightedSmoothRange(i, step, deltaP, deltaL); double deltaStepP = GetDeltaOfWeightedSmoothRange(i, stepWeight, deltaP, deltaL); double deltaStepC = GetDeltaOfWeightedSmoothRange(i, stepWeight, deltaC, deltaL); double timesOfP = deltaP / deltaPs; double timesOfC = deltaC / deltaCs; double timesOfWeightedP = deltaP / deltaWeightedPs; double timesOfWeightedC = deltaC / deltaWeightedCs; if (i < 1000) { table.NewRow(); table.AddItem("Epoch", i); table.AddItem("σRawSP", deltaPs); if (isShowCA) { table.AddItem("σRawSC", deltaCs); } table.AddItem("σWSP", deltaWeightedPs); if (isShowCA) { table.AddItem("σWSC", deltaWeightedCs); } table.AddItem("σStepSP", deltaStepP); table.AddItem("σStepSP2", deltaStepP2); if (isShowCA) { table.AddItem("σStepSC", deltaStepC); } } // 精度提高倍数 else if ( //i <= 10 // || (i > 10 && i <= 100 && i % 10 == 0) // || (i > 100 && i <= 1000 && i % 100 == 0) // || (i > 1000 && i % 1000 == 0) || (i > 10000 && i % 10000 == 0) || (i > 100000 && i % 100000 == 0)) { table.NewRow(); table.AddItem("Epoch", i); table.AddItem("σRawSP", deltaPs); if (isShowCA) { table.AddItem("σRawSC", deltaCs); } table.AddItem("σWSP", deltaWeightedPs); if (isShowCA) { table.AddItem("σWSC", deltaWeightedCs); } table.AddItem("σStepSP", deltaStepP); if (isShowCA) { table.AddItem("σStepSC", deltaStepP); } } } table.IndexColName = "Epoch"; this.objectTableControl1.DataBind(table); }
/// <summary> /// 卫星天线相位中心改正,参照RTKLIB /// </summary> /// <param name="prn"></param> /// <param name="freq"></param> /// <param name="satPos"></param> /// <param name="ReceiverPosition"></param> /// <param name="sunPosition"></param> /// <param name="svPCcorr"></param> /// <param name="antenna"></param> /// <returns></returns> private static double GetPhaseCorrection1(SatelliteNumber prn, RinexSatFrequency freq, XYZ satPos, XYZ ReceiverPosition, GeoCoord StationLonLatHeight, XYZ sunPosition, double svPCcorr, IAntenna antenna) { XYZ ru = ReceiverPosition - satPos; XYZ rz = -satPos; double[] eu = new double[3]; eu[0] = ru.X / ru.Length; eu[1] = ru.Y / ru.Length; eu[2] = ru.Z / ru.Length; double[] ez = new double[3]; ez[0] = rz.X / rz.Length; ez[1] = rz.Y / rz.Length; ez[2] = rz.Z / rz.Length; double cosa = eu[0] * ez[0] + eu[1] * ez[1] + eu[2] * ez[2]; cosa = cosa < -1.0 ? -1.0 : (cosa > 1.0 ? 1.0 : cosa); double nadir = Math.Acos(cosa) * CoordConsts.RadToDegMultiplier; //// The nadir angle should always smaller than 14.0 deg, // // but some times it's a bit bigger than 14.0 deg, we // // force it to 14.0 deg to stop throwing an exception. // // The Reference is available at: // // http://igscb.jpl.nasa.gov/igscb/resource/pubs/02_ott/session_8.pdf nadir = (nadir > 14) ? 14.0 : nadir; double elev = 90.0 - nadir; // Get antenna eccentricity for frequency "G01" (L1), in // satellite reference system. // NOTE: It is NOT in ECEF, it is in UEN!!! //lly注释 //SatelliteFrequency freq = new SatelliteFrequency(prn, 1); // NEU satAnt = antenna.GetAntennaEccentricity(AntennaFrequency.G01); //NEU satAnt = antenna.TryGetAntennaEccentricity(freq); //if (satAnt.Equals(NEU.Zero)) // return 0; //Now, get the phase center variation. double u = antenna.GetPcvValue(freq, elev); NEU var = new NEU(0, 0, u); //只有U方向有值 // Projection of "svAntenna" vector to line of sight vector rrho svPCcorr = var.U; //Compute vector station-satellite, in ECEF //XYZ ray = satPos - ReceiverPosition; //Rotate vector ray to UEN reference frame //此处修改为 NEU 坐标系。 //NEU rayNeu = CoordTransformer.XyzToNeu(ray, StationLonLatHeight, AngleUnit.Degree); //XYZ ray0 = XYZ.RotateZ(ray, StationLonLatHeight.Lon); //XYZ ray1 = XYZ.RotateY(ray0, -StationLonLatHeight.Lat); //ray = XYZ.RotateZ(ray, lon); //ray = XYZ.RotateY(ray, -lat); //Convert ray to an unitary vector // XYZ xyzNeu = new XYZ(rayNeu.N, rayNeu.E, rayNeu.U); //NEU unit = rayNeu.UnitNeuVector(); //if (var == null) return 0; ////计算沿着射线方向的改正数。Compute corrections = displacement vectors components along ray direction. //double correctForL = var.Dot(unit); //if(svPCcorr != correctForL) //{ // correctForL = svPCcorr; //} return(var.U); }