示例#1
0
        public override void Correct(EpochInformation epochInformation)
        {
            Time gpsTime         = epochInformation.ReceiverTime;//.CorrectedTime;
            XYZ  reciverPosition = epochInformation.SiteInfo.EstimatedXyz;

            //查找地球自转信息
            //gpst2utc
            Time tutc = gpsTime.GpstToUtc();

            Gnsser.Data.ErpItem erpv = null;
            if (DataSouceProvider.ErpDataService != null)
            {
                erpv = DataSouceProvider.ErpDataService.Get(tutc);
            }
            if (erpv == null)
            {
                erpv = ErpItem.Zero;
            }

            var pos = DataSouceProvider.UniverseObjectProvider.GetOrCreate(gpsTime, erpv);

            //Gnsser.Data.ErpItem erpv = epochInformation.DataSouceProvider.ErpDataService.Gete);
            //XYZ sunPos = new XYZ(); XYZ moonPos = new XYZ(); double gmst = 0.0;
            //epochInformation.DataSouceProvider.UniverseObjectProvider.GetSunPosition(gpsTime, erpv, ref sunPos, ref moonPos,ref gmst);

            NEU correction = GetSolidTidesCorrectValue(gpsTime, reciverPosition, pos.SunXyz, pos.MoonXyz);

            this.Correction = (correction);
        }
示例#2
0
 /// <summary>
 /// 字符串
 /// </summary>
 /// <param name="n"></param>
 /// <returns></returns>
 public static string GetNEUString(NEU n)
 {
     return
         (StringUtil.FillSpaceLeft(n.N.ToString("0.0000"), 8) + "  "
          + StringUtil.FillSpaceLeft(n.E.ToString("0.0000"), 8) + "  "
          + StringUtil.FillSpaceLeft(n.U.ToString("0.0000"), 8));
 }
示例#3
0
        /// <summary>
        /// 接收机天线改正
        /// </summary>
        /// <param name="epochInformation"></param>
        public override void Correct(EpochInformation epochInformation)
        {
            HEN offsetARPHEN = epochInformation.SiteInfo.Hen;

            if (offsetARPHEN == null)
            {
                return;
            }

            // Vector from monument to ARP([UEN]),标石到天线参考点(ARP)的矢量。
            NEU offsetARP  = new NEU(offsetARPHEN.N, offsetARPHEN.E, offsetARPHEN.H);
            NEU correction = offsetARP;

            this.Correction = correction;
            //this.Correction = NEU.Zero;// correction;
        }
示例#4
0
        /// <summary>
        /// 极潮改正,参考RTKLIB模块
        /// </summary>
        /// <param name="reciverPosition"></param>
        /// <param name="xDisplacement"></param>
        /// <param name="yDisplacement"></param>
        /// <returns></returns>
        private static NEU GetPoleTidesCorrectValue2(XYZ reciverPosition, double xDisplacement, double yDisplacement)
        {
            double[] pos = new double[2];
            pos[0] = Math.Asin(reciverPosition.Z / reciverPosition.Length);
            pos[1] = Math.Atan2(reciverPosition.Y, reciverPosition.X);

            double cosl = Math.Cos(pos[1]); double sinl = Math.Sin(pos[1]);

            double e = 9E-3 * Math.Sin(pos[0]) * (xDisplacement * sinl + yDisplacement * cosl);
            double n = -9E-3 * Math.Cos(2.0 * pos[0]) * (xDisplacement * cosl - yDisplacement * sinl);
            double u = -32E-3 * Math.Sin(2.0 * pos[0]) * (xDisplacement * cosl - yDisplacement * sinl);

            NEU correction = new NEU(n, e, u);

            return(correction);
        }
示例#5
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);
        }
