Skip to content

火箭推力计算流程详解 (Thrust Calculation Pipeline)

概述 (Overview)

推力系统遵循 5 阶段数据流:YAML 配置 → CSV 表格加载 → 发动机状态机 → 真空推力查表 → 动力学力管线。它跨越了三个命名空间(io, rocket, dynamics),并使用单子化(Monadic)的 BodyRWS 架构进行纯函数式组合。


阶段 1:配置加载 (Configuration Loading: YAML → Structs)

入口点 (Entry Point): data/input/rocket_v1/rocket.yaml:19-20

yaml
devices: "devices.yaml"

火箭配置引用外部的 devices.yaml 文件。

设备配置 (Device Config): data/input/rocket_v1/devices.yaml:1-55

COMPOSITE 键下定义发动机组。每台发动机包含:

  • id — 例如 "center_engine", "peripheral_engine_1"
  • rated_thrust — 标称真空推力 (牛顿),中心发动机为 679700.0,周向为 693357.143。
  • install — 物理安装几何(万向节限位、方位角、安装角、执行器偏差、轴向/径向偏移)。
  • tables — 6 个用于插值曲线的 CSV 文件路径。

加载链 (Loading Chain):

  1. BodyAsset::load_from_yaml() (src/dynamics/config/BodyAsset.cpp:48-52) 检测到 devices 键,解析路径并委托给:
  2. EngineConfig::load_from_yaml() (src/rocket/device/actuator/EngineConfig.cpp:31-106)
    • 递归处理标量节点(文件引用)(35-39 行)。
    • 解析顶层常量:rated_thrust_center, rated_thrust_peripheral, skip_liftoff_time_calculation, real_liftoff_time
    • 迭代映射键作为阶段组名(48 行)。
    • 为每个组解析可选的 deviations(4 元素数组,56-62 行)和 engines 列表。
    • 为每个发动机节点构建 EngineUnitConfig(70-101 行):
      • 解析 InstallParams(75-81 行)。
      • 通过 CSVReader::load_table_1d() 加载 6 个 CSV 表到 shared_ptr<InterpTable1D>(93-98 行)。
    • 填充 engine_groups[key](分组)和 engines(平铺列表)。

核心结构体 (Key Structs):

InstallParams (src/rocket/device/actuator/EngineConfig.h:19-26):

cpp
struct InstallParams {
    double gimbal_limit;              // rad
    double location_angle;            // 喷管方位角 (rad)
    double gimbal_install_angle;      // 喷管安装角 (rad)
    double actuator_install_deviation; // 舵机扭转偏差 (rad)
    double x_offset;                  // 距离头部的轴向偏移 (m)
    double z_offset;                  // 径向偏移 (m), 中心发动机为 0
};

EngineUnitConfig (src/rocket/device/actuator/EngineConfig.h:31-43):

cpp
struct EngineUnitConfig {
    std::string id;
    InstallParams install;
    double rated_thrust;
    shared_ptr<InterpTable1D> thrust_start;     // 起动推力曲线
    shared_ptr<InterpTable1D> thrust_stop;      // 关机推力曲线
    shared_ptr<InterpTable1D> mass_flux_start;  // 起动质量流
    shared_ptr<InterpTable1D> mass_flux_stop;   // 关机质量流
    shared_ptr<InterpTable1D> perturb;          // 摄动系数
    shared_ptr<InterpTable1D> params;           // 运行参数 vs 推力
};

EngineConfig (class) (src/rocket/device/actuator/EngineConfig.h:51-75):

cpp
class EngineConfig {
    map<string, vector<EngineUnitConfig>> engine_groups;     // 按阶段分组
    map<string, array<double,4>> stage_deviations;           // 摄动种子
    vector<EngineUnitConfig> engines;                        // 平铺列表
    bool skip_liftoff_time_calculation = false;
    double real_liftoff_time = 0.0;
    double rated_thrust_center = 0.0;
    double rated_thrust_peripheral = 0.0;
};

阶段 2:CSV 表格加载与插值 (CSV Table Loading & Interpolation)

CSV 读取器 (CSV Reader): src/io/reader/CSVReader.h:26-68

CSVReader::load_table_1d() 读取 CSV 文件,其中第 0 列是自变量 (x),第 1..N 列是因变量 (y)。跳过以 # 开头或为空的行。

InterpTable1D: src/io/types/InterpTable1D.h:23-157

核心插值表功能:

  • x_values — 断点。
  • y_columns — 多个输出列。
  • interpolator(col_index) — 返回单列查找的 std::function<double(double)> 闭包。
  • all_interpolator() — 返回一次性查找所有列的 std::function<vector<double>(double)> 闭包。
  • 使用 线性插值 并在边界处钳位(139-156 行):
    • 低于最小 x → 返回第一个 y。
    • 高于最大 x → 返回最后一个 y。
    • 否则 → y0 + t * (y1 - y0),其中 t = (x - x0) / (x1 - x0)

每个发动机的 6 张 CSV 表:

表名 (Table)X 轴 (X-axis)Y 列 (Y-columns)用途 (Purpose)
thrust_start时间 (s)推力 (N)起动爬升过程 (0→3s,随后稳定)
thrust_stop时间 (s)推力 (N)关机衰减过程 (0→1s)
mass_flux_start时间 (s)燃料 (kg/s), 氧化剂 (kg/s)起动过程质量流
mass_flux_stop时间 (s)燃料 (kg/s), 氧化剂 (kg/s)关机过程质量流
params推力 (N)参考推力, Isp, 燃料流量, 氧化剂流量以推力水平索引的运行参数
perturb油门比 (throttle ratio)12 个摄动系数小偏差修正矩阵

示例: center_thrust_start.csv 显示推力从 t=0.7s 时的 0N 爬升至 t=3.0s 时的 679723N。


阶段 3:发动机状态机与真空输出 (Engine State Machine & Vacuum Output)

发动机状态 (Engine States): src/rocket/device/actuator/EngineState.h:11-16

OFF → STARTING → RUNNING → SHUTTING_DOWN → OFF

状态机 (State Machine): EngineModel::evaluate_phase() (src/rocket/device/actuator/EngineModel.h:14-60)

  • 处理 BusMessage 命令以触发状态转换。
  • OFF + cmd_activeSTARTING (elapsed_time = 0 或 real_liftoff_time)。
  • STARTING + !cmd_activeOFF
  • RUNNING + !cmd_activeSHUTTING_DOWN
  • 自动转换:STARTING 3.0s 后 → RUNNINGSHUTTING_DOWN 1.0s 后 → OFF

真空输出 (Vacuum Output): EngineModel::evaluate_vacuum_output() (src/rocket/device/actuator/EngineModel.h:63-110)

这是核心推力查表逻辑,根据发动机相位分支:

  • STARTING: vacuum_thrust = throttle * thrust_start.interpolate(elapsed_time),质量流从 mass_flux_startbase_t 索引。
  • RUNNING: vacuum_thrust = throttle * rated_thrust,质量流从 params 第 2, 3 列按 base_t 索引。
  • SHUTTING_DOWN: vacuum_thrust = throttle * thrust_stop.interpolate(elapsed_time),质量流从 mass_flux_stopbase_t 索引。
  • OFF: 全部为 0。

返回一个 EngineEffect 结构体。

EngineEffect: src/rocket/interface/PhysicalEffect.h:13-25

cpp
struct EngineEffect {
    uint32_t engine_id;
    double vacuum_thrust;
    double mass_flow_fuel;
    double mass_flow_ox;
    double current_throttle;
    Angle nozzle_pitch;
    Angle nozzle_yaw;
};

阶段 4:动力学推力管线 (Dynamics Thrust Pipeline: BodyRWS)

EngineEffect 向量跨越火箭→动力学边界并进入 compute_thrust_pipeline()

管线 (Pipeline): src/dynamics/pipeline/Thrust.cpp:145-153

apply_perturbation → compensate_ambient_pressure → resolve_thrust_vectors

三个单子化阶段使用 >> (bind) 链式调用:

4a. 摄动修正 (Perturbation Correction): Thrust.cpp:40-85

  • 通过 body.body_idEngineConfig 查找 stage_deviations (4 元素数组: [δφ, δψ, δγ, δx])。
  • 对于每个 vacuum_thrust > 0 且具有有效 perturb/params 表的发动机:
    1. 通过 perturb->all_interpolator()current_throttle 处插值所有 12 个摄动系数。
    2. 使用 4 个偏差参数与系数子集的点积计算 3 个修正量:
      • dF = Σ(stage_dev[i] * coeffs[0..3]) — 推力修正。
      • dMf_f = Σ(stage_dev[i] * coeffs[4..7]) — 燃料流量修正。
      • dMf_ox = Σ(stage_dev[i] * coeffs[8..11]) — 氧化剂流量修正。
    3. params 表获取参考推力。
    4. 应用:vacuum_thrust = vacuum_thrust + dF - ref_thrust

