-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathiss2.py
executable file
·134 lines (115 loc) · 3.75 KB
/
iss2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/usr/bin/env python
# ISS tracker (needs Skyfield)
import pygame
from skyfield.api import load, wgs84, utc
from daynight import get_img
import time, datetime, os.path
UPDATE = .5 # zoomed map update interval in s
UPDATETRACK = 10 # track update interval in s
WIN_WIDTH = 1900 # window width
BMAPW = int(2 / 3 * WIN_WIDTH) # big map width
ZMAPW = WIN_WIDTH - BMAPW # zoomed map width
LWID = 4 # line width
CSIZ = int(100 / 8192 * BMAPW) # cursor size
bg = pygame.image.load("cities.png")
b2 = pygame.image.load("earth4k_3_bright.png")
b2 = pygame.transform.scale(b2, (BMAPW, ZMAPW))
# download new orbital elements each day
try:
mtime = os.path.getmtime("stations.txt")
except:
mtime = 0
if time.time() - mtime > 40000:
update = True
else:
update = False
# from https://rhodesmill.org/skyfield/earth-satellites.html
stations_url = 'https://celestrak.com/NORAD/elements/stations.txt'
satellites = load.tle_file(stations_url, reload = update)
by_name = {sat.name: sat for sat in satellites}
satellite = by_name['ISS (ZARYA)']
ts = load.timescale()
def getpos():
tnow = ts.now()
geocentric = satellite.at(tnow)
lat, lon = wgs84.latlon_of(geocentric)
return lat.degrees, lon.degrees
class ISS:
def __init__(s):
pygame.init()
s.res = ZMAPW + BMAPW, ZMAPW
s.screen = pygame.display.set_mode(s.res)
pygame.display.set_caption('ISS Tracker')
s.clock = pygame.time.Clock()
s.last = 0
s.lasttrack = 0
s.plot = pygame.Surface((100, 100))
s.lpos = []
def events(s):
for event in pygame.event.get():
if event.type == pygame.QUIT: s.running = False
def run(s):
s.running = True
while s.running:
s.clock.tick(10)
s.events()
s.update()
pygame.quit()
def update(s):
# update zoomed map
if time.time() - s.last > UPDATE:
s.lat, s.lon = getpos()
s.last = time.time()
mx = int((180 + s.lon) * 8192 / 360)
my = int(( 90 - s.lat) * 4096 / 180)
for y in range(100):
for x in range(100):
try:
c = bg.get_at(((x + mx - 50) % 8192, y + my - 50))
except:
c = 120, 120, 120
s.plot.set_at((x, y), c)
# update track data
dt = time.time() - s.lasttrack
if dt > UPDATETRACK or dt < 0:
s.lasttrack = time.time()
s.lpos = []
# calculate track for +-90 minutes:
for x in range(-90, 91, 2):
# https://blog.miguelgrinberg.com/post/it-s-time-for-a-change-datetime-utcnow-is-now-deprecated
tnow = datetime.datetime.now(datetime.timezone.utc)
td = datetime.timedelta(minutes = 1)
t = tnow + x * td
t = ts.from_datetime(t)
geocentric = satellite.at(t)
lat, lon = wgs84.latlon_of(geocentric)
s.lpos.append((lat.degrees, lon.degrees))
s.dn = get_img()
s.dn = pygame.transform.smoothscale(s.dn, (BMAPW, ZMAPW))
out = pygame.transform.scale(s.plot, (ZMAPW, ZMAPW))
s.screen.blit(b2, (ZMAPW, 0))
s.screen.blit(s.dn, (ZMAPW, 0))
# draw track
for n in range(0, len(s.lpos) - 1):
l1 = int((180 + s.lpos[n][1]) * BMAPW / 360) + ZMAPW
l2 = int(( 90 - s.lpos[n][0]) * ZMAPW / 180)
l3 = int((180 + s.lpos[n+1][1]) * BMAPW / 360) + ZMAPW
l4 = int(( 90 - s.lpos[n+1][0]) * ZMAPW / 180)
if n >= len(s.lpos) // 2:
c = (255, 255, 0)
else:
c = (255, 0, 0)
if abs(l1 - l3) < BMAPW / 5 and abs(l2 - l4) < BMAPW / 5:
pygame.draw.line(s.screen, c, (l1, l2), (l3, l4), LWID)
else:
pygame.draw.line(s.screen, c, (l1, l2), (l3 + BMAPW, l4), LWID)
pygame.draw.line(s.screen, c, (l1 - BMAPW, l2), (l3, l4), LWID)
# draw current position
lx = int((180 + s.lon) * BMAPW / 360) + ZMAPW
ly = int(( 90 - s.lat) * ZMAPW / 180)
if time.time() % 1 < .5:
pygame.draw.rect(s.screen, (255, 0, 0), [lx - CSIZ // 2, ly - CSIZ // 2, CSIZ, CSIZ])
s.screen.blit(out, (0, 0))
pygame.display.flip()
c = ISS()
c.run()