Files
SystemSimulationApp/docs/standard/system-xml-v3.md
T

12 KiB
Raw Blame History

System XML v3 协议

System XML v3 是 SystemSimulationApp 当前唯一的 XML 求解输入格式。它只描述可执行模型,不再承担 ReactFlow 画布存档职责。

机器可读结构见 schemas/system-simulation-v3.xsd。当前校验、解析、编译和仿真接口固定按 v3 处理,不会根据 schemaVersion 自动切换到 v1 或 v2。

1. 设计边界

v3 遵循一条简单规则:

XML 保存“求解什么”,工程 JSON 保存“怎样编辑和显示”。

因此 XML 保留:

  • 仿真起止时间、结果采样间隔、内部最大步长和积分方法;
  • 组件实例 ID、后端模型类型、模型版本和完整 SI 参数;
  • 每条连接的两个端点。

XML 不保存:

  • 组件显示名称、画布坐标、旋转、镜像;
  • 图标、端口显示侧和显示顺序;
  • 端口的 kind/domain/nominalRole/positiveFlowDirection/variables 快照;
  • 参数表达式、显示单位、科学记数法偏好;
  • ReactFlow 的选择状态、撤销历史或仿真结果。

这些信息中,编辑器状态留在工程 JSON;端口物理合同由 Component.type + Endpoint.port 从后端组件注册表恢复。

2. 完整结构示例

下面的例子包含一条信号连接和一条机械连接,展示 v3 的全部结构元素:

<?xml version="1.0" encoding="UTF-8"?>
<System name="signal-force-demo" schemaVersion="3" unitSystem="SI">
  <Simulation
      tStart="0"
      tStop="1"
      sampleStep="0.01"
      maxStep="0.001"
      method="BDF"/>

  <Components>
    <Component id="step_1" type="amesim_step0" modelVersion="0.1.0">
      <Parameter name="initial" value="0"/>
      <Parameter name="final" value="0"/>
      <Parameter name="time" value="0.5"/>
    </Component>

    <Component id="force_1" type="amesim_forc" modelVersion="0.2.0">
      <Parameter name="direction" value="1"/>
    </Component>

    <Component id="zero_1" type="amesim_f000" modelVersion="0.1.0"/>
  </Components>

  <Connections>
    <Connection id="signal-1">
      <Endpoint component="step_1" port="out"/>
      <Endpoint component="force_1" port="res"/>
    </Connection>
    <Connection id="mechanical-1">
      <Endpoint component="force_1" port="port_2"/>
      <Endpoint component="zero_1" port="port_1"/>
    </Connection>
  </Connections>
</System>

XML 的外形是一棵树,模型本身仍是一张连接图。组件平铺在 Components 中,Connections 再用 (component, port) 地址建立拓扑。

固定骨架为:

System
├─ Simulation
├─ Components
│  └─ Component *
│     └─ Parameter *
└─ Connections
   └─ Connection *
      ├─ Endpoint
      └─ Endpoint

顶层顺序固定为 Simulation → Components → Connections。每条 Connection 恰好包含两个 Endpoint。

3. System 根元素

属性 是否必填 规则
schemaVersion 是 固定为 3
unitSystem 是 固定为 SI
name 否 非空工程名称;省略后解析模型使用 untitled

schemaVersion="3" 已经表示唯一的介质引用和 AMESim 离散参数编码语义。根元素不接受额外的版本提示字段,也不会据此触发兼容猜测。

4. Simulation

属性 含义 主要校验
tStart 仿真开始时刻 必须是有限数值
tStop 仿真结束时刻 必须有限且大于 tStart
sampleStep 结果相邻采样点的时间间隔 必须大于 0,且整个区间最多生成 10001 个采样点
maxStep 自适应积分器单个内部步的上限 必须大于 0
method 积分方法 RK45/RK23/DOP853/Radau/BDF/LSODA

sampleStep 和 maxStep 不是一回事:

  • sampleStep 决定结果曲线多久保存一个点;
  • maxStep 限制求解器内部一次最多前进多久;
  • 自适应求解器可以因为误差、事件或试探状态失败而走得比 maxStep 更短。

