Skip to content

Instantly share code, notes, and snippets.

@wiseman
Last active April 4, 2023 14:36
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save wiseman/4782b9eb77566fbdeb9db1725e6c547e to your computer and use it in GitHub Desktop.
Save wiseman/4782b9eb77566fbdeb9db1725e6c547e to your computer and use it in GitHub Desktop.
Print the 10 closest spacecraft/satellites.
import datetime
import requests
import math
import ephem
import os
import sys
def get_tles():
if os.path.exists("active.txt") and (datetime.datetime.utcnow() - datetime.datetime.utcfromtimestamp(os.path.getmtime("active.txt"))).total_seconds() < 3600:
with open("active.txt", "r") as f:
tles = f.read().split("\n")[:-1]
else:
sys.stderr.write("Downloading TLE data from Celestrak...\n")
url = "https://www.celestrak.com/NORAD/elements/active.txt" # URL for the TLE data source
response = requests.get(url)
tles = response.text.split("\n")[:-1] # Split the response text by newline characters and remove the last empty element
with open("active.txt", "w") as f:
f.write(response.text)
return tles
# Latitude and longitude of Los Angeles.
my_lat = 34.0522
my_lon = -118.2437
observer = ephem.Observer()
observer.lat = str(my_lat)
observer.lon = str(my_lon)
observer.elevation = 0
observer.date = datetime.datetime.utcnow()
def haversine(lat1, lon1, lat2, lon2):
R = 3958.8 # Earth's radius in miles
dlat = math.radians(lat2 - lat1)
dlon = math.radians(lon2 - lon1)
a = math.sin(dlat / 2)**2 + math.cos(math.radians(lat1)) \
* math.cos(math.radians(lat2)) * math.sin(dlon / 2)**2
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
distance = R * c
return distance
tles = get_tles()
# Print out how many objects are being tracked.
sys.stderr.write(f"Tracking {len(tles) // 3} objects.\n")
objs = []
for i in range(0, len(tles), 3):
line1 = tles[i]
line2 = tles[i+1]
line3 = tles[i+2]
name = line1.strip()
sat = ephem.readtle(name, line2, line3)
sat.compute(observer)
objs.append(sat)
# Print the current date and time, in local time and then in UTC.
print(f"{observer.date.datetime().strftime('%Y-%m-%d %H:%M:%S')} Local")
print(f"{observer.date.datetime().astimezone(datetime.timezone.utc).strftime('%Y-%m-%d %H:%M:%S')} UTC")
# Print a nicely formatted table of the 10 closest objects.
# Print the name, altitude, range, and velocity.
# Print headers.
print(f"{'Name':<30} {'Altitude (mi)':>14} {'Range (mi)':>10} {'Radial Velocity (mph)':>21}")
# Print dashes, to separate the headers from the data.
print(f"{'-' * 30} {'-' * 14} {'-' * 10} {'-' * 21}")
for obj in sorted(objs, key=lambda x: x.range)[0:10]:
range_miles = obj.range * 0.000621371
# range_velocity is in meters.
velocity_mph = obj.range_velocity * 2.23694
elevation_miles = obj.elevation * 3.28084 / 5280
print(f"{obj.name:<30} {elevation_miles:>14.0f} {range_miles:>10.1f} {velocity_mph:>21.1f}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment