Last active
November 22, 2021 16:45
-
-
Save cbassa/9055ef79a717bfca7c566459115874b8 to your computer and use it in GitHub Desktop.
Generate a TLE for an object above the horizon for a given observer and a given time
This file contains 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 ephem | |
import datetime | |
import math | |
# Compute checksum | |
def set_checksum(line): | |
s = 0 | |
for c in line[:-1]: | |
if c.isdigit(): | |
s += int(c) | |
if c == "-": | |
s += 1 | |
return line[:-1]+"%d"%(s%10) | |
def datetime_to_epoch(t): | |
epochyr = t.timetuple().tm_year - 2000 | |
fday = t.hour / 24 + t.minute / 1440 + t.second / 86400 | |
epochdoy = t.timetuple().tm_yday + fday | |
return epochyr, epochdoy | |
def generate_fake_tle(t, observer): | |
# Set epoch 10 minutes later | |
tepoch = t + datetime.timedelta(minutes=10) | |
observer.date = ephem.date(tepoch) | |
# Compute epoch | |
epochyr, epochdoy = datetime_to_epoch(tepoch) | |
# RA of ascending node | |
raan = (observer.sidereal_time() * 180 / math.pi) % 360 | |
# Mean anomaly | |
m = (observer.lat * 180 / math.pi) % 360 | |
# Format TLE strings | |
line0 = "Test satellite" | |
line1 = set_checksum(f"1 70000U 20600A {epochyr:02d}{epochdoy:012.8f} " \ | |
f".00000000 00000-0 50000-4 0 0000") | |
line2 = set_checksum(f"2 70000 90.0000 {raan:8.4f} 0001000 000.0000 " \ | |
f"{m:8.4f} 15.50000000 0") | |
return line0, line1, line2 | |
def generate_fake_tle_at_rise(t, observer): | |
# Intial guess | |
dt = datetime.timedelta(seconds=600) | |
# Interate for 5 steps | |
for i in range(5): | |
# Set epoch | |
tepoch = t + dt | |
observer.date = ephem.date(tepoch) | |
# Compute epoch | |
epochyr, epochdoy = datetime_to_epoch(tepoch) | |
# RA of ascending node | |
raan = (observer.sidereal_time() * 180 / math.pi) % 360 | |
# Mean anomaly | |
m = (observer.lat * 180 / math.pi) % 360 | |
# Format TLE strings | |
line0 = "Test satellite" | |
line1 = set_checksum(f"1 70000U 20600A {epochyr:02d}{epochdoy:012.8f} " \ | |
f".00000000 00000-0 50000-4 0 0000") | |
line2 = set_checksum(f"2 70000 90.0000 {raan:8.4f} 0001000 000.0000 " \ | |
f"{m:8.4f} 15.50000000 0") | |
# Compute next pass | |
observer.date = ephem.date(t) | |
sat = ephem.readtle(line0, line1, line2) | |
sat.compute(observer) | |
tr, azr, tt, altt, ts, azs = observer.next_pass(sat) | |
# Time offset | |
dt -= tr.datetime() - t - datetime.timedelta(seconds=1) | |
return line0, line1, line2 | |
if __name__ == "__main__": | |
# Set observer | |
observer = ephem.Observer() | |
observer.lon = "10.00" | |
observer.lat = "45.00" | |
observer.elevation = 0.0 | |
# Set time | |
t = datetime.datetime(2020, 5, 19, 6, 55, 0, 0) | |
# Generate TLE | |
line0, line1, line2 = generate_fake_tle_at_rise(t, observer) | |
# Set date | |
observer.date = ephem.date(t) | |
# Define satellite | |
sat = ephem.readtle(line0, line1, line2) | |
sat.compute(observer) | |
# Compute next pass | |
tr, azr, tt, altt, ts, azs = observer.next_pass(sat) | |
print(f"Rise at: {tr}, azimuth: {azr}") | |
print(f"Transit at: {tt}, altitude: {altt}") | |
print(f"Set at : {ts}, azimuth: {azs}") | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment