public static void calculateSatellitePosition(string catalogID, Site site) { // update TLE values if (dataObject.getLatestN(satelliteList, numTLEs)) { writeConfigSatelliteFile(); } Satellite theSat; dataObject.satelliteList.TryGetValue(catalogID, out theSat); TLE tle = new TLE(theSat.TLEs[0].name, theSat.TLEs[0].line1, theSat.TLEs[0].line2); // Create an orbit object using the TLE object. Orbit orbit = new Orbit(tle); // Get the location of the satellite from the Orbit object. The // earth-centered inertial information is placed into eciSDP4. // Here we ask for the location of the satellite 90 minutes after // the TLE epoch. //EciTime eciSDP4 = orbitSDP4.GetPosition(90.0); // get the position, as of NOW!!! EciTime eciSDP4 = orbit.GetPosition((DateTime.UtcNow - orbit.EpochTime).TotalMinutes); Console.Write("\n TSINCE X Y Z\n"); Console.Write("{0,12} {1,19:f8} {2,19:f8} {3,19:f8}\n", DateTime.UtcNow.ToString(), eciSDP4.Position.X, eciSDP4.Position.Y, eciSDP4.Position.Z); Console.Write("\n XVEL YVEL ZVEL\n"); Console.Write("{0,38:f8} {1,20:f8} {2,20:f8}\n", eciSDP4.Velocity.X, eciSDP4.Velocity.Y, eciSDP4.Velocity.Z); // Now get the "look angle" from the site to the satellite. // Note that the ECI object "eciSDP4" has a time associated // with the coordinates it contains; this is the time at which // the look angle is valid. Topo topoLook = site.GetLookAngle(eciSDP4); // Print out the results. Note that the Azimuth and Elevation are // stored in the CoordTopo object as radians. Here we convert // to degrees using Rad2Deg() Console.Write("\n{0,15} - AZ: {1:f3} EL: {2:f3}\n", tle.Name, topoLook.AzimuthDeg, topoLook.ElevationDeg); Console.WriteLine("-------------------------------------------------------------------------"); }
// ////////////////////////////////////////////////////////////////////////// // // Routine to output position and velocity information of satellite // in orbit described by TLE information. // static void PrintPosVel(TLE tle) { const int Step = 360; Orbit orbit = new Orbit(tle); List<Eci> coords = new List<Eci>(); // Calculate position, velocity // mpe = "minutes past epoch" for (int mpe = 0; mpe <= (Step * 4); mpe += Step) { // Get the position of the satellite at time "mpe". // The coordinates are placed into the variable "eci". Eci eci = orbit.GetPosition(mpe); // Add the coordinate object to the list coords.Add(eci); } // Print TLE data Console.Write("{0}\n", tle.Name); Console.Write("{0}\n", tle.Line1); Console.Write("{0}\n", tle.Line2); // Header Console.Write("\n TSINCE X Y Z\n\n"); // Iterate over each of the ECI position objects pushed onto the // coordinate list, above, printing the ECI position information // as we go. for (int i = 0; i < coords.Count; i++) { Eci e = coords[i] as Eci; Console.Write("{0,8}.00 {1,16:f8} {2,16:f8} {3,16:f8}\n", i * Step, e.Position.X, e.Position.Y, e.Position.Z); } Console.Write("\n XVEL YVEL ZVEL\n\n"); // Iterate over each of the ECI position objects in the coordinate // list again, but this time print the velocity information. for (int i = 0; i < coords.Count; i++) { Eci e = coords[i] as Eci; Console.Write("{0,24:f8} {1,16:f8} {2,16:f8}\n", e.Velocity.X, e.Velocity.Y, e.Velocity.Z); } }
// /////////////////////////////////////////////////////////////////// protected double GetRad(TLE.Field fld) { return Tle.GetField(fld, TLE.Unit.Radians); }
// /////////////////////////////////////////////////////////////////// protected double GetDeg(TLE.Field fld) { return Tle.GetField(fld, TLE.Unit.Degrees); }
// ////////////////////////////////////////////////////////////////////////// public TLE(TLE tle) : this(tle.Name, tle.Line1, tle.Line2) { }
/// <summary> /// Standard constructor. /// </summary> /// <param name="tle">Two-line element orbital parameters.</param> public Orbit(TLE tle) { Tle = tle; Epoch = Tle.EpochJulian; m_Inclination = GetRad(TLE.Field.Inclination); m_Eccentricity = Tle.GetField(TLE.Field.Eccentricity); m_RAAN = GetRad(TLE.Field.Raan); m_ArgPerigee = GetRad(TLE.Field.ArgPerigee); m_BStar = Tle.GetField(TLE.Field.BStarDrag); m_Drag = Tle.GetField(TLE.Field.MeanMotionDt); m_MeanAnomaly = GetRad(TLE.Field.MeanAnomaly); m_TleMeanMotion = Tle.GetField(TLE.Field.MeanMotion); // Recover the original mean motion and semimajor axis from the // input elements. double mm = TleMeanMotion; double rpmin = mm * Globals.TwoPi / Globals.MinPerDay; // rads per minute double a1 = Math.Pow(Globals.Xke / rpmin, 2.0 / 3.0); double e = Eccentricity; double i = Inclination; double temp = (1.5 * Globals.Ck2 * (3.0 * Globals.Sqr(Math.Cos(i)) - 1.0) / Math.Pow(1.0 - e * e, 1.5)); double delta1 = temp / (a1 * a1); double a0 = a1 * (1.0 - delta1 * ((1.0 / 3.0) + delta1 * (1.0 + 134.0 / 81.0 * delta1))); double delta0 = temp / (a0 * a0); m_rmMeanMotionRec = rpmin / (1.0 + delta0); m_aeAxisSemiMajorRec = a0 / (1.0 - delta0); m_aeAxisSemiMinorRec = m_aeAxisSemiMajorRec * Math.Sqrt(1.0 - (e * e)); m_kmPerigeeRec = Globals.Xkmper * (m_aeAxisSemiMajorRec * (1.0 - e) - Globals.Ae); m_kmApogeeRec = Globals.Xkmper * (m_aeAxisSemiMajorRec * (1.0 + e) - Globals.Ae); if (Period.TotalMinutes >= 225.0) { // SDP4 - period >= 225 minutes. NoradModel = new NoradSDP4(this); } else { // SGP4 - period < 225 minutes NoradModel = new NoradSGP4(this); } }