你好,我是大象。聚焦航天轨道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,轨道越扁。
有了 a 和 e,轨道本身的大小和形状就定了。但轨道在空间里怎么「摆」?这就靠下一组。
2. 第二组:轨道在空间中的方位
这一组用三个角度来固定轨道在三维空间里的摆放姿势:轨道倾角、升交点赤经和近地点幅角。
1. 轨道倾角 —— 轨道面「斜」了多少
(Inclination)是轨道倾角,定位为航天器轨道平面与参考平面(如地球赤道面)之间的夹角。
可以把地球赤道想象成一个水平的盘子,轨道面是另一个平面——它和地面赤道之间夹了一个角,这个角就是 。
- = 0°:轨道面和赤道面重合。航天器在地球赤道正上方飞行,比如地球静止轨道卫星。
- = 90°:轨道面垂直于赤道面。航天器飞越南北极,这就是极地轨道——气象卫星、侦察卫星的最爱,因为地球自转会帮它扫过整个地球表面。
- = 180°:轨道面还是和赤道面重合,但飞行方向相反(逆行)。
因此,轨道倾角描述是两个平面之间的夹角。
2. 升交点赤经 —— 轨道从哪「钻出」赤道面
(Right Ascension of the Ascending Node, 简称 RAAN)是升交点赤经,描述了航天器从南半球穿过参考平面进入北半球的点被称为“升交点”。
为什么是穿过参考平面,而不是赤道平面呢?
因为赤道是地球的平面,如果是月球的轨道,就不是赤道平面了,所以统称为参考平面。
航天器一直飞,总会从一个半球飞到另一个半球。
当它从南半球飞到北半球、穿过赤道面的那个瞬间,它在赤道面上的那个点就叫「升交点」。
描述的就是这个升交点在赤道面上的方位——从天球上的春分点(一个固定的参考方向)开始,沿参考面向东,量到升交点为止。
生活类比:想象一个斜着转的呼啦圈。呼啦圈和地面有两个交点:一个从下往上穿(升交点),一个从上往下穿(降交点)。 告诉你这个「从下往上穿」的点在东南西北哪个方向。
3. 近地点幅角 —— 轨道的「最胖那头」朝哪
我们知道椭圆有近地点(离地球最近)和远地点(离地球最远)。但近地点指向哪个方向呢?
就是从升交点到近地点之间的角度。
3. 第三组:轨道上的位置
真近点角 f —— 航天器现在在哪
这是六根数里最简单、也最动态的一个。
在前面的五根数已经把轨道画好了之后,最后一步:航天器在这条轨道上的哪个位置?
f 就是从近地点到航天器当前位置的角度。
- f = 180°:航天器恰好在远地点,离地球最远。
- f = 90° 或 270°:航天器在半通径上,轨道高度正好等于半长轴。
可以这么理解,在钟表上,假如时针一直不动的话,秒针与时针的夹角一直在变化。这个夹角就是真近点角。
在二体问题(只考虑地球引力的理想情况)中,前五根数是常数,只有 f 随时间变化。航天器沿着这条固定轨道一直在跑,f 从 0° 跑到 360°,一圈又一圈。
看一张展示轨道六要素的图:

结合前面的概念,是不是对轨道六要素有了直观的认识?
4. 说点有用的:六根数有什么用?
轨道六根数到底有什么用?
- 火箭发射窗口计算:火箭什么时候打,打完之后进入什么轨道——轨道设计师干的就是决定这 6 个数。
- 太空交会对接:两艘飞船要碰面,它们的六根数必须匹配。不能一艘飞圆形轨道,另一艘飞扁椭圆——那样永远追不上。
- 星座设计:SpaceX 的星链计划有上万颗卫星,每一颗都有一套精心计算的六根数,保证它们不撞上彼此。
- 轨道预报:输入六根数 + 时间,就能算出未来任何时刻卫星的位置。
5. 六根数的局限
任何好用的工具都有边界。六根数也不是万能药:
- 只适用于二体问题:真实空间中,地球不是完美球体,还有大气阻力、日月引力——这些「摄动」会让轨道悄悄变形。六根数描述的「完美椭圆」只存在于理想世界中。
摄动力可以类比我们要做一件事情,过程一定会遇到各种干扰:手机来了条消息、口渴了等等,这些干扰因素就是轨道的摄动,让轨道的轨迹不会按照着理想的情况传播。
i=0 或 180° 时 无定义:轨道面和赤道面重合时,没有「升交点」这回事。
实际航天任务怎么做?:高精度任务用「密切轨道根数」(随时间变化的六根数),或者直接用笛卡尔坐标做数值积分。六根数更多用于概念理解、初步设计和粗略预报。
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()
运行结果:






可以看到,在理想的二体运动中,除了真近点角,其它的轨道要素都是一个常量。而真近点角会随着航天器运行圈数的增加,会一直处于递增的状态,用来表示运转了很多圈。
但实际上,考虑了摄动因素之后,有些轨道元素是会随着时间发生变化的。有摄运动的轨道要素变化会在后面的章节中介绍。
最后,用一句话总结轨道六要素:
轨道倾角、升交点赤经和近地点幅角:决定了轨道在空间中的摆放