Exemple #1
0
 public Eci(Vector pos, Vector vel, Julian date, bool IsAeUnits)
 {
     m_pos      = pos;
      m_vel      = vel;
      m_date     = date;
      m_VecUnits = (IsAeUnits ? VecUnits.UNITS_AE : VecUnits.UNITS_NONE);
 }
Exemple #2
0
        // ///////////////////////////////////////////////////////////////////
        // Calculate the ECI coordinates of the location "geo" at time "date".
        // Assumes geo coordinates are km-based.
        // Assumes the earth is an oblate spheroid as defined in WGS '72.
        // Reference: The 1992 Astronomical Almanac, page K11
        // Reference: www.celestrak.com (Dr. TS Kelso)
        public Eci(CoordGeo geo, Julian date)
        {
            m_VecUnits = VecUnits.UNITS_KM;

             double mfactor = Globals.TWOPI * (Globals.OMEGA_E / Globals.SEC_PER_DAY);
             double lat = geo.m_Lat;
             double lon = geo.m_Lon;
             double alt = geo.Altitude.Kilometers;

             // Calculate Local Mean Sidereal Time (theta)
             double theta = date.toLMST(lon);
             double c = 1.0 / Math.Sqrt(1.0 + Globals.F * (Globals.F - 2.0) * Globals.Sqr(Math.Sin(lat)));
             double s = Globals.Sqr(1.0 - Globals.F) * c;
             double achcp = (Globals.XKMPER * c + alt) * Math.Cos(lat);

             m_date = date;

             m_pos = new Vector();

             m_pos.X = achcp * Math.Cos(theta);                    // km
             m_pos.Y = achcp * Math.Sin(theta);                    // km
             m_pos.Z = (Globals.XKMPER * s + alt) * Math.Sin(lat); // km
             m_pos.W = Math.Sqrt(Globals.Sqr(m_pos.X) +
                   Globals.Sqr(m_pos.Y) +
                   Globals.Sqr(m_pos.Z));            // range, km

             m_vel = new Vector();

             m_vel.X = -mfactor * m_pos.Y;               // km / sec
             m_vel.Y =  mfactor * m_pos.X;
             m_vel.Z = 0.0;
             m_vel.W = Math.Sqrt(Globals.Sqr(m_vel.X) +  // range rate km/sec^2
                   Globals.Sqr(m_vel.Y));
        }
Exemple #3
0
        /// <summary>
        /// Creates a new instance of the class given XYZ coordinates.
        /// </summary>
        private Geo(Vector pos, double theta)
        {
            theta = theta % Globals.TwoPi;

             if (theta < 0.0)
             {
            // "wrap" negative modulo
            theta += Globals.TwoPi;
             }

             double r = Math.Sqrt(Globals.Sqr(pos.X) + Globals.Sqr(pos.Y));
             double e2 = Globals.F * (2.0 - Globals.F);
             double lat = Globals.AcTan(pos.Z, r);

             const double DELTA = 1.0e-07;
             double phi;
             double c;

             do
             {
            phi = lat;
            c = 1.0 / Math.Sqrt(1.0 - e2 * Globals.Sqr(Math.Sin(phi)));
            lat = Globals.AcTan(pos.Z + Globals.Xkmper * c * e2 * Math.Sin(phi), r);
             }
             while (Math.Abs(lat - phi) > DELTA);

             LatitudeRad  = lat;
             LongitudeRad = theta;
             Altitude = (r / Math.Cos(lat)) - Globals.Xkmper * c;
        }
