4. 联合仿真架构与接口

联合仿真的本质,是让两个或多个各自独立求解的模型在时间推进上“对齐”,并在每个同步点上交换数据。机电系统里常见的组合是:机械多体/液压模型在 Simcenter Amesim 或 Adams 中求解,控制器在 Simulink 或 PLC 环境中运行,两者通过某种接口机制耦合。接口选得对不对,直接决定仿真能否跑通、结果是否可信。本节围绕四类主流接口机制展开,并重点讨论信号映射与单位一致性这两个最容易出问题的环节。

四类接口机制的本质差异

FMI/FMU 是当前跨工具联合仿真的首选标准。FMI 定义了模型交换(Model Exchange, ME)和联合仿真(Co-Simulation, CS)两种模式。ME 模式下,FMU 只提供方程,由外部求解器统一积分;CS 模式下,FMU 自带求解器,通过 FMI 接口的 doStep 推进自身状态。机电系统常用 CS 模式,因为机械、液压工具通常已有成熟求解器。FMU 是一个压缩包,内含 modelDescription.xml(描述所有输入输出变量、单位、类型、初始值)和平台相关的二进制库。接口调用遵循固定顺序:fmi2Instantiate → fmi2SetupExperiment → fmi2EnterInitializationMode → fmi2ExitInitializationMode → 循环 fmi2SetReal/fmi2DoStep/fmi2GetReal → fmi2Terminate。

S-Function 是 Simulink 的原生扩展机制,适合把 C/C++ 编写的求解器或外部程序嵌入 Simulink 时间步。它比 FMU 更底层,需要自己管理状态导数、采样时间和直接馈通(direct feedthrough)。S-Function 的 mdlOutputs 在每个主步被调用,mdlDerivatives 由 Simulink 求解器积分。它的优势是零拷贝、低延迟,劣势是耦合逻辑要自己写,跨工具复用性差。

共享内存 适用于同一台机器上两个进程的高频数据交换。典型做法是创建一块命名共享内存区(如 Windows 的 CreateFileMapping 或 Linux 的 shm_open + mmap),双方按约定的结构体布局读写。它没有协议开销,延迟可到微秒级,但需要自己实现同步(互斥量或双缓冲),且不具备跨平台、跨机器的可移植性。

TCP/IP 适合分布式联合仿真,例如控制器跑在实时目标机上、被控对象跑在另一台服务器。它天然跨平台、跨机器,但引入网络延迟和抖动。工程上常用“定步长 + 阻塞收发”来保证确定性:每个通信步双方都 send 后 recv,用 TCP_NODELAY 关闭 Nagle 算法,避免小包合并带来的额外延迟。

联合仿真接口机制与信号映射关系 机械 / 液压模型 Amesim / Adams 自带求解器(CS 模式) 输出:位移 x [m] 输入:力 F [N] 控制器 Simulink / PLC 定步长 1 ms 输入:位移 x [m] 输出:力 F [N] 接口机制 FMI / FMU (CS) S-Function 共享内存 TCP/IP x [m] x [m] F [N] F [N] 信号映射与单位一致性检查链 ① 变量名映射 FMU 端口 ↔ Simulink 端口 x_out ↔ x_in ② 单位核对 FMU: mm → SI: m ×0.001 换算 ③ 类型与量纲 Real / Integer 匹配 角度 rad ↔ deg ④ 步长与延迟 通信步长 ≤ 最小时间常数/10 检查代数环 任一环节不通过 → 仿真发散、稳态偏差或能量不守恒 通过 → 接口数据可信,可进入结果验证

信号映射:从端口名到物理量

接口机制解决“怎么传”,信号映射解决“传什么”。以 FMU 为例,modelDescription.xml 中每个 ScalarVariable 都有 name、valueReference、causality(input/output/parameter)和 unit。联合仿真时,主控侧需要把 FMU 的输出变量映射到本地模型的输入端口。常见做法是建立一张映射表:

FMU 变量名causality单位本地端口换算系数
position_xoutputmmController.x_in0.001
force_FinputNController.F_out1.0
angle_thetaoutputdegController.theta_inπ/180
torque_TinputN·mController.T_out1.0

这张表不是形式主义。实际工程中,FMU 导出时单位常被工具默认设为 mm、deg、bar,而 Simulink 侧习惯用 SI 单位 m、rad、Pa。如果直接连线不做换算,位移会放大 1000 倍,控制器立刻饱和,仿真在第一个通信步就发散。因此映射表必须显式写出换算系数,并在初始化阶段做一次“单位自检”:给 FMU 输入一个已知量(如 1 N),读回其输出,确认数值与预期一致。

单位一致性的三个检查点

第一,FMU 内部单位与导出声明是否一致。 有些工具在导出 FMU 时,modelDescription.xml 里的 unit 字段是手工填写的,可能与模型内部实际使用的单位不符。验证方法是:在 FMU 单独运行时给输入 1.0,观察输出量级。若声明为 m 但实际按 mm 计算,输出会差三个数量级。

第二,通信步长与模型时间常数的关系。 联合仿真的通信步长 T_comm 必须小于被控对象最小时间常数的 1/10。例如液压缸的响应时间常数约 20 ms,则 T_comm 应取 2 ms 或更小。若 T_comm 过大,接口处会引入等效延迟,表现为相位滞后,闭环系统可能从稳定变为振荡。判断依据是:逐步减小 T_comm,若仿真结果不再明显变化,说明步长已足够小。

第三,代数环与直接馈通。 如果 FMU 的输出直接依赖当前步的输入(即 directFeedthrough=true),而控制器输出又依赖 FMU 输出,就形成代数环。FMI CS 模式下,FMU 的 doStep 内部会处理这个问题,但主控侧仍需检查:Simulink 中若 FMU 模块被标记为直接馈通,而反馈路径没有单位延迟,Simulink 会报代数环错误。解决办法是在反馈路径插入 Memory 模块或 Unit Delay,人为引入一个通信步的延迟,代价是引入 T_comm 的相位滞后,需与步长选择一并权衡。

实操建议: 首次搭建联合仿真时,先不要接闭环控制器。把 FMU 的输出直接引出,给一个阶跃输入,观察输出是否与 FMU 单独运行一致。确认接口映射和单位无误后,再接入控制器。这一步能排除 80% 以上的接口问题。

接口机制选型参考

四类机制没有绝对优劣,取决于部署形态。同一台机器、追求低延迟、双方都能改代码,选共享内存;跨工具、需要复用和归档,选 FMU;控制器是 Simulink 且需要精细控制求解过程,选 S-Function;跨机器、跨操作系统、需要与实时目标机通信,选 TCP/IP。实际项目中,FMU + TCP/IP 的组合也很常见:FMU 封装被控对象,TCP/IP 负责与实时控制器交换数据。

无论选哪种机制,信号映射表和单位检查都必须落到文档里,而不是只存在于搭建者的记忆中。联合仿真的调试成本,大部分消耗在“数值不对”的排查上,而数值不对的根源,往往就是某个变量的单位或方向定义在两侧不一致。把映射关系显式化、把单位换算写成代码而不是靠心算,是让联合仿真从“能跑”走向“可信”的关键一步。