@@ -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+
6493offset = array ([0 , 1 ])[None ,None ,:] # Dimensions: [xyz, time, offset]
6594
6695def build_multi_at (_at ):
@@ -135,15 +164,11 @@ def sub(a, b):
135164 return (a .T - b .T ).T
136165
137166def _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
193267if __name__ == '__main__' :
0 commit comments