使用pyephem计算卫星何时穿越经度
我在想怎么计算一个卫星什么时候会经过某个特定的经度。能提供一个时间段和一个TLE(轨道元素)信息,然后返回在这个时间段内卫星经过这个经度的所有时间,这样就太好了。请问pyephem这个库支持这样做吗?
2 个回答
程序计算卫星经过某个经度的时间和实际时间之间存在差异。我用NASA在国际空间站(ISS)内部的LIS系统来查找闪电,进行了检查。结果发现,在欧洲的某些轨道上,程序计算的经过时间比实际时间提前了30秒。而在哥伦比亚的某些轨道上,这个提前的时间大约是3分钟(可能是因为在哥伦比亚,1度经度的实际距离比在欧洲要大)。不过,这个问题只发生在两个特定的轨道上!一个是经过法国然后下降到西西里,另一个是经过美国然后下降到古巴。 这可能是什么原因呢?我觉得可能是ephem.newton算法有问题,或者是TLE(轨道元素)出了错。通常情况下,TLE是在每天的00:00:00生成的(而不是实时的,因为国际空间站每天会生成3到4个TLE),或者可能是sat.sublong函数计算了错误的卫星天顶点。 有没有人对这个问题有想法或者解释呢?为什么会发生这种情况? 附注:我需要确认这个问题,因为我需要知道国际空间站何时经过某个区域(以便检测该区域内的闪电)。如果程序在某些轨道上计算的时间比实际时间提前,那么sat.sublong函数就会计算出卫星还没有到达该区域,但程序却显示它已经在区域内了。所以在某些情况下,实际时间和程序计算的时间不匹配。 非常感谢你的时间!
用户可能会问很多问题,比如卫星什么时候会经过某个特定的经度;什么时候到达某个特定的纬度;什么时候达到某个高度或降到最低点;什么时候速度最快或最慢等等。由于情况太多,PyEphem并没有为所有这些情况提供内置的函数。相反,它提供了一个 newton()
函数,让你可以找到卫星某个属性和你想要查找的那个属性的预设值之间的交点。
需要注意的是,SciPy这个Python库里有几个非常精确的搜索函数,比PyEphem的 newton()
函数要复杂得多,特别是当你处理一些表现不太好的函数时,可以考虑使用这些函数:
http://docs.scipy.org/doc/scipy/reference/optimize.html
下面是一个例子,展示如何查找卫星(这里以国际空间站ISS为例)经过某个特定经度的时间。这种方法并不是最快的,尤其是逐分钟搜索的部分,如果我们更加小心的话,可以加快速度。但这个方法设计得很通用,也很安全,以防你还想查找其他值,而不仅仅是经度。我尽量添加了一些文档和注释,来解释发生了什么,以及为什么我使用 znorm
而不是简单返回差值。如果这个脚本对你有用,并且能清楚地解释它的方法,请告诉我!
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
当我运行这个脚本时,输出结果表明,它确实找到了国际空间站达到目标经度的时刻(在合理的误差范围内):
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