4b. 环境压力补偿 (Ambient Pressure Compensation): Thrust.cpp:88-105

  • AeroCtx 读取 static_pressure
  • 对于每个发动机:actual_thrust = vacuum_thrust + Sa * (101325.0 - pressure)
    • Sa = 0.6578 (喷管出口面积 m²,目前硬编码 — 95 行标记为 TODO)。
    • 这是标准的喷管出口面积压力修正:在海平面 (101325 Pa) 补偿值为 0;在真空下增加 Sa * 101325 N。

4c. 矢量分解与力矩 (Vector Resolution & Torque): Thrust.cpp:108-141

对于每台发动机:

  1. 喷管坐标系推力矢量 (Thrust.cpp:11-16): F_nozzle = magnitude * [cos(gz)*cos(gy), sin(gz)*cos(gy), -sin(gy)] 其中 gy = 万向节偏航 (yaw),gz = 万向节俯仰 (pitch)(来自舵机)。
  2. 喷管到体轴旋转 (Thrust.cpp:18-21): R = transpose(Rz(τ) * Ry(r) * Rx(φ)) 其中 φ = location_angle, r = gimbal_install_angle, τ = actuator_install_deviation
  3. 体轴系作用力: F_body = R * F_nozzle
  4. 力臂 (Thrust.cpp:23-25): lever = [centroid_x - x_offset, 0, z_offset] 其中 centroid_x 是来自 body.inertial_state.centroid 的当前质心位置。
  5. 力矩: torque = lever × F_body
  6. 累加: 将所有发动机的 F_bodytorque 累加到 ThrustAndMassFlux.ft,并求和所有质量流。

输出类型 (Output Types): src/dynamics/interface/PhysicalTypes.h:1-64

cpp
struct ThrustAndMassFlux {
    vector<EngineForceState> engine_states;  // 单个发动机结果
    ForceAndTorque ft;                       // 体轴系总力和力矩
    MassFluxResult mf;                       // 总/燃料/氧化剂质量流
};

阶段 5:整合至物理注册表 (Integration into PhysicalRegistry)

src/dynamics/pipeline/PhysicalRegistry.cpp:13-97

WorldRWS 编排器逻辑:

  1. 并行分发 (Parallel dispatch) (30-78 行): 为每个物体启动 std::async:
    • 探测上下文:TrajectoryCtx, AeroCtx, MassPropsCtx
    • 注入包含资产(包含 EngineConfig)、探测到的上下文和时间的 BodyEnv
    • 构建管线:Forces::zero() >> compute_thrust_pipeline >> compute_aero_forces >> compute_gravity_forces
    • 推力结果累加至 Forces:
      cpp
      next_f.total_force_b += res.ft.force;
      next_f.total_moment_b += res.ft.torque;
      next_f.d_mass_dt += res.mf.total;
      next_f.d_fuel_dt += res.mf.fuel;
      next_f.d_oxidizer_dt += res.mf.oxidizer;
  2. 合并 (Merge) (80-94 行): 收集 futures,更新 WorldState.bodies,通过单子加法合并 DynLog

环境注入路径 (Environment Injection Path):

WorldEnv.body_assets["COMPOSITE"].engines (EngineConfig)BodyEnv.asset.engines → 动力学内核通过 body_ask() → env.asset.engines.engines[i] 访问。


数据流简图 (Summary Data Flow Diagram)

YAML (devices.yaml)
  └→ EngineConfig::load_from_yaml()
       └→ CSVReader::load_table_1d() × 每台发动机 6 张表
            └→ InterpTable1D (带边界钳位的线性插值)

BusMessage (点火命令)
  └→ EngineModel::evaluate_phase()         [状态机: OFF→STARTING→RUNNING→SHUTTING_DOWN]
       └→ EngineModel::evaluate_vacuum_output()  [基于相位和油门的查表]
            └→ EngineEffect {真空推力, 质量流, 喷管角度}

EngineEffect[]
  └→ compute_thrust_pipeline()             [BodyRWS 单子链]
       ├→ apply_perturbation()             [基于摄动表的小偏差修正]
       ├→ compensate_ambient_pressure()    [F = F_vac + Sa*(P0 - P_atm)]
       └→ resolve_thrust_vectors()         [喷管→体轴旋转, 力臂, 力矩]
            └→ ThrustAndMassFlux {体轴力, 体轴力矩, 质量流}

PhysicalRegistry (WorldRWS)
  └→ 累加至 Forces → 馈送给 ODE 积分器