当前位置:首页>python>用Python实现航天器轨道六根数的可视化

用Python实现航天器轨道六根数的可视化

  • 2026-09-09 08:40:35
用Python实现航天器轨道六根数的可视化

你好,我是大象。聚焦航天轨道AI编程与Agent开发。

我本人是航天爱好者和从业者,但发现很多没有系统学习过航天领域知识的人,对航天的基本概念不甚了解。

我知道一定有很多从事在这个领域的人,苦恼于国内外教材大多偏理论推导,即使学完了基础理论,但在和专业人员交流时,还是一脸懵。

因此,我打算写一系列的航天领域技术科普 + 代码工程实践,希望能让你在从事相关工作时,能听懂航天专业人员在说什么。

由于我本人工作主要涉及到航天器轨道动力学、自主定位与导航方面,所以先从这两个系列的文章讲起。

今天是航天器轨道动力学系列文章的第一篇:航天器轨道六根数——用于唯一确定航天器在空间中两体运动轨道的六个几何参数。

轨道六根数用来描述轨道的特征,类似于用身高、体重、胖瘦等描述一个人的外貌特征。

但不同的是,相同的轨道六根数本质上是一条轨道,一条轨道上可以运行成千上万颗卫星。

那么,到底轨道六根数有哪 6 个元素呢?

今天我们就来把它拆开揉碎了讲。没有让人头大的公式,只有基本的概念、图片和代码!

为什么空间中需要6个元素描述轨道?

先退一步想:要描述空间中一个物体的运动状态,需要几个数字?

高中物理告诉我们:3 个位置坐标 + 3 个速度分量 = 6 个自由度。

轨道六根数本质上就是把「3 个位置 + 3 个速度」换了一套坐标来表达——从「你在哪、你往哪飞」翻译成了「你飞的是怎样一条轨道」。

打个比方:描述一个人跑步时刻的运动状态,你可以说「他在东经 116°、北纬 40°,以每小时 10 公里的速度向正东方向移动」。

你也可以说:「他跑的是一个椭圆跑道,跑道长轴 400 米,稍微有点扁,跑道面倾斜 5°,跑道长长的这一头朝正北偏 30°,他现在刚跑过起点线 20°」。

这就是六根数的思路——不关心你瞬间的速度是多少,只关心你飞的那条轨道长什么样。

六根数可以很自然地分成三组来记。每组描述了轨道的不同特征:

  • 第一组(, ):用来描述轨道的大小和形状,通俗讲,就是这条轨道有多高(轨道半长轴)和多胖(偏心率)

  • 第二组(, , ):用来描述轨道在空间里怎么摆,这三个都是角度。

  • 第三组():航天器在轨道的哪个位置?——当前走到哪了

下面我们逐个击破。

1. 第一组:轨道的大小和形状

1. 半长轴 a —— 轨道有多「大」

在卫星围绕地球运转的过程中,卫星看起来是围绕着空间中的一个圆、椭圆运行的, 则描述了这个圆的半径,或者椭圆的半长轴有多大。

你可以把它理解为环形跑道的「半径」。 越大,轨道越高、速度不变的情况下,跑一圈的时间就越长。

举个例子,国际空间站飞在约 400 公里高的轨道上,它的半长轴大约是 6771 公里(地球半径 6371 公里 + 400 公里)。

很多人容易把半长轴 a 和 轨道高度认为是同一个东西,其实不是。轨道高度说的是轨道距离地面的高度。

2. 偏心率 e —— 轨道有多「扁」

描述轨道扁平程度的无量纲几何参数(没有单位的参数),即焦点到椭圆中心的距离与半长轴的比值。它决定了轨道的形状。

在高中数学我们知道,不同的偏心率表示了不同的形状。

  • e = 0:正圆。轨道是个完美的圆,航天器在任何位置离地球一样远。
  • 0 < e < 1:椭圆。e 越接近 1,轨道越扁。
  • e = 1:抛物线轨道。
  • e > 1:双曲线轨道。

有了 a 和 e,轨道本身的大小和形状就定了。但轨道在空间里怎么「摆」?这就靠下一组。

2. 第二组:轨道在空间中的方位

这一组用三个角度来固定轨道在三维空间里的摆放姿势:轨道倾角、升交点赤经和近地点幅角。

1. 轨道倾角  —— 轨道面「斜」了多少

 (Inclination)是轨道倾角,定位为航天器轨道平面与参考平面(如地球赤道面)之间的夹角。

可以把地球赤道想象成一个水平的盘子,轨道面是另一个平面——它和地面赤道之间夹了一个角,这个角就是 。

  •  = 0°:轨道面和赤道面重合。航天器在地球赤道正上方飞行,比如地球静止轨道卫星。
  •  = 90°:轨道面垂直于赤道面。航天器飞越南北极,这就是极地轨道——气象卫星、侦察卫星的最爱,因为地球自转会帮它扫过整个地球表面。
  •  = 180°:轨道面还是和赤道面重合,但飞行方向相反(逆行)。

因此,轨道倾角描述是两个平面之间的夹角。

2. 升交点赤经   —— 轨道从哪「钻出」赤道面

 (Right Ascension of the Ascending Node, 简称 RAAN)是升交点赤经,描述了航天器从南半球穿过参考平面进入北半球的点被称为“升交点”。

为什么是穿过参考平面,而不是赤道平面呢?

因为赤道是地球的平面,如果是月球的轨道,就不是赤道平面了,所以统称为参考平面。

航天器一直飞,总会从一个半球飞到另一个半球。

当它从南半球飞到北半球、穿过赤道面的那个瞬间,它在赤道面上的那个点就叫「升交点」。

  描述的就是这个升交点在赤道面上的方位——从天球上的春分点(一个固定的参考方向)开始,沿参考面向东,量到升交点为止。

生活类比:想象一个斜着转的呼啦圈。呼啦圈和地面有两个交点:一个从下往上穿(升交点),一个从上往下穿(降交点)。 告诉你这个「从下往上穿」的点在东南西北哪个方向。

3. 近地点幅角  —— 轨道的「最胖那头」朝哪

我们知道椭圆有近地点(离地球最近)和远地点(离地球最远)。但近地点指向哪个方向呢?

 就是从升交点到近地点之间的角度。

3. 第三组:轨道上的位置

真近点角 f —— 航天器现在在哪

这是六根数里最简单、也最动态的一个。

在前面的五根数已经把轨道画好了之后,最后一步:航天器在这条轨道上的哪个位置?

f 就是从近地点到航天器当前位置的角度。

  • f = 0°:航天器恰好在近地点,离地球最近。
  • f = 180°:航天器恰好在远地点,离地球最远。
  • f = 90° 或 270°:航天器在半通径上,轨道高度正好等于半长轴。

可以这么理解,在钟表上,假如时针一直不动的话,秒针与时针的夹角一直在变化。这个夹角就是真近点角。

在二体问题(只考虑地球引力的理想情况)中,前五根数是常数,只有 f 随时间变化。航天器沿着这条固定轨道一直在跑,f 从 0° 跑到 360°,一圈又一圈。

看一张展示轨道六要素的图:

结合前面的概念,是不是对轨道六要素有了直观的认识?

4. 说点有用的:六根数有什么用?

轨道六根数到底有什么用?

  • 火箭发射窗口计算:火箭什么时候打,打完之后进入什么轨道——轨道设计师干的就是决定这 6 个数。
  • 太空交会对接:两艘飞船要碰面,它们的六根数必须匹配。不能一艘飞圆形轨道,另一艘飞扁椭圆——那样永远追不上。
  • 星座设计:SpaceX 的星链计划有上万颗卫星,每一颗都有一套精心计算的六根数,保证它们不撞上彼此。
  • 轨道预报:输入六根数 + 时间,就能算出未来任何时刻卫星的位置。

5. 六根数的局限

任何好用的工具都有边界。六根数也不是万能药:

  1. 只适用于二体问题:真实空间中,地球不是完美球体,还有大气阻力、日月引力——这些「摄动」会让轨道悄悄变形。六根数描述的「完美椭圆」只存在于理想世界中。

