バックナンバーはこちら。
https://www.simulationroom999.com/blog/model-based-of-minimum-2-backnumber/
はじめに
tkinterによるFMUシミュレーションのリアルタイム波形描画。
ついに前回からFMU関連処理に突入したが、
いろいろと考えるポイントがありそうということで一旦情報整理をした。
結論としては、
FIFO、Queueのようなデータ構造を利用して、
古いデータを捨てていかないとメモリがいくらあってもたりなり。
dequeを使用するとそこらへんは解決できそう。
今回はFMU関連の処理を振り返りながらコードを追加していく。
登場人物
博識フクロウのフクさん
イラスト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
FMU関連処理前準備
じゃ、早速FMU関連処理についてコードを追加していこう。
内容的にはすでにやったものばかりなので走り気味に行くよ。
まずimportするのは以下。
from pyfmi import load_fmu, FMUModelCS2, Master
from pyfmi.tests.test_util import Dummy_FMUModelCS2
以前やったコードからすると追加するコードは以下になるかな。
model_sub1 = FMUModelCS2( "PID.fmu", "", _connect_dll=True)
model_sub2 = FMUModelCS2( "Motor.fmu", "", _connect_dll=True)
model_dummy = Dummy_FMUModelCS2([], "Dummy.fmu", "", _connect_dll=False)
model_dummy.values[model_dummy.get_variable_valueref("y")] = 0
def do_dummy( current_t, step_size, new_step=True):
model_dummy.values[model_dummy.get_variable_valueref("y")] = _y
model_dummy.completed_integrator_step()
return 0
_y = 0
model_dummy.do_step = do_dummy
models = [model_sub1, model_sub2, model_dummy]
connections = [(model_dummy,"y", model_sub1,"target" ),
(model_sub1,"y",model_sub2,"voltage"),
(model_sub2,"speed",model_sub1,"u")]
master = Master(models, connections)
うん。
おそらくOKだろう。
コード自体はどこに追加すれば良いのかな?
ぶっちゃけroot.mainloop()より前だったらどこでも良いな。
まぁ具体的は配置箇所は改めて見せるとしてとりあえず適当に配置しておこう。
deque関連の初期化
次が今回新顔のdeque。
即行で出て来たな。deque。
dequeはcollectionsというライブラリの一部なので先にimportしておく必要がある。
import collections
そして、一定時間以上のデータは捨てるようサイズの最大値を決めておく必要がある。
データ個数の最大値だったら決められる気がするけど、
一定時間ってのは中々決め辛いような・・・。
シミュレーションのstep時間を決めてしまえば、そこからデータ個数が確定する。
例えば、0.001秒をstep時間として、
8.5秒分のデータを格納するのであれば、
8.5÷0.001=8500
で、8500個のデータを指定すれば良い。
なるほど。
時間の刻みが分かっていれば格納個数も決められるのか。
というわけで、コードは以下になる。
step_size = 0.001
queue_max = int(8.5/step_size) # 8.5秒分のqueueを用意
# define queues
deque_voltage = collections.deque(maxlen=queue_max)
deque_current = collections.deque(maxlen=queue_max)
deque_speed = collections.deque(maxlen=queue_max)
deque_loadTorqueStep_tau = collections.deque(maxlen=queue_max)
deque_target = collections.deque(maxlen=queue_max)
deque_time = collections.deque(maxlen=queue_max)
deque_cpuload = collections.deque(maxlen=queue_max)
取り出す信号分のdequeを先に作っておくんだね。
そうそう。
次はFMUのシミュレーションをするためのタイマハンドラの実装ではあるが、
タイマハンドラ内の処理に対して、もう少し前準備が残っている。
まとめ
まとめだよ。
- FMU関連処理前準備を一気に説明。
- いままでやってきたものなので細かい説明は省略。
- deque関連の初期化。
- dequeはcollectionsライブラリの一部。
- maxlenで最大要素数を指定できる。
- 指定なしの場合は無限に入れられる。
- 実際には物理的な限界はあるだろうが・・・。
- 指定なしの場合は無限に入れられる。
バックナンバーはこちら。
コメント