示例#1
0
        /// <summary>
        /// Returns the position of Sun ECEF coordinates (meters) at the indicated time.
        /// </summary>
        /// <param name="t">the time to look up</param>
        /// <returns>the position of the Sun at time (as a Triple)</returns>
        /// @throw InvalidRequest If the request can not be completed for any
        /// reason, this is thrown. The text may have additional
        /// information as to why the request failed.
        /// @warning This method yields an approximate result, given that pole movement
        /// is not taken into account, neither precession nor nutation.
        public void GetPosition(Time time, ErpItem erpv)
        {
            //gpst2utc
            Time tutc = time.GpstToUtc();


            // Test if the time interval is correct
            if ((tutc < initialTime) || (tutc > finalTime))
            {
                throw new Exception("Provided epoch is out of bounds!");
            }

            //utc -> ut1
            Time tut = tutc + erpv.Ut12Utc;

            //sun and moon position in eci
            XYZ rs = new XYZ(0, 0, 0);
            XYZ rm = new XYZ(0, 0, 0);

            sunmoonpos_eci(tut, ref rs, ref rm);


            //eci to ecef transformation matrix
            double[] U     = new double[9];//3*3 transformation matrix
            double   gmst_ = 0.0;

            eci2ecef(tutc, erpv, ref U, ref gmst_);


            //sun and moon postion in ecef
            char[]   tr  = new char[2]; tr[0] = 'N'; tr[1] = 'N';
            double[] rsn = new double[3]; rsn[0] = rs.X; rsn[1] = rs.Y; rsn[2] = rs.Z;
            double[] rmn = new double[3]; rmn[0] = rm.X; rmn[1] = rm.Y; rmn[2] = rm.Z;

            double[] rsun = new double[3]; double[] rmoon = new double[3];

            matmul(tr, 3, 1, 3, 1.0, U, rsn, 0.0, ref rsun);

            matmul(tr, 3, 1, 3, 1.0, U, rmn, 0.0, ref rmoon);



            this.rSun  = new XYZ(rsun);
            this.rMoon = new XYZ(rmoon);
            this.gmst  = gmst_;
        }
        /// <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);
        }
示例#3
0
        /// <summary>
        /// eci to ecef transformation matrix
        /// compute eci to ecef transformation matrix
        /// </summary>
        /// <param name="tutc">time in UTC</param>
        /// <param name="erpv">erp value (xp, yp, ut1_utc, lod) (rad, rad, s, s/d)</param>
        /// <param name="U">eci to ecef transformation matrix (3*3)</param>
        /// <param name="gmst">greenwich mean sidereal time (rad)</param>
        private void eci2ecef(Time tutc, ErpItem erpv, ref double[] U, ref double gmst)
        {
            Time tutc_ = tutc;

            Time gpstime0 = new Time(2000, 1, 1, 12);

            //terrestrial time
            Time tgps = tutc_.UtcToGpsT();

            double t = ((double)(tgps - gpstime0) + 19.0 + 32.184) / 86400.0 / 36525.0;

            double t2 = t * t; double t3 = t2 * t;


            double[] f = new double[5];

            //astronomical arguments
            ast_args(t, ref f);

            /* iau 1976 precession */
            double ze  = (2306.2181 * t + 0.30188 * t2 + 0.017998 * t3) * SunMoonPosition.DAS2R;
            double th  = (2004.3109 * t - 0.42665 * t2 - 0.041833 * t3) * SunMoonPosition.DAS2R;
            double z   = (2306.2181 * t + 1.09468 * t2 + 0.018203 * t3) * SunMoonPosition.DAS2R;
            double eps = (84381.448 - 46.8150 * t - 0.00059 * t2 + 0.001813 * t3) * SunMoonPosition.DAS2R;

            double[] R1 = Rz(-z); double[] R2 = Ry(th); double[] R3 = Rz(-ze);
            char[]   tr = new char[2]; tr[0] = 'N'; tr[1] = 'N';
            double[] R  = new double[9];
            matmul(tr, 3, 3, 3, 1.0, R1, R2, 0.0, ref R);
            double[] P = new double[9];
            matmul(tr, 3, 3, 3, 1.0, R, R3, 0.0, ref P);/* P=Rz(-z)*Ry(th)*Rz(-ze) */

            // iau 1980 nutation
            double dpsi = 0.0, deps = 0.0;

            nut_iau1980(t, f, ref dpsi, ref deps);
            R1 = Rx(-eps - deps); R2 = Rz(-dpsi); R3 = Rx(eps);

            R = new double[9];
            matmul(tr, 3, 3, 3, 1.0, R1, R2, 0.0, ref R);
            double[] N = new double[9];
            matmul(tr, 3, 3, 3, 1.0, R, R3, 0.0, ref N); /* N=Rx(-eps)*Rz(-dspi)*Rx(eps) */

            //greenwich aparent sidereal time (rad)
            double gmst_ = Time.UtcToGmst(tutc_, erpv.Ut12Utc);

            double gast = gmst_ + dpsi * Math.Cos(eps);

            gast += (0.00264 * Math.Sin(f[4]) + 0.000063 * Math.Sin(2.0 * f[4])) * SunMoonPosition.DAS2R;

            /* eci to ecef transformation matrix */
            R1 = Ry(-erpv.Xpole * SunMoonPosition.DAS2R); R2 = Rx(-erpv.Ypole * SunMoonPosition.DAS2R); R3 = Rz(gast);
            double[] W = new double[9];
            matmul(tr, 3, 3, 3, 1.0, R1, R2, 0.0, ref W);


            R = new double[9];
            matmul(tr, 3, 3, 3, 1.0, W, R3, 0.0, ref R); /* W=Ry(-xp)*Rx(-yp) */
            double[] NP = new double[9];
            matmul(tr, 3, 3, 3, 1.0, N, P, 0.0, ref NP);
            double[] U_ = new double[9];
            matmul(tr, 3, 3, 3, 1.0, R, NP, 0.0, ref U_); /* U=W*Rz(gast)*N*P */

            for (int i = 0; i < 9; i++)
            {
                U[i] = U_[i];
            }
            gmst = gmst_;
        }