采样点数量会在创建时间数组前计算。若区间长度不可表示为有限数、请求超过 10001 点,或在当前浮点精度下无法得到包含 tStart/tStop 的严格递增时间序列,输入会在 仿真前被拒绝,不会把超大或重复的 t_eval 交给积分器。

工程 JSON 为兼容现有前端仍把采样字段命名为 simulation.step;导出 v3 时必须映射为 Simulation/@sampleStep。

5. Component 与 Parameter

5.1 Component

属性 是否必填 含义
id 是 当前系统内唯一的实例 ID;连接通过它引用组件
type 是 后端组件注册键,例如 amesim_forc
modelVersion 是 该 type 的模型合同版本

语义校验要求 modelVersion 与当前注册表完全一致。版本不匹配时返回 COMPONENT_MODEL_VERSION_MISMATCH,不会静默套用新模型默认值或自动改写旧参数。

v3 不保存 name/componentType/x/y/rotation/mirrored。其中:

  • 显示名称和画布位置只属于工程 JSON;
  • componentType 在当前系统中与后端 type 重复;
  • 旋转和镜像只属于画面布局,不再改变求解方程。

5.2 Parameter

<Parameter name="direction" value="-1"/>

每个参数只保存稳定参数名和已经换算到 SI 基准单位的数值。v3 要求组件显式列出当前模型注册表中的全部参数:

  • 参数名重复会报错;
  • 缺少注册参数会报 PARAMETER_REQUIRED_MISSING;
  • 出现未知参数会报 PARAMETER_UNSUPPORTED;
  • 超范围或不在枚举集合内会报 PARAMETER_VALUE_INVALID。

前端和后端导出器会先用注册默认值补齐工程 JSON 中省略的参数,再写入 XML。XML 解析器本身不替缺失参数猜默认值。

5.3 AMESim 介质引用

介质仍用普通参数表达,不增加额外 XML 层级:

  • gi=0:内置理想空气;
  • 对普通气动组件,gi=1..99 引用同一 XML 中显式介质定义组件的索引;
  • 对介质定义组件自身,gi=1..99 表示它所定义的索引;
  • 介质定义的 gi 必须唯一;
  • 一个连通气动网络只能使用同一 gi;
  • property_model 也是普通必填参数,由对应介质模型注册表解释。

6. 端口与连接

6.1 为什么 v3 没有 Port 元素

端口不是组件实例的自由数据,而是组件模型合同的一部分。后端根据:

Component.type + Endpoint.port

从注册表恢复:

  • kind:物理或信号;
  • domain:气动、机械或信号;
  • nominalRole:输入、输出或物理名义角色;
  • positiveFlowDirection:物理流变量统一以进入组件为正;
  • 端口变量、单位和 equal/sumToZero/streamMix/directed 连接规则。

XML 不能通过写一个新端口名来扩展组件,也不能通过修改字符串把气动口变成机械口。

6.2 Connection

Connection/@id 可省略。省略时解析器按文档顺序生成 connection_1、connection_2 等内部 ID;显式 ID 和生成 ID 都必须唯一。

连接本身不再保存 kind 或 domain。语义层解析两个端点的注册端口后检查:

  • 组件和端口存在;
  • 两端同为物理端口或同为信号端口;
  • 两端 domain 和完整变量合同一致;
  • 信号连接恰好连接一个 output 和一个 input;
  • 一个信号输出可以驱动多个输入,但每个信号输入只能有一个驱动;
  • 同一物理端口只使用一次;分支必须使用显式 Tee/节点组件;
  • 不允许自连接或重复端点对。

6.3 两个 Endpoint 的顺序

物理连接的两个端点无序,交换顺序不改变方程或实际流向。

信号连接也不写 role="source" 或 role="target"。发送方和接收方由注册端口的 output/input 合同确定,而不是由 XML 中的先后顺序决定。导出器可以为了便于阅读把输出端写在前面,但求解器不能依赖这一顺序。

