/// <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); }
/// <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_; }