【PyFMI】最小構成のMBD事例 第2章 その104【ダミーFMU⑥】

【PyFMI】最小構成のMBD事例 第2章 その104【ダミーFMU⑥】 事例

バックナンバーはこちら。
https://www.simulationroom999.com/blog/model-based-of-minimum-2-backnumber/

はじめに

前回、実験構成を決め、
ダミーFMUを混ぜたFMUロードのところまで。
既存のFMUをロードした方がインターフェース仕様の整合が付けやすい。
(インターフェースだけのアルゴリズムは空っぽでOK)

今回は、Dummy_FMUModelCS2でオーバーライドしたdo_stepの話を中心にしていく。

登場人物

博識フクロウのフクさん

指差しフクロウ

イラストACにて公開の「kino_k」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=iKciwKA9&area=1

エンジニア歴8年の太郎くん

技術者太郎

イラストACにて公開の「しのみ」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=uCKphAW2&area=1

do_stepの実装方針

太郎くん
太郎くん

今回はdo_stepをやるんだよねー。

フクさん
フクさん

そうだね。
まずは実装方針を書き出そう。

フクさん
フクさん

ちなみにRampの代わりに出力する部分なので、
出力信号は以下とする。

  • 出力初期値は0.0
  • 0.2秒から1.0秒にかけて出力値1.0になるようにRamp Up
  • 1.2秒まで出力を1.0に固定
  • 1.2秒から2.0秒にかけて出力値0.0になるようRamp Down
太郎くん
太郎くん

登って、止まって、下るって感じか。

フクさん
フクさん

そして時間制御の部分は以下。

  • シミュレーション開始時刻を記憶。
  • \([現時刻 – シミュレーション開始時刻]\)をシミュレーション時間と比較
  • シミュレーション時間が上記以上になるまで処理をホールド
太郎くん
太郎くん

これで、シミュレーション時間と実時間が一致するようになるのか。

do_stepの出力信号のソースコード

フクさん
フクさん

そして、出力に関するコードはこんな感じにする予定。

def do_dummy(current_t, step_size, new_step=True):
    y = model_dummy.values[model_dummy.get_variable_valueref("y")];
    if 0.2 < current_t and current_t < 1.0:
        y = y + 100.0/800.0
    if 1.2 < current_t and current_t < 2.0:
        y = y - 100.0/800.0
    model_dummy.values[model_dummy.get_variable_valueref("y")] = y
    model_dummy.completed_integrator_step()
太郎くん
太郎くん

PyFMIでも実際の信号にアクセスする場合は一旦valueReferenceの取得が必要なんだね。

フクさん
フクさん

そうそう。
valueReferenceが取れれば
valuesがvalueReferenceをキーとして連想配列になってるんで、それを利用して信号の読み書きができる。

do_stepの時間制御のソースコード

フクさん
フクさん

そして、時間制御の部分はこんな感じになる。

シミュレーション開始前に以下を実施

start_time = timeit.default_timer()

do_stepから戻る手前で以下の処理を実施

    while True:
        if timeit.default_timer() - start_time >= current_t:
            break
太郎くん
太郎くん

start_timeがオフセットになるイメージか。

フクさん
フクさん

そうだね。
本来だとtimeit.default_timer()のオーバーフローとかも気にする必要はあるのだろうが、
timeit.default_timer()がプロセス開始時に0.0であるのと
シミュレーション時間が数秒ということで気にしないこととした。

do_stepの上書き

太郎くん
太郎くん

そういえば、do_stepを上書きするんだっけ?
そのためにDummy_FMUModelCS2でオーバーライドされてるんだよね?

フクさん
フクさん

うん。
これはシンプルで以下に感じにすればOK。

model_dummy.do_step = do_dummy
太郎くん
太郎くん

ホントに上書きするんだ・・・。

フクさん
フクさん

これでdo_stepの処理がdo_dummyに切り替わって、step毎処理をこちらで制御できる状態となる。

まとめ

フクさん
フクさん

まとめだよ。

  • do_stepの実装方針を決めた。
    • Ramp UpとRamp Down。
  • 出力信号のソースコード。
    • シミュレーション時間を見ながら出力信号を決定する方式。
  • 時刻同期のソースコード。
    • 単にタイマーを使ってシミュレーション時間が実時間に追いつくのを待つ。
  • do_stepメソッドの上書きはそのまま作成関数で上書きすればOK。

バックナンバーはこちら。

コメント

タイトルとURLをコピーしました