.. pycraf-satellite: ************************************** Satellites (`pycraf.satellite`) ************************************** .. currentmodule:: pycraf.satellite Introduction ============ Often the compatibility of space-based radio communications with other services has to be studied. Then, it may happen, that one has to determine the position of one or more satellites with respect to an observer on Earth's surface. The `~pycraf.satellite` sub-package uses the `sgp4 package `_ to calculate Geocentric cartesian inertial (ECI) position for a given time and adds the transformations to the ( local) horizontal coordinates (azimuth, elevation, distance) of an observer. Using `pycraf.satellite` ========================= The first step to calculate a satellite's position is to obtain a so-called `Two-line element set (TLE) `_. .. note:: The TLEs are usually published once a day, because the contained parameters quickly change; drag forces cause rapid changes in the orbits of almost all satellites. On most websites that offer TLEs (e.g., `Celestrak `_) in fact three-line strings are used, where the first line just contains the name of the satellite: .. code-block:: none ISS (ZARYA) 1 25544U 98067A 13165.59097222 .00004759 00000-0 88814-4 0 47 2 25544 51.6478 121.2152 0011003 68.5125 263.9959 15.50783143834295 The pycraf package follows this format. To calculate the horizontal coordinates of the ISS at a given time, download the current TLE and do:: >>> import datetime >>> import numpy as np >>> from astropy.coordinates import EarthLocation >>> from astropy import time >>> from pycraf import satellite >>> tle_string = '''ISS (ZARYA) ... 1 25544U 98067A 13165.59097222 .00004759 00000-0 88814-4 0 47 ... 2 25544 51.6478 121.2152 0011003 68.5125 263.9959 15.50783143834295''' >>> # define observer location >>> location = EarthLocation(6.88375, 50.525, 366.) >>> # create a SatelliteObserver instance >>> sat_obs = satellite.SatelliteObserver(location) >>> dt = datetime.datetime(2010, 7, 22, 8, 38, 57) >>> obstime = time.Time(dt) >>> az, el, dist = sat_obs.azel_from_sat(tle_string, obstime) # doctest: +REMOTE_DATA >>> print('az, el, dist: {:.1f}, {:.1f}, {:.0f}'.format(az, el, dist)) # doctest: +REMOTE_DATA az, el, dist: -165.5 deg, 7.4 deg, 1713 km >>> # can also use arrays of obstime >>> mjd = 55123. + np.array([0.123, 0.99, 50.3]) >>> obstime2 = time.Time(mjd, format='mjd') >>> az, el, dist = sat_obs.azel_from_sat(tle_string, obstime2) # doctest: +REMOTE_DATA >>> np.set_printoptions(precision=3) >>> az # doctest: +SKIP >>> el # doctest: +SKIP >>> dist # doctest: +SKIP The `~pycraf.satellite.SatelliteObserver.azel_from_sat` method also accepts a `sgp4.io.Satellite` object. This could be created by using the `sgp4 package `_ directly. pycraf also offers a convenience routine, `~pycraf.satellite.get_sat`, which does the TLE parsing for your and returns the satellite name and `Satellite` object. It also uses caching to save some computing time, if many different satellites are to be processed:: >>> from pycraf import satellite >>> tle_string = '''ISS (ZARYA) ... 1 25544U 98067A 13165.59097222 .00004759 00000-0 88814-4 0 47 ... 2 25544 51.6478 121.2152 0011003 68.5125 263.9959 15.50783143834295''' >>> satname, sat = satellite.get_sat(tle_string) >>> satname 'ISS (ZARYA)' >>> sat.satnum 25544 # using sgp4 directly, to get position and velocity in ECI coordinates >>> from sgp4.api import jday >>> jd, fr = jday(2017, 6, 29, 12, 50, 19) >>> err_code, position, velocity = sat.sgp4(jd, fr) >>> position # km # doctest: +FLOAT_CMP (3289.302521216188, 3816.880925531413, 4443.175627001508) >>> velocity # km/s # doctest: +FLOAT_CMP (-2.958995807371371, 6.335950621185331, -3.241778555003016) See Also ======== - `Astropy Units and Quantities package `_, which is used extensively in pycraf. - `sgp4 package `_ - `Two-line element set (TLE) `_ - `Celestrak `_ Reference/API ============= .. automodapi:: pycraf.satellite :no-inheritance-diagram: