Skip to content

Instantly share code, notes, and snippets.

@cbassa
Created November 16, 2021 20:42
Show Gist options
  • Save cbassa/93460fcd406b98d6fd53126a642135f2 to your computer and use it in GitHub Desktop.
Save cbassa/93460fcd406b98d6fd53126a642135f2 to your computer and use it in GitHub Desktop.
Plot TLE parameters to find swapped objects
#!/usr/bin/env python3
import os
import json
from spacetrack import SpaceTrackClient
from sgp4.earth_gravity import wgs84
from sgp4.io import twoline2rv
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from astropy.time import Time
class twolineelement:
"""TLE class"""
def __init__(self, tle0, tle1, tle2):
"""Define a TLE"""
self.tle0 = tle0
self.tle1 = tle1
self.tle2 = tle2
if tle0[:2] == "0 ":
self.name = tle0[2:].rstrip()
else:
self.name = tle0.rstrip()
if tle1.split(" ")[1] == "":
self.id = int(tle1.split(" ")[2][:4])
else:
self.id = int(tle1.split(" ")[1][:5])
self.desig = tle1.split(" ")[2]
def download_tles_from_spacetrack(settings, intldes_query, fname):
# Login
st = SpaceTrackClient(settings["username"], settings["password"])
# Find objects
satcat = st.satcat(intldes=intldes_query)
print(satcat)
# Get NORAD IDs
norad_cat_ids = sorted([int(s["NORAD_CAT_ID"]) for s in satcat])
# Download TLEs
with open(fname, "w") as fp:
for norad_cat_id in norad_cat_ids:
lines = st.tle(iter_lines=True, norad_cat_id=norad_cat_id, orderby="epoch desc", format="3le")
for line in lines:
fp.write("%s\n" % line)
return
def read_tles(fname):
with open(fname, "r") as fp:
lines = fp.readlines()
tles = []
for i in range(0, len(lines), 3):
tles.append(twolineelement(lines[i], lines[i+1], lines[i+2]))
return tles
if __name__ == "__main__":
# Query
intldes_query = ["2016-066E", "2016-066G"]
# Set login
# Of the form
# {"username": "usrname", "password": "password"}
with open("login.json", "r") as fp:
settings = json.load(fp)
# Download TLEs if absent
if not os.path.exists("database.txt"):
download_tles_from_spacetrack(settings, intldes_query, "database.txt")
# Load TLEs
tles = read_tles("database.txt")
# Read TLEs
sats = []
for tle in tles:
sats.append(twoline2rv(tle.tle1, tle.tle2, wgs84))
# Extract parameters
norad_cat_ids = [sat.satnum for sat in sats]
r = np.array([sat.a for sat in sats]) * wgs84.radiusearthkm
a = np.array([sat.a-1 for sat in sats]) * wgs84.radiusearthkm
mm = np.array([sat.no_kozai for sat in sats]) * 1440 / (2 * np.pi)
raan = np.array([sat.nodeo for sat in sats])*180.0/np.pi
raandot = np.array([sat.nodedot for sat in sats])
incl = np.array([sat.inclo for sat in sats])*180.0/np.pi
argp = np.array([sat.argpo for sat in sats])*180.0/np.pi
ma = np.array([sat.mo for sat in sats])*180.0/np.pi
ecc = np.array([sat.ecco for sat in sats])
q = (1.0 - ecc) * r - wgs84.radiusearthkm
Q = (1.0 + ecc) * r - wgs84.radiusearthkm
t = Time([sat.epoch for sat in sats])
names = np.array([tle.name for tle in tles])
desigs = np.array([tle.desig for tle in tles])
fig, (ax1, ax2, ax3, ax4) = plt.subplots(4, 1, sharex=True, figsize=(10, 8))
for norad_cat_id in np.unique(norad_cat_ids):
c = norad_cat_ids==norad_cat_id
name, desig = names[c][0], desigs[c][0]
ax1.plot_date(t[c].datetime, q[c], fmt="-", label="[%d/%s] %s" % (norad_cat_id, desig, name), alpha=0.9)
ax1.grid()
ax1.set_ylabel("Altitude of perigee (km)")
for norad_cat_id in np.unique(norad_cat_ids):
c = norad_cat_ids==norad_cat_id
name, desig = names[c][0], desigs[c][0]
ax2.plot_date(t[c].datetime, Q[c], fmt="-", label="[%d/%s] %s" % (norad_cat_id, desig, name), alpha=0.9)
ax2.grid()
ax2.set_ylabel("Altitude of apogee (km)")
for norad_cat_id in np.unique(norad_cat_ids):
c = norad_cat_ids==norad_cat_id
name, desig = names[c][0], desigs[c][0]
ax3.plot_date(t[c].datetime, raan[c], fmt="-", label="[%d/%s] %s" % (norad_cat_id, desig, name), alpha=0.9)
ax3.grid()
ax3.set_ylabel("RA of ascending node")
for norad_cat_id in np.unique(norad_cat_ids):
c = norad_cat_ids==norad_cat_id
name, desig = names[c][0], desigs[c][0]
ax4.plot_date(t[c].datetime, incl[c], fmt="-", label="[%d/%s] %s" % (norad_cat_id, desig, name), alpha=0.9)
ax4.grid()
ax4.set_xlabel("Date (UTC)")
ax4.set_ylabel("Inclination (deg)")
ax4.legend(loc="upper left")
plt.tight_layout()
plt.savefig("tle_swap.png")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment