Cysgp4 quick tour#
Using cysgp4 is possible via an object-oriented interface or with a
fast numpy
-array functional approach. The former works like this:
>>> import cysgp4
>>> # Define a date/time and an observer
>>> pydt = cysgp4.PyDateTime.from_mjd(58805.57)
>>> lon_deg, lat_deg = 6.88375, 50.525
>>> alt_km = 0.366
>>> obs = cysgp4.PyObserver(lon_deg, lat_deg, alt_km)
>>> # Define satellite properties/orbit via two-line element string (TLE)
>>> hst_tle = cysgp4.PyTle(
... 'HST',
... '1 20580U 90037B 19321.38711875 .00000471 00000-0 17700-4 0 9991',
... '2 20580 28.4699 288.8102 0002495 321.7771 171.5855 15.09299865423838',
... )
>>> # Create a satellite object for querying coordinates
>>> sat = cysgp4.Satellite(hst_tle, obs, pydt)
>>> sat.eci_pos().loc # ECI cartesian position, km
(5879.5931344459295, 1545.7455647032068, 3287.4155452595)
>>> sat.eci_pos().vel # ECI cartesian velocity, km/s
(-1.8205895517672226, 7.374044252723081, -0.20697960810978586)
>>> sat.geo_pos() # geographic (geodetic) position, lon/lat/alt
<PyCoordGeodetic: 112.2146d, 28.5509d, 538.0173km>
>>> sat.topo_pos() # topocentric position, az/el/dist/dist_rate
<PyCoordTopocentric: 60.2453d, -35.6845d, 8314.5681km, 3.5087km/s>
>>> # One can change time to determine positions at another moment
>>> sat.mjd += 1 / 720. # one minute later
>>> sat.topo_pos()
<PyCoordTopocentric: 54.8446d, -38.2749d, 8734.9196km, 3.4885km/s>
In many cases, however, one probably wants to calculate coordinates for a
(large) number of satellites, observer locations, and/or observing times. For
this, the function propagate_many
is useful. This is an array
interface to the sgp4 calculations, which allows to perform calculations for
different satellite TLEs, observers and times in a parallelized manner.
numpy
broadcasting rules apply:
>>> import numpy as np
>>> from cysgp4 import PyTle, PyObserver
>>> from cysgp4 import get_example_tles, propagate_many
>>> # Download many TLEs from a website
>>> # import requests
>>> # url = 'http://celestrak.com/NORAD/elements/science.txt'
>>> # ctrak_science = requests.get(url).text
>>> # or use built-in example TLE text file
>>> ctrak_science = get_example_tles()
>>> # Need to convert them to a list of tuples (each tuple consisting
>>> # of the three TLE strings)
>>> tle_list = cysgp4.tle_tuples_from_text(ctrak_science)
>>> # Create an array of PyTle and PyObserver objects, and MJDs
>>> tles = np.array([
... PyTle(*tle) for tle in tle_list
... ])[np.newaxis, np.newaxis, :20] # use first 20 TLEs
>>> observers = np.array([
... PyObserver(6.88375, 50.525, 0.366),
... PyObserver(16.88375, 50.525, 0.366),
... ])[np.newaxis, :, np.newaxis]
>>> mjds = np.linspace(
... 58805.5, 58806.5, 1000 # 1000 time steps
... )[:, np.newaxis, np.newaxis]
>>> # The result is a dictionary
>>> result = propagate_many(mjds, tles, observers)
>>> print(sorted(result.keys()))
['eci_pos', 'eci_vel', 'geo', 'topo']
>>> # Returned array shapes are as follows; last array dimension
>>> # contains the coordinate pairs.
>>> print(np.broadcast(mjds, tles, observers).shape)
(1000, 2, 20)
>>> print(result['eci_pos'].shape, result['topo'].shape)
(1000, 2, 20, 3) (1000, 2, 20, 4)
>>> # One can also skip over coordinate frames.
>>> result = propagate_many(
... mjds, tles, observers,
... do_eci_pos=False, do_eci_vel=False, do_geo=False, do_topo=True
... )
>>> print(result.keys())
dict_keys(['topo'])
Note
This “minimal example” is also contained in a fully-working Jupyter tutorial notebook.