Closed meawoppl closed 1 year ago
Also, if you ever find yourself at or near that lat/long, I owe you at least a couple drinks :beers:
A shot in the dark: This might be one of the rare cases where the solutions are oscillatory/bi-stable? Probably this happens when there is more than one position with almost the same light delay, perhaps when the satellite is right above the observer's head at that point in time [or at the antipodal point, one earth diameter plus 300 km of altitude corresponding to 15.9 rounds per day of the LTE]. The positions of constant time delay are sets of spheres centered at the observer, and if the satellite just scrapes past one of these (almost tangentially) there might be 2 close positions...
Printing the position of the satellite for each of the 10 iterations ought to reveal that kind of quiver/oscillation. The usual recipe in the software would be not to take an absolute value as the convergence criterion but to leave the loop if subsequent updates of the delta don't decrease anymore.
That was my suspicion. Again this is a 1/1000000 case or so, but I took the time to round it up and make a repro as it might be helpful in testing/triage for others.
I suspect the "right" thing to do here is roughly:
I think the problem is that the Starlink satellite is moving at super-relativistic speed, and therefore images of the satellite are arriving at the viewer in reverse order—by the time its distant image has reached you, it's already close enough to Earth to have delivered several more recent images, so that the observer will actually see it appear to travel backwards in time as, looking up, you see the satellite appearing to move away as more and more distant images finally reach you.
To wit:
tle_0 = """STARLINK-1885"""
tle_1 = """1 47168U 20088AY 22221.92842503 .01483002 11676-2 34717-2 0 9991"""
tle_2 = """2 47168 53.0385 305.4734 0002390 239.0067 121.2198 15.96617970 96526"""
from skyfield.api import EarthSatellite, load
from skyfield.functions import length_of
c_km_per_s = 299792.458
satellite = EarthSatellite(tle_1, tle_2, tle_0)
ts = load.timescale()
t = ts.tt_jd(2459831.9170483043)
xyz_previous = satellite.at(t).xyz
one_second = 1/24.0/3600.0
for i in range(10):
t = t + one_second
xyz = satellite.at(t).xyz
range_km = length_of(xyz.km)
moved_km = length_of(xyz.km - xyz_previous.km)
print(
t.utc_strftime(),
' Range from Earth (km): {:.1f}'.format(range_km),
' Speed (c): {:.3f}'.format(moved_km / c_km_per_s),
)
xyz_previous = xyz
Which produces:
2022-09-09 09:59:25 UTC Range from Earth (km): 1685123.5 Speed (c): 8.761
2022-09-09 09:59:26 UTC Range from Earth (km): 1613951.1 Speed (c): 8.486
2022-09-09 09:59:27 UTC Range from Earth (km): 1547649.9 Speed (c): 8.935
2022-09-09 09:59:28 UTC Range from Earth (km): 1485763.7 Speed (c): 2.711
2022-09-09 09:59:29 UTC Range from Earth (km): 1427889.8 Speed (c): 5.380
2022-09-09 09:59:30 UTC Range from Earth (km): 1373671.8 Speed (c): 8.900
2022-09-09 09:59:31 UTC Range from Earth (km): 1322793.0 Speed (c): 6.029
2022-09-09 09:59:32 UTC Range from Earth (km): 1274971.2 Speed (c): 3.727
2022-09-09 09:59:33 UTC Range from Earth (km): 1229954.1 Speed (c): 2.316
2022-09-09 09:59:34 UTC Range from Earth (km): 1187515.8 Speed (c): 6.507
Check my math here—scripts that I write after midnight have been known to have impressive flaws—but it looks like the satellite's speed second-to-second is varying between about 2× the speed of light and 8× the speed of light. Under such conditions a convergence won't be found.
‘Luke, at that speed do you think you'll be able to pull out in time?’
So the problem appears to be that the program is trying to observe a satellite on 2022-09-09 which decayed in 2022-08-14 and was for that end-of-life starting an extreme (non-physical) elliptic orbit approximately 2 days earlier while actually crashing into the atmosphere: https://isstracker.pl/en/satelity/47168 . The extreme LTE parameter set to 0.0148 (on 2022-08-10) for the change in the n-parameter is in some way indicating that sort of problem.
That appears to be quite non-physical! As an optical imaging group, I think our chances of catching super-relativistic objects on camera are pretty low :wink:
I appreciate the time/triage effort you spent here!
Might it make sense to check the value of tvelocity
for this then balk explicitly? Happy to open a PR if you think it would be helpful.
Might it make sense to check the value of
tvelocity
for this then balk explicitly? Happy to open a PR if you think it would be helpful.
Since the caller might be asking about n dates, I actually would like to back away from the ValueError
that Skyfield currently raises, and probably just drop back to returning nan
if the result doesn't converge, so that if there are multiple dates involved maybe some of them could still return good results. My guess is that for now a pull request might not be worth it, as this is the only time this problem has ever come up?
Heyo @brandon-rhodes thanks for skyfield!
We do a lot of satellite math using your package, and I bumped into this gem while working with it. Here is a reproduction case:
This code takes a road less traveled and reports the following:
This case was hard to find... I suspect we have called an equivalent of this subroutine maybe... a few million times without experiencing it....
Happy to dig in more if there isn't something obvious that springs to mind.