示例#6
0
        public override void Correct(EpochInformation epochInformation)
        {
            string markerName = epochInformation.SiteInfo.SiteName;

            //   Time gpsTime = epochInformation.CorrectedTime;
            Time gpsTime = epochInformation.ReceiverTime;


            //gpst2utc
            Time tutc = gpsTime.GpstToUtc();

            //查找地球自转信息
            Gnsser.Data.ErpItem erpv = null;
            if (DataSouceProvider.ErpDataService != null)
            {
                erpv = DataSouceProvider.ErpDataService.Get(tutc);
            }
            if (erpv == null)
            {
                erpv = ErpItem.Zero;
            }

            //GPS时转UTC时,再加上ERP改正
            gpsTime = tutc + erpv.Ut12Utc;


            // Geo.Algorithm.Matrix harmonics = new Geo.Algorithm.Matrix(6, 11, 0.0);


            // harmonics = epochInformation.AssistantInfo.Harmonics;
            if (markerName.Length > 4)
            {
                markerName = markerName.Substring(0, 4);
            }
            Geo.Algorithm.IMatrix harmonics = DataSouceProvider.OceanLoadingDataSource.Get(markerName);


            //GPSTK模块
            // NEU correction = GetOceanTidesCorrectValue(gpsTime,  harmonics);

            //RTKLIB模块
            NEU correction = GetOceanTidesCorrectValue1(gpsTime, harmonics);

            this.Correction = (correction);
        }
示例#7
0
        public override void Correct(EpochInformation epochInformation)
        {
            Time gpsTime = epochInformation.ReceiverTime;//.CorrectedTime;

            XYZ reciverPosition = epochInformation.SiteInfo.EstimatedXyz;

            GeoCoord geoCoord = epochInformation.SiteInfo.ApproxGeoCoord;

            if (XYZ.IsZeroOrEmpty(reciverPosition))
            {
                this.Correction = NEU.Zero;
                return;
            }

            //GPS时转UTC时
            Time tutc = gpsTime.GpstToUtc();

            //查找ERP信息
            //查找地球自转信息
            Gnsser.Data.ErpItem erpv = null;
            if (DataSouceProvider.ErpDataService != null)
            {
                erpv = DataSouceProvider.ErpDataService.Get(tutc);
            }
            if (erpv == null)
            {
                erpv = ErpItem.Zero;
            }

            //EarthPoleDisplacement
            double xp = erpv.Xpole;//arcsec
            double yp = erpv.Ypole;

            //RTKLIB的极潮改正模块
            // NEU correction = GetPoleTidesCorrectValue2(reciverPosition, xp, yp);

            //GPSTK的极潮改正模块
            NEU correction = GetPoleTidesCorrectValue(gpsTime, reciverPosition, xp, yp, geoCoord);

            this.Correction = (correction);
        }
示例#8
0
        public override void Correct(EpochInformation epochInformation)
        {
            if (XYZ.IsZeroOrEmpty(epochInformation.SiteInfo.EstimatedXyz) || epochInformation.EnabledSatCount == 0 || epochInformation.ReceiverTime.IsZero)
            {
                this.Correction = new NEU(); return;
            }

            //   Time gpsTime = epochInformation.CorrectedTime;
            Time gpsTime = epochInformation.ReceiverTime;

            XYZ reciverPosition = epochInformation.SiteInfo.EstimatedXyz;

            GeoCoord geoPosition = epochInformation.SiteInfo.ApproxGeoCoord;

            XYZ rsun = new XYZ(); XYZ rmoon = new XYZ(); double gmst = 0;

            //gpst2utc
            Time tutc = gpsTime.GpstToUtc();

            //查找地球自转信息
            Gnsser.Data.ErpItem erpv = null;
            if (DataSouceProvider.ErpDataService != null)
            {
                erpv = DataSouceProvider.ErpDataService.Get(tutc);
            }
            if (erpv == null)
            {
                erpv = ErpItem.Zero;
            }

            Time tut = tutc + erpv.Ut12Utc;

            //采用RTKLIB的太阳月亮位置计算方法(历书计算方法不同,相关文献表明对最终的定位精度影响差别不大)
            DataSouceProvider.UniverseObjectProvider.GetSunPosition(gpsTime, erpv, ref rsun, ref rmoon, ref gmst);

            NEU Correction = GetSolidTidesCorrectValue(geoPosition, reciverPosition, rsun, rmoon, gmst);

            this.Correction = (Correction);
        }