Exemple #4
0
        /// <summary>
        /// Creates a instance of the class from geodetic coordinates.
        /// </summary>
        /// <param name="geo">The geocentric coordinates.</param>
        /// <param name="date">The Julian date.</param>
        /// <remarks>
        /// Assumes the Earth is an oblate spheroid.
        /// Reference: The 1992 Astronomical Almanac, page K11
        /// Reference: www.celestrak.com (Dr. T.S. Kelso)
        /// </remarks>
        public Eci(Geo geo, Julian date)
        {
            double lat = geo.LatitudeRad;
             double lon = geo.LongitudeRad;
             double alt = geo.Altitude;

             // Calculate Local Mean Sidereal Time (theta)
             double theta = date.ToLmst(lon);
             double c = 1.0 / Math.Sqrt(1.0 + Globals.F * (Globals.F - 2.0) *
                          Globals.Sqr(Math.Sin(lat)));
             double s = Globals.Sqr(1.0 - Globals.F) * c;
             double achcp = (Globals.Xkmper * c + alt) * Math.Cos(lat);

             Position = new Vector();

             Position.X = achcp * Math.Cos(theta);             // km
             Position.Y = achcp * Math.Sin(theta);             // km
             Position.Z = (Globals.Xkmper * s + alt) * Math.Sin(lat);   // km
             Position.W = Math.Sqrt(Globals.Sqr(Position.X) +
                                Globals.Sqr(Position.Y) +
                                Globals.Sqr(Position.Z));  // range, km

             Velocity = new Vector();
             double mfactor = Globals.TwoPi * (Globals.OmegaE / Globals.SecPerDay);

             Velocity.X = -mfactor * Position.Y;               // km / sec
             Velocity.Y =  mfactor * Position.X;               // km / sec
             Velocity.Z = 0.0;                                 // km / sec
             Velocity.W = Math.Sqrt(Globals.Sqr(Velocity.X) +  // range rate km/sec^2
                                Globals.Sqr(Velocity.Y));
        }
		// /////////////////////////////////////////////////////////////////////
		// Subtract a vector from this one.
		public void Sub(Vector vec)
		{
			m_x -= vec.m_x;
			m_y -= vec.m_y;
			m_z -= vec.m_z;
			m_w -= vec.m_w;
		}
		// ///////////////////////////////////////////////////////////////////////////
		// getLookAngle()
		// Return the topocentric (azimuth, elevation, etc.) coordinates for a target
		// object described by the input ECI coordinates.
		public CoordTopo getLookAngle(Eci eci)
		{
			// Calculate the ECI coordinates for this Site object at the time
			// of interest.
			Julian date    = eci.Date;
			Eci    eciSite = new Eci(m_geo, date);

			// The Site ECI units are km-based; ensure target ECI units are same
			if (!eci.UnitsAreKm())
				throw new Exception("ECI units must be kilometer-based");

			Vector vecRgRate = new Vector(eci.Velocity.X - eciSite.Velocity.X,
				eci.Velocity.Y - eciSite.Velocity.Y,
				eci.Velocity.Z - eciSite.Velocity.Z);

			double x = eci.Position.X - eciSite.Position.X;
			double y = eci.Position.Y - eciSite.Position.Y;
			double z = eci.Position.Z - eciSite.Position.Z;
			double w = Math.Sqrt(Globals.Sqr(x) + Globals.Sqr(y) + Globals.Sqr(z));

			Vector vecRange = new Vector(x, y, z, w);

			// The site's Local Mean Sidereal Time at the time of interest.
			double theta = date.toLMST(Longitude);

			double sin_lat   = Math.Sin(Latitude);
			double cos_lat   = Math.Cos(Latitude);
			double sin_theta = Math.Sin(theta);
			double cos_theta = Math.Cos(theta);

			double top_s = sin_lat * cos_theta * vecRange.X +
				sin_lat * sin_theta * vecRange.Y -
				cos_lat * vecRange.Z;
			double top_e = -sin_theta * vecRange.X +
				cos_theta * vecRange.Y;
			double top_z = cos_lat * cos_theta * vecRange.X +
				cos_lat * sin_theta * vecRange.Y +
				sin_lat * vecRange.Z;
			double az    = Math.Atan(-top_e / top_s);

			if (top_s > 0.0)
				az += Globals.PI;

			if (az < 0.0)
				az += 2.0 * Globals.PI;

			double el   = Math.Asin(top_z / vecRange.W);
			double rate = (vecRange.X * vecRgRate.X +
				vecRange.Y * vecRgRate.Y +
				vecRange.Z * vecRgRate.Z) / vecRange.W;

			CoordTopo topo = new CoordTopo(az,         // azimuth, radians
				el,         // elevation, radians
				vecRange.W, // range, km
				rate);      // rate, km / sec
#if WANT_ATMOSPHERIC_CORRECTION
      // Elevation correction for atmospheric refraction.
      // Reference:  Astronomical Algorithms by Jean Meeus, pp. 101-104
      // Note:  Correction is meaningless when apparent elevation is below horizon
      topo.m_El += Globals.Deg2Rad((1.02 /
                                    Math.Tan(Globals.Deg2Rad(Globals.Rad2Deg(el) + 10.3 /
                                    (Globals.Rad2Deg(el) + 5.11)))) / 60.0);
      if (topo.m_El < 0.0)
         topo.m_El = el;    // Reset to true elevation

      if (topo.m_El > (Globals.PI / 2))
         topo.m_El = (Globals.PI / 2);
#endif
			return topo;
		}
		// /////////////////////////////////////////////////////////////////////
		protected Eci FinalPosition(double  incl, double omega,  double     e,
			double     a, double    xl,  double xnode,
			double    xn, double tsince)
		{
			if ((e * e) > 1.0)
			{
				throw new Exception("Error in satellite data");
			}

			double beta = Math.Sqrt(1.0 - e * e);

			// Long period periodics
			double axn  = e * Math.Cos(omega);
			double temp = 1.0 / (a * beta * beta);
			double xll  = temp * m_xlcof * axn;
			double aynl = temp * m_aycof;
			double xlt  = xl + xll;
			double ayn  = e * Math.Sin(omega) + aynl;

			// Solve Kepler's Equation
			double capu   = Globals.Fmod2p(xlt - xnode);
			double temp2  = capu;
			double temp3  = 0.0;
			double temp4  = 0.0;
			double temp5  = 0.0;
			double temp6  = 0.0;
			double sinepw = 0.0;
			double cosepw = 0.0;
			bool   fDone  = false;

			for (int i = 1; (i <= 10) && !fDone; i++)
			{
				sinepw = Math.Sin(temp2);
				cosepw = Math.Cos(temp2);
				temp3 = axn * sinepw;
				temp4 = ayn * cosepw;
				temp5 = axn * cosepw;
				temp6 = ayn * sinepw;

				double epw = (capu - temp4 + temp3 - temp2) /
					(1.0 - temp5 - temp6) + temp2;

				if (Math.Abs(epw - temp2) <= Globals.E6A)
					fDone = true;
				else
					temp2 = epw;
			}

			// Short period preliminary quantities
			double ecose = temp5 + temp6;
			double esine = temp3 - temp4;
			double elsq  = axn * axn + ayn * ayn;
			temp  = 1.0 - elsq;
			double pl = a * temp;
			double r  = a * (1.0 - ecose);
			double temp1 = 1.0 / r;
			double rdot  = Globals.XKE * Math.Sqrt(a) * esine * temp1;
			double rfdot = Globals.XKE * Math.Sqrt(pl) * temp1;
			temp2 = a * temp1;
			double betal = Math.Sqrt(temp);
			temp3 = 1.0 / (1.0 + betal);
			double cosu  = temp2 * (cosepw - axn + ayn * esine * temp3);
			double sinu  = temp2 * (sinepw - ayn - axn * esine * temp3);
			double u     = Globals.AcTan(sinu, cosu);
			double sin2u = 2.0 * sinu * cosu;
			double cos2u = 2.0 * cosu * cosu - 1.0;

			temp  = 1.0 / pl;
			temp1 = Globals.CK2 * temp;
			temp2 = temp1 * temp;

			// Update for short periodics
			double rk = r * (1.0 - 1.5 * temp2 * betal * m_x3thm1) +
				0.5 * temp1 * m_x1mth2 * cos2u;
			double uk = u - 0.25 * temp2 * m_x7thm1 * sin2u;
			double xnodek = xnode + 1.5 * temp2 * m_cosio * sin2u;
			double xinck  = incl + 1.5 * temp2 * m_cosio * m_sinio * cos2u;
			double rdotk  = rdot - xn * temp1 * m_x1mth2 * sin2u;
			double rfdotk = rfdot + xn * temp1 * (m_x1mth2 * cos2u + 1.5 * m_x3thm1);

			// Orientation vectors
			double sinuk  = Math.Sin(uk);
			double cosuk  = Math.Cos(uk);
			double sinik  = Math.Sin(xinck);
			double cosik  = Math.Cos(xinck);
			double sinnok = Math.Sin(xnodek);
			double cosnok = Math.Cos(xnodek);
			double xmx = -sinnok * cosik;
			double xmy = cosnok * cosik;
			double ux  = xmx * sinuk + cosnok * cosuk;
			double uy  = xmy * sinuk + sinnok * cosuk;
			double uz  = sinik * sinuk;
			double vx  = xmx * cosuk - cosnok * sinuk;
			double vy  = xmy * cosuk - sinnok * sinuk;
			double vz  = sinik * cosuk;

			// Position
			double x = rk * ux;
			double y = rk * uy;
			double z = rk * uz;

			Vector vecPos = new Vector(x, y, z);

			// Validate on altitude
			double altKm = (vecPos.Magnitude() * (Globals.XKMPER / Globals.AE));

			if ((altKm < Globals.EARTH_RAD) || (altKm > (2 * Globals.GEOSYNC_ALT)))
			{
				throw new Exception("Satellite orbit may have decayed");
			}

			// Velocity
			double xdot = rdotk * ux + rfdotk * vx;
			double ydot = rdotk * uy + rfdotk * vy;
			double zdot = rdotk * uz + rfdotk * vz;

			Vector vecVel = new Vector(xdot, ydot, zdot);

			DateTime gmt = m_Orbit.EpochTime;

			gmt = gmt.AddMinutes(tsince);

			return new Eci(vecPos, vecVel, new Julian(gmt), true);
		}
		// ///////////////////////////////////////////////////////////////////
		// Calculate the ECI coordinates of the location "geo" at time "date".
		// Assumes geo coordinates are km-based.
		// Assumes the earth is an oblate spheroid as defined in WGS '72.
		// Reference: The 1992 Astronomical Almanac, page K11
		// Reference: www.celestrak.com (Dr. TS Kelso)
		public Eci(CoordGeo geo, Julian date)
		{
			m_VectorUnits = VectorUnits.Km;

			double mfactor = Globals.TWOPI * (Globals.OMEGA_E / Globals.SEC_PER_DAY);
			double lat = geo.Latitude;
			double lon = geo.Longitude;
			double alt = geo.Altitude;

			// Calculate Local Mean Sidereal Time (theta)
			double theta = date.toLMST(lon);
			double c = 1.0 / Math.Sqrt(1.0 + Globals.F * (Globals.F - 2.0) * Globals.Sqr(Math.Sin(lat)));
			double s = Globals.Sqr(1.0 - Globals.F) * c;
			double achcp = (Globals.XKMPER * c + alt) * Math.Cos(lat);

			m_Date = date;

			m_Position = new Vector();

			m_Position.X = achcp * Math.Cos(theta);                    // km
			m_Position.Y = achcp * Math.Sin(theta);                    // km
			m_Position.Z = (Globals.XKMPER * s + alt) * Math.Sin(lat); // km
			m_Position.W = Math.Sqrt(Globals.Sqr(m_Position.X) +
				Globals.Sqr(m_Position.Y) +
				Globals.Sqr(m_Position.Z));            // range, km

			m_Velocity = new Vector();

			m_Velocity.X = -mfactor * m_Position.Y;               // km / sec
			m_Velocity.Y =  mfactor * m_Position.X;
			m_Velocity.Z = 0.0;
			m_Velocity.W = Math.Sqrt(Globals.Sqr(m_Velocity.X) +  // range rate km/sec^2
				Globals.Sqr(m_Velocity.Y));
		}
		public Eci(Vector pos, Vector vel, Julian date, bool IsAeUnits)
		{
			m_Position      = pos;
			m_Velocity      = vel;
			m_Date     = date;
			m_VectorUnits = (IsAeUnits ? VectorUnits.Ae : VectorUnits.None);
		}
