今回は久々にmodeica関連の記事になります。
JuliaでOpen Modelicaを操作するパッケージ「OMJulia」を用いてopen modelicaのモデルのパラメーターを最適化します。 関連する記事は以下になります。
今回のモデル
今回モデリングする対象は上図です。物理の授業でよくある、ボールをある角度で投擲して地面(y=0)に落下するまでのモデルになります。 今回、ModelicaとJuliaを使って、地面にぶつかるまでx方向に最も長く飛ぶ角度θを探索します。
Open Modelicaでモデリング
まず、適当にθ=0.5としてModelicaでモデリングしてみます。初期速度v0=0.5としています。
model RocketBall parameter Real v0 = 5;//初期速度 parameter Real theta = 0.5;//打ち上げ角度 constant Real g = 9.81;//重力加速度 Real x; Real y; Real vy(start=v0*sin(theta));//y方向速度 equation der(y) = vy; der(vy) = -g; der(x) = v0*cos(theta); algorithm when y < 0 then terminate("simulation end"); end when; end RocketBall;
これをOpenModelicaでシミュレーションします。
シミュレーション結果のうち、高さyの時間変化をプロットしたものが以下のグラフです。 与えられた初速によりある程度の高さに到達した後、重力に従って地面(y=0)に落下するまでの過程が描かれています。
また今回最大化する、横方向xの時間変化を見てみます。
角度θ=0.5の時はx方向に2.1~2.2進むことができたようです。
Juliaを使用してパラメーターの最適化
では、x方向に最も進む角度θを探していきます。人手でOpenModelicaのパラメーターを変えながら逐一シミュレーションしていくのは非常に手間がかかりますので、この過程をJuliaで自動化します。 パッケージとしてOMJuliaを使用します。
原始的な総当り方法を使用します。 Juliaのfor~end構文でパラメーターθの値を変えながらmodelicaのシミュレーションを繰り返します。 コードは以下になります。
using OMJulia using Plots RocketBall = OMJulia.OMCSession() RocketBall.ModelicaSystem("RocketBall.mo","RocketBall") np = 100; par = range(0,pi/2,length=np); position = zeros(np); for i = 1:np RocketBall.setSimulationOptions(["stopTime=10", "stepSize=0.01"]) RocketBall.setParameters("theta=$(par[i])"); RocketBall.simulate() position[i] = RocketBall.getSolutions("x")[end][end]; end plot(par,position) xlabel!("θ") ylabel!("position")
θを[0~π/2]の範囲で100分割し、それぞれの値に対してModelicaのシミュレーションを実行し、ボールが地面に落下したときの到達点xの値をposition
に格納していきます。
結果、θとxの到達点の関係は以下のグラフになります。
およそθの値がπ/4付近のときにxの到達点が最大化することがわかりました。
今回のようにmodelicaのパラメーターを最適化したり、パラメーターの影響を確認する際は他のプログラミング言語と連携すると便利です。
今回はここまでにします。