Created
November 16, 2021 20:42
-
-
Save cbassa/93460fcd406b98d6fd53126a642135f2 to your computer and use it in GitHub Desktop.
Plot TLE parameters to find swapped objects
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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