如何在PyFMI中动态获取变量值并调整输入参数?
如何在PyFMI输入回调中获取模型状态或分段调整输入仿真
问题原因
调用model.simulate()时,PyFMI的仿真引擎会接管模型内部状态更新流程,此时直接在输入回调函数中调用model.get('x')无法获取当前仿真时刻的实时状态——模型的中间状态仅在仿真引擎内部循环中可用,外部调用无法访问。
解决方案
方案1:使用带状态参数的输入回调函数
PyFMI允许输入回调函数接收额外参数,第三个参数即为当前仿真时刻的状态变量数组,可直接通过该参数获取x的值,无需调用model.get()。
修改后的代码示例:
from pyfmi import load_fmu model = load_fmu('D:/FMU/Test.fmu') # 先确认状态变量顺序,确保x的索引正确 print(model.get_states_list()) # 输出类似['x'],因此x是states数组的第0个元素 def f(time, _, states): # 通过states数组获取当前x的值 current_x = states[0] # 根据current_x动态调整k的值,示例为基于x计算k return current_x * 0.001 # 替换原有的time*0.1逻辑 inputs = ('k', f) result = model.simulate(final_time=10, input=inputs)
方案2:分段仿真(手动控制流程)
若需要更灵活地控制仿真节奏,比如在每个时间步结束后获取状态并调整输入,可采用分段仿真的方式:每次仿真一小段时间,获取当前状态后更新输入,再继续仿真。
代码示例:
from pyfmi import load_fmu import pandas as pd model = load_fmu('D:/FMU/Test.fmu') start_time = 0.0 current_time = start_time total_final_time = 10.0 step_duration = 1.0 # 每次仿真的时间步长 # 初始化模型 model.setup_experiment(start_time=start_time) model.initialize() # 存储所有分段仿真的结果 all_results = [] while current_time < total_final_time: # 计算本次仿真的结束时间 next_time = min(current_time + step_duration, total_final_time) # 仿真到下一个时间点 segment_result = model.simulate(start_time=current_time, final_time=next_time) # 获取当前时刻的x值(取结果数组的最后一个元素) current_x = segment_result['x'][-1] # 根据x调整输入k的值 new_k = current_x * 0.001 model.set('k', new_k) # 更新当前时间 current_time = next_time # 保存分段结果 all_results.append(segment_result) # 合并所有分段结果为一个DataFrame(可选) final_result = pd.concat([pd.DataFrame(res) for res in all_results]).reset_index(drop=True)
注意事项
- 方案1中,状态变量的顺序可通过
model.get_states_list()确认,确保从states数组中取到正确的变量。 - 方案2的步长可根据需求调整,步长越小状态更新频率越高,但仿真效率会有所下降。
内容的提问来源于stack exchange,提问作者cwydw
相关产品推荐
相关产品推荐

