PCR-arch 代码审计报告 (2026-05-08)
一、被删除或降级的关键计算逻辑
1. FCC 完全被拆空 (src/fcc/FccCore.cpp: 241 → 7 行)
FccOutFrame run_fcc_step(const FccInFrame& in, FccState& state, const FccEnv& env) {
return FccOutFrame{};
}原分支的 Free Monad 解释器、Navigation/Guidance/Control 管线、Stage FSM 路由、Shutdown 逻辑、Interrupt handling 全部移除。src/main/closed_loop_10s.cpp 里也不再调用 FCC,整个"闭环"实际上是纯被动弹道积分。
2. plant/physics/Drag.cpp (137 → 44 行)
被删除:
compute_ascending_aero/compute_descending_aero的完整 6 分量(力+力矩)查表aero_coeffs_ascending/aero_coeffs_descending表驱动(含零位、俯仰、偏航、滚转小偏差)- 栅格舵(grid fin)舵偏注入
- 绕质心的力矩修正项
(0.0 - centroid) * F_y/F_z FAI_Q → PHI_A下降段坐标转换- Aero→Body1→Body2 的三次坐标变换矩阵
被替换为:hard-coded Cd(Mach) 折线(0.42~0.65 之间),只算轴向阻力标量,以 ecf_pos.magnitude() < 6400000 判断上升/下降(这实际是海平面以下的判据,并非返回段判据)。
3. plant/physics/Thrust.cpp (158 → 46 行)
被删除:
- 小偏量修正 (
apply_perturbation),即stage_dev × perturb_coeffs推力-流量扰动 - 喷管→本体的旋转矩阵
Rz(tau)·Ry(r)·Rx(phi).T,基于location_angle, gimbal_install_angle, actuator_install_deviation——外侧发动机的推力方向因此会被错误算成轴向 - 关于当前质心的力臂:旧版
lever = (centroid.x - install.x_offset, 0, install.z_offset);新版退化为mount_pos_body.cross(f_body),完全忽略瞬时质心,力矩会有系统性偏差 - 正确的背压补偿基准
nozzle_area * (design_back_pressure - p_amb),新版仅-p_amb * area
4. plant/physics/FlightStateProber.cpp (104 → 61 行)
被删除:
- 100 km 卡门线气动截断 — 新版在轨道段会继续吃非零动压
- 全部气动角计算
alpha_A, alpha, beta, FAI_Q— 即便将来恢复查表,入参也已缺失 - 流向符号翻转:旧版
flow_lic = -(v_rel_earth - v_wind)(来流方向,与飞行方向相反),新版v_air_lic = v_rel_earth - v_wind(飞行空速方向)。配合新 Drag 的flow_dir * drag_mag,阻力现在沿飞行方向加速火箭而非减速。
同时 Assembler.cpp 给出的 mach_number = [](double v, double h){ return v/340.0; } 参数顺序与调用点 env.atmosphere.mach_number(h, v_mag) 相反。
5. plant/physics/Gravity.cpp
新版用 μ/r² 的 ECF 中心引力(形式上比旧版的 -9.80665 占位更好),但自注释承认直接把 ECF 向量塞进 gravity_lic——t=0 之后发射点随地球转动,误差越积越大。
6. dynamics/PhysicalRegistry.cpp
- 没有 Hardware Phase 1(发动机 FSM 步进、ICU Mealy、SCU 伺服)
engine_effects必须外部注入,而closed_loop_10s.cpp传入{}——火箭永远不会点火update_inertial_properties里engine_mass = 50.0硬编码、inertia = I·(m·10)写死单位阵const_cast<runtime::WorldEnv&>(env).bus.publish(...)粗暴破坏 Reader monad 的 const 约束- 没有
TopologyEvent的产生/消费循环
7. 保留未退化的部分
ode/EquationsOfMotion.cpp:RK4 导数、pack/unpack、欧拉方程、四元数导数、pad-clamp 约束 — 几乎逐行保留ode/Integrator.cpp的integrate_euler/integrate_rk4— 完全一致types/,Frames.h, Monad RWS infrastructure — 基本不变
二、相对 Refactoring 文档的架构落实度(以 Blueprint 为主依据)
| 文档承诺 | 代码现状 | 落实度 |
|---|---|---|
八层静态库 truth/plant_model/plant_physics/plant_hardware/bus/fcc/dynamics_core/runtime | 目录已创建但内容分布混乱:src/plant/ 仍是主力,src/plant_model/ 只有 2 个 header,src/plant_hardware/ 空,src/dynamics_core/ 只有一个未引用的 StageMachine.h | 30% |
强类型 BusMessage{src, dst, emitted_at, variant<Imu/Gps/Scu/IcuPayload>} | 在 src/bus/IBus.h + BusPayloads.h + TransparentBus.h 定义(namespace pcr::bus),但这些头 #include "src/types/Vector.h"(不存在)和 "src/types/Time.h"(路径错),根本不会被编译进任何 target。真正使用的仍是老的 bus::BusChannel(namespace bus,std::vector<double> payload + SignalTag)。两个平行的"总线宇宙"共存。 | 20% |
| 三相管线 (Hardware FSM → Physics → Integration+Topology+Route) | 只有 Phase 2。Phase 1 被删,Phase 3 仅保留 integrate | 33% |
dynamics_v1/stages.yaml 声明式 per-body 阶段机 | 没有 YAML;BodyStageAlgebra 只有 SeparationOp 和 IgnitionOp 的 std::variant 硬编码,且 IgnitionOp 分支是 no-op | 10% |
Run = Rocket × Mission × World × Deployment 四维正交装配 | 只有 data/input/world/;没有 missions/、deployments/、runs/;Assembler 从单一 world.yaml 入口装配,没有 Deployment 模板 | 25% |
AssembledPlant reflectable tree + RuntimeTables(slot→spec、slot→ICU 全 uint32 O(1)) | Assembler.cpp 只填充 BodyAsset.engines(字符串 id + 基本几何)。没有 slot_to_spec、icu_to_slots、RuntimeTables | 15% |
Bus<MemoryTransport> 模板化 Transport 编译期绑定 | TransparentBus 是 vtable 版(没问题),但没有 UDP/CAN 配套,也没有按 Transport 模板化 | 25% |
AvionicsAction::ActivateClone / Continue / None 在分离时深拷贝 FCC 状态 | 完全缺失 — BodyStageAlgebra::evolve_topology 只复制几何与 engines_state,不涉及 FCC/Bus 继承 | 0% |
| FCC 可独立链接至 RTOS(八层库里最重要的可移植目标) | FCC 被掏空,无法作为独立库承担任何任务 | 0% |
三、对新实现的困惑与潜在问题
FCC 的 7 行 stub:是阶段性"先让动力学侧编译过"的占位,还是
free_monad/子系统迁移到pcr::bus::IcuPayload/ScuPayload还没完成?src/fcc/core/Navigation.cpp、guidance/Guidance.cpp、control/Control.cpp等文件都还在,但被FccCore.cpp绕过。恢复路径是什么?两套 Bus 并存:
pcr::bus::的三个头文件(符合 Blueprint)根本编不过(include 路径src/types/Vector.h不存在),但文件在CMakeLists.txt里是列出的?同时runtime::WorldEnv里嵌的是老的bus::BusChannel。哪一个是"正朔"?建议是要pcr::bus::IBus成为唯一入口,bus::BusChannel作为 deprecated。flow_in_body符号翻转:这是 bug 还是 Drag.cpp 将来会配合地改?目前是静默的物理错误——火箭会被"阻力"推着走,但数值不会爆,很难在 regression test 里发现。closed_loop_10s.cpp其实是纯被动弹道:主循环里engine_effects = {},不调用 FCC,但 stage_name 被硬写成"BOOSTER"。命名误导。要不要改成ballistic_integrator_smoke_test.cpp直到闭环真正恢复?update_inertial_properties的魔法常数:engine_mass=50、I = m·10·I3,完全绕过 YAML 的inertia_table。是 PoC 范围内接受的简化,还是待做?这会直接影响 RK4 的转动积分稳定性。Gravity 的 ECF 直接塞进
gravity_lic:注释说"为了过编译先这样"。FrameConfig里有ecf_to_lic_matrix(t)吗?我在WorldEnv.h里没看到,这个 TODO 该怎么闭合?dynamics_core/StageMachine.h的身份:这个头定义了BodyStageTag{ASCENT_BOOST, ASCENT_COAST, DESCENT_BALLISTIC, DESCENT_AERO_BRAKING, LANDING_BURN},和 PoC 文档 §2.1 里的prelaunch / engine_startup / power_ascend / descent_ballistic / descent_powered / coast_to_ignition / upper_ascend不一致,并且没有被任何.cpp引用。是废弃草稿还是还没 wire up?Mission 域完全缺席:PoC §1 定义的
Mission维度(初始约束pinned、分离事件列表、传感器注入)在data/input/里找不到对应 YAML,也没有MissionConfigC++ 类型。这是不是整个 PoC 还没开始动的一大块?const_cast<runtime::WorldEnv&>(env).bus.publish:这里把 const Reader 环境强行改写,等于默认 WorldEnv 里的bus/monitor是可变的单例,违背"Reader 只读"原则。切到pcr::bus::TransparentBus后,IBus*指针本身可以 const,但底层 mailbox 仍需可变——是否在 PlantScope/RuntimeContext 里单独拿出来、不塞在WorldEnv这一 Reader?
四、总体判断
pcr-arch 分支是一次结构性框架落地 + 计算逻辑临时搁置的提交:
- 结构分层雏形建立:目录拆分、namespace、
plant_model / plant_physics / plant_hardware / bus / runtime / dynamics_core架构已初步可见。 - 类型骨架搭建:
ForcesMonoid、BodyEnv、runtime::WorldEnv、BodyStageAlgebra、pcr::busvariant payload 等基础设施已就绪。 - 计算逻辑断档:
Thrust / Drag / FlightStateProber / Gravity四大物理 kernel、FCC全家桶、Hardware FSM/ICU/SCU、Mission+Deployment 四维正交配置,目前处于占位或严重简化状态。