Python 两个Topos()位置之间的路径:确定到达给定高度的纬度和经度

Python 两个Topos()位置之间的路径:确定到达给定高度的纬度和经度,python,skyfield,Python,Skyfield,我是轨道力学领域的新手,目前正在努力解决以下问题,这应该很容易用Skyfield解决,但我有点被所有不同的坐标系和它们之间的转换所淹没 我有一个地球上的Topos位置和一个低轨卫星的Topos位置。我正在考虑他们之间的视线。我想确定沿着这条路径的纬度和经度,它与大气的特定层相交的位置 一个例子是中层和一个基于纬度和经度给出的关于其在大约100公里处的属性的现有数据集。交叉点将使我更好地理解这些属性在与卫星通信中的相互作用 我试着直接用Skyfield来做,但最终得到的是一个明显的物体,我无法转换

我是轨道力学领域的新手,目前正在努力解决以下问题,这应该很容易用Skyfield解决,但我有点被所有不同的坐标系和它们之间的转换所淹没

我有一个地球上的
Topos
位置和一个低轨卫星的
Topos
位置。我正在考虑他们之间的视线。我想确定沿着这条路径的纬度和经度,它与大气的特定层相交的位置

一个例子是中层和一个基于纬度和经度给出的关于其在大约100公里处的属性的现有数据集。交叉点将使我更好地理解这些属性在与卫星通信中的相互作用

我试着直接用Skyfield来做,但最终得到的是一个明显的物体,我无法转换回地球上的纬度和经度。首先,我用三角法确定了从地球到达到100公里高度的点的距离

然后,我选择了地球上的位置,使用不变的仰角、方位角来保持路径的方向,最后加上计算出的距离来到达这个位置。我想我需要得到一个地心的对象来使用
subpoint()
,以获得这个位置所需的纬度和经度

这就是我到目前为止所做的:

from skyfield.api import load, Distance
from skyfield.toposlib import Topos
import numpy as np

ts = load.timescale()

earth_position = Topos('52.230039 N', '4.842402 E', elevation_m=10)
space_position = Topos('51.526200 N', '5.347795 E', elevation_m=625 * 1000)

difference = (space_position - earth_position).at(ts.now()).altaz()

distance_to_height = 100 / np.sin(difference[0].radians)

position = earth_position.at(ts.now()).from_altaz(alt_degrees=difference[0].degrees, az_degrees=difference[1].degrees, distance=Distance(km=distance_to_height))
我已经阅读了多次文档,偶然发现了通用ICRF对象的
frame\u latlon(frame)
,但不确定如何进一步进行

尝试将纬度和经度完全三角化也不会产生预期的结果


不幸的是,我没有任何验证结果可以用来更容易地解决这个问题。从三角角度再想象一下,很明显,卫星位置的高度增加会使交叉点的纬度、经度更接近地球上的位置。降低高度将使这个交叉点更靠近卫星。

这是一个有趣的问题,Skyfield的API并没有提供简单的方法来询问;如果您可以通过了解视线与特定高度的交点来概述将要解决的更大问题,那么有可能为解决同一问题的未来用户编写解决该问题的例行程序

同时:

  • 为了让脚本运行,我必须从
    api
    导入
    Distance
  • 名称
    dis
    无法识别,因此我将其替换为
    distance\u to\u height
    ,希望它是预期的名称
  • 调用
    ts.now()
    会在每次调用中为您提供稍微不同的日期和时间。虽然脚本运行速度很快,可能并不重要,但为了清楚起见,我只在脚本开始时调用了一次
    now()
    ,这比反复调用要快一些。(实际上,在这种情况下,速度要快得多,因为旋转矩阵只计算一次,而不必为每个单独的时间对象重复计算,但这是一个不容易看到的隐藏细节。)
  • 我怀疑你的几何学有问题:
    100/sin()
    机动只有在地球是平的情况下才会起作用,我想?但也许你总是在处理接近头顶的卫星,所以误差是可控的?(或者可能是我错误地想象了几何体;如果数学事实上是正确的,请随意提供图表。)
  • 为了便于阅读,我将给出
    altaz()
    的组件名称,而不是数字
  • 有了这些调整, 我认为答案是你需要手动构建一个地心的 通过将观察者的位置相加来确定位置 以及您创建的相对向量 在观察者和视线上100公里点之间。 必须采取像这样的手动步骤意味着一个可能的领域 Skyfield可以改进的地方。 下面是它在代码中的外观:

    from skyfield.api import load, Distance
    from skyfield.positionlib import Geocentric
    from skyfield.toposlib import Topos
    import numpy as np
    
    ts = load.timescale()
    t = ts.now()
    
    earth_position = Topos('52.230039 N', '4.842402 E', elevation_m=10)
    space_position = Topos('51.526200 N', '5.347795 E', elevation_m=625 * 1000)
    
    alt, az, distance = (space_position - earth_position).at(t).altaz()
    
    distance_to_height = 100 / np.sin(alt.radians)
    
    e = earth_position.at(t)
    p = e.from_altaz(alt_degrees=alt.degrees, az_degrees=az.degrees, distance=Distance(km=distance_to_height))
    
    g = Geocentric(e.position.au + p.position.au, t=t)
    s = g.subpoint()
    print(s)
    print(s.elevation.km, '<- warning: 100/sin() did not produce exactly 100')
    
    从skyfield.api导入负载,距离
    从skyfield.positionlib导入地心
    从skyfield.toposlib导入地形
    将numpy作为np导入
    ts=加载。时间刻度()
    t=ts.now()
    接地位置=地形('52.230039北纬','4.842402东经',标高=10)
    空间位置=地形('51.526200 N','5.347795 E',标高=625*1000)
    高度,高度,距离=(空间位置-地球位置).at(t).altaz()
    距离高度=100/np.sin(高度弧度)
    e=接地位置(t)
    p=e.从阿尔泰(阿尔泰度=阿尔泰度,阿兹度=阿兹度,距离=距离(公里=距离到高度))
    g=地心(e.position.au+p.position.au,t=t)
    s=g.子点()
    印刷品
    
    打印(s.elevation.km),你能用一个近似“期望结果”的例子更新你的问题吗对于这两个特定的职位?这会让那些想要开发答案的人有信心,他们正在生成你想要的数字,而不必猜测他们的答案是否正确。非常感谢你的回答!我在目标中加入了更多的上下文,并纳入了你的评论,我本可以注意到这一点关于4)我认为在我的情况下,这个错误通常是可以控制和接受的。由于卫星基本上是绕着地球运行的,一直在高海拔处有一个纬度、经度的子点,所以用三角法来计算它是可以接受的。至少这是我想象的
    subpoint()
    正在计算卫星在地球上的位置。尽管它可能要复杂得多。
    Topos 52deg 06' 30.0" N 04deg 55' 51.7" E
    100.02752954478532 <- warning: 100/sin() did not produce exactly 100