PCR 重构:装配根、Plant Scope 与总线抽象实现细节
1. 配置层:Runner 是唯一的装配根(Composition Root)
Runner 是链接“编译能力”与“运行配置”的终点。配置层划分为:
text
data/input/sim/
├── deployments/
│ ├── sil_monolithic.yaml # 所有组件在本机
│ ├── dyn_node.yaml # 只装 Plant + Dynamics,FCC 在远端
│ └── fcc_node.yaml # 只装 FCC,Plant 在远端
├── missions/ # 任务脚本(见第 4 点)
│ ├── nominal_ascent.yaml
│ ├── static_fire_test.yaml
│ └── sit_ground_test.yaml
├── worlds/ # 环境真相(风场、大气、发射场)
│ ├── standard_atmosphere.yaml
│ ├── gale_wind.yaml
│ └── launch_site_wenchang.yaml
└── runs/ # 具体运行的装配清单
└── run_001.yaml # 引用 deployment + mission + world + rocket_version关键洞察:链接决定“能力上限”,配置决定“能力用多少”
同一个 SIL 二进制可以通过切换 run_xxx.yaml 来模拟不同部署。启动流程:
cpp
// runtime/runner.cpp
int main(int argc, char** argv) {
auto run = load_run_yaml(argv[1]); // run_001.yaml
auto depl = load_deployment(run.deployment); // sil_monolithic.yaml
RunContext ctx;
if (depl.has_plant) ctx.plant = load_plant(run.rocket_version);
if (depl.has_dynamics) ctx.dynamics = load_mission(run.mission);
if (depl.has_fcc) ctx.fcc = load_fcc_config(run.rocket_version);
if (depl.has_world) ctx.world = load_world(run.world);
apply_overrides(ctx, run.overrides);
// 编译期已选定模板,运行期选择 Transport 参数
auto bus = make_bus(depl.transport);
// 装配
auto assembled = assemble(ctx);
run_simulation(assembled, bus);
}2. Plant Scope 概念:一套真相,三种视图
Plant 物理真相始终唯一,但不同部署下实例化的子集不同:
cpp
// plant_model 层
struct PlantScope {
bool include_physics_bodies; // 气动、推力、质量 → 要积分的
bool include_hardware_engines; // 发动机状态机
bool include_hardware_sensors; // IMU/GPS 状态演化
bool include_hardware_icus; // ICU 状态机
bool include_bus_endpoints; // 本机驻留的总线节点集合
std::vector<uint32_t> local_bus_addresses; // 本机承载的地址
std::vector<uint32_t> remote_bus_addresses; // 需要通过 Transport 代理的
};在 HIL 部署中,远端地址会被装配为 BusProxy(如 UdpBusProxy),使得本地 ICU 无法区分 FCC 是本地还是远端——这就是 Transport 抽象的价值。
3. Assembler 输出:可反射的装配树(前端数据模型)
AssembledPlant 既是热路径数据,又是自省式树(introspectable tree):
cpp
// plant_model 层
struct AssembledNode {
std::string kind; // "EngineGroup", "Icu", "ImuUnit"
std::string display_name; // "一级助推器发动机组"
std::string path; // "/rocket/propulsion/stage_1_group"
std::map<std::string, Value> parameters; // YAML 原始参数
std::vector<AssetRef> assets; // 曲线/表格引用
std::vector<std::string> controlled_by; // 拓扑关联:控制者
std::vector<std::string> controls; // 拓扑关联:被控对象
std::map<std::string, Value> mutable_initial_state; // 加注量、惯组误差等
};
struct AssembledPlant {
std::vector<AssembledNode> nodes;
std::unordered_map<std::string, size_t> path_index;
RuntimeTables runtime; // O(1) uint32 索引热路径视图
};4. Mission × Rocket × World 三正交维度
stages.yaml 属于 Mission 属性而非 Rocket 属性。
- Mission:定义初始状态、动力学约束(如
pinned)、事件机、传感器数据注入。 - 正交组合:
Run = Rocket × Mission × World × Deployment。
例如:同一枚火箭,在“名义飞行”任务中包含分离事件,在“静态点火”任务中则是固定在架位上(约束自由度),无分离事件。
5. 代数效应与 BodyStageAlgebra
BodyStageAlgebra 是声明式的操作集合,YAML 驱动,C++ 解释。
cpp
enum class StageOp {
IgniteEngines { slots: [...] },
ShutdownEngines { slots: [...] },
TransitionAerodynamicModel { from: ascending, to: descending },
SplitBody { into: [...], sep_plane: ... },
};
struct StageTransition {
StageTag from;
EventMatcher trigger;
std::vector<StageOp> ops;
StageTag to;
};6. HardwareState 与 HardwareOutput 的单子链演化
硬件层遵循 Mealy 机模式:
cpp
// 长期存在的内部状态(跨 tick 累积)
struct HardwareState {
std::map<uint32_t, EngineFsm> engine_fsms;
std::map<uint32_t, double> icu_delay_timers; // 处理如 1s 延时分离
std::map<uint32_t, ImuBias> imu_biases;
};
// 本 tick 的瞬时产出
struct HardwareOutput {
std::vector<EngineEffect> engine_effects;
std::vector<BusMessage> emitted_bus_messages;
std::vector<TopologyEvent> topology_events; // 由状态机演化产生(如延时到期)
};
// 演化规则
std::pair<HardwareState, HardwareOutput>
step_hardware(const HardwareState& prev, const std::vector<BusMessage>& incoming, const BodyPhysicalState& phys, Time dt);三相管线单子链(Monad Chain):
- Phase 1: Hardware:硬件状态演化 -> 产出
HardwareOutput。 - Phase 2: Physics:通过 Reader 注入
HardwareOutput计算力 -> 积分导数。 - Phase 3: Topology & Bus:消费
topology_events改变 body 集合,路由消息。
7. Bus 在不同部署下的角色
Bus 是跨场景的枢纽,所有节点只对 Bus 地址可见。
| 模式 | Transport 实现 | 消息特征 | 用途 |
|---|---|---|---|
| SIL | MemoryTransport | 原生 C++ 结构体,零拷贝 | 验证算法,回归测试 |
| Dyn-HIL | UdpTransport | UDP 序列化,跨机通信 | FCC 实时机联调 |
| FCC-HIL | CanTransport | CAN 帧编码,硬件总线 | 飞控软件压力测试 |
代码通过模板 Transport 保持完全一致:Bus<MemoryTransport> vs Bus<UdpTransport>。