示例#9
0
        /** Returns the effect of ocean tides loading (meters) at the given
         *  station and epoch, in the Up-East-North (UEN) reference frame.
         *
         * @param name  Station name (case is NOT relevant).
         * @param time  Epoch to look up
         *
         * @return a Triple with the ocean tidas loading effect, in meters
         * and in the UEN reference frame.
         *
         * @throw InvalidRequest If the request can not be completed for any
         * reason, this is thrown. The text may have additional information
         * about the reason the request failed.
         */
        /// <summary>
        /// 海洋负荷改正,采用GPSTK模块
        /// 此处采用NEU表示,其中的各个分量相对应。
        /// </summary>
        /// <param name="gpsTime">Epoch to look up</param>
        /// <param name="position">Position of interest</param>
        /// <returns></returns>
        public static NEU GetOceanTidesCorrectValue(Time gpsTime, Geo.Algorithm.IMatrix harmonics)
        {
            const int NUM_COMPONENTS = 3;
            const int NUM_HARMONICS  = 11;

            double[] arguments = new double[11];
            // List<double> arguments = new List<double>(11);
            //Compute arguments
            arguments = GetArg(gpsTime);


            double[] triple = new double[NUM_COMPONENTS];
            for (int i = 0; i < NUM_COMPONENTS; i++)
            {
                double temp = 0.0;
                for (int k = 0; k < NUM_HARMONICS; k++)
                {
                    double tttt = harmonics[i, k];
                    double ttt  = arguments[k];
                    double tt   = harmonics[i + 3, k];
                    temp += harmonics[i, k] * Math.Cos(arguments[k] - harmonics[i + 3, k] * CoordConsts.DegToRadMultiplier);
                }
                triple[i] = temp;
            }
            // This Triple is in Up, West, South reference frame
            double up     = triple[0];
            double west   = triple[1];
            double sourth = triple[2];

            double north = -sourth;
            double east  = -west;

            NEU oceanTides = new NEU(north, east, up);

            return(oceanTides);
        }
示例#10
0
        /** Returns the effect of pole tides (meters) at the given
         *  position and epoch, in the Up-East-North (UEN) reference frame.
         *
         * @param[in]  t Epoch to look up
         * @param[in]  info Position of interest
         *
         * @return a Triple with the pole tide effect, in meters and in
         *    the UEN reference frame.
         *
         * @throw InvalidRequest If the request can not be completed for any
         *    reason, this is thrown. The text may have additional
         *    information about the reason the request failed.
         *
         * @warning In order to use this method, you must have previously
         *    set the current pole displacement parameters.
         *
         */
        public NEU GetPoleTide(Time t, XYZ p)
        {
            //store the results
            NEU res = new NEU(0.0, 0.0, 0.0);

            //Declare J2000 reference time: January 1st, 2000, at noon
            Time j2000 = new Time(2000, 1, 1, 12, 0, 0.0);

            //Get current position's latitude and longitude, in radians
            GeoCoord geoCoord  = Geo.Coordinates.CoordTransformer.XyzToGeoCoord_Rad(p.X, p.Y, p.Z);
            double   latitude  = geoCoord.Lat;
            double   longitude = geoCoord.Lon;

            // Compute appropriate running averages
            // Get time difference between current epoch and
            // J2000.0, in years
            double timedif = (double)((t.MJulianDays - j2000.MJulianDays) / 365.25M);

            //IERS mean pole model
            //double xpbar = (0.054 + timedif * 0.00083);
            //double ypbar = (0.357 + timedif * 0.00395);
            double xpbar = 0.0;
            double ypbar = 0.0;

            #region IERS Conventions 2010 p115

            if (t.Year < 2010)
            {
                xpbar = 55.974 * 1.0e-3 + timedif * 1.8243 * 1.0e-3 + timedif * timedif * 0.18413 * 1.0e-3 + timedif * timedif * timedif * 0.007024 * 1.0e-3;
                ypbar = 346.346 * 1.0e-3 + timedif * 1.7896 * 1.0e-3 + timedif * timedif * (-0.10729) * 1.0e-3 + timedif * timedif * timedif * (-0.000908) * 1.0e-3;
            }
            else
            {
                xpbar = 23.513 * 1.0e-3 + timedif * 7.6141 * 1.0e-3;
                ypbar = 358.891 * 1.0e-3 + timedif * (-0.6287) * 1.0e-3;
            }

            #endregion
            // Now, compute m1 and m2 parameters
            double m1 = (XDisplacement - xpbar);
            double m2 = (ypbar - YDisplacement);

            // Now, compute some useful values
            double sin2lat = (Math.Sin(2.0 * latitude));
            double cos2lat = (Math.Cos(2.0 * latitude));
            double sinlat  = (Math.Sin(latitude));
            double sinlon  = (Math.Sin(longitude));
            double coslon  = (Math.Cos(longitude));

            // Finally, get the pole tide values, in UEN reference
            // frame and meters
            double u = -0.033 * sin2lat * (m1 * coslon + m2 * sinlon);
            double e = +0.009 * sinlat * (m1 * sinlon - m2 * coslon);
            double n = -0.009 * cos2lat * (m1 * coslon + m2 * sinlon);

            res = new NEU(n, e, u);

            // Please be aware that the former equations take into account
            // that the IERS pole tide equations use CO-LATITUDE instead
            // of LATITUDE. See Wahr, 1985.
            return(res);
        }
