Skip to content

Commit ed993b2

Browse files
authored
Py Fix3
1 parent 7c0e615 commit ed993b2

File tree

1 file changed

+54
-43
lines changed

1 file changed

+54
-43
lines changed

usr/local/bin/iss-tracker.py

Lines changed: 54 additions & 43 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, WGS72, jday
6+
from sgp4.api import Satrec, jday
77
from datetime import datetime, timedelta
88
import math
99
import cartopy.crs as ccrs
@@ -23,14 +23,6 @@ def generate_map():
2323
plt.close(fig)
2424
return Image.open(buf)
2525

26-
def get_pi_location():
27-
try:
28-
response = requests.get("http://ip-api.com/json/")
29-
data = response.json()
30-
return data['lat'], data['lon']
31-
except:
32-
return 0, 0
33-
3426
def fetch_iss_tle():
3527
url = "https://celestrak.org/NORAD/elements/stations.txt"
3628
tle_data = requests.get(url).text
@@ -40,6 +32,26 @@ def fetch_iss_tle():
4032
return lines[i+1], lines[i+2]
4133
return None, None
4234

35+
def eci_to_latlon(pos, jd):
36+
# Calculate GMST (Greenwich Mean Sidereal Time)
37+
T = (jd - 2451545.0) / 36525.0
38+
GMST = 280.46061837 + 360.98564736629 * (jd - 2451545.0) + 0.000387933 * T**2 - T**3 / 38710000.0
39+
GMST = GMST % 360.0
40+
theta = math.radians(GMST)
41+
42+
# ECI to ECEF rotation
43+
x = pos[0]*math.cos(theta) + pos[1]*math.sin(theta)
44+
y = -pos[0]*math.sin(theta) + pos[1]*math.cos(theta)
45+
z = pos[2]
46+
47+
# Convert to lat/lon
48+
r = math.sqrt(x**2 + y**2 + z**2)
49+
lat = math.degrees(math.asin(z / r))
50+
lon = math.degrees(math.atan2(y, x))
51+
if lon > 180:
52+
lon -= 360
53+
return lat, lon
54+
4355
def latlon_to_xy(lat, lon, width, height):
4456
x = (lon + 180) * (width / 360)
4557
y = (90 - lat) * (height / 180)
@@ -56,7 +68,6 @@ def __init__(self, root):
5668
self.tk_image = ImageTk.PhotoImage(self.image)
5769
self.canvas.create_image(0, 0, anchor="nw", image=self.tk_image)
5870

59-
self.lat, self.lon = get_pi_location()
6071
self.load_tle()
6172

6273
self.time_offset = timedelta(seconds=0)
@@ -78,45 +89,45 @@ def update_display(self):
7889
self.canvas.delete("markers")
7990
self.canvas.create_image(0, 0, anchor="nw", image=self.tk_image)
8091

81-
x, y = latlon_to_xy(self.lat, self.lon, 800, 400)
82-
self.canvas.create_oval(x-4, y-4, x+4, y+4, fill="red", tags="markers")
83-
84-
if self.satellite:
85-
now = datetime.utcnow() + self.time_offset
86-
jd, fr = jday(now.year, now.month, now.day, now.hour, now.minute, now.second + now.microsecond/1e6)
87-
e, pos, vel = self.satellite.sgp4(jd, fr)
88-
r = math.sqrt(pos[0]**2 + pos[1]**2 + pos[2]**2)
89-
iss_lat = math.degrees(math.asin(pos[2] / r))
90-
iss_lon = math.degrees(math.atan2(pos[1], pos[0]))
91-
if iss_lon > 180:
92-
iss_lon -= 360
93-
94-
iss_x, iss_y = latlon_to_xy(iss_lat, iss_lon, 800, 400)
95-
self.canvas.create_oval(iss_x-4, iss_y-4, iss_x+4, iss_y+4, fill="purple", tags="markers")
96-
97-
for mins in range(5, 90, 5):
98-
future_time = now + timedelta(minutes=mins)
99-
jd_fut, fr_fut = jday(
100-
future_time.year, future_time.month, future_time.day,
101-
future_time.hour, future_time.minute,
102-
future_time.second + future_time.microsecond / 1e6
103-
)
104-
e_fut, pos_fut, vel_fut = self.satellite.sgp4(jd_fut, fr_fut)
105-
r_fut = math.sqrt(pos_fut[0]**2 + pos_fut[1]**2 + pos_fut[2]**2)
106-
lat_fut = math.degrees(math.asin(pos_fut[2] / r_fut))
107-
lon_fut = math.degrees(math.atan2(pos_fut[1], pos_fut[0]))
108-
if lon_fut > 180:
109-
lon_fut -= 360
110-
path_x, path_y = latlon_to_xy(lat_fut, lon_fut, 800, 400)
111-
self.canvas.create_oval(path_x-1, path_y-1, path_x+1, path_y+1, fill="blue", tags="markers")
92+
now = datetime.utcnow() + self.time_offset
93+
jd, fr = jday(now.year, now.month, now.day, now.hour, now.minute, now.second + now.microsecond/1e6)
94+
95+
# Current ISS position
96+
e, pos, vel = self.satellite.sgp4(jd, fr)
97+
lat, lon = eci_to_latlon(pos, jd)
98+
iss_x, iss_y = latlon_to_xy(lat, lon, 800, 400)
99+
self.canvas.create_oval(iss_x-4, iss_y-4, iss_x+4, iss_y+4, fill="purple", tags="markers")
100+
101+
# Future path
102+
path_coords = []
103+
for mins in range(0, 90, 2):
104+
future_time = now + timedelta(minutes=mins)
105+
jd_fut, fr_fut = jday(
106+
future_time.year, future_time.month, future_time.day,
107+
future_time.hour, future_time.minute,
108+
future_time.second + future_time.microsecond / 1e6
109+
)
110+
e_fut, pos_fut, vel_fut = self.satellite.sgp4(jd_fut, fr_fut)
111+
lat_fut, lon_fut = eci_to_latlon(pos_fut, jd_fut)
112+
path_x, path_y = latlon_to_xy(lat_fut, lon_fut, 800, 400)
113+
path_coords.append((path_x, path_y))
114+
115+
# Draw blue path line
116+
for i in range(len(path_coords)-1):
117+
self.canvas.create_line(path_coords[i][0], path_coords[i][1],
118+
path_coords[i+1][0], path_coords[i+1][1],
119+
fill="blue", width=2, tags="markers")
120+
121+
# Draw time label
122+
self.canvas.create_text(400, 20, text=now.strftime("%Y-%m-%d %H:%M:%S UTC"), font=("Arial", 16), fill="white", tags="markers")
112123

113124
self.root.after(1000, self.update_display)
114125

115126
def go_forward(self, event):
116-
self.time_offset += timedelta(minutes=10)
127+
self.time_offset += timedelta(minutes=2)
117128

118129
def go_back(self, event):
119-
self.time_offset -= timedelta(minutes=10)
130+
self.time_offset -= timedelta(minutes=2)
120131

121132
def reset_time(self, event):
122133
self.time_offset = timedelta(seconds=0)

0 commit comments

Comments
 (0)