导入 FMU 协同模拟组件¶
展示如何使用FMU Import
块将外部 FMU 格式的模型添加到 Engee 画布。
模型描述¶
FMU(功能模拟单元)组件中的协同模拟模式旨在将不同建模工具中开发的多个模型组合成一个时间同步系统。
该模式可将在不同环境(MATLAB/Simulink、Dymola、OpenModelica 等)中创建的模型结合起来,而无需重写代码。
每个 FMU 都是一个 "黑盒子",有自己的求解器。
在本例中,我们的 "外部 "模型在fmuVanDerPol.fmu
文件中,我们将把它放入 FMU 导入块,设置完成后,我们将从它所包含的模型中获取图形。
我们建议研究 FMU 文件。为此,让我们安装一些库并调用info(fmu)
命令。
In [ ]:
Pkg.add( ["FMI"] )
using FMI
fmu = loadFMU( "fmuVanDerPol.fmu" )
info(fmu)
#################### Begin information for FMU #################### Model name: myvdp FMI-Version: 2.0 GUID: {a50ebd80-9a0f-b492-4bf4-893f9611b1a5} Generation tool: [Unknown generation tool] Generation time: 2018-09-26T19:47:29Z Var. naming conv.: structured Event indicators: 0 Inputs: 0 Outputs: 2 0 ["Out1"] 1 ["Out2"] States: 0 Parameters: 1 2 ["mu"] Supports Co-Simulation: true Model identifier: myvdp Get/Set State: true Serialize State: true Dir. Derivatives: false Var. com. steps: false Input interpol.: false Max order out. der.: nothing Supports Model-Exchange: false ##################### End information for FMU #####################
设置程序块¶
在这些信息中,我们需要找到输入端口名称、输出端口名称和参数名称,以便正确创建程序块接口和配置程序块。
这个模型没有输入端口,有两个输出端口(Out1
和Out2
),还有一个参数mu
。此外,我们也没有看到该模型的求解器正在等待的时间步长设置。
我们根据经验发现,该 FMU 模型的计算步长不应小于
0.1 с
。整个模拟的全局步长可以是任何步长。
让我们在运行时运行模型并绘制图表:
In [ ]:
model_name = "fmu_co_simulation";
model_name in [m.name for m in engee.get_all_models()] ? engee.open(model_name) : engee.load( "$(@__DIR__)/$(model_name).engee");
res = engee.run( model_name );
plot( res["x"].time, [res["x"].value res["dx"].value], label=["x" "dx"],
lw=3, size=(600,300) )
Out[0]:
何时选择协同仿真而不是模型交换?¶
模型交换(ME)要求整个系统使用单一求解器,如果所有模型都能使用单一求解器,则适合使用该方法。
在下列情况下,可选择协同仿真(CS):
- 模型使用不同的求解器、
- 有遗留代码或专有模拟器、
- 需要分布式执行(如 HIL 测试)。
结论¶
协同仿真 FMU 是整合异构模型的强大工具,无需完全重写模型,但需要权衡受控同步和潜在的采样误差。
{"id": "d73567c4-fc96-4377-beba-4292122a4de9", "data": [{"showlegend": true, "mode": "lines", "xaxis": "x", "colorbar": {"y": 0.5185185185185185, "title": {"text": ""}, "len": 0.936716243802858, "x": 0.9934383202099738}, "name": "x", "yaxis": "y", "legendgroup": "x", "line": {"color": "rgba(0, 154, 250, 1.000)", "shape": "linear", "dash": "solid", "width": 3}, "y": [2, 1.991, 1.967053928591668, 1.9319446295352218, 1.8882868657255774, 1.837817345100953, 1.7816370714157164, 1.720390912443356, 1.6543915487242917, 1.5837003158541976, 1.5081763369269523, 1.4275025267668409, 1.3411943422759074, 1.248595096285817, 1.148860372171079, 1.0409336824327668, 0.9235163262017531, 0.7950371601142134, 0.6536341376500157, 0.4971713985790433, 0.32333668381839437, 0.1298962675439932, -0.08477702389765718, -0.32077372218798234, -0.5752826359582779, -0.8410992836473743, -1.10592696673003, -1.3537781119310621, -1.5689112020813347, -1.7405356830669882, -1.865334666836358, -1.9465931913081636, -1.9913249676455533, -2.0074504953127734, -2.002062763146558, -1.9807644408118683, -1.9476545010964432, -1.9055826869744807, -1.8564525502782379, -1.801482031226678, -1.7413991793541046, -1.6765784326027842, -1.607130333502007, -1.53295697966182, -1.4537826426455716, -1.3691660756287207, -1.2784987504840313, -1.18099176194739, -1.0756534751875015, -0.9612604003296126, -0.8363258387927661, -0.6990757511856218, -0.5474511322218978, -0.3791740311311702, -0.19194327744314155, 0.016135818613113778, 0.24575638319861123, 0.4951672939371867, 0.758652802851862, 1.025452075230045, 1.2803918072648601, 1.5071210697791808, 1.6928977152988933, 1.8320466818970205, 1.9260819715214659, 1.9812106592095287, 2.005321349742527, 2.0058786433437246, 1.9889688414566111, 1.9591343840429891, 1.9195772347072753, 1.8724616930249562, 1.819192791926763, 1.7606322491205342, 1.6972518336510558, 1.629236024848271, 1.5565468719864644, 1.4789614436329626, 1.3960892356100314, 1.3073744013431026, 1.2120859199920204, 1.1092978828668223, 0.9978621129035949, 0.8763767865668305, 0.7431585736914265, 0.5962338277375407, 0.43337934925255667, 0.25226853058674353, 0.05081491717401443, -0.17215993584352302, -0.41582202012881436, -0.675844922122534, -0.943074801979174, -1.2034864953475313, -1.4406070363446786, -1.6400794147846611, -1.7938534373486668, -1.901394267760074, -1.9677894969148115, -2.0006874651073043, -2.007836099769441], "type": "scatter", "x": [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 4, 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9, 5, 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 5.7, 5.8, 5.9, 6, 6.1, 6.2, 6.3, 6.4, 6.5, 6.6, 6.7, 6.8, 6.9, 7, 7.1, 7.2, 7.3, 7.4, 7.5, 7.6, 7.7, 7.8, 7.9, 8, 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7, 8.8, 8.9, 9, 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 9.7, 9.8, 9.9, 10]}, {"showlegend": true, "mode": "lines", "xaxis": "x", "colorbar": {"y": 0.5185185185185185, "title": {"text": ""}, "len": 0.936716243802858, "x": 0.9934383202099738}, "name": "dx", "yaxis": "y", "legendgroup": "dx", "line": {"color": "rgba(227, 111, 71, 1.000)", "shape": "linear", "dash": "solid", "width": 3}, "y": [0, -0.17283634791666666, -0.30100150062324194, -0.3977063334072956, -0.47314921039623725, -0.5347910956546068, -0.587980138751756, -0.6365672584470178, -0.683402425688082, -0.7307045028010848, -0.7803300960983489, -0.8339709900534732, -0.8933044607213521, -0.960113251727297, -1.0363838242259824, -1.124381516626691, -1.2266863395121277, -1.3461478203440795, -1.4856731826690643, -1.6476898241454772, -1.8330164778359745, -2.038769693390557, -2.254968576884805, -2.460068235177658, -2.617383560630539, -2.677332088616308, -2.591771064803224, -2.339703542191047, -1.947638521312524, -1.482831373664316, -1.0211332996595632, -0.6163342245031908, -0.2905750711535876, -0.04215069575750191, 0.142187997464425, 0.27827125777797396, 0.3801443968908372, 0.4587775159851883, 0.5222233766212409, 0.5762422300311895, 0.6249538180529262, 0.6713722949929317, 0.7178064521145447, 0.7661495722560973, 0.8180902543415517, 0.8752707854838963, 0.9394120500802521, 1.0124159311244365, 1.096447007854284, 1.1939824789080138, 1.3077979344359807, 1.440819368818358, 1.595708517041845, 1.7739514093004582, 1.9741044412675381, 2.1888165879357833, 2.4005898814539184, 2.5775484984892643, 2.6731846245099553, 2.636490361953328, 2.435167767180765, 2.080282799660821, 1.6292431650225438, 1.1592412557881975, 0.7330115948480269, 0.38216701900728334, 0.11100142402726265, -0.091377978766014, -0.24067900455124822, -0.3517484702084308, -0.436532713312795, -0.5039272407140983, -0.5603258135005706, -0.6102896457022787, -0.6571242137259556, -0.7033194839364058, -0.750870442043571, -0.8015091125238781, -0.8568766798019696, -0.9186571329135464, -0.9886859227197089, -1.0690385107891616, -1.162092366278836, -1.2705379404746435, -1.397282855403754, -1.545139480076106, -1.716099538377499, -1.909884640582829, -2.1213813623254123, -2.3367453693012785, -2.5288939397405943, -2.6553946044676398, -2.664701705209547, -2.515707392717195, -2.204244261838493, -1.7749876368952502, -1.30292564894718, -0.8581818654766749, -0.48240011463036314, -0.18718446013577628, 0.03495063764791806], "type": "scatter", "x": [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 4, 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9, 5, 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 5.7, 5.8, 5.9, 6, 6.1, 6.2, 6.3, 6.4, 6.5, 6.6, 6.7, 6.8, 6.9, 7, 7.1, 7.2, 7.3, 7.4, 7.5, 7.6, 7.7, 7.8, 7.9, 8, 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7, 8.8, 8.9, 9, 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 9.7, 9.8, 9.9, 10]}], "config": {"showlegend": true, "xaxis": {"showticklabels": true, "gridwidth": 0.5, "tickvals": [0, 2.5, 5, 7.5, 10], "range": [-0.3000000000000007, 10.3], "domain": [0.03619130941965587, 0.9934383202099738], "mirror": false, "tickangle": 0, "showline": true, "ticktext": ["0.0", "2.5", "5.0", "7.5", "10.0"], "zeroline": false, "tickfont": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "zerolinecolor": "rgba(0, 0, 0, 1)", "anchor": "y", "visible": true, "ticks": "inside", "tickmode": "array", "linecolor": "rgba(0, 0, 0, 1)", "showgrid": true, "title": {"text": "", "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}}, "gridcolor": "rgba(0, 0, 0, 0.1)", "tickcolor": "rgb(0, 0, 0)", "type": "linear"}, "paper_bgcolor": "rgba(255, 255, 255, 1.000)", "annotations": [], "height": 300, "margin": {"l": 0, "b": 20, "r": 0, "t": 20}, "plot_bgcolor": "rgba(255, 255, 255, 1.000)", "yaxis": {"showticklabels": true, "gridwidth": 0.5, "tickvals": [-2, -1, 0, 1, 2], "range": [-2.837847590010096, 2.833700125903743], "domain": [0.050160396617089535, 0.9868766404199475], "mirror": false, "tickangle": 0, "showline": true, "ticktext": ["-2", "-1", "0", "1", "2"], "zeroline": false, "tickfont": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "zerolinecolor": "rgba(0, 0, 0, 1)", "anchor": "x", "visible": true, "ticks": "inside", "tickmode": "array", "linecolor": "rgba(0, 0, 0, 1)", "showgrid": true, "title": {"text": "", "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}}, "gridcolor": "rgba(0, 0, 0, 0.1)", "tickcolor": "rgb(0, 0, 0)", "type": "linear"}, "legend": {"yanchor": "auto", "xanchor": "auto", "bordercolor": "rgba(0, 0, 0, 1)", "bgcolor": "rgba(255, 255, 255, 1.000)", "borderwidth": 1, "tracegroupgap": 0, "y": 1, "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "title": {"font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}, "text": ""}, "traceorder": "normal", "x": 1}, "width": 838.765625}}