Skip to content

Commit 4040b13

Browse files
authored
PyFix6
1 parent 8707fae commit 4040b13

File tree

1 file changed

+37
-73
lines changed

1 file changed

+37
-73
lines changed

usr/local/bin/iss-tracker.py

Lines changed: 37 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import tkinter as tk
44
from tkinter import Canvas
55
import requests
6-
from sgp4.api import Satrec, jday
6+
from skyfield.api import load, EarthSatellite
77
from datetime import datetime, timedelta
88
import math
99
import cartopy.crs as ccrs
@@ -16,16 +16,19 @@ class ISSTrackerApp:
1616
def __init__(self, root):
1717
self.root = root
1818
self.root.title("ISS Tracker")
19-
self.canvas = Canvas(root, width=800, height=400, bg="black")
20-
self.canvas.pack()
19+
self.width = 800
20+
self.height = 400
2121

22-
self.image = self.generate_map().resize((800, 400))
23-
self.tk_image = ImageTk.PhotoImage(self.image)
24-
self.canvas.create_image(0, 0, anchor="nw", image=self.tk_image)
22+
self.canvas = Canvas(root, width=self.width, height=self.height, bg="black")
23+
self.canvas.pack(fill="both", expand=True)
2524

26-
self.time_offset = timedelta(seconds=0)
25+
self.original_map = self.generate_map()
26+
self.tk_image = None
27+
28+
self.ts = load.timescale()
2729
self.satellite = None
2830
self.last_tle_update = None
31+
self.time_offset = timedelta(seconds=0)
2932

3033
self.load_tle()
3134
self.schedule_tle_refresh()
@@ -34,6 +37,7 @@ def __init__(self, root):
3437
self.root.bind("<Right>", self.go_forward)
3538
self.root.bind("<space>", self.reset_time)
3639

40+
self.root.bind("<Configure>", self.resize)
3741
self.update_display()
3842

3943
def generate_map(self):
@@ -57,15 +61,14 @@ def load_tle(self):
5761
if "ISS (ZARYA)" in line:
5862
tle1 = lines[i+1].strip()
5963
tle2 = lines[i+2].strip()
60-
self.satellite = Satrec.twoline2rv(tle1, tle2)
64+
self.satellite = EarthSatellite(tle1, tle2, 'ISS (ZARYA)', self.ts)
6165
self.last_tle_update = datetime.utcnow()
6266
print("TLE updated:", self.last_tle_update)
6367
return
6468
except Exception as e:
6569
print("Error updating TLE:", e)
6670

6771
def schedule_tle_refresh(self):
68-
# Refresh TLE every 10 minutes
6972
def tle_updater():
7073
while True:
7174
now = datetime.utcnow()
@@ -74,35 +77,38 @@ def tle_updater():
7477
threading.Event().wait(60)
7578
threading.Thread(target=tle_updater, daemon=True).start()
7679

80+
def resize(self, event):
81+
self.width = event.width
82+
self.height = event.height
83+
self.update_display()
84+
7785
def update_display(self):
7886
self.canvas.delete("all")
87+
88+
# Resize map image
89+
resized_image = self.original_map.resize((self.width, self.height))
90+
self.tk_image = ImageTk.PhotoImage(resized_image)
7991
self.canvas.create_image(0, 0, anchor="nw", image=self.tk_image)
8092

8193
now = datetime.utcnow() + self.time_offset
82-
jd, fr = jday(now.year, now.month, now.day, now.hour, now.minute, now.second + now.microsecond/1e6)
83-
e, pos, vel = self.satellite.sgp4(jd, fr)
84-
lat, lon = self.eci_to_latlon(pos, jd)
85-
iss_x, iss_y = self.latlon_to_xy(lat, lon, 800, 400)
94+
t_now = self.ts.utc(now)
95+
96+
geocentric = self.satellite.at(t_now)
97+
subpoint = geocentric.subpoint()
98+
lat, lon = subpoint.latitude.degrees, subpoint.longitude.degrees
99+
iss_x, iss_y = self.latlon_to_xy(lat, lon, self.width, self.height)
86100

