#!/usr/bin/env python # coding: utf-8 # ### 入力信号のあるエンジンモデル # [JModelica User Guide - Version.2.10](https://jmodelica.org/downloads/UsersGuide-2.10.pdf) の # 5.4.3. Simulation of an Engine model with input のシミュレーションを実行します。 # # このモデルは Modelica.Mechanics.MultiBody.Examples.Loops.EngineV6_analytic のエンジンの負荷となるトルクコンポーネントを、回転数から計算する QuadraticSpeedDependentTorque から、入力信号として設定可能な Torque に変更したものです。トルクは入力信号 u で設定します。 # # モデルのソースコードを作成します。 # In[1]: get_ipython().run_cell_magic('writefile', 'EngineV6.mo', 'model EngineV6_analytic_with_input\n output Real engineSpeed_rpm= Modelica.SIunits.Conversions.to_rpm(load.w);\n output Real engineTorque = filter.u;\n output Real filteredEngineTorque = filter.y;\n \n input Real u;\n\n import Modelica.Mechanics.*;\n \n inner MultiBody.World world;\n MultiBody.Examples.Loops.Utilities.EngineV6_analytic engine(\n redeclare model Cylinder = MultiBody.Examples.Loops.Utilities.Cylinder_analytic_CAD\n );\n \n Rotational.Components.Inertia load(\n phi(start=0,fixed=true),\n w(start=10,fixed=true),\n stateSelect=StateSelect.always,J=1\n );\n Rotational.Sensors.TorqueSensor torqueSensor;\n Rotational.Sources.Torque torque;\n \n Modelica.Blocks.Continuous.CriticalDamping filter(\n n=2,initType=Modelica.Blocks.Types.Init.SteadyState,f=5\n );\n\nequation\n torque.tau = u;\n connect(world.frame_b, engine.frame_a);\n connect(torque.flange, load.flange_b);\n connect(torqueSensor.flange_a, engine.flange_b);\n connect(torqueSensor.flange_b, load.flange_a);\n connect(torqueSensor.tau, filter.u);\n \n annotation (experiment(StopTime=1.01));\nend EngineV6_analytic_with_input;\n') # コンパイルして FMU を作成します。 # In[2]: from pymodelica import compile_fmu name = compile_fmu("EngineV6_analytic_with_input", "EngineV6.mo") # 入力信号を未設定 (u = 0) のままシミュレーションを実行します。 # In[3]: from pyfmi import load_fmu # In[4]: model = load_fmu(name) opts = model.simulate_options() opts["ncp"] = 1000 res = model.simulate(options=opts) # シミュレーション結果をプロットします。 # In[5]: get_ipython().run_line_magic('matplotlib', 'notebook') import matplotlib.pyplot as plt # In[6]: plt.figure(1) plt.subplot(3,1,1) plt.plot(res["time"],res["u"]) plt.legend(["Load Torque"], loc='lower right') plt.ylabel("Torque [N.m]") plt.grid(b=True, linestyle="--") plt.subplot(3,1,2) plt.plot(res["time"],res["filteredEngineTorque"]) plt.legend(["Filtered Engine Torque"], loc='lower right') plt.ylabel("Torque [N.m]") plt.grid(b=True, linestyle="--") plt.subplot(3,1,3) plt.plot(res["time"],res["engineSpeed_rpm"]) plt.legend(["Engine Speed"], loc='lower right') plt.ylabel("Speed [1/min]") plt.grid(b=True, linestyle="--") plt.xlabel("Time [s]") plt.show() # 入力信号を表す Python の関数を作成します。 # In[7]: def input_func(t): return -100.0*t # 入力信号を設定してシミュレーションを実行します。 # In[8]: model = load_fmu(name) opts = model.simulate_options() opts["ncp"] = 1000 res = model.simulate(options=opts, input=("u",input_func)) # シミュレーション結果をプロットします。 # In[9]: plt.figure(2) plt.subplot(3,1,1) plt.plot(res["time"],res["u"]) plt.legend(["Load Torque"], loc='upper right') plt.ylabel("Torque [N.m]") plt.grid(b=True, linestyle="--") plt.subplot(3,1,2) plt.plot(res["time"],res["filteredEngineTorque"]) plt.legend(["Filtered Engine Torque"], loc='lower right') plt.ylabel("Torque [N.m]") plt.grid(b=True, linestyle="--") plt.subplot(3,1,3) plt.plot(res["time"],res["engineSpeed_rpm"]) plt.legend(["Engine Speed"], loc='lower right') plt.ylabel("Speed [1/min]") plt.grid(b=True, linestyle="--") plt.xlabel("Time [s]") plt.show() # In[ ]: