a software update knocked the ground station's automated pass prediction system offline just before a scheduled communications window.
the operations team still has the satellite's latest TLEs and the station's coordinates, but they need you to manually determine when the satellite will be above the horizon and visible from the ground station. calculate the visibility windows so contact can be re-established before the next scheduled transmission is missed.
read the doc for skyfield and install it.
challenge must be solved dynamically and in one persistent session.
Challenge Sat 1
TLE:
DIGITWIN HTB
1 01337U 00000A 26277.58845255+.00000000 00000-0 18941-3 0 189 7
2 01337 97.3224 170.3767 0047165 301.1887 95.3084 15.43215537179265
Station location:
(Lat,Long): 46.57527473265949,-48.605998524385605
When will it be visible next?>
#!/usr/bin/python3.11
import socket, re, time
from datetime import timedelta
from skyfield.api import load, EarthSatellite, wgs84
HOST = "154.57.164.72"
PORT = 32211
def calculate(sat, lat, lon):
station = wgs84.latlon(lat,lon)
#print(station)
t0 = ts.now()
t1 = ts.from_datetime(t0.utc_datetime() + timedelta(hours=24))
t, events = sat.find_events(station, t0, t1, altitude_degrees=30.0)
out, i = [], 0
while i < len(events) - 2:
if events[i] == 0 and events[i+1] == 1 and events[i+2] == 2:
out.append(t[i].utc_strftime("%Y-%m-%dT%H:%M:%SZ"))
out.append(t[i+2].utc_strftime("%Y-%m-%dT%H:%M:%SZ"))
i += 1
return " ".join(out)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
while True:
buffer = ""
while "visible next?" not in buffer:
time.sleep(1)
data = s.recv(4096)
if not data:
break
buffer += data.decode(errors="replace")
print(buffer)
if "visible next?" not in buffer:
break
lines = buffer.splitlines()
found = False
i = 0
while i < len(lines) - 2:
ts = load.timescale()
line1, line2 = lines[i], lines[i + 1]
line3 = lines[i + 2]
if line1.startswith("1 ") and line2.startswith("2 "):
sat = EarthSatellite(line1, line2, 'DIGITWIN HTB', ts)
pos = re.search(r"\(Lat,Long\):\s*(-?\d+\.?\d*)\s*,\s*(-?\d+\.?\d*)", buffer)
#print(sat)
#print(pos)
answer = calculate(sat, float(pos.group(1)), float(pos.group(2)))
#print(answer)
s.sendall((answer + "\n").encode())
#print(s.recv(4096).decode(errors="replace"))
found = True
break
i += 2
else:
i += 1
if not found:
break