Skip to content

Commit fd603ea

Browse files
authored
Add files via upload
1 parent 83ddb77 commit fd603ea

File tree

1 file changed

+284
-0
lines changed

1 file changed

+284
-0
lines changed
Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
from pwn import *
2+
from skyfield.api import load, wgs84
3+
from skyfield.framelib import ecliptic_J2000_frame
4+
from math import floor
5+
import numpy as np
6+
from math import sin, cos, acos, sqrt
7+
from numpy.linalg import norm
8+
from numpy import sqrt, dot, cross
9+
from skyfield.framelib import \
10+
true_equator_and_equinox_of_date as of_date
11+
12+
def proj(u, v):
13+
v_norm = np.linalg.norm(v)
14+
return (np.dot(u, v) / v_norm**2) * v
15+
16+
r = remote("crosslinks2.satellitesabove.me", 5400)
17+
r.recvline()
18+
r.sendline(b"ticket{oscar561388quebec3:GAaopaxYK9ldU3wbbDC6XAqeccNoornlfDo_jptrIyXfq-B-yjLnteC7KLBkgFZzzg}")
19+
data = r.recvuntil(b"What's my position").replace(b"What's my position", b"").strip()
20+
21+
tles = data.split(b"TLE")[1].split(b"Measurements")[0].strip()
22+
with open("comms.tle", "wb") as f:
23+
f.write(tles)
24+
25+
t = load.timescale()
26+
27+
observations = {}
28+
for i in data.split(b"Measurements")[1].strip().split(b"\n"):
29+
if b"Observations" in i:
30+
cur_sat = int(i.split(b"-")[-1])
31+
observations[cur_sat] = []
32+
if b"Time, " in i:
33+
continue
34+
if i.startswith(b"2022"):
35+
date, range_, range_rate = i.split(b", ")
36+
range_ = float(range_)
37+
range_rate = float(range_rate)
38+
year = int(date.split(b"-")[0])
39+
month = int(date.split(b"-")[1])
40+
day = int(date.split(b"-")[2].split(b"T")[0])
41+
42+
hour = int(date.split(b"T")[1].split(b":")[0])
43+
minute = int(date.split(b"T")[1].split(b":")[1])
44+
second = float(date.split(b"T")[1].split(b":")[2].split(b"+")[0])
45+
ts = t.utc(year, month, day, hour, minute, second)
46+
observations[cur_sat].append((ts, range_, range_rate))
47+
48+
print(observations)
49+
50+
comms = load.tle_file("comms.tle")
51+
52+
sat_dic = {}
53+
54+
for sat in comms:
55+
print(sat)
56+
key = int(str(sat).split("-")[1].split()[0])
57+
sat_dic[key] = sat
58+
59+
def trilaterate(P1,P2,P3,r1,r2,r3):
60+
temp1 = P2-P1
61+
e_x = temp1/norm(temp1)
62+
temp2 = P3-P1
63+
i = dot(e_x,temp2)
64+
temp3 = temp2 - i*e_x
65+
e_y = temp3/norm(temp3)
66+
e_z = cross(e_x,e_y)
67+
d = norm(P2-P1)
68+
j = dot(e_y,temp2)
69+
x = (r1*r1 - r2*r2 + d*d) / (2*d)
70+
y = (r1*r1 - r3*r3 -2*i*x + i*i + j*j) / (2*j)
71+
temp4 = r1*r1 - x*x - y*y
72+
if temp4<0:
73+
return None
74+
z = sqrt(temp4)
75+
p_12_a = P1 + x*e_x + y*e_y + z*e_z
76+
p_12_b = P1 + x*e_x + y*e_y - z*e_z
77+
return p_12_a,p_12_b
78+
79+
def compute_radius(sat, t, d):
80+
pos = sat.at(t).position.to("km")
81+
vel = sat.at(t).velocity
82+
pos = pos.value
83+
x, y, z = pos
84+
radius = d
85+
origin = np.array(pos)
86+
return radius, origin
87+
88+
def compute_rr_error(velocities, pos, pr=False):
89+
least_error = 9999999999999999999.0
90+
win_num = 0
91+
results = []
92+
for vel in velocities:
93+
error = 0.0
94+
for observe_num in observations:
95+
# sat_num observe observe_num
96+
for observation in observations[observe_num]:
97+
if observe_num not in sat_dic:
98+
continue
99+
ts, range_, range_rate = observation
100+
sat_loc = pos
101+
observe_loc = sat_dic[observe_num].at(ts).position.to("km").value
102+
103+
# 'au_per_d', 'km_per_s', 'm_per_s'
104+
sat_vel = vel
105+
observe_vel = sat_dic[observe_num].at(ts).velocity.km_per_s
106+
107+
p = proj(observe_vel - sat_vel, observe_loc - sat_loc)
108+
calc_range_rate = np.linalg.norm(p)
109+
unit_vec = np.dot(observe_vel - sat_vel, observe_loc - sat_loc)
110+
unit_vec = unit_vec / abs(unit_vec)
111+
calc_range_rate = np.linalg.norm(p) * unit_vec
112+
113+
if pr: print("RR", calc_range_rate, range_rate)
114+
115+
error += abs((calc_range_rate) - (range_rate))
116+
# print("{},{},{}".format(vel[0], vel[1], vel[2]), error)
117+
results.append((error, "{},{},{}".format(vel[0], vel[1], vel[2]).encode()))
118+
if error < least_error:
119+
least_error = error
120+
win_num = vel
121+
results.sort()
122+
123+
print(results[:200])
124+
return win_num, least_error, results
125+
126+
def compute_error(positions):
127+
least_error = 9999999999999999999.0
128+
win_num = 0
129+
results = []
130+
for pos in positions:
131+
error = 0.0
132+
for observe_num in observations:
133+
# sat_num observe observe_num
134+
for observation in observations[observe_num]:
135+
ts, range_, range_rate = observation
136+
observe_loc = sat_dic[observe_num].at(ts)
137+
138+
sat_vec = pos
139+
observe_vec = np.array(observe_loc.position.to("km").value)
140+
distance = np.linalg.norm(sat_vec - observe_vec)
141+
error += (distance - range_)**2
142+
print(pos, error)
143+
results.append((error, pos))
144+
if error < least_error:
145+
least_error = error
146+
win_num = pos
147+
results.sort()
148+
for i in results[:1000]:
149+
print(i)
150+
return win_num, least_error, results
151+
152+
poss_pos = []
153+
154+
keys = list(observations.keys())
155+
for i in range(len(keys)):
156+
for j in range(len(keys)):
157+
for k in range(len(keys)):
158+
if i != j and j != k and i != k:
159+
r1, o1 = compute_radius(sat_dic[keys[i]], observations[keys[i]][0][0], observations[keys[i]][0][1])
160+
r2, o2 = compute_radius(sat_dic[keys[j]], observations[keys[j]][0][0], observations[keys[j]][0][1])
161+
r3, o3 = compute_radius(sat_dic[keys[k]], observations[keys[k]][0][0], observations[keys[k]][0][1])
162+
163+
res = trilaterate(o1, o2, o3, r1, r2, r3)
164+
if res is not None and not np.any(np.isnan(res[0])):
165+
bad1 = False
166+
bad2 = False
167+
for l in poss_pos:
168+
if np.linalg.norm(res[0] - l) < 5:
169+
bad1 = True
170+
if np.linalg.norm(res[1] - l) < 5:
171+
bad2 = True
172+
if bad1 and bad2:
173+
break
174+
if not bad1:
175+
poss_pos.append(res[0])
176+
if not bad2:
177+
poss_pos.append(res[1])
178+
if len(poss_pos) > 1000:
179+
break
180+
if len(poss_pos) > 1000:
181+
break
182+
if len(poss_pos) > 1000:
183+
break
184+
print(poss_pos)
185+
pos, error, pos_results = compute_error(poss_pos)
186+
pos_error = error
187+
print(pos, error)
188+
for i in pos_results[:200]:
189+
print(i)
190+
191+
r.close()
192+
193+
for pos_error, pos in pos_results[::4]:
194+
195+
poss_vel = []
196+
keys = list(observations.keys())
197+
198+
for i in range(len(keys)):
199+
for j in range(len(keys)):
200+
for k in range(len(keys)):
201+
if i != j and j != k and i != k:
202+
vo1 = sat_dic[keys[i]].at(ts).velocity.km_per_s
203+
vo2 = sat_dic[keys[j]].at(ts).velocity.km_per_s
204+
vo3 = sat_dic[keys[k]].at(ts).velocity.km_per_s
205+
# vo1 = np.reshape(vo1, (3, 1))
206+
# vo2 = np.reshape(vo1, (3, 1))
207+
# vo3 = np.reshape(vo1, (3, 1))
208+
209+
r1 = observations[keys[i]][0][2]
210+
r2 = observations[keys[j]][0][2]
211+
r3 = observations[keys[k]][0][2]
212+
213+
rso_k1 = sat_dic[keys[i]].at(ts).position.to("km").value - pos
214+
rso_k2 = sat_dic[keys[j]].at(ts).position.to("km").value - pos
215+
rso_k3 = sat_dic[keys[k]].at(ts).position.to("km").value - pos
216+
# rso_k1 = np.reshape(rso_k1, (3, 1))
217+
# rso_k2 = np.reshape(rso_k2, (3, 1))
218+
# rso_k3 = np.reshape(rso_k3, (3, 1))
219+
220+
p1 = rso_k1 / np.linalg.norm(rso_k1) * r1
221+
p2 = rso_k2 / np.linalg.norm(rso_k2) * r2
222+
p3 = rso_k3 / np.linalg.norm(rso_k3) * r3
223+
224+
# p_matrix1 = (rso_k1 * (np.transpose(rso_k1) * rso_k1)[0][0]) @ np.transpose(rso_k1)
225+
# p_rhs1 = p_matrix1 @ vo1 - p1
226+
# p_matrix2 = (rso_k2 * (np.transpose(rso_k2) * rso_k2)[0][0]) @ np.transpose(rso_k2)
227+
# p_rhs2 = p_matrix2 @ vo2 - p2
228+
# p_matrix3 = (rso_k3 * (np.transpose(rso_k3) * rso_k3)[0][0]) @ np.transpose(rso_k3)
229+
# p_rhs3 = p_matrix3 @ vo3 - p3
230+
231+
# A = np.vstack((p_matrix1, p_matrix2, p_matrix3))
232+
# B = np.vstack((p_rhs1, p_rhs2, p_rhs3))
233+
234+
v1 = rso_k1 * np.dot(vo1, rso_k1) / np.dot(rso_k1, rso_k1) - p1
235+
v2 = rso_k2 * np.dot(vo2, rso_k2) / np.dot(rso_k2, rso_k2) - p2
236+
v3 = rso_k3 * np.dot(vo3, rso_k3) / np.dot(rso_k3, rso_k3) - p3
237+
238+
w1 = np.linalg.norm(v1) * np.linalg.norm(rso_k1)
239+
w2 = np.linalg.norm(v2) * np.linalg.norm(rso_k2)
240+
w3 = np.linalg.norm(v3) * np.linalg.norm(rso_k3)
241+
242+
mat = np.array([[*rso_k1], [*rso_k2], [*rso_k3]])
243+
vec = np.array([w1, w2, w3])
244+
sol = np.linalg.solve(mat, vec).reshape(3)
245+
246+
# print(A.shape)
247+
# print(B.shape)
248+
# sol = np.linalg.solve(A, B)
249+
250+
poss_vel.append(sol)
251+
252+
if len(poss_vel) > 1000:
253+
break
254+
if len(poss_vel) > 1000:
255+
break
256+
if len(poss_vel) > 1000:
257+
break
258+
vel, error, results = compute_rr_error(poss_vel, pos)
259+
print(vel, error)
260+
261+
print("POS: {},{},{} ERROR:{}".format(pos[0], pos[1], pos[2], pos_error))
262+
print("VEL: {},{},{} ERROR:{}".format(vel[0], vel[1], vel[2], error))
263+
264+
compute_rr_error([vel], pos, True)
265+
266+
for i in results[:3]:
267+
r = remote("crosslinks2.satellitesabove.me", 5400)
268+
r.recvline()
269+
r.sendline(b"ticket{oscar561388quebec3:GAaopaxYK9ldU3wbbDC6XAqeccNoornlfDo_jptrIyXfq-B-yjLnteC7KLBkgFZzzg}")
270+
data = r.recvuntil(b"What's my position").replace(b"What's my position", b"").strip()
271+
272+
# pos = b"6676.958887049956,-2070.6729547915697,-11.891150202096647"
273+
print("SEND", pos, i[1])
274+
r.recvuntil(b": ")
275+
r.sendline("{},{},{}".format(pos[0], pos[1], pos[2]).encode())
276+
r.recvuntil(b": ")
277+
r.sendline(i[1])
278+
279+
res = r.recvline() + r.recvline() + r.recvline() + r.recvline()
280+
print(res)
281+
if b"Wrong!" not in res:
282+
print(b"WIN")
283+
r.interactive()
284+
r.close()

0 commit comments

Comments
 (0)