e2m2e.algorithm package

算法层:领域知识构造问题的编排。

第 3 层,依赖方向:data/ + _integrators(Rust)。不 import api/、不 import tools/(ADR 0012)。

Python 算法层 = 一切"需要领域知识构造问题"的编排,不做数值迭代(迭代在 Rust solver/):①构造问题(选轨道族、定约束、选流形方向)②调 Rust 迭代器 ③解释结果。

子模块: - design/:任务轨道设计(三段编排:family → 星历修正[Rust 打靶] → propagation)。 - family/:轨道族生成(种子/初猜/族行走/注册表)。 - station_keeping/:轨道保持(controller + 三控制律 + 误差模型 + 蒙特卡洛)。 - transfer/:转移设计(transfer_orbit 编排器 + 数学模块)。 - dynamics/:System + Dynamics。 - forces/:力模型类(ForceModel/PhysicalModel 子类/推力)。 - propagation.py:轨道预报薄壳。 - coordinate/:坐标转换算法。 - manifold/:不变流形 + 庞加莱截面。 - proximity/:相对运动。 - stability.py:稳定性。 - normal_form/:正规化(可选依赖)。 - nominal_orbit/:名义轨道。

实现状态:骨架。模块逐个实现/迁入中,未实现能力占位函数抛 NotImplementedError

顶层模块

e2m2e.algorithm.propagation module

轨道预报:给定初值与力模型的高精度数值外推。

单段能力(不建独立编排器,ADR 0011):配 ForceModel + 调 propagate + 输出 EphemerisTable。单文件模块(不是目录)。

class e2m2e.algorithm.propagation.PropagationResult(ephemeris, status, cause, message)[源代码]

基类:object

一次轨道预报任务的结果。

参数:
ephemeris: EphemerisTable
status: ConvergenceState
cause: FailureCause
message: str
e2m2e.algorithm.propagation.propagate_orbit(initial_state, epoch, duration, force_config=None, output_step=3600.0, **kwargs)[源代码]

高精度轨道预报。

配 ForceModel 并传播,输出通用星历表容器(UTC + GCRS 位置/速度)。

参数:
  • initial_state (Any) -- 初值(GCRS,km, km/s,形状 (6,))。

  • epoch (Any) -- 起始历元 UTC(ISO 字符串或 [年,月,日,时,分,秒])。

  • duration (float) -- 预报时长(秒)。

  • force_config (dict[str, Any] | None) -- 力模型配置(缺省用默认三体力模型)。

  • output_step (float) -- 输出间隔(秒)。

  • kwargs -- 传给 ForceModel 的额外配置(如 system/spice 等)。

返回:

含星历与最终状态三元组的预报结果。

抛出:

ValueError -- 初值形状或时长非法。

返回类型:

PropagationResult

e2m2e.algorithm.results module

算法结果的统一最终状态契约。

class e2m2e.algorithm.results.ResultStatus(status, cause, message)[源代码]

基类:object

同步算法结果共享的最终状态三元组。

参数:
status: ConvergenceState
cause: FailureCause
message: str
class e2m2e.algorithm.results.CandidateSearchResult(candidates, status, cause, message)[源代码]

基类:Sequence[CandidateT], Generic[CandidateT]

候选网格搜索的最终结果。

保持序列读取接口,使既有调用方可继续迭代、索引和取长度;搜索是否 完成及空结果的原因则由统一状态三元组明确表达。

参数:
candidates: tuple[CandidateT, ...]
status: ConvergenceState
cause: FailureCause
message: str
e2m2e.algorithm.results.scipy_slsqp_status(success, code)[源代码]

把 SciPy SLSQP 的原生结束码翻译为领域状态。

参数:
返回类型:

tuple[ConvergenceState, FailureCause]

class e2m2e.algorithm.results.DifferentialCorrectionResult(status, cause, message, orbit, iterations, residual, residual_history=())[源代码]

基类:object

微分修正结果,软失败时可保留近似轨道。

参数:
status: ConvergenceState
cause: FailureCause
message: str
orbit: Orbit | None
iterations: int
residual: float | None
residual_history: tuple[float, ...] = ()
class e2m2e.algorithm.results.ContinuationResult(status, cause, message, family, steps, step_size)[源代码]

基类:object

延拓结果,失败时仍可携带已生成的部分轨道族。

参数:
status: ConvergenceState
cause: FailureCause
message: str
family: OrbitFamily
steps: int
step_size: float
class e2m2e.algorithm.results.FamilyGenerationResult(status, cause, message, family, requested_members, generated_members)[源代码]

基类:object

多族生成结果;软失败时保留已生成的部分轨道族。

参数:
status: ConvergenceState
cause: FailureCause
message: str
family: OrbitFamily
requested_members: int
generated_members: int
class e2m2e.algorithm.results.TransferCandidateResult(status, cause, message, departure_state=None, departure_time=0.0, alpha=0.0, transfer_trajectory=None, transfer_times=None, transfer_time=None, min_distance=inf, min_distance_idx=None, min_distance_orbit_idx=None, dv_departure=0.0, dv_insertion=None, intersection_found=False, intersection_point=None, intersection_idx=None, first_intersection_idx=None, first_intersection_time=None, first_min_distance_idx=None, first_min_distance_time=None, local_minimum_found=False, local_minimum_distance=inf, local_minimum_idx=None, collision_found=False, collision_body=None, collision_idx=None, departure_orbit_name=None, arrival_orbit_name=None, departure_time_index=None)[源代码]

基类:object

转移搜索单格的类型化候选评估。

承载搜索阶段对单个 (departure, alpha) 候选的全部几何与可行性信息。 替代历史裸字典(ADR 0024);get/__getitem__ 提供对字典风格 消费方的兼容读取。

参数:
  • status (ConvergenceState)

  • cause (FailureCause)

  • message (str)

  • departure_state (ndarray | None)

  • departure_time (float)

  • alpha (float)

  • transfer_trajectory (Any | None)

  • transfer_times (Any | None)

  • transfer_time (float | None)

  • min_distance (float)

  • min_distance_idx (int | None)

  • min_distance_orbit_idx (int | None)

  • dv_departure (float)

  • dv_insertion (float | None)

  • intersection_found (bool)

  • intersection_point (Any | None)

  • intersection_idx (int | None)

  • first_intersection_idx (int | None)

  • first_intersection_time (float | None)

  • first_min_distance_idx (int | None)

  • first_min_distance_time (float | None)

  • local_minimum_found (bool)

  • local_minimum_distance (float)

  • local_minimum_idx (int | None)

  • collision_found (bool)

  • collision_body (str | None)

  • collision_idx (int | None)

  • departure_orbit_name (str | None)

  • arrival_orbit_name (str | None)

  • departure_time_index (int | None)

status: ConvergenceState
cause: FailureCause
message: str
departure_state: ndarray | None = None
departure_time: float = 0.0
alpha: float = 0.0
transfer_trajectory: Any | None = None
transfer_times: Any | None = None
transfer_time: float | None = None
min_distance: float = inf
min_distance_idx: int | None = None
min_distance_orbit_idx: int | None = None
dv_departure: float = 0.0
dv_insertion: float | None = None
intersection_found: bool = False
intersection_point: Any | None = None
intersection_idx: int | None = None
first_intersection_idx: int | None = None
first_intersection_time: float | None = None
first_min_distance_idx: int | None = None
first_min_distance_time: float | None = None
local_minimum_found: bool = False
local_minimum_distance: float = inf
local_minimum_idx: int | None = None
collision_found: bool = False
collision_body: str | None = None
collision_idx: int | None = None
departure_orbit_name: str | None = None
arrival_orbit_name: str | None = None
departure_time_index: int | None = None
get(key, default=None)[源代码]

字典风格读取兼容。

参数:
返回类型:

Any

class e2m2e.algorithm.results.StageRecord(name, applicable, executed, result_status, message='')[源代码]

基类:object

任务可选阶段的适用性与执行记录。

参数:
name: str
applicable: bool
executed: bool
result_status: ConvergenceState | None
message: str = ''
class e2m2e.algorithm.results.EphemerisCorrectionResult(status, cause, message, iterations, max_residual, residual_history, t_patch, state_patch, velocity_residual=None, velocity_residual_history=None)[源代码]

基类:object

星历修正统一结果(Rust 多重打靶结果的领域重包)。

变量:
参数:
status: ConvergenceState
cause: FailureCause
message: str
iterations: int
max_residual: float
residual_history: list[float]
t_patch: ndarray
state_patch: ndarray
velocity_residual: float | None = None
velocity_residual_history: list[float] | None = None

e2m2e.algorithm.stability module

稳定性分析模块

提供轨道稳定性分析功能,包括单值矩阵计算、Floquet乘子分析、分岔检测等。

class e2m2e.algorithm.stability.StabilityType(*values)[源代码]

基类:Enum

稳定性类型枚举

STABLE = 'stable'
UNSTABLE = 'unstable'
MARGINALLY_STABLE = 'marginally_stable'
HYPERBOLIC = 'hyperbolic'
ELLIPTIC = 'elliptic'
PARABOLIC = 'parabolic'
class e2m2e.algorithm.stability.BifurcationType(*values)[源代码]

基类:Enum

分岔类型枚举

NONE = 'none'
PERIOD_DOUBLING = 'period_doubling'
SADDLE_NODE = 'saddle_node'
TORUS = 'torus'
PITCHFORK = 'pitchfork'
TRANSCRITICAL = 'transcritical'
SECONDARY_HOPF = 'secondary_hopf'
class e2m2e.algorithm.stability.OrbitStability(monodromy_matrix, eigenvalues, stability_indices, classification, bifurcation, numerical_errors)[源代码]

基类:object

轨道稳定性分析结果。

StabilityAnalysis.analyze() 返回的结果容器,包含单值矩阵、 Floquet 乘子、稳定性指数、分类与分岔信息。

变量:
  • monodromy_matrix (numpy.ndarray | None) -- 单值矩阵,形状 (6, 6)

  • eigenvalues (numpy.ndarray | None) -- 单值矩阵特征值数组

  • stability_indices (dict[str, float | None]) -- 稳定性指数字典

  • classification (dict[str, Any]) -- 稳定性分类结果

  • bifurcation (dict[str, Any]) -- 分岔分析结果

  • numerical_errors (dict[str, float | None]) -- 数值误差估计

参数:
monodromy_matrix: ndarray | None
eigenvalues: ndarray | None
stability_indices: dict[str, float | None]
classification: dict[str, Any]
bifurcation: dict[str, Any]
numerical_errors: dict[str, float | None]
class e2m2e.algorithm.stability.StabilityAnalysis(orbit, dynamics=None)[源代码]

基类:object

轨道稳定性分析

计算轨道的单值矩阵、Floquet乘子、稳定性指数等, 并进行稳定性分类和分岔检测。

变量:
  • orbit -- Orbit对象

  • dynamic -- CR3BP_Dynamics对象

  • monodromy_matrix -- 单值矩阵

  • eigenvalues -- 特征值

  • stability_indices -- 稳定性指数

参数:
STABILITY_THRESHOLD = 1e-06
BIFURCATION_TOLERANCE = 1e-08
__init__(orbit, dynamics=None)[源代码]

初始化分析器

参数:
  • orbit (Orbit) -- Orbit对象

  • dynamics (CR3BP_Dynamics | None) -- CR3BP_Dynamics对象(可选,如果orbit关联了system则自动创建)

返回类型:

None

monodromy_matrix: ndarray | None
stm_history: list[ndarray]
eigenvalues: ndarray | None
eigenvalue_pairs: list[tuple[complex, complex]]
stability_indices: dict[str, float | None]
lyapunov_exponents: list[float] | ndarray
numerical_errors: dict[str, float | None]
compute_monodromy()[源代码]

计算单值矩阵

通过积分一个完整周期的状态转移矩阵获得单值矩阵。

返回:

6x6 单值矩阵

返回类型:

np.ndarray

compute_floquet_multipliers()[源代码]

计算Floquet乘子(特征值)

返回:

Floquet乘子

返回类型:

np.ndarray

compute_stability_index()[源代码]

计算稳定性指数

Broucke稳定性参数定义为:ν = λ + 1/λ, 其中λ是单值矩阵的特征值。

返回:

稳定性指数字典

返回类型:

dict

classify_orbit()[源代码]

对轨道进行稳定性分类

返回:

稳定性分类结果

返回类型:

dict

analyze_bifurcation()[源代码]

分析分岔类型

通过检查单值矩阵特征值的分布判断是否存在分岔。

返回:

分岔分析结果

返回类型:

dict

analyze()[源代码]

执行完整稳定性分析并返回不可变结果对象。

返回:

包含单值矩阵、特征值、稳定性指数、 分类、分岔与数值误差的独立结果对象。

返回类型:

OrbitStability

full_analysis()[源代码]

执行完整的稳定性分析

返回:

完整分析结果

返回类型:

dict

static detect_bifurcation_in_family(orbits, dynamics, tolerance=1e-08)[源代码]

检测轨道族中的分岔点

遍历轨道族中的每条轨道,计算其单值矩阵特征值, 检测是否有特征值接近 +1(切分岔/saddle-node bifurcation)。

参数:
  • orbits (list[Orbit]) -- Orbit 对象列表(轨道族)。

  • dynamics (CR3BP_Dynamics) -- CR3BP_Dynamics 对象。

  • tolerance (float) -- 特征值接近 +1 的容差,默认 1e-8。

返回:

分岔点列表,每个元素为字典,包含键 orbit_index(族内索引)、 orbit、eigenvalues、eigenvalue_diff(特征值 λ 与 1 之差的绝对值)、 bifurcation_type。

返回类型:

list[dict[str, Any]]

static find_nearest_bifurcation(orbits, dynamics, target_x0=None, tolerance=0.0001)[源代码]

在轨道族中找到最接近目标参数的分岔点

参数:
  • orbits (list[Orbit]) -- Orbit对象列表

  • dynamics (CR3BP_Dynamics) -- CR3BP_Dynamics对象

  • target_x0 (float | None) -- 目标x0坐标(可选)

  • tolerance (float) -- 搜索容差

返回:

分岔点字典,如果未找到则返回None

返回类型:

dict[str, Any] | None

e2m2e.algorithm.coordinate package

坐标转换算法:IAU2006/synodic↔J2000/GCRS↔EBCRS。

转换**算法** 归这里(ADR 0011 迁移,源:core/coordinate/), data/frames/ 只留数据(EOP/闰秒/历表句柄,ADR 0015)。强化现有 Axes/Origin/CoordinateSystem 抽象(不新增 Frame 抽象):所有坐标系表达 为 Axes + Origin + CoordinateSystem,时空间联合转换作为 CoordinateSystem 扩展方法。转换算法最终留 Python,Rust 下沉是后续性能优化。

e2m2e.algorithm.coordinate.axes module

坐标轴抽象基类。

class e2m2e.algorithm.coordinate.axes.Axes[源代码]

基类:ABC

坐标轴抽象基类。

rotation_matrix(et) 返回的矩阵 R 满足 r_icrf = R @ r_axesrotation_and_rate(et) 返回 (R, Rdot),满足 v_icrf = R @ v_axes + Rdot @ r_axes

abstractmethod rotation_matrix(et)[源代码]

返回从该坐标轴到 ICRF/J2000 的 3x3 旋转矩阵。

参数:

et (float)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

rotation_and_rate(et)[源代码]

返回从该坐标轴到 ICRF/J2000 的旋转矩阵及其时间导数。

子类可覆盖该方法提供解析或内核给出的 Rdot。若旧子类只覆盖 angular_velocity,默认实现会按兼容角速度语义构造 Rdot。 否则使用中心差分作为通用路径。

参数:

et (float)

返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]]

state_transform_matrix(et)[源代码]

返回 6x6 状态变换矩阵。

参数:

et (float)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

angular_velocity(et)[源代码]

返回 ICRF 中观测到的该坐标轴角速度。

这是兼容 API;高精度状态转换优先使用 rotation_and_rate

参数:

et (float)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.coordinate.origin module

坐标原点抽象基类。

定义参考坐标系位置基准的抽象接口。具体子类(如天体中心、航天器位置) 通过 state 方法给出该原点在 ICRF 中的绝对状态。

class e2m2e.algorithm.coordinate.origin.Origin[源代码]

基类:ABC

坐标原点抽象基类。

描述一个参考坐标系的位置基准。子类必须实现 state,返回该原点 在 ICRF 中的绝对六维状态 [r, v]

对于相对 ICRF 没有平移的原点(例如太阳系质心),返回零向量即可。

abstractmethod state(et)[源代码]

返回该原点在 ICRF 中的绝对状态。

参数:

et (float) -- SPICE 历书时(秒)。

返回:

长度为 6 的数组,前 3 个元素为位置(km),后 3 个为速度(km/s)。

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.coordinate.coordinate_system module

坐标系组合与转换。

class e2m2e.algorithm.coordinate.coordinate_system.CoordinateSystem(axes, origin)[源代码]

基类:object

由坐标轴和原点组成的参考系。

构造后即视为只读约定:调用方不应在运行时换 axes / origin 组件。运行时偷换的防护不在应用层(篡改防护由 GitHub 代码来源验证承担), 代码风格的静态守门员由 test_coordinate_immutability.py 覆盖。

参数:
transform_vector(vec, from_cs, to_cs, et)[源代码]

将三维向量从 from_cs 转换到 to_cs

参数:
返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

transform_state(state, from_cs, to_cs, et)[源代码]

将六维状态从 from_cs 转换到 to_cs

坐标轴约定为 r_icrf = R @ r_axes,速度使用 v_icrf = R @ v_axes + Rdot @ r_axes

参数:
返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.coordinate.dynamic_axes module

动态坐标轴抽象基类。

class e2m2e.algorithm.coordinate.dynamic_axes.DynamicAxes[源代码]

基类:Axes, ABC

动态坐标轴抽象基类。

依赖外部状态(位置、速度)的坐标轴。子类须先调用 update(t, state) 后,再使用 rotation_matrix(et)rotation_and_rate(et)

rotation_and_rate 沿用 Axes 基类的中心差分默认实现。

abstractmethod update(t, state)[源代码]

更新坐标轴的内部状态。

参数:
  • t (float) -- 历元(秒,自 J2000)。

  • state (ndarray) -- 6 元素状态向量 [r, v](ICRF)。

返回类型:

None

rotation_matrix(et)[源代码]

返回从该坐标轴到 ICRF/J2000 的 3x3 旋转矩阵。

参数:

et (float)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

rotation_and_rate(et)[源代码]

返回从该坐标轴到 ICRF/J2000 的旋转矩阵及其时间导数。

子类可覆盖该方法提供解析或内核给出的 Rdot。若旧子类只覆盖 angular_velocity,默认实现会按兼容角速度语义构造 Rdot。 否则使用中心差分作为通用路径。

参数:

et (float)

返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]]

e2m2e.algorithm.coordinate.standard_axes module

常用坐标轴实现。

class e2m2e.algorithm.coordinate.standard_axes.ICRSAxes[源代码]

基类:Axes

国际天球参考系(ICRF)坐标轴。

rotation_matrix(et)[源代码]

返回从该坐标轴到 ICRF/J2000 的 3x3 旋转矩阵。

参数:

et (float)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

rotation_and_rate(et)[源代码]

返回从该坐标轴到 ICRF/J2000 的旋转矩阵及其时间导数。

子类可覆盖该方法提供解析或内核给出的 Rdot。若旧子类只覆盖 angular_velocity,默认实现会按兼容角速度语义构造 Rdot。 否则使用中心差分作为通用路径。

参数:

et (float)

返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]]

class e2m2e.algorithm.coordinate.standard_axes.IAU2000EqAxes(time_step=1.0)[源代码]

基类:Axes

基于简化 IAU 2000/2006 岁差章动模型的近似惯性轴。

参数:

time_step (float)

rotation_matrix(et)[源代码]

返回从该坐标轴到 ICRF/J2000 的 3x3 旋转矩阵。

参数:

et (float)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

class e2m2e.algorithm.coordinate.standard_axes.ITRFSpiceAxes(frame='ITRF93')[源代码]

基类:Axes

SPICE-backed 高精度 ITRF 坐标轴,默认使用 ITRF93

参数:

frame (str)

property frame: str
rotation_matrix(et)[源代码]

返回从该坐标轴到 ICRF/J2000 的 3x3 旋转矩阵。

参数:

et (float)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

rotation_and_rate(et)[源代码]

返回从该坐标轴到 ICRF/J2000 的旋转矩阵及其时间导数。

子类可覆盖该方法提供解析或内核给出的 Rdot。若旧子类只覆盖 angular_velocity,默认实现会按兼容角速度语义构造 Rdot。 否则使用中心差分作为通用路径。

参数:

et (float)

返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]]

class e2m2e.algorithm.coordinate.standard_axes.ITRFAxes(frame='ITRF93')[源代码]

基类:ITRFSpiceAxes

向后兼容别名:默认精确 ITRF 为 SPICE-backed ITRF93

参数:

frame (str)

class e2m2e.algorithm.coordinate.standard_axes.GMATITRFAxes(*, tai_utc_path=None, eop_path=None, xys_provider=None, eop_extrapolation='raise')[源代码]

基类:Axes

显式 opt-in 的第一阶段 GMAT-compatible ITRF 坐标轴。

参数:
  • tai_utc_path (str | Path | None)

  • eop_path (str | Path | None)

  • xys_provider (XysProvider | None)

  • eop_extrapolation (str)

rotation_matrix(et)[源代码]

返回从该坐标轴到 ICRF/J2000 的 3x3 旋转矩阵。

参数:

et (float)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

rotation_and_rate(et)[源代码]

返回从该坐标轴到 ICRF/J2000 的旋转矩阵及其时间导数。

子类可覆盖该方法提供解析或内核给出的 Rdot。若旧子类只覆盖 angular_velocity,默认实现会按兼容角速度语义构造 Rdot。 否则使用中心差分作为通用路径。

参数:

et (float)

返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]]

class e2m2e.algorithm.coordinate.standard_axes.ITRFApproxAxes(time_step=1.0)[源代码]

基类:Axes

低精度/教学用途的近似 ITRF 坐标轴。

参数:

time_step (float)

rotation_matrix(et)[源代码]

返回从该坐标轴到 ICRF/J2000 的 3x3 旋转矩阵。

参数:

et (float)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.coordinate.standard_axes.standard_itrf()[源代码]

返回公共默认 ITRF:SPICE-backed ITRF93

返回类型:

ITRFSpiceAxes

e2m2e.algorithm.coordinate.standard_axes.standard_icrf()[源代码]

返回 ICRF 标准坐标系预设。

ICRF = ICRSAxes(恒等旋转,与 ICRF/J2000 同向)+ InertialOrigin(太阳系 质心,无平移)。这是地心 ITRF 转换的惯性别,常作为 CoordinateSystem 组合的一端。

standard_itrf 不同,这里直接返回完整 CoordinateSystem—— ICRF 预设在调用方通常直接用作转换源/目标,不需再自行拼 Axes + Origin。

返回类型:

CoordinateSystem

e2m2e.algorithm.coordinate.standard_dynamic_axes module

常用动态坐标轴实现。

  • VNBAxes: 速度-法向-副法向(VNB)坐标轴

  • LVLHAxes: 本地垂直本地水平(LVLH)坐标轴

class e2m2e.algorithm.coordinate.standard_dynamic_axes.VNBAxes[源代码]

基类:DynamicAxes

速度-法向-副法向(VNB)坐标轴。

V = 速度方向(归一化),N = 角动量方向(r × v,归一化), B = V × N(归一化)。旋转矩阵 R = [v_hat, n_hat, b_hat]^T, 即 R 的第 0 列为 v_hat,第 1 列为 n_hat,第 2 列为 b_hat。

抛出:

ValueError -- 零速度(|v| < VELOCITY_NORM_MIN)或零角动量 (|r×v| < ANGULAR_MOMENTUM_NORM_MIN,即 r ∥ v 或 r=0)时 轴向奇异(ADR 0007 补白 / ADR 0020 决策 5:退化态显式失败, 不静默);异常信息含实测范数与阈值。

update(t, state)[源代码]

更新坐标轴的内部状态。

参数:
  • t (float) -- 历元(秒,自 J2000)。

  • state (ndarray) -- 6 元素状态向量 [r, v](ICRF)。

返回类型:

None

class e2m2e.algorithm.coordinate.standard_dynamic_axes.LVLHAxes[源代码]

基类:DynamicAxes

本地垂直本地水平(LVLH)坐标轴。

R = 径向(r 归一化),H = 角动量方向(r × v,归一化), V = H × R(归一化)。旋转矩阵 R = [r_hat, v_hat, h_hat]^T, 即 R 的第 0 列为 r_hat,第 1 列为 v_hat,第 2 列为 h_hat。

抛出:

ValueError -- 零位置(|r| < POSITION_NORM_MIN)或零角动量 (|r×v| < ANGULAR_MOMENTUM_NORM_MIN,即 r ∥ v)时 轴向奇异(ADR 0007 补白 / ADR 0020 决策 5:退化态显式失败, 不静默);异常信息含实测范数与阈值。

update(t, state)[源代码]

更新坐标轴的内部状态。

参数:
  • t (float) -- 历元(秒,自 J2000)。

  • state (ndarray) -- 6 元素状态向量 [r, v](ICRF)。

返回类型:

None

e2m2e.algorithm.coordinate.standard_origins module

常用坐标原点实现。

提供基于 SPICE 的天体中心原点等标准原点实现。

class e2m2e.algorithm.coordinate.standard_origins.CelestialBodyOrigin(body, spice)[源代码]

基类:Origin

天体中心原点。

表示某一大天体(如地球、月球、太阳)的中心,其在 ICRF 中的绝对状态 通过 SPICE 实时查询。

参数:
__init__(body, spice)[源代码]

初始化天体中心原点。

参数:
  • body (str) -- 天体名称,如 'EARTH''MOON''SUN'

  • spice (SPICEManager) -- SPICE 管理器实例,用于查询天体状态。

返回类型:

None

property body: str

天体名称(大写)。

state(et)[源代码]

返回该天体中心在 ICRF 中的绝对状态。

参数:

et (float) -- SPICE 历书时(秒)。

返回:

长度为 6 的数组,前 3 个元素为位置(km),后 3 个为速度(km/s)。

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

class e2m2e.algorithm.coordinate.standard_origins.InertialOrigin[源代码]

基类:Origin

惯性原点。

表示 ICRF 原点本身,相对 ICRF 无平移。

state(et)[源代码]

返回零状态。

参数:

et (float)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.coordinate.synodic_axes module

由 SPICE 月球瞬时状态驱动的会合(synodic)坐标轴。

该轴在 ICRF/J2000 下的基向量由 spice.get_body_state("MOON", et, "J2000", "EARTH") 实时确定: - e1:地月连线方向(指向月球) - e3:瞬时轨道角动量方向 - e2:右手系补齐

约定 r_icrf = R @ r_axesR = column_stack([e1, e2, e3])

class e2m2e.algorithm.coordinate.synodic_axes.SynodicAxes(spice, cache_capacity=256)[源代码]

基类:Axes

SPICE 驱动的会合旋转坐标轴。

参数:

cache_capacity (int)

rotation_matrix(et)[源代码]

返回从该坐标轴到 ICRF/J2000 的 3x3 旋转矩阵。

参数:

et (float)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

rotation_and_rate(et)[源代码]

返回从该坐标轴到 ICRF/J2000 的旋转矩阵及其时间导数。

子类可覆盖该方法提供解析或内核给出的 Rdot。若旧子类只覆盖 angular_velocity,默认实现会按兼容角速度语义构造 Rdot。 否则使用中心差分作为通用路径。

参数:

et (float)

返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]]

characteristic_length(et)[源代码]

返回当前时刻的地月距离 (km)。

参数:

et (float)

返回类型:

float

e2m2e.algorithm.coordinate.synodic_j2000 module

基于 CoordinateSystem 的 synodic ↔ J2000 转换器。

synodic 坐标系 = (SynodicAxes, CelestialBodyOrigin("EARTH")) J2000 坐标系 = (ICRSAxes, CelestialBodyOrigin("EARTH"))

二者原点相同 (地心) 因此 CoordinateSystem.transform_state 仅旋转轴向; 无量纲 synodic 状态在调用前后通过 l_c / t_c 量纲化与无量纲化。

class e2m2e.algorithm.coordinate.synodic_j2000.SynodicJ2000System(cr3bp_system, spice)[源代码]

基类:object

基于 CoordinateSystem 的 synodic ↔ J2000 转换器。

参数:

cr3bp_system (CR3BP_System)

synodic_to_j2000(state_syn, t_syn, et0)[源代码]
参数:
返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

j2000_to_synodic(state_j2000, t_syn, et0)[源代码]
参数:
  • state_j2000 (ArrayLike)

  • t_syn (float)

  • et0 (float)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

batch_synodic_to_j2000(states_syn, t_syn_arr, et0)[源代码]

批量 synodic→J2000(下沉 Rust,逐位对齐逐点版)。

参数:
  • states_syn (ArrayLike)

  • t_syn_arr (ArrayLike)

  • et0 (float)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

batch_j2000_to_synodic(states_j2000, t_syn_arr, et0)[源代码]

批量 J2000→synodic(下沉 Rust,逐位对齐逐点版)。

参数:
  • states_j2000 (ArrayLike)

  • t_syn_arr (ArrayLike)

  • et0 (float)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.coordinate.gcrs_ebcrs module

TDT+GCRS ↔ TDB+EBCRS 时空坐标转换(r2s2 后端)。

TDT 是 TT(地球时)的旧称;EBCRS 是地月质心天球参考系,轴向与 BCRS/ICRS 一致,原点在地月质心。

r2s2 直接覆盖 (TT, GCRS 地心位置) ↔ (TDB, BCRS 太阳系质心位置) 的相对论 时空转换(TT2TDB / TDB2TT)。EBCRS 与 BCRS 只差原点平移,本模块用 同一历表中的地月质心位置补上这一缺口:x_ebcrs = xs - x_emb(t)

历表要求:必须含内置时间星历(TT−TDB),推荐 JPL de440t.bsp (注意带 t 后缀的变体);INPOP21a 的 spice 格式历表对(主文件 + *_time.bsp)可作为路径列表传入。普通的 de440s.bsp/de440.bsp 不含时间星历,会在构造时报错;INPOP 原生格式(.dat)主文件与时间星历 分属两个文件,calceph 不支持多开,不可用。

class e2m2e.algorithm.coordinate.gcrs_ebcrs.GCRSEBCRSSystem(ephemeris_path)[源代码]

基类:object

TDT+GCRS ↔ TDB+EBCRS 时空坐标转换器。

转换同时作用于时间与空间:输入输出均为 (儒略日, 位置三元组 km), 时间尺度随方向在 TT(TDT)与 TDB 之间切换。r2s2 只转换位置,速度不在 转换范围内。

参数:

ephemeris_path (str | os.PathLike | list[str]) -- 含内置时间星历的行星历表路径(如 de440t.bsp), 或路径列表(如 INPOP 主文件 + 时间星历文件)。

备注

r2s2 的历表句柄是进程级全局状态(R2S2.init_E),用不同历表 构造多个实例会互相覆盖,后构造者生效。

gcrs_to_ebcrs(jd_tt, position_gcrs)[源代码]

(TDT/TT 儒略日, GCRS 地心位置 km) → (TDB 儒略日, EBCRS 位置 km)。

参数:
  • jd_tt (float)

  • position_gcrs (ArrayLike)

返回类型:

tuple[float, ndarray[tuple[Any, ...], dtype[floating]]]

ebcrs_to_gcrs(jd_tdb, position_ebcrs)[源代码]

(TDB 儒略日, EBCRS 位置 km) → (TDT/TT 儒略日, GCRS 地心位置 km)。

参数:
  • jd_tdb (float)

  • position_ebcrs (ArrayLike)

返回类型:

tuple[float, ndarray[tuple[Any, ...], dtype[floating]]]

e2m2e.algorithm.coordinate.gmat_itrf module

GMAT 风格 ITRF reduction stages。

e2m2e.algorithm.coordinate.gmat_itrf.rotation1(angle)[源代码]
参数:

angle (float)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.coordinate.gmat_itrf.rotation2(angle)[源代码]
参数:

angle (float)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.coordinate.gmat_itrf.rotation3(angle)[源代码]
参数:

angle (float)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.coordinate.gmat_itrf.skew(vector)[源代码]
参数:

vector (ArrayLike)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.coordinate.gmat_itrf.celestial_intermediate_matrix(x, y, s)[源代码]
参数:
返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

class e2m2e.algorithm.coordinate.gmat_itrf.GmatItrfReduction(time_converter, eop, xys_provider, *, eop_extrapolation='raise')[源代码]

基类:object

GMAT 现代 ITRF reduction 的 first-phase Python 实现。

参数:
eop_sample_for_et(et)[源代码]
参数:

et (float)

返回类型:

EopSample

rotation_and_rate(et)[源代码]
参数:

et (float)

返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]]

e2m2e.algorithm.coordinate.gmat_time module

GMAT 兼容时间转换。

class e2m2e.algorithm.coordinate.gmat_time.TimeSystemConverter(tai_utc)[源代码]

基类:object

保持公共 ET 秒输入,同时提供 GMAT 低层时间量。

参数:

tai_utc (TaiUtcTable)

utc_mjd_to_tai_mjd(utc_mjd)[源代码]
参数:

utc_mjd (float)

返回类型:

float

tai_mjd_to_utc_mjd(tai_mjd)[源代码]
参数:

tai_mjd (float)

返回类型:

float

utc_mjd_to_tt_mjd(utc_mjd)[源代码]
参数:

utc_mjd (float)

返回类型:

float

tai_mjd_to_a1_mjd(tai_mjd)[源代码]
参数:

tai_mjd (float)

返回类型:

float

a1_mjd_to_tai_mjd(a1_mjd)[源代码]
参数:

a1_mjd (float)

返回类型:

float

utc_mjd_to_a1_mjd(utc_mjd)[源代码]
参数:

utc_mjd (float)

返回类型:

float

a1_mjd_to_utc_mjd(a1_mjd)[源代码]
参数:

a1_mjd (float)

返回类型:

float

a1_mjd_to_tt_mjd(a1_mjd)[源代码]
参数:

a1_mjd (float)

返回类型:

float

et_to_tdb_mjd(et)[源代码]
参数:

et (float)

返回类型:

float

et_to_tt_mjd(et)[源代码]
参数:

et (float)

返回类型:

float

et_to_utc_mjd(et)[源代码]
参数:

et (float)

返回类型:

float

et_to_a1_mjd(et)[源代码]
参数:

et (float)

返回类型:

float

e2m2e.algorithm.coordinate.iau_2006 module

IAU 2006 简化地球定向参数计算。

提供岁差矩阵与章动矩阵的纯 Python 实现,不依赖外部 EOP 文件。 本模块使用 IAU 2006 简化理论,适合教学、快速验证以及无 SPICE 内核 场景下的近似地固系计算。

参考

  • IAU 2006 Precession-Nutation Model (Capitaine et al. 2003)

  • Explanatory Supplement to the Astronomical Almanac, 3rd edition

  • NASA NAIF SPICE Toolkit 文档中的 pxformiau2000 说明

e2m2e.algorithm.coordinate.iau_2006.precession_angles(t)[源代码]

计算 IAU 2006 岁差角。

参数:

t (float) -- 从 J2000.0 起算的儒略世纪数。

返回:

三元组 (zeta_A, theta_A, z_A),单位为弧度。 满足岁差矩阵 P = R3(-z_A) @ R2(theta_A) @ R3(-zeta_A)

返回类型:

tuple[float, float, float]

e2m2e.algorithm.coordinate.iau_2006.precession_matrix(t)[源代码]

计算 IAU 2006 岁差矩阵 P(t)。

参数:

t (float) -- 从 J2000.0 起算的儒略世纪数。

返回:

3x3 岁差矩阵,满足 r_J2000 = P @ r_mean_equator

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.coordinate.iau_2006.mean_obliquity(t)[源代码]

计算 J2000.0 平黄赤交角 epsilon_0。

参数:

t (float) -- 从 J2000.0 起算的儒略世纪数。

返回:

平黄赤交角,单位为弧度。

返回类型:

float

e2m2e.algorithm.coordinate.iau_2006.nutation_angles(t)[源代码]

计算 IAU 2000A 简化章动角。

本实现仅包含最大项(黄经章动 psi 与交角章动 epsilon 的主项), 精度约为 0.1 角秒量级。对于更高精度需求,应使用 SPICE 内核。

参数:

t (float) -- 从 J2000.0 起算的儒略世纪数。

返回:

三元组 (dpsi, deps, eps0),分别为黄经章动、交角章动和平黄赤 交角,单位均为弧度。

返回类型:

tuple[float, float, float]

e2m2e.algorithm.coordinate.iau_2006.nutation_matrix(t)[源代码]

计算章动矩阵 N(t)。

参数:

t (float) -- 从 J2000.0 起算的儒略世纪数。

返回:

3x3 章动矩阵,满足 r_true_equator = N @ r_J2000

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.coordinate.iau_2006.iau2000eq_matrix(et)[源代码]

计算从 IAU2000Eq 平赤道/平春分点到 ICRF/J2000 的旋转矩阵。

该矩阵仅包含岁差效应:R = P。平赤道/平春分点系不包含章动。

参数:

et (float) -- SPICE 历书时(秒)。

返回:

3x3 旋转矩阵,满足 r_ICRF = R @ r_IAU2000Eq

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.coordinate.iau_2006.iau2000eq_true_matrix(et)[源代码]

计算从真赤道/真春分点(含章动)到 ICRF/J2000 的旋转矩阵。

该矩阵包含岁差与章动效应:R = N @ P

参数:

et (float) -- SPICE 历书时(秒)。

返回:

3x3 旋转矩阵,满足 r_ICRF = R @ r_true_equator

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.coordinate.rho_bridge module

rho 无量纲坐标 ↔ ECI(J2000, km)坐标桥接。

将 qiao rho_to_eci / eci_to_rho 的功能用 e2m2e 的 EphemerisSystem + SynodicAxes 重写。rho 坐标系以选定平动点为原点,使用 CR3BP 归一化单位, 轴向与瞬时 EMR 会合系对齐。

数学关系:

r_ECI = C @ rho_km + r_LP
v_ECI = C @ rhodot_km + Cdot @ rho_km + C @ v_LP

其中 C 是 EMR→J2000 旋转矩阵(与 qiao Calc_MoonParam 约定一致), r_LP/v_LP 是平动点在 J2000 中的位置/速度。

class e2m2e.algorithm.coordinate.rho_bridge.RhoContext(*args, **kwargs)[源代码]

基类:Protocol

rho↔ECI 桥接所需的最小上下文契约。

core 层不应认识 algorithms 的类型;本 Protocol 描述 rho_bridge 实际用到的 几个属性(归一化参数、平动点选择),让 NormalFormContext 等上层 类型按结构匹配,消除 core → algorithms 的反向依赖。

LU: float
TU: float
jd0: float
gamma: float
libration_point: LibrationPoint
e2m2e.algorithm.coordinate.rho_bridge.compute_emr_rotation(et, system)[源代码]

从 SPICE 构造 EMR 会合系旋转矩阵 C(t) 及导数 Cdot(t)。

约定与 qiao Calc_MoonParam 一致:C 满足 r_J2000 = C @ r_EMR (EMR → J2000),其列向量在 J2000 中给出 EMR 基向量。 SynodicAxes.rotation_matrix(et) 返回相同的矩阵。

参数:
  • et (float) -- 历书时(秒)。

  • system (EphemerisSystem) -- 星历系统,提供 SPICE 访问。

返回:

(C, Cdot),各为 (3, 3) 数组。C 从 EMR→J2000,Cdot 为其时间导数。

返回类型:

tuple[npt.NDArray[np.floating], npt.NDArray[np.floating]]

e2m2e.algorithm.coordinate.rho_bridge.tu_to_et(t_nd, context, system)[源代码]

归一化时间 TU → SPICE 历书时(秒)。

NormalFormContext.tu_to_seconds() 命名族对称:后者停在 SI 秒, 本函数进一步经 SPICE str2et("... JDTDB") 转到历书时,供 ForceModel 等 ET 驱动的力模型使用。

参数:
  • t_nd (float) -- 归一化时间(TU)。

  • context (RhoContext) -- 标准形上下文,提供 jd0TU

  • system (EphemerisSystem) -- 星历系统,提供 SPICE 访问。

返回类型:

float

e2m2e.algorithm.coordinate.rho_bridge.rho_to_eci(rho_nd, rhodot_nd, t_nd, context, system)[源代码]

rho 无量纲坐标 → ECI(J2000, km, km/s)。

参数:
  • rho_nd (npt.ArrayLike) -- 无量纲位置 (3,),以平动点为原点。

  • rhodot_nd (npt.ArrayLike) -- 无量纲速度 (3,)

  • t_nd (float) -- 无量纲时间(TU)。

  • context (RhoContext) -- 标准形上下文,提供 LU、TU、平动点选择等。

  • system (EphemerisSystem) -- 星历系统。

返回:

(r_eci, v_eci) 各为 (3,) 数组,km 和 km/s。

返回类型:

tuple[npt.NDArray[np.floating], npt.NDArray[np.floating]]

e2m2e.algorithm.coordinate.rho_bridge.eci_to_rho(r_eci, v_eci, t_nd, context, system)[源代码]

ECI(J2000, km, km/s)→ rho 无量纲坐标。

参数:
  • r_eci (npt.ArrayLike) -- J2000 位置 (3,),km。

  • v_eci (npt.ArrayLike) -- J2000 速度 (3,),km/s。

  • t_nd (float) -- 无量纲时间(TU)。

  • context (RhoContext) -- 标准形上下文。

  • system (EphemerisSystem) -- 星历系统。

返回:

(rho_nd, rhodot_nd) 各为 (3,) 无量纲数组。

返回类型:

tuple[npt.NDArray[np.floating], npt.NDArray[np.floating]]

e2m2e.algorithm.coordinate.xys module

IAU X, Y, s 参数提供器实现。

class e2m2e.algorithm.coordinate.xys.XysProvider[源代码]

基类:ABC

为 ITRF native reduction 提供 IAU CIP/CIO X,Y,s

保留为 ABC(而非折叠为唯一实现 ErfaXysProvider):ADR 0003 明确记录了 日后用 GMAT 表格支撑的 GMATXysProvider 替换 pyerfa 来源以实现与 GMAT XYS 插值精确一致的需求——erfa 可替换性是真实设计意图,非"万一"式死灵活性。

abstractmethod xys(tt_mjd)[源代码]

返回 TT MJD 对应的 X,Y,s (弧度)。

参数:

tt_mjd (float)

返回类型:

tuple[float, float, float]

class e2m2e.algorithm.coordinate.xys.ErfaXysProvider[源代码]

基类:XysProvider

基于 pyerfa/SOFA 的 IAU 2006/2000A X,Y,s provider。

xys(tt_mjd)[源代码]

返回 TT MJD 对应的 X,Y,s (弧度)。

参数:

tt_mjd (float)

返回类型:

tuple[float, float, float]

e2m2e.algorithm.design package

任务轨道设计(三段编排)。

回答"一个任务参数怎么变成一条可用的标称轨道"。三段编排(ADR 0011 迁移, 源:dfh/design_orbit.py):family(初猜)→ 星历修正(Rust 多重打靶 multiple_shooting_correct_py,segmented 或稳定轨道默认路径)→ propagation(高精度预报)。六类轨道: DRO / NRHO / Halo / Lissajous / L4 / L5。api/ 只做 Pydantic 校验 + 薄调用,编排逻辑留这里。

e2m2e.algorithm.design.design_orbit module

任务轨道设计入口。

链路(对齐 docs/plans/dfh-parity-prd.md FR1):

  1. CR3BP 初猜:按形状参数生成周期轨道(cr3bp_orbits);

  2. 星历修正:周期轨道采样 patch points → synodic→J2000 转换 → 星历 N 体模型下多重打靶收敛。稳定轨道(DRO 等)走 two_level (Rust 打靶 + vel_weight),不稳定轨道(Halo/NRHO)走 segmented (分段打靶拼接,全程分段约束、不依赖自由外推);

  3. 标称星历:以修正后状态为初值,在 perturbation_to_force_config 映射出的高精度力模型下生成——two_level 自由外推整段 duration, segmented 逐段积分填满 et_grid。输出文本格式星历(EphemerisTable)。

参数语义对齐 MATLAB design_orbit.m 与 inputs-dac.txt 设计块: DRO 振幅+初始相位;Halo 共线点编号+带符号面外振幅+初始相位; NRHO 共线点编号+北/南+近月点高度+初始相位。初始相位为周期份额 (0~1),历元时刻的状态 = 周期轨道参考状态沿轨道推进 phase × T; 相位零点按历史标定——Halo/NRHO 在 y=0 穿越点,DRO 在远侧 x 轴穿越点(e2m2e 的 DRO 参考状态为近侧穿越点,内部偏移半周期)。 DRO 振幅取一个周期内距月距离最小/最大值的均值(同按历史标定)。

已知系统差(历史标定值):

  • 参考输出 GCRS,e2m2e 在 ICRF(J2000)下传播,frame bias(~23 mas) 在月距量级约 0.04 km,计入对比容差;

  • 维持时间按 1 年 = 365.25 天折算;

  • NRHO 近月点高度起算面取月球平均半径 1737.4 km。

exception e2m2e.algorithm.design.design_orbit.DesignNotConvergedError(message, *, status=ConvergenceState.FAILED, cause=FailureCause.UNKNOWN)[源代码]

基类:RuntimeError

任务轨道设计未生成可用标称轨道。

参数:
返回类型:

None

class e2m2e.algorithm.design.design_orbit.OrbitDesignResult(orbit_type, epoch_utc, duration_day, output_step_sec, initial_state, ephemeris, cr3bp_orbit, cr3bp_jacobi, correction, force_config, status=ConvergenceState.CONVERGED, cause=FailureCause.NONE, message='任务完成', stages=(), correction_method=None, drift_e=None, drift_aop_deg=None, drift_rp_km=None, secular_aop_rate_deg_per_year=None, moon_centric_elements=None)[源代码]

基类:object

任务轨道设计结果。

变量:
  • orbit_type (str) -- 轨道类型("DRO" / "HALO" / "NRHO" / "ELFO")。

  • epoch_utc (str) -- 起始历元 UTC(ISO 字符串)。

  • duration_day (float) -- 维持时间(天)。

  • output_step_sec (float) -- 星历输出间隔(秒)。

  • initial_state (numpy.ndarray) -- 历元时刻惯性系状态(km, km/s),星历修正后首节点。

  • ephemeris (e2m2e.data.types.trajectory.EphemerisTable) -- 标称星历(文本格式容器:UTC + GCRS 位置 km / 速度 m/s + 地月会合系无量纲位置)。

  • cr3bp_orbit (e2m2e.data.types.orbit.Orbit | None) -- CR3BP 周期轨道(参考相位,无量纲);ELFO 场景为 None。

  • cr3bp_jacobi (float) -- CR3BP 周期轨道的 Jacobi 常数;ELFO 场景为 nan。

  • correction (e2m2e.algorithm.results.EphemerisCorrectionResult | None) -- 星历修正结果(收敛标志、迭代次数、残差历史、修正后 patch points);ELFO 场景为 None。

  • correction_method (str | None) -- 实际执行的星历修正方法("segmented" / "two_level" 等);ELFO 场景(无星历修正)为 None。

  • force_config (dict[str, Any]) -- 标称预报使用的力模型配置字典。

  • drift_e (float | None) -- 传播弧段 Δe 首末差(仅 ELFO)。

  • drift_aop_deg (float | None) -- 传播弧段 Δω 首末差(度,仅 ELFO)。

  • drift_rp_km (float | None) -- 传播弧段 Δrp 首末差(km,仅 ELFO)。

  • secular_aop_rate_deg_per_year (float | None) -- ω 线性拟合年漂移率(仅 ELFO)。

  • moon_centric_elements (dict[str, numpy.ndarray] | None) -- 月心惯性系根数序列(仅 ELFO)。

参数:
orbit_type: str
epoch_utc: str
duration_day: float
output_step_sec: float
initial_state: ndarray
ephemeris: EphemerisTable
cr3bp_orbit: Orbit | None
cr3bp_jacobi: float
correction: EphemerisCorrectionResult | None
force_config: dict[str, Any]
status: ConvergenceState = 'converged'
cause: FailureCause = 'none'
message: str = '任务完成'
stages: tuple[StageRecord, ...] = ()
correction_method: str | None = None
drift_e: float | None = None
drift_aop_deg: float | None = None
drift_rp_km: float | None = None
secular_aop_rate_deg_per_year: float | None = None
moon_centric_elements: dict[str, ndarray] | None = None
write_ephemeris(path)[源代码]

按文本格式写出标称星历。

参数:

path (str | Path)

返回类型:

None

e2m2e.algorithm.design.design_orbit.default_kernel_dir()[源代码]

仓库自带 SPICE 内核目录(kernels/)。

返回类型:

str

e2m2e.algorithm.design.design_orbit.design_orbit(request, *, spice=None, kernel_dir=None, verbose=False)[源代码]

端到端设计标称轨道(DRO/DPO/NRHO/Halo/Lissajous/L4/L5/Axial/.../ELFO)。

通过 request.orbit_type 在内部分派管线:

  • CR3BP 类型 (DRO/NRHO/Halo/Lissajous/…):CR3BP 初猜 → 星历修正 (多重打靶)→ 高精度长期预报。

  • ELFO:经典开普勒根数构造初值 → 全摄动传播 → 月心根数漂移分析。

参数:
  • request (DesignOrbitRequest) -- DesignOrbitRequest,经 model_validator 校验并填充默认值。

  • spice (SPICEManager | None) -- 已加载内核的 SPICEManager;缺省自动创建并加载。

  • kernel_dir (str | None) -- SPICE 内核目录。

  • verbose (bool) -- 修正过程显示进度条。

返回:

OrbitDesignResult (标称星历 + 收敛/漂移信息)。

抛出:
返回类型:

OrbitDesignResult

e2m2e.algorithm.design.design_orbit.load_design_kernels(spice, kernel_dir=None)[源代码]

加载设计链路所需内核:行星历 + body-fixed 帧内核。

行星名→质心/本体 NAIF ID 别名由 SPICEManager.load_kernel() 首次 调用时统一注册(双侧同步,见 _BODY_ID_ALIASES)。

返回实际加载的内核路径列表(调用方管理卸载)。

参数:
返回类型:

list[str]

e2m2e.algorithm.design.frozen_orbit module

ELFO 冻结轨道设计的经典力学转换与漂移分析。

本模块为 design_orbit 的 ELFO 分支提供两类辅助:

  1. 经典轨道根数 ↔ 笛卡尔状态转换(_oe2cart / _cart2oe)——CR3BP 管线不走这条路(初值来自轨道族生成器),ELFO 管线从六根数构造初值。

  2. 月心惯性系根数提取与漂移统计(_extract_moon_centric_elements / _compute_drift)——传播在地心系进行,冻结特性看的是月心根数。

e2m2e.algorithm.dynamics package

动力学:System(数据上下文)+ Dynamics(传播编排)。

System + Dynamics 都归 algorithm/dynamics/(ADR 0011 迁移,源: core/system.pycore/cr3bp_system.pycore/ephemeris_system.pycore/dynamics.pycore/bcr4bp_system.pycore/bcr4bp_dynamics.pycore/ephemeris_dynamics.pycore/potential.py)。System 描述模型 (坐标系、单位、引力参数、天体列表),Dynamics 用 system 传播(模板方法 模式 ADR 0002)。标准参数数据(μ/DU/TU/平动点值)在 data/templates/systems.py

CR3BP_System/CR3BP_Dynamics 等类名保持原样(三体问题文献惯例, 不统一 PascalCase/snake_case,ADR 0011 规则 3)。

e2m2e.algorithm.dynamics.system module

动力学系统抽象基类模块。

定义 System 抽象基类,统一 CR3BP 系统与星历系统的公共接口。 具体实现见 cr3bp_system.pyCR3BP_System)和 ephemeris_system.pyEphemerisSystem)。

class e2m2e.algorithm.dynamics.system.System[源代码]

基类:ABC

动力学系统抽象基类。

描述天体的几何、引力与运动学模型,是后续一切计算的上下文。 所有具体系统(CR3BP、星历)都应实现以下最小接口:

  • frame:坐标框架(ReferenceFrame

  • unit_system:单位系统(UnitSystem

  • gravitational_parameter(body):天体引力参数

注意:mubody_state(body, t)coordinate_system 等不在基类中, 它们属于特定系统实现的概念。

abstract property frame: ReferenceFrame

系统的坐标框架。

abstract property unit_system: UnitSystem

系统的单位系统。

abstractmethod gravitational_parameter(body)[源代码]

获取指定天体的引力参数。

参数:

body (str) -- 天体标识。CR3BP 系统接受 "primary"/"secondary"; 星历系统接受 SPICE 天体名称(如 "EARTH"、"MOON")。

返回:

引力参数。CR3BP 系统返回无量纲值,星历系统返回 km³/s²。

返回类型:

float

get_body_position(body, t)[源代码]

获取天体在时刻 t 的位置(仅星历系统实现)。

CR3BP 等非星历系统不使用此方法,调用时抛出 NotImplementedError。

参数:
  • body (str) -- 天体名称(如 "MOON"、"SUN")。

  • t (float) -- SPICE et 秒。

返回:

天体位置向量。

e2m2e.algorithm.dynamics.dynamics module

三体问题动力学模块

包含通用 Dynamics 基类和 CR3BP_Dynamics 类,用于计算和积分圆型限制性三体问题的动力学方程。

物理背景

在圆型限制性三体问题 (CR3BP) 中,两个主天体(如地球和月球)绕其公共质心做圆周运动, 第三体(航天器)质量小到不影响两个主天体的运动。采用以质心为原点的旋转坐标系, 使得两个主天体固定在 x 轴上。

坐标系约定:
  • 原点:系统质心

  • x 轴:从质心指向较大天体(质量 1-μ)的方向

  • 较大天体位于 x = -μ,较小天体(质量 μ)位于 x = 1-μ

  • y 轴在轨道平面内垂直于 x 轴

  • z 轴与 x-y 平面正交

所有量均采用无量纲化单位(距离单位 DU = 主天体间距,时间单位 TU 使主天体角速度为 1)。

class e2m2e.algorithm.dynamics.dynamics.Dynamics(system)[源代码]

基类:object

通用天体系统动力学基类

采用 Template Method 模式:基类定义 propagate() 的算法骨架, 子类通过钩子方法提供具体的 ODE 函数和步长配置。

契约(对应 MBSE REQ-002): - propagate() 返回的 states 形状始终为 (n_points, 6) - stm (如果存在)形状为 (n_points, 6, 6)

变量:
  • system -- 关联的系统对象

  • integrator -- 数值积分器类型

  • rtol -- 相对积分容差

  • atol -- 绝对积分容差

  • max_step -- 最大积分步长

  • last_trajectory -- 最近一次积分的轨迹 [t, y]

  • last_stm -- 最近一次积分的状态转移矩阵

  • cross_section_tolerance -- 截面检测容差

  • last_crossing -- 上次穿过截面的点和时间

参数:

system (System)

DEFAULT_TOLERANCE = 1e-12
DEFAULT_MAX_STEP = 0.01
STATE_DIM = 6
STM_DIMENSION = 42
MIN_DISTANCE = 1e-10
__init__(system)[源代码]

初始化动力学

参数:

system (System) -- 系统对象(CR3BP_System 或 EphemerisSystem)

返回类型:

None

equations_of_motion(t, state)[源代码]

运动方程(子类需实现)

参数:
返回:

状态导数

抛出:

NotImplementedError -- 子类未实现此方法

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

propagate(initial_state, t_span, t_eval=None, with_stm=False, with_jacobi=False, events=None, backend=None, collision_detection=False)[源代码]

传播轨迹(Template Method)

统一的传播入口,保证: - states 形状为 (n_points, 6)(REQ-002) - stm 形状为 (n_points, 6, 6)(当 with_stm=True 时) - time 数组单调递增

参数:
  • initial_state (ArrayLike) -- 初始状态向量

  • t_span (tuple[float, float]) -- 时间区间 [t0, tf]

  • t_eval (ArrayLike | None) -- 评估时间点数组(可选)

  • with_stm (bool) -- 是否计算状态转移矩阵

  • with_jacobi (bool) -- 是否沿轨迹逐点计算 Jacobi 常数

  • events (Callable[[float, ndarray], float] | list[Callable[[float, ndarray], float]] | None) -- 事件函数(单个 callable 或列表),scipy solve_ivp 语义:g(t, state) -> float,零点即事件面;可给函数对象 设 terminal = True (触发即停)与 direction (> 0 只记 上行穿越,< 0 只记下行,0 双向)属性。 with_stm=True 时事件函数接收 42 维增广状态。

  • backend (Literal['scipy', 'rust'] | None) -- 事件积分路径(ADR 0020 决策 4,能力缺失显式选择): 仅当 events 非 None 时有意义,二选一:"scipy" 走 scipy solve_ivp 事件积分;"rust" 走 Rust solve_ivp_events (事件语义与 scipy 未完全对齐,由调用方 显式选择并接受差异)。不传则报错;不允许 "auto" 等隐式 选择。无 events 时忽略(Rust 快速路径为唯一路径)。

  • collision_detection (bool) -- 是否启用碰撞终止(ADR 0020 决策 5)。启用时 从系统 body-radius 配置(primary_radius_km/ secondary_radius_km)构造 g = |r - body_pos| - R_bodyterminal=True 事件,与 events 合并后走事件积分 (须显式 backend);半径未注入或特征尺度未初始化时抛 ValueError。默认 False(不启用,行为与现状一致)。

返回:

轨迹结果字典,包含 timestates 键; 当 with_stm=True 时额外包含 stm 键; 当 with_jacobi=True 时额外包含 jacobijacobi_error 键; 当传入 events 时额外包含 t_eventsy_events 键 (逐事件的触发时刻与状态数组,scipy 语义); 当 collision_detection=True 时额外包含 collision 键 (None 表示未碰撞;否则为 {"body": 天体名, "t": 终止时刻, "state": 终止状态})。

返回类型:

dict[str, Any]

compute_jacobi_constant(state)[源代码]

计算能量常数(子类需实现)

参数:

state (ArrayLike) -- 状态向量

返回:

能量常数

抛出:

NotImplementedError -- 子类未实现此方法

返回类型:

float

check_cross_section(state, plane, value)[源代码]

检查是否穿过指定截面

参数:
  • state (ArrayLike) -- 状态向量

  • plane (str) -- 截面平面 ('x', 'y', 'z')

  • value (float) -- 平面值

返回:

是否穿过截面

抛出:

ValueError -- 无效的平面参数

返回类型:

bool

class e2m2e.algorithm.dynamics.dynamics.CR3BP_Dynamics(system)[源代码]

基类:Dynamics

CR3BP动力学方程

封装了CR3BP的动力学模型,提供状态传播、状态转移矩阵计算、 Jacobi常数计算等核心功能。支持6维状态向量(位置+速度)和 42维增广状态向量(状态+状态转移矩阵)的数值积分。

CR3BP 运动方程(旋转坐标系中):

ẍ - 2ẏ = ∂Ω/∂x ÿ + 2ẋ = ∂Ω/∂y z̈ = ∂Ω/∂z

其中 Ω 为伪势能(见 equations_of_motion 方法的详细注释), 等号左侧的 2ẏ、-2ẋ 项为科里奥利力(Coriolis),伪势能中 已包含离心力项 x²/2 + y²/2。

变量:

system (e2m2e.algorithm.dynamics.cr3bp_system.CR3BP_System) -- CR3BP 系统对象,提供 mu 等系统常数与 Jacobi 常数计算。

参数:

system (CR3BP_System)

system: CR3BP_System
__init__(system)[源代码]

初始化CR3BP动力学

参数:

system (CR3BP_System) -- CR3BP_System对象,包含质量参数μ等系统常数

返回类型:

None

jacobi_history: list[float]
jacobi_error: float
equations_of_motion(t, state)[源代码]

6维状态向量的运动方程

实现 CR3BP 在旋转坐标系中的运动方程。旋转坐标系以两个主天体的 公共质心为原点,与主天体同步旋转(角速度 ω = 1),因此两个主天体 在坐标系中固定不动。

在旋转坐标系中,运动方程为:

ẍ - 2ẏ = ∂Ω/∂x (x 方向:离心力 + 引力 + 科里奥利力) ÿ + 2ẋ = ∂Ω/∂y (y 方向:离心力 + 引力 + 科里奥利力) z̈ = ∂Ω/∂z (z 方向:仅引力,无科里奥利力)

伪势能 Ω = (x² + y²)/2 + (1-μ)/r₁ + μ/r₂,其偏导数为:

∂Ω/∂x = x - (1-μ)(x+μ)/r₁³ - μ(x-1+μ)/r₂³ ∂Ω/∂y = y - (1-μ)y/r₁³ - μy/r₂³ ∂Ω/∂z = - (1-μ)z/r₁³ - μz/r₂³

因此加速度各项的物理含义:
  • "x" / "y" 项:离心力(伪势能中的二次项贡献)

  • "(1-μ)(x+μ)/r₁³" 等:较大天体(如地球)的引力加速度

  • "μ(x-1+μ)/r₂³" 等:较小天体(如月球)的引力加速度

  • "2vy" / "-2vx":科里奥利力(旋转坐标系中的虚拟力)

参数:
  • t (float) -- 时间(旋转坐标系中,CR3BP方程不显含时间,即自治系统)

  • state (ndarray[tuple[Any, ...], dtype[floating]]) -- 状态向量 [x, y, z, vx, vy, vz]

返回:

状态导数 [vx, vy, vz, ax, ay, az]

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

compute_jacobian_A(state)[源代码]

计算 CR3BP 状态方程的雅可比矩阵 A(t)

A(t) 是 6x6 矩阵,满足 dΦ/dt = A(t)·Φ。 结构如下:

| 0₃ₓ₃  I₃ₓ₃ |    位置方程的雅可比:∂(v)/∂(r,v) = [0, I]
| U_ij   Ω   |    速度方程的雅可比:∂(a)/∂(r,v) = [U, Ω]

此方法提取自 equations_with_stm,供 Continuation 等模块复用(REQ-103)。

参数:

state (ndarray[tuple[Any, ...], dtype[floating]]) -- 状态向量 [x, y, z, vx, vy, vz]

返回:

6x6 雅可比矩阵 A

返回类型:

ndarray

equations_with_stm(t, augmented_state)[源代码]

42维增广状态向量的运动方程(包含状态转移矩阵)

同时积分状态向量和状态转移矩阵(STM),满足 dΦ/dt = A(t)·Φ。

状态转移矩阵 Φ(t, t₀) 将初始状态的微小扰动映射到当前时刻:

δx(t) = Φ(t, t₀) · δx(t₀)

通过将 Φ 拉伸为 36 维向量并与 6 维状态拼接为 42 维增广状态, 可以用标准的 ODE 积分器同时求解轨道和 STM。

参数:
返回:

增广状态导数

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

propagate_orbit_state_at_time(orbit, t, integration_dt=0.01)[源代码]

从轨道首点状态积分到给定时刻对应的相位(周期轨道上对周期取模)

利用周期轨道的周期性,将目标时间对周期取模后从轨道起始状态 重新积分,得到该相位处的精确状态。

参数:
  • orbit (Orbit) -- 周期轨道数据(须含 statestimes、有效 period

  • t (float) -- 与轨道 times 一致的时间坐标(绝对时间)

  • integration_dt (float) -- 构造 t_eval 的步长

返回:

积分末端状态 [x, y, z, vx, vy, vz]

抛出:
返回类型:

npt.NDArray[np.floating]

compute_state_transition_matrix(initial_state, t)[源代码]

计算状态转移矩阵

参数:
  • initial_state (ArrayLike) -- 初始状态向量

  • t (float) -- 积分终止时间

返回:

状态转移矩阵 (6x6)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

compute_jacobi_constant(state)[源代码]

计算Jacobi常数

参数:

state (ArrayLike) -- 状态向量 [x, y, z, vx, vy, vz]

返回:

Jacobi常数

返回类型:

float

e2m2e.algorithm.dynamics.dynamics.propagate_state_at_orbit_time(orbit, t, dynamics, integration_dt=0.01)[源代码]

委托 CR3BP_Dynamics.propagate_orbit_state_at_time(),便于顶层导入兼容

参数:
  • orbit (Any) -- 周期轨道数据

  • t (float) -- 目标时间(绝对时间)

  • dynamics (CR3BP_Dynamics) -- CR3BP动力学对象

  • integration_dt (float) -- 积分步长

返回:

积分末端状态

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.dynamics.potential module

CR3BP 伪势能函数

包含伪势能 Ω 的 Hessian 矩阵计算,供动力学方程和稳定性分析共用。

e2m2e.algorithm.dynamics.potential.pseudo_potential_hessian(mu, x, y, z, min_distance=1e-10)[源代码]

计算 CR3BP 伪势能 Ω 的 Hessian 矩阵 U_ij = ∂²Ω/∂rᵢ∂rⱼ

参数:
  • mu (float) -- 质量参数

  • x (float) -- 旋转系 x 坐标(无量纲)

  • y (float) -- 旋转系 y 坐标(无量纲)

  • z (float) -- 旋转系 z 坐标(无量纲)

  • min_distance (float) -- 最小距离钳位,防止在天体位置处除零

返回:

3×3 对称 Hessian 矩阵

返回类型:

ndarray[tuple[Any, ...], dtype[float64]]

e2m2e.algorithm.dynamics.cr3bp_system module

圆型限制性三体问题系统模块。

包含 CR3BP_System 类与 LibrationPoint 枚举,用于定义和操作 圆型限制性三体问题系统。CR3BP_System 继承自 System 抽象基类。

class e2m2e.algorithm.dynamics.cr3bp_system.CR3BP_System(mu, primary, secondary, primary_radius_km=None, secondary_radius_km=None)[源代码]

基类:System

圆型限制性三体问题系统

变量:
  • mu -- 质量参数 μ = m2/(m1+m2)

  • primary_body -- 主天体名称

  • secondary_body -- 次天体名称

  • L_points -- 平动点位置字典

  • L1 -- L1平动点坐标

  • L2 -- L2平动点坐标

  • L3 -- L3平动点坐标

  • L4 -- L4平动点坐标

  • L5 -- L5平动点坐标

  • characteristic_length -- 特征长度 (km)

  • characteristic_time -- 特征时间 (s)

  • characteristic_velocity -- 特征速度 (km/s)

  • mass_primary -- 主天体质量 (kg)

  • mass_secondary -- 次天体质量 (kg)

  • total_mass -- 总质量 (kg)

  • semi_major_axis -- 半长轴 (km)

  • orbital_period -- 轨道周期 (s)

  • mean_motion -- 平均角速度 (rad/s)

  • has_L_points -- 是否已计算平动点

参数:
  • mu (float)

  • primary (str)

  • secondary (str)

  • primary_radius_km (float | None)

  • secondary_radius_km (float | None)

EARTH_MOON_DISTANCE_KM = 384405.0
AU = 149597870.7
G = 6.6743e-20
DAY = 86400.0
YEAR = 31557600.0
__init__(mu, primary, secondary, primary_radius_km=None, secondary_radius_km=None)[源代码]

初始化系统参数

参数:
  • mu (float) -- 质量参数 μ = m2/(m1+m2)

  • primary (str) -- 主天体名称

  • secondary (str) -- 次天体名称

  • primary_radius_km (float | None) -- 主天体半径(km),供碰撞终止(ADR 0020 决策 5) 使用;None 表示不启用碰撞检测。

  • secondary_radius_km (float | None) -- 次天体半径(km),同上。

返回类型:

None

property frame: ReferenceFrame

CR3BP 采用会合(旋转)坐标框架。

property unit_system: UnitSystem

CR3BP 在无量纲空间计算。

gravitational_parameter(body)[源代码]

获取天体的无量纲引力参数。

CR3BP 约定总质量为 1:primary 的 GM 为 1 - mu, secondary 的 GM 为 mu

参数:

body (str) -- "primary" 或 "secondary"。

返回:

无量纲引力参数。

抛出:

ValueError -- body 不是 "primary" 或 "secondary"。

返回类型:

float

property DU: float

特征长度 (km)

property TU: float

特征时间 (天) — TOD 约定

property VU: float

特征速度 (m/s) — TOD 约定

set_characteristic_scales(distance, period)[源代码]

设置特征尺度

参数:
  • distance (float) -- 两天体之间的距离 (km)

  • period (float) -- 轨道周期 (s)

返回类型:

None

compute_libration_points()[源代码]

计算五个平动点

返回:

平动点位置字典,键为 LibrationPoint 枚举,值为坐标数组

返回类型:

dict[LibrationPoint, ndarray[tuple[Any, ...], dtype[floating]]]

get_libration_point(point)[源代码]

获取指定平动点

若尚未计算平动点,会自动调用 compute_libration_points()。

参数:

point (LibrationPoint) -- LibrationPoint枚举值

返回:

平动点坐标数组

抛出:

ValueError -- 平动点无效

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

get_jacobi_constant(state)[源代码]

计算Jacobi常数(Parker 约定)

C = 2U - V²,其中 U = ½(x²+y²) + (1-μ)/r₁ + μ/r₂(不含常数项 ½μ(1-μ))。

注意:Belbruno/Gómez 文献使用含常数项的 Ω = U + ½μ(1-μ), 对应 C_Belbruno = C_Parker + μ(1-μ) ≈ C_Parker + 0.012。 两种约定给出相同运动方程(常数项梯度为零),仅 Jacobi 绝对值不同。 参见 Gómez 2001 Vol. I §2.1.1 Convention A/B。

参数:

state (ArrayLike) -- 状态向量 [x, y, z, vx, vy, vz]

返回:

Jacobi常数(Parker 约定,无常数项)

返回类型:

float

dimensionless_to_physical(state)[源代码]

无量纲化转物理单位

参数:

state (ArrayLike) -- 无量纲状态向量 [x, y, z, vx, vy, vz]

返回:

物理状态向量 [km, km/s]

抛出:

ValueError -- 系统未初始化特征尺度

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

physical_to_dimensionless(state)[源代码]

物理单位转无量纲化

参数:

state (ArrayLike) -- 物理状态向量 [x, y, z, vx, vy, vz] (km, km/s)

返回:

无量纲状态向量

抛出:

ValueError -- 系统未初始化特征尺度

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

compute_stability_index(L_point)[源代码]

计算平动点稳定性指标

通过线性化运动方程的特征值分析平动点稳定性。

参数:

L_point (LibrationPoint) -- LibrationPoint枚举值

返回:

稳定性指标字典,包含 is_stable、max_real_part、max_imag_part、 eigenvalues 和 linear_matrix

返回类型:

dict[str, Any]

info(mode='default')[源代码]

输出系统信息

参数:

mode (str) -- 信息模式,"default" 为基础信息,"all" 为详细信息

返回类型:

None

e2m2e.algorithm.dynamics.bcr4bp_system module

双圆限制性四体问题(BCR4BP)系统模块。

包含 BCR4BPSystem 类:在 CR3BP_System (地月会合旋转系)之上叠加 太阳质点摄动。双圆近似下,地月绕公共质心作圆周运动(CR3BP 假设),太阳 也在会合系中绕质心作共面圆周运动,其位置是时间 t 的解析函数,无需星历。

无量纲约定与 CR3BP 一致:距离单位 DU = 地月距离,时间单位 TU 使地月 会合系角速度为 1,总质量(地+月)为 1。太阳参数(质量、距离、角速度) 均在此约定下无量纲化。

class e2m2e.algorithm.dynamics.bcr4bp_system.BCR4BPSystem(mu, primary, secondary, sun_mass=None, sun_distance=None, sun_angular_rate=None, sun_phase0=0.0, primary_radius_km=None, secondary_radius_km=None)[源代码]

基类:CR3BP_System

双圆限制性四体问题(Bicircular Restricted Four-Body Problem)系统

地月会合旋转系 + 太阳质点摄动。太阳在会合系中作共面圆周运动:

r_s(t) = a_s · (cos θ(t), sin θ(t), 0), θ(t) = θ0 + ω_s · t

其中 ω_s = n_s - 1 < 0:n_s 是太阳公转的无量纲角速度(惯性系), 减去会合系自身角速度 1 后即太阳在会合系中的(逆行)角速度。 系统是时间周期的,周期 T = 2π/|ω_s|,约一个会合月。

变量:
  • sun_mass -- 太阳无量纲质量 m_s = GM_sun / (GM_earth + GM_moon)

  • sun_distance -- 太阳圆周轨道半径 a_s(无量纲,日地平均距离 / DU)

  • sun_angular_rate -- 太阳在会合系中的角速度 ω_s(无量纲,负值表示逆行)

  • sun_phase0 -- t = 0 时刻的太阳相位角 θ0(弧度)

参数:
  • mu (float)

  • primary (str)

  • secondary (str)

  • sun_mass (float | None)

  • sun_distance (float | None)

  • sun_angular_rate (float | None)

  • sun_phase0 (float)

  • primary_radius_km (float | None)

  • secondary_radius_km (float | None)

其余属性(mu、特征尺度、平动点等)继承自 CR3BP_System。 注意:BCR4BP 无 Jacobi 积分,compute_libration_points 给出的是 对应 CR3BP 的平动点,仅作参考位置使用。

SUN_GM_KM3_S2 = 132712440018.0
EARTH_MOON_GM_KM3_S2 = 403503.235502
SUN_EARTH_DISTANCE_KM = 149597870.7
__init__(mu, primary, secondary, sun_mass=None, sun_distance=None, sun_angular_rate=None, sun_phase0=0.0, primary_radius_km=None, secondary_radius_km=None)[源代码]

初始化 BCR4BP 系统

参数:
  • mu (float) -- 质量参数 μ = m2/(m1+m2)。地月系默认使用 DE421 基准 Datum.DE421.mu,废弃 1965 旧值 0.0121506683。

  • primary (str) -- 主天体名称

  • secondary (str) -- 次天体名称

  • sun_mass (float | None) -- 太阳无量纲质量;None 时按地月系默认值 (GM_sun / GM_EMB,DE440)

  • sun_distance (float | None) -- 太阳圆周轨道半径(无量纲);None 时取 日地平均距离 / 地月距离

  • sun_angular_rate (float | None) -- 太阳会合系角速度 ω_s;None 时按地月系默认值 (需在 set_characteristic_scales 之后由 earth_moon 类方法设置,直接构造时请显式给出)

  • sun_phase0 (float) -- t = 0 时刻的太阳相位角(弧度)

  • primary_radius_km (float | None) -- 主天体半径(km),供碰撞终止(ADR 0020 决策 5) 使用;None 表示不启用碰撞检测。

  • secondary_radius_km (float | None) -- 次天体半径(km),同上。

返回类型:

None

classmethod earth_moon(mu=0.012150585350562453, sun_phase0=0.0)[源代码]

构造标准地月 BCR4BP 系统(含默认特征尺度)

特征尺度与 CR3BP_System._with_default_scales 的地月分支一致 (DU = 384405 km,周期 27.32 天),太阳参数取 DE440 / 日地平均 距离推导的无量纲值。地月 μ 默认使用 DE421 基准。

参数:
  • mu (float) -- 地月质量参数,默认 Datum.DE421.mu

  • sun_phase0 (float) -- t = 0 时刻的太阳相位角(弧度)

返回:

已初始化的 BCR4BPSystem

返回类型:

BCR4BPSystem

property sun_angular_rate: float

太阳在会合系中的角速度 ω_s(无量纲,负值表示逆行)

set_characteristic_scales(distance, period)[源代码]

设置特征尺度,并按特征时间推导默认太阳角速度

若构造时未显式给出 sun_angular_rate,则按太阳公转周期 (儒略年,CR3BP_System.YEAR)推导:

n_s = 2π·t* / P_year = P_em / P_year, ω_s = n_s - 1

其中 t* = period/(2π) 为特征时间,P_em 为地月轨道周期。 显式传入的 sun_angular_rate 不受本方法影响。

参数:
返回类型:

None

sun_position(t)[源代码]

太阳在会合系中的解析位置(无量纲)

双圆近似:太阳在会合系中作共面圆周运动,

r_s(t) = a_s · (cos θ, sin θ, 0), θ = θ0 + ω_s·t

参数:

t (float) -- 无量纲时间(以地月会合系特征时间计)

返回:

太阳位置向量,形状 (3,)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

gravitational_parameter(body)[源代码]

获取天体的无量纲引力参数

在 CR3BP 约定("primary"/"secondary")之上额外接受 "sun", 返回太阳无量纲质量 m_s。

参数:

body (str)

返回类型:

float

e2m2e.algorithm.dynamics.bcr4bp_dynamics module

双圆限制性四体问题(BCR4BP)动力学模块。

包含 BCR4BP_Dynamics 类:在 CR3BP 运动方程上叠加太阳直接项与间接项 摄动。太阳位置由 BCR4BPSystem.sun_position(t) 解析给出,系统显式含 时间 t(时间周期系统),propagate 接口语义与 CR3BP_Dynamics 一致(无量纲时间、无量纲状态)。

运动方程(地月会合旋转系,无量纲):

ẍ - 2ẏ = ∂Ω/∂x + a_sun,x ÿ + 2ẋ = ∂Ω/∂y + a_sun,y z̈ = ∂Ω/∂z + a_sun,z

其中太阳摄动加速度(与 ThirdBodyGravity 同一公式):

a_sun = -m_s · [ (r - r_s)/|r - r_s|³ + r_s/|r_s|³ ]

第一项为直接项(太阳对航天器的引力),第二项为间接项(扣除太阳对 系统质心的引力)。

class e2m2e.algorithm.dynamics.bcr4bp_dynamics.BCR4BP_Dynamics(system)[源代码]

基类:Dynamics

BCR4BP 动力学方程(CR3BP + 太阳质点摄动)

支持 6 维状态向量与 42 维增广状态向量(状态 + 状态转移矩阵)的 数值积分。STM 变分方程 dΦ/dt = A(t)·Φ 中的雅可比 A(t) 显式依赖 时间:太阳项对位置的偏导随 r_s(t) 变化。

BCR4BP 无 Jacobi 积分(太阳项显式含时),with_jacobi=True 会 抛出 NotImplementedError

变量:

system (e2m2e.algorithm.dynamics.bcr4bp_system.BCR4BPSystem) -- BCR4BPSystem 对象,提供 mu 与太阳参数。

参数:

system (BCR4BPSystem)

system: BCR4BPSystem
__init__(system)[源代码]

初始化 BCR4BP 动力学

参数:

system (BCR4BPSystem) -- BCR4BPSystem 对象

返回类型:

None

sun_acceleration(t, position)[源代码]

太阳摄动加速度(直接项 + 间接项,无量纲)

a_sun = -m_s · [ (r - r_s)/|r - r_s|³ + r_s/|r_s|³ ]

ThirdBodyGravity 的公式一致(间接项以地月质心为参考点)。

参数:
  • t (float) -- 无量纲时间

  • position (ArrayLike) -- 航天器位置(无量纲),形状 (3,)

返回:

加速度向量,形状 (3,)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

equations_of_motion(t, state)[源代码]

6 维状态向量的运动方程(显式含时间 t)

CR3BP 方程 + 太阳摄动项。太阳位置 r_s(t) 使方程显式依赖时间, 系统为非自治(时间周期)系统。

参数:
  • t (float) -- 无量纲时间(会合系;与 CR3BP 不同,此处不能忽略)

  • state (ndarray[tuple[Any, ...], dtype[floating]]) -- 状态向量 [x, y, z, vx, vy, vz]

返回:

状态导数 [vx, vy, vz, ax, ay, az]

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

compute_jacobian_A(t, state)[源代码]

计算 BCR4BP 状态方程的雅可比矩阵 A(t)

结构与 CR3BP 相同:

| 0₃ₓ₃  I₃ₓ₃ |
| U_ij   Ω   |

但左下块在 CR3BP 伪势能 Hessian 上叠加太阳项对位置的偏导 (第三体雅可比,标准公式):

J_sun = -m_s · ( I/|d|³ - 3·d·dᵀ/|d|⁵ ), d = r - r_s(t)

间接项 -m_s·r_s/|r_s|³ 不依赖航天器位置,偏导为零。

参数:
  • t (float) -- 无量纲时间(太阳位置随时间变化,A 显式含时)

  • state (ndarray[tuple[Any, ...], dtype[floating]]) -- 状态向量 [x, y, z, vx, vy, vz]

返回:

6x6 雅可比矩阵 A

返回类型:

ndarray

equations_with_stm(t, augmented_state)[源代码]

42 维增广状态向量的运动方程(包含状态转移矩阵)

与 CR3BP 的增广方程相同结构,但 A(t) 显式含时(太阳项)。

参数:
返回:

增广状态导数

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

compute_state_transition_matrix(initial_state, t, t0=0.0)[源代码]

计算状态转移矩阵 Φ(t, t0)

BCR4BP 显式含时,STM 依赖起止时刻(而非仅时间跨度), 故比 CR3BP 版本多一个 t0 参数。

参数:
  • initial_state (ArrayLike) -- 初始状态向量

  • t (float) -- 积分终止时间

  • t0 (float) -- 积分起始时间(决定太阳初始相位),默认 0

返回:

状态转移矩阵 (6x6)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

compute_jacobi_constant(state)[源代码]

BCR4BP 无 Jacobi 积分,调用抛出 NotImplementedError

参数:

state (ArrayLike)

返回类型:

float

e2m2e.algorithm.dynamics.ephemeris_system module

星历系统模块。

提供天体位置、引力常数等星历信息的统一查询接口, 底层通过 SPICE 工具包获取数据。

class e2m2e.algorithm.dynamics.ephemeris_system.EphemerisSystem(bodies, spice, origin='EARTH', frame=ReferenceFrame.J2000, coordinate_system=None)[源代码]

基类:System

星历系统,管理一组天体的星历查询。

封装 SPICE 工具包,为轨道设计流程提供统一的天体数据访问层。 支持自定义参考原点和坐标框架。

变量:
  • bodies -- 天体名称列表,如 ["EARTH", "MOON", "SUN"]。

  • spice -- SPICE 管理器实例,负责底层星历数据读取。

  • origin -- 参考原点天体名称,默认为 "EARTH"。

  • frame -- 坐标系名称,默认为 "J2000"。

参数:
__init__(bodies, spice, origin='EARTH', frame=ReferenceFrame.J2000, coordinate_system=None)[源代码]

初始化星历系统。

参数:
  • bodies (list[str]) -- 需要纳入计算的天体名称列表。

  • spice (SPICEManager) -- 已完成内核加载的 SPICE 管理器实例。

  • origin (str) -- 参考原点天体,所有位置矢量将相对于此天体计算。

  • frame (ReferenceFrame) -- 参考坐标系名称,用于确定位置矢量的坐标框架。

  • coordinate_system (CoordinateSystem | None) -- 可选的默认坐标系;用于 ForceModel 传播。

返回类型:

None

property frame: ReferenceFrame

星历系统的坐标框架。

property unit_system: UnitSystem

星历系统使用物理单位。

property coordinate_system: CoordinateSystem | None

星历系统的默认坐标系。

update_coordinate_systems(t, state)[源代码]

更新动态坐标系。

coordinate_system.axesDynamicAxes 实例, 调用 axes.update(t, state)

参数:
  • t (float)

  • state (ArrayLike)

返回类型:

None

gravitational_parameter(body)[源代码]

获取天体的引力参数 GM。

参数:

body (str) -- 天体名称。

返回:

GM 值,单位 km³/s²。

返回类型:

float

get_body_position(body, et)[源代码]

获取天体相对于原点的位置向量。

自动使用初始化时设定的 frame 和 origin。

参数:
  • body (str) -- 天体名称,如 "MOON"、"SUN"。

  • et (float) -- 历书时(秒)。

返回:

位置向量,形状 (3,),单位 km。

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

get_body_state(body, et)[源代码]

获取天体相对于原点的状态向量。

自动使用初始化时设定的 frame 和 origin。

参数:
  • body (str) -- 天体名称,如 "MOON"、"SUN"。

  • et (float) -- 历书时(秒)。

返回:

状态向量,形状 (6,),前 3 元素为位置 [km],后 3 元素为速度 [km/s]。

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

get_gm(body)[源代码]

获取天体的引力参数 GM。

参数:

body (str) -- 天体名称。

返回:

GM 值,单位 km³/s²。

返回类型:

float

get_gm_values()[源代码]

获取所有管理天体的引力常数 (GM) 值。

返回:

与 self.bodies 顺序对应的 GM 值数组,单位通常为 km³/s²。

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.dynamics.ephemeris_dynamics module

星历动力学模型 —— 在多体 N 体引力场中传播航天器轨道。

本模块实现 EphemerisDynamics,它继承自 Dynamics,利用 SPICE 星历数据提供的高精度天体位置与引力参数,计算多体引力加速度、 状态转移矩阵 (STM) 并完成数值积分传播。

核心物理模型

采用 受限 N 体问题 (Restricted N-Body Problem) 建模:

  1. system.origin 为坐标原点(通常是主天体,如地球)。

  2. 原点天体对航天器施加中心引力加速度。

  3. 其余天体(如月球、太阳等)对航天器施加第三体摄动加速度, 同时扣除其对原点天体的引力加速度(即间接项),以保持坐标原点 位于原点天体而非质心。

加速度公式(以原点天体 P0 为中心):

\[a = - \mu_0 \frac{r}{|r|^3} - \sum_i \mu_i \left[ \frac{r - r_i}{|r - r_i|^3} + \frac{r_i}{|r_i|^3} \right]\]

引用

  • Battin, R. H. An Introduction to the Methods of Astrodynamics.

  • Gurfil, P., & Seidelmann, P. K. Celestial Mechanics and Astrodynamics.

class e2m2e.algorithm.dynamics.ephemeris_dynamics.EphemerisDynamics(system)[源代码]

基类:Dynamics

星历 N 体动力学类,提供运动方程、STM 变分方程与轨道传播功能。

参数:

system (EphemerisSystem) -- 星历系统配置,包含天体列表、SPICE 内核接口、参考系与原点天体等信息。

变量:
  • system (e2m2e.algorithm.dynamics.ephemeris_system.EphemerisSystem) -- 星历系统对象(EphemerisSystem ),提供 bodies / origin / get_gm / get_body_position 等星历接口。

  • integrator (str) -- SciPy 积分器名称,默认 "DOP853" (8 阶 Runge-Kutta)。

  • rtol (float) -- 相对积分容差。

  • atol (float) -- 绝对积分容差。

  • max_step (float) -- 积分器最大步长(秒)。

system: EphemerisSystem
MIN_DISTANCE = 1e-06
equations_of_motion(t, state)[源代码]

计算受限 N 体问题的运动方程右端项(加速度)。

对每个天体分别处理:

  • 原点天体:中心引力 -μ₀ r/|r|³

  • 摄动天体:第三体摄动 -μᵢ [(r-rᵢ)/|r-rᵢ|³ + rᵢ/|rᵢ|³]; 第二项为间接项(扣除摄动天体对原点的引力)。

参数:
  • t (float) -- 历元时刻(ephemeris seconds past J2000),用于查询天体星历位置。

  • state (ndarray[tuple[Any, ...], dtype[floating]]) -- 航天器状态向量,形状 (6,),前 3 个元素为位置 [km], 后 3 个元素为速度 [km/s]。

返回:

状态导数向量,形状 (6,),即 [v, a]

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

compute_jacobian_A(t, state)[源代码]

计算星历 N 体状态方程的雅可比矩阵 A(t)。

A = | 0₃ₓ₃ I₃ₓ₃ |
U₃ₓ₃ 0₃ₓ₃ |

其中 U = ∂a/∂r 是加速度对位置的偏导数 (3x3)。 N 体问题中无速度相关力,因此 ∂a/∂v = 0。

参数:
返回:

雅可比矩阵,形状 (6, 6)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

equations_with_stm(t, augmented_state)[源代码]

计算含状态转移矩阵 (STM) 的增广运动方程右端项。

增广状态向量布局:[r(3), v(3), Φ(36)],共 42 维。 其中 Φ 为 6×6 状态转移矩阵按行展平。

参数:
返回:

增广状态导数向量,形状 (42,),即 [v, a, dΦ/dt_flat]

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.forces package

力模型类:ForceModel/PhysicalModel 子类/推力。

Python 类是"力模型定义"(参数验证 + to_rust_spec 序列化),与 Rust e2m2e-forces 的 CompiledForce 枚举对应(ADR 0011,源:core/forces/)。 配置 schema 在 data/templates/force_config.py (纯数据);大气密度模型 (atmosphere.py)一并迁入(源 core/atmosphere/)。

FiniteBurn(恒质量 6D)与 VariableMassFiniteBurn(变质量 7D)均通过 Rust Rust 编译传播执行;仅可序列化的固定控制可下沉,任意 Python callable 会显式拒绝。

e2m2e.algorithm.forces.force_config module

ForceModel 配置驱动:力模型 ↔ dict 序列化与 JSON IO。

设计见 ADR 0004。容器级编排(信封、version、entry 拼装)在 ForceModel.to_config / from_config;本模块只负责"单条力"的 类型分发与 JSON 文件读写。

e2m2e.algorithm.forces.force_config.serialize_force(force)[源代码]

把单条力序列化为 {type, params};未知类型抛 NotSerializableError

参数:

force (PhysicalModel)

返回类型:

dict[str, Any]

e2m2e.algorithm.forces.force_config.build_force(type_name, params)[源代码]

按 type 名与 params 构造单条力;未知 type 抛 ValueError

参数:
返回类型:

PhysicalModel

e2m2e.algorithm.forces.force_config.dump_force_config(fm, path)[源代码]

ForceModel.to_config() 的结果写入 JSON 文件。

参数:
返回类型:

None

e2m2e.algorithm.forces.force_config.load_force_config(path, system)[源代码]

从 JSON 文件读取配置并构建 ForceModel

参数:
返回类型:

Any

e2m2e.algorithm.forces.force_model module

力模型容器与 Rust 积分器传播实现。

class e2m2e.algorithm.forces.force_model.ForceEntry(name, force, enabled=True)[源代码]

基类:object

容器内单个力模型的注册记录。

参数:
name: str
force: PhysicalModel
enabled: bool = True
class e2m2e.algorithm.forces.force_model.ForceModel(system, forces=None)[源代码]

基类:object

聚合多个 PhysicalModel 并完成传播的动力学容器。

不继承 DynamicsDynamics 是 CR3BP/Ephemeris 的基类,其 propagate() 基于 scipy.solve_ivp 与 STM 模板方法;ForceModel 用 Rust rk_step 单步步进器实现自适应传播,支持 with_stm=True (各力解析雅可比叠加、无雅可比的力用有限差分兜底),不支持 Jacobi。 此前形式上继承 Dynamics 只为复用几个数据属性,却全部重写 propagate 并对 STM/Jacobi 抛 NotImplementedError——是 LSP 违反(假继承)。

参数:
DEFAULT_TOLERANCE = 1e-12
DEFAULT_MAX_STEP = 60.0
STATE_DIM = 6
STM_DIM = 42
__init__(system, forces=None)[源代码]

初始化 ForceModel。

参数:
  • system (Any) -- 动力学系统,必须提供 coordinate_system

  • forces (list[PhysicalModel] | None) -- 初始力模型列表,默认空列表。

返回类型:

None

rtol: float
atol: float
max_step: float
last_trajectory: tuple[ndarray, ndarray] | None
property forces: tuple[PhysicalModel, ...]

当前聚合的力模型,只读(含已 disable 的项)。

add_force(force, name=None)[源代码]

添加一个力模型。

参数:
  • force (PhysicalModel) -- 待添加的力模型。

  • name (str | None) -- 力模型的名字。缺省时按类名自动生成,遇同类自动消歧 (FooFoo_2Foo_3…)。显式给出且与已有名字 冲突时抛 ValueError

返回类型:

None

get_force(name)[源代码]

按名取力模型;不存在抛 KeyError

参数:

name (str)

返回类型:

PhysicalModel

list_forces()[源代码]

返回所有力模型的注册记录(含已 disable 的项)。

forces 属性的区别:本方法暴露 nameenabled 两个维度。

返回类型:

list[ForceEntry]

enable(name)[源代码]

按名启用一个力模型;不存在抛 KeyError

参数:

name (str)

返回类型:

None

disable(name)[源代码]

按名禁用一个力模型(跳过加速度计算,但保留在容器内)。

不存在抛 KeyError

参数:

name (str)

返回类型:

None

to_config()[源代码]

序列化为配置字典 {version, forces: [...]}

每条力经 force_config.serialize_force{type, params}, 容器补 nameenabled。round-trip 契约见 ADR 0004。

返回类型:

dict[str, Any]

classmethod from_config(config, system)[源代码]

从配置字典构建 ForceModel

校验 version,逐条 force_config.build_force 构造并按 name 注册;enabled: false 的条目构造后立即 disable。

参数:
返回类型:

ForceModel

remove_force(index)[源代码]

移除一个力模型(按索引或名字)。

参数:

index (int | str) -- 整数索引,或力模型注册名。

抛出:
返回类型:

None

propagate(initial_state, t_span, t_eval=None, with_stm=False, with_jacobi=False, *, initial_step=None, events=None, max_steps=100000, method=None)[源代码]

使用 Rust 编译传播轨迹(零跨界)。

issue #378:默认传播一律走编译 Rust(propagate_compiled / propagate_compiled_stm_py / propagate_compiled_lowthrust)。 扩展不可用(RustExtensionUnavailableError)或力模型无 Rust spec (NotImplementedError 能力错误)时显式报错,不再静默回退 Python/scipy。

参数:
  • initial_state (ArrayLike) -- 初始状态向量,形状 (6,)。

  • t_span (tuple[float, float]) -- 时间区间 [t0, tf],单位为 SPICE et 秒。

  • t_eval (ArrayLike | None) -- 评估时间点数组,默认 linspace(t0, tf, 100)。

  • with_stm (bool) -- 是否同时积分状态转移矩阵。返回字典额外含 stm 键, 形状 (n_points, 6, 6)。STM 不参与步长误差控制(对齐 GMAT)。

  • with_jacobi (bool) -- 不支持,传 True 抛 NotImplementedError。

  • initial_step (float | None) -- 初始步长,默认从初始状态估算。

  • events (list[Callable[[float, ndarray[tuple[Any, ...], dtype[floating]]], float]] | None) -- 不支持。ForceModel 事件传播需要 compiled-forces Rust API, 当前未提供,传 events 抛 NotImplementedError(不能回退 Python RHS,issue #378)。

  • max_steps (int) -- 最大积分步数,默认 100_000。

  • method (RkMethod | None) -- Runge-Kutta 积分器方法,默认 PD45。

返回:

包含 timestatesterminal_event_index 的字典; with_stm=True 时额外含 stm 键。

返回类型:

dict[str, Any]

propagate_maneuvers(initial_state, t_span, burns, *, initial_step=None, max_steps=100000, method=None)[源代码]

带脉冲机动的传播:coast 段之间在 burn epoch 处施加 Δv。

按 epoch 排序 burns,依次 coast → 施加 Δv → 续传。burn epoch 处 输出行携带 post-burn 速度(丢 pre-burn 行,无重复 epoch)。

参数:
返回类型:

dict[str, Any]

e2m2e.algorithm.forces.force_mapping module

摄动开关 → e2m2e 力模型配置映射表。

inputs-dac.txt(第 9~17 行 + 阶次/DYB 行)的力模型是"地球+月球质点 引力常开 + 一组摄动开关";e2m2e 侧是 ForceModel 聚合若干 PhysicalModel (ADR 0004 配置驱动)。本模块给出两者的逐项对应,产出 ForceModel.from_config 可直接消费的配置字典,保证"同款力模型"两侧 可复现。

对应关系(地心 GCRS 传播)如下:

  • 基础模型(常开):地球质点 PointMassGravity(EARTH) (状态以地心为 原点,中心项模型适用);月球质点 ThirdBodyGravity(MOON)——地心 传播下航天器状态不以月心为原点,PointMassGravity(MOON) 会把月心 引力错算成朝向地心,必须用带星历直接项的 ThirdBodyGravity (自带 间接项,无需另补)。

  • earth_nonspherical=1:地球中心项换成 GravityField(EARTH, degree=order=earth_degree) (球谐含 degree=0 中心项, 不重复计质点)。

  • moon_nonspherical=1:月球中心项换成 GravityField(MOON, degree=order=moon_degree) + IndirectTerm(MOON) (球谐只算直接 引力,地心加速系需单补间接项)。

  • sun_body=1ThirdBodyGravity(SUN)

  • planets=1:七大行星(水星~海王星)各一个 ThirdBodyGravity

  • solar_radiation=1 (炮弹模型):SolarRadiationPressurearea=等效面质比, mass=1, cr=1——输入侧"等效面质比"(dyb[0])已把 Cr 折进去,故 cr 取 1;无阴影模型(阴影行为未确认)。

  • solar_radiation=2 (ECOM):未实现,NotImplementedError (#253)。

  • atmosphere=1DragModel (ExponentialAtmosphere 默认 f107/ap, cd=2.2,面积同取等效面质比;输入侧 Cd/大气模型参数不可见)。

  • relativity=1RelativisticCorrection(EARTH),仅 Schwarzschild 主项(修正项构成未确认,待 P0 对齐实验核实)。

  • tide=1:地球固体潮,挂在地球 GravityFieldtide_mode="solid" 上——因此要求 earth_nonspherical=1, 否则抛 ValueError。月球引力场不带潮(开关写明"地球的潮汐")。

  • coupling=1 (地球非球形×大天体耦合项):强制启用固体潮 tide_mode="solid" (与 tide=1 共用 IERS TN32 固体潮公式)。

output_step 不是力模型参数,不进配置;它是传播输出网格,由调用方 (阶段 3 传播对齐)用于构造 t_eval

e2m2e.algorithm.forces.force_mapping.PLANET_BODIES: tuple[str, ...] = ('MERCURY', 'VENUS', 'MARS', 'JUPITER', 'SATURN', 'URANUS', 'NEPTUNE')

"大行星的第三体引力"对应的摄动天体(地球除外,月球有独立开关)

e2m2e.algorithm.forces.force_mapping.perturbation_to_force_config(perturbation=None, *, earth_degree=10, moon_degree=10, dyb=None, area_to_mass=None)[源代码]

把摄动开关映射为 e2m2e ForceModel 配置字典。

参数:
  • perturbation (dict[str, int] | None) -- 摄动开关字典(键与取值同 inputs_dacDEFAULT_PERTURBATION);缺省项取默认值。

  • earth_degree (int) -- 地球非球形引力位阶次数(degree=order)。

  • moon_degree (int) -- 月球非球形引力位阶次数(degree=order)。

  • dyb (Sequence[float] | None) -- DYB 面质比系数 9 分量;dyb[0] 为等效面质比(m²/kg), 炮弹光压与大气阻力共用;其余分量在炮弹档忽略。

  • area_to_mass (float | None) -- 显式等效面质比(m²/kg),给出时覆盖 dyb[0]

返回:

{"version": 1, "forces": [...]} 配置字典,可直接交给 ForceModel.from_config(config, system)dump_force_config 链路。

抛出:
  • NotImplementedError -- solar_radiation=2 (ECOM,#253)。

  • ValueError -- 开关取值非法;tide=1coupling=1earth_nonspherical=0dyb 非 9 分量。

返回类型:

dict[str, Any]

e2m2e.algorithm.forces.physical_model module

力模型抽象基类。

class e2m2e.algorithm.forces.physical_model.PhysicalModel[源代码]

基类:object

物理力模型基类。

力模型在 Python 侧只承担"配置定义"职责:参数验证、to_rust_spec 序列化、to_config/from_config。加速度与雅可比计算全部由 Rust 编译路径(ForceModel.propagatepropagate_compiled/ propagate_compiled_stm_py)承载,不保留 Python 参考实现(issue #378): 需要 Rust 的场景扩展不可用即显式报错,不静默回退到 Python。

所有坐标约定都在 system.coordinate_system 下完成;需要非默认坐标系 计算的子类应通过 system.coordinate_system.transform_state() / transform_vector() 自行完成转换。

to_rust_spec(system)[源代码]

序列化该 force 为 Rust propagate_compiled 接受的元组。

返回 None 表示该 force 不支持 Rust 编译,ForceModel.propagate 检测到任一 force 返回 None 时抛能力错误(显式报错,不静默回退到 Python eom 路径)。子类按需覆盖。元组协议见 parse_force_tuple (Rust lib.rs):

  • GravityField: ("gravity", c_flat, s_flat, mu, radius, degree, order, input_frame, propagation_frame, body, propagation_origin, tide_mode, k_love_flat, k_plus_flat_or_none)

  • ThirdBody: ("third_body", naif_id_str, mu)

  • Indirect: ("indirect", naif_id_str, mu)

  • SRP: ("srp", area, mass, cr, shadow_bodies_list)

参数:

system (System) -- 当前动力学系统(用于查 origin / frame 等运行时参数)。

返回:

力元组,或 None

返回类型:

tuple | None

e2m2e.algorithm.forces.physical_model.require_inertial_frame(system, t)[源代码]

校验参考系为惯性系,返回 (coordinate_system, spice, origin_body)。

供在传播惯性系(ICRF,轴旋转矩阵为单位阵)中直接计算的力模型调用。 非惯性系(如 ITRFApproxAxes)抛 NotImplementedError

参数:
返回类型:

tuple[Any, Any, str]

e2m2e.algorithm.forces.point_mass_gravity module

点质量引力模型。

class e2m2e.algorithm.forces.point_mass_gravity.PointMassGravity(body, mu=None)[源代码]

基类:PhysicalModel

点质量引力加速度模型。

返回 \(-\mu / r^3 \cdot \mathbf{r}\),即中心天体二体引力加速度。

参数:
  • body (str) -- 中心天体名称(如 'EARTH')。

  • mu (float | None) -- 引力参数(km³/s²)。为 None 时, 在 to_rust_spec 中从 system.gravitational_parameter(body) 获取。

property body: str

中心天体名称。

property mu: float | None

显式设置的引力参数;None 表示从 system 获取。

to_rust_spec(system)[源代码]

序列化为 Rust propagate_compiled 接受的 ("point_mass", mu) 元组。

GravityField (degree=0 等价点质量)的 Rust 路径对齐,但更轻量 (不查 body-fixed 轴、不查星历)。muNone 时从 system 解析。

参数:

system (System)

返回类型:

tuple | None

e2m2e.algorithm.forces.gravity_field module

球谐重力场力模型。

class e2m2e.algorithm.forces.gravity_field.GravityField(body, degree=2, order=None, gravity_file=None, input_frame=None, tide_mode='none', tide_convention='tide_free', epoch=None, polar_motion_provider=None)[源代码]

基类:PhysicalModel

球谐重力场模型。

在指定的固连坐标系(默认 ITRF93)中展开球谐级数,计算引力加速度。 加速度计算全部由 Rust 编译路径承载(("gravity", ...) 力元组, crates/e2m2e-forces/src/forces/gravity_field.rs,含潮汐),Python 侧 不保留参考实现(issue #378)。

参数:
  • body (str)

  • degree (int)

  • order (int | None)

  • gravity_file (str | Path | None)

  • input_frame (str | None)

  • tide_mode (str)

  • tide_convention (str)

  • epoch (float | None)

  • polar_motion_provider (Callable[[float], tuple[float, float]] | None)

__init__(body, degree=2, order=None, gravity_file=None, input_frame=None, tide_mode='none', tide_convention='tide_free', epoch=None, polar_motion_provider=None)[源代码]

初始化 GravityField。

参数:
  • body (str) -- 中心天体名称,如 'EARTH''MOON'

  • degree (int) -- 最大 degree,默认 2。

  • order (int | None) -- 最大 order,默认等于 degree。

  • gravity_file (str | Path | None) -- 自定义重力场文件路径(.gfc 或 .cof);None 时按 body 取包内默认文件(地球 EGM96-to10,月球 GRGM900C)。

  • input_frame (str | None) -- 球谐展开坐标系的 SPICE frame 名。None 时按 body 推导:地球 ITRF93、月球 MOON_PA;其它天体需显式提供。

  • tide_mode (str) -- 潮汐档位,对齐 GMAT ETide 三档: "none" (无潮汐)、"solid" (固体潮 Step1+Step2)、 "solid_and_pole" (固体潮 + 极潮)。

  • tide_convention (str) -- 系数约定,"tide_free""zero_tide" 。 zero_tide 模式减去永久潮汐(系数已含永久分量)。

  • epoch (float | None) -- dot 项(系数长期变化率)外推的参考历元(SPICE et 秒)。 与 .gfc 的 dot 行配合;None 表示不外推。

  • polar_motion_provider (Callable[[float], tuple[float, float]] | None) -- 极潮 xp/yp 提供者,签名 (et) -> (xp, yp) (arcsec)。solid_and_pole 档必需;由调用方从 gmat_eop 注入。

返回类型:

None

property body: str

中心天体名称。

property degree: int

最大 degree。

property order: int

最大 order。

property input_frame: str

球谐展开坐标系的 SPICE frame 名。

property gravity_file: str | Path | None

用户传入的自定义 .gfc 路径;None 表示用包内默认 EGM96。

property gravitational_parameter: float

引力参数 GM。

property reference_radius: float

参考半径 R_e。

property coefficients: dict[str, ndarray[tuple[Any, ...], dtype[floating]]]

正规化系数副本。

property tide_mode: str

潮汐档位。

to_rust_spec(system)[源代码]

序列化为 Rust propagate_compiled 的 ("gravity", ...) 元组。

SolidAndPole 档暂不支持(需外部 xp/yp provider),返回 None 让 ForceModel 回退 Python 路径。

参数:

system (Any)

返回类型:

tuple | None

property tide_convention: str

系数约定。

e2m2e.algorithm.forces.gravity_file module

重力场文件解析。

支持两种格式:

  • ICGEM .gfcload_gfc_file)。

  • GMAT .cofload_cof_file),移植 GMAT HarmonicGravity.cppLM_LoadCof 逻辑。

统一入口 load_gravity_file 按文件扩展名分发。

class e2m2e.algorithm.forces.gravity_file.GravityFileData(model_name, mu, radius, max_degree, normalized, C, S, dotC, dotS)[源代码]

基类:object

解析后的重力场文件数据。

参数:
model_name: str
mu: float
radius: float
max_degree: int
normalized: bool
C: ndarray[tuple[Any, ...], dtype[floating]]
S: ndarray[tuple[Any, ...], dtype[floating]]
dotC: ndarray[tuple[Any, ...], dtype[floating]]
dotS: ndarray[tuple[Any, ...], dtype[floating]]
e2m2e.algorithm.forces.gravity_file.load_gfc_file(path, *, requested_degree=None, default_mu=398600.4415, default_radius=6378.1363)[源代码]

加载 ICGEM .gfc 格式重力场文件。

参数:
  • path (str | Path) -- 文件路径。

  • requested_degree (int | None) -- 请求的最大 degree,用于校验。

  • default_mu (float) -- 文件头缺失 GM 时的默认值,单位 km^3/s^2。

  • default_radius (float) -- 文件头缺失参考半径时的默认值,单位 km。

返回:

解析后的重力场数据。

返回类型:

GravityFileData

e2m2e.algorithm.forces.gravity_file.load_cof_file(path, *, requested_degree=None, default_mu=398600.4415, default_radius=6378.1363)[源代码]

加载 GMAT .cof 格式重力场文件。

解析逻辑移植自 GMAT HarmonicGravity.cppLM_LoadCof。文件结构:

  • 头行 POTFIELD<NNN><MMM> <flag> <Mu> <RefRadius> <Normalized>

    • NNN/MMM 各 3 字符,分别为文件中包含的最大 degree 与 order (如 POTFIELD360360)。

    • Mu 单位 m³/s²×1e9,解析时除以 1e9 得到 km³/s²。

    • RefRadius 单位 m×1e3,解析时除以 1e3 得到 km。

    • Normalized 为 1.0 表示系数已完全正规化。

  • 系数行 RECOEF <n:3> <m:3> <Cnm:21> <Snm:21>,按固定列宽解析 (n=substr(8,3), m=substr(11,3), Cnm=substr(17,21), Snm=substr(38,21))。 m=0 时无 Snm 列。

  • COMMENTC + 空格开头的行为注释,跳过。

返回结构与 load_gfc_file() 完全一致。COF 文件不含 dot 项, 故 dotC/dotS 全零;COF 通常省略 C₀₀,此处补 1.0。

参数:
  • path (str | Path) -- 文件路径。

  • requested_degree (int | None) -- 请求的最大 degree,用于截断读取。

  • default_mu (float) -- 头行缺失 GM 时的默认值,单位 km^3/s^2。

  • default_radius (float) -- 头行缺失参考半径时的默认值,单位 km。

返回:

解析后的重力场数据。

返回类型:

GravityFileData

e2m2e.algorithm.forces.gravity_file.load_gravity_file(path, *, requested_degree=None, default_mu=398600.4415, default_radius=6378.1363)[源代码]

按文件扩展名分发到对应格式的解析器。

其它扩展名抛 ValueError

参数:
  • path (str | Path) -- 重力场文件路径。

  • requested_degree (int | None) -- 请求的最大 degree。

  • default_mu (float) -- 头部缺失 GM 时的默认值,单位 km^3/s^2。

  • default_radius (float) -- 头部缺失参考半径时的默认值,单位 km。

返回:

解析后的重力场数据。

返回类型:

GravityFileData

e2m2e.algorithm.forces.gravity_file.extrapolate_coefficients(C, S, dotC, dotS, t, t0)[源代码]

按 dot 项(系数长期变化率)外推球谐系数到历元 t。

dot 单位为 1/年(ICGEM .gfc 标准,与 GMAT DAYS_PER_YEAR 一致); t 与 t0 为 SPICE et 秒,差值转换为儒略年。

参数:
返回:

外推后的 (C_out, S_out),新数组(不修改输入)。

返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]]

e2m2e.algorithm.forces.third_body_gravity module

第三体引力摄动模型。

class e2m2e.algorithm.forces.third_body_gravity.ThirdBodyGravity(body, mu=None)[源代码]

基类:PhysicalModel

第三体引力摄动加速度模型。

对一个摄动天体 \(i\),返回相对原点天体 \(P_0\) 的第三体摄动加速度:

\[a = -\mu_i \left[ \frac{r - r_i}{|r - r_i|^3} + \frac{r_i}{|r_i|^3} \right]\]

其中 \(r\) 为航天器相对原点的位置,\(r_i\) 为摄动天体相对原点 的位置(由 system.get_body_position 自动以 system.origin 为观察者 计算)。第一项为直接项(摄动天体对航天器的引力),第二项为间接项 (扣除摄动天体对原点的引力),与 EphemerisDynamics 的第三体分支 逐字对齐。

参数:
  • body (str) -- 摄动天体名称(如 'MOON''SUN')。

  • mu (float | None) -- 引力参数(km³/s²)。为 None 时,在 to_rust_spec 中 从 system.gravitational_parameter(body) 获取。

MIN_DISTANCE = 1e-06

防止除零的最小距离钳位(km,约 1 米),与 EphemerisDynamics.MIN_DISTANCE 一致。

property body: str

摄动天体名称。

property mu: float | None

显式设置的引力参数;None 表示从 system 获取。

to_rust_spec(system)[源代码]

序列化为 ("third_body", naif_id_str, mu)

返回类型:

tuple | None

e2m2e.algorithm.forces.indirect_term module

第三体引力间接项。

class e2m2e.algorithm.forces.indirect_term.IndirectTerm(body, mu=None)[源代码]

基类:PhysicalModel

第三体引力的间接项(geocentric 加速系所需)。

在以某天体(如地球)为原点的非惯性系下传播时,运动方程需对每个摄动 天体 \(i\) 补一项 -μ_i · r_i / |r_i|³ (间接项),扣除摄动天体 对原点的引力(见 EphemerisDynamics 的 N 体闭式公式)。

ThirdBodyGravity 内部已自带间接项,但 GravityField 只算球谐 直接引力(含中心项 degree=0),不带间接项。所以用 GravityField 模拟月球(中心+非球形)时,必须单独补月球间接项——既不能用 ThirdBodyGravity("MOON") (会与 GravityField 的 degree=0 中心项 重复算月球点质量),也不能省略(地心系下物理不正确)。

加速度:-μ_body · r_body / |r_body|³,其中 r_body 为摄动天体相对 system.origin 的位置(由 system.get_body_position 自动以 origin 为观察者计算)。与 ThirdBodyGravity 的间接项逐字一致。

参数:
  • body (str) -- 摄动天体名称(如 'MOON')。

  • mu (float | None) -- 引力参数(km³/s²)。为 None 时, 在 to_rust_spec 中从 system.gravitational_parameter(body) 获取。

property body: str

摄动天体名称。

property mu: float | None

显式设置的引力参数;None 表示从 system 获取。

to_rust_spec(system)[源代码]

序列化为 ("indirect", naif_id_str, mu)

返回类型:

tuple | None

e2m2e.algorithm.forces.atmosphere module

标准指数大气密度模型。

class e2m2e.algorithm.forces.atmosphere.ExponentialAtmosphere(f107=150.0, ap=15.0)[源代码]

基类:object

US Standard Atmosphere 1976 分段指数大气密度模型。

在每个高度层内使用 ρ(h) = ρ₀ · exp(-(h - h₀) / H) 计算密度。 层间标高由相邻断点密度比推导,确保密度连续且单调递减。 F10.7 太阳射电通量和 Ap 地磁指数通过线性乘法因子对基准密度做一阶修正。

参数:
  • f107 (float) -- F10.7 太阳射电通量(sfu),默认 150(中等太阳活动)。

  • ap (float) -- Ap 地磁指数,默认 15(中等地磁活动)。

property f107: float

F10.7 太阳射电通量(sfu)。

property ap: float

Ap 地磁指数。

density(altitude)[源代码]

返回指定高度处的大气密度。

高度超出模型范围时:高于 1000 km 返回 0(阻力可忽略), 低于 0 km 钳到 0 km(用地表密度,避免负高度导致 exp 爆炸)。

参数:

altitude (float) -- 几何高度,单位 km。

返回:

大气密度,单位 kg/m³。

返回类型:

float

e2m2e.algorithm.forces.drag module

大气阻力力模型。

class e2m2e.algorithm.forces.drag.DragModel(atmosphere, area, mass, body='EARTH', cd=2.2)[源代码]

基类:PhysicalModel

大气阻力力模型。

在 ITRF(地固系)中计算大气密度与相对速度,求得阻力加速度后转换回 参考系。大气在 ITRF 中静止,因此相对速度等于航天器 ITRF 速度。

加速度计算全部由 Rust 编译路径承载(("drag", ...) 力元组, crates/e2m2e-forces/src/forces/drag.rs),Python 侧不保留参考实现 (issue #378)。to_rust_spec 需 system 提供 SPICE(ITRF93 pxform 帧旋转);不满足时返回 NoneForceModel.propagate 据此显式报 能力错误(不静默回退)。

参数:
  • atmosphere (ExponentialAtmosphere) -- 大气密度模型(依赖注入)。

  • body (str) -- 中心天体名称,默认 'EARTH'

  • cd (float) -- 阻力系数,默认 2.2。

  • area (float) -- 航天器迎风截面积,单位 m²。

  • mass (float) -- 航天器质量,单位 kg。

property atmosphere: ExponentialAtmosphere

大气密度模型。

property body: str

中心天体名称。

property cd: float

阻力系数 Cd。

property area: float

迎风截面积,单位 m²。

property mass: float

航天器质量,单位 kg。

property ballistic_coefficient: float

弹道系数 Cd·A/m,单位 m²/kg。

to_rust_spec(system)[源代码]

序列化为 Rust ("drag", area, mass, cd, propagation_frame, f107, ap) 元组。

f107/ap 从注入的大气模型取出,确保 Rust 路径与配置用同一组太阳活动 参数(issue #315 的 drag 静默分歧先例,Rust 与配置同源)。

需要 system 提供 SPICE 以做 ITRF93 pxform 帧旋转。若 system 未暴露 spice 属性、或中心天体非 EARTH,返回 None——由 ForceModel.propagate 显式报能力错误,不静默回退 Python 路径。

参数:

system (Any)

返回类型:

tuple | None

e2m2e.algorithm.forces.srp module

太阳光压力模型(cannonball / 基础 Cr 系数)。

实现 Montenbruck & Gill eq. 3.75 的 cannonball SRP 模型:

a = flux_factor · P · (1 AU / r)² · Cr · A / m · û

其中 û 为 Sun→SC 单位向量(指向远离太阳),P = 4.56e-6 N/m² 为 1 AU 处的太阳光压常数。flux_factor [0, 1] 由阴影模型给出(全光照=1,本影=0)。

加速度计算全部由 Rust 编译路径承载(("srp", ...) 力元组, crates/e2m2e-forces/src/forces/srp.rs),Python 侧不保留参考实现(issue #378)。

引用

  • Montenbruck & Gill, Satellite Orbits, eq. 3.75

  • GMAT R2026a SolarRadiationPressure (Spherical 模型)

class e2m2e.algorithm.forces.srp.SolarRadiationPressure(area, mass, cr=1.5, shadow=None)[源代码]

基类:PhysicalModel

基础 Cr 系数太阳光压模型(cannonball)。

参数:
  • area (float) -- 航天器迎风截面积,单位 m²。

  • mass (float) -- 航天器质量,单位 kg。

  • cr (float) -- 辐射反射系数(1=全吸收,2=全反射),默认 1.5。

  • shadow (ConicalShadowModel | None) -- 阴影模型(注入)。None 表示全光照(flux_factor 恒为 1)。

property area: float

截面积(m²)。

property mass: float

质量(kg)。

property cr: float

辐射反射系数 Cr。

property shadow: ConicalShadowModel | None

注入的阴影模型,None 表示全光照。

to_rust_spec(system)[源代码]

序列化为 ("srp", area, mass, cr, shadow_bodies)

返回类型:

tuple | None

class e2m2e.algorithm.forces.srp.VariableMassSolarRadiationPressure(area, cr=1.5, shadow=None)[源代码]

基类:PhysicalModel

质量由增广状态提供的 cannonball 光压模型。

小推力任务质量在线衰减,固定质量的 SolarRadiationPressure 会 在整个传播区间用同一初始质量。本类只存截面积 area``(m²)与 ``cr, 质量在每个增广状态里取出,因此 a = flux·P·(1AU/r)²·cr·area/m 随 推进耗质量自动更新。

参数:
  • area (float) -- 航天器迎风截面积,单位 m²。

  • cr (float) -- 辐射反射系数,默认 1.5。

  • shadow (ConicalShadowModel | None) -- 阴影模型(注入);None 表示全光照。

property area: float
property cr: float
property shadow: ConicalShadowModel | None
to_rust_spec(system)[源代码]

序列化为 ("srp_variable_mass", area, cr, shadow_bodies)

返回类型:

tuple | None

e2m2e.algorithm.forces.ecom_srp module

ECOM 光压模型(DFH 兼容 9 系数 DYB 参数化)。

ECOM(Empirical CODE Orbit Model)将光压加速度分解到卫星本体坐标系的 D(太阳方向)、Y(太阳帆板法向)、B(D×Y)三轴,每个方向用常量+周期项展开。

DFH 的 DYB 9 系数含义: - dyb[0] = 等效面质比 (m²/kg) - dyb[1:5] = D 方向周期项(cos(u), sin(u), cos(2u), sin(2u)) - dyb[5:7] = Y 方向(cos(u), sin(u)) - dyb[7:9] = B 方向(常量, cos(u))

当仅 dyb[0] 非零时,模型退化为标准 cannonball SRP。

加速度计算全部由 Rust 编译路径承载(("ecom_srp", dyb, shadow_bodies) 力元组,crates/e2m2e-forces/src/forces/ecom.rs),Python 侧不保留参考实现 (issue #378)。

class e2m2e.algorithm.forces.ecom_srp.EcomSolarRadiationPressure(dyb, shadow=None)[源代码]

基类:PhysicalModel

ECOM 光压模型(DFH 兼容 9 系数 DYB 参数化)。

参数:
  • dyb (list[float]) -- DYB 系数列表(长度 9)。 - dyb[0] = 等效面质比 (m²/kg) - dyb[1:5] = D 方向周期项(cos(u), sin(u), cos(2u), sin(2u)) - dyb[5:7] = Y 方向(cos(u), sin(u)) - dyb[7:9] = B 方向(常量, cos(u))

  • shadow (ConicalShadowModel | None) -- 阴影模型(注入)。None 表示全光照(flux_factor 恒为 1)。

property dyb: list[float]

DYB 系数列表副本。

property shadow: ConicalShadowModel | None

注入的阴影模型,None 表示全光照。

to_rust_spec(system=None)[源代码]

序列化为 ("ecom_srp", dyb, shadow_bodies)

参数:

system (System | None)

返回类型:

tuple

to_config()[源代码]

序列化为配置字典。

返回类型:

dict

classmethod from_config(config)[源代码]

从配置字典构造实例。

参数:

config (dict)

返回类型:

EcomSolarRadiationPressure

e2m2e.algorithm.forces.shadow module

圆锥阴影模型(地影/月影)。

实现 GMAT ShadowState 的圆锥阴影算法(Montenbruck & Gill §3.4.2 的 "Shadow Function"):从航天器看太阳与遮挡体的视角径 (a, b) 与角距 c,分四 分支判定全光照 / 本影 / 半影 / 环形食,半影区用 M&G eq. 3.92-3.94 的精确 圆面重叠面积。多遮挡体合成遵循 GMAT GMT-6543 规范。

引用

  • Montenbruck & Gill, Satellite Orbits, §3.4.2 (eq. 3.85-3.94)

  • GMAT R2026a ShadowState / SolarRadiationPressure::GetShadowStateFromAllBodies

class e2m2e.algorithm.forces.shadow.ConicalShadowModel(bodies=('EARTH',), radii=None)[源代码]

基类:object

圆锥阴影模型(本影 + 半影 + 环形食)。

参数:
  • bodies (list[str] | tuple[str, ...]) -- 遮挡体名称列表(大写),默认 ["EARTH"]。需显式列出所有 想计算阴影的天体(含传播原点天体,若其阴影相关)。

  • radii (dict[str, float] | None) -- 天体半径覆盖字典(km),用于补充默认表外的天体。

property bodies: tuple[str, ...]

遮挡体列表(大写)。

property radii: dict[str, float] | None

用户传入的天体半径覆盖(大写键);None 表示全用默认值。

body_radius(body)[源代码]

返回天体半径(km)。

参数:

body (str)

返回类型:

float

flux_factor(t, state, system)[源代码]

系统感知光照份额。

system 读取传播原点与 SPICE,查询太阳及各遮挡体相对原点的 J2000 位置,调用纯几何 _body_flux_factor_combine_body_fluxes。 要求参考系为惯性系(轴旋转矩阵为单位阵)。

参数:
返回类型:

float

e2m2e.algorithm.forces.earth_tide module

固体潮修正(天体无关 Step1 + 地球专用 Step2/极潮/永久潮)。

solid_tide_step1 天体无关:对任意中心天体,把扰动体位置 + 该天体的 Love 数表喂进去即可算 ΔC/ΔS(对齐 GMAT HarmonicGravity::IncrementSolidTide)。 Step2(频率相关)、极潮、永久潮修正均为地球专用,保留原样。

公式与系数取自 IERS Technical Note 32 (Conventions 2003),与 GMAT R2026a HarmonicGravity 对齐。单位一致:位置 km、GM km³/s²、参考半径 km。

e2m2e.algorithm.forces.earth_tide.load_love_number_file(path)[源代码]

读取 GMAT 风格 Love 数文件(如 grgm900c.tide)。

文件格式:每行 k <n> <m> <value>``(可带 ``% 注释行与空行)。返回 _LOVE_TABLE_SIZE``×``_LOVE_TABLE_SIZEK[n][m] 表,n=0,1,4 行 默认为零;文件中未给出的项也为零。

参数:

path (str | Path) -- Love 数文件路径。

返回:

K[n][m] 表,形状 (5,5)。

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.forces.earth_tide.solid_tide_step2(et)[源代码]

固体潮 Step 2(频率相关)。

只影响 (2,0)/(2,1)/(2,2)。用 5 个 Delaunay 幅角 + GMST + Table 6.3a/b/c。 量级 ~1e-10(GMAT freq_dep * 1e-12 缩放)。

实现:1:1 移植到 Rust(crates/e2m2e-integrators/src/solid_tide.rs), Python 侧仅做一次 FFI 调用与 reshape。精度回归:< 1e-15(机器精度)。

参数:

et (float) -- SPICE et 秒(past J2000)。

返回:

(DeltaC, DeltaS),各为 5×5 数组;仅 (2,0)/(2,1)/(2,2) 非零。

返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]]

e2m2e.algorithm.forces.earth_tide.solid_tide_step1(perturbers, k_love, k_plus, mu_central, r_central)[源代码]

固体潮 Step 1(频率无关,天体无关)。

对一组扰动天体累加 ΔC/ΔS。公式本身天体无关(IERS TN32 eqn 1, p.59; eqn 4, p.60),Love 数由调用方按中心天体传入。

对每个扰动天体:

ΔC[n][m] += K[n][m]/(2n+1) · (μ_p/μ_c) · (R_c/r)^(n+1) · P_nm(sinφ) · cos(mλ) ΔS[n][m] += K[n][m]/(2n+1) · (μ_p/μ_c) · (R_c/r)^(n+1) · P_nm(sinφ) · sin(mλ)

n=2 且 k_plus 非空时额外(弹性 Love 数,3 阶位移,IERS eqn 4):

ΔC[4][m] += KPlus[m]/5 · ... ; ΔS[4][m] += KPlus[m]/5 · ...

与 GMAT HarmonicGravity::IncrementEarthTide 对齐:其内部对 Sun、Moon 各调一次 IncrementSolidTide 并累加;本函数把"逐体累加"内化,调用方 一次性传完整扰动体列表。

参数:
  • perturbers (list[tuple[ArrayLike, float]] | tuple[ArrayLike, float]) -- 扰动天体列表 [(position, gm), ...],``position`` 为扰动 体相对中心天体的位置(中心天体 body-fixed 系,如 ITRF93/MOON_PA), 形状 (3,)、单位 km;``gm`` 为扰动体 GM(km³/s²)。也接受单个 (position, gm) 元组以兼容旧调用方。

  • k_love (ndarray[tuple[Any, ...], dtype[floating]]) -- n=2,3 阶位移 Love 数表 K[n][m],形状 (5,5)(n=0,1,4 行用零 填充,与 GMAT LoveMax+1=5 对齐)。地球用 _K_EARTH

  • k_plus (ndarray[tuple[Any, ...], dtype[floating]] | None) -- n=2 时的弹性 3 阶位移 KPlus[m],形状 (5,)(m>2 处为零)。 地球用 _K_PLUS_EARTH;月球等无此贡献时传 None

  • mu_central (float) -- 中心天体 GM,km³/s²。

  • r_central (float) -- 中心天体参考半径,km。

返回:

(DeltaC, DeltaS),各为 5×5 数组。

返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]]

实现:1:1 移植到 Rust(crates/e2m2e-integrators/src/solid_tide.rs)。 Python 侧仅做参数打包(perturbers → [px,py,pz,gm,...] 扁平化)+ reshape。

e2m2e.algorithm.forces.earth_tide.pole_tide(et, xp, yp)[源代码]

极潮(固体极潮 IERS p.65 + Desai 海洋极潮 TN32 §6.3)。

只影响 (2,1)。对齐 GMAT ETide::SolidAndPole 档(固体极潮 + 海洋极潮都做); Solid 档不做极潮。

公式:

ym2000 = (JD - JD_J2000) / 365.25 xp_bar = 0.054 + ym2000·0.00083 (IERS p.84 mean pole) yp_bar = 0.357 + ym2000·0.00395 m1 = xp - xp_bar;m2 = -(yp - yp_bar) 固体极潮:ΔC21 -= 1.333e-9·(m1+0.0115·m2);ΔS21 -= 1.333e-9·(m2-0.0115·m1) 海洋极潮:ΔC21 -= 2.2344e-10·(m1-0.01737·m2);ΔS21 -= 1.7680e-10·(m2-0.03351·m1)

参数:
  • et (float) -- SPICE et 秒(past J2000)。

  • xp (float) -- 极移 x 分量(arcsec,IERS EOP C04)。

  • yp (float) -- 极移 y 分量(arcsec)。

返回:

(DeltaC, DeltaS),各为 5×5 数组;仅 (2,1) 非零。

返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]]

实现:1:1 移植到 Rust(crates/e2m2e-integrators/src/solid_tide.rs)。

e2m2e.algorithm.forces.earth_tide.permanent_tide_correction(mu_sun, mu_moon, mu_earth, r_earth, a_sun, a_moon)[源代码]

永久潮汐修正(IERS TN32 Step 3,时间平均)。

zero-tide 系数约定下,GravityField 在叠加固体潮后减去此值——因为 zero-tide 系数已含永久潮汐,运行时若再加完整固体潮(含永久分量)会重复。

solid_tide_step1 在 Sun/Moon 半长轴距离 + 赤道(零纬度,时间平均 近似)计算。GMAT 把永久潮汐处理放在系数加载 setup;e2m2e 用运行时减除, 公式等价。

参数:
  • mu_sun (float) -- Sun/Moon GM,km³/s²。

  • mu_moon (float) -- Sun/Moon GM,km³/s²。

  • mu_earth (float) -- 地球 GM,km³/s²。

  • r_earth (float) -- 地球参考半径,km。

  • a_sun (float) -- Sun/Moon 轨道半长轴,km(时间平均距离近似)。

  • a_moon (float) -- Sun/Moon 轨道半长轴,km(时间平均距离近似)。

返回:

(DeltaC, DeltaS),各为 5×5 数组。

返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]]

e2m2e.algorithm.forces.relativistic_correction module

相对论修正力模型。

class e2m2e.algorithm.forces.relativistic_correction.RelativisticCorrection(central_body, *, primary_body='SUN', enable_schwarzschild=True, enable_lense_thirring=True, enable_de_sitter=True, angular_momentum_vector=None, body_radius=None, c=299792.458, gamma=1.0)[源代码]

基类:PhysicalModel

相对论修正力模型。

实现 Schwarzschild、Lense-Thirring 与 de Sitter(geodesic)三项相对论 加速度修正,公式与 GMAT R2026a RelativisticCorrection 对齐。

加速度计算全部由 Rust 编译路径承载(("relativistic", ...) 力元组, crates/e2m2e-forces/src/forces/relativistic.rs),Python 侧不保留参考 实现(issue #378)。

参数:
  • central_body (str)

  • primary_body (str | None)

  • enable_schwarzschild (bool)

  • enable_lense_thirring (bool)

  • enable_de_sitter (bool)

  • angular_momentum_vector (npt.ArrayLike | None)

  • body_radius (float | None)

  • c (float)

  • gamma (float)

property central_body: str

中心天体名称(大写)。

property primary_body: str | None

de Sitter 项主天体名称(大写),可能为 None

property enable_schwarzschild: bool

Schwarzschild 项开关。

property enable_lense_thirring: bool

Lense-Thirring 项开关。

property enable_de_sitter: bool

de Sitter 项开关。

property angular_momentum_vector: ndarray[tuple[Any, ...], dtype[floating]] | None

Lense-Thirring 角动量矢量(覆盖值),单位 km²/s。

注意:这里的 J 与 GMAT 约定一致,是 (2/5) * * spin_rate 形式的归一化量,不是 SI 物理角动量(kg·m²/s)。

property body_radius: float | None

中心天体赤道半径(覆盖值),单位 km。

property c: float

光速,单位 km/s。

property gamma: float

后牛顿参数 gamma。

to_rust_spec(system)[源代码]

序列化为 ("relativistic", ...) 元组。

  • LT 项需要 sxform + body-fixed frame;本仓库已实测 NRHO 上 LT 量级 < 1m (#343 排查),但完整移植已实现(含 sxform via cspice-sys FFI)。

  • 如果 LT 启用但 angular_momentum_vector 未传,Rust 侧会每步 sxform 自动算(与 Python 一致);如需避免 sxform 开销,可在 Python 侧 预先算好 J 向量并传入 angular_momentum_vector。

返回类型:

tuple | None

e2m2e.algorithm.forces.thrust module

推力与机动模型。

提供两种推力/机动表示:

  • ImpulsiveBurn:瞬时 Δv 机动事件,由 ForceModel.propagate_maneuvers 在指定 epoch 处中断传播并施加速度增量。

  • FiniteBurn:连续推力加速度力模型,继承 PhysicalModel, 在传播过程中实时参与加速度计算。

FiniteBurn 合并了 GMAT R2026a 的 FiniteBurn (配置)与 FiniteThrust (力模型)两层,未引入 Thruster 硬件层。 推力大小与方向解耦:thrust_profile(t) 返回标量推力(N), direction 给出方向向量(固定向量或随状态更新的可调用), 内部归一化为单位向量。质量为常量(不支持推进剂消耗)。

VariableMassFiniteBurn 是其可变质量对应物:质量作为状态量 state[6] 随推力消耗( = −T/(Isp·g₀)),是低推力最优控制与 月面动力下降的受控动力学基座。详见 docs/plans/lowthrust-foundation-prd.md

direction_frame 支持 "VNB""LVLH"None

  • Nonedirection 直接在传播(惯性)坐标系内解释。

  • "VNB"direction 在 VNB 坐标系下解释,其中 \(V = v/\\|v\\|\) (速度方向), \(N = (r \\times v)/\\|r \\times v\\|\) (角动量方向), \(B = V \\times N\) (副法向)。

  • "LVLH"direction 在 LVLH 坐标系下解释,其中 \(R = r/\\|r\\|\) (径向), \(N = (r \\times v)/\\|r \\times v\\|\) (法向), \(T = N \\times R\) (沿迹方向)。

class e2m2e.algorithm.forces.thrust.ImpulsiveBurn(epoch, delta_v)[源代码]

基类:object

瞬时 Δv 机动事件。

delta_v 在传播(惯性)坐标系内解释,由 e2m2e.algorithm.forces.force_model.ForceModel.propagate_maneuvers()epoch 处施加 state[3:6] += delta_v

VNB/LVLH burn 坐标系暂不支持(届时加 frame 字段,转换走 CoordinateSystem.transform_vector(),对应 GMAT Burn::ConvertDeltaVToInertialcoincident=true 纯旋转)。

参数:
  • epoch (float) -- 施加时刻,SPICE et 秒,与 ForceModel.propagatet_span 一致。

  • delta_v (ndarray[tuple[Any, ...], dtype[floating]]) -- 速度增量,参考系,形状 (3,)

epoch: float
delta_v: ndarray[tuple[Any, ...], dtype[floating]]
class e2m2e.algorithm.forces.thrust.FiniteBurn(thrust_profile, direction, mass, direction_frame=None)[源代码]

基类:PhysicalModel

恒质量连续推力加速度力模型。

6D 状态传播由 Rust 编译路径执行。配置 DSL 构造的常量或 pulse 推力曲线和 固定方向可下沉;任意 Python callable 无法进入 Rust RK 内循环,在传播入口会 显式报能力错误。需要推进剂消耗时使用 VariableMassFiniteBurn(变质量,7D 状态)。

direction 给出方向向量(固定向量或随状态更新的可调用), 内部归一化为单位向量。质量为常量(不支持推进剂消耗)。

direction_frame 支持 "VNB""LVLH"None

  • Nonedirection 直接在传播(惯性)坐标系内解释。

  • "VNB":三个分量依次对应速度单位向量、角动量单位向量和副法向量。

  • "LVLH":三个分量依次对应径向单位向量、沿迹单位向量和轨道面法向量; 沿迹单位向量由法向量叉径向量得到。

参数:
  • thrust_profile (Callable[[float], float]) -- t -> thrust (N,标量;0 表示关机)。

  • direction (npt.ArrayLike | Callable[[float, npt.NDArray[np.floating]], npt.ArrayLike]) -- 固定方向向量 (3,),或 (t, state) -> (3,) 可调用。

  • mass (float) -- 航天器质量(kg,常量)。

  • direction_frame (str | None) -- 方向解释坐标系,"VNB" / "LVLH" / None

property thrust_profile: Callable[[float], float]

推力大小随时间变化的可调用(N)。

property direction: ArrayLike | Callable[[float, ndarray[tuple[Any, ...], dtype[floating]]], ArrayLike]

推力方向:固定向量或 (t, state) -> (3,) 可调用。

property direction_frame: str | None

方向解释坐标系:'VNB'、'LVLH' 或 None。

property mass: float

航天器质量(kg,常量)。

to_rust_spec(system)[源代码]

序列化为恒质量 6D 编译传播接受的推力规格。

只有配置 DSL 构造的 constant/pulse 推力 profile 和固定方向可以下沉 到 Rust;任意 Python callable 无法在 Rust RK 内安全求值,返回 None。 返回规格为 ("low_thrust", mass, thrust, t_start, t_end, direction, direction_frame),其中 constant profile 的起止时间为 None

参数:

system (object)

返回类型:

tuple | None

class e2m2e.algorithm.forces.thrust.VariableMassFiniteBurn(thrust, isp, initial_mass, direction, direction_frame=None)[源代码]

基类:PhysicalModel

连续推力加速度力模型(质量随推力消耗)。

FiniteBurn 的唯一区别:质量不是常量,而是状态量 state[6]。低推力转移与月面动力下降等最优控制问题中,质量演化 是燃耗最优的基本变量( = −T/(Isp·g₀)),必须纳入状态向量。

配套的 7D 传播在 propagate 中走 Rust 快速路径 propagate_compiled_lowthrust:状态 [x, y, z, vx, vy, vz, m],受控动力学在 Rust 侧(augmented_stateaugmented_eom_7d)。详见 docs/plans/lowthrust-foundation-prd.md

推力大小与方向解耦,语义同 FiniteBurndirection 支持 固定向量或 (t, state) -> (3,) 可调用;state 为 7D 时可调用方向 可读取 state[6] 中的质量。direction_frame 支持 "VNB" / "LVLH" / None,帧解析与 FiniteBurn 一致。

参数:
  • thrust (float) -- 推力幅值(N,常量)。

  • isp (float) -- 比冲(s)。

  • initial_mass (float) -- 初始质量(kg),用于初始化状态第 7 维与校验。

  • direction (npt.ArrayLike | Callable[[float, npt.NDArray[np.floating]], npt.ArrayLike]) -- 固定方向向量 (3,),或 (t, state) -> (3,) 可调用。

  • direction_frame (str | None) -- 方向解释坐标系,"VNB" / "LVLH" / None

property thrust: float

推力幅值(N,常量)。

property isp: float

比冲(s)。

property initial_mass: float

初始质量(kg),用于初始化状态第 7 维。

property direction: ArrayLike | Callable[[float, ndarray[tuple[Any, ...], dtype[floating]]], ArrayLike]

推力方向:固定向量或 (t, state) -> (3,) 可调用。

property direction_frame: str | None

方向解释坐标系:'VNB'、'LVLH' 或 None。

to_rust_spec(system)[源代码]

序列化为低推力 7D 传播路径接受的推力规格。

仅当 direction 为固定向量时返回元组(可调用方向需 Python 求值, 无法下沉到 Rust);常量推力映射成满油门(throttle = 1.0), t_max = thrust。返回元组会被 ForceModel 的低推力分支拆出, 交给 propagate_compiled_lowthrust,不经过 6D 的 CompiledForce 路径。

参数:

system (object)

返回类型:

tuple | None

class e2m2e.algorithm.forces.thrust.BurnApplication(index, epoch, delta_v, velocity_before, velocity_after)[源代码]

基类:object

单次脉冲机动在 propagate_maneuvers 输出中的记录。

参数:
index: int
epoch: float
delta_v: ndarray[tuple[Any, ...], dtype[floating]]
velocity_before: ndarray[tuple[Any, ...], dtype[floating]]
velocity_after: ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.forces.exceptions module

力模型子包异常。

所有异常均继承 e2m2e.exceptions.E2M2EError,并同时保留 对原有 Python 内置异常的多重继承,使既有 except ValueError / except TypeError 等子句继续生效。

exception e2m2e.algorithm.forces.exceptions.CoordinateTransformError[源代码]

基类:E2M2EError, ValueError

坐标转换失败时抛出。

exception e2m2e.algorithm.forces.exceptions.RelativisticCorrectionError[源代码]

基类:E2M2EError

相对论修正力模型专用异常。

exception e2m2e.algorithm.forces.exceptions.NotSerializableError[源代码]

基类:E2M2EError, TypeError

力模型无法序列化为配置(如含任意 Python callable)时抛出。

e2m2e.algorithm.solver package

迭代求解器的 Python 问题构造与编排入口。

ADR 0011 的下沉边界:DifferentialCorrection 的 CR3BP 数值内核已经在 Rust,Python 侧保留对称性配置、问题构造、结果与 Orbit 编排;ContinuationMultipleShooting 类仍保留 Python 编排或数值实现,按各自迁移工作项推进。

星历 patch points 修正的旧 Python 求解器(MultipleShooting/` TwoLevelMultipleShooting 包装层 ephemeris_correction 子包)已删除: 设计链路统一走 Rust multiple_shooting_correct_py``(segmented 与稳定轨道 默认路径)。``MultipleShooting 本身保留(transfer/hohmann 等仍使用)。

e2m2e.algorithm.solver.continuation module

轨道族延拓算法模块

提供自然参数延拓和伪弧长延拓方法,用于沿轨道族参数方向逐步生成相邻轨道。

e2m2e.algorithm.solver.continuation.compute_F_and_dF_symmetric_xz_plane(X, SV0, dynamics)[源代码]

计算XZ平面对称轨道的约束向量和雅可比矩阵

对应MATLAB: computeFdF_symPeriodicPlanes_CR3BP(X, SV0i, mu, plane=13)

X = [rx; rz; vy; tf2] - 自由变量向量 SV0 = [rx, ry, rz, vx, vy, vz] - 初始状态向量

F = [vx; vz; ry] - 约束向量(半周期终点状态) dF = ∂F/∂X - 约束雅可比矩阵 (3x4)

参数:
  • X (ndarray) -- 自由变量向量 [rx, rz, vy, tf2]

  • SV0 (ndarray) -- 初始状态向量 [x, y, z, vx, vy, vz]

  • dynamics (CR3BP_Dynamics) -- CR3BP_Dynamics实例,提供运动方程和雅可比矩阵

返回:

约束向量 [vx, vz, ry] dF: 雅可比矩阵 (3, 4)

返回类型:

F

e2m2e.algorithm.solver.continuation.compute_tangent_vector(dF)[源代码]

计算切向量(约束雅可比矩阵的零空间)

对应MATLAB: Xdot = null(dF)

参数:

dF (ndarray) -- 约束雅可比矩阵 (3, 4)

返回:

切向量 (4,),单位化

返回类型:

Xdot

class e2m2e.algorithm.solver.continuation.Continuation(corrector, step=None)[源代码]

基类:object

轨道族延拓

通过延拓算法生成一族周期轨道,支持自然参数延拓和伪弧长延拓。

变量:
  • corrector -- DifferentialCorrection对象

  • continuation_parameter -- 延拓参数名称

  • step_size -- 延拓步长

  • family_orbits -- 轨道族列表

参数:
DEFAULT_STEP_SIZE = 0.01
MIN_STEP_SIZE = 1e-06
MAX_STEP_SIZE = 0.1
DEFAULT_PREDICTOR_ORDER = 1
__init__(corrector, step=None)[源代码]

初始化延拓器

参数:
  • corrector (DifferentialCorrection) -- DifferentialCorrection对象,已配置好对称性和约束

  • step (float | None) -- 初始延拓步长(默认 0.01)

返回类型:

None

natural_continuation(seed_orbit, param_range, step_size, verbose=False)[源代码]

自然参数延拓

从种子轨道出发,逐步改变延拓参数,生成一族周期轨道。 支持双向延拓:如果param_range的最小值小于种子轨道参数值,则向小值方向延拓; 如果param_range的最大值大于种子轨道参数值,则向大值方向延拓。

参数:
  • seed_orbit -- Orbit, 种子轨道

  • param_range -- tuple, 延拓参数范围 (param_min, param_max)

  • step_size -- float, 步长(始终为正值,延拓方向由参数范围自动确定)

  • verbose -- 是否打印信息

返回:

结果状态三元组(status/cause/message)+ 轨道族与延拓统计(族在 .family,含种子与新生成成员)。

返回类型:

ContinuationResult

pseudo_arclength_continuation(seed_orbit, n_orbits=50, step_size=0.005, direction='positive', verbose=True, TolPAL=1e-06, TolDiffCorr=1e-06, IterMax=100, dc_scheme='adaptive', libration_point=1, directional_increment=False, target_vector=0, target_direction=1, progress_callback=None, backend='rust')[源代码]

伪弧长延拓(对应 MATLAB continuation_PAL_CR3BP,plane=13 / XZ 对称)

自由变量 X = [rx, rz, vy, T/2]Xdot = null(dF),PAL 约束 G = [F; (Xnew-X)·Xdot - ΔS];内层用 Xnew 计算 F (与 MATLAB 中仅用固定 X 相比更一致)。每步后用微分修正闭合。

参数:
  • seed_orbit -- 种子轨道(Orbit 对象)。

  • n_orbits (int) -- 本支要生成的新轨道条数(与 MATLAB 中 N 一致)。

  • step_size (float) -- 伪弧长步长 ΔS 的模长(正数;direction 决定符号)。

  • direction (str) -- 延拓方向,取 positive 或 negative;双侧延拓请调用两次, 或改用 halo_pseudo_arclength_continuation(direction='both')。

  • dc_scheme (str) -- 微分修正方案,见 Continuation 类文档字符串。

  • target_vector (int) -- 与 MATLAB TargetVector 对应的 0 基下标 (0=rx, 1=rz, 2=vy, 3=T/2)。

  • backend (str) -- 数值内核后端。"rust"``(默认)走 Rust PAL 内核 (``pal_newton_step_py / pal_f_df_tangent_py); "python" 走 numpy 参照路径(对照与降级)。初始切向量 两后端统一由 Python 参照计算——零空间符号约定在 SVD 与 Rust 广义叉积间无保证,首步延拓方向须由同一实现锁定。

  • verbose (bool)

  • TolPAL (float)

  • TolDiffCorr (float)

  • IterMax (int)

  • libration_point (int)

  • directional_increment (bool)

  • target_direction (int)

返回:

结果状态三元组(status/cause/message)+ 轨道族与延拓统计(族在 .family,仅含种子与本支新轨道)。

返回类型:

ContinuationResult

generate_halo_family(seed_orbit, n_orbits=50, direction='positive', step_size=0.001, z_range=None, verbose=False, progress_callback=None)

Halo 自然参数延拓族(作为 Continuation 实例方法使用)

参数:
返回类型:

list[Orbit]

generate_halo_seed_orbit(libration_point, amplitude_z, halo_class=0, verbose=False)

生成 Halo 种子轨道(作为 Continuation 实例方法使用)

参数:
  • libration_point (int)

  • amplitude_z (float)

  • halo_class (int)

  • verbose (bool)

返回类型:

Orbit

halo_pseudo_arclength_continuation(seed_orbit, n_orbits=50, direction='both', step_size=0.0045, step_size_negative=None, verbose=True, TolPAL=1e-06, TolDiffCorr=1e-06, IterMax=100, dc_scheme='adaptive', directional_increment=True, progress_callback=None, backend='rust')

Halo 轨道族伪弧长延拓(作为 Continuation 实例方法使用)

参数:
返回类型:

OrbitFamily

e2m2e.algorithm.solver.differential_correction module

CR3BP 周期轨道的微分修正问题构造与 Rust 内核适配。

class e2m2e.algorithm.solver.differential_correction.DifferentialCorrection(dynamic, target=None, free_vars=None)[源代码]

基类:object

周期轨道微分修正的问题构造入口。

对称性配置、自由变量和结果编排保留在 Python;残差、STM 雅可比、Newton 修正与收敛判定只由 Rust CR3BP 内核执行。

参数:
DEFAULT_TOLERANCE = 1e-12
DEFAULT_MAX_ITERATIONS = 50
DEFAULT_DAMPING_FACTOR = 1.0
VALID_SETUP_TYPES = ['2D_symmetric_x_fixed_x0', '2D_symmetric_x_fixed_t', '2D_symmetric_y_fixed_y0', '3D_symmetric_x_fixed_x0', '3D_symmetric_xz_fixed_x0', '3D_symmetric_xz_fixed_z0', 'axial_orbit_fixed_vz0', 'halo_orbit_fixed_z0', 'halo_orbit_fixed_x0', 'spo_fixed_x0', 'lpo_fixed_x0']
setup_2D_symmetric_x_fixed_x0(x0=0.0)[源代码]

配置固定初始 x 坐标的平面 x 轴对称周期轨道。

setup_2D_symmetric_x_fixed_t(t_half)[源代码]

配置固定半周期的平面 x 轴对称周期轨道。

setup_2D_symmetric_y_fixed_y0(y0=0.0)[源代码]

配置固定初始 y 坐标的平面 y 轴对称周期轨道。

setup_3D_symmetric_x_fixed_x0(x0)[源代码]

配置固定初始 x 坐标的三维 x 轴对称周期轨道。

setup_3D_symmetric_xz_fixed_x0(x0)[源代码]

配置固定初始 x 坐标的三维 XZ 对称周期轨道。

setup_3D_symmetric_xz_fixed_z0(z0)[源代码]

配置固定初始 z 坐标的三维 XZ 对称周期轨道。

setup_halo_orbit_fixed_z0(z0, libration_point=1)[源代码]

配置固定 z0 的 Halo 轨道修正。

setup_halo_orbit_fixed_x0(x0, libration_point=1)[源代码]

配置固定 x0 的 Halo 轨道修正。

setup_axial_orbit_fixed_vz0(vz0, libration_point=1)[源代码]

配置固定初始 z 方向速度的 Axial 轨道修正。

setup_spo_fixed_x0(x0, libration_point=5)[源代码]

配置固定 x0 的短周期全周期闭合修正。

setup_lpo_fixed_x0(x0, libration_point=5)[源代码]

配置固定 x0 的长周期全周期闭合修正。

iterate_correction(initial_guess, verbose=False, callback=None)[源代码]

修正半周期对称轨道,数值迭代只在 Rust 中执行。

返回类型:

DifferentialCorrectionResult

iterate_full_period_correction(initial_guess, verbose=False, callback=None)[源代码]

修正无对称性假设的全周期闭合轨道,数值迭代只在 Rust 中执行。

返回类型:

DifferentialCorrectionResult

check_convergence()[源代码]

返回上一次 Rust 修正是否收敛。

get_convergence_history()[源代码]

返回 Rust 内核回传的收敛历史。

e2m2e.algorithm.solver.multiple_shooting module

多重打靶法模块

提供多重打靶法(Multiple Shooting)修正器,将一条轨迹分为多段弧段, 通过匹配相邻段端点状态构建残差向量,利用状态转移矩阵(STM)组装 雅可比矩阵进行最小二乘迭代修正。

支持串行、多线程和多进程(SPICE 内核独立加载)三种并行模式。

class e2m2e.algorithm.solver.multiple_shooting.MultipleShootingResult(t_patch, state_patch, status, cause, message, outer_iterations, max_residual, residual_history)[源代码]

基类:object

多重打靶法迭代修正的结果。

参数:
t_patch: ndarray
state_patch: ndarray
status: ConvergenceState
cause: FailureCause
message: str
outer_iterations: int
max_residual: float
residual_history: list[float]
class e2m2e.algorithm.solver.multiple_shooting.MultipleShooting(dynamics, n_workers=1, kernel_dir=None)[源代码]

基类:object

多重打靶法(Multiple Shooting)修正器。

将一条轨迹分为 N 个节点、n_seg = N-1 段弧段,对每段独立积分后, 通过匹配相邻段端点状态来构建残差向量,再利用雅可比矩阵(含 STM) 进行最小二乘修正,反复迭代直到残差满足容差。

当 var_time=True 时,时间节点也作为自由变量参与修正(适用于自由时间问题)。

动力学对象需提供以下接口:

  • propagate(state, time_span, with_stm=True) ——积分传播, 返回含 "states""stm" 的字典。

  • equations_of_motion(t, state) ——计算状态导数(右端函数值)。

并行策略

  • n_workers=1 :串行(默认)。

  • n_workers>1kernel_dir=None :多线程 (ThreadPoolExecutor ),适合 CR3BP 等纯 Python/NumPy 动力学, 但受 GIL 限制,并发收益有限。

  • n_workers>1kernel_dir 已设置:多进程 (ProcessPoolExecutor ),每个子进程重载 SPICE 内核,绕过 GIL, 可充分利用多核 CPU,仅适用于 EphemerisDynamics (需 SPICE 内核)。

__init__(dynamics, n_workers=1, kernel_dir=None)[源代码]

初始化多重打靶修正器。

动力学对象接口与并行策略详见类文档字符串。

参数:
  • dynamics -- 动力学模型对象,需提供 propagateequations_of_motion 接口。

  • n_workers (int) -- 并行工作进程/线程数,默认 1 (串行)。

  • kernel_dir (str | None) -- SPICE 内核目录路径(含 de440.bspnaif0012.tls ),仅在 n_workers>1 时需要。

返回类型:

None

correct(t_patch, state_patch, var_time=False, max_iter=None, tolerance=None, verbose=False)[源代码]

执行多重打靶修正。

将整条轨迹分为若干弧段,对每段独立积分后检验节点处的状态连续性, 利用状态转移矩阵(STM)组装雅可比矩阵,通过最小二乘求解修正量并迭代。

参数:
  • t_patch (ndarray) -- 初始时间节点数组,长度 N

  • state_patch (ndarray) -- 初始状态量数组,形状 (N, 6),每行 [x, y, z, vx, vy, vz]

  • var_time (bool) -- 是否允许时间节点作为自由变量参与修正

  • max_iter (int | None) -- 最大迭代次数(默认使用 self.max_iter)

  • tolerance (float | None) -- 收敛容差(默认使用 self.tolerance)

  • verbose (bool) -- 是否显示进度条

返回:

包含修正后的时间/状态、收敛标志、迭代次数和残差历史

返回类型:

MultipleShootingResult

参数:
  • n_workers (int)

  • kernel_dir (str | None)

e2m2e.algorithm.solver.multiple_shooting.sample_patch_points(orbit, n_points)[源代码]

沿周期轨道均匀采样 patch points(打靶节点)。

该方法用于多重打靶法(Multiple Shooting)的前处理,将一条周期轨道 在时间上均匀分割为 n_points 个节点,并通过线性插值获取每个节点处的状态。

参数:
  • orbit -- 轨道对象,需包含以下属性: - period: 轨道周期(归一化时间单位) - times: 时间数组,形状 (M,) - states: 状态数组,形状 (M, 6),每行 [x, y, z, vx, vy, vz]

  • n_points (int) -- 需要采样的节点数量

返回:

包含两个数组的元组:
  • t_patch: 采样时间节点数组,形状 (n_points,),归一化时间单位

  • states: 采样状态数组,形状 (n_points, 6),每行 [x, y, z, vx, vy, vz]

返回类型:

Tuple[np.ndarray, np.ndarray]

抛出:

ValueError -- 当轨道对象没有 period 属性时抛出

备注

  • 采样时间范围为 [0, period),不包含周期终点(endpoint=False)

  • 使用线性插值从原始轨道数据中获取节点状态

  • 适用于 CR3BP 归一化坐标系下的周期轨道采样

e2m2e.algorithm.solver.multiple_shooting.sample_patch_points_perilune_clustered(orbit, dynamics, n_base=8, n_perilune=5, perilune_window=0.15)[源代码]

在近月点附近加密采样 patch points。

NRHO 近月点速度大、STM 条件数高,等时间间隔采样会让近月点落在节点 之间而欠约束,导致多重打靶残差停滞。本函数先积分一圈定位近月点 (离次天体最近的点),在其两侧 perilune_window·period 窗口内 加密 n_perilune 个节点,其余 n_base 个节点等时间间隔分布在 窗口外。

参数:
  • orbit -- 周期轨道,需含 periodtimesstates

  • dynamics -- 动力学对象,用于积分定位近月点(需提供 propagate_orbit_state_at_time )。

  • n_base (int) -- 窗口外的等时间间隔节点数。

  • n_perilune (int) -- 近月点窗口内的加密节点数(含近月点本身)。

  • perilune_window (float) -- 加密窗口半宽,占周期比例(如 0.15 表示近月点 前后各 15% 周期)。

返回:

(t_patch, states):时间节点与对应状态,按时间升序排列。

返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]]

e2m2e.algorithm.solver.multiple_shooting.sample_patch_points_drop_near_perilune(orbit, dynamics, n_points=8, drop_window=0.12)[源代码]

等时间采样的对偶:节点落在近月点窗口之外,并强制包含历元 t=0

NRHO 近月点速度大、STM 条件数高。把节点加密到近月点附近( sample_patch_points_perilune_clustered())或让节点落在近月点上, 会让星历多重打靶残差卡在约 10² km。秦理民等 2024 的多点打靶离散策略 是**删除**近月点附近的离散点,让节点落在条件数较好的弧段。

实现:先积分一圈定位近月点,再在窗口 [t_p - w, t_p + w] 之外的 互补弧上均匀放置 n_points - 1 个节点(w = drop_window · period ), 并强制并入 t=0 。不钉历元时首节点常落在 t>0 ,segmented 逐段 填充从 et0 起的时间网格会出现前缀空洞,星历长度断言失败(#473)。 去重后点数不足则回退等时间采样。与近月点加密互补——加密往窗口内堆点, 本函数把非历元节点放在窗口外。

注:自 #473 起 NRHO 生产默认改为等时间;本函数保留供对照与研究。

参数:
  • orbit -- 周期轨道,需含 periodtimesstates

  • dynamics -- 动力学对象,用于积分定位近月点。

  • n_points (int) -- 目标节点数(含历元钉点)。

  • drop_window (float) -- 近月点禁区半宽,占周期比例。

返回:

(t_patch, states):时间节点与对应状态,按时间升序排列; t_patch[0] == 0 (或回退等时间时同样从 0 起)。

返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]]

e2m2e.algorithm.solver.multiple_shooting.convert_to_j2000(t_patch_syn, states_syn, syn_j2000, reference_et, tu_days=4.34811305)[源代码]

将 synodic 坐标系下的 patch points 转换到 J2000 惯性坐标系。

该方法用于将 CR3BP 归一化 synodic 坐标系中的轨道节点转换到 J2000 惯性坐标系,以便在星历模型(Ephemeris)中进行高精度轨道修正。

参数:
  • t_patch_syn (ArrayLike) -- synodic 坐标系下的时间节点数组,归一化时间单位(TU)

  • states_syn (ArrayLike) -- synodic 坐标系下的状态数组,形状 (N, 6), 每行 [x, y, z, vx, vy, vz],归一化单位(DU, DU/TU)

  • syn_j2000 -- SynodicJ2000System 对象,提供坐标转换功能

  • reference_et (float) -- 参考历元的 SPICE ephemeris time(ET),单位秒

  • tu_days (float) -- 归一化时间单位(TU)对应的天数,默认值为 4.34811305 天

返回:

包含两个数组的元组:
  • t_patch_j2000: J2000 坐标系下的时间数组,SPICE ET(秒)

  • states_j2000: J2000 坐标系下的状态数组,形状 (N, 6),

    每行 [x, y, z, vx, vy, vz],单位(km, km/s)

返回类型:

Tuple[np.ndarray, np.ndarray]

备注

  • 时间转换公式:t_j2000 = reference_et + t_syn * (tu_days * 86400)

  • 状态转换使用 SynodicJ2000System.batch_synodic_to_j2000() 方法

  • 适用于将 CR3BP 轨道转换到星历模型进行高精度修正的场景

  • 转换后的状态可用于 EphemerisDynamics 进行轨道传播

e2m2e.algorithm.family package

轨道族生成:种子/初猜/族行走/注册表。

回答"一条轨道/一族轨道怎么收敛出来"(ADR 0011 迁移,源: dfh/cr3bp_orbits.py 六类初猜 + algorithms/halo_family.py + algorithms/halo_initial_guess.py + algorithms/lissajous_initial_guess.py + algorithms/triangular_initial_guess.py + algorithms/strategies/)。

轨道族注册表 = 函数形态(registry: dict[str, Callable]),注册表值 = 设计函数 design_xxx(params) -> Orbitalgorithm/designdesign_orbit 查注册表按族分发(新族 = 写一个设计函数 + 注册)。

cr3bp_orbits (六类初猜)依赖 algorithm/solver,而 solver 依赖本包 的 halo_initial_guess——为打破包级循环,初猜函数经 PEP 562 __getattr__ 惰性导出。

design_*_family 是面向 Facade 的多成员生成入口,返回带状态三元组的 FamilyGenerationResult;成功结果中的 familyOrbitFamily。 单轨注册表与多成员生成入口保持两套明确契约。

e2m2e.algorithm.family.cr3bp_orbits module

CR3BP 周期轨道生成:design_orbit 链路的初猜段。

把 DFH 形状参数翻译成地月 CR3BP 周期轨道:

  • DRO:以近侧 x 轴穿越点 x0 为族参数,从标准种子出发沿族行走, 选取振幅(一个周期内距月球的最大距离,km)命中目标的成员;

  • DPO:与 DRO 对称的顺行族,以 x0 为族参数,vy0 < 0(顺行), 振幅定义同 DRO(距月心距离 min/max 均值,km);

  • Halo:Richardson 三阶近似种子 + 定 z0 微分修正,沿族把 z0 走到目标面外振幅(km,符号区分北/南);

  • NRHO:Halo 族成员中按近月距(距月心 = 近月点高度 + 月球半径)选取, 北/南对应 halo_class 0/1;

  • Axial:Gómez Type B 分岔族,以面外速度 vz0 为族参数, 从 xy 平面出发的 3D 周期轨道(x 轴对称),振幅 = max|z|(km)。

族行走统一用割线法(_walk_family):前一条轨道的修正结果作为下 一条的初猜,天然延拓,避免大步长下微分修正发散。

exception e2m2e.algorithm.family.cr3bp_orbits.Cr3bpOrbitError(message, *, status=ConvergenceState.FAILED, cause=FailureCause.UNKNOWN)[源代码]

基类:RuntimeError

CR3BP 轨道生成硬失败,携带统一状态三元组。

参数:
返回类型:

None

e2m2e.algorithm.family.cr3bp_orbits.earth_moon_system()[源代码]

构造标准地月 CR3BP 系统(含特征尺度与平动点)。

返回类型:

CR3BP_System

e2m2e.algorithm.family.cr3bp_orbits.design_dro(amplitude_km, *, dynamics=None, tol_km=20.0)[源代码]

生成指定振幅的 DRO 周期轨道。

振幅定义:一个周期内距月心距离最小/最大值的均值(km)。历史标定: amplitude=10000 的 DRO 距月范围约 4825~15290 km,(min+max)/2≈10058 km,比最大距离或 y 半宽更贴近 输入值。以近侧 x 轴穿越点 x0 为族参数行走,命中 tol_km 内即停。

参数:
返回类型:

Orbit

e2m2e.algorithm.family.cr3bp_orbits.design_dpo(amplitude_km, *, dynamics=None, tol_km=20.0)[源代码]

生成指定振幅的 DPO(Direct Prograde Orbit)周期轨道。

DPO 是 xy 平面内围绕月球的顺行周期轨道(旋转坐标系下逆时针), 与 DRO(逆行)对称。振幅定义同 DRO:一个周期内距月心距离 最小/最大值的均值(km)。以近侧 x 轴穿越点 x0 为族参数行走, 命中 tol_km 内即停。

引用

Folta et al. (2015). An Earth–Moon system trajectory design reference catalog. AIAA SciTech. Guzzetti et al. (2016). Rapid trajectory design in the Earth–Moon ephemeris system via an interactive catalog of periodic orbits. JGCD.

参数:
返回类型:

Orbit

e2m2e.algorithm.family.cr3bp_orbits.design_halo(collinear_point, amplitude_km, *, dynamics=None)[源代码]

生成指定面外振幅的 Halo 周期轨道。

amplitude_km 带符号:正为北族、负为南族(与 DFH ±73000 km 的 约定一致)。振幅对应 Halo 参考状态(y=0 穿越点)的 z 坐标。 |z0| 不超过 _HALO_FOLD_Z0 时直接固定 z0 行走;更大振幅先走到 折叠点前的族成员,再改用固定 x0 行走逼近目标。

参数:
返回类型:

Orbit

e2m2e.algorithm.family.cr3bp_orbits.design_halo_family(libration_point, max_amplitude_km, *, n_orbits=50, dynamics=None)[源代码]

生成一族 Halo 周期轨道(从种子延拓到指定面外振幅上限)。

族从 Richardson 小振幅种子(_HALO_SEED_Z0)出发,自然参数 延拓(固定 z0 微分修正)覆盖 [0, |max_amplitude_km|], 至多 n_orbits 条(含种子)。振幅上限不得超过该平动点的族 折叠点(seed._HALO_FOLD_Z0),折叠点后固定 z0 延拓失效。

max_amplitude_km 带符号:正为北族、负为南族(与 design_halo 约定一致);符号只决定延拓方向,振幅上限取绝对值。

参数:
  • libration_point (int) -- 平动点编号(1=L1, 2=L2)。

  • max_amplitude_km (float) -- 族振幅上限(km),带符号区分北/南族。

  • n_orbits (int) -- 族成员数量上限(含种子),默认 50。

  • dynamics (CR3BP_Dynamics | None) -- CR3BP 动力学;缺省构造标准地月系统。

返回:

含一族周期轨道的 OrbitFamily

返回类型:

OrbitFamily | FamilyGenerationResult

e2m2e.algorithm.family.cr3bp_orbits.design_nrho(collinear_point, north_south, perilune_height_km, *, dynamics=None, tol_km=10.0)[源代码]

生成指定近月点高度的 NRHO 周期轨道(Halo 族特选成员)。

北/南(north_south 1/2)对应 halo_class 0/1;近月距目标为 perilune_height_km + MOON_RADIUS_KM (距月心)。L2:先固定 z0 走到折叠点前的族成员,再固定 x0 向月侧行走;L1:固定 x0 在折叠点 两侧均失效,改用 PAL 延拓(_walk_pal_to_perilune)。近月距命中 tol_km 内即停。

参数:
返回类型:

Orbit

e2m2e.algorithm.family.cr3bp_orbits.design_lissajous(collinear_point, amplitude_in_km, amplitude_out_km, phase_in, phase_out, *, dynamics=None, n_periods=3)[源代码]

生成指定共线点(L1/L2/L3)的 Lissajous 拟周期轨道。

Lissajous 面内/面外频率不可约,是准周期轨道,不做周期闭合。一阶线性 初猜在非线性 CR3BP 下必发散(不稳定方向泄漏,见 compute_lissajous_bounded_trajectory()),故本函数返回**中心流形 约化流的有界多点轨迹**(覆盖 n_periods 个名义周期),供下游可视化 与 patch-point 采样直接使用——原生 CR3BP 重传播会重新激发不稳定方向 而发散,下游不得用 states[0] 重传播。

period 取面内名义周期 2π/ω_xy;states[0] 为历元参考状态。

参数:
  • collinear_point (int) -- 共线点编号 1/2/3。

  • amplitude_out_km (float) -- 面内/面外振幅(km)。

  • phase_out (float) -- 面内/面外初始相位(0~1)。

  • dynamics (CR3BP_Dynamics | None) -- CR3BP 动力学;缺省构造标准地月系统。

  • n_periods (int) -- 返回轨迹覆盖的名义周期数(默认 3)。

  • amplitude_in_km (float)

  • amplitude_out_km

  • phase_in (float)

  • phase_out

返回:

含多点有界轨迹的 Orbit。中心流形约化失败时退回一阶线性 单点初猜并发出 RuntimeWarning (保下游不崩,但失去有界性)。

返回类型:

Orbit

e2m2e.algorithm.family.cr3bp_orbits.design_triangular(point, amplitude_in_km, amplitude_out_km, phase_in, phase_out, *, dynamics=None)[源代码]

生成 L4/L5 邻域拟周期轨道初猜(等边三角形平动点)。

面内振幅默认均分给短/长两模态(拆分比例待 golden 标定)。不做微分 修正:现有 algorithms/strategies/ 全基于 x 轴/y 轴镜面对称,L4/L5 无适用对称性。初猜状态直接作星历修正 patch points 的采样基准。

参数:
返回类型:

Orbit

e2m2e.algorithm.family.cr3bp_orbits.design_axial(collinear_point, amplitude_km, *, dynamics=None)[源代码]

生成指定面外振幅的 Axial 周期轨道(Gómez Type B 分岔族)。

amplitude_km 带符号:正为上族、负为下族。振幅 = 一个周期内 |z| 的最大值(km)。以面外速度 vz0 为族参数沿 Type B 分支行 走,从 Lyapunov 分岔邻域的小振幅种子出发逼近目标。

参数:
返回类型:

Orbit

e2m2e.algorithm.family.cr3bp_orbits.design_spo(libration_point, amplitude_km, *, dynamics=None, tol_km=20.0)[源代码]

生成指定振幅的 L4/L5 SPO 周期轨道。

SPO(Short-Period Orbit)是 CR3BP 中围绕三角平动点的短周期族 成员(Gómez vol II, $mathcal{L}_s$),周期约 1 朔望月(~28 天), 近稳定(特征值模 ≈ 1.001)。

振幅定义:一个周期内距 L4/L5 径向距离最小/最大值的均值(km)。 以 x₀ 为族参数,在 L4/L5 附近做二分搜索逼近目标振幅。

实现策略(直接二分,非族行走): SPO 短周期族在 L4/L5 附近的振幅-×₀ 映射非单调(小振幅区间 步长敏感),_walk_family 假设单调性,不适合此族。改用 x₀ 上的直接二分搜索 + 每步全周期修正,每步都从线性化初猜出发 (SPO 近稳定,牛顿收敛可靠)。

参数:
  • libration_point (int) -- 平动点编号(4=L4, 5=L5)。

  • amplitude_km (float) -- 目标振幅(km)。

  • dynamics (CR3BP_Dynamics | None) -- CR3BP 动力学对象;缺省构造标准地月系统。

  • tol_km (float) -- 振幅匹配容差(km),默认 20。

返回:

修正后的 SPO 周期轨道。

返回类型:

Orbit

引用

Gómez et al. (2001). Dynamics and mission design near libration points, Vol. II. ESA Contract Report. Capdevila & Howell (2018). A transfer network linking Earth, Moon, and the triangular libration point regions. JGCD.

e2m2e.algorithm.family.cr3bp_orbits.design_lpo(libration_point, amplitude_km, *, dynamics=None, tol_km=20.0)[源代码]

生成指定振幅的 L4/L5 LPO 周期轨道。

LPO(Long-Period Orbit)是 CR3BP 中围绕三角平动点的长周期族 成员(Gómez vol II, $mathcal{L}_l$)。小振幅时为椭圆形,大振幅 时呈马蹄形(Horseshoe),跨越 L4-L1-L5(Marchal 1990, Brown C.2)。

振幅定义同 SPO:一个周期内距 L4/L5 径向距离最小/最大值的均值(km)。 以 x₀ 为族参数,用网格搜索 + 局部精化逼近目标振幅。

实现策略(网格搜索 + 局部二分): LPO 长周期族的振幅-x₀ 映射高度非单调(小振幅椭圆 → 混沌过渡区 → 大振幅马蹄族),简单二分搜索无法收敛。改用两步策略: 1) 均匀网格采样 x₀,找到振幅最接近目标的候选点; 2) 在候选点附近做局部二分精化(利用局部单调性)。

参数:
  • libration_point (int) -- 平动点编号(4=L4, 5=L5)。

  • amplitude_km (float) -- 目标振幅(km),范围 1,000~110,000。

  • dynamics (CR3BP_Dynamics | None) -- CR3BP 动力学对象;缺省构造标准地月系统。

  • tol_km (float) -- 振幅匹配容差(km),默认 20。

返回:

修正后的 LPO 周期轨道(小振幅椭圆 或 大振幅马蹄形)。

返回类型:

Orbit

引用

Gómez et al. (2001). Vol. II. 长周期族 L_l。 Marchal (1990). The Three-Body Problem. Brown 猜想 C.2。 Taylor (1981). A&A 103, 288. 马蹄周期轨道数值计算。

e2m2e.algorithm.family.cr3bp_orbits.design_horseshoe(libration_point, amplitude_km=100000.0, *, dynamics=None, tol_km=50.0)[源代码]

生成 L4/L5 Horseshoe 马蹄形周期轨道。

Horseshoe 是 LPO 长周期族的大振幅成员,轨道形状呈马蹄形, 跨越 L4-L1-L5(Marchal 1990, Brown 猜想 C.2, Taylor 1981)。

本函数是 design_lpo 的便捷封装,默认振幅为 100,000 km。 振幅定义同 LPO/SPO:距 L4/L5 径向距离均值(km)。

参数:
  • libration_point (int) -- 平动点编号(4=L4, 5=L5)。

  • amplitude_km (float) -- 目标振幅(km),范围 50,000~110,000,默认 100,000。

  • dynamics (CR3BP_Dynamics | None) -- CR3BP 动力学对象;缺省构造标准地月系统。

  • tol_km (float) -- 振幅匹配容差(km),默认 50(比 LPO 默认 20 宽松, 因为大振幅族行走精度下降)。

返回:

修正后的 Horseshoe 周期轨道。

返回类型:

Orbit

引用

Taylor (1981). A&A 103, 288. Sun-Jupiter 马蹄周期轨道。 Marchal (1990). The Three-Body Problem. Brown C.2 证实。 Murray & Dermott (1999). §3.9 Horseshoe 运动学描述。

e2m2e.algorithm.family.cr3bp_orbits.design_dro_family(min_amplitude_km, max_amplitude_km, *, n_orbits=50, dynamics=None)[源代码]

生成 DRO 族:月心逆行族中振幅落入请求范围的成员。

振幅定义同 design_dro``(一个周期内距月心距离 min/max 均值,km)。 DRO 不绑定平动点;族参数为近侧 x 轴穿越点 ``x0,从标准种子出发 单次自然参数延拓(修正失败步长减半),按请求窗口与种子振幅的相对 位置选择行走方向(跨种子窗口双向行走),收集振幅落入 [min_amplitude_km, max_amplitude_km] 的成员,至多 n_orbits 条, 按振幅升序排列。

参数:
  • min_amplitude_km (float) -- 族振幅下限(km)。

  • max_amplitude_km (float) -- 族振幅上限(km)。

  • n_orbits (int) -- 族成员数量上限。

  • dynamics (CR3BP_Dynamics | None) -- CR3BP 动力学;缺省构造标准地月系统。

返回:

FamilyGenerationResultfamily 是 DRO 成员组成的 OrbitFamily``(``family_type="dro"),软失败时保留部分成员。

返回类型:

FamilyGenerationResult

e2m2e.algorithm.family.cr3bp_orbits.design_nrho_family(libration_point, north_south, perilune_height_max_km, *, n_orbits=50, continuation_direction='toward-moon', dynamics=None)[源代码]

生成 NRHO 族:Halo 族折叠点后近月段中近月点高度达标的成员。

NRHO 不是独立的族,而是 Halo 族越过折叠点后的近直线段;族成员 = 近月点高度 ≤ perilune_height_max_km 的连续段,至多 n_orbits 条。Rust 的 L1 路径从小振幅 Halo 种子做单次 PAL,L2 从 DE421 地月 模型标定的折叠后成员固定 x0 向月侧延拓;每个成员在加入结果前重新 修正并测量近月点。

参数:
  • libration_point (int) -- 平动点编号(1=L1, 2=L2)。

  • north_south (int) -- 1=北族,2=南族。

  • perilune_height_max_km (float) -- 族成员的近月点高度上限(km)。

  • n_orbits (int) -- 族成员数量上限。

  • dynamics (CR3BP_Dynamics | None) -- CR3BP 动力学;缺省构造标准地月系统。

  • continuation_direction (str)

返回:

FamilyGenerationResultfamily 是近月段成员组成的 OrbitFamily``(``family_type="nrho"),软失败时保留部分成员。

返回类型:

FamilyGenerationResult

e2m2e.algorithm.family.cr3bp_orbits.design_axial_family(libration_point, max_amplitude_km, *, n_orbits=50, continuation_direction='increase-amplitude', dynamics=None)[源代码]

生成 Axial 族(Gómez Type B 分岔族)成员。

以面外速度 vz0 为族参数,从 Lyapunov 分岔邻域的小振幅成员出 发等步行走(失败步长减半),收集 |z| 振幅不超过 |max_amplitude_km| 的成员,至多 n_orbits 条。 max_amplitude_km 带符号:正为上族、负为下族(与 design_axial 约定一致)。

参数:
  • libration_point (int) -- 平动点编号(1=L1, 2=L2)。

  • max_amplitude_km (float) -- 族振幅上限(km),带符号区分上/下族。

  • n_orbits (int) -- 族成员数量上限。

  • dynamics (CR3BP_Dynamics | None) -- CR3BP 动力学;缺省构造标准地月系统。

  • continuation_direction (str)

返回:

FamilyGenerationResultfamily 是 Axial 成员组成的 OrbitFamily``(``family_type="axial")。

返回类型:

FamilyGenerationResult

e2m2e.algorithm.family.cr3bp_orbits.design_lissajous_family(libration_point, amplitude_in_km, amplitude_out_km, phase_in, phase_out, *, n_orbits=50, sampling_mode='linear-amplitudes', dynamics=None, n_periods=3)[源代码]

生成 Lissajous 拟周期轨迹采样族。

Lissajous 面内/面外频率不可约,不是周期族;族生成是参数采样而 非延拓:面内/面外振幅从请求值的 1/n 到 1 线性插值取 n_orbits 个样本,两相位固定。每个成员是 Rust 非线性中心约化流上的 有界多点轨迹(语义同 design_lissajous),无周期闭合,不得 按严格周期族消费——族上显式标注 metadata["periodicity"] = "quasi-periodic"

参数:
  • libration_point (int) -- 共线点编号(1/2/3)。

  • amplitude_out_km (float) -- 面内/面外振幅上限(km)。

  • phase_out (float) -- 面内/面外初始相位(0~1,采样中固定)。

  • n_orbits (int) -- 采样成员数。

  • dynamics (CR3BP_Dynamics | None) -- CR3BP 动力学;缺省构造标准地月系统。

  • n_periods (int) -- 每条轨迹覆盖的名义周期数(默认 3)。

  • amplitude_in_km (float)

  • amplitude_out_km

  • phase_in (float)

  • phase_out

  • sampling_mode (str)

返回:

FamilyGenerationResultfamily 是拟周期成员组成的 OrbitFamily``(``family_type="lissajous"is_quasi_periodic 为真)。

返回类型:

FamilyGenerationResult

e2m2e.algorithm.family.cr3bp_orbits.design_spo_family(libration_point, min_amplitude_km, max_amplitude_km, *, n_orbits=50, continuation_direction='decrease-x0', match_tolerance_km=20.0, dynamics=None)[源代码]

生成 L4/L5 SPO 族:短周期族中振幅落入请求范围的成员。

振幅定义同 design_spo``(距 L4/L5 径向距离 min/max 均值,km)。 族生成方法见 ``_design_triangular_family

参数:
返回类型:

FamilyGenerationResult

e2m2e.algorithm.family.cr3bp_orbits.design_lpo_family(libration_point, min_amplitude_km, max_amplitude_km, *, n_orbits=50, continuation_direction='decrease-x0', match_tolerance_km=20.0, dynamics=None)[源代码]

生成 L4/L5 LPO 族:长周期族中振幅落入请求范围的成员。

振幅定义同 design_lpo。族生成方法见 _design_triangular_family

参数:
返回类型:

FamilyGenerationResult

e2m2e.algorithm.family.cr3bp_orbits.design_horseshoe_family(libration_point, min_amplitude_km=50000.0, max_amplitude_km=110000.0, *, n_orbits=50, continuation_direction='decrease-x0', match_tolerance_km=50.0, dynamics=None)[源代码]

生成 L4/L5 Horseshoe 族:LPO 长周期族的大振幅(马蹄形)成员。

Horseshoe 是 LPO 族的成员分类,不获第二套求解器(ADR 0028): 沿 LPO 链行走到大振幅段,收集振幅落入请求范围的成员并标记为 horseshoe。声明范围不得超出 #435 标定的可达包络。

参数:
返回类型:

FamilyGenerationResult

e2m2e.algorithm.family.halo_family module

Halo 轨道族编排模块

continuation.py 拆出的 Halo 专用编排:种子生成、自然参数族延拓、 伪弧长(PAL)延拓。Continuation 实例上同名方法仍可用 — 在 continuation.py 文件末尾以方法重绑定的形式保留调用语法。

e2m2e.algorithm.family.halo_family.generate_halo_seed_orbit(continuation, libration_point, amplitude_z, halo_class=0, verbose=False)[源代码]

生成 Halo 种子轨道(作为 Continuation 实例方法使用)

参数:
  • libration_point (int)

  • amplitude_z (float)

  • halo_class (int)

  • verbose (bool)

返回类型:

Orbit

e2m2e.algorithm.family.halo_family.generate_halo_family(continuation, seed_orbit, n_orbits=50, direction='positive', step_size=0.001, z_range=None, verbose=False, progress_callback=None)[源代码]

Halo 自然参数延拓族(作为 Continuation 实例方法使用)

参数:
返回类型:

list[Orbit]

e2m2e.algorithm.family.halo_family.halo_pseudo_arclength_continuation(continuation, seed_orbit, n_orbits=50, direction='both', step_size=0.0045, step_size_negative=None, verbose=True, TolPAL=1e-06, TolDiffCorr=1e-06, IterMax=100, dc_scheme='adaptive', directional_increment=True, progress_callback=None, backend='rust')[源代码]

Halo 轨道族伪弧长延拓(作为 Continuation 实例方法使用)

参数:
返回类型:

OrbitFamily

e2m2e.algorithm.family.halo_initial_guess module

Halo轨道初始猜测模块

提供 Richardson 三阶近似方法,用于生成 Halo 轨道的初始猜测参数。 配合微分修正器使用,将解析近似结果精化为精确的周期轨道。

包含: - Lagrange 点距离参数 gamma 的求解 - 面内振荡频率 omega_p 的计算 - Richardson 三阶近似系数 - Halo 轨道三阶解析近似 - 初始猜测参数生成

引用

Richardson, D. L. (1980). Analytic construction of periodic orbits about the collinear points. Celestial Mechanics, 22(3), 303-320.

e2m2e.algorithm.family.halo_initial_guess.compute_halo_coefficients(mu, L)[源代码]

计算 Halo 轨道 Richardson 三阶近似所需的全部系数。

根据 Richardson (1980) 的三阶解析构造方法,在共线平动点附近将 CR3BP 运动方程 展开为非线性扰动级数。三阶近似将轨道位移分解为面内(u-v)和面外(w)分量, 用 Fourier 级数表示,包含基频 omega_p 的各阶谐波。

核心系数包括: - a_ij: u 方向(沿主天体连线)的振幅修正系数 - b_ij: v 方向(面内垂直方向)的振幅修正系数 - d_ij: w 方向(面外方向)的振幅修正系数 - k, delta: 与平动点位置相关的符号因子 - kappa1, kappa2: 频率修正系数(用于计算非线性周期)

参数:
  • mu (float) -- 质量比 mu = m2 / (m1 + m2)。

  • L (int) -- 拉格朗日点编号(1=L1, 2=L2)。

返回:

包含所有 Richardson 三阶近似系数的字典,键包括:
  • gamma: 次天体到平动点的距离(L2 时取负值)

  • omega_p: 面内振荡基频

  • c1, c2, c3: Legendre 系数(有效势展开的前三阶)

  • a21~a31, b21~b31, d21~d32: 各方向振幅修正系数

  • k, delta: 符号因子

  • l1~l3, kappa1, kappa2: 频率和周期修正系数

返回类型:

Dict[str, float]

抛出:

ValueError -- 当 L 不为 1 或 2 时。

引用

Richardson, D. L. (1980). Analytic construction of periodic orbits about the collinear points. Celestial Mechanics, 22(3), 303-320.

e2m2e.algorithm.family.halo_initial_guess.halo_third_order_approximation(mu, Au, Aw, phi, L, tf, N, halo_class=0)[源代码]

计算Halo轨道三阶解析近似

参数:
  • mu (float) -- 质量比

  • Au (float) -- U方向振幅

  • Aw (float) -- W方向振幅

  • phi (float) -- 相位偏移

  • L (int) -- 拉格朗日点 (1=L1, 2=L2)

  • tf (float) -- 终止时间

  • N (int) -- 点数

  • halo_class (int) -- 0=Class I (北), 1=Class II (南)

返回:

状态向量序列 (N, 6),[u, v, w, u_dot, v_dot, w_dot] t: 时间序列 T: 周期

返回类型:

SV_uvw

Reference:

Richardson, D. L. (1980). Analytic construction of periodic orbits about the collinear points. Celestial Mechanics.

e2m2e.algorithm.family.halo_initial_guess.compute_halo_initial_guess(mu, z_amplitude, L=1, halo_class=0)[源代码]

计算Halo轨道初始猜测参数

使用 Richardson 三阶近似系数生成初始猜测,配合微分修正器使用。 初始状态位于 XZ 平面穿越点(y=0),赤道面穿越处(z=0)。

参数:
  • mu (float) -- 质量比

  • z_amplitude (float) -- Z方向振幅

  • L (int) -- 拉格朗日点 (1=L1, 2=L2)

  • halo_class (int) -- 0=北Halo, 1=南Halo(当前不影响返回值,z 方向由调用方处理)

返回:

  • x0: 初始x坐标

  • y0: 初始y坐标 (0)

  • z0: 初始z坐标 (0)

  • vx0: 初始vx (0)

  • vy0: 初始vy

  • vz0: 初始vz (0)

  • T_half: 半周期

  • Au: U方向振幅

  • Aw: W方向振幅

返回类型:

包含初始猜测参数的字典

e2m2e.algorithm.family.axial_initial_guess module

Axial 轨道初猜(Gómez Type B 分岔族)。

Axial 轨道从 planar Lyapunov 轨道通过 pitchfork 分岔产生(Gómez Type B), 关于 x 轴对称。与 Halo(Type A, xz 平面对称)的区别:

  • Halo: 初始 (x₀, 0, z₀, 0, ẏ₀, 0) — 从 xz 平面出发,ż₀=0

  • Axial: 初始 (x₀, 0, 0, 0, ẏ₀, ż₀) — 从 xy 平面出发,z₀=0,ż₀≠0

分岔机制:沿 planar Lyapunov 族行走,在垂直临界轨道处(monodromy 的 z-vz 块半迹 vt = +1),Lyapunov 轨道的面内振幅不再为零。Axial 族从此 分岔,继承面内振幅,并叠加面外速度 ż₀。

初猜构造: 1. 沿 Lyapunov 族扫描,找到 vt = +1 且 Jacobi 在 Haapala 区间的轨道 2. 取该 Lyapunov 轨道的初始状态 (x₀, 0, 0, 0, ẏ₀, 0) 3. 叠加小 ż₀ 扰动:(x₀, 0, 0, 0, ẏ₀, ż₀_seed)

引用

Gómez, G., et al. (2001). Dynamics and mission design near libration points, Vol. III, Sec. 3.3. Type B 垂直临界分岔。 Haapala & Howell (2016). Axial Jacobi 范围 [2.991, 3.021](L1)、 [2.967, 3.014](L2)。

e2m2e.algorithm.family.axial_initial_guess.compute_axial_initial_guess(dynamics, collinear_point, vz0)[源代码]

构造 Axial 轨道初猜状态。

从 planar Lyapunov 族的垂直临界轨道(Gómez Type B 分岔点)出发, 继承 Lyapunov 轨道的面内振幅 (x₀, ẏ₀),叠加小 ż₀ 扰动。

参数:
  • dynamics (CR3BP_Dynamics) -- CR3BP 动力学对象(用于 Lyapunov 族扫描)。

  • collinear_point (int) -- 共线点编号 1/2/3。

  • vz0 (float) -- 初始 z 方向速度(无量纲 DO/TU),带符号区分上/下族。

返回:

(state0, period):t=0 的 6 维状态 (x₀, 0, 0, 0, ẏ₀, ż₀) 与分岔 Lyapunov 轨道的周期(无量纲 TU)。

返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]], float]

e2m2e.algorithm.family.lissajous_initial_guess module

Lissajous 轨道一阶解析初猜(共线平动点 L1/L2/L3)。

Lissajous 是围绕共线点的**准周期** 轨道:面内运动(x-y)以频率 ω_xy、 面外运动(z)以频率 ω_z 独立振荡,两频率不可约(不共振)。Halo 轨道是 其面内/面外锁相(1:1 共振)的周期特例。

本模块通过 Rust 数值内核求解共线点和线性中心模态,统一处理 L1/L2/L3。 一阶初猜对小振幅(L1/L2 ≤7600 km)精度足够;更大振幅由下游星历修正 (多重打靶)精化。

引用

Gómez, G., et al. (2001). Dynamics and mission design near libration points, Vol. I, Sec. 7. Lissajous 作为双频率 Lindstedt-Poincaré 展开 的一阶近似。

e2m2e.algorithm.family.lissajous_initial_guess.compute_lissajous_initial_guess(system, collinear_point, amplitude_in_km, amplitude_out_km, phase_in, phase_out)[源代码]

构造 Lissajous 轨道一阶初猜状态。

在共线点邻域,面内运动为椭圆(频率 ω_xy),面外为正弦(频率 ω_z):

\[\vec x(t) = \vec x_L + \alpha\, \mathrm{Re}[\vec v_{xy}\, e^{i(\omega_{xy} t + \phi)}] + \beta\, \mathrm{Re}[\vec v_z\, e^{i(\omega_z t + \psi)}]\]

其中 α、β 为面内/面外振幅(无量纲),φ、ψ 为相位,v_xy/v_z 为完整 6 维 复特征向量(含位置+速度,保证位置与速度的相位关系自洽)。

参数:
  • system (CR3BP_System) -- CR3BP 系统(含已计算的平动点)。

  • collinear_point (int) -- 共线点编号 1/2/3。

  • amplitude_in_km (float) -- 面内振幅(km,物理单位)。

  • amplitude_out_km (float) -- 面外振幅(km,物理单位)。

  • phase_in (float) -- 面内初始相位(0~1,映射到 0~2π)。

  • phase_out (float) -- 面外初始相位(0~1,映射到 0~2π)。

返回:

(state0, nominal_period):t=0 的 6 维状态(无量纲 synodic), 与面内标称周期 2π/ω_xy(作 patch points 采样基准)。

返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]], float]

e2m2e.algorithm.family.lissajous_initial_guess.compute_lissajous_bounded_trajectory(system, collinear_point, amplitude_in_km, amplitude_out_km, phase_in, phase_out, *, n_periods=3)[源代码]

生成非线性 CR3BP 下有界的 Lissajous 轨迹(中心流形约化流)。

该单轨设计入口保留原有高阶 normal-form 语义;#428 的统一轨道族参数 采样由独立 Rust family_generation 模块完成,不经过本函数。

参数:
  • system (CR3BP_System) -- CR3BP 系统(含已计算的平动点)。

  • collinear_point (int) -- 共线点编号 1/2/3。

  • amplitude_in_km (float) -- 面内振幅(km)。

  • amplitude_out_km (float) -- 面外振幅(km)。

  • phase_out (float) -- 面内/面外初始相位(0~1)。

  • n_periods (int) -- 轨迹覆盖的名义周期数。

  • phase_in (float)

  • phase_out

返回:

(states, times, nominal_period):states 形状 (M, 6) synodic 质心 系无量纲状态,times 形状 (M,) 对应无量纲时间(TU = T/(2π),与 CR3BP_Dynamics 一致),nominal_period 面内名义周期。

抛出:

RuntimeError -- 中心流形约化或参数化传播失败。

返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]], float]

e2m2e.algorithm.family.lpo_initial_guess module

LPO(Long-Period Orbit)初猜模块。

从 L4/L5 线性化动力学中提取长周期模态(频率 ω_l),构造仅含 长周期分量的平面初猜。不含短周期和垂直模态——它们会导致拟周期 运动,阻碍全周期闭合修正的收敛。

引用

Gómez et al. (2001). Dynamics and mission design near libration points, Vol. II. ESA Contract Report.

e2m2e.algorithm.family.lpo_initial_guess.compute_lpo_initial_guess(system, point, amplitude_km)[源代码]

构造 L4/L5 LPO 初猜状态(仅长周期模态)。

从 L4/L5 线性化矩阵提取长周期模态 v_l(低频),施加面内 振幅扰动,不含短周期和垂直模态。

初猜形状为扁长椭圆(轴比 ~0.19,Catlin & McLaughlin 2007), 适合全周期闭合修正。

参数:
  • system (CR3BP_System) -- CR3BP 系统(含已计算平动点)。

  • point (int) -- 4(L4)或 5(L5)。

  • amplitude_km (float) -- 面内振幅(km),扰动幅度。

返回:

(state0, nominal_period):t=0 的 6 维状态(无量纲 synodic)与 长周期名义周期 2π/ω_l。

返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]], float]

e2m2e.algorithm.family.spo_initial_guess module

SPO(Short-Period Orbit)初猜模块。

从 L4/L5 线性化动力学中提取短周期模态(频率 ω_s),构造仅含 短周期分量的平面初猜。不含长周期和垂直模态——它们会导致拟周期 运动,阻碍全周期闭合修正的收敛。

引用

Gómez et al. (2001). Dynamics and mission design near libration points, Vol. II. ESA Contract Report.

e2m2e.algorithm.family.spo_initial_guess.compute_spo_initial_guess(system, point, amplitude_km)[源代码]

构造 L4/L5 SPO 初猜状态(仅短周期模态)。

从 L4/L5 线性化矩阵提取短周期模态 v_s(高频),施加面内 振幅扰动,不含长周期和垂直模态。

初猜形状为近似椭圆(主导谐波 n=1),适合全周期闭合修正。

参数:
  • system (CR3BP_System) -- CR3BP 系统(含已计算平动点)。

  • point (int) -- 4(L4)或 5(L5)。

  • amplitude_km (float) -- 面内振幅(km),扰动幅度。

返回:

(state0, nominal_period):t=0 的 6 维状态(无量纲 synodic)与 短周期名义周期 2π/ω_s。

返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]], float]

e2m2e.algorithm.family.triangular_initial_guess module

L4/L5 三角平动点邻域的一阶解析初猜。

L4/L5 在纯 CR3BP 下是椭圆型平衡点(地月 μ=0.0122 < μ_Routh≈0.0385), 线性化矩阵只有纯虚特征值,没有双曲方向。邻域运动是三模态拟周期叠加:

  • 面内两个模态:短周期(频率 ω_s,高频)与长周期(频率 ω_l,低频);

  • 面外一个模态:垂直方向独立振动(频率 ω_v)。

两频率满足特征方程 ω⁴ − ω² + 27μ(1−μ)/4 = 0(无量纲),比值不可约, 因此 L4/L5 邻域本质是拟周期轨道,不强求周期闭合。本模块用线性化特征 向量构造一阶初猜,面内振幅默认均分给短/长两模态,后续按 DFH golden 样本标定拆分比例。初猜直接作 patch points 采样基准,交给下游星历 多重打靶精化。

引用

Gómez, G., et al. (2001). Dynamics and mission design near libration points, Vol. I. 三角点邻域的线性化模态分解。

e2m2e.algorithm.family.triangular_initial_guess.compute_triangular_initial_guess(system, point, amplitude_in_km, amplitude_out_km, phase_in, phase_out)[源代码]

构造 L4/L5 邻域一阶初猜状态。

\[\vec x(t) = \vec x_L + \alpha_s\, \mathrm{Re}[\vec v_s\, e^{i(\omega_s t + \phi)}] + \alpha_l\, \mathrm{Re}[\vec v_l\, e^{i(\omega_l t + \phi)}] + \beta\, \mathrm{Re}[\vec v_z\, e^{i(\omega_v t + \psi)}]\]

面内振幅 amplitude_in_km 默认均分给短/长两模态(按 golden 标定 前的约定);面外振幅给垂直模态。相位 phase_in 同时作用于两个面内 模态,phase_out 作用于垂直模态。

参数:
  • system (CR3BP_System) -- CR3BP 系统(含已计算平动点)。

  • point (int) -- 4(L4)或 5(L5)。

  • amplitude_in_km (float) -- 面内振幅(km)。

  • amplitude_out_km (float) -- 面外振幅(km)。

  • phase_in (float) -- 面内初始相位(0~1,映射到 0~2π)。

  • phase_out (float) -- 面外初始相位(0~1,映射到 0~2π)。

返回:

(state0, nominal_period):t=0 的 6 维状态(无量纲 synodic)与 面内短周期名义周期 2π/ω_s(作 patch points 采样基准)。

返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]], float]

e2m2e.algorithm.family.strategies package

微分修正策略函数。

每个策略函数返回一个不可变的 CorrectionConfig,完整描述修正配置 (对称性、自由变量、约束等)。DifferentialCorrection 类委托给这些函数, 使配置逻辑与迭代求解器分离。

e2m2e.algorithm.family.strategies.base module

微分修正策略的基础配置数据类。

class e2m2e.algorithm.family.strategies.base.CorrectionConfig(setup_type, symmetry_condition, fixed_parameters=<factory>, free_variables=<factory>, free_variable_indices=<factory>, target_conditions=<factory>, constraint_indices=<factory>, constraint_weights=<factory>, constraint_types=<factory>)[源代码]

基类:object

微分修正策略的不可变配置。

将原本散布在 DifferentialCorrection 各 setup_* 方法中的 修正参数封装为单一数据对象。

变量:
  • setup_type (str) -- 修正配置类型标识符。

  • symmetry_condition (str) -- 修正所利用的对称性(如 'x_axis')。

  • fixed_parameters (dict[str, float]) -- 修正过程中保持不变的参数值。

  • free_variables (list[str]) -- 牛顿求解器可调整的变量名列表。

  • free_variable_indices (list[int]) -- 自由变量在状态向量中对应的索引。

  • target_conditions (dict[str, float]) -- 约束名称到目标值的映射。

  • constraint_indices (list[int]) -- 约束在状态向量中的求值索引。

  • constraint_weights (dict[str, float]) -- 各约束的雅可比加权因子。

  • constraint_types (dict[str, str]) -- 各约束的分类(如 'equality')。

参数:
setup_type: str
symmetry_condition: str
fixed_parameters: dict[str, float]
free_variables: list[str]
free_variable_indices: list[int]
target_conditions: dict[str, float]
constraint_indices: list[int]
constraint_weights: dict[str, float]
constraint_types: dict[str, str]

e2m2e.algorithm.family.strategies.symmetric_2d module

二维对称修正策略(平面 CR3BP)。

e2m2e.algorithm.family.strategies.symmetric_2d.symmetric_2d_fixed_x0(x0=0.0)[源代码]

固定 x0 的二维对称修正:自由变量为 y_dot0 和 T_half。

用于在起点和半周期处均垂直穿越 x 轴的平面对称周期轨道。

参数:

x0 (float) -- 固定的初始 x 坐标。

返回:

包含对应修正参数的 CorrectionConfig。

返回类型:

CorrectionConfig

e2m2e.algorithm.family.strategies.symmetric_2d.symmetric_2d_fixed_t(t_half)[源代码]

固定半周期的二维对称修正:自由变量为 x0 和 y_dot0。

参数:

t_half (float) -- 固定的半周期值。

返回:

包含对应修正参数的 CorrectionConfig。

返回类型:

CorrectionConfig

e2m2e.algorithm.family.strategies.symmetric_2d.symmetric_2d_fixed_y0(y0=0.0)[源代码]

固定 y0 的 y 轴对称修正:自由变量为 x_dot0 和 T_half。

适用于从 y 轴出发的共振轨道(RO)等周期轨道。

参数:

y0 (float) -- 固定的初始 y 坐标。

返回:

包含对应修正参数的 CorrectionConfig。

返回类型:

CorrectionConfig

e2m2e.algorithm.family.strategies.symmetric_3d module

三维对称修正策略(空间 CR3BP)。

e2m2e.algorithm.family.strategies.symmetric_3d.symmetric_3d_fixed_x0(x0)[源代码]

固定 x0 的三维对称修正:自由变量为 z0、y_dot0 和 T_half。

用于具有 x 轴对称性的空间周期轨道(如 Halo 轨道)。

参数:

x0 (float) -- 固定的初始 x 坐标。

返回:

包含对应修正参数的 CorrectionConfig。

返回类型:

CorrectionConfig

e2m2e.algorithm.family.strategies.symmetric_3d.symmetric_xz_fixed_x0(x0)[源代码]

固定 x0 的 XZ 平面对称修正:自由变量为 z0、y_dot0 和 T_half。

参数:

x0 (float) -- 固定的初始 x 坐标。

返回:

包含对应修正参数的 CorrectionConfig。

返回类型:

CorrectionConfig

e2m2e.algorithm.family.strategies.symmetric_3d.symmetric_xz_fixed_z0(z0)[源代码]

固定 z0 的 XZ 平面对称修正:自由变量为 x0、y_dot0 和 T_half。

参数:

z0 (float) -- 固定的初始 z 坐标。

返回:

包含对应修正参数的 CorrectionConfig。

返回类型:

CorrectionConfig

e2m2e.algorithm.family.strategies.halo module

Halo 轨道微分修正策略。

e2m2e.algorithm.family.strategies.halo.halo_fixed_z0(z0, libration_point=1)[源代码]

固定 z0 的 Halo 轨道修正(XZ 平面对称)。

自由变量为 x0、y_dot0 和 T_half。平动点编号作为固定参数记录, 供延拓器查询使用。

参数:
  • z0 (float) -- 固定的初始 z 坐标。

  • libration_point (int) -- 拉格朗日点编号(1=L1, 2=L2)。

返回:

包含对应修正参数的 CorrectionConfig。

返回类型:

CorrectionConfig

e2m2e.algorithm.family.strategies.halo.halo_fixed_x0(x0, libration_point=1)[源代码]

固定 x0 的 Halo 轨道修正(XZ 平面对称)。

自由变量为 z0、y_dot0 和 T_half。

参数:
  • x0 (float) -- 固定的初始 x 坐标。

  • libration_point (int) -- 拉格朗日点编号(1=L1, 2=L2)。

返回:

包含对应修正参数的 CorrectionConfig。

返回类型:

CorrectionConfig

e2m2e.algorithm.family.strategies.axial module

Axial 轨道微分修正策略(Gómez Type B 分岔族)。

e2m2e.algorithm.family.strategies.axial.axial_fixed_vz0(vz0, libration_point=1)[源代码]

固定 vz0 的 Axial 轨道修正(x 轴对称,Type B)。

Axial 轨道关于 x 轴对称(旋转 π + 时间反演),初始状态在 x 轴上: (x0, 0, 0, 0, y_dot0, vz0),半周期处回到 x 轴(y=0, z=0, x_dot=0)。

与 Halo(Type A, xz 平面对称, z0≠0, vz0=0)的区别: Axial 的 z0=0, vz0≠0——轨道从 xy 平面出发,获得面外速度后 在半周期返回 xy 平面(z 翻转:z(t) = -z(T-t))。

自由变量为 x0、y_dot0 和 T_half(3 自由变量 vs 3 约束,方阵)。

参数:
  • vz0 (float) -- 固定的初始 z 方向速度(无量纲 DU/TU),带符号区分上/下族。

  • libration_point (int) -- 拉格朗日点编号(1=L1, 2=L2)。

返回:

包含对应修正参数的 CorrectionConfig。

返回类型:

CorrectionConfig

e2m2e.algorithm.family.strategies.lpo module

LPO(Long-Period Orbit)修正策略。

L4/L5 长周期族是 xy 平面内围绕三角平动点的周期轨道, 不具有 x 轴或 xz 平面对称性。使用通用平面周期修正(全周期闭合)。 最大振幅成员呈马蹄形(Horseshoe),跨越 L4-L1-L5。

引用

Gómez et al. (2001). Dynamics and mission design near libration points, Vol. II. ESA Contract Report. Marchal, C. (1990). The Three-Body Problem. Brown 猜想 C.2.

e2m2e.algorithm.family.strategies.lpo.lpo_fixed_x0(x0, libration_point=5)[源代码]

固定 x₀ 的 LPO 通用平面周期修正。

LPO 无 x 轴对称性(y₀≠0),与 SPO 使用相同的修正框架。 直接求解全周期闭合条件:state(T) - state(0) = 0。

自由变量: [y₀, ẋ₀, ẏ₀, T](4 个,x₀ 固定,z₀=ż₀=0 平面约束) 约束: [Δy=0, Δẋ=0, Δẏ=0](3 个,全周期闭合) → 4 自由 vs 3 约束,欠定系统用最小二乘求解(最小范数修正)。

参数:
  • x0 (float) -- 固定的初始 x 坐标(族参数)。

  • libration_point (int) -- 平动点编号(4=L4, 5=L5),默认 5。

返回类型:

CorrectionConfig

e2m2e.algorithm.family.strategies.spo module

SPO(Short-Period Orbit)修正策略。

L4/L5 短周期族是 xy 平面内围绕三角平动点的周期轨道, 不具有 x 轴或 xz 平面对称性。使用通用平面周期修正(全周期闭合)。

引用

Gómez et al. (2001). Dynamics and mission design near libration points, Vol. II. ESA Contract Report. Capdevila & Howell (2018). A transfer network linking Earth, Moon, and the triangular libration point regions. JGCD.

e2m2e.algorithm.family.strategies.spo.spo_fixed_x0(x0, libration_point=5)[源代码]

固定 x₀ 的 SPO 通用平面周期修正。

SPO 无 x 轴对称性(y₀≠0),不能使用半周期约束。 直接求解全周期闭合条件:state(T) - state(0) = 0。

平面轨道(z₀=ż₀=0):z 方向解耦,Δz 约束恒为零(雅可比奇异), 因此只使用 y/ẋ/ẏ 三个闭合约束 + 周期 T 一个时间自由变量。

自由变量: [y₀, ẋ₀, ẏ₀, T](4 个,x₀ 固定,z₀=ż₀=0 平面约束) 约束: [Δy=0, Δẋ=0, Δẏ=0](3 个,全周期闭合) → 4 自由 vs 3 约束,欠定系统用最小二乘求解(最小范数修正)。

参数:
  • x0 (float) -- 固定的初始 x 坐标(族参数)。

  • libration_point (int) -- 平动点编号(4=L4, 5=L5),默认 5。

返回类型:

CorrectionConfig

e2m2e.algorithm.normal_form package

标准形(Normal Form)算法包(ADR 0011 迁移,源:algorithms/normal_form/)。

为圆型限制性三体问题(CR3BP)平动点附近的轨道设计提供标准形化简流水线 的基础脚手架(算法层子模块 + 可选依赖 [normal-form] + 惰性导入 + 不注册 MCP,三档辅助)。

归一化约定沿用 qiao Global_File.py:长度单位 LU(km)、时间单位 TU(s)、速度单位 VU = LU/TU(km/s)。本包不强制依赖 sympy / joblib:它们仅在 Legendre / Hamiltonian 模块内部惰性导入。

e2m2e.algorithm.normal_form.context module

标准形化简上下文对象 NormalFormContext

集中存放一条标准形化简流水线所需的全部静态/派生数据: 归一化常量、平动点几何、基础频率、中心流形频率、特征指数、用户传入的 历元与展开阶数。本切片只交付构造与读取;后续切片在该对象上调用具体 化简器(DynamicalSubstituteCorrector、QuasiFloquetReducer 等)。

class e2m2e.algorithm.normal_form.context.NormalFormContext(system, libration_point, epoch, order, *, LU=None, TU=None, mu=None, mu_e=None, mu_m=None, mu_s=None, frequency_scale=1.0, force_cr3bp=False)[源代码]

基类:object

标准形化简流水线上下文。

构造时由 System 提供质量比与归一化尺度(若有),并由 LibrationPoint 选择平动点;其余 qiao 归一化常量(LU、TU、mu_e/m/s、JD0、基础频率等) 采用固化值,与 qiao Global_File.py 保持一致。

变量:
  • system -- 关联的 e2m2e System (一般 CR3BP_System)。

  • libration_point -- 选定平动点。

  • epoch -- 参考历元儒略日。

  • order -- 法型展开阶数。

  • LU -- 归一化长度(km)。

  • TU -- 归一化时间(s)。

  • VU -- 归一化速度(km/s),由 LU/TU 推导。

  • mu -- 系统质量比。

  • mu_e -- 归一化地球引力常数(无量纲)。

  • mu_m -- 归一化月球引力常数(无量纲)。

  • mu_s -- 归一化太阳引力常数(无量纲)。

  • jd0 -- 参考历元儒略日。

  • libration_position -- 平动点在无量纲会合系下的 (3,) 坐标。

  • gamma -- 共线平动点的 γ 值;L4/L5 为 None

  • base_frequencies -- 基础频率 (omega_1, ..., omega_4)

  • central_frequencies -- 中心流形频率 (nu_1, nu_2)

  • characteristic_exponent -- 特征指数 λ。

参数:
__init__(system, libration_point, epoch, order, *, LU=None, TU=None, mu=None, mu_e=None, mu_m=None, mu_s=None, frequency_scale=1.0, force_cr3bp=False)[源代码]

构造上下文。

参数:
  • system (System) -- 关联 SystemCR3BP_System 提供 mu; 其他系统如不显式传入 mu 参数则取 0.0

  • libration_point (LibrationPoint) -- 平动点枚举(L1–L5)。

  • epoch (float | datetime) -- 历元,可为儒略日 floatdatetime

  • order (int) -- 法型展开阶数,必须为正整数。

  • LU (float | None) -- 覆盖默认 LU(km)。仅供测试/非地月系统使用。

  • TU (float | None) -- 覆盖默认 TU(s)。仅供测试/非地月系统使用。

  • mu (float | None) -- 覆盖系统/默认质量比。

  • mu_e (float | None) -- 覆盖默认地球引力常数。

  • mu_m (float | None) -- 覆盖默认月球引力常数。

  • mu_s (float | None) -- 覆盖默认太阳引力常数。

  • force_cr3bp (bool) -- 强制纯 CR3BP 模式——整条约化路径(动力学替代 rhs、 Bdot2AC_pq、rho↔EM 旋转矩阵 C)一律直接用 CR3BP 常量,不探 SPICE 星历。用于只要 CR3BP 中心流形约化 的场景(如 design_lissajous 生成有界 Lissajous):即便进程 已全局加载 SPICE 内核也走 CR3BP,避免星历几何进入约化、使 quasi-Floquet↔中心流形 Lie 级数 ODE 失稳。是 CR3BP 约化的 正路声明,不是"SPICE 不可用→降级"。

  • frequency_scale (float)

抛出:

ValueError -- order 非正整数;libration_point 非法。

返回类型:

None

seconds_to_tu(t_seconds)[源代码]

SI 秒 → 归一化 TU。

参数:

t_seconds (float)

返回类型:

float

tu_to_seconds(t_tu)[源代码]

归一化 TU → SI 秒。

参数:

t_tu (float)

返回类型:

float

e2m2e.algorithm.normal_form.types module

Normal-form 流水线的结果类型。

NormalFormResultNormalFormPipeline (issue #175)输出的统一 载体:把前四个切片(动力学替代 / quasi-Floquet / 中心流形 / 表征参数目录) 的结果聚合到一个不可变句柄里。通用化简诊断字段(Hamiltonian 系数、变换 矩阵、残差)与各子结果句柄并存——前者供算法诊断,后者让外部用户一行代码 拿到 catalog_transformer 完成坐标变换。

class e2m2e.algorithm.normal_form.types.NormalFormResult(context, order, substitute_residual=0.0, status=ConvergenceState.FAILED, cause=FailureCause.UNKNOWN, message='', metadata=<factory>, ds_result=None, qf_result=None, cm_result=None, catalog_transformer=None)[源代码]

基类:object

标准形化简流水线统一结果容器。

不可变:所有字段在构造后只读,确保下游消费方按值传递。

字段分两组:

  • 通用化简诊断substitute_residualsuccessmessagemetadata):跨切片稳定,描述整条流水线的收敛情况。保留给仅关心 "是否收敛、残差多大"的诊断调用方。

  • 子结果句柄ds_result / qf_result / cm_result / catalog_transformer):issue #175 新增。指向四个子 reducer 的产物; catalog_transformer 一等公民字段使外部用户能直接 result.catalog_transformer.rho_to_param(X_rho, t) 完成完整坐标变换, 无需自己重组装 LibrationCatalogData

所有新增字段都带默认值,保证仅关心通用字段的既有调用方 (NormalFormResult(context, order, ...))不受影响。

变量:
  • context (NormalFormContext) -- 关联的 NormalFormContext

  • order (int) -- 实际展开阶数(一般等于 context.order)。

  • substitute_residual (float) -- 动力学替代步(多重打靶)的段间连续性残差 (来自 ds_result.residual_norm)。注意它不是 Lie 变换的 截断残差——后者当前写入 metadata["cm_hyperbolic_coupling"]residual 是其向后兼容别名。

  • success -- 流水线是否在容差内收敛。

  • message (str) -- 人类可读的终止原因。

  • metadata (dict[str, object]) -- 自由扩展字段;保留供后续切片写入诊断数据。

  • ds_result (DynamicalSubstituteResult | None) -- 动力学替代结果(切片 #171);流水线未跑到该步时为 None

  • qf_result (QuasiFloquetResult | None) -- quasi-Floquet 结果(切片 #172);同上。

  • cm_result (CenterManifoldResult | None) -- 中心流形化简结果(切片 #173);同上。

  • catalog_transformer (LibrationCatalogTransformer | None) -- 表征参数目录变换器(切片 #174), 绑定 ds_result、qf_result、cm_result 三个子 结果与 context;流水线跑完四步后非 None,是外部用户做 rho param 坐标变换的入口。

参数:
context: NormalFormContext
order: int
substitute_residual: float = 0.0
status: ConvergenceState = 'failed'
cause: FailureCause = 'unknown'
message: str = ''
metadata: dict[str, object]
ds_result: DynamicalSubstituteResult | None = None
qf_result: QuasiFloquetResult | None = None
cm_result: CenterManifoldResult | None = None
catalog_transformer: LibrationCatalogTransformer | None = None
property residual: float

substitute_residual 的向后兼容别名。

早期版本该字段名 residual,但 docstring 描述的"截断残差"与实际 写入的"动力学替代连续性残差"语义不符(见 #224)。新代码应用 substitute_residual;本 property 仅为不破坏既有消费者保留。

save(path)[源代码]

把结果存为 .npz 文件。

所有子结果(DS / QF / CM)及 context 参数一并序列化; catalog_transformer 反序列化时由三个子结果重建,不单独存储。

参数:

path (str | Path) -- 输出 .npz 文件路径;父目录自动创建。

返回类型:

None

classmethod load(path)[源代码]

.npz 文件重建 NormalFormResult

反序列化后 catalog_transformer 自动由三个子结果重建, 与原始对象在 rho_to_param / param_to_rho 上数值等价。

参数:

path (str | Path) -- .npz 文件路径。

返回:

重建的 NormalFormResult

返回类型:

NormalFormResult

e2m2e.algorithm.normal_form.units module

SI ↔ qiao 归一化单位转换。

约定:

  • SI 状态 [x, y, z, vx, vy, vz] 单位为 km + km/s (与 CR3BP_System.physical_to_dimensionless 物理接口一致);

  • qiao 归一化状态使用 LU (位置)与 VU = LU/TU (速度),与 Global_File.py 中无量纲状态保持一致;

  • 时间方向上 SI 秒 ↔ 归一化 TU 通过 NormalFormContext.seconds_to_tu / tu_to_seconds 完成。

to_normalizedfrom_normalized 互为精确逆运算(数值精度内 无截断),后续切片中的所有归一化 Hamilton 量都基于此接口之上。

e2m2e.algorithm.normal_form.units.to_normalized(state_si, context)[源代码]

SI 物理状态 → qiao 归一化状态。

位置除以 context.LU (km),速度除以 context.VU (km/s)。 支持 (6,) 单状态与 (n, 6) 批量状态。

参数:
  • state_si (npt.ArrayLike) -- 物理状态向量 [x, y, z, vx, vy, vz],单位 km + km/s。

  • context (NormalFormContext) -- 归一化上下文。

返回:

与输入同形状的归一化状态数组。

抛出:

ValueError -- 最后一维不是 6。

返回类型:

npt.NDArray[np.floating]

e2m2e.algorithm.normal_form.units.from_normalized(state_norm, context)[源代码]

qiao 归一化状态 → SI 物理状态。

位置乘以 context.LU (km),速度乘以 context.VU (km/s)。 支持 (6,) 单状态与 (n, 6) 批量状态。

参数:
  • state_norm (npt.ArrayLike) -- 归一化状态向量 [x, y, z, vx, vy, vz],无量纲。

  • context (NormalFormContext) -- 归一化上下文。

返回:

与输入同形状的物理状态数组,单位 km + km/s。

抛出:

ValueError -- 最后一维不是 6。

返回类型:

npt.NDArray[np.floating]

e2m2e.algorithm.normal_form.constants module

Normal-form 归一化常数与平动点几何工具。

集中存放 qiao Global_File.py / Calc_LPstate.py 中固化下来的物理 与几何常量,以及从给定质量比反解平动点无量纲坐标、共线点 γ 值的辅助函数。

本模块刻意保持为零依赖(仅依赖 numpy),方便上层模块在 __init__ 阶段按需加载。sympy / joblib 的引入留待后续化简器内部惰性导入。

e2m2e.algorithm.normal_form.constants.LU_KM: float = 384747.981

归一化长度单位 LU(km)。qiao 约定;与 e2m2e 默认地月距离 (384405 km) 略有差异。

e2m2e.algorithm.normal_form.constants.TU_S: float = 375699.843898365

归一化时间单位 TU(秒)。

e2m2e.algorithm.normal_form.constants.VU_KMS: float = 1.0240834199124202

归一化速度单位 VU(km/s),由 LU_KM / TU_S 推导。

e2m2e.algorithm.normal_form.constants.MU: float = 0.01215058560962404

地月质量比 mu = mu_m / (mu_e + mu_m),qiao 约定值。

e2m2e.algorithm.normal_form.constants.MU_E: float = 0.987849414390376

归一化地球引力常数(无量纲,总质量归一)。

e2m2e.algorithm.normal_form.constants.MU_M: float = 0.012150585609624

归一化月球引力常数(无量纲)。

e2m2e.algorithm.normal_form.constants.MU_S: float = 328900.5614

归一化太阳引力常数(无量纲)。

e2m2e.algorithm.normal_form.constants.BASE_FREQUENCIES: tuple[float, ...] = (0.99154828857, 0.07480066375, 0.92519871658, 1.00402177967)

qiao 流水线使用的基础频率 omega_1..omega_4(TU^-1),针对地月系统。

e2m2e.algorithm.normal_form.constants.jday(yr, mon, day, hr=0, minute=0, sec=0.0)[源代码]

公历日期 → 儒略日(Vallado 算法)。

参数:
  • yr (int) -- 年(1900–2100)。

  • mon (int) -- 月(1–12)。

  • day (int) -- 日(1–31)。

  • hr (int) -- 时(0–23)。

  • minute (int) -- 分(0–59)。

  • sec (float) -- 秒(0.0–59.999)。

返回:

对应时刻的儒略日(浮点数)。

返回类型:

float

e2m2e.algorithm.normal_form.constants.JD0_J2000: float = 2451545.0

00)。

Type:

参考历元 J2000.0 的儒略日(2000-01-01 12

Type:

00

e2m2e.algorithm.normal_form.constants.compute_libration_position(point, mu, gamma=None)[源代码]

计算无量纲会合系下平动点位置。

对共线点 (L1/L2/L3),qiao 使用固化 γ 值;如 gammaNone 则 退回到 fsolve 求解与 e2m2e 内部 CR3BP_System.compute_libration_points 一致的非线性方程。三角点 (L4/L5) 给出解析精确位置,与 γ 无关。

参数:
  • point (LibrationPoint) -- 平动点枚举。

  • mu (float) -- 系统质量比。

  • gamma (float | None) -- 共线点的 γ 值;为 None 时自动求解。

返回:

形状 (3,) 的无量纲会合系坐标 [x, y, z]

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.normal_form.constants.libration_gamma(point)[源代码]

返回共线平动点的 qiao 固化 γ 值。

参数:

point (LibrationPoint) -- 必须是 LibrationPoint.L1/L2/L3 之一。

抛出:

ValueError -- point 不是共线平动点。

返回类型:

float

e2m2e.algorithm.normal_form.constants.central_frequencies(point)[源代码]

返回 qiao 中心流形频率 (nu1, nu2)

参数:

point (LibrationPoint) -- 平动点枚举。

返回类型:

tuple[float, float]

e2m2e.algorithm.normal_form.constants.characteristic_exponent(point)[源代码]

返回 qiao 特征指数 λ。

参数:

point (LibrationPoint) -- 平动点枚举。

返回类型:

float

e2m2e.algorithm.normal_form.catalog module

表征参数目录变换器(issue #174,切片 5)。

把切片 #171–#173 的三个预计算结果(动力学替代 W_poly、quasi-Floquet B(t)、中心流形 W_series)绑定到一个**不可变聚合句柄** LibrationCatalogData,并提供面向对象的访问入口 LibrationCatalogTransformer,实现 qiao rho2param / param2rho 的完整坐标变换链 rho param

变换数学完全委托给 coord_trans 子包(5 段函数式叶子函数 + 端到端链式组合)。本模块的职责是:

  1. 聚合:把 DynamicalSubstituteResult / QuasiFloquetResult / CenterManifoldResult 三个句柄 + NormalFormContext 打包成 一个数据类,避免调用方每次变换都要传 4 个参数;

  2. 时间插值封装rho_to_param / param_to_rho 内部对 W / B / W_series 做时刻 t 的插值(由叶子函数完成),调用方只 传状态和时间。

与 #175(pipeline.py 最终 NormalFormResult)的衔接取舍:

  • types.NormalFormResult (切片 0)是一个**通用流水线结果容器** (Hamiltonian 系数、变换矩阵、残差等),字段语义偏"化简结果",不适合 直接当坐标变换的系数聚合器;

  • 本切片定义独立的 LibrationCatalogData 作为**坐标变换专用聚合 句柄**(只持有三个子结果 + context),命名上避开 NormalFormResult 以免与 #175 冲突;

  • #175 可以直接复用本类LibrationCatalogTransformer 的构造只 依赖 context / ds_result / qf_result / cm_result 四个 访问器,#175 的 NormalFormResult 只需暴露这四个属性即可无缝构造 LibrationCatalogData (或直接传 LibrationCatalogData 当字段)。 本切片不在 types.NormalFormResult 上加字段,保持切片 0 容器稳定。

class e2m2e.algorithm.normal_form.catalog.LibrationCatalogData(context, ds_result, qf_result, cm_result)[源代码]

基类:object

表征参数目录变换所需的预计算系数聚合句柄。

不可变:把切片 #171–#173 的三个结果 + 上下文打包,供 LibrationCatalogTransformer 绑定使用。

设计取舍见模块 docstring:本类是**坐标变换专用** 聚合器,不复用 NormalFormResult (后者是 通用流水线结果容器)。#175 的最终 NormalFormResult 可暴露 context/ds_result/qf_result/cm_result 四个属性后直接 构造本类,或反过来把本类当字段嵌入。

变量:
参数:
context: NormalFormContext
ds_result: DynamicalSubstituteResult
qf_result: QuasiFloquetResult
cm_result: CenterManifoldResult
class e2m2e.algorithm.normal_form.catalog.LibrationCatalogTransformer(data)[源代码]

基类:object

表征参数目录变换器(上下文 + 系数绑定)。

LibrationCatalogData 绑定到方法,提供面向对象的 rho_to_param / param_to_rho 入口。所有时刻 t 的插值由 coord_trans 叶子函数在内部完成,调用方只传状态与时间。

参数:

data (LibrationCatalogData) -- 预计算系数聚合句柄(context + 三个子结果)。

data: LibrationCatalogData
property context: NormalFormContext

绑定上下文(透传到 data.context)。

rho_to_param(X_rho, t)[源代码]

rho 坐标 → 表征参数(完整逆链)。

对应 qiao rho2paramrho EM DS QF CM param

参数:
  • X_rho (ArrayLike) -- (6,) rho 状态 [ρ, ρ̇],无量纲。

  • t (float) -- 归一化时间 TU。

返回:

(6,) 表征参数 [q1, p1, I2, θ2, I3, θ3],无量纲。

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

param_to_rho(X_param, t)[源代码]

表征参数 → rho 坐标(完整正链)。

对应 qiao param2rhoparam CM QF DS EM rho。 是 rho_to_param() 的精确逆。

参数:
  • X_param (ArrayLike) -- (6,) 表征参数 [q1, p1, I2, θ2, I3, θ3],无量纲。

  • t (float) -- 归一化时间 TU。

返回:

(6,) rho 状态 [ρ, ρ̇],无量纲。

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.normal_form.polynomial module

多项式 dict 工具:{pow_tuple: coefficient} 的内部表示与运算。

对应 qiao 仓库的 poly_operator (符号 / 混合系数)和 list_operator (数值时间系列系数)两组辅助函数,但只取本切片需要的 子集——expr2polypoly2exprpoly_poissonpoly_simplify 与对应的 polylist_* 数值版本。

约定:

  • 多项式 dict 的幂次向量固定为 (n1, n2, n3, n4, n5, n6), 对应 (q1, q2, q3, p1, p2, p3)

  • 系数可以是 sympy 符号、纯数值(int/float)、或长度为 M 的 一维 numpy.ndarray (数值时间序列);

  • 零多项式统一表示为 {(0, 0, 0, 0, 0, 0): 0} (或长度 M 的零数组)。

本模块属于 normal_form 包内部基础设施,只被同包的 legendre / hamiltonian / 后续 reducer 调用,不对用户 直接暴露——上游接口请走 legendrehamiltonian

e2m2e.algorithm.normal_form.polynomial.order(pow_tuple)[源代码]

返回幂次向量的总阶数(各分量之和)。

参数:

pow_tuple (tuple[int, ...])

返回类型:

int

e2m2e.algorithm.normal_form.polynomial.keys_by_order(poly, *, backend='rust')[源代码]

按总阶数分组返回幂次键。

默认 backend='rust'backend='python' 仅作显式等价性对照。

参数:
返回类型:

dict[int, list[tuple[int, ...]]]

e2m2e.algorithm.normal_form.polynomial.trim_degree(poly, max_degree, *, backend='rust')[源代码]

截断总阶数大于 max_degree 的项。

默认 backend='rust'``(数值系数);含 sympy 符号系数时自动走 Python 参照路径。``backend='python' 仅作显式等价性对照。

参数:
返回类型:

dict[tuple[int, ...], object]

e2m2e.algorithm.normal_form.polynomial.expr2poly(expr, variables=None)[源代码]

把 sympy 表达式分解为幂次向量 → 系数 的 dict。

与 qiao expr2poly 等价,使用 sp.Poly 提取单项式系数。 零多项式返回 {(0,) * 6: 0}

参数:
  • expr (object) -- sympy 表达式。

  • variables (tuple[object, ...] | None) -- 6 个 sympy 符号;默认 (q1, q2, q3, p1, p2, p3)None 时从 expr 中按名 q1, q2, q3, p1, p2, p3 解析; 若 expr 中仍有同名以外的自由符号,多出的会被并入变量顺序中。

返回:

幂次向量 → 系数 dict。

返回类型:

dict[tuple[int, ...], object]

e2m2e.algorithm.normal_form.polynomial.poly2expr(poly, variables=None)[源代码]

幂次向量 → 系数 dict 反向组装为 sympy 表达式。

对应 qiao poly2expr。零项跳过。

参数:
返回类型:

object

e2m2e.algorithm.normal_form.polynomial.poly_subs(poly, subs_map)[源代码]

多项式变量替换:把每个旧变量替换为 subs_map 给出的表达式。

用于 H→QF 映射(Code09):subs_map 把旧坐标 (x1..x6) 映到 新坐标 (q1..p3) 的线性组合 X = B·Y,即 subs_map[x_i] = Σ_j B[i,j]·y_j,其中 y_j 必须命名为 q1, q2, q3, p1, p2, p3。替换后展开、按这套新变量的幂次重排系数。

系数可以是 sympy 表达式(含 B 元素符号)或数值/ndarray(此时 subs_map 的值也应是同形数值/符号,sympy 会广播)。

参数:
  • poly (Mapping[tuple[int, ...], object]) -- 幂次向量 → 系数 dict(变量为 subs_map 的键,即旧变量)。

  • subs_map (Mapping[object, object]) -- 旧变量符号 → 新变量表达式的映射。新变量必须命名为 q1, q2, q3, p1, p2, p3——否则会被 expr2poly() 误当常数,本函数会对此做校验并抛 ValueError

返回:

替换后的幂次向量 → 系数 dict(变量为新变量 q1..p3)。

抛出:

ValueError -- subs_map 值中出现了非 q1..p3 命名的自由符号。

返回类型:

dict[tuple[int, ...], object]

e2m2e.algorithm.normal_form.polynomial.poly_poisson(poly1, poly2, *, backend='rust')[源代码]

计算两个多项式 dict 的泊松括号 {poly1, poly2}

6-DOF 辛流形 (q1, q2, q3, p1, p2, p3) 的泊松括号:

{f, g} = Σ_{k=1}^{3} (∂f/∂q_k · ∂g/∂p_k − ∂f/∂p_k · ∂g/∂q_k)

对单项式 f = c₁ x_i^{a_i}, g = c₂ x_i^{b_i}

{f, g} = c₁ c₂ Σ_k (a_k b_{k+3} - b_k a_{k+3}) x^{a+b-e_k-e_{k+3}}

默认 backend='rust' 走数值核(标量/时间序列、实/复);含 sympy 符号系数时自动走 Python。backend='python' 仅作显式等价性对照, 绝不作为运行时静默回退。

参数:
返回类型:

dict[tuple[int, ...], object]

e2m2e.algorithm.normal_form.polynomial.poly_simplify(poly, eps=1e-12, *, backend='rust')[源代码]

合并同幂次项并剔除小于 eps 的近零项。

默认 backend='rust';含 sympy 符号系数时自动走 Python。 backend='python' 仅作显式等价性对照。

参数:
返回类型:

dict[tuple[int, ...], object]

e2m2e.algorithm.normal_form.polynomial.polylist_simplify(poly, eps=1e-15, *, backend='rust')[源代码]

数值版 poly_simplify:合并同幂次项,剔除均幅值过小的时间序列。

与 qiao polylist_simplify 等价,使用 mean abs 作为阈值。 系数为时间序列 ndarray (实或复值皆可,仅做幅值阈值与逐项累加)。

默认 backend='rust'backend='python' 仅作显式等价性对照。

参数:
返回类型:

dict[tuple[int, ...], Any]

e2m2e.algorithm.normal_form.legendre module

Legendre 展开 1/r,得到关于 (q1, q2, q3, p1, p2, p3) 的多项式字典。

对应 qiao Code02_Legendre_expr.py。思路:

  • 对单位矢量夹角的余弦 cos θ = (qv · r0v) / (q · r0),用 Legendre 多项式递推 P_{n+1} = ((2n+1)/(n+1)) x P_n (n/(n+1)) P_{n-1} 展开 1/|r - q| = (1/r0) Σ (q/r0)^n P_n(cos θ)

  • 每一项代回 q = sqrt(q1² + q2² + q3²),使展开式成为 q1, q2, q3 的纯多项式(P_ncos θ 的多项式,因此 P_n((qv · r0v)/(q·r0))(q/r0)^n 后得到以 q 为分母的各阶齐次多项式,乘 r0 后 的总幂次恰为 n,但符号上每阶仍含分母,待 r0 替换回符号后分母消去);

  • 最后用 sympy 的 Poly 提取幂次 → 系数字典,再 trim_degree 截断 到用户指定的阶数。

API:

本切片中 sympy 仅在函数内部惰性导入,e2m2e.algorithm.normal_form 顶层导入不强制依赖。

class e2m2e.algorithm.normal_form.legendre.LegendreExpansionResult(polynomial, term_count=0, max_degree=0, source_degree=0, notes=<factory>)[源代码]

基类:object

Legendre 展开 1/r 的结果。

变量:
  • polynomial (dict[tuple[int, ...], object]) -- 幂次向量 (n1, n2, n3, n4, n5, n6) → sympy 系数 的字典;(0, 0, 0, 0, 0, 0) 对应常数项。

  • term_count (int) -- polynomial 中非零项数。

  • max_degree (int) -- 截断阶数(总阶数上限)。

  • source_degree (int) -- sympy 推导时使用的最高阶数(在 max_degree 处可能已被 trim_degree 截掉部分项)。

参数:
polynomial: dict[tuple[int, ...], object]
term_count: int = 0
max_degree: int = 0
source_degree: int = 0
notes: tuple[str, ...]
e2m2e.algorithm.normal_form.legendre.expand_legendre_1_over_r(max_degree=10)[源代码]

对 1/|(rx, ry, rz) − (q1, q2, q3)| 做 Legendre 多项式展开。

返回 sympy 系数多项式 dict:键为 (n1, n2, n3, n4, n5, n6), 值为 sympy 系数(标量场不带 μ 乘子;乘子由调用方在 expand_legendre_for_body()hamiltonian 中补上)。

参数:

max_degree (int) -- 截断阶数。共线点通常 8–12;过大会令符号展开变慢、 下游数值化耗时增加。max_degree < 1ValueError

返回:

LegendreExpansionResult

返回类型:

LegendreExpansionResult

e2m2e.algorithm.normal_form.legendre.expand_legendre_for_body(expansion, mu)[源代码]

· Le 形式应用到 Legendre 标量场,输出 hamiltonian 用 dict。

参数:
返回:

expansion.polynomial 同形状、键相同的 dict;每个系数 变为原系数乘

返回类型:

dict[tuple[int, ...], object]

e2m2e.algorithm.normal_form.legendre.legendre_free_symbols(expansion)[源代码]

返回 expansion.polynomial 中所有符号(用于 hamiltonian 替换检测)。

参数:

expansion (LegendreExpansionResult)

返回类型:

set[object]

e2m2e.algorithm.normal_form.hamiltonian module

构建与数值化标准形 Hamilton 量。

对应 qiao Code03_Hamilton_expr.py (符号构造)与 Code04_Hamilton_num.py (在指定历元窗口上求数值时间序列)。

公开接口:

  • Hamiltonian —— 不可变结果容器,封装符号 dict {pow_tuple: coefficient}、依赖的动态参数名,以及数值化方法 evaluated_coefficients(times, context)coefficient 字段 可以是 sympy 符号(build_hamiltonian 之后),也可以是 numpy 数组 (evaluate_hamiltonian 之后);两者互斥,分别服务于静/动态两种 消费路径。

  • build_hamiltonian() —— 接受 NormalFormContextLegendreExpansionResult,构造包含动能 / Coriolis-pq / 离心-qq / 强制项 f·q / 地球+月球+太阳引力势的 Hamilton 多项式(sympy 系数)。

  • evaluate_hamiltonian() —— 在 Hamiltonian 上批量求数值 时间序列,返回 ndarray 形状 (len(times), n_terms);幂次向量 同步保留在 Hamiltonian 中。

设计上让 Hamiltonian 始终保留幂次向量,便于后续 QuasiFloquetReducer / CenterManifoldReducer 调用同一对象。

class e2m2e.algorithm.normal_form.hamiltonian.Hamiltonian(powers, coefficients=None, sources=<factory>, max_degree=0)[源代码]

基类:object

Hamilton 量封装,包含符号系数 dict 与幂次向量数组。

变量:
  • powers (numpy.ndarray[tuple[Any, ...], numpy.dtype[numpy.integer]]) -- (n_terms, 6) int64 幂次向量数组;行序与 coefficients 一一对应。

  • coefficients (dict[tuple[int, ...], object] | numpy.ndarray[tuple[Any, ...], numpy.dtype[numpy.floating]] | None) -- 幂次向量 → sympy 系数(来自 build_hamiltonian) 或 → ndarray 时间序列(来自 evaluate_hamiltonian)。 默认为 None,代表该 Hamiltonian 尚未填充系数。

  • sources (dict[str, dict[tuple[int, ...], object]]) -- dict,键为各组成(kinetic / coriolis / centrifugal / force / earth / moon / sun)名称,值为幂次向量 → sympy 系数 的子字典;用于诊断 / 中间检查。

  • max_degree (int) -- 构造时使用的截断阶数;保留以便复用。

参数:
powers: ndarray[tuple[Any, ...], dtype[integer]]
coefficients: dict[tuple[int, ...], object] | ndarray[tuple[Any, ...], dtype[floating]] | None = None
sources: dict[str, dict[tuple[int, ...], object]]
max_degree: int = 0
property n_terms: int
property is_evaluated: bool
e2m2e.algorithm.normal_form.hamiltonian.build_hamiltonian(context, legendre_result, *, max_degree=None, store_sources=True)[源代码]

组装符号 Hamilton 量。

Hamilton = f·q + ½‖p‖² + pᵀ C_pq q + ½ qᵀ C_qq q

− μ_e / |r_e − q_LP − q| − μ_m / |r_m − q_LP − q| − μ_s / |r_s − q_LP − q|

三个引力势分别用 Legendre 标量场乘 替换 (rx, ry, rz, r0) 成对应天体的观测向量后加入。

参数:
返回:

Hamiltoniancoefficients 是幂次向量 → sympy 系数 的 dict。

返回类型:

Hamiltonian

e2m2e.algorithm.normal_form.hamiltonian.build_cr3bp_hamiltonian(context, max_degree=None)[源代码]

构造纯 CR3BP Hamiltonian(数值系数 dict,不依赖 SPICE)。

CR3BP 是自治系统,平动点是不动点,故 Hamiltonian 系数为常数。本函数 复用 build_hamiltonian() 的符号构造,再把全部动态参数替换为 CR3BP 常数值,得到 {pow_tuple: float} 的纯数值 dict。

对应 Gómez vol III 2.7 的 LISWCH GENHAM 步(CR3BP 原路):在平动点 偏移坐标 q = (q1,q2,q3) 下展开

\[H = \tfrac12\|p\|^2 + p^T C_{pq} q + \tfrac12 q^T C_{qq} q - \mu_e/\|r_e - q\| - \mu_m/\|r_m - q\|\]

其中 C_pq 为科里奥利、C_qq 为离心,r_e=(-\mu-x_{LP},0,0)r_m=(1-\mu-x_{LP},0,0) 为两主天体相对平动点的位置。太阳项置零 (CR3BP 只含两个主天体)。一阶项 f·q 在平动点处为零(平衡点)。

参数:
  • context (NormalFormContext) -- 归一化上下文(提供 mulibration_position 等)。 本函数内部以 mu_s=0 重新构造上下文以消去太阳项。

  • max_degree (int | None) -- 截断阶数;None 时用 context.order

返回:

幂次向量 → 纯数值 float 系数的 dict。系数为常数(不随时间), 可直接广播成时间序列供 CenterManifoldReducer 注入。

返回类型:

dict[tuple[int, ...], float]

备注

evaluate_hamiltonian() 不同,本函数**不** 产出时间序列—— CR3BP 自治,系数恒定。调用方(如 pipeline)若需与 qf_result.tlist 对齐的时间序列,自行 np.full(N, coef) 广播即可。

e2m2e.algorithm.normal_form.hamiltonian.evaluate_hamiltonian(hamiltonian, times, context)[源代码]

对 Hamilton 量在指定时刻序列上求数值时间序列。

参数:
返回:

一个新的 Hamiltonian

  • powers(n_terms, 6) int64 数组;

  • coefficients(n_times, n_terms) 浮点 ndarray

  • max_degree 等字段与输入一致。

返回类型:

Hamiltonian

e2m2e.algorithm.normal_form.hamiltonian.hamiltonian_constant_term(hamiltonian, times, context)[源代码]

返回 Hamilton 量常值项 H_0(t) 的时间序列,形状 (len(times),)

常值项即 (0, 0, 0, 0, 0, 0) 幂次对应的系数;当 Hamilton 量 已被数值化时直接取列;未数值化时本函数会先走完一遍 evaluate_hamiltonian() 再取常值列。

参数:
返回类型:

npt.NDArray[np.floating]

e2m2e.algorithm.normal_form.dynamical_substitution module

动力学替代轨道与生成函数 W 计算(Code5)。

对应 qiao Code05_DynSubs_Gfunc.py

  1. 多点打靶:在归一化时间窗口上以等距节点构造初值;用块三对角 Newton 迭代求解连续性方程,得到一条围绕平动点的闭轨道 b(t) = (rho, rhodot)

  2. 频域分解:对 b(t) 做频率分析(NAFF/FFT),把受迫分量与 中心流形分量分离;

  3. 生成函数 ``W(t)``:对动量分量数值微分得 ,由 Bdot2A 公式把 BA 拼起来,组装 W_poly / Wdot_poly

Public API:

实现策略:

  • 复用 multiple_shooting 的块三对角消元;

  • 复用 fft 的 NAFF/FFT 后端显式选择;

  • 复用 hamiltonian.evaluate_hamiltonian() / 星历参数(与 slice 1 保持接口一致);

  • 当外部 SPICE 内核不可用时(如 CI 环境),reducePure CR3BP 退路:忽略太阳与三体摄动,使用旋转系下的 Hill 方程; 该退路仅供烟雾测试,不用于生产数据。

e2m2e.algorithm.normal_form.dynamical_substitution.DEFAULT_TOTAL_TU: float = 6553.6

qiao Code05 默认总窗口:0.1 * 2^16 = 6553.6 TU

e2m2e.algorithm.normal_form.dynamical_substitution.DEFAULT_NODE_STEP: float = 0.8

qiao Code05 默认节点间距:0.8 TU

e2m2e.algorithm.normal_form.dynamical_substitution.DEFAULT_DENSE_STEP: float = 0.1

qiao Code05 稠密输出采样间距:0.1 TU

e2m2e.algorithm.normal_form.dynamical_substitution.DEFAULT_MAX_ITER: int = 19

qiao Code05 Newton 迭代最大轮数:20

e2m2e.algorithm.normal_form.dynamical_substitution.DEFAULT_TOLERANCE: float = 1e-11

qiao Code05 收敛容差:1e-11

class e2m2e.algorithm.normal_form.dynamical_substitution.DynamicalSubstituteCorrector(context, t_total=6553.6, node_step=0.8, dense_step=0.1, max_iter=19, tolerance=1e-11, prefer='fft', spice_optional=False)[源代码]

基类:object

动力学替代 corrector(上下文绑定)。

通过 reduce()seed 状态修正到动力学替代轨道 b(t), 并输出生成函数 W / Wdot 与频率分析结果。

参数:
  • context (NormalFormContext) -- 归一化上下文。

  • t_total (float) -- 打靶总窗口(TU)。

  • node_step (float) -- 节点间距(TU)。

  • dense_step (float) -- 稠密输出采样间距(TU)。

  • max_iter (int) -- Newton 最大迭代轮数。

  • tolerance (float) -- 收敛容差(最大连续性残差)。

  • prefer (str) -- 频率分析后端选择("naff"/"fft"),默认 "fft"; 选定 "naff" 而二进制不可用时抛错(ADR 0020 决策 4)。

  • spice_optional (bool) -- SPICE 内核不可用时是否允许降级到纯 CR3BP。 默认 False:SPICE 不可用即抛(ADR 0020 决策 4,资源缺失 不隐式降级);显式传 True 才允许调用方显式接受降级。

context: NormalFormContext
t_total: float = 6553.6
node_step: float = 0.8
dense_step: float = 0.1
max_iter: int = 19
tolerance: float = 1e-11
prefer: str = 'fft'
spice_optional: bool = False
reduce(seed=None)[源代码]

seed 状态执行动力学替代校正。

参数:

seed (ArrayLike | None) -- (6,) rho 坐标初始状态;None 时用平动点位置 零速度作为初始猜测(X_Q 全零初值)。

返回:

DynamicalSubstituteResult

抛出:

RuntimeError -- 当 spice_optional=False (默认)且 SPICE 不可用。

返回类型:

DynamicalSubstituteResult

class e2m2e.algorithm.normal_form.dynamical_substitution.DynamicalSubstituteResult(context, order, substitute_orbit, tlist, Xlist, W_poly, Wdot_poly, fft_components=<factory>, shooting_result=None, backend='fft', spice_available=False, metadata=<factory>)[源代码]

基类:object

动力学替代校正结果。

变量:
  • context (NormalFormContext) -- 关联 NormalFormContext

  • order (int) -- 展开阶数(与 context.order 一致)。

  • substitute_orbit (npt.NDArray[np.floating]) -- 替代轨道稠密输出,(n, 6) 状态数组。

  • tlist (npt.NDArray[np.floating]) -- 稠密输出时间数组,形状 (n,),归一化 TU。

  • Xlist (npt.NDArray[np.floating]) -- 稠密输出状态数组,形状 (n, 6)

  • W_poly (dict[tuple[int, ...], npt.NDArray[np.floating]]) -- (pow, coef_array) 形式的生成函数 W(t);6 个 线性项各对应一个幂次 (1,0,0,0,0,0)/.../(0,0,0,0,0,1)

  • Wdot_poly (dict[tuple[int, ...], npt.NDArray[np.floating]]) -- 与 W_poly 同结构的 Wdot(t)

  • fft_components (dict[str, list[FFTComponent]]) -- x/y/z 三个方向的 FFTComponent 列表; 供后续 slice 引用。

  • shooting_result (normal_form.multiple_shooting.MultipleShootingResult | None) -- 多重打靶迭代结果(节点、残差历史、收敛标志)。

  • backend (str) -- 实际使用的频率分析后端:"naff" / "fft"

  • spice_available (bool) -- 本次 reduce 是否实际使用了 SPICE 星历模型。

  • metadata (dict[str, object]) -- 自由扩展字段。

参数:
context: NormalFormContext
order: int
substitute_orbit: npt.NDArray[np.floating]
tlist: npt.NDArray[np.floating]
Xlist: npt.NDArray[np.floating]
W_poly: dict[tuple[int, ...], npt.NDArray[np.floating]]
Wdot_poly: dict[tuple[int, ...], npt.NDArray[np.floating]]
fft_components: dict[str, list[FFTComponent]]
shooting_result: normal_form.multiple_shooting.MultipleShootingResult | None = None
backend: str = 'fft'
spice_available: bool = False
metadata: dict[str, object]
property residual_norm: float

打靶连续性残差最大值(供调用方快速判定收敛性)。

e2m2e.algorithm.normal_form.fft module

频率分析(FFT/NAFF)辅助函数。

对应 qiao Subfunction/fft_operatorSubfunction/fft2num

NAFF 检测只在调用方显式调用 detect_naff() 时触发;本模块其余函数 不强制依赖 NAFF 可用性,从而保证 import e2m2e.algorithm.normal_form 在任何环境都能正常工作。

class e2m2e.algorithm.normal_form.fft.FFTComponent(freq, amp_s=0.0, amp_c=0.0, amp=0.0, match_freq=0.0, coef=<factory>, err=0.0)[源代码]

基类:object

单个频域分量 s·sin(ωt) + c·cos(ωt)

变量:
  • freq (float) -- 角频率 ω

  • amp_s (float) -- 正弦振幅 s

  • amp_c (float) -- 余弦振幅 c

  • amp (float) -- 总振幅 sqrt(s² + c²)

  • match_freq (float) -- 在基频表上最近邻匹配频率(frequency_match 写入)。

  • coef (tuple[int, ...]) -- 与 match_freq 对应的整数系数向量。

  • err (float) -- 频率匹配误差 |freq - match_freq|

参数:
freq: float
amp_s: float = 0.0
amp_c: float = 0.0
amp: float = 0.0
match_freq: float = 0.0
coef: tuple[int, ...]
err: float = 0.0
e2m2e.algorithm.normal_form.fft.NAFF_TIMEOUT_S: float = 300.0

NAFF 调用超时(秒)。

e2m2e.algorithm.normal_form.fft.naff_available()[源代码]

当前环境是否可调用外部 NAFF(无须抛错)。

返回类型:

bool

e2m2e.algorithm.normal_form.fft.detect_naff(times, data, *, n_components=10, timeout=300.0)[源代码]

调用外部 NAFF 提取时间序列主要频率分量。

参数:
  • times (ArrayLike) -- 等距采样时间序列,形状 (N,)

  • data (ArrayLike) -- 与 times 对应的实信号,形状 (N,)

  • n_components (int) -- NAFF 期望返回的分量数(透传给控制文件第 8 行)。

  • timeout (float) -- NAFF 调用超时(秒)。

返回:

按振幅降序排列的 FFTComponent 列表;直流分量(ω=0) 始终位于首位。

抛出:

RuntimeError -- NAFF 不可用(naff_available() 返回 False), 或调用失败。

返回类型:

list[FFTComponent]

e2m2e.algorithm.normal_form.fft.fft_extract(times, data, *, n_components=None, detrend=True)[源代码]

用 NumPy FFT 提取时间序列的主要频率分量(NAFF 不可用时的降级路径)。

算法:去均值 → Hanning 窗 → FFT → 取正频率 → 找 n_components 个最大幅值 → 二次谱插值校正(提高频率估计精度)→ 构造 FFTComponent

与真正的 NAFF 相比,FFT 路径的频率估计误差量级为 Δf / N,对 本切片(T_total = 0.1·2^16 TUN 6554)足以分辨受迫 频率与中心流形频率。

参数:
  • times (ArrayLike) -- 等距采样时间序列。

  • data (ArrayLike) -- 同形状实信号。

  • n_components (int | None) -- 保留分量数。None 时取 min(N // 2, 50), 并去掉直流项;显式给定 0 或负数返回空列表。

  • detrend (bool) -- 是否先减去均值再变换。

返回:

按振幅降序排列的 FFTComponent` 列表;直流分量始终位于 首位(若信号均值非零)。

返回类型:

list[FFTComponent]

e2m2e.algorithm.normal_form.fft.frequency_match(components, basis_freqs, basis_coefs=None)[源代码]

把 FFT 分量匹配到预计算基频表最近邻。

对应 qiao fft_match

参数:
  • components (list[FFTComponent]) -- detect_naff()fft_extract() 输出。

  • basis_freqs (ArrayLike) -- (M,) 基频角频率数组。

  • basis_coefs (ArrayLike | None) -- (M, k) 整数系数矩阵(每行一个基频对应的 整数系数向量)。None 时系数填零向量。

返回:

原列表的浅拷贝(每个 FFTComponent 替换为带匹配信息 的新实例)。

返回类型:

list[FFTComponent]

e2m2e.algorithm.normal_form.fft.reconstruct_signal(t, components)[源代码]

从 FFT 频域表示重构时域信号 X(t) = Σ s·sin(ωt) + c·cos(ωt)

对应 qiao FFT_X。当所有 amp_s == 0 (FFT 路径常见情况)时, 该函数退化为余弦和;一般配合 least_squares_sin_cos_fit() 精细分配 (amp_s, amp_c) 后使用。

参数:
  • t (ArrayLike) -- 标量或 (M,) 数组。

  • components (list[FFTComponent]) -- 频域分量列表。

返回:

t 同形状的实数数组。

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.normal_form.fft.reconstruct_derivative(t, components)[源代码]

从 FFT 频域表示重构时域信号的一阶导数 dX/dt

对应 qiao FFT_dXd(sin)/dt = ω·cosd(cos)/dt = -ω·sin

参数:
返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.normal_form.fft.least_squares_sin_cos_fit(times, data, frequencies, *, subtract_mean=True)[源代码]

对给定频率集合用最小二乘拟合 s·sin(ωt) + c·cos(ωt)

当频率由 fft_extract() 得到但 amp_s == 0 时,本函数可 给出更精确的正弦/余弦振幅分配:每个频率解一个 2×2 正规方程。

参数:
  • times (ArrayLike) -- (N,) 采样时刻。

  • data (ArrayLike) -- (N,) 信号采样值。

  • frequencies (ArrayLike) -- (K,) 角频率(含 0 表示直流)。

  • subtract_mean (bool) -- 是否先减去均值(与 fft_extract() 默认行为一致)。

返回:

frequencies 同序的 FFTComponent 列表。

返回类型:

list[FFTComponent]

e2m2e.algorithm.normal_form.fft.extract_frequencies(times, data, *, n_components=None, prefer='fft')[源代码]

频率分析入口:后端显式选择,只收 "naff" / "fft"

参数:
  • times (ArrayLike) -- (N,) 时间数组。

  • data (ArrayLike) -- (N,) 信号数组。

  • n_components (int | None) -- NAFF/FFT 保留分量数;None 时取 min(N // 2, 50)

  • prefer (str) -- "naff" / "fft" 之一,默认 "fft"。选定 "naff" 而二进制不可用或调用失败时抛 RuntimeError (ADR 0020 决策 4:资源缺失报错,不隐式降级;ADR 0025 废除 "auto")。

返回:

(components, backend) —— componentsFFTComponent 列表;backend"naff""fft",便于调用方记录诊断。

返回类型:

tuple[list[FFTComponent], str]

e2m2e.algorithm.normal_form.multiple_shooting module

块三对角多重打靶法(Block-Tridiagonal Multiple Shooting)。

对应 qiao Code05_DynSubs_Gfunc.py 的多重打靶 Newton 迭代部分:

  • t_Q 节点上每段独立积分并组装状态转移矩阵 Φ_i

  • 用块三对角消元(L/D/X_d 前代 + 回代)解连续性残差 Xf_i - X_Q_{i+1}

  • 在多次迭代中收敛,得到只含受迫频率的动力学替代轨道 b(t)

与既有 e2m2e.algorithm.solver.multiple_shooting.MultipleShooting 不同, 本模块:

  • 不引入可变时间节点;

  • 不使用工作池并行(qiao 流水线单进程即可,下游 fft/w_func 也是单线程串行);

  • 暴露 SubstituteSolver 协议,把"如何积分一段弧并给出 (Xf, Φ)"留给调用方注入,便于:

    1. 单元测试注入假动力学;

    2. 未来把现有 MultipleShooting 适配到本接口 (多进程并行路径)。

Public API:

e2m2e.algorithm.normal_form.multiple_shooting.PatchStates

(N, 6) 节点状态数组;每行 [q1, q2, q3, p1, p2, p3] (rho 坐标)。

ndarray[tuple[Any, ...], dtype[floating]] 的别名

e2m2e.algorithm.normal_form.multiple_shooting.STMStack

(N-1, 6, 6) 状态转移矩阵 Φ_i = Φ(t_{i+1}; t_i, X_i)

ndarray[tuple[Any, ...], dtype[floating]] 的别名

class e2m2e.algorithm.normal_form.multiple_shooting.SubstituteSolver(*args, **kwargs)[源代码]

基类:Protocol

动力学替代打靶求解器协议。

给定 (t0, tf, X0),返回 (Xf, Phi)

  • Xf: (6,) 段终端状态;

  • Phi: (6, 6) 段状态转移矩阵 ∂Xf/∂X0

propagate_segment(t0, tf, x0)[源代码]
参数:
返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]]

class e2m2e.algorithm.normal_form.multiple_shooting.ShootingPatch(t_Q, X_Q)[源代码]

基类:object

打靶节点与时间。

变量:
参数:
t_Q: ndarray[tuple[Any, ...], dtype[floating]]
X_Q: ndarray[tuple[Any, ...], dtype[floating]]
class e2m2e.algorithm.normal_form.multiple_shooting.MultipleShootingResult(t_Q, X_Q, max_residual, mean_residual, iterations, status, cause, message, residual_history=())[源代码]

基类:object

多重打靶迭代结果。

变量:
参数:
t_Q: ndarray[tuple[Any, ...], dtype[floating]]
X_Q: ndarray[tuple[Any, ...], dtype[floating]]
max_residual: float
mean_residual: float
iterations: int
status: ConvergenceState
cause: FailureCause
message: str
residual_history: tuple[float, ...] = ()
e2m2e.algorithm.normal_form.multiple_shooting.solve_block_tridiagonal(phi_stack, xf_stack, X_Q)[源代码]

对给定段结果做单轮块三对角 Newton 修正。

对应 qiao Code05_DynSubs_Gfunc.py 第 100–145 行。

参数:
返回:

(delta_Q, errors)delta_Q(N, 6) 的修正量;errors 是每段连续性残差范数。

返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]], list[float]]

e2m2e.algorithm.normal_form.multiple_shooting.multiple_shooting_newton(initial, solver, *, max_iter=19, tolerance=1e-11, min_iter=5, early_stop=True, phi_stack=None, xf_stack=None)[源代码]

多轮 Newton 迭代收敛动力学替代轨道。

与 qiao 主循环等价的策略:

  1. 对每段调用 solver.propagate_segment 得到 (Xf, Φ)

  2. solve_block_tridiagonal() 算修正量 delta_Q

  3. max_residual < tolerance 或超过 min_iter 且残差平稳则退出;

  4. 否则 X_Q += delta_Q 继续迭代。

参数:
  • initial (ShootingPatch) -- 初始 ShootingPatch (包含 t_QX_Q)。

  • solver (SubstituteSolver) -- SubstituteSolver 实现,给出每段 (Xf, Φ)

  • max_iter (int) -- 最大迭代轮数。

  • tolerance (float) -- 收敛容差(最大连续性残差)。

  • min_iter (int) -- 最少迭代轮数;早于此值不接受早停。

  • early_stop (bool) -- 是否在残差平稳时早停。

  • phi_stack (ndarray[tuple[Any, ...], dtype[floating]] | None) -- 预计算的 (N-1, 6, 6) STM 栈;为 None 时内部重算。 主要用于调用方在重构/FFT 分析之间复用 STM。

  • xf_stack (ndarray[tuple[Any, ...], dtype[floating]] | None) -- 预计算的 (N-1, 6) 终端状态栈;同上。

返回:

MultipleShootingResult,含收敛后的 t_Q / X_Q 与 残差历史。

返回类型:

MultipleShootingResult

class e2m2e.algorithm.normal_form.multiple_shooting.ODESubstituteSolver(rhs, rtol=1e-10, atol=1e-12, max_step=None, stm_eps=1e-07)[源代码]

基类:object

通用 ODE 替代打靶求解器。

通过注入 rhs(t, X) -> (6,) 即可工作;STM 用中心差分近似。

变量:
  • rhs (collections.abc.Callable[[float, numpy._typing.ArrayLike], numpy._typing.ArrayLike]) -- 状态右端项 f(t, X) -> (6,)

  • rtol (float) -- 相对容差(默认 1e-10)。

  • atol (float) -- 绝对容差(默认 1e-12)。

  • max_step (float | None) -- 最大步长(默认 None,由 solver 自适应)。

  • stm_eps (float) -- 中心差分步长(默认 1e-7)。

参数:
rhs: Callable[[float, ArrayLike], ArrayLike]
rtol: float = 1e-10
atol: float = 1e-12
max_step: float | None = None
stm_eps: float = 1e-07
propagate_segment(t0, tf, x0)[源代码]

积分单段并用中心差分近似 STM。

参数:
返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]]

e2m2e.algorithm.normal_form.quasi_floquet module

quasi-Floquet 变换矩阵 B(t) (Code7–Code9)。

对应 qiao Code08_QuasiFloquet.py (矩阵法)与 Code08_QuasiFloquet_LA.py (李代数法):从动力学替代轨道出发,求解

\[\dot{B}(t) = M(t)\,B(t) - B(t)\,D,\qquad B^{T} J B = J,\]

其中 M(t) 是替代轨道邻域的时变线性化矩阵,D 是实标准形矩阵 (一双曲方向 ±λ,两中心方向 ±i ω_p±i ω_v),J 是 6 维 辛矩阵。B(t) 把受迫线性化系统化为常系数的 = D·Y

两种实现:

  • 矩阵法method="matrix"):把 B 展平为 36 维状态直接积分 = M·B B·D,事后用 Newton 迭代把每个采样点的 B 投影到 最近的辛矩阵(qiao Code08_QuasiFloquet);

  • 李代数法method="lie_algebra"):参数化 B = B₀·exp(ξ)ξ sp(6, R) (21 维),在李代数里做修正,B 自动保辛(qiao Code08_QuasiFloquet_LA);

  • 常数法method="constant"):CR3BP 下 M 是常数矩阵, 方程 = M·B B·D 有常数解 B = V (把 M 化到实标准形 D 的变换矩阵)。V 的元素 O(1)、不随 e^{λt} 增长,投影到 QF 坐标的 Hamiltonian 系数保持常数——中心流形化简的同调方程退化为 代数除法(Gómez vol III §2.7.1),无需 FFT 频域求解。矩阵法/多点 打靶在 CR3BP 下解出的时变解(B(0)=I 前向或 B(T)=I 末端)使 系数随窗口变化,短窗口下 FFT 求解器因频率分辨率不足产生系统偏差。

辛保持性的数值保证:当 M(t)D 都是 Hamilton 矩阵 (MᵀJ + JM = 0)时,BᵀJB 方程的精确首次积分,因此 本模块刻意构造 M(t) = J·S(t)S 对称)以保证辛约束在 <1e-12 量级成立;矩阵法仍在末尾做一次辛投影兜底。

Public API:

单位约定:M(t)DB(t) 全部在 qiao 归一化单位(TU)下 运算;与 SI 之间的换算只能经由 NormalFormContextunits 模块。本模块不暴露 qiao 的 QFtrans_mat 原始结构。

e2m2e.algorithm.normal_form.quasi_floquet.J6: ndarray[tuple[Any, ...], dtype[floating]] = array([[ 0.,  0.,  0.,  1.,  0.,  0.],        [ 0.,  0.,  0.,  0.,  1.,  0.],        [ 0.,  0.,  0.,  0.,  0.,  1.],        [-1., -0., -0.,  0.,  0.,  0.],        [-0., -1., -0.,  0.,  0.,  0.],        [-0., -0., -1.,  0.,  0.,  0.]])

6 维辛矩阵 J = [[0, I₃], [-I₃, 0]] (位置在前、动量在后)。

class e2m2e.algorithm.normal_form.quasi_floquet.QuasiFloquetReducer(context, method='matrix', project=True, rtol=1e-11, atol=1e-13, segment=None)[源代码]

基类:object

quasi-Floquet 变换 reducer(上下文绑定)。

通过 reduce() 从一条 DynamicalSubstituteResult 提取 时变线性化 M(t)、求解 = M·B B·D,并施加辛约束, 输出可插值的 QuasiFloquetResult

参数:
  • context (NormalFormContext) -- 归一化上下文(提供频率 ω_p/ω_v、特征指数 λ)。

  • method (str) -- "matrix" (默认,36 维直接积分 + 辛投影)或 "lie_algebra" (21 维 sp(6) 参数化,自动保辛)。

  • project (bool) -- 矩阵法是否在末尾做辛投影兜底(默认 True)。

  • rtol (float) -- ODE 相对容差。

  • atol (float) -- ODE 绝对容差。

  • segment (float | None) -- 矩阵法分段辛重投影的段长(TU)。None (默认)单次积分, 适合 λT < 10 的小窗口;非 None 时分短段 + 每段辛投影, 抑制双曲方向 e^(λt) 增长导致的 overflow(详见 _solve_qf_matrix())。

context: NormalFormContext
method: str = 'matrix'
project: bool = True
rtol: float = 1e-11
atol: float = 1e-13
segment: float | None = None
reduce(ds_result)[源代码]

ds_result 执行 quasi-Floquet 变换。

参数:

ds_result (DynamicalSubstituteResult) -- 切片 #171 的动力学替代结果,至少提供 tlistXlistcontext

返回:

QuasiFloquetResult

抛出:

ValueError -- method 非法,或 ds_result 数据不足。

返回类型:

QuasiFloquetResult

class e2m2e.algorithm.normal_form.quasi_floquet.QuasiFloquetResult(context, order, tlist, B_samples, D, method, M_samples=None, metadata=<factory>)[源代码]

基类:object

quasi-Floquet 变换结果句柄。

变量:
  • context (NormalFormContext) -- 关联 NormalFormContext

  • order (int) -- 展开阶数(与 context.order 一致)。

  • tlist (npt.NDArray[np.floating]) -- 采样时间数组 (n,),归一化 TU。

  • B_samples (npt.NDArray[np.floating]) -- B(t) 在采样点的堆叠,形状 (n, 6, 6)

  • D (npt.NDArray[np.floating]) -- 6×6 实标准形矩阵。

  • method (str) -- 实际使用的求解方法("matrix""lie_algebra")。

  • M_samples (npt.NDArray[np.floating] | None) -- 时变线性化矩阵 M(t) 在采样点的堆叠,形状 (n, 6, 6);诊断用,None 表示未保留。

  • metadata (dict[str, object]) -- 自由扩展字段。

参数:
  • context (NormalFormContext)

  • order (int)

  • tlist (npt.NDArray[np.floating])

  • B_samples (npt.NDArray[np.floating])

  • D (npt.NDArray[np.floating])

  • method (str)

  • M_samples (npt.NDArray[np.floating] | None)

  • metadata (dict[str, object])

context: NormalFormContext
order: int
tlist: npt.NDArray[np.floating]
B_samples: npt.NDArray[np.floating]
D: npt.NDArray[np.floating]
method: str
M_samples: npt.NDArray[np.floating] | None = None
metadata: dict[str, object]
property max_symplectic_error: float

所有采样点上 ‖BᵀJB J‖∞ 的最大值。

B(t)[源代码]

在时刻 t 处线性插值 B(t)

参数:

t (float) -- 归一化时间 TU。允许 tlist 之外的端点外推。

返回:

(6, 6) 插值矩阵。

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.normal_form.quasi_floquet.build_sp6_basis()[源代码]

构造 sp(6, R) 的 21 维正交基 {E_k} (Frobenius 归一)。

三块结构:An²=9E_ij = e_i e_jᵀ e_{n+j} e_{n+i}ᵀ)、 Bn(n+1)/2=6 (右上对称)、Cn(n+1)/2=6 (左下对称)。对应 qiao _build_sp6_basis

返回类型:

list[ndarray[tuple[Any, ...], dtype[floating]]]

e2m2e.algorithm.normal_form.quasi_floquet.real_normal_form_matrix(lam, wp, wv)[源代码]

构造 6×6 实标准形矩阵 D

对应 qiao Global_File 中固化的 Mat_D:一双曲方向 ±λ、 平面内中心方向 ±i ω_p、垂直中心方向 ±i ω_v。基底顺序与 qiao 一致:[p₁, q₁, q₂, p₂, ...]——指数 0 双曲、指数 1/4 平面 中心对、指数 2/5 垂直中心对。

参数:
  • lam (float) -- 双曲特征指数 λ(>0)。

  • wp (float) -- 平面内中心频率 ω_p(>0)。

  • wv (float) -- 垂直中心频率 ω_v(>0)。

返回:

(6, 6) 实标准形矩阵 D

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.normal_form.quasi_floquet.sp6_to_vector(mat, basis)[源代码]

sp(6) 矩阵 → 21 维系数向量(Frobenius 内积投影)。

参数:
返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.normal_form.quasi_floquet.symplectic_project(B, *, tol=1e-14, max_iter=50)[源代码]

B 投影到最近的辛矩阵(Newton 迭代,qiao 风格)。

迭代 B B ½ B (Jᵀ S),其中 S = BᵀJB J

参数:
返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.normal_form.quasi_floquet.vector_to_sp6(xi, basis)[源代码]

21 维系数向量 → sp(6) 矩阵 M = Σ ξ_k E_k

参数:
返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.normal_form.center_manifold module

高阶中心流形化简(qiao Code10–Code11)。

在 quasi-Floquet 坐标(切片 #172)基础上,用逐阶 Lie 变换消去 Hamiltonian 的双曲-中心耦合项,把非线性 Hamiltonian 化简为仅依赖 作用量的函数:

  • Step 1 ``"invariant"`` (qiao Code10_DepartInvarManifold): 消去 q_1^k·p_1^lk l)的双曲交叉项,判别条件 pow(1)==pow(4) 保留双曲"循环坐标" I_1 = q_1·p_1。经此步后 双曲方向与中心方向解耦,中心部分可独立分析;

  • Step 2 ``"center"`` (qiao Code11_DepartCenterManifold): 在 Step 1 结果上,消去两个中心方向 (q_2,p_2)/(q_3,p_3) 之间 的非共振耦合,更严判别条件 pow(1)==pow(4) && pow(2)==pow(5) && pow(3)==pow(6),结果只剩 作用量 I_1 = q_1·p_1I_2 = (q_2²+p_2²)/2I_3 = (q_3²+p_3²)/2

算法(两步结构相同):

  1. 逐阶(3..max_order)解同调方程 {H_2, W_i} = -H_i^{待消}}W_i 由频域 ODE 求解器 _solve_wfunc_fft() / _solve_wfunc_fft_imag() 给出特解 = k·y + f(t); 特征频率 k = (j_1−i_1)·λ + (j_2−i_2)·i·ω_p + (j_3−i_3)·i·ω_v

  2. W_i 对各高阶 Hamiltonian 的贡献由 Poisson 括号链 ad_{W_i}^n / n! (Lie 级数)累加,再加上 Ẇ_i 项更新各阶;

  3. i 阶按判别条件删去被 W_i 消去的项。

与 qiao 数值实现一致,每个化简步骤前后做复基底变换( _linear_basis_change()):先虚变换 X = D·Y (实坐标 → 复坐标, 二阶部分成复对角形 λ·y1·y4 + i·ω_p·y2·y5 + i·ω_v·y3·y6,同调方程 的复值特征频率 k 只有在此坐标系下才与 H_2 的泊松谱匹配), Lie 变换完成后实变换 Y = D⁻¹·X 映回实坐标并取实部(吸收数值虚部 噪声)。生成函数 W 保持复坐标——coord_trans.qf_cm 的 QF↔CM Lie 流在复域消费它(先 Re2Im 再应用 WIm2Re)。

单位约定:内部 Hamiltonian 系数全部在 qiao 归一化单位(TU)下运算; 与 SI 之间换算只能经 NormalFormContextunitssympy 仅在 Legendre/Hamiltonian 构造时惰性导入;本模块不依赖 sympy。joblib 为可选优化(qiao 用其并行 Poisson 括号),本模块 串行实现并显式注明。

Public API:

输入 QuasiFloquetResult 只提供二阶实标准形 D (频率 λω_pω_v);高阶非线性 Hamiltonian 项需经 hamiltonian_terms 参数注入(对应 qiao Code09L?_QF_Hamilton.npz{pow_tuple: coef_array},系数为时间序列 ndarray)。若不注入,reducer 退化为只含二阶项的平凡情形 (仍能跑通,但无高阶项可消,仅供 smoke)。

e2m2e.algorithm.normal_form.center_manifold.DEFAULT_MAX_ORDER: int = 10

默认展开阶数(与 qiao Code10/Code11 一致)。

class e2m2e.algorithm.normal_form.center_manifold.CenterManifoldReducer(context, max_order=10, backend='rust')[源代码]

基类:object

中心流形化简 reducer(上下文绑定)。

通过 reduce() 在 quasi-Floquet 化简后的 Hamiltonian 上执行 一步或两步 Lie 变换,消去双曲-中心耦合与中心方向间非共振耦合, 输出 CenterManifoldResult

默认 backend="rust" 走完整 Rust 数值内核(#466); backend="python" 仅作显式等价性对照,绝不自动回退(ADR 0020)。

参数:
  • context (NormalFormContext) -- 归一化上下文(提供频率 ω_p/ω_v、特征指数 λ)。

  • max_order (int) -- Lie 变换截断阶数,默认 10 (与 qiao 一致)。

  • backend (Literal['rust', 'python']) -- 数值后端,"rust"``(默认)或 ``"python"

context: NormalFormContext
max_order: int = 10
backend: Literal['rust', 'python'] = 'rust'
reduce(qf_result, hamiltonian_terms=None, steps=None)[源代码]

qf_result 执行中心流形化简。

参数:
  • qf_result (QuasiFloquetResult) -- quasi-Floquet 变换结果(切片 #172),提供实标准形 D (频率 λ/ω_p/ω_v)与采样时间 tlist

  • hamiltonian_terms (Mapping[tuple[int, ...], ArrayLike] | None) -- 高阶 Hamiltonian 系数表 {pow_tuple: coef_array} (对应 qiao Code09L?_QF_Hamilton.npz)。None 时 reducer 只用二阶实 标准形项(平凡情形,仅供 smoke)。系数为时间序列 ndarray,长度应与 qf_result.tlist 一致。

  • steps (tuple[str, ...] | None) -- 要执行的步骤元组,按顺序;默认 ("invariant", "center")。可选单步 ("invariant",)("center",)

返回:

CenterManifoldResult

抛出:

ValueError -- steps 含非法名;max_order 非正; hamiltonian_terms 系数长度与 tlist 不一致; backend 非法。

返回类型:

CenterManifoldResult

class e2m2e.algorithm.normal_form.center_manifold.CenterManifoldResult(context, order, W_series, hamiltonian_terms, steps_performed, metadata=<factory>)[源代码]

基类:object

中心流形化简结果句柄。

变量:
  • context (NormalFormContext) -- 关联 NormalFormContext

  • order (int) -- 化简截断阶数(max_order)。

  • W_series (dict[str, dict[int, dict[tuple[int, ...], npt.NDArray[np.complex128]]]]) -- 各步、各阶生成函数 W 的系数表。结构 {step_name: {order: {pow_tuple: coef_array}}},封装访问; step_name {"invariant", "center"}。系数为**复值** 时间 序列 ndarrayinvariant 步 W 天然实值、虚部≈0; center 步 W 为纯虚、实部≈0)——与 qiao Code10/Code11 输出的复值 .npz 一致,供 coord_trans 的 QF↔CM Lie 流在复域消费。不直接暴露 qiao 的 powers/coefficients 扁平数组命名。

  • hamiltonian_terms (dict[tuple[int, ...], npt.NDArray[np.floating]]) -- 化简后 Hamiltonian 的 {pow_tuple: coef_array} 系数表(实 QF 坐标)。

  • steps_performed (tuple[str, ...]) -- 实际执行的化简步骤名元组(按顺序)。

  • metadata (dict[str, object]) -- 自由扩展字段(频率、项数等诊断信息)。

参数:
context: NormalFormContext
order: int
W_series: dict[str, dict[int, dict[tuple[int, ...], npt.NDArray[np.complex128]]]]
hamiltonian_terms: dict[tuple[int, ...], npt.NDArray[np.floating]]
steps_performed: tuple[str, ...]
metadata: dict[str, object]
property max_hyperbolic_coupling: float

化简后剩余双曲-中心**耦合** 项系数的最大绝对值。

耦合指双曲方向不平衡(pow[0] != pow[3])且涉及中心方向的 项——Step 1(invariant)的消去对象。双曲平衡的作用量项 (如 I₁³·I₂²)在中心流形上(q₁=p₁=0)自动为零,不是 耦合,不统计。本属性是步骤 "invariant" 化简效果的核心 诊断量:值越小,化简越彻底。

返回:

max_{k∈terms} |coef_k|,其中 k 遍历双曲不平衡且 含中心方向的项;无此类项时返回 0.0

W_for(step, order)[源代码]

封装访问器:取出某步某阶的 W 系数表。

参数:
  • step (str) -- 步骤名("invariant" / "center")。

  • order (int) -- 阶数。

返回:

{pow_tuple: coef_array};该步/阶未执行或无项时返回 {}

抛出:

KeyError -- step 未执行。

返回类型:

dict[tuple[int, ...], ndarray[tuple[Any, ...], dtype[complex128]]]

e2m2e.algorithm.normal_form.center_manifold.list_deriv(y, h, n=14, swi=4, ord_boundary=10)[源代码]

等距采样高阶数值微分。

迁移自 qiao list_deriv:内部 n 阶中心差分,两端用 swi 点前/后向差分(阶 ord_boundary),过渡区用递降阶中心 差分。复值 y 自动转实/虚部分别处理。

参数:
  • y (ArrayLike) -- (N,) 等距采样数据(实或复)。

  • h (float) -- 采样间距。

  • n (int) -- 中心差分阶(偶数)。

  • swi (int) -- 端点前/后向差分点数。

  • ord_boundary (int) -- 端点差分阶。

返回:

(N,) 导数 dy/dt

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.normal_form.propagation module

M0 流积分器:在中心流形上传播表征参数。

移植 qiao propagation.pypropagate_parametric,用降幂写法计算 Hamilton 正则方程右端项(避免 qiao 原版的除法 0/0)。

表征参数链(M0 流):

rho 初值 → param(经 catalog_transformer)→ Hamilton 正则方程积分 (钳制双曲方向 q1/p1=0,留 4 维中心流形)→ param → rho

中心流形约化后,Hamilton 量 H 不含双曲-中心耦合;在中心流形上(q1=p1=0) 积分 H 的正则方程即得 Lissajous 轨道。双曲方向被钳制,保证不发散。

参考: - qiao propagate_parametric / _eval_hamiltonian_rhs - Gómez vol III 2.7:约化 H⁰ 在 (ξ, η) 中心坐标上的流 - run_nrho_normal_form.py 的约定注释(CM 坐标、降幂写法、双曲钳制)

e2m2e.algorithm.normal_form.propagation.propagate_parametric(rho_state, t_span, nf_result, context, *, truth_rho=None)[源代码]

表征参数链外推(M0 流:Hamilton 正则方程,DOP853 积分器)。

在中心流形上积分 Hamilton 正则方程(钳制双曲方向 q1/p1=0),逐时刻 转回 rho。这是约化 Hamilton H⁰ 的流——Lissajous 轨道。

坐标约定:积分在 CM 笛卡尔坐标 [q1,q2,q3,p1,p2,p3] 上进行 (_eval_hamiltonian_rhs() 的正则方程),输入输出端经 param_to_cm/cm_to_param 与表征参数 (q1,p1,I2,θ2,I3,θ3) 互转。不要直接把 param 当笛卡尔积分——作用量-角变量不是正则坐标。

参数:
  • rho_state (npt.ArrayLike) -- (6,) 初始 rho 状态(无量纲)。

  • t_span (npt.ArrayLike) -- (K,) 时间序列(无量纲 TU),单调递增。

  • nf_result (NormalFormResult) -- 标准形结果(提供 catalog_transformer 与 hamiltonian_terms)。

  • context (NormalFormContext) -- 标准形上下文。

  • truth_rho (npt.ArrayLike | None) -- 可选真值 rho 轨迹 (K, 6),与 t_span 同网格。

返回:

(t_out, rho_out, pos_err_km) 元组。 - t_out: (M,) 输出时间(TU)。 - rho_out: (M, 6) rho 状态。 - pos_err_km: (M,) 位置误差(km),无真值时为 None

返回类型:

tuple[npt.NDArray, npt.NDArray, npt.NDArray | None]

e2m2e.algorithm.normal_form.qf_projection module

H→QF 映射:把 Hamiltonian 投影到 quasi-Floquet 坐标。

对应 qiao Code09_Kamilton_QF.m。把平动点偏移坐标 (q1..p3) 下的 Hamiltonian 高阶项(阶 ≥ 3),经 quasi-Floquet 变换矩阵 B(t) 做线性 替换 X = B·Y,重排为 QF 坐标 Y 的多项式,逐时刻代入 B(t) 数值 得到时间序列系数。

二阶项不投影——CenterManifoldReducer_assemble_hamiltonian 自加实标准形二阶项(λ q₁p₁ + ω/2(q²+p²));本函数只提供 ≥3 阶非线性 项,供 Lie 变换消去双曲-中心耦合。

两条实现路径:

  1. Rust 数值展开 (默认):e2m2e._integrators.project_hamiltonian_qf_py 对每个采样时刻做 X = B·Y 的数值多项式展开(multinomial 组合枚举), 不依赖符号运算。CR3BP 标量系数路径下毫秒级完成。

  2. sympy 符号展开 (回退):扩展未编译、或系数为时间序列(星历路径) 时回退到 _project_hamiltonian_to_qf_sympy() (原实现,符号替换 x_i Σ_j B[i,j]·y_j + 逐时刻求值,较慢)。

e2m2e.algorithm.normal_form.qf_projection.project_hamiltonian_to_qf(hamiltonian_terms, qf_result)[源代码]

把 Hamiltonian 高阶项投影到 QF 坐标。

参数:
  • hamiltonian_terms (dict[tuple[int, ...], float]) -- 平动点偏移坐标 (q1..p3) 下的 Hamiltonian 系数 dict {pow_tuple: float} (如 build_cr3bp_hamiltonian() 输出)。阶 < 3 的项被丢弃。 系数为标量(CR3BP 自治)或 ndarray 时间序列。

  • qf_result (QuasiFloquetResult) -- quasi-Floquet 结果,提供 B(t)tlist

返回:

{pow_tuple: coef_array}coef_array 长度与 qf_result.tlist 一致。变量为 QF 坐标(命名为 q1..p3)。

返回类型:

dict[tuple[int, ...], npt.NDArray[np.floating]]

e2m2e.algorithm.normal_form.pipeline module

标准形化简一键式流水线(issue #175)。

把前面四个切片的 reducer 串成一条完整路径:

星历轨道初值
    │  DynamicalSubstituteCorrector  (切片 #171)
    ▼
动力学替代轨道 + 生成函数 W
    │  QuasiFloquetReducer           (切片 #172)
    ▼
quasi-Floquet 变换 B(t) + 实标准形 D
    │  CenterManifoldReducer         (切片 #173)
    ▼
中心流形化简 W_series
    │  LibrationCatalogTransformer   (切片 #174)
    ▼
表征参数目录变换器(rho ↔ param)

外部用户一行代码即可完成"星历轨道 → 表征参数":

result = NormalFormPipeline(context).reduce(x0)
param = result.catalog_transformer.rho_to_param(x0, t=0.0)

返回的 NormalFormResult 既是通用化简诊断容器(Hamiltonian 系数、 残差、收敛标志),也把四个子结果句柄作为一等公民字段暴露,使下游无需自行 重组装 LibrationCatalogData 即可做坐标变换。

class e2m2e.algorithm.normal_form.pipeline.NormalFormPipeline(context, quasi_floquet_method='matrix', center_max_order=10, center_steps=('invariant', 'center'), dynamical_kwargs=<factory>, qf_segment=None)[源代码]

基类:object

标准形化简一键式流水线(上下文绑定)。

通过 reduce() 把一条 (6,) rho 坐标初值依次送进动力学替代 corrector、quasi-Floquet reducer、中心流形 reducer,最后绑定成表征 参数目录变换器,返回聚合的 NormalFormResult

只暴露用户真正需要的旋钮(quasi-Floquet 求解法、中心流形截断阶与步 序列);动力学替代的打靶窗口/容差沿用 DynamicalSubstituteCorrector 的默认值(与 qiao Code05 一致),需要覆盖时传 dynamical_kwargs

参数:
  • context (NormalFormContext) -- 归一化上下文(提供平动点、频率、历元等)。

  • quasi_floquet_method (str) -- quasi-Floquet 求解法,"matrix" (默认, 36 维直接积分 + 辛投影)或 "lie_algebra" (21 维 sp(6) 参数化,自动保辛)。

  • center_max_order (int) -- 中心流形 Lie 变换截断阶数,默认 10 (与 qiao Code10/Code11 一致)。

  • center_steps (tuple[str, ...]) -- 中心流形化简步骤元组,默认 ("invariant", "center")

  • dynamical_kwargs (dict[str, object]) -- 透传给 DynamicalSubstituteCorrector 的 覆盖项(如 {"t_total": 8.0, "node_step": 0.8})。None 时用该 corrector 的全部默认值。

  • qf_segment (float | None) -- quasi-Floquet 矩阵法分段辛重投影的段长(TU)。None 单次积分(小窗口);0.4 等短段值用于长窗口抑制双曲 overflow。

context: NormalFormContext
quasi_floquet_method: str = 'matrix'
center_max_order: int = 10
center_steps: tuple[str, ...] = ('invariant', 'center')
dynamical_kwargs: dict[str, object]
qf_segment: float | None = None
reduce(orbit)[源代码]

对 rho 坐标初值跑完整标准形化简流水线。

参数:

orbit (ArrayLike) -- (6,) rho 坐标初始状态 [ρ, ρ̇] (无量纲),作为 动力学替代 corrector 的种子。SPICE 内核不可用时底层自动 降级到纯 CR3BP(仅供烟雾测试)。

返回:

NormalFormResult:聚合了四个子结果句柄与通用化简诊断 字段。catalog_transformer 字段在四步全部成功后非 None

返回类型:

NormalFormResult

备注

任一步抛异常时,流水线不向上传播,而是把已完成的子结果填进 NormalFormResult,置 success=Falsemessage 记录失败步骤与原因——这样部分失败也保留诊断价值。输入校验 (如 orbit 形状非法)仍直接抛 ValueError,因为这是 调用方错误而非流水线内部失败。

e2m2e.algorithm.normal_form.coord_trans package

函数式坐标变换链:rho EM DS QF CM param

本子包把 qiao rho2param / param2rho 的完整变换链拆成 5 段函数式 接口(对应 qiao Subfunction/coord_trans/ 各子模块),并在本 __init__ 里组合成端到端的 rho_to_param / param_to_rho

变换链(全部无量纲,qiao 归一化单位):

rho → EM → DS → QF → CM → param

  • rho ↔ EM (rho_em):纯动量耦合 p = ρ̇ Cdot_dimᵀ·C·ρ

  • EM ↔ DS (em_ds):平移 W(t) = [A, B] (动力学替代);

  • DS ↔ QF (ds_qf):矩阵变换 X_QF = B(t)⁻¹·X_DS

  • QF ↔ CM (qf_cm):高阶 Lie 级数(生成函数 W_series);

  • CM ↔ param (cm_param):复→极坐标(作用量-角变量)。

端到端链式函数 rho_to_param() / param_to_rho() 依赖三个预计算 结果句柄(切片 #171–#173 交付):

调用方负责把这三个结果聚合(LibrationCatalogData 是开箱即用的聚合器);本模块只做纯函数,不在内部缓存。

e2m2e.algorithm.normal_form.coord_trans.rho_em module

rho ↔ EM:平动点相对坐标 ↔ 星历模型 Hamilton 坐标 (q, p)。

迁移自 qiao Subfunction/coord_trans/rho2qpEM.py / qpEM2rho.py。本模块对应变换链的第一段:rho(无量纲平动点相对 坐标 [ρ, ρ̇])与星历模型 Hamilton 坐标 (q, p) 之间的**纯动量 耦合**层。

数学关系(qiao CONTEXT.md §二):

q = ρ p = ρ̇ − Cdot_dimᵀ · C · ρ

其中 C 是 EMR 旋转矩阵(月球瞬时姿态),Cdot_dim = Cdot · TU 是其无量纲时间导数。该耦合把会合系下的速度 ρ̇ 投影到非惯性 Hamilton 系的共轭动量 p不做物理量换算——qp 仍在 无量纲 rho 单位下。

与 qiao 的差异:

  • qiao 的 rho2qpEM / qpEM2rho 同时做单位换算(输出 km/km/s)并 平移平动点位置;本仓库按 PRD 约定**全程无量纲**,单位换算交给 e2m2e.algorithm.normal_form.units 的调用方;平动点平移在 DS 段(em_ds)由生成函数 W 完成。

  • CCdot 不通过 qiao 的 globalparam.data_array 二进制表 暴露,而由 NormalFormContext + _ephemeris 在请求时刻 重新解析求值(SPICE 不可用时退化到纯 CR3BP 常值旋转)。

退化(纯 CR3BP):C 取会合系单位旋转 [[0,1,0],[-1,0,0],[0,0,0]]Cdot = 0 (无量纲时间下为常数)。此时动量耦合项消失, p = ρ̇——这正是切片 0–4 测试一直使用的纯 CR3BP 退路,往返误差 应在机器精度内。

e2m2e.algorithm.normal_form.coord_trans.rho_em.em_to_rho(X_em, t, context)[源代码]

EM 坐标 (q, p) → rho 状态(无量纲)。

对应 qiao param2rho 末段(逆动量耦合):ρ = qρ̇ = p + Cdot_dimᵀ · C · q。是 rho_to_em() 的精确逆。

参数:
  • X_em (npt.ArrayLike) -- (6,) EM 状态 [q, p],无量纲。

  • t (float) -- 归一化时间 TU。

  • context (NormalFormContext) -- 归一化上下文。

返回:

(6,) rho 状态 [ρ, ρ̇],无量纲。

返回类型:

npt.NDArray[np.floating]

e2m2e.algorithm.normal_form.coord_trans.rho_em.rho_to_em(X_rho, t, context)[源代码]

rho 状态 → EM 坐标 (q, p) (无量纲)。

对应 qiao rho2param 第一段:q = ρp = ρ̇ Cdot_dimᵀ · C · ρ

参数:
  • X_rho (npt.ArrayLike) -- (6,) rho 状态 [ρ_x, ρ_y, ρ_z, ρ̇_x, ρ̇_y, ρ̇_z], 无量纲。

  • t (float) -- 归一化时间 TU。

  • context (NormalFormContext) -- 归一化上下文。

返回:

(6,) EM 状态 [q_x, q_y, q_z, p_x, p_y, p_z],无量纲。

返回类型:

npt.NDArray[np.floating]

e2m2e.algorithm.normal_form.coord_trans.em_ds module

EM ↔ DS:星历模型 Hamilton 坐标 ↔ 动力学替代坐标。

迁移自 qiao Subfunction/coord_trans/qpDS2qpEM.py / qpEM2qpDS.py。对应变换链第二段:EM 坐标 (q, p) 与动力学 替代坐标 (Q, P) 之间的**平移** 关系。

数学关系(qiao CONTEXT.md §三"动态替换"):

DS = W(t) (生成函数,6 维 [A, B] 时间序列) A = DS[:3] B = DS[3:] q = Q + B (正向 EM = DS + W 平移) p = P − A Q = q − B (反向 DS = EM − W 平移) P = p + A

即 DS 是 EM 减去替代轨道的平移 W(t) = [A(t), B(t)]——把坐标原点从 平动点挪到动力学替代轨道上。本段是纯仿射变换,无量纲、无单位换算。

与 qiao 的差异:

  • qiao 通过 list_interp 在全局 data_array 上 Catmull-Rom 插值 W_poly;本仓库的 DynamicalSubstituteResult 已在每个采样点上 存好 W_poly{pow_tuple: coef_array},6 个线性项),这里只做 线性插值 到时刻 t 即可(与 QuasiFloquetResult.B_at 的 策略一致)。Catmull-Rom 在等距光滑数据上与线性插值差别极小,且 本仓库不引入 qiao 的二进制系数表。

e2m2e.algorithm.normal_form.coord_trans.em_ds.ds_to_em(X_ds, W_poly_at_t)[源代码]

动力学替代坐标 → EM 坐标(平移)。

q = Q + Bp = P A,其中 [A, B] = W(t)。对应 qiao qpDS2qpEM。是 em_to_ds() 的精确逆。

参数:
  • X_ds (ArrayLike) -- (6,) DS 状态 [Q, P],无量纲。

  • W_poly_at_t (ArrayLike) -- (6,) 在时刻 t 插值后的 W(t) = [A, B]

返回:

(6,) EM 状态 [q, p],无量纲。

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.normal_form.coord_trans.em_ds.em_to_ds(X_em, W_poly_at_t)[源代码]

EM 坐标 → 动力学替代坐标(平移)。

Q = q BP = p + A,其中 [A, B] = W(t)。对应 qiao qpEM2qpDS

参数:
  • X_em (ArrayLike) -- (6,) EM 状态 [q, p],无量纲。

  • W_poly_at_t (ArrayLike) -- (6,) 在时刻 t 插值后的 W(t) = [A, B]

返回:

(6,) DS 状态 [Q, P],无量纲。

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.normal_form.coord_trans.ds_qf module

DS ↔ QF:动力学替代坐标 ↔ quasi-Floquet 坐标。

迁移自 qiao Subfunction/coord_trans/qpDS2qpQF.py / qpQF2qpDS.py。对应变换链第三段:DS 坐标与 quasi-Floquet 坐标 之间的**矩阵变换**。

数学关系(qiao CONTEXT.md §三"quasi-Floquet 变换"):

X_QF = B(t)⁻¹ · X_DS (正向 DS → QF) X_DS = B(t) · X_QF (反向 QF → DS)

其中 B(t) 是切片 #172 求解的 quasi-Floquet 变换矩阵(6×6 辛矩阵), 把受迫时变线性化系统化为常系数的 = D·Y。本段是纯线性变换, 无量纲、无单位换算。

与 qiao 的差异:

  • qiao 通过 get_QFmat(t, QFtrans_mat)globalparam.data_array 上插值 B(t);本仓库的 QuasiFloquetResult.B_at 已提供线性 插值访问器,本模块直接接收插值后的 B_at_t,把"何时插值"的决策 上浮到 LibrationCatalogTransformer (与 EM/CM 段保持一致)。

e2m2e.algorithm.normal_form.coord_trans.ds_qf.ds_to_qf(X_ds, B_at_t)[源代码]

动力学替代坐标 → quasi-Floquet 坐标(矩阵变换)。

X_QF = B⁻¹ · X_DS。对应 qiao qpDS2qpQF

参数:
  • X_ds (ArrayLike) -- (6,) DS 状态 [Q, P],无量纲。

  • B_at_t (ArrayLike) -- (6, 6) 在时刻 t 插值后的 quasi-Floquet 矩阵 B(t) (辛)。

返回:

(6,) QF 状态 [Q_qf, P_qf],无量纲。

抛出:

numpy.linalg.LinAlgError -- B(t) 奇异。

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.normal_form.coord_trans.ds_qf.qf_to_ds(X_qf, B_at_t)[源代码]

quasi-Floquet 坐标 → 动力学替代坐标(矩阵变换)。

X_DS = B · X_QF。对应 qiao qpQF2qpDS。是 ds_to_qf() 的精确逆。

参数:
  • X_qf (ArrayLike) -- (6,) QF 状态 [Q_qf, P_qf],无量纲。

  • B_at_t (ArrayLike) -- (6, 6) 在时刻 t 插值后的 quasi-Floquet 矩阵 B(t) (辛)。

返回:

(6,) DS 状态 [Q, P],无量纲。

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.normal_form.coord_trans.qf_cm module

QF ↔ CM:quasi-Floquet 坐标 ↔ 中心流形坐标(高阶 Lie 级数)。

迁移自 qiao Subfunction/coord_trans/qpQF2qpCM.py / qpCM2qpQF.py——变换链中最复杂的一段。对应切片 #173 中心流形化简 (Code10/Code11)的**坐标层面** 应用:把 quasi-Floquet 坐标通过生成函数 W 的高阶 Lie 级数映射到中心流形坐标。

算法(qiao CONTEXT.md §三"化简到中心流形"):

  1. 实→复基底变换 Re2Im:用对角化矩阵 D⁻¹ 把实 QF 坐标 (q, p) 映到复坐标。D 把双曲/中心方向拆成纯实/复分量: 双曲方向 (q1, p1) 不变,平面/垂直中心方向 (q2, p2)/(q3, p3) 各组合成 ±i 模式(√2 归一)。

  2. 逐阶 Lie 流:对每个阶 order 2 (qiao W_series{3..N}), 用生成函数 W_order(q,p) 的 Hamilton 流 dX/dt = J·∇W_ordert=0 积到 t=1 (一步近恒等变换)。 正向(QF→CM)取 W 系数取反;反向(CM→QF)不取反、阶序倒序。

  3. 复→实基底变换 Im2Re:用 D 映回实坐标,取实部。

Hamilton 流的右端 dX/dt = J·∇W 用向量化实现 (_hamilton_flow_rhs()),与 qiao _dynfunc_wtrans_vec 逐位一致; 0^0=1 边界用降幂写法(qp^(n-1))天然正确,避免除法写法的 0/0=nan

与 qiao 的差异:

  • qiao 在 globalparam.data_array 上对每个 W_series 系数做 Catmull-Rom 插值(preinterp_coeffs 路径);本仓库的 CenterManifoldResult.W_series 已按 {step: {order: {pow: coef_array}}} 组织,本模块接收**已插值为标量** 的系数表 W_series_at_t{order: {pow: complex_scalar}}),把插值决策上浮 到 LibrationCatalogTransformer

  • qiao 依赖 globalparam.odeoptionsscipy.solve_ivp 选项);本模块 显式传 DOP853 默认容差(rtol=1e-11atol=1e-13),不引入 全局可变状态。

默认后端为 Rust(issue #465):复值 Lie 流用 12 实维分裂 ([Re X, Im X])走 e2m2e-integrators 的 DOP853,与 scipy 对复 y0 的内部分裂数学等价。backend="python" 仅作显式对照,禁止 auto 静默降级(ADR 0020)。

e2m2e.algorithm.normal_form.coord_trans.qf_cm.cm_to_qf(X_cm, W_series_at_t, *, backend='rust', rtol=1e-11, atol=1e-13)[源代码]

中心流形坐标 → quasi-Floquet 坐标(高阶 Lie 级数,反向)。

对应 qiao qpCM2qpQF:实→复基底 → 逐阶 Lie 流(W 不取反、 降序)→ 复→实基底。是 qf_to_cm() 的精确逆。

参数:
  • X_cm (ArrayLike) -- (6,) CM 状态 [Q_cm, P_cm],无量纲实数。

  • W_series_at_t (dict[int, dict[tuple[int, ...], complex]]) -- 同 qf_to_cm()

  • backend (Literal['rust', 'python']) -- "rust"``(默认)或显式对照 ``"python"。禁止 auto。

  • rtol (float) -- ODE 容差。

  • atol (float) -- ODE 容差。

返回:

(6,) QF 状态 [Q_qf, P_qf],无量纲实数。

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.normal_form.coord_trans.qf_cm.qf_to_cm(X_qf, W_series_at_t, *, backend='rust', rtol=1e-11, atol=1e-13)[源代码]

quasi-Floquet 坐标 → 中心流形坐标(高阶 Lie 级数)。

对应 qiao qpQF2qpCM:实→复基底 → 逐阶 Lie 流(W 取反、升序) → 复→实基底。

参数:
  • X_qf (ArrayLike) -- (6,) QF 状态 [Q_qf, P_qf],无量纲实数。

  • W_series_at_t (dict[int, dict[tuple[int, ...], complex]]) -- {order: {pow_tuple: complex_scalar}}——在时刻 t 插值后的 CenterManifoldResult.W_series (复值 系数,跨 invariant/center 两步合并)。

  • backend (Literal['rust', 'python']) -- "rust"``(默认)或显式对照 ``"python"。禁止 auto。

  • rtol (float) -- ODE 容差(与历史 Python 默认一致)。

  • atol (float) -- ODE 容差(与历史 Python 默认一致)。

返回:

(6,) CM 状态 [Q_cm, P_cm],无量纲实数。

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.normal_form.coord_trans.cm_param module

CM ↔ param:中心流形坐标 ↔ 表征参数(复→极坐标,作用量-角变量)。

迁移自 qiao Subfunction/coord_trans/param2ActionAngle.py (仅 方向:CM → 作用量-角变量)+ 本仓库补齐的逆变换。对应变换链的最后一段: 把中心流形坐标 (q1, q2, q3, p1, p2, p3) 转成表征参数 (q1, p1, I2, θ2, I3, θ3)

数学关系:

  • 双曲方向 (q1, p1) 保持原状——双曲方向不是循环坐标,无作用量- 角变量表示,表征参数里直接用 (q1, p1) 携带;

  • 平面中心方向 (q2, p2)I2 = (q2² + p2²)/2θ2 = atan2(p2, q2)

  • 垂直中心方向 (q3, p3)I3 = (q3² + p3²)/2θ3 = atan2(p3, q3)

逆变换用 q = √(2I)·cos θp = √(2I)·sin θ 还原中心对。

约定说明:

  • qiao param2ActionAngleatan2(q2, p2) (参数交换),本仓库 按 PRD 显式约定 atan2(p2, q2)——二者互为 π/2 θ 的镜像,但 只要往返变换内部自洽(θ2 算出来再用同公式反解),往返误差仍为 机器精度。本模块在 docstring/常量上显式标注约定,避免与 qiao 混淆。

  • 角变量 θ 不做 % 折回:表征参数保留原始连续角,往返时 atan2 的主值分支自动与 cos/sin 配对,无需手动折回。若调用方 需要折回,可对返回值自行 % (2π)

e2m2e.algorithm.normal_form.coord_trans.cm_param.cm_to_param(X_cm)[源代码]

中心流形坐标 → 表征参数 (复→极坐标)。

X_cm = [q1, q2, q3, p1, p2, p3]X_param = [q1, p1, I2, θ2, I3, θ3]

参数:

X_cm (ArrayLike) -- (6,) CM 状态 [q1, q2, q3, p1, p2, p3],无量纲实数。

返回:

(6,) 表征参数 [q1, p1, I2, θ2, I3, θ3],无量纲。

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.normal_form.coord_trans.cm_param.param_to_cm(X_param)[源代码]

表征参数 → 中心流形坐标 (极→复坐标)。

X_param = [q1, p1, I2, θ2, I3, θ3]X_cm = [q1, q2, q3, p1, p2, p3]。是 cm_to_param() 的精确逆。

中心对还原:q = √(2I)·cos θp = √(2I)·sin θ

参数:

X_param (ArrayLike) -- (6,) 表征参数 [q1, p1, I2, θ2, I3, θ3],无量纲。

返回:

(6,) CM 状态 [q1, q2, q3, p1, p2, p3],无量纲。

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.manifold package

不变流形与庞加莱截面。

流形种子生成与批量传播数值在 Rust;Python 侧保留参数校验、领域对象组装 与庞加莱截面定义(sections.py 有意留 Python)。

e2m2e.algorithm.manifold.manifolds module

不变流形计算模块

提供 CR3BP 周期轨道不变流形(稳定/不稳定)的种子生成与批量传播功能。

算法要点

单值矩阵 M(沿轨道传播一周的 STM)的实特征值给出流形方向: 稳定流形取模小于 1 的实特征向量,不稳定流形取模大于 1 的实特征向量。 沿周期轨道取 n_points 个相位点,用从轨道首点到各相位的 STM 把特征向量 转运到该相位,位置部分归一化后施加 ±ε 的无量纲扰动得到种子; 稳定流形反向积分、不稳定流形正向积分得到流形管。

数值内核在 Rust(特征分解、STM 转运、种子扰动、批量传播调度); Python 侧只做参数校验、领域对象组装与可选的事后截面截断。

class e2m2e.algorithm.manifold.manifolds.ManifoldKind(*values)[源代码]

基类:Enum

不变流形类型枚举

STABLE = 'stable'
UNSTABLE = 'unstable'
class e2m2e.algorithm.manifold.manifolds.ManifoldTube(orbit, kind, branch, epsilon, trajectories=<factory>)[源代码]

基类:object

不变流形管(一族流形弧)。

变量:
参数:
orbit: Orbit
kind: ManifoldKind
branch: str
epsilon: float
trajectories: list[Orbit]
class e2m2e.algorithm.manifold.manifolds.InvariantManifold(orbit, kind, branch, epsilon)[源代码]

基类:object

周期轨道的不变流形

变量:
  • orbit -- 周期轨道(可只存首点,但 period 须已设置)

  • kind -- 流形类型(稳定/不稳定)

  • branch -- 扰动分支 "+" / "-"

  • epsilon -- 无量纲扰动幅度(位置方向长度,典型取 50 km / DU)

  • dynamics -- CR3BP_Dynamics 对象

参数:
SAMPLE_DT = 0.005
__init__(orbit, kind, branch, epsilon)[源代码]

初始化不变流形

参数:
  • orbit (Orbit) -- 周期轨道(period 须已知;只存首点时 seeds 会先传播一周采样相位)

  • kind (ManifoldKind) -- ManifoldKind.STABLE 或 ManifoldKind.UNSTABLE

  • branch (Literal['+', '-']) -- 扰动方向分支,"+""-"

  • epsilon (float) -- 无量纲扰动幅度(正值)

抛出:

ValueError -- 轨道周期未知、未关联 system、branch 或 epsilon 非法

返回类型:

None

seeds(n_points)[源代码]

生成相位扫掠种子

沿周期轨道均匀取 n_points 个相位点,把首点处的流形特征向量 用各段 STM 转运到该相位,位置部分归一化后施加 ±ε 扰动。

参数:

n_points (int) -- 相位点个数

返回:

种子状态数组,形状 (n_points, 6)

返回类型:

ndarray

propagate(t_span, section=None, n_workers=1)[源代码]

批量传播流形弧

积分方向由 kind 决定:STABLE 反向积分、UNSTABLE 正向积分, t_span 取绝对值作为积分时长。

参数:
  • t_span (float) -- 积分时长(无量纲时间,符号被忽略)

  • section (PoincareSection | None) -- 可选庞加莱截面;给定时每条弧在首次穿越截面处截断, 并把求精后的穿越态追加为弧的末点

  • n_workers (int) -- 并行 worker 数(>1 启用 Rayon)

返回:

流形管,含全部流形弧

返回类型:

ManifoldTube

e2m2e.algorithm.manifold.sections module

庞加莱截面工具模块

提供平面截面与近拱点截面的定义,以及两类截面穿越检测:

  • 积分中检测PoincareSection.event() 生成事件函数 g(t, state) -> float (携带 direction/terminal 属性),传给 Dynamics.propagate(events=...),由积分器在步内定位穿越,无需密采样。

  • 事后检测crossings/detect_crossings,传播时密采样 t_eval → 逐采样点求截面函数 s(t)(平面:state[axis]-value;近拱点: r·v,r 为相对中心天体的位置)→ 符号变化区间内对线性插值态用二分 法求精,穿越态残差可达 1e-10 以下。

class e2m2e.algorithm.manifold.sections.SectionCrossings(section, states, times, trajectory_index)[源代码]

基类:object

截面穿越结果容器。

变量:
参数:
section: PoincareSection
states: ndarray
times: ndarray
trajectory_index: ndarray
e2m2e.algorithm.manifold.sections.detect_crossings(times, states, section_fn)[源代码]

事后截面穿越检测

逐采样点求截面函数,符号变化区间内对分段线性插值态用二分法求精。 正向与反向(时间递减)积分均适用。

参数:
  • times (ndarray) -- 采样时刻,形状 (n,),单调(递增或递减)

  • states (ndarray) -- 采样状态,形状 (n, 6)

  • section_fn (Callable[[ndarray], float]) -- 截面函数,输入 6 维状态返回标量,零点即截面

返回:

穿越列表,每项为 (穿越时刻, 穿越态, 区间左端采样索引)

返回类型:

list[tuple[float, ndarray, int]]

class e2m2e.algorithm.manifold.sections.PoincareSection(section_fn, description='')[源代码]

基类:object

庞加莱截面

截面由标量函数 s(state) 的零等值面定义。提供两类常用构造: 平面截面(某一坐标分量等于给定值)与近拱点截面(相对中心天体 位置 r 与速度 v 的点积为零,即 r·v = 0)。

参数:
  • section_fn (Callable[[np.ndarray], float])

  • description (str)

event(direction=0, terminal=False)[源代码]

生成事件函数,供积分中检测使用

返回的 callable g(t, state) -> float 可直接传给 Dynamics.propagate(events=...);函数对象携带 direction/terminal 属性。截面函数只依赖前 6 维物理状态, STM 增广传播(42 维状态)时自动截取前 6 维。

参数:
  • direction (int) -- 穿越方向过滤。> 0 只记上行穿越(s 由负到正), < 0 只记下行,0 双向

  • terminal (bool) -- True 时首次触发即终止积分

返回:

事件函数,零点即截面

返回类型:

Callable[[float, ndarray], float]

classmethod plane(axis, value)[源代码]

构造平面截面 s = state[axis] - value

参数:
  • axis (int) -- 状态分量索引(0=x, 1=y, 2=z, 3=vx, 4=vy, 5=vz)

  • value (float) -- 平面取值

返回:

PoincareSection 实例

返回类型:

PoincareSection

classmethod periapsis(center, system)[源代码]

构造近拱点截面 s = r·v

r 为相对 center 天体的位置。CR3BP 会合系中主天体固定于 x=-μ, 次天体固定于 x=1-μ。center 与 system 的主/次天体名称 (不区分大小写)匹配,"earth"/"moon" 分别回退为主/次天体。

参数:
  • center (str) -- 中心天体名称(如 "earth" / "moon")

  • system (CR3BP_System) -- CR3BP_System 对象(提供 mu 与天体名称)

返回:

PoincareSection 实例

返回类型:

PoincareSection

crossings(tube)[源代码]

检测流形管中所有流形弧的截面穿越

参数:

tube (ManifoldTube) -- 流形管(或任何带 trajectories 列表的容器, 每条轨迹须含 timesstates

返回:

全部穿越点(插值求精后)

返回类型:

SectionCrossings

e2m2e.algorithm.nominal_orbit package

名义轨道:NominalOrbit + Interpolator(FR1↔FR2 契约)。

NominalOrbit 数据契约在 data/types/trajectory.py (ADR 0015);本模块放 插值器与使用逻辑(Gómez vol I §8.2.3:等间距历元状态表 + Floquet 基 + 投影因子表 + 高次插值器 Lagrange r=5~6)。Floquet 基 + 投影因子由 FR1 预计算,控制全程插值不复算。

实现状态:插值器待 FR1 落地(当前为占位)。

e2m2e.algorithm.proximity package

相对运动(交会对接,主题 3)。

领域算法与 station_keeping/family 同类(ADR 0011 迁移,源:proximity/): relative_dynamics(RLM/Encke/LVLH)、phasing(调相)、safety(保持点安全)。 属二档三档扩展位(relative_motion 标二档、safety 标三档,ADR 0014)。

e2m2e.algorithm.proximity.phasing module

调相设计:同轨道不同相位间转移(主题 3)。

基于 STM 的两脉冲调相(Fossa 2022 NRHO 范式):在目标周期轨道上, 从相位 φ₀ 到相位 φ₁ = φ₀ + Δφ,用两脉冲完成转移。

算法:对每个飞行时间 tof,用相对 STM 解两点边值:

δr_f = Φ_rr δr₀ + Φ_rv (δv₀ + Δv₁) 0 = Φ_vr δr₀ + Φ_vv (δv₀ + Δv₁) + Δv₂

其中 δr₀/δv₀ 是初始相对状态(由相位差决定),δr_f = 0(到达目标相位), Δv₁/Δv₂ 是待求脉冲。

class e2m2e.algorithm.proximity.phasing.PhasingManeuver(t, dv)[源代码]

基类:object

调相脉冲。

变量:
  • t (float) -- 脉冲时刻(与目标轨道时间坐标一致)

  • dv (numpy.ndarray) -- 脉冲速度增量,形状 (3,),无量纲(CR3BP DU/TU)

参数:
t: float
dv: ndarray
class e2m2e.algorithm.proximity.phasing.PhasingSolution(maneuvers, tof, total_dv, status, cause, message)[源代码]

基类:object

调相解。

变量:
参数:
maneuvers: list[PhasingManeuver]
tof: float
total_dv: float
status: ConvergenceState
cause: FailureCause
message: str

调相搜索:在 tof 网格上求两脉冲调相解。

对周期轨道,相位差 dphase 对应目标轨道上的时间差 dt = dphase / (2π) * period。初始相对状态由目标轨道在 t0t0 + dt 的状态差给出。

对每个 tof,用相对 STM 解两点边值求两脉冲。

参数:
  • orbit (Orbit) -- 目标周期轨道

  • dphase (float) -- 相位差(rad), 为一整圈

  • tof_grid (npt.ArrayLike) -- 飞行时间网格,形状 (m,),与轨道时间坐标一致

  • dynamics (DynamicsLike) -- CR3BP 动力学

  • t0 (float | None) -- 出发时刻,None 时取轨道起点

返回:

每个 tof 对应的 PhasingSolution 列表

返回类型:

list[PhasingSolution]

e2m2e.algorithm.proximity.relative_dynamics module

CR3BP 相对运动动力学(主题 3)。

在目标轨道邻域内线性化 CR3BP 动力学,得到时变相对运动方程(RLM)。 相对状态 ρ = [δr, δv] 在会合系(Synodic)下定义,随目标轨道演化。

核心组件: - TargetOrbit:目标轨道包装,提供任意时刻状态查询 - RelativeDynamics:RLM 线性化 + 相对状态/STM 传播

坐标系约定:相对状态默认在**会合系(Synodic)** 下定义(与 CR3BP 动力学 同系),LVLH 转换由调用方经 LVLHAxes 完成。

class e2m2e.algorithm.proximity.relative_dynamics.RelativeState(rho, rho_dot, frame, epoch)[源代码]

基类:object

相对状态(会合系)。

变量:
  • rho (numpy.ndarray) -- 相对位置,形状 (3,),无量纲(CR3BP DU)

  • rho_dot (numpy.ndarray) -- 相对速度,形状 (3,),无量纲(CR3BP DU/TU)

  • frame (str) -- 坐标系标签,"Synodic""LVLH"

  • epoch (float) -- 参考历元(目标轨道时间坐标)

参数:
rho: ndarray
rho_dot: ndarray
frame: str
epoch: float
class e2m2e.algorithm.proximity.relative_dynamics.TargetOrbit(orbit)[源代码]

基类:object

目标轨道包装:任意时刻状态查询。

线性插值(C⁰ 连续)。对长期高精度需求,后续可升级为三次样条。

参数:

orbit (Orbit)

property t_span: tuple[float, float]

轨道覆盖的时间范围。

state_at(t)[源代码]

线性插值取 t 时刻目标状态,形状 (6,)

参数:

t (float) -- 时间(与轨道 times 同坐标)

返回:

目标状态 [x, y, z, vx, vy, vz]

抛出:

ValueError -- t 超出轨道时间范围

返回类型:

ndarray

class e2m2e.algorithm.proximity.relative_dynamics.DynamicsLike(*args, **kwargs)[源代码]

基类:Protocol

鸭子类型协议:描述 CR3BP_Dynamics / EphemerisDynamics 的公共接口。

相对运动动力学模块通过此协议访问底层绝对动力学对象,不依赖具体类。

system: _SystemLike
compute_jacobian_A(**kwds)

Helper for @overload to raise when called.

propagate(initial_state, t_span, t_eval=None, with_stm=False, with_jacobi=False, events=None)[源代码]
参数:
  • initial_state (ArrayLike)

  • t_span (tuple[float, float])

  • t_eval (ArrayLike | None)

  • with_stm (bool)

  • with_jacobi (bool)

  • events (None)

返回类型:

dict[str, Any]

equations_of_motion(t, state)[源代码]
参数:
返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

class e2m2e.algorithm.proximity.relative_dynamics.RelativeDynamics(target, dynamics)[源代码]

基类:object

相对运动动力学(RLM 时变线性化)。

在目标轨道邻域内把动力学线性化,得到时变相对运动方程:

δẋ = A(t) δx

其中 A(t) 由 dynamics.compute_jacobian_A(t, state) 在目标状态处求值。 支持 CR3BP(CR3BP_Dynamics)和星历(EphemerisDynamics)两套动力学, 鸭子类型适配:只要对象有 compute_jacobian_A(t, state)propagate(..., with_stm=True) 即可。

参数:
linear_model(t)[源代码]

返回 t 时刻 RLM 的 A(t) 矩阵,形状 (6, 6)

CR3BP:A = [[0, I], [U, Ω]],U 为伪势能 Hessian,Ω 为科里奥利项。 星历:A = [[0, I], [∂a/∂r, 0]],∂a/∂r 为 N 体引力雅可比。

参数:

t (float)

返回类型:

ndarray

propagate(rho0, t_span, *, rtol=1e-10, atol=1e-12, max_step=None)[源代码]

传播相对状态(6 维)。

在目标轨道上逐点线性化,用变步长 RK89 积分 δẋ = A(t)δx。

参数:
  • rho0 (ArrayLike) -- 初始相对状态 [δr, δv],形状 (6,)

  • t_span (tuple[float, float]) -- 传播区间 (t0, tf)

  • rtol (float) -- 积分容差

  • atol (float) -- 积分容差

  • max_step (float | None) -- 最大步长,None 时自动

返回:

(times, rhos):times 形状 (n,),rhos 形状 (n, 6)

返回类型:

tuple[ndarray, ndarray]

propagate_with_stm(rho0, t_span, *, rtol=1e-10, atol=1e-12)[源代码]

传播相对状态 + 相对 STM(42 维增广)。

相对 STM Φ_rel(t, t₀) 满足 δx(t) = Φ_rel(t, t₀) δx(t₀)。 由于线性化在同一会合系下,Φ_rel = Φ_abs(绝对 STM)。 本方法复用 CR3BP_Dynamics.propagate() 的 with_stm=True, 在目标轨道上传播绝对 STM,即得相对 STM。

参数:
  • rho0 (ArrayLike) -- 初始相对状态 [δr, δv],形状 (6,)

  • t_span (tuple[float, float]) -- 传播区间

  • rtol (float)

  • atol (float)

返回:

(times, rhos, stms):stms 形状 (n, 6, 6)

返回类型:

tuple[ndarray, ndarray, ndarray]

nonlinear_eom(t, rho)[源代码]

非线性相对运动方程右端(牛顿式,两式相减)。

δẍ = f(x_target + δx) − f(x_target)

近距离时两式相减产生截断误差(Cuevas del Valle 2022)。 供对比验证用;实际传播建议用 encke_eom()

参数:
  • t (float) -- 时间

  • rho (ndarray) -- 相对状态 [δr, δv],形状 (6,)

返回:

相对状态导数 [δv, δa]

返回类型:

ndarray

encke_eom(t, rho)[源代码]

Encke 改写的非线性相对运动方程右端。

把引力加速度差分项改写为 Encke 形式,避免近距离 1/r³ 两式相减的截断误差。精度比牛顿式提升一个量级(Cuevas del Valle 2022)。

对每个引力中心,Encke 公式(Battin 标准形式):

a_grav(r + δr) - a_grav(r) = -μ/|r|³ [f(q)·q·r + g(q)·δr]

其中 q = (2r·δr + |δr|²)/|r|²f(q) = ((1+q)^(−3/2) 1)/q (q→0 时 f→−3/2,用级数展开), g(q) = (1+q)^(−3/2)

参数:
  • t (float) -- 时间

  • rho (ndarray) -- 相对状态 [δr, δv],形状 (6,)

返回:

相对状态导数 [δv, δa]

返回类型:

ndarray

propagate_nonlinear(rho0, t_span, *, method='encke', rtol=1e-10, atol=1e-12, max_step=None)[源代码]

传播相对状态(非线性方程)。

参数:
  • rho0 (ArrayLike) -- 初始相对状态 [δr, δv],形状 (6,)

  • t_span (tuple[float, float]) -- 传播区间

  • method (str) -- "encke" (推荐)或 "newton" (两式相减,精度低)

  • rtol (float) -- 积分容差

  • atol (float) -- 积分容差

  • max_step (float | None) -- 最大步长

返回:

(times, rhos)

返回类型:

tuple[ndarray, ndarray]

ephemeris_linear_model(t)[源代码]

星历 RLM 的 A(t) 矩阵(同 linear_model(),显式命名)。

参数:

t (float)

返回类型:

ndarray

ephemeris_encke_eom(t, rho)[源代码]

星历 Encke 改写的非线性相对运动方程右端(预留)。

星历惯性系无科里奥利/离心项,Encke 公式需按 N 体逐项改写 (每个天体的直接项差 Encke 化,间接项与位置无关直接相消)。 当前版本暂用牛顿式两式相减,后续实现。

参数:
  • t (float) -- 时间

  • rho (ndarray) -- 相对状态 [δr, δv],形状 (6,)

返回:

相对状态导数 [δv, δa]

返回类型:

ndarray

to_lvlh(rho_syn, t)[源代码]

把会合系相对状态转换到 LVLH 系。

LVLH 系定义(LVLHAxes):R = 径向,H = 角动量,V = H × R。 转换公式:

ρ_lvlh = Rᵀ δr_syn ρ̇_lvlh = Rᵀ δv_syn + Ṙᵀ δr_syn

其中 R 为目标轨道的 LVLH 旋转矩阵,Ṙ 用中心差分近似 (步长 1e-5,与 Axes.rotation_and_rate 一致)。

参数:
  • rho_syn (ArrayLike) -- 会合系相对状态 [δr, δv],形状 (6,)

  • t (float) -- 参考历元

返回:

(rho_lvlh, rho_dot_lvlh):LVLH 系相对位置与速度, 各形状 (3,)

返回类型:

tuple[ndarray, ndarray]

from_lvlh(rho_lvlh, rho_dot_lvlh, t)[源代码]

把 LVLH 系相对状态转换回会合系。

逆转换:

δr_syn = R ρ_lvlh δv_syn = R ρ̇_lvlh + Ṙ ρ_lvlh

参数:
  • rho_lvlh (ArrayLike) -- LVLH 系相对位置,形状 (3,)

  • rho_dot_lvlh (ArrayLike) -- LVLH 系相对速度,形状 (3,)

  • t (float) -- 参考历元

返回:

会合系相对状态 [δr, δv],形状 (6,)

返回类型:

ndarray

e2m2e.algorithm.proximity.safety module

保持点与安全分析(主题 3)。

Bucchioni 2022 保持点 + 被动安全校验 + Chan 最大碰撞概率。

核心概念:

  • 保持点(Keeping Point):相对轨道上的安全驻留位置,自由漂移 一圈后仍在安全域内

  • 安全域(Safety Region):球/椭球/逼近锥,分 keep-out(禁区) 和 approach(逼近区)两种语义

  • 被动安全:自由漂移轨迹不违背安全域

  • 碰撞概率:Chan 公式,协方差等比例放大使联合 PDF 等值线 切于组合球时的最大 Pc

class e2m2e.algorithm.proximity.safety.SafetyRegion(kind, shape, center, radius, cone_axis=None, cone_half_angle=None)[源代码]

基类:object

安全域(球或逼近锥)。

变量:
  • kind (Literal['keep_out', 'approach']) -- "keep_out" (禁区,不可进入)或 "approach" (逼近区, 可进入但需监控)

  • shape (Literal['sphere', 'cone']) -- "sphere" (球)或 "cone" (逼近锥)

  • center (numpy.ndarray) -- 中心位置,形状 (3,),km(LVLH 系)

  • radius (float) -- 半径(球)或锥底半径(锥),km

  • cone_axis (numpy.ndarray | None) -- 锥轴方向(仅 shape="cone" 时用),形状 (3,)

  • cone_half_angle (float | None) -- 锥半顶角(rad,仅 shape="cone" 时用)

参数:
kind: Literal['keep_out', 'approach']
shape: Literal['sphere', 'cone']
center: ndarray
radius: float
cone_axis: ndarray | None = None
cone_half_angle: float | None = None
contains(point)[源代码]

判断点是否在安全域内。

参数:

point (ArrayLike)

返回类型:

bool

distance_to(point)[源代码]

点到安全域边界的有向距离(正=外部,负=内部)。

参数:

point (ArrayLike)

返回类型:

float

class e2m2e.algorithm.proximity.safety.SafetyReport(safe, violation_intervals, min_distance, collision_probability)[源代码]

基类:object

被动安全校验报告。

变量:
  • safe (bool) -- 是否全程安全

  • violation_intervals (list[tuple[float, float]]) -- 违背区间列表 [(t_start, t_end), ...]

  • min_distance (float) -- 最小距离(到安全域边界),km

  • collision_probability (float) -- 最大碰撞概率(Chan 公式)

参数:
safe: bool
violation_intervals: list[tuple[float, float]]
min_distance: float
collision_probability: float
class e2m2e.algorithm.proximity.safety.KeepingPoint(position, epoch, dwell_time, safety_region)[源代码]

基类:object

保持点。

变量:
参数:
position: ndarray
epoch: float
dwell_time: float
safety_region: SafetyRegion
e2m2e.algorithm.proximity.safety.check_passive_safety(traj_times, traj_positions, region, *, cov=None, r_chaser=5.0, r_target=5.0)[源代码]

校验自由漂移轨迹的被动安全性。

逐点检查轨迹是否进入 keep-out 安全域。若提供协方差,同时计算 Chan 最大碰撞概率。

参数:
  • traj_times (ArrayLike) -- 轨迹时间序列,形状 (n,)

  • traj_positions (ArrayLike) -- 轨迹位置序列,形状 (n, 3),km(LVLH 系)

  • region (SafetyRegion) -- 安全域

  • cov (ndarray | None) -- 相对位置协方差,形状 (3, 3),km²。None 时不算碰撞概率

  • r_chaser (float) -- 追逐器半径,km

  • r_target (float) -- 目标器半径,km

返回:

SafetyReport

返回类型:

SafetyReport

e2m2e.algorithm.proximity.safety.max_collision_probability(d, cov, r_chaser, r_target)[源代码]

Chan 最大碰撞概率公式。

最大碰撞概率 = 协方差等比例放大使联合 PDF 等值线切于组合球时的 Pc。 组合球半径 R = r_chaser + r_target,相对距离 d,协方差 Σ。

公式(Chan 2008, 简化球形近似):

Pc_max = (R / (2√π σ))³ exp(−d² / (4σ²))

其中 σ² 为协方差最大特征值(最不利方向)。

参数:
  • d (float) -- 相对距离,km

  • cov (ndarray) -- 相对位置协方差,形状 (3, 3),km²

  • r_chaser (float) -- 追逐器半径,km

  • r_target (float) -- 目标器半径,km

返回:

最大碰撞概率(0~1)

返回类型:

float

e2m2e.algorithm.station_keeping package

轨道保持(轨道控制)。

站保控制律留 Python(领域知识,ADR 0011 迁移,源:dfh/control_orbit.py 编排 + algorithms/station_keeping/):特征点控制(special_point)、目标 点严格/宽松控制(target_point)、误差模型(error_models)、角动量管理 (momentum_management)、三轨道蒙特卡洛(monte_carlo)。controller.py 是编排器(读输入星历、选控制律、配双力模型、汇总输出)。

e2m2e.algorithm.station_keeping.controller module

功能码 2(任务轨道控制/轨道保持)对齐入口。

端到端轨道保持功能:输入标称轨道星历(FR1 design_orbit 产物),按控制模式(特征点/目标点严格/目标点宽松,可选角动量管理)施加 脉冲控制,以三轨道结构(目标/真实/测量)仿真测定轨与控制误差,蒙特卡洛 批量评估,输出 SK_STATISTIC / MANEUVERS / 受控星历。算法以《控制方案.md》 (hybrid_auto 版)为准,规格见 docs/plans/dfh-parity-prd.md FR2。

参数与 MATLAB control_orbit.m 对齐(关键字参数 + dataclass 结果)。 角动量管理模式(control_mode 4-6)通过 engine_layout 参数激活, 对应 MATLAB ControlMode 4-6。两处能力边界差异(e2m2e 尚未实现,见 #253):光压默认用炮弹模型(solar_radiation=1,MATLAB 默认 ECOM=2); 耦合项默认关闭(coupling=0,MATLAB 默认开)。

class e2m2e.algorithm.station_keeping.controller.ControlOrbitResult(sk_statistic, num_failed, maneuvers, controlled_ephemeris, raw, status=ConvergenceState.CONVERGED, cause=FailureCause.NONE, message='任务完成', stages=())[源代码]

基类:object

轨道保持仿真结果(对齐 MATLAB control_orbit 输出结构)。

变量:
参数:
sk_statistic: SKStatistic
num_failed: int
maneuvers: ManeuverTable
controlled_ephemeris: EphemerisTable | None
raw: MonteCarloResult
status: ConvergenceState = 'converged'
cause: FailureCause = 'none'
message: str = '任务完成'
stages: tuple[StageRecord, ...] = ()
write_outputs(out_dir, mode=1)[源代码]

把三个输出文件写入目录(SK_STATISTIC/MANEUVERS/受控星历)。

参数:
返回类型:

list[Path]

e2m2e.algorithm.station_keeping.controller.control_orbit(input_ephemeris, *, control_mode=1, is_nrho=0, special_mode=1, control_interval=30.0, feedback_arc=28.0, special_crossings=3, num_controls=120, num_monte_carlo=5, output_step=86400.0, position_accuracy=1500.0, velocity_accuracy=0.002, thrust_angle_err=0.333, thrust_mean=10.0, thrust_rel_err=0.003, thrust_abs_err=0.033, thrust_min=0.1, thrust_max=100.0, thrust_total=1000.0, srp_error_level=0.1, perturbation=None, dyb=None, earth_degree=2, moon_degree=2, real_perturbation=None, real_dyb=None, real_earth_degree=10, real_moon_degree=10, spice=None, kernel_dir=None, n_workers=1, seed=None, engine_layout=None, momentum_interval=5.0, srp_offset_m=None, spacecraft_mass=1000.0, srp_torque=None, tight_tolerance_km=0.1, tight_max_iter=6, special_damping_factor=1.0)[源代码]

端到端轨道保持仿真。

参数:
  • input_ephemeris (str | Path | EphemerisTable) -- 标称轨道星历文件路径或 EphemerisTable

  • control_mode (int) -- 1=目标点宽松、2=目标点严格、3=特征点、 4=目标点宽松+角动量管理、5=目标点严格+角动量管理、6=特征点+角动量管理

  • is_nrho (int) -- 目标轨道是否 NRHO(1=是;特征点模式的约束随之取 ẋ=0 且 ż=0 由 special_mode 决定,本参数保留作输入对齐)

  • special_mode (int) -- 特征点模式 1=Lissajous(ẋ=0)、2=Halo/NRHO(ẋ=0 且 ż=0)

  • control_interval (float) -- 控制时间间隔(天)

  • feedback_arc (float) -- 目标点模式反馈弧段(天)

  • special_crossings (int) -- 特征点目标穿越 x-z 平面次数

  • num_controls (int) -- 控制次数(总时间 = (N-1)·间隔)

  • num_monte_carlo (int) -- 蒙特卡洛样本数(惯例 100)

  • output_step (float) -- 受控星历输出间隔(秒)

  • velocity_accuracy (float) -- 测定轨 1-sigma(m / m/s)

  • / (thrust_angle_err / thrust_mean / thrust_rel_err / thrust_abs_err)

  • thrust_total (float) -- 分段控制误差参数 (角度 1-sigma deg、中点值 m/s、相对/绝对 1-sigma、最小/最大 开机 m/s、累计上限 m/s,见《控制方案.md》式 5.40)

  • srp_error_level (float) -- 光压弧段随机误差量级(百分比/100)

  • dyb (Sequence[float] | None) -- 控制(理论)力模型 (表 5-3 左列;默认 2×2、关相对论/大气,见 _DEFAULT_CTRL_PERTURBATION

  • real_dyb (Sequence[float] | None) -- 真实(实际)力模型(表 5-3 右列;默认 10×10、全开)

  • spice (SPICEManager | None) -- 已加载内核的 SPICEManager;缺省自动创建

  • kernel_dir (str | None) -- SPICE 内核目录(缺省仓库 kernels/n_workers>1 时 worker 用它在子进程重建上下文)

  • n_workers (int) -- 进程池大小(>1 时样本并行)

  • seed (int | None) -- 随机种子(同种子同结果)

  • engine_layout (EngineLayout | None) -- EngineLayout 实例(角动量管理模式 4-6 必填)

  • momentum_interval (float) -- 角动量卸载间隔(天),0 表示与轨道控制同步

  • srp_offset_m (Sequence[float] | None) -- SRP 压心相对质心偏移 [x,y,z] (m),常值

  • spacecraft_mass (float) -- 航天器质量(kg)

  • srp_torque (Sequence[float] | None) -- 常值 SRP 力矩 [τx,τy,τz] (N·m)

  • tight_tolerance_km (float) -- TIGHT 模式位置重合容差(km,默认 0.1)

  • tight_max_iter (int) -- TIGHT 模式微分修正迭代上限(默认 6)

  • special_damping_factor (float) -- SPECIAL 模式牛顿迭代阻尼因子(<1 时启用回溯,默认 1.0 不阻尼)

  • position_accuracy (float)

  • velocity_accuracy

  • thrust_angle_err (float)

  • thrust_mean (float)

  • thrust_rel_err (float)

  • thrust_abs_err (float)

  • thrust_min (float)

  • thrust_max (float)

  • thrust_total

  • perturbation (dict[str, int] | None)

  • dyb

  • earth_degree (int)

  • moon_degree (int)

  • real_perturbation (dict[str, int] | None)

  • real_dyb

  • real_earth_degree (int)

  • real_moon_degree (int)

返回:

ControlOrbitResult (SK_STATISTIC/MANEUVERS/受控星历)

抛出:
返回类型:

ControlOrbitResult

e2m2e.algorithm.station_keeping.target_point module

基于目标轨道的目标点控制(《控制方案.md》§1.3-1.4)。

两种模式都以标称轨道(FR1 设计产物)为目标参照,在控制节点施加 Δv 使 受控轨道贴近标称:

  • 严格控制 (§1.3,式 5.35):受控轨道外推至目标节点时刻的位置与 标称轨道节点严格重合,微分修正式迭代求解。目标节点取控制时刻后 feedback_arc 天处的标称轨道节点("1 月内距当前最远的节点"的 DFH 参数化)。

  • 宽松控制 (§1.4,式 5.36):不要求重合,最小化 J = ΔvᵀQΔv + ΣpᵢᵀRᵢpᵢ + ΣvᵢᵀSᵢvᵢ (位置/速度偏差加权), 用标称轨道 STM 线性传递偏差,解析最优(默认单节点反馈,Q=R=I、 S=1e-2·I)。

STM 在 GCRS 惯性系传播,偏差 p₀/v₀ 也在惯性系计算(与标称轨道同为 GCRS 表达,无需转会合系)。控制量输出 GCRS 速度增量(km/s)。

class e2m2e.algorithm.station_keeping.target_point.NominalOrbitView(*args, **kwargs)[源代码]

基类:Protocol

标称轨道视图:任意时刻的标称状态(GCRS,km, km/s)。

state_at(t)[源代码]

t(秒)时刻的标称状态(6 维)。

参数:

t (float)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

class e2m2e.algorithm.station_keeping.target_point.StrictTargetPointLaw(feedback_arc_days=28.0, tolerance_km=0.1, max_iter=6)[源代码]

基类:object

目标点严格控制律(§1.3)。

变量:
  • feedback_arc_days (float) -- 反馈弧段长度(天),即目标节点相对控制时刻的 时间偏移(DFH 默认 28 天,即"1 月内最远节点")

  • tolerance_km (float) -- 位置重合容差(km)

  • max_iter (int) -- 微分修正迭代上限

参数:
feedback_arc_days: float = 28.0
tolerance_km: float = 0.1
max_iter: int = 6
compute_maneuver(state0, t0, *, propagator, nominal)[源代码]

计算控制量 Δv(km/s)。

参数:
  • state0 (ArrayLike) -- 控制时刻状态(GCRS,km, km/s;通常为测量轨道状态)

  • t0 (float) -- 控制时刻(秒)

  • propagator (StmPropagator) -- 带 STM 传播器

  • nominal (NominalOrbitView) -- 标称轨道视图

返回:

Δv 矢量(km/s)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

class e2m2e.algorithm.station_keeping.target_point.LooseTargetPointLaw(feedback_arc_days=28.0, q=1.0, r=1.0, s=0.01)[源代码]

基类:object

目标点宽松控制律(§1.4,单节点反馈解析解,式 5.36)。

偏差取**当前偏差**:变轨前测量状态与目标(标称)轨道在控制时刻的 状态差 p₀/v₀(式 5.36 原文语义);Φ(t_k, t₀) 分块 A/B/C/D 由 STM 传播给出,控制后的目标节点偏差经线性传递 p_k = Φ·(p₀, v₀+Δv)。 最小化 J = ΔvᵀQΔv + pᵀRp + vᵀSv 得解析最优:

Δv* = -(Q + BᵀRB + DᵀSD)⁻¹·[(BᵀRB + DᵀSD)·v₀ + (BᵀRA + DᵀSC)·p₀]

对 NRHO 这类强不稳定轨道,A 块(位置-位置)放大巨大,BᵀRA·p₀ 项 主导控制量(实测 p₀~90 km 时 Δv 达 m/s 量级,与历史标定样本一致)。

变量:
  • feedback_arc_days (float) -- 反馈弧段长度(天),目标节点时间偏移

  • q (float) -- 控制量权重矩阵 Q = q·I

  • r (float) -- 目标节点位置偏差权重 R = r·I

  • s (float) -- 目标节点速度偏差权重 S = s·I(默认 1e-2,速度偏差权重取小)

参数:
feedback_arc_days: float = 28.0
q: float = 1.0
r: float = 1.0
s: float = 0.01
compute_maneuver(state0, t0, *, propagator, nominal)[源代码]

计算控制量 Δv(km/s)。

单节点反馈(N=1,式 5.36 的解析解)。p₀/v₀ 为控制时刻测量状态 相对标称的偏差;A/B/C/D 为 Φ(t_j, t₀) 的四块。

参数:
返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.station_keeping.special_point module

特征点控制(《控制方案.md》§1.2)。

L3 点 Lissajous 轨道穿越地月连线坐标系的 x-z 平面时近似满足 ẋ=0(式 5.31);NRHO/Halo 作为晕轨道的特殊成员还满足 ż=0(式 5.32)。控制过程: 在当前控制时刻 t₀ 施加 Δv,使轨道在第 1 次(或第 N 次)穿越 x-z 平面 (y=0)时满足上述约束,牛顿迭代(式 5.33/5.34)求解,雅可比为从 t₀ 至 穿越时刻状态转移矩阵的子矩阵;解不唯一时取最小范数解(本项目做法)。

实现要点:

  • 传播在 GCRS 惯性系进行(Rust 42 维 STM 传播),约束在会合系评估: 穿越检测用会合系 y 分量符号变化,约束残差用会合系速度分量

  • 雅可比:∂ẋ_syn/∂v₀ = e1ᵀ·Φ[3:6,3:6]∂ż_syn/∂v₀ = e3ᵀ·Φ[3:6,3:6] (会合系基向量 e1/e3 在穿越时刻求值;旋转/平移项不依赖 v₀,对雅可比 无贡献,穿越时刻随 v₀ 的变化项按 §1.2 的"STM 子矩阵"处理忽略)

  • 牛顿迭代每次重传播:初迭代粗网格全弧段找第 N 次穿越区间,后续迭代 只在上次穿越时刻 ± 窗口内传播(穿越时刻收敛过程中移动很小)

控制量输出为 GCRS 速度增量(km/s),与传播器单位一致。

class e2m2e.algorithm.station_keeping.special_point.SpecialPointLaw(special_mode=1, crossings=3, tolerance=1e-06, max_iter=8, window_days=1.0, horizon_sec=None, synodic=None, damping_factor=1.0, v_c=None)[源代码]

基类:object

特征点控制律。

变量:
  • special_mode (int) -- 特征点控制模式——1=Lissajous 类型(约束 ẋ=0); 2=halo/NRHO 类型(约束 ẋ=0 且 ż=0)

  • crossings (int) -- 目标穿越次数 N(第 N 次穿越 x-z 平面),DFH 默认 3

  • tolerance (float) -- 约束残差容差(无量纲会合系速度,1e-6 约合 1e-3 m/s)

  • max_iter (int) -- 牛顿迭代上限

  • window_days (float) -- 后续迭代的穿越时刻搜索窗口(天)

  • horizon_sec (float | None) -- 首迭代搜索穿越的弧段长度(秒),取控制时间间隔

  • synodic (e2m2e.algorithm.station_keeping.special_point.SynodicView | None) -- 会合系视图(GCRS↔会合系批量转换 + 旋转矩阵)

参数:
special_mode: int = 1
crossings: int = 3
tolerance: float = 1e-06
max_iter: int = 8
window_days: float = 1.0
horizon_sec: float | None = None
synodic: SynodicView | None = None
damping_factor: float = 1.0
v_c: float | None = None
compute_maneuver(state0, t0, *, propagator, nominal=None, grid_sec=600.0)[源代码]

计算控制量 Δv(GCRS,km/s)。

参数:
  • state0 (npt.ArrayLike) -- 控制时刻状态(GCRS,km, km/s;通常为测量轨道状态)

  • t0 (float) -- 控制时刻(秒)

  • propagator (StmPropagator) -- 带 STM 传播器

  • nominal (NominalOrbitView | None) -- 未使用(特征点控制不需要标称轨道),为接口一致保留

  • grid_sec (float) -- 首迭代粗网格间隔(秒)

返回:

Δv 矢量(km/s);找不到穿越(弧段内不足 N 次)或未收敛时 返回 None

返回类型:

npt.NDArray[np.floating] | None

class e2m2e.algorithm.station_keeping.special_point.StmPropagator(*args, **kwargs)[源代码]

基类:Protocol

带 STM 的传播器(Rust 批量/单样本 STM 传播的薄封装)。

propagate_with_stm(state0, t0, t_eval)[源代码]

state0 (GCRS,km, km/s)在 t0 时刻传播到 t_eval 各时间点(秒)。

返回:

{"time", "states" (n,6), "stm" (n,6,6)}

参数:
  • state0 (ArrayLike)

  • t0 (float)

  • t_eval (ArrayLike)

返回类型:

dict[str, ndarray[tuple[Any, ...], dtype[floating]]]

class e2m2e.algorithm.station_keeping.special_point.SynodicView(*args, **kwargs)[源代码]

基类:Protocol

会合系视图:GCRS 状态批量转会合系 + 会合系旋转矩阵。

to_synodic(states, ets)[源代码]

GCRS 状态(km, km/s)批量转无量纲会合系状态(n,6)。

参数:
  • states (ArrayLike)

  • ets (ArrayLike)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

rotation_matrix(et)[源代码]

会合系旋转矩阵 R(r_icrf = R @ r_syn)。

参数:

et (float)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.station_keeping.error_models module

站保误差模型:采样、测定轨扰动、分段控制误差、光压弧段误差。

算法依据《控制方案.md》(hybrid_auto 版)§1.5:

  • §1.5.1 轨道误差仿真:式 5.37-5.39 的测定轨高斯扰动(位置/速度 1-sigma 可配),标准正态样本用式 5.37 下方的 Marsaglia 极坐标 Box-Muller 构造

  • §1.5.2 控制误差仿真:式 5.40 分段模型——Δv < Δv_min 不开机; Δv_min Δv < Δv_mid 绝对误差(大小 1-sigma + 球面角 α/β 误差); Δv_mid Δv Δv_max 相对误差;Δv > Δv_max 判控制失败

  • §1.5.3 力模型误差仿真:真实轨道与控制轨道的光压差异每控制弧段随机 生成、弧段内固定(表 5-3 脚注)

单位约定:轨道状态为 GCRS(位置 km、速度 km/s),与传播器一致;误差 参数沿用 DFH 惯例(位置精度 m、速度精度 m/s、脉冲大小 m/s)。

class e2m2e.algorithm.station_keeping.error_models.BoxMullerSampler(seed=None)[源代码]

基类:object

Marsaglia 极坐标 Box-Muller 标准正态采样器(§1.5.1 构造)。

u1, u2 (0,1)v = 2u - 1 = v1² + v2² < 1z1 = v1·sqrt(-2·ln(r²)/r²)z2 = v2·sqrt(-2·ln(r²)/r²) 为 两个独立标准正态数。可设种子复现(蒙特卡洛回归要求同种子同结果)。

参数:

seed (int | None)

standard_normal(size=1)[源代码]

生成 size 个独立标准正态样本。

参数:

size (int)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

class e2m2e.algorithm.station_keeping.error_models.NavigationErrorModel(position_sigma_m=1500.0, velocity_sigma_mps=0.002)[源代码]

基类:object

测定轨误差模型(§1.5.1)。

变量:
  • position_sigma_m (float) -- 位置 1-sigma(m),DFH 默认 1500

  • velocity_sigma_mps (float) -- 速度 1-sigma(m/s),DFH 默认 0.002

参数:
  • position_sigma_m (float)

  • velocity_sigma_mps (float)

position_sigma_m: float = 1500.0
velocity_sigma_mps: float = 0.002
perturb(state, sampler)[源代码]

叠加一次测定轨高斯扰动(式 5.37/5.38/5.39)。

参数:
  • state (ArrayLike) -- GCRS 状态 [x, y, z, vx, vy, vz] (km, km/s)

  • sampler (BoxMullerSampler) -- 标准正态采样器

返回:

扰动后的状态(km, km/s)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

class e2m2e.algorithm.station_keeping.error_models.ThrustExecutionError(dv_min=0.1, dv_mid=10.0, dv_max=100.0, abs_sigma_mps=0.033, rel_sigma=0.003, angle_sigma_deg=0.333)[源代码]

基类:object

轨控发动机执行误差模型(式 5.40 分段)。

变量:
  • dv_min (float) -- 最小开机速度增量(m/s);Δv < dv_min 完全不开机

  • dv_mid (float) -- 中点值(m/s);小量段(绝对误差)与大量段(相对误差)分界

  • dv_max (float) -- 最大开机速度增量(m/s);Δv > dv_max 判控制失败

  • abs_sigma_mps (float) -- 小量段大小 1-sigma(m/s,DFH 默认 0.033)

  • rel_sigma (float) -- 大量段相对 1-sigma(DFH 默认 0.003)

  • angle_sigma_deg (float) -- 推力方向球面角 1-sigma(deg,DFH 默认 0.333)

参数:
dv_min: float = 0.1
dv_mid: float = 10.0
dv_max: float = 100.0
abs_sigma_mps: float = 0.033
rel_sigma: float = 0.003
angle_sigma_deg: float = 0.333
apply(dv_c, sampler)[源代码]

施加执行误差,返回(实际 Δv 矢量 m/s,是否控制失败)。

理论控制量 Δv_c 为 3 矢量(m/s)。结果约定:

  • 不开机(|Δv_c| < dv_min):返回 None (零矢量),非失败

  • 绝对误差段:大小 Δv + N(0, abs_sigma)、方向角加高斯误差

  • 相对误差段:大小 Δv·(1 + N(0, rel_sigma))、方向角加高斯误差

  • 失败(|Δv_c| > dv_max):返回 (None, True)

方向误差按式 5.40 的球面角模型:α (方位角)与 β (仰角) 各加高斯误差,实际方向为 (cosβ'cosα', cosβ'sinα', sinβ')。

参数:
返回类型:

tuple[ndarray[tuple[Any, ...], dtype[floating]] | None, bool]

class e2m2e.algorithm.station_keeping.error_models.SrpErrorModel(error_level=0.1)[源代码]

基类:object

光压弧段随机误差(表 5-3 脚注)。

真实轨道与控制轨道的光压模型差异每控制弧段随机生成、弧段内固定。 实现为真实轨道光压系数乘子 1 + error_level·z,每弧段抽一次。

参数:

error_level (float)

error_level: float = 0.1
sample_cr_scale(sampler)[源代码]

抽样当前弧段的光压系数乘子。

参数:

sampler (BoxMullerSampler)

返回类型:

float

e2m2e.algorithm.station_keeping.momentum_management module

角动量管理联合控制(《控制方案.md》§1.6)。

太阳光压力矩导致姿态角动量累积,需周期性卸载。姿态发动机布局由安装位置 rᵢ (相对质心,m)与喷气方向 eᵢ (单位矢量)描述,构造常数矩阵:

  • E (3×N):力臂矩阵,E[:,i] = rᵢ × eᵢ

  • E_r (3×N):力矩方向矩阵,E_r[:,i] = eᵢ

两种求解场景:

  1. 纯角动量卸载 (mode 4-6 的角动量事件):min ‖V‖²  s.t.  m·E_r·V = ΔM

  2. 联合控制 (轨道控制 + 角动量卸载一次开机):min ‖V‖²  s.t. E·V = Δv_orbital,  m·E_r·V = ΔM

发动机数 N ≥ 6(6 维约束需 N 维自由度保证可解性)。

用户输入参考:MATLAB fmt_inputs_control.m 角动量块、控制方案 §1.6 图 5-38 发动机安装示意(仅示意,布局必须作为用户输入)。

class e2m2e.algorithm.station_keeping.momentum_management.EngineLayout(positions_m, directions, E=None, E_r=None)[源代码]

基类:object

姿态发动机布局。

变量:
参数:
positions_m: ndarray[tuple[Any, ...], dtype[floating]]
directions: ndarray[tuple[Any, ...], dtype[floating]]
E: ndarray[tuple[Any, ...], dtype[floating]] = None
E_r: ndarray[tuple[Any, ...], dtype[floating]] = None
property num_engines: int
e2m2e.algorithm.station_keeping.momentum_management.compute_delta_m(torque_nm, dt_sec)[源代码]

角动量卸载需求:ΔM = τ × Δt。

参数:
  • torque_nm (ArrayLike) -- 3 矢量(N·m),SRP 力矩

  • dt_sec (float) -- 自上次卸载以来的时间间隔(秒)

返回:

3 矢量(kg·m²/s)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.station_keeping.momentum_management.compute_srp_torque(srp_force_n, offset_m)[源代码]

计算 SRP 力矩(压心偏移 × SRP 力)。

参数:
  • srp_force_n (ArrayLike) -- SRP 力矢量(N),方向为 Sun→SC

  • offset_m (ArrayLike) -- SRP 压心相对质心偏移(m),用户输入常数

返回:

3 矢量(N·m)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.station_keeping.momentum_management.solve_joint_control(E, E_r, dv_orbital_mps, delta_m, mass_kg)[源代码]

联合控制求解(轨道控制 + 角动量卸载一次开机)。

min ‖V‖²  s.t.  E·V = Δv_orbital,  m·E_r·V = ΔM

增广线性方程组 A·V = bA = [E; m·E_r] (6×N,N≥6)。

参数:
  • E (ArrayLike) -- 力臂矩阵(3×N)

  • E_r (ArrayLike) -- 力矩方向矩阵(3×N)

  • dv_orbital_mps (ArrayLike) -- 轨道控制速度增量(3 矢量,m/s)

  • delta_m (ArrayLike) -- 角动量需求(3 矢量,kg·m²/s)

  • mass_kg (float) -- 航天器质量(kg)

返回:

N 矢量(m/s),各发动机速度增量

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.station_keeping.momentum_management.solve_momentum_unload(E_r, delta_m, mass_kg)[源代码]

纯角动量卸载求解。

min ‖V‖²  s.t.  m · E_r · V = ΔM

参数:
  • E_r (ArrayLike) -- 力矩方向矩阵(3×N)

  • delta_m (ArrayLike) -- 角动量需求(3 矢量,kg·m²/s)

  • mass_kg (float) -- 航天器质量(kg)

返回:

N 矢量(m/s),各发动机速度增量

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

e2m2e.algorithm.station_keeping.momentum_management.validate_engine_layout(layout)[源代码]

校验发动机布局的可解性。

检查项(全部抛 ValueError,附中文信息):

  1. E_r 秩 < 3:角动量管理无解(三维角动量变化需 E_r 行满秩)

  2. 增广 [E; E_r] 秩 < 6:联合控制不可解(存在 Δv_o + ΔM 组合无法同时满足)

发动机数 N < 6 的检查在 EngineLayout.__post_init__ 中完成。

参数:

layout (EngineLayout)

返回类型:

None

e2m2e.algorithm.station_keeping.monte_carlo module

三轨道结构蒙特卡洛仿真驱动(《控制方案.md》§1.5/§1.7)。

误差仿真的三轨道结构(§1.5.1):

  • 目标轨道:标称轨道(FR1 设计产物),只作参照

  • 真实轨道:入轨时刻相对目标加测定轨扰动(式 5.38),以"实际"力 模型外推,模拟探测器的真实状态

  • 测量轨道:每个控制时刻相对真实轨道加测定轨扰动(式 5.39),以 "理论"力模型外推,控制量基于它计算

控制量施加于真实轨道;执行误差按式 5.40 分段(< Δv_min 不开机、小量 绝对误差、大量相对误差、> Δv_max 判失败);真实轨道与控制轨道的力模型 差异为表 5-3 双配置,其中光压误差每控制弧段重新抽样、弧段内固定(表 5-3 脚注)。蒙特卡洛对每个样本独立抽样运行(§1.7,DFH 惯例 100 次), 统计总 Δv、最大 Δv 与失败次数。

传播全部走 Rust 编译力模型(propagate_compiled*),控制律的 STM 由 42 维增广传播给出。蒙特卡洛的样本并行在 Python 进程池(CSPICE 全局状态非线程安全,rayon 不可用,见 spice_ffi.rs 模块注释)。

class e2m2e.algorithm.station_keeping.monte_carlo.MonteCarloResult(total_delta_v, max_delta_v, failed_mask, num_failed, maneuvers=<factory>, controlled_ephemeris=None, attitude_delta_v=<factory>, attitude_delta_v_independent=<factory>)[源代码]

基类:object

蒙特卡洛批量结果(对应 DFH SK_STATISTIC/MANEUVERS/受控星历)。

变量:
参数:
total_delta_v: ndarray[tuple[Any, ...], dtype[floating]]
max_delta_v: ndarray[tuple[Any, ...], dtype[floating]]
failed_mask: ndarray[tuple[Any, ...], dtype[bool]]
num_failed: int
maneuvers: ndarray[tuple[Any, ...], dtype[floating]]
controlled_ephemeris: EphemerisTable | None = None
attitude_delta_v: ndarray[tuple[Any, ...], dtype[floating]]
attitude_delta_v_independent: ndarray[tuple[Any, ...], dtype[floating]]
sk_statistic()[源代码]

组装 SK_STATISTIC 表(3 列或 5 列版)。

无角动量管理时 3 列(仿真序号/总 Δv/最大 Δv,序号在写出时追加); 含角动量管理时 5 列(追加姿态总 Δv、姿态独立 Δv)。

对齐外部工具口径:失败样本不写统计行(历史标定样本中失败行缺失)。

返回类型:

SKStatistic

maneuver_table()[源代码]

组装 MANEUVERS 表(MJD(TDB) = 51544.5 + et/86400,SPICE et 原点为 J2000 历元 JD 2451545.0,即 MJD 51544.5)。

返回类型:

ManeuverTable

class e2m2e.algorithm.station_keeping.monte_carlo.NominalOrbit(ephemeris, spice)[源代码]

基类:object

标称轨道视图:EphemerisTable + SPICE 时间轴,state_at(t) 线性插值。

变量:

t_start/t_end -- 星历时间轴覆盖范围(et 秒)

参数:
property t_start: float
property t_end: float
state_at(t)[源代码]

t(et 秒)时刻的标称状态(GCRS,km, km/s),逐分量线性插值。

参数:

t (float)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

class e2m2e.algorithm.station_keeping.monte_carlo.RustPropagator(observer, forces_py, rtol=1e-10, atol=1e-10, max_step=3600.0, max_steps=500000)[源代码]

基类:object

Rust 编译力模型传播器(StmPropagator 实现,单样本)。

直接调 propagate_compiled*_py (不经 ForceModel),绕开其 STM 路径对 SRP 的排除(站保控制模型含光压,STM 必须含光压贡献;Rust 侧 已补 SRP 雅可比,见 compiled.rs::acceleration_and_jacobian)。

参数:
propagate_with_stm(state0, t0, t_eval)[源代码]
参数:
  • state0 (ArrayLike)

  • t0 (float)

  • t_eval (ArrayLike)

返回类型:

dict[str, ndarray[tuple[Any, ...], dtype[floating]]]

propagate(state0, t0, t_eval)[源代码]

无 STM 传播,返回 (n, 6) 状态序列。

走 STM 传播路径(propagate_compiled_stm_py):propagate_compiled 的步长无上限,稀疏 t_eval 下自适应步长失控(实测 2 点 vs 31 点 网格 30 天结果差 22 万 km);STM 路径受 max_step 限制,网格 无关。STM 计算为附带成本。

参数:
  • state0 (ArrayLike)

  • t0 (float)

  • t_eval (ArrayLike)

返回类型:

ndarray[tuple[Any, ...], dtype[floating]]

class e2m2e.algorithm.station_keeping.monte_carlo.SampleResult(total_delta_v_mps, max_delta_v_mps, failed, maneuver_times, maneuver_dv_mps, controlled_times, controlled_states, attitude_delta_v_mps=0.0, attitude_delta_v_independent_mps=0.0)[源代码]

基类:object

单样本蒙特卡洛结果。

变量:
  • total_delta_v_mps (float) -- 总 Δv(m/s),角动量管理模式含轨道+姿态联合 Δv

  • max_delta_v_mps (float) -- 最大单次 Δv(m/s)

  • failed (bool) -- 是否控制失败(单次 > Δv_max 或累计 > 总上限)

  • maneuver_times (numpy.ndarray[tuple[Any, ...], numpy.dtype[numpy.floating]]) -- 控制时刻(et 秒),形状 (n,)

  • maneuver_dv_mps (numpy.ndarray[tuple[Any, ...], numpy.dtype[numpy.floating]]) -- 各控制时刻施加的 Δv(m/s),形状 (n,)

  • controlled_times (numpy.ndarray[tuple[Any, ...], numpy.dtype[numpy.floating]]) -- 受控星历时间(et 秒),形状 (m,)

  • controlled_states (numpy.ndarray[tuple[Any, ...], numpy.dtype[numpy.floating]]) -- 受控真实轨道状态(GCRS,km, km/s),形状 (m, 6)

  • attitude_delta_v_mps (float) -- 姿态总 Δv(m/s),仅角动量管理模式非零

  • attitude_delta_v_independent_mps (float) -- 姿态不影响轨道时的 Δv(m/s),即 纯角动量卸载(不含轨道控制贡献)的 Δv 累计量

参数:
total_delta_v_mps: float
max_delta_v_mps: float
failed: bool
maneuver_times: ndarray[tuple[Any, ...], dtype[floating]]
maneuver_dv_mps: ndarray[tuple[Any, ...], dtype[floating]]
controlled_times: ndarray[tuple[Any, ...], dtype[floating]]
controlled_states: ndarray[tuple[Any, ...], dtype[floating]]
attitude_delta_v_mps: float = 0.0
attitude_delta_v_independent_mps: float = 0.0
class e2m2e.algorithm.station_keeping.monte_carlo.SingleSampleSimulation(nominal, law, control_interval_sec, num_controls, output_step_sec, nav_error, thrust_error, srp_error, thrust_total_mps, factory, force_config_ctrl, force_config_true, sampler, engine_layout=None, momentum_interval_sec=0.0, srp_offset_m=None, spacecraft_mass_kg=1000.0, srp_torque_nm=None)[源代码]

基类:object

单样本闭环仿真(三轨道结构 + 分段控制误差 + 光压弧段误差)。

变量:
参数:
nominal: NominalOrbit
law: Any
control_interval_sec: float
num_controls: int
output_step_sec: float
nav_error: NavigationErrorModel
thrust_error: ThrustExecutionError
srp_error: SrpErrorModel
thrust_total_mps: float
factory: PropagatorFactory
force_config_ctrl: dict[str, Any]
force_config_true: dict[str, Any]
sampler: BoxMullerSampler
engine_layout: Any = None
momentum_interval_sec: float = 0.0
srp_offset_m: ndarray[tuple[Any, ...], dtype[floating]] | None = None
spacecraft_mass_kg: float = 1000.0
srp_torque_nm: ndarray[tuple[Any, ...], dtype[floating]] | None = None
run()[源代码]
返回类型:

SampleResult

e2m2e.algorithm.station_keeping.monte_carlo.run_monte_carlo(nominal_ephemeris, *, spice, system, force_config_ctrl, force_config_true, control_mode=1, special_mode=1, special_crossings=3, control_interval_days=30.0, feedback_arc_days=28.0, num_controls=120, num_monte_carlo=5, output_step_sec=86400.0, position_accuracy_m=1500.0, velocity_accuracy_mps=0.002, thrust_angle_err_deg=0.333, thrust_mean_mps=10.0, thrust_rel_err=0.003, thrust_abs_err_mps=0.033, thrust_min_mps=0.1, thrust_max_mps=100.0, thrust_total_mps=1000.0, srp_error_level=0.1, seed=None, n_workers=1, kernel_dir=None, engine_layout=None, momentum_interval_days=0.0, srp_offset_m=None, spacecraft_mass_kg=1000.0, srp_torque_nm=None, tight_tolerance_km=0.1, tight_max_iter=6, special_damping_factor=1.0)[源代码]

运行蒙特卡洛站保仿真(DFH 功能码 2 的数值核心)。

参数:
  • nominal_ephemeris (EphemerisTable) -- 标称轨道星历(FR1 design_orbit 产物)

  • spice (Any) -- SPICE 管理器(n_workers>1 时仅用于构造标称视图)

  • system (Any) -- 星历动力学系统(地心 ICRF)

  • force_config_ctrl (dict[str, Any]) -- 控制(理论)力模型配置(表 5-3 左列)

  • force_config_true (dict[str, Any]) -- 真实(实际)力模型配置(表 5-3 右列)

  • control_mode (int) -- 1=目标点宽松、2=目标点严格、3=特征点

  • special_mode (int) -- 特征点模式 1=Lissajous、2=Halo/NRHO

  • special_crossings (int) -- 特征点目标穿越次数

  • control_interval_days (float) -- 控制时间间隔(天)

  • feedback_arc_days (float) -- 目标点模式反馈弧段(天)

  • num_controls (int) -- 控制次数(总时间 = (N-1)·间隔)

  • num_monte_carlo (int) -- 蒙特卡洛样本数

  • output_step_sec (float) -- 受控星历输出间隔(秒)

  • position_accuracy_m/velocity_accuracy_mps -- 测定轨 1-sigma

  • thrust_* -- 分段控制误差参数(§1.5.2)

  • srp_error_level (float) -- 光压弧段随机误差量级(百分比/100)

  • seed (int | None) -- 随机种子(同种子同结果)

  • n_workers (int) -- 进程池大小(>1 时样本并行;需 kernel_dir 供 worker 重建 SPICE 上下文)

  • kernel_dir (str | None) -- SPICE 内核目录(n_workers>1 时必填)

  • engine_layout (Any) -- EngineLayout 实例(None 表示无角动量管理)

  • momentum_interval_days (float) -- 角动量卸载间隔(天),0 表示与轨道控制同步

  • srp_offset_m (ArrayLike | None) -- SRP 压心相对质心偏移(m)

  • spacecraft_mass_kg (float) -- 航天器质量(kg)

  • srp_torque_nm (ArrayLike | None) -- 常值 SRP 力矩(N·m)

  • position_accuracy_m (float)

  • velocity_accuracy_mps (float)

  • thrust_angle_err_deg (float)

  • thrust_mean_mps (float)

  • thrust_rel_err (float)

  • thrust_abs_err_mps (float)

  • thrust_min_mps (float)

  • thrust_max_mps (float)

  • thrust_total_mps (float)

  • tight_tolerance_km (float)

  • tight_max_iter (int)

  • special_damping_factor (float)

返回:

MonteCarloResult (含 SK_STATISTIC/MANEUVERS 组装方法)

返回类型:

MonteCarloResult