7. AmesimForc.direction

amesim_forc 从模型版本 0.2.0 开始使用显式物理参数:

<Parameter name="direction" value="1"/>

它只允许:

  • +1:默认方向,方程为 port_2.f + inputForce = 0;
  • -1:反向,方程为 port_2.f - inputForce = 0。

组件的图标旋转和镜像不会改变该参数,也不会改变求解结果。用户要反转施力方向时必须修改 direction,而不是旋转图标。

7.1 MECMAS21 离散选项编码

amesim_mecmas21 只使用 AMESim 原生的 1/2 编码。以两个布尔选项为例:

参数 1 2
useFriction 不启用摩擦 启用摩擦
strib 不使用 Stribeck 效应 使用 Stribeck 效应

工程 JSON v1 和 System XML v3 都直接保存上述值。后端不会把 0/1 自动换算成 1/2,也不会根据缺失的兼容标记猜测工程含义;不在目录选项集合内的值会被拒绝。

8. 工程 JSON 与 System XML 的分工

信息 工程 JSON System XML v3
组件实例 ID、模型类型 保存 保存
模型版本 每个节点显式保存并与目录核对 每个组件显式保存
数值参数 保存编辑值及显示信息 保存完整 SI 数值
组件显示名、坐标、旋转、镜像 保存 不保存
端口快照、side/order 保存供编辑器使用 不保存
ReactFlow source/target/handle 保存 转成两个 Endpoint
端口物理合同 目录快照用于前端检查 不重复保存,由注册表恢复
参数表达式、显示单位 保存 不保存
仿真结果 不作为模型输入 不保存

因此 /api/system-xml/parse 返回的是规范化执行模型,不是可无损恢复原画布的 ReactFlow 工程文件。需要继续编辑时,应保存和打开工程 JSON;需要校验、交换或求解时,使用 System XML v3。

9. 校验与 API

校验固定分三层:

层级 负责内容
XML 5 MiB 大小限制、语法、安全解析、禁止 DTD/实体和网络访问
XSD 元素顺序、必填属性、数量、基础数值类型、schemaVersion=3、unitSystem=SI
semantic 模型及版本、完整参数、端点引用、注册端口兼容性、介质引用和拓扑占用

当前相关接口都直接接收 Content-Type: application/xml 的原始 v3 XML:

  • POST /api/system-xml/validate:返回三层校验报告;
  • POST /api/system-xml/parse:返回规范化执行模型;
  • POST /api/system-xml/compile-model:返回编译后的网络和仿真设置;
  • POST /api/system-xml/simulate:同步运行并返回完整结果;
  • POST /api/system-xml/simulate-stream:通过 NDJSON 返回心跳、进度和最终结果。

POST /api/reactflow/system-xml 可将工程 JSON 导出为 v3;当前前端也能在浏览器中直接生成同一结构。

通过 XML/XSD/语义校验只说明输入合同正确。完整仿真前仍会检查动态储能锚点、未连接物理端口、方程结构和不允许的理想储能直连等可求解条件。物理连通岛只由物理组件和物理连接构成;控制信号扇出不会把两个独立气路或机械网络合并成一个物理岛。

10. 旧版本处理边界

当前 API 不读取或自动转换 System XML v1/v2,也不会为不匹配的 Component/@modelVersion 选择旧模型实现。旧输入会在 XSD 或语义层被明确拒绝。

本阶段不定义转换步骤、迁移注册表或兼容承诺。仓库不再保存旧版 XSD、规范或示例; 需要进入当前系统的模型必须由来源端重新导出为 v3,不能只修改版本号。

11. 事实来源

  • XSD:schemas/system-simulation-v3.xsd
  • XML 数据类、解析和三层校验:app/system_xml.py
  • 后端 JSON→XML 导出及 XML 仿真路由:app/main.py
  • 前端 XML 生成:frontend/src/App.tsx 中的 buildSystemXml()
  • 组件和端口事实来源:app/simulation/registry.py、app/simulation/core/ports.py
  • 网络最终兼容检查:app/simulation/systems/network.py