5

问题陈述

我需要使用或类似方法从 space-track.org 传播最近 TLE 的整个目录(需要免费帐户才能查看) 。skyfield列表中通常有 15k-16k TLE。我有它的工作,但它慢。在服务器上使用 46 个内核大约需要几个小时。

没有结婚skyfield。如果astropypyephem或其他东西更快,我会很乐意接受一个答案,表明我正在尝试使用它来做什么。

最小的例子

对于我的应用程序,我将 TLE 加载到 Pandas 数据框中并在那里进行分析,因此我将把我的示例保留在 Pandas 世界中。最小的例子如下。

假设卫星目录保存为catalog.txt,设置环境,然后读取 TLE,生成sf.sgp4lib.EarthSatellite对象,并将所有内容加载到 Pandas 数据帧中。我们还向一些观察点偏移了位置。我将选择一个观察点留给读者(0、0、0 可以):

import skyfield as sf
import pandas as pd
from skyfield.api import load, Topos
from datetime import datetime, timezone, timedelta

with open('catalog.txt', 'r') as f:
    tle_list = [line.strip() for line in f.read().split('\n')
                if line is not '']
data = []
for i in range(0, len(tle), 2):  # every two lines
    temp = {}
    temp['tle1'] = tle_list[i]
    temp['tle2'] = tle_list[i+1]
    temp['earthsat'] = sf.sgp4lib.EarthSatellite(tle_list[i],
                                                 tle_list[i+1])
    data.append(temp)
df = pd.DataFrame(data=data)
site = Topos(latitude_degrees=site_lat,
             longitude_degrees=site_lon,
             elevation_m=site_alt)
df['earthsat'] = df.earthsat - site  # offset to site location

每个循环 2.1 秒 ± 20 毫秒(平均值 ± 标准偏差。7 次运行,每个循环 1 个)

创建一个时区感知日期时间对象数组,在其上传播所有卫星。在这里,我选择了从写这篇文章当天午夜前 4 小时到之后 4 小时的每 10 分钟。

ts = load.timescale()
tz = timezone(timedelta(hours=-4))  # Eastern or whatever timezone
midnight = datetime(2018, 4, 4, 0, 0, 0, tzinfo=tz)  # midnight today
start = midnight - timedelta(hours=4)
end = midnight + timedelta(hours=4)
delta_time = timedelta(minutes=10)
# This is ugly, but I had issues using linspace or arange...
times = [start]
now = start
while now <= end:
    now += delta_time
    times.append(now)

每个循环 189 毫秒 ± 36.9 毫秒(平均值 ± 标准偏差。7 次运行,每次 10 次循环)

最后,计算每个卫星的每个时间步长的天体测量位置。这需要永远。为了获得时间,我再次运行时间太长了,但在服务器上使用 46 个内核大约需要几个小时。

df['astrometric'] = df.earthsat.apply(lambda x: [x.at(ts.utc(time)) for time in times])

额外细节

在文档中发现了关于日期数组的讨论,该讨论建议一次传递整个数组:x.at(ts.utc(times)). 到目前为止,这需要更少的内核并且运行速度更快,但仍然需要非常长的时间。

通过为天体测量创建生成器,我暂时解决了这种减速问题(最初是为什么我不再一次性传递整个times数组),但最终我实际上需要评估事情,所以我无法永远避免繁重的工作。

如果最终的用例适合某种特定的加速,我最终需要从这些对象中获取站点的观察角度,所以[x.altaz() for x in row.astrometrics]类型的东西。

关于解决方案的想法

我现在的想法是,我正在为目录中的每颗卫星计算整个夜间每个时间步长的观测点位置。我可能是错的,但如果我是对的,那么我想通过计算一次然后为每颗新卫星查找它,我会看到一个相当不错的加速(可能还不够)。有人知道怎么做这个吗?

此外,如果那里有更快的轨道传播器实施,或者有一种加快天空场实施的方法,我会很乐意接受一个答案,说明如何使用它来做我正在尝试做的事情(因此包括astropypyephem标签)。

谢谢你。

4

1 回答 1

1

我最好的建议是使用NASA SPICE Toolkit进行此类工作。这让您加载两行元素,然后使用 NASA 的 NAIF/SPICE 内核来完成其余的工作(您可能还会发现一些其他格式的卫星,但 TLE 很好)。

如果您使用 C 语言工作,您将使用getelm_c方法读取它们并使用spkpos_c获取位置。幸运的是,有一个名为spiceypy的 python 包装器!

getelm_c方法被包装在您spiceypy.spiceypy.getelm(frstyr, lineln, lines)TLE中。您希望他们spiceypy.spiceypy.spkpos(targ, et, ref, abcorr, obs)用来获取您相对于参考主体的位置。

如果您决定使用 NASA 的 SPICE 内核,我建议使用来自 spiceypy 的文档,特别是 Cassini 示例的位置,以确保您拥有所有正确的文件: https ://spiceypy.readthedocs.io/en/master/ exampleone.html

于 2019-08-03T02:52:54.703 回答