示例#11
0
        /// <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);
        }
示例#12
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);
        }
示例#13
0
        /// <summary>
        /// 海潮改正模型,采用RTKLIB的模块
        /// 2015.04.12
        /// </summary>
        /// <param name="gpsTime"></param>
        /// <param name="harmonics"></param>
        /// <returns></returns>
        public static NEU GetOceanTidesCorrectValue1(Time gpsTime, Geo.Algorithm.IMatrix harmonics)
        {
            double[][] args =
            {
                new double[]   { 1.40519E-4,  2.0, -2.0,  0.0,  0.00 }, /* M2 */
                new double[]   { 1.45444E-4,  0.0,  0.0,  0.0,  0.00 }, /* S2 */
                new double[]   { 1.37880E-4,  2.0, -3.0,  1.0,  0.00 }, /* N2 */
                new double[]   { 1.45842E-4,  2.0,  0.0,  0.0,  0.00 }, /* K2 */
                new double[]   { 0.72921E-4,  1.0,  0.0,  0.0,  0.25 }, /* K1 */
                new double[]   { 0.67598E-4,  1.0, -2.0,  0.0, -0.25 }, /* O1 */
                new double[]   { 0.72523E-4, -1.0,  0.0,  0.0, -0.25 }, /* P1 */
                new double[]   { 0.64959E-4,  1.0, -3.0,  1.0, -0.25 }, /* Q1 */
                new double[]   { 0.53234E-5,  0.0,  2.0,  0.0,  0.00 }, /* Mf */
                new double[]   { 0.26392E-5,  0.0,  1.0, -1.0,  0.00 }, /* Mm */
                new double[]   { 0.03982E-5,  2.0,  0.0,  0.0,  0.00 }  /* Ssa */
            };                                                          //11 * 5
            Time ep1975 = new Time(1975, 1, 1);
            //angular argument
            // double fday = gpsTime.SecondsOfDay;// gpsTime.Hour * 3600 + gpsTime.Minute * 60 + gpsTime.Fraction;

            double fday = gpsTime.Hour * 3600 + gpsTime.Minute * 60 + gpsTime.Seconds;



            Time gpsTime0 = gpsTime.Date;

            double days = (double)(gpsTime0 - ep1975) / 86400.0;
            double t, t2, t3, ang;

            double[] a = new double[5]; double[] dp = new double[3];

            t  = (27392.500528 + 1.000000035 * days) / 36525.0;
            t2 = t * t; t3 = t2 * t;

            a[0] = fday;
            a[1] = (279.69668 + 36000.768930485 * t + 3.03E-4 * t2) * SunMoonPosition.DegToRad;                 /* H0 */
            a[2] = (270.434358 + 481267.88314137 * t - 0.001133 * t2 + 1.9E-6 * t3) * SunMoonPosition.DegToRad; /* S0 */
            a[3] = (334.329653 + 4069.0340329577 * t + 0.010325 * t2 - 1.2E-5 * t3) * SunMoonPosition.DegToRad; /* P0 */
            a[4] = 2.0 * SunMoonPosition.PI;

            //displancements by 11 constituents
            for (int i = 0; i < 11; i++)
            {
                ang = 0.0;
                for (int j = 0; j < 5; j++)
                {
                    ang += a[j] * args[i][j];
                }
                for (int j = 0; j < 3; j++)
                {
                    dp[j] += harmonics[j, i] * Math.Cos(ang - harmonics[j + 3, i] * SunMoonPosition.DegToRad);
                }
            }

            double e = -dp[1];
            double n = -dp[2];
            double u = dp[0];

            NEU res = new NEU(n, e, u);

            return(res);
        }
