Mam trudności z ustaleniem, jak obliczyć, kiedy satelita przekracza określoną długość geograficzną. Byłoby miło móc zapewnić okres czasu i TLE i móc zwrócić wszystkie czasy, w których satelita przekracza określoną długość geograficzną w określonym czasie. Czy Pyephem obsługuje coś takiego?Używanie pyemmu do obliczenia, kiedy satelita przekracza długość geograficzną
Odpowiedz
Jest tyle możliwych okoliczności, o których użytkownicy mogą pytać - kiedy satelita przekracza określoną długość geograficzną; kiedy osiągnie określoną szerokość geograficzną; gdy osiągnie określoną wysokość lub schodzi do najniższej wysokości; kiedy jego prędkość jest największa lub najmniejsza - PyEphem nie stara się zapewnić wbudowanych funkcji dla nich wszystkich. Zamiast tego zapewnia on funkcję newton()
, która umożliwia znalezienie przejścia przez zero niezależnie od tego, jakie porównania chcesz przeprowadzić między atrybutem satelitarnym a wstępnie określoną wartością tego atrybutu, który chcesz wyszukać.
Zauważ, że biblioteka scipy Python zawiera kilka bardzo ostrożnym funkcje wyszukiwania, które są znacznie bardziej wyrafinowane niż newton()
funkcji PyEphem jest, w przypadku, gdy mamy do czynienia ze szczególnie słabo zachowywał funkcję:
http://docs.scipy.org/doc/scipy/reference/optimize.html
Oto jak możesz szukać, kiedy satelita - w tym przykładzie ISS - przejdzie przez określoną długość geograficzną, aby pokazać ogólną technikę. Nie jest to najszybsze z możliwych rozwiązań - w szczególności wyszukiwanie minuta po minucie mogłoby być przyspieszone, gdybyśmy byli bardzo ostrożni - ale jest napisane bardzo ogólnie i bardzo bezpiecznie, na wypadek gdyby były inne wartości poza Ty też chcesz szukać. Próbowałem dodać dokumentację i komentarze, aby wyjaśnić, co się dzieje i dlaczego używam znorm
zamiast zwracać prostą różnicę. Daj mi znać, jeśli ten skrypt będzie działał dla Ciebie i wystarczająco wyraźnie wyjaśni to podejście!
import ephem
line0 = 'ISS (ZARYA) '
line1 = '1 25544U 98067A 13110.27262069 .00008419 00000-0 14271-3 0 6447'
line2 = '2 25544 51.6474 35.7007 0010356 160.4171 304.1803 15.52381363825715'
sat = ephem.readtle(line0, line1, line2)
target_long = ephem.degrees('-83.8889')
def longitude_difference(t):
'''Return how far the satellite is from the target longitude.
Note carefully that this function does not simply return the
difference of the two longitudes, since that would produce a
terrible jagged discontinuity from 2pi to 0 when the satellite
crosses from -180 to 180 degrees longitude, which could happen to be
a point close to the target longitude. So after computing the
difference in the two angles we run degrees.znorm on it, so that the
result is smooth around the point of zero difference, and the
discontinuity sits as far away from the target position as possible.
'''
sat.compute(t)
return ephem.degrees(sat.sublong - target_long).znorm
t = ephem.date('2013/4/20')
# How did I know to make jumps by minute here? I experimented: a
# `print` statement in the loop showing the difference showed huge jumps
# when looping by a day or hour at a time, but minute-by-minute results
# were small enough steps to bring the satellite gradually closer to the
# target longitude at a rate slow enough that we could stop near it.
#
# The direction that the ISS travels makes the longitude difference
# increase with time; `print` statements at one-minute increments show a
# series like this:
#
# -25:16:40.9
# -19:47:17.3
# -14:03:34.0
# -8:09:21.0
# -2:09:27.0
# 3:50:44.9
# 9:45:50.0
# 15:30:54.7
#
# So the first `while` loop detects if we are in the rising, positive
# region of this negative-positive pattern and skips the positive
# region, since if the difference is positive then the ISS has already
# passed the target longitude and is on its way around the rest of
# the planet.
d = longitude_difference(t)
while d > 0:
t += ephem.minute
sat.compute(t)
d = longitude_difference(t)
# We now know that we are on the negative-valued portion of the cycle,
# and that the ISS is closing in on our longitude. So we keep going
# only as long as the difference is negative, since once it jumps to
# positive the ISS has passed the target longitude, as in the sample
# data series above when the difference goes from -2:09:27.0 to
# 3:50:44.9.
while d < 0:
t += ephem.minute
sat.compute(t)
d = longitude_difference(t)
# We are now sitting at a point in time when the ISS has just passed the
# target longitude. The znorm of the longitude difference ought to be a
# gently sloping zero-crossing curve in this region, so it should be
# safe to set Newton's method to work on it!
tn = ephem.newton(longitude_difference, t - ephem.minute, t)
# This should be the answer! So we print it, and also double-check
# ourselves by printing the longitude to see how closely it matches.
print 'When did ISS cross this longitude?', target_long
print 'At this specific date and time:', ephem.date(tn)
sat.compute(tn)
print 'To double-check, at that time, sublong =', sat.sublong
Wyjście które otrzymuję, gdy uruchomiony skrypt ten sugeruje, że rzeczywiście znalazł chwilę (w rozsądnej tolerancji), kiedy ISS osiąga długość docelowa:
When did ISS cross this longitude? -83:53:20.0
At this specific date and time: 2013/4/20 00:18:21
To double-check, at that time, sublong = -83:53:20.1
Niestety, jeśli dobrze rozumiem, w czas "2013/04/20 00:18:21" satelita Wysokość nad poziomem morza -83.8889 wynosi 90º ?, czyli "dokładnie" powyżej długości geograficznej -83.8889? – mikesneider
Satelita znajduje się gdzieś powyżej tej długości geograficznej. Oczywiście może to być dowolne miejsce od bieguna północnego na południe i tylko dla jednego punktu wzdłuż tej długości satelity satelita będzie skierowany prosto w górę. Dla pozostałych miejsc wzdłuż tej długości geograficznej satelita będzie niższy niż 90 ° lub nawet poniżej linii horyzontu. –