使用PyFMI的Master模块获取FMU联合仿真结果的问题
PyFMI Master联合仿真结果变量获取与处理
我尝试使用PyFMI的Master模块对两个Matlab-Simulink导出的FMU进行联合仿真,代码如下:
from pyfmi import Master """ Loading FMUs, establishing connection between models, defining Master simulator and simulation options """ dummy_model = load_fmu('dummy.fmu', log_level = 4) batt_model = load_fmu('battery.fmu', log_level = 4) models = [dummy_model, batt_model] connection = [(dummy_model, 'P_to_batt_fmu', batt_model, 'P_to_batt_fmu')] mastersim = Master(models, connection) opts = mastersim.simulate_options() opts['step_size'] = 1000 opts['result_handling'] = 'memory' """ Simulating """ res = mastersim.simulate(final_time = 1000, options = opts)
仿真过程正常,但从res中获取结果时遇到问题:Simulink模型中的输出变量(如'Ibatt'、'SoC'、'Qbatt')并未作为res的键存在,当前res的结构为:
{0: <pyfmi.common.algorithm_drivers.AssimuloSimResult object at 0x000002B3AC3CCF10>, <pyfmi.fmi.FMUModelCS2 object at 0x000002B3AB8BC800>: <pyfmi.common.algorithm_drivers.AssimuloSimResult object at 0x000002B3AC3CCF10>, 1: <pyfmi.common.algorithm_drivers.AssimuloSimResult object at 0x000002B3AC3CE1A0>, <pyfmi.fmi.FMUModelCS2 object at 0x000002B3AB889670>: <pyfmi.common.algorithm_drivers.AssimuloSimResult object at 0x000002B3AC3CE1A0>}
而单独仿真单个FMU时,res.keys()就是Simulink输出变量名,符合预期:
batt_model = load_fmu('battery.fmu', log_level = 4) opts = batt_model.simulate_options() opts['ncp'] = 1000 res = batt_model.simulate(final_time=1000, options = opts)
我的问题是:
- 使用
Master时,如何在res中找到目标变量? - 如何便捷地处理这些变量?
目前我通过设置opts['result_handling'] = 'file',可以从results.txt文件中处理结果,但更希望在内存中存储和处理结果。
问题1:获取目标变量
Master模块返回的res字典中,每个键对应一个参与联合仿真的FMU模型——可以是模型在列表中的索引(比如0对应dummy_model,1对应batt_model),也可以是FMU对象本身(比如batt_model)。对应的值是该模型独立仿真时会返回的AssimuloSimResult对象,结构和单独仿真完全一致。
所以要提取目标变量,只需先通过索引或模型对象拿到对应模型的结果集,再通过变量名访问:
# 方式1:通过模型索引获取 batt_result = res[1] ibatt = batt_result['Ibatt'] soc = batt_result['SoC'] # 方式2:通过FMU对象获取 batt_result = res[batt_model] qbatt = batt_result['Qbatt']
问题2:便捷处理变量
推荐将每个模型的结果转换为Pandas DataFrame,方便后续的数据分析、可视化等操作:
1. 单个模型结果转DataFrame
import pandas as pd # 获取电池模型的结果 batt_result = res[1] # 提取时间序列和所有变量,组合成DataFrame batt_df = pd.DataFrame({ 'time': batt_result['time'], 'Ibatt': batt_result['Ibatt'], 'SoC': batt_result['SoC'], 'Qbatt': batt_result['Qbatt'] }) # 查看前5行数据 print(batt_df.head())
2. 批量提取所有模型变量
如果需要同时处理多个模型的结果,可以写一个简单的工具函数:
def fmu_result_to_df(result_obj): """将AssimuloSimResult转换为DataFrame""" data = {var: result_obj[var] for var in result_obj.keys()} return pd.DataFrame(data) # 转换所有模型的结果 dummy_df = fmu_result_to_df(res[0]) batt_df = fmu_result_to_df(res[1]) # 合并两个模型的结果(按时间对齐) combined_df = pd.merge(dummy_df, batt_df, on='time', suffixes=('_dummy', '_batt'))
3. 直接访问变量数组
如果不需要DataFrame,也可以直接将变量提取为NumPy数组进行数值计算:
import numpy as np soc_array = np.array(batt_result['SoC']) # 计算SoC的平均值 avg_soc = np.mean(soc_array)
内容的提问来源于stack exchange,提问作者glitchb3rt
相关产品推荐
相关产品推荐