摄动力可以类比我们要做一件事情,过程一定会遇到各种干扰:手机来了条消息、口渴了等等,这些干扰因素就是轨道的摄动,让轨道的轨迹不会按照着理想的情况传播。

  1. i=0 或 180° 时  无定义:轨道面和赤道面重合时,没有「升交点」这回事。

  2. 实际航天任务怎么做?:高精度任务用「密切轨道根数」(随时间变化的六根数),或者直接用笛卡尔坐标做数值积分。六根数更多用于概念理解、初步设计和粗略预报。

7. 用 Python 画国际空间站的轨道六根数

以下是用 Python 把计算国际空间站轨道六根数的代码。

"""国际太空站 (ISS) 无摄动轨道传播与六根数绘图===============================================使用 poliastro 库计算 ISS 在二体问题(无摄动)下的轨道传播,传播时间为 3 个轨道周期,并在 2×3 子图中绘制轨道六根数随时间的变化。轨道六根数 (Classical Orbital Elements):  a  - 半长轴 (Semi-major axis), km  e  - 偏心率 (Eccentricity), 无量纲  i  - 轨道倾角 (Inclination), deg  Ω  - 升交点赤经 (RAAN), deg  ω  - 近地点幅角 (Argument of periapsis), deg  ν  - 真近点角 (True anomaly), deg在无摄动下,a, e, i, Ω, ω 保持恒定,仅 ν 随时间线性变化。"""import numpy as npimport matplotlib.pyplot as pltimport matplotlibfrom astropy import units as ufrom poliastro.bodies import Earthfrom poliastro.twobody import Orbitfrom poliastro.twobody.propagation import propagate, kepler# -------- 配置 matplotlib 中文字体 (macOS) --------matplotlib.rcParams["font.sans-serif"] = ["PingFang SC",        # 苹方 (macOS 10.11+)"Heiti SC",           # 黑体"STHeiti",            # 华文黑体"Arial Unicode MS",   # 备用]matplotlib.rcParams["axes.unicode_minus"] = False# 解决负号显示异常defmain():# -------- ISS 轨道初始参数 --------# ISS 典型轨道高度约 415 km(近圆轨道)    r_peri = (Earth.R + 415 * u.km).to(u.km)   # 近地点地心距    r_apo  = (Earth.R + 420 * u.km).to(u.km)   # 远地点地心距    a = (r_peri + r_apo) / 2# 半长轴, km    ecc = ((r_apo - r_peri) / (r_apo + r_peri)).decompose()  # 偏心率, 无量纲    inc = 51.6 * u.deg                          # ISS 轨道倾角    raan = 60.0 * u.deg                         # 升交点赤经 (任意选)    argp = 30.0 * u.deg                         # 近地点幅角 (任意选)    nu = 0.0 * u.deg                            # 初始真近点角# 用经典轨道根数构造 Orbit 对象    orb = Orbit.from_classical(Earth, a, ecc, inc, raan, argp, nu)# -------- 传播时间: 3 个轨道周期 --------    T = orb.period                           # 一个轨道周期    n_periods = 3    tof_total = n_periods * T                # 总传播时间# 采样点 (每个周期采样 100 个点)    n_samples = n_periods * 100    times = np.linspace(0, tof_total.to(u.s).value, n_samples) * u.s    print(f"轨道周期: {T.to(u.min):.2f}")    print(f"总传播时间: {tof_total.to(u.min):.2f} ({n_periods} 个周期)")    print(f"采样点数: {n_samples}")    print(f"\n初始轨道六根数:")    print(f"  半长轴 a   = {a.to(u.km):.2f}")    print(f"  偏心率 e   = {ecc:.6f}")    print(f"  倾角 i     = {inc.to(u.deg):.4f}")    print(f"  升交点赤经 Ω = {raan.to(u.deg):.4f}")    print(f"  近地点幅角 ω = {argp.to(u.deg):.4f}")    print(f"  真近点角 ν   = {nu.to(u.deg):.4f}")# -------- 传播轨道,提取每一时刻的六根数 --------# 二体问题中 a, e, i, Ω, ω 严格守恒 → 直接用初值常量填充    a_const   = a.to(u.km).value    ecc_const = ecc.value    inc_const = inc.to(u.deg).value    raan_const = raan.to(u.deg).value    argp_const = argp.to(u.deg).value    a_arr    = np.full(n_samples, a_const)    ecc_arr  = np.full(n_samples, ecc_const)    inc_arr  = np.full(n_samples, inc_const)    raan_arr = np.full(n_samples, raan_const)    argp_arr = np.full(n_samples, argp_const)    nu_arr = np.zeros(n_samples)for idx, dt in enumerate(times):# 使用 Kepler 解析传播器(纯二体,不引入数值积分误差)        orb_at_t = propagate(orb, dt, method=kepler)        nu_arr[idx] = orb_at_t.nu.to(u.deg).value# 将真近点角解包到 [0, 360) 范围,便于观察连续变化    nu_arr = np.unwrap(nu_arr, period=360.0)    time_hours = times.to(u.h).value      # 横轴用小时表示# -------- 2×3 子图绘制 --------    fig, axes = plt.subplots(2, 3, figsize=(16, 10))    fig.suptitle("ISS 无摄动轨道六根数随时间变化 (3 个轨道周期)",        fontsize=14, fontweight="bold",    )    elements = [        (axes[0, 0], time_hours, a_arr,"半长轴 $a$", "km", "C0"),        (axes[0, 1], time_hours, ecc_arr,"偏心率 $e$", "", "C1"),        (axes[0, 2], time_hours, inc_arr,"轨道倾角 $i$", "deg", "C2"),        (axes[1, 0], time_hours, raan_arr,r"升交点赤经 $\Omega$", "deg", "C3"),        (axes[1, 1], time_hours, argp_arr,r"近地点幅角 $\omega$", "deg", "C4"),        (axes[1, 2], time_hours, nu_arr,r"真近点角 $\nu$", "deg", "C5"),    ]# 为每个子图设置合理的 y 轴范围,避免 matpolotlib 自动缩放# 将微小的浮点噪声放大为可见的"波动"    y_limits = [        (a_arr[0] - 5,  a_arr[0] + 5),          # 半长轴 ±5 km        (ecc_arr[0] * 0.9, ecc_arr[0] * 1.1),    # 偏心率 ±10%        (inc_arr[0] - 0.5, inc_arr[0] + 0.5),     # 倾角 ±0.5°        (raan_arr[0] - 0.5, raan_arr[0] + 0.5),   # 升交点赤经 ±0.5°        (argp_arr[0] - 0.5, argp_arr[0] + 0.5),   # 近地点幅角 ±0.5°None,                                      # 真近点角,自动缩放    ]for (ax, x, y, ylabel, unit, color), ylim in zip(elements, y_limits):        ax.plot(x, y, color=color, linewidth=0.8)        ax.set_xlabel("时间 [h]")        ax.set_ylabel(f"{ylabel} [{unit}]"if unit else ylabel)        ax.set_title(ylabel)        ax.grid(True, alpha=0.4)if ylim isnotNone:            ax.set_ylim(ylim)    fig.tight_layout()# 保存到脚本同级目录import os    script_dir = os.path.dirname(os.path.abspath(__file__))    out_path = os.path.join(script_dir, "iss_keplerian_elements.png")    plt.savefig(out_path, dpi=150)    plt.show()    print("\n图片已保存为 iss_keplerian_elements.png")if __name__ == "__main__":    main()

运行结果:

  1. 轨道半长轴
  1. 偏心率
  1. 轨道倾角
  1. 升交点赤经
  1. 近地点幅角
  1. 真近点角

可以看到,在理想的二体运动中,除了真近点角,其它的轨道要素都是一个常量。而真近点角会随着航天器运行圈数的增加,会一直处于递增的状态,用来表示运转了很多圈。

但实际上,考虑了摄动因素之后,有些轨道元素是会随着时间发生变化的。有摄运动的轨道要素变化会在后面的章节中介绍。

最后,用一句话总结轨道六要素:

  • 轨道半长轴和偏心率:决定了轨道的大小和形状;

  • 轨道倾角、升交点赤经和近地点幅角:决定了轨道在空间中的摆放

  • 真近点角:用于描述航天器在轨道上转到哪了

最新文章

随机文章