Exemple #10
0
        /// <summary>
        /// Returns the topo-centric (azimuth, elevation, etc.) coordinates for
        /// a target object described by the given ECI coordinates.
        /// </summary>
        /// <param name="eci">The ECI coordinates of the target object.</param>
        /// <returns>The look angle to the target object.</returns>
        public TopoTime GetLookAngle(EciTime eci)
        {
            // Calculate the ECI coordinates for this Site object at the time
             // of interest.
             Julian  date     = eci.Date;
             EciTime eciSite  = GetPosition(date);
             Vector vecRgRate = new Vector(eci.Velocity.X - eciSite.Velocity.X,
                                       eci.Velocity.Y - eciSite.Velocity.Y,
                                       eci.Velocity.Z - eciSite.Velocity.Z);

             double x = eci.Position.X - eciSite.Position.X;
             double y = eci.Position.Y - eciSite.Position.Y;
             double z = eci.Position.Z - eciSite.Position.Z;
             double w = Math.Sqrt(Globals.Sqr(x) + Globals.Sqr(y) + Globals.Sqr(z));

             Vector vecRange = new Vector(x, y, z, w);

             // The site's Local Mean Sidereal Time at the time of interest.
             double theta = date.ToLmst(LongitudeRad);

             double sin_lat   = Math.Sin(LatitudeRad);
             double cos_lat   = Math.Cos(LatitudeRad);
             double sin_theta = Math.Sin(theta);
             double cos_theta = Math.Cos(theta);

             double top_s = sin_lat * cos_theta * vecRange.X +
                        sin_lat * sin_theta * vecRange.Y -
                        cos_lat * vecRange.Z;
             double top_e = -sin_theta * vecRange.X +
                         cos_theta * vecRange.Y;
             double top_z = cos_lat * cos_theta * vecRange.X +
                        cos_lat * sin_theta * vecRange.Y +
                        sin_lat * vecRange.Z;
             double az    = Math.Atan(-top_e / top_s);

             if (top_s > 0.0)
             {
            az += Globals.Pi;
             }

             if (az < 0.0)
             {
            az += 2.0 * Globals.Pi;
             }

             double el   = Math.Asin(top_z / vecRange.W);
             double rate = (vecRange.X * vecRgRate.X +
                        vecRange.Y * vecRgRate.Y +
                        vecRange.Z * vecRgRate.Z) / vecRange.W;

             TopoTime topo = new TopoTime(az,         // azimuth, radians
                                      el,         // elevation, radians
                                      vecRange.W, // range, km
                                      rate,       // rate, km / sec
                                      eci.Date);

            #if WANT_ATMOSPHERIC_CORRECTION
              // Elevation correction for atmospheric refraction.
              // Reference:  Astronomical Algorithms by Jean Meeus, pp. 101-104
              // Note:  Correction is meaningless when apparent elevation is below horizon
              topo.m_El += Globals.ToRadians((1.02 /
                                    Math.Tan(Globals.ToRadians(Globals.ToDegrees(el) + 10.3 /
                                    (Globals.ToDegrees(el) + 5.11)))) / 60.0);
              if (topo.m_El < 0.0)
              {
             topo.m_El = el;    // Reset to true elevation
              }

              if (topo.m_El > (Globals.PI / 2))
              {
             topo.m_El = (Globals.PI / 2);
              }
            #endif
             return topo;
        }
