如何使用FMPy获取因果性为'calculatedParameter'的存储变量值
如何使用FMPy获取因果性为'calculatedParameter'的存储变量值
我完全懂你现在的困扰——用FMPy调用simulate_fmu()时,明明能看到那些派生参数的元数据(名称、可变性fixed、因果性calculatedParameter这些),但就是找不到它们的实际计算值,而且这类参数本来就是由其他参数推导出来的,硬塞进start_values里也不符合逻辑,反观PyFMI却能轻松拿到这些值,确实让人头疼。
其实问题出在simulate_fmu()的返回逻辑上:它主要记录的是模拟过程中动态变化的变量数据,而这类calculatedParameter属于初始化阶段就计算完成的固定参数,并不会被自动包含在模拟输出里。要拿到它们的值,你需要绕开快捷的simulate_fmu(),直接操作FMU实例来读取,具体步骤如下:
具体实现代码
from fmpy import read_model_description, extract, instantiate_fmu, free_fmu # 替换成你的FMU文件路径 fmu_path = "your_target_model.fmu" # 1. 解析FMU的模型描述,提取必要信息 model_desc = read_model_description(fmu_path) unzip_dir = extract(fmu_path) # 2. 筛选出所有因果性为calculatedParameter的变量 calculated_params = [var for var in model_desc.modelVariables if var.causality == 'calculatedParameter'] # 3. 实例化FMU并完成初始化(关键:初始化阶段会完成参数计算) fmu_instance = instantiate_fmu(unzip_dir, model_desc) fmu_instance.setupExperiment() fmu_instance.enterInitializationMode() fmu_instance.exitInitializationMode() # 4. 根据变量类型读取对应的值 for param in calculated_params: # 根据变量类型选择读取方法:getReal/getInteger/getBoolean/getString if param.type == 'Real': value = fmu_instance.getReal([param.valueReference])[0] elif param.type == 'Integer': value = fmu_instance.getInteger([param.valueReference])[0] elif param.type == 'Boolean': value = fmu_instance.getBoolean([param.valueReference])[0] elif param.type == 'String': value = fmu_instance.getString([param.valueReference])[0] print(f"参数 {param.name} 的值:{value}") # 5. 记得清理资源,避免内存泄漏 free_fmu(fmu_instance)
为什么这个方法可行?
这类calculatedParameter是在FMU的初始化阶段就完成计算并固定下来的,而simulate_fmu()的输出默认只追踪模拟过程中会变化的变量。通过直接实例化FMU并走完初始化流程,我们就能直接从FMU实例中读取这些已经计算好的固定参数值,和PyFMI的get_variable_causality()逻辑类似,只是FMPy需要手动完成实例化和初始化的步骤。
额外注意点
- 一定要匹配变量的类型选择对应的读取方法,比如实数用
getReal(),布尔值用getBoolean(),否则会读取失败 - 如果需要在模拟完成后再读取这些参数,也可以在模拟流程中保留FMU实例,模拟结束后再执行读取步骤
- 你当前使用的FMPy 0.3.20版本完全支持这个操作,不需要升级版本
备注:内容来源于stack exchange,提问作者janpeter
相关产品推荐
相关产品推荐