87-
# Draw ISS current position
88101
self.canvas.create_oval(iss_x-4, iss_y-4, iss_x+4, iss_y+4, fill="purple", tags="iss")
89102

90-
# Draw current orbit path
103+
# Draw upcoming path (next orbit)
91104
path_coords = []
92-
prev_lon = None
93-
for mins in range(-10, 90, 2):
105+
for mins in range(-10, 90, 1):
94106
future_time = now + timedelta(minutes=mins)
95-
jd_fut, fr_fut = jday(future_time.year, future_time.month, future_time.day,
96-
future_time.hour, future_time.minute,
97-
future_time.second + future_time.microsecond/1e6)
98-
e_fut, pos_fut, vel_fut = self.satellite.sgp4(jd_fut, fr_fut)
99-
lat_fut, lon_fut = self.eci_to_latlon(pos_fut, jd_fut)
100-
101-
if prev_lon is not None:
102-
lon_fut = self.smooth_longitude(prev_lon, lon_fut)
103-
prev_lon = lon_fut
104-
105-
x, y = self.latlon_to_xy(lat_fut, lon_fut, 800, 400)
107+
t_future = self.ts.utc(future_time)
108+
geocentric_future = self.satellite.at(t_future)
109+
subpoint_future = geocentric_future.subpoint()
110+
lat_fut, lon_fut = subpoint_future.latitude.degrees, subpoint_future.longitude.degrees
111+
x, y = self.latlon_to_xy(lat_fut, lon_fut, self.width, self.height)
106112
path_coords.append((x, y))
107113

108114
for i in range(len(path_coords)-1):
@@ -111,51 +117,9 @@ def update_display(self):
111117
fill="blue", width=2)
112118

113119
# Draw current UTC time
114-
self.canvas.create_text(400, 20, text=now.strftime("%Y-%m-%d %H:%M:%S UTC"),
120+
self.canvas.create_text(self.width//2, 20, text=now.strftime("%Y-%m-%d %H:%M:%S UTC"),
115121
font=("Arial", 16, "bold"), fill="white")
116122

117-
self.root.after(1000, self.update_display)
118-
119-
def eci_to_latlon(self, pos, jd):
120-
T = (jd - 2451545.0) / 36525.0
121-
GMST = 280.46061837 + 360.98564736629 * (jd - 2451545.0) + 0.000387933 * T**2 - T**3 / 38710000.0
122-
GMST = GMST % 360.0
123-
theta = math.radians(GMST)
124-
125-
x = pos[0]*math.cos(theta) + pos[1]*math.sin(theta)
126-
y = -pos[0]*math.sin(theta) + pos[1]*math.cos(theta)
127-
z = pos[2]
128-
129-
r = math.sqrt(x**2 + y**2 + z**2)
130-
lat = math.degrees(math.asin(z / r))
131-
lon = math.degrees(math.atan2(y, x))
132-
if lon > 180:
133-
lon -= 360
134-
return lat, lon
135-
136-
def latlon_to_xy(self, lat, lon, width, height):
137-
x = (lon + 180) * (width / 360)
138-
y = (90 - lat) * (height / 180)
139-
return x, y
140-
141-
def smooth_longitude(self, prev_lon, curr_lon):
142-
delta = curr_lon - prev_lon
143-
if delta > 180:
144-
curr_lon -= 360
145-
elif delta < -180:
146-
curr_lon += 360
147-
return curr_lon
148-
149-
def go_forward(self, event):
150-
self.time_offset += timedelta(minutes=2)
151-
152-
def go_back(self, event):
153-
self.time_offset -= timedelta(minutes=2)
154-
155-
def reset_time(self, event):
156-
self.time_offset = timedelta(seconds=0)
123+
self.root.after(100, self.update_display)
157124

158-
if __name__ == "__main__":
159-
root = tk.Tk()
160-
app = ISSTrackerApp(root)
161-
root.mainloop()
125+
de

0 commit comments

Comments
 (0)