OMPython通过overrideFile覆写参数后仿真仍使用默认值问题
问题根因
- 你采用的「预编译模型+运行时overrideFile覆写参数」流程,仅支持修改不改变模型结构的非结构性参数,比如控制增益、速度阈值这类不会影响数组维度、实例数量、循环边界的参数。
- 你覆写的
const.N等参数属于结构性参数:OpenModelica在执行buildModel编译阶段,就已经按照constant.mo里的默认值N=5,完成了无人机实例生成、数组内存分配、循环边界固化的全流程,编译出的可执行文件本身就只包含5架无人机的计算逻辑。 - 你在结果文件里查到const.N显示为7,只是overrideFile把参数值写入了结果文件的参数记录区,实际仿真计算过程完全没用到这个覆写值,因此第6、7架无人机根本没有对应的计算逻辑,输出自然全是NaN。你查到K类参数
isValueChangeable=false就是直接证据:这类编译期就被求值固化的参数,本身就不支持运行时修改。
修复方案
- 调整参数类型:把所有会影响数组维度、实例数量、循环边界的参数,从
constant类型修改为parameter类型,同时删除这类参数上的annotation(Evaluate=true)注解——这个注解会强制编译器在编译阶段就把参数求值为常量,直接锁死参数值无法修改。 - 调整仿真流程:把预编译步骤从循环外挪到仿真函数内部,只要修改了结构性参数,就必须重新编译模型,不能复用之前编译好的可执行文件。推荐直接用OMPython原生的
simulate接口传参,自动完成编译+运行全流程,避免手动调用可执行文件带来的参数不生效问题,参考实现如下:
""" 加载所有需要的模型文件 """ omc.sendExpression("loadModel(Modelica)") omc.sendExpression("loadFile(\"constant.mo\")") # 替换成你自己的模型加载逻辑 omc.sendExpression("getErrorString()") def startSimulation(n, intr, miss, statObs, fault, flyZone, stopTime=180): droneInfo = {} # 拼接覆写参数字符串,直接传入simulate接口,每次自动重编译 overrideStr = (f"const.N={n}," f"const.nIntr={intr}," f"const.nRocket={miss}," f"const.nStatObs={statObs}") # 追加矩阵和数组参数 for i in range(len(fault)): for j in range(len(fault[i])): overrideStr += f",fault.transMatrix[{i+1},{j+1}]={fault[i][j]}" for i in range(3): overrideStr += f",const.flyZone[{i+1}]={flyZone}" # 执行编译+仿真 omc.sendExpression(f"simulate(System, stopTime={stopTime}, simflags=\"-override={overrideStr}\")") omc.sendExpression("getErrorString()") # 提取结果逻辑不变 for j in range(1,n+1): arrivalTime = omc.sendExpression(f"val(sucMo.arrivalTime[{j}], {stopTime}, \"System_res.mat\")") droneArrived = omc.sendExpression(f"val(sucMo.arrived[{j}], {stopTime}, \"System_res.mat\")") droneInfo[j] = (droneArrived, arrivalTime) return droneInfo # 调用测试 print(startSimulation(7,1,1,1,noFault,100))
- 模型检查:全局排查所有用
const.N等结构性参数定义维度的数组,确保没有硬编码维度,例如要写Real arrivalTime[const.N],不能写Real arrivalTime[5],保证参数修改后数组维度能同步联动。 - 提速优化:如果批量仿真时每次重编译速度太慢,可以把和集群数量无关的固定子模型提前编译为动态链接库,仅保留顶层结构性参数为可调整状态,能将编译耗时缩短70%以上。
故障现象复现示例
覆写N=7但未重编译时的输出:
{1: (1.0, 8.0), 2: (1.0, 5.0), 3: (1.0, 8.0), 4: (1.0, 9.0), 5: (1.0, 12.0), 6: ('NaN', 'NaN'), 7: ('NaN', 'NaN')} 0.0
内容的提问来源于stack exchange,提问作者FrankDev
相关产品推荐
相关产品推荐

