Skip to content

Commit c8db673

Browse files
For #526, another approach: upside down vectors
1 parent c0ed29e commit c8db673

File tree

1 file changed

+84
-10
lines changed

1 file changed

+84
-10
lines changed

design/broadcasting.py

Lines changed: 84 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def main():
3232
# The above maneuvers work fine even with the old version of the
3333
# routine. But to proceed from here, we need to switch.
3434

35-
print('==== N times, one observers, M targets ====')
35+
print('==== N times, one observers, M targets [TRY: RIGHT SIDE UP] ====')
3636

3737
t = ts.utc(2021, 2, 19, 13, [46, 47, 48, 49])
3838
planets = load('de421.bsp')
@@ -61,6 +61,35 @@ def main():
6161
print('Second planet:')
6262
print(r[:,:,1])
6363

64+
print('==== N times, one observers, M targets [TRY: UPSIDE DOWN] ====')
65+
66+
t = ts.utc(2021, 2, 19, 13, [46, 47, 48, 49])
67+
planets = load('de421.bsp')
68+
69+
earth = planets['earth']
70+
if 0:
71+
# Turn Earth into two observation positions.
72+
earth = planets['earth']
73+
earth._at = build_multi_at(earth._at)
74+
observer = earth.at(t)
75+
print('observer', observer.position.au.shape)
76+
77+
target = planets['mars']
78+
target._at = build_multi_at(target._at) # Turn Mars into 2 planets.
79+
print('target', target.at(t).position.au.shape)
80+
81+
t = ts.tt(t.tt[:,None]) # What if we add a dimension to t?
82+
print('t', t.shape)
83+
84+
r, v, t2, light_time = _correct_for_light_travel_time3(observer, target)
85+
print(t.shape, observer.position.km.shape, '->', r.shape)
86+
87+
print('Does it look like a second planet 1 AU away at the same 4 times?')
88+
print('First planet:')
89+
print(r[:,:,0])
90+
print('Second planet:')
91+
print(r[:,:,1])
92+
6493
offset = array([0, 1])[None,None,:] # Dimensions: [xyz, time, offset]
6594

6695
def build_multi_at(_at):
@@ -135,15 +164,11 @@ def sub(a, b):
135164
return (a.T - b.T).T
136165

137166
def _correct_for_light_travel_time2(observer, target):
138-
"""Return a light-time corrected astrometric position and velocity.
139-
140-
Given an `observer` that is a `Barycentric` position somewhere in
141-
the solar system, compute where in the sky they will see the body
142-
`target`, by computing the light-time between them and figuring out
143-
where `target` was back when the light was leaving it that is now
144-
reaching the eyes or instruments of the `observer`.
145-
146-
"""
167+
#
168+
# This version makes subtraction work by replacing normal NumPy
169+
# broadcasting subtraction with a sub() function of our own that
170+
# broadcasts in the other direction.
171+
#
147172
t = observer.t
148173
ts = t.ts
149174
whole = t.whole
@@ -188,6 +213,55 @@ def _correct_for_light_travel_time2(observer, target):
188213
raise ValueError('light-travel time failed to converge')
189214
return sub(tposition, cposition), sub(tvelocity, cvelocity), t, light_time
190215

216+
# What if we turn things upside down and then do normal subtraction?
217+
218+
def _correct_for_light_travel_time3(observer, target):
219+
#
220+
# This version uses normal NumPy subtraction with its default
221+
# broadcasting, which it makes work by always turning the position
222+
# vectors upside down when it receives them from other parts of
223+
# Skyfield, then turning them back over when its own computations
224+
# are done.
225+
#
226+
t = observer.t
227+
ts = t.ts
228+
whole = t.whole
229+
tdb_fraction = t.tdb_fraction
230+
231+
cposition = observer.position.au
232+
cvelocity = observer.velocity.au_per_d
233+
234+
cposition = cposition.T
235+
cvelocity = cvelocity.T
236+
237+
tposition, tvelocity, gcrs_position, message = target._at(t)
238+
tposition = tposition.T
239+
tvelocity = tvelocity.T
240+
241+
distance = length_of((tposition - cposition).T).T
242+
light_time0 = 0.0
243+
for i in range(10):
244+
light_time = distance / C_AUDAY
245+
delta = light_time - light_time0
246+
if abs(max(delta)) < 1e-12:
247+
break
248+
249+
# We assume a light travel time of at most a couple of days. A
250+
# longer light travel time would best be split into a whole and
251+
# fraction, for adding to the whole and fraction of TDB.
252+
t2 = ts.tdb_jd(whole, (tdb_fraction - light_time).T)
253+
254+
tposition, tvelocity, gcrs_position, message = target._at(t2)
255+
tposition = tposition.T
256+
tvelocity = tvelocity.T
257+
distance = length_of((tposition - cposition).T).T
258+
light_time0 = light_time
259+
else:
260+
raise ValueError('light-travel time failed to converge')
261+
tposition = tposition - cposition
262+
tvelocity = tvelocity - cvelocity
263+
return tposition.T, tvelocity.T, t, light_time
264+
191265
_reconcile # So CI will think we used it, whether use above is commented or not
192266

193267
if __name__ == '__main__':

0 commit comments

Comments
 (0)