Exemple #11
0
 /// <summary>
 /// Calculates the dot product of this vector and another.
 /// </summary>
 /// <param name="vec">The second vector.</param>
 /// <returns>The dot product.</returns>
 public double Dot(Vector vec)
 {
     return (X * vec.X) + (Y * vec.Y) + (Z * vec.Z);
 }
		// /////////////////////////////////////////////////////////////////////
		// Calculate the angle between this vector and another
		public double Angle(Vector vec)
		{
			return Math.Acos(Dot(vec) / (Magnitude() * vec.Magnitude()));
		}
Exemple #13
0
 /// <summary>
 /// Creates a new instance of the class from ECI coordinates.
 /// </summary>
 /// <param name="eci">The ECI coordinates.</param>
 public Eci(Eci eci)
 {
     Position = new Vector(eci.Position);
      Velocity = new Vector(eci.Velocity);
 }
Exemple #14
0
 /// <summary>
 /// Creates a new instance of the class with the given position and
 /// velocity components.
 /// </summary>
 /// <param name="pos">The position vector.</param>
 /// <param name="vel">The velocity vector.</param>
 public Eci(Vector pos, Vector vel)
 {
     Position = pos;
      Velocity = vel;
 }
Exemple #15
0
 /// <summary>
 /// Creates a new instance of the class from XYZ coordinates.
 /// </summary>
 /// <param name="pos">The XYZ coordinates.</param>
 public Eci(Vector pos)
     : this(pos, new Vector())
 {
 }
