示例#1
0
        /// <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);
        }
示例#2
0
        /// <summary>
        /// 改正
        /// </summary>
        /// <param name="input"></param>
        public override void Correct(EpochSatellite input)
        {
            var correction = new Dictionary <RinexSatFrequency, double>();

            this.Correction = correction;

            IAntenna antenna = input.SiteInfo.Antenna;

            if (antenna == null)
            {
                if (!WarnedSites.Contains(input.SiteInfo.SiteName))
                {
                    WarnedSites.Add(input.SiteInfo.SiteName);
                    log.Warn(input.Name + "接收机天线为: " + input.SiteInfo.AntennaType + ", " + input.SiteInfo.AntennaNumber + " 没有在天线文件夹中找到该类型的天线,无法进行 PCV 改正,精度影响可达10厘米(特别是高程)!请到 https://www.ngs.noaa.gov/ANTCAL/ 下载对应天线改正信息,并追加到.atx文件中");
                }
                return;
            }
            List <RinexSatFrequency> frequences = input.RinexSatFrequences;

            XYZ rcvPos = input.SiteInfo.EstimatedXyz;

            if (rcvPos.Equals(XYZ.Zero))//测站未获取近似值,不改正
            {
                log.Warn(input.ReceiverTime + ", " + input.Name + ", 测站未获取近似值,不改正PCV");
                this.Correction = correction;
                return;
            }

            var elev = input.GeoElevation;
            var azim = input.Polar.Azimuth;

            foreach (var item in antenna.Data)
            {
                var    satFreq = item.Key;
                double pcv     = 0;
                if (IsUseAzimuthAntenna)
                {
                    pcv = antenna.GetPcvValue(satFreq, elev, azim);
                }
                else
                {
                    pcv = antenna.GetPcvValue(satFreq, elev);
                    ///**PCV 是站星距离,不是ENU, 不用再次改正 */
                    //不信,可以试试:转换成站星方向改正等效距离算法如下:
                    //double rangeCorretion = CoordUtil.GetDirectionLength(pcv, input.Polar);
                    ////approx, 用以验证
                    //double test = pcv.U * Math.Sin(input.GeoElevation * Geo.CoordConsts.DegToRadMultiplier);
                    //double differ = rangeCorretion - test;
                }

                correction.Add(satFreq, pcv);
            }

            //多频的权宜之计
            if (input.EpochInfo.SatelliteTypes.Count > 0)
            {
                correction[RinexSatFrequency.BdsA]     = antenna.GetPcvValue(RinexSatFrequency.GpsA, elev);
                correction[RinexSatFrequency.BdsB]     = antenna.GetPcvValue(RinexSatFrequency.GpsB, elev);
                correction[RinexSatFrequency.GalileoA] = correction[RinexSatFrequency.BdsA];
                correction[RinexSatFrequency.GalileoB] = correction[RinexSatFrequency.BdsB];
            }
            this.Correction = correction;
        }
示例#3
0
        /// <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);
        }
示例#4
0
        /// <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);
        }