<p>有太多可能的情况,用户可能会问-当一颗卫星穿过某个特定的经度;当它到达某个特定的纬度;当它达到某个高度或下降到它的最低高度;当它的速度是最大或最小时——PyEphem并没有试图为所有这些情况提供内置的功能。相反,它提供了一个<code>newton()</code>函数,该函数允许您查找卫星属性与要搜索的该属性的预先确定值之间的任何比较的零交叉。在</p>
<p>请注意,SciPy Python库包含几个非常仔细的搜索函数,这些函数比PyEphem的<code>newton()</code>函数复杂得多,以防您处理的是一个性能特别差的函数:</p>
<p><a href="http://docs.scipy.org/doc/scipy/reference/optimize.html" rel="noreferrer">http://docs.scipy.org/doc/scipy/reference/optimize.html</a></p>
<p>以下是如何搜索卫星(在本例中为国际空间站)通过特定经度时的方法,以显示一般技术。这并不是最快的方法——特别是,如果我们非常小心的话,分秒必争的搜索速度可能会加快——但它被写为非常通用和非常安全的,以防除了经度之外还有其他值需要搜索。我尝试添加文档和注释来解释发生了什么,以及为什么我使用<code>znorm</code>而不是返回简单的差异。让我知道这个脚本是否适合你,并解释它的方法足够清楚!在</p>
<pre><code>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
</code></pre>
<p>运行此脚本时得到的输出表明,它确实找到了ISS到达目标经度的时刻(在合理的公差范围内):</p>
^{pr2}$