示例#14
0
        private static NEU GetSolidTidesCorrectValue(GeoCoord geoPosition, XYZ reciverPosition, XYZ rsun, XYZ rmoon, double gmst)
        {
            double[] pos = new double[2];
            pos[0] = Math.Asin(reciverPosition.Z / reciverPosition.Length);
            pos[1] = Math.Atan2(reciverPosition.Y, reciverPosition.X);

            double sinp = Math.Sin(pos[0]); double cosp = Math.Cos(pos[0]);
            double sinl = Math.Sin(pos[1]); double cosl = Math.Cos(pos[1]);

            double[] E = new double[9];

            E[0] = -sinl; E[3] = cosl; E[6] = 0.0;
            E[1] = -sinp * cosl; E[4] = -sinp * sinl; E[7] = cosp;
            E[2] = cosp * cosl; E[5] = cosp * sinl; E[8] = sinp;


            double[] eu = new double[3];
            /* step1: time domain */
            eu[0] = E[2]; eu[1] = E[5]; eu[2] = E[8];


            double[] dr1 = tide_pl(eu, rsun, SunMoonPosition.GMS, pos);

            double[] dr2 = tide_pl(eu, rmoon, SunMoonPosition.GMM, pos);

            /* step2: frequency domain, only K1 radial */
            double sin2l = Math.Sin(2.0 * pos[0]);
            double du    = -0.012 * sin2l * Math.Sin(gmst + pos[1]);

            double[] dr = new double[3];
            dr[0] = dr1[0] + dr2[0] + du * E[2]; //x
            dr[1] = dr1[1] + dr2[1] + du * E[5]; //y
            dr[2] = dr1[2] + dr2[2] + du * E[8]; //z


            double lat = geoPosition.Lat;
            double lon = geoPosition.Lon;

            double refLat = 0, refLon = 0;

            if (lat > 90.0 || lat < -90.0)
            {
                //如果在此,说明有大错误!
                refLat = 0.0;
            }
            else
            {
                refLat = lat * SunMoonPosition.DegToRad;
            }
            refLon = lon * SunMoonPosition.DegToRad;



            double sinlat = Math.Sin(refLat); double coslat = Math.Cos(refLat);
            double sinlon = Math.Sin(refLon); double coslon = Math.Cos(refLon);

            double[][] rotate =
            {
                new double[] { -coslon * sinlat, -sinlon, coslat *coslon },
                new double[] { -sinlon * sinlat, coslon,  coslat *sinlon },
                new double[] { coslat,               0.0, sinlat         },
            };


            double detN = rotate[0][0] * dr[0] + rotate[1][0] * dr[1] + rotate[2][0] * dr[2];
            double detE = rotate[0][1] * dr[0] + rotate[1][1] * dr[1] + rotate[2][1] * dr[2];
            double detH = rotate[0][2] * dr[0] + rotate[1][2] * dr[1] + rotate[2][2] * dr[2];


            double e11 = -sinlon; double e12 = coslon; double e13 = 0.0;
            double e21 = -sinlat * coslon; double e22 = -sinlat * sinlon; double e23 = coslat;
            double e31 = coslat * coslon; double e32 = coslat * sinlon; double e33 = sinlat;

            double e = e11 * dr[0] + e12 * dr[1] + e13 * dr[2];
            double n = e21 * dr[0] + e22 * dr[1] + e23 * dr[2];
            double u = e31 * dr[0] + e32 * dr[1] + e33 * dr[2];



            NEU newCorrection = new NEU(n, e, u);

            return(newCorrection);
        }
示例#15
0
        /** Returns the effect of pole tides (meters) at the given
         *  position and epoch, in the Up-East-North (UEN) reference frame.
         *
         * @param[in]  t Epoch to look up
         * @param[in]  info Position of interest
         *
         * @return a Triple with the pole tide effect, in meters and in
         *    the UEN reference frame.
         *
         * @throw InvalidRequest If the request can not be completed for any
         *    reason, this is thrown. The text may have additional
         *    information about the reason the request failed.
         *
         * @warning In order to use this method, you must have previously
         *    set the current pole displacement parameters.
         *
         */
        /// <summary>
        /// 固体潮改正
        /// Returns the effect of solid Earth tides (meters) at the given position and epoch, in the Up-East-North (UEN) reference frame.
        /// 此处采用NEU表示,其中的各个分量相对应。
        /// </summary>
        /// <param name="gpsTime">Epoch to look up</param>
        /// <param name="position">Position of interest</param>
        /// <returns></returns>
        public static NEU GetSolidTidesCorrectValue(Time gpsTime, XYZ position, XYZ sunPos, XYZ moonPos)
        {
            NEU solidTides = new NEU();

            ////Objects to compute Sun and Moon positions
            //SunPosition sunPosition = new SunPosition();
            //MoonPosition moonPosition = new MoonPosition();

            //// Variables to hold Sun and Moon positions
            //XYZ sunPos = (sunPosition.GetPosition(gpsTime));
            //XYZ moonPos = (moonPosition.GetPosition(gpsTime));


            // Compute the factors for the Sun
            double rpRs = (position.X * sunPos[0] +
                           position.Y * sunPos[1] +
                           position.Z * sunPos[2]);

            double Rs2 = sunPos[0] * sunPos[0] +
                         sunPos[1] * sunPos[1] +
                         sunPos[2] * sunPos[2];
            double rp2 = (position.X * position.X + position.Y * position.Y + position.Z * position.Z);

            double xy2p   = (position.X * position.X + position.Y * position.Y);
            double sqxy2p = (Math.Sqrt(xy2p));

            double sqRs2 = (Math.Sqrt(Rs2));

            double fac_s = (3.0 * SunMoonPosition.MU_SUN * rp2 / (sqRs2 * sqRs2 * sqRs2 * sqRs2 * sqRs2));

            double g1sun = (fac_s * (rpRs * rpRs / 2.0 - rp2 * Rs2 / 6.0));

            double g2sun = (fac_s * rpRs * (sunPos[1] * position.X -
                                            sunPos[0] * position.Y) * Math.Sqrt(rp2) / sqxy2p);

            double g3sun = (fac_s * rpRs * (sqxy2p * sunPos[2] -
                                            position.Z / sqxy2p * (position.X * sunPos[0] +
                                                                   position.Y * sunPos[1])));

            // Compute the factors for the Moon
            double rpRm = (position.X * moonPos[0] +
                           position.Y * moonPos[1] +
                           position.Z * moonPos[2]);

            double Rm2 = (moonPos[0] * moonPos[0] +
                          moonPos[1] * moonPos[1] +
                          moonPos[2] * moonPos[2]);

            double sqRm2 = (Math.Sqrt(Rm2));

            double fac_m = (3.0 * SunMoonPosition.MU_MOON * rp2 / (sqRm2 * sqRm2 * sqRm2 * sqRm2 * sqRm2));

            double g1moon = (fac_m * (rpRm * rpRm / 2.0 - rp2 * Rm2 / 6.0));

            double g2moon = (fac_m * rpRm * (moonPos[1] * position.X -
                                             moonPos[0] * position.Y) * Math.Sqrt(rp2) / sqxy2p);

            double g3moon = (fac_m * rpRm * (sqxy2p * moonPos[2] -
                                             position.Z / sqxy2p * (position.X * moonPos[0] +
                                                                    position.Y * moonPos[1])));



            // Effects due to the Sun
            double delta_sun1 = (H_LOVE * g1sun);
            double delta_sun2 = (L_LOVE * g2sun);
            double delta_sun3 = (L_LOVE * g3sun);

            // Effects due to the Moon
            double delta_moon1 = (H_LOVE * g1moon);
            double delta_moon2 = (L_LOVE * g2moon);
            double delta_moon3 = (L_LOVE * g3moon);

            // Combined effect
            //Up-East-North
            double up    = delta_sun1 + delta_moon1;
            double east  = delta_sun2 + delta_moon2;
            double north = delta_sun3 + delta_moon3;

            solidTides = new NEU(north, east, up);

            return(solidTides);
        }
示例#16
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);
        }