Exemple #16
0
 /// <summary>
 /// Creates an instance of the class with the given position, velocity, and time.
 /// </summary>
 /// <param name="pos">The position vector.</param>
 /// <param name="vel">The velocity vector.</param>
 /// <param name="date">The time associated with the position.</param>
 public EciTime(Vector pos, Vector vel, Julian date)
     : base(pos, vel)
 {
     Date = date;
 }
Exemple #17
0
 /// <summary>
 /// Creates a new vector from an existing vector.
 /// </summary>
 /// <param name="v">The existing vector to copy.</param>
 public Vector(Vector v)
     : this(v.X, v.Y, v.Z, v.W)
 {
 }
Exemple #18
0
 /// <summary>
 /// Subtracts a vector from this vector.
 /// </summary>
 /// <param name="vec">The vector to subtract.</param>
 public void Sub(Vector vec)
 {
     X -= vec.X;
      Y -= vec.Y;
      Z -= vec.Z;
      W -= vec.W;
 }
		// /////////////////////////////////////////////////////////////////////
		// Return the dot product
		public double Dot(Vector vec)
		{
			return (m_x * vec.m_x) + (m_y * vec.m_y) + (m_z * vec.m_z);
		}
Exemple #20
0
 /// <summary>
 /// Calculates the distance between two vectors as points in XYZ space.
 /// </summary>
 /// <param name="vec">The second vector.</param>
 /// <returns>The calculated distance.</returns>
 public double Distance(Vector vec)
 {
     return Math.Sqrt(Math.Pow(X - vec.X, 2.0) +
                   Math.Pow(Y - vec.Y, 2.0) +
                   Math.Pow(Z - vec.Z, 2.0));
 }