TRNSYSでJavaScriptを使ってみる(試作です)
前回の投稿で、Equationの使い方を紹介しました。Equationはいろいろ使えて便利なんですが、ちょっと複雑な条件になると、それなりに工夫が必要になります。というか、だんだん一見して何の処理か解りにくいのが難点。
どうもプログラマ的な視点でみると、なんで普通にif-then-elseできないんだろうかと、そう思ってしまいます。
まー、でも判定式を実装しようとしたら、それなりに手間だ。ちょっとしたスクリプトを実装するのと変わらない。すげー大変。と、ここまで考えて、ふと気がついた。
オープンソースのスクリプトとか使えるんでは?
今時はフリーで使えるスクリプトエンジンが存在します。ちょっと調べてみると、組み込みできそうなのが幾つかあります。
代表的なのは、
・JavaScript
・Lua
・Ruby
さらに調べてみると、GoogleのJavaScriptエンジンなんかが割と簡単に実装できそうな事がわかります。こことか↓
人の話を聞かない人の V8 エンジン。 V8 を C++ に組み込んで遊ぼう
JavaScriptエンジン、しかもv8って、googleのブラウザ、Chromeに搭載されている超高速なやつです。これはもう、使わない手はないんでないかと。
Google JavaScript V8 Engineをコンポーネントに組み込む
早速、実装してみました。詳細は省きますが、ああだこうだと試行錯誤すること数日、土日を潰して、なんとか動くプロトタイプが出来上がりました。
仕組みは単純で、JavaScriptのエンジンに、コンポーネントのInputs/Outputsの値をやり取りする関数を追加しているだけです。かなりシンプルな拡張です。この関数を使って、JavaScript側でif-then-elseの処理を行います。
試しにEquationの例と同じ、タイムステップが特定の範囲内になったら、出力の値を変更するスクリプトを書いてみました。
例)暖房期以外は冷房期
暖房期 1/1-4/25, 10/21-12/31(1-2760, 7056-)
冷房期 4/26-10/20(暖房期以外)
var time = getInputValue(1);
if(time<=2760 || 7056 <= time)
{
heating = true;
}
else
{
heating = false;
}
cooling = (!heating);
setOutputValue(1, heating);
setOutputValue(2, cooling);
ちなみに前回のEquationで書いたのはこちら。
HEATING = or(le(time,2760 ),ge(time,7056))
COOLING = not(HEATING)
こっちの方が行数が少なくて、なんかスッキリした感じですが、可読性はやっぱりJavaScriptの方がいいですよね?(そんなことない?)
コンポーネントを配置して、スクリプトを用意したら、いよいよSimulation Studioから実行!
おー、ちゃんと動いた。Heatingの状態がOn/Offしているのが確認できます。
If-then-elseが使えりゃいいやって思ってたけど、スクリプトで簡易なコンポーネントのような使い方もできますね。例えば、こんな感じ。
サインカーブを描くスクリプト。
var inp2=getInputValue(1);
var ret;
ret = Math.sin(inp1 / 180 * Math.PI);
setOutputValue(1,ret);
おー、これも無事に動いた。
いろいろ使えそうな感じです。とはいえ、いいことばかりでもなくて実行速度が出ない。これがガッカリするぐらいに遅い。
コンポーネントの仕組み上、イテレーションごとにスクリプトのロードが発生します。おそらく、それが遅くなっている理由。
それとエディタもデバッガーもないので、エラーが起きても原因が何か調べるのも手探り状態。ちょっと普段使いには向かないですね、これじゃ。
スクリプトを使うことを思いついたときは、良いアイディアだと思ったんだけど厳しいですね。
もちょっと試行錯誤が必要そうです。
2件のピンバック
TRNSYSにIF文が欲しい – 建築環境工学系日記
TRNSYS Type79 とスピード対決 | 建築環境工学系日記