Example #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);
        }
Example #2
0
        /// <summary>
        /// 计算改正数
        /// </summary>
        /// <param name="input"></param>
        public override void Correct(EpochInformation input)
        {
            if (input.EnabledSatCount == 0)
            {
                return;
            }
            var correction = new Dictionary <RinexSatFrequency, NEU>();

            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文件中");
                }
                this.Correction = correction;
                return;
            }

            foreach (var item in antenna.Data)
            {
                var satFreq = item.Key;
                var pco     = antenna.GetPcoValue(satFreq); //这个值不变,实际上一次赋值就可以了!!//2018.08.02, czs,in hmx
                correction.Add(satFreq, pco);
            }
            //多频的权宜之计
            if (input.SatelliteTypes.Count > 0)
            {
                correction[RinexSatFrequency.BdsA]     = correction[RinexSatFrequency.GpsA];
                correction[RinexSatFrequency.BdsB]     = correction[RinexSatFrequency.GpsB];
                correction[RinexSatFrequency.GalileoA] = correction[RinexSatFrequency.GpsA];
                correction[RinexSatFrequency.GalileoB] = correction[RinexSatFrequency.GpsB];
            }

            this.Correction = correction;
        }
        /// <summary>
        /// 根据太阳计算卫星偏差
        /// </summary>
        /// <param name="prn"></param>
        /// <param name="eph"></param>
        /// <param name="emissionTime"></param>
        /// <returns></returns>
        private XYZ GetSatAntOff(SatelliteNumber prn, IEphemeris eph, Time emissionTime)
        {
            ErpItem erpv = null;

            if (DataSouceProvider.ErpDataService != null)
            {
                erpv = DataSouceProvider.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.DataSouceProvider.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 (DataSouceProvider.AntennaDataSource == null)
            {
                return(new XYZ());
            }

            IAntenna antenna = DataSouceProvider.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!!!
            RinexSatFrequency freq = new RinexSatFrequency(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);
        }
Example #4
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);
        }