この記事で扱っていること
- フォーミュラノードでブロックダイアグラムをすっきりさせる方法
を紹介しています。
注意:すべてのエラーを確認しているわけではないので、記事の内容を実装する際には自己責任でお願いします。また、エラー配線は適当な部分があるので適宜修正してください。
LabVIEWはグラフィカルにプログラムを書けるため、様々なアルゴリズムを実装するのにアイコンをつなげていきます。
見ただけで機能を判断しやすいなど利点は多いのですが、どんな場合でもアイコンをつなげていくと考えると見た目が複雑に見えることがあります。
特に、ワイヤをつなげてプログラムを書くことは、きれいに書いていればプログラムの中でデータがどのように処理されていくかを追いやすいのですが、それなりに大きいプログラムになるとワイヤの数が多くなりがちです。
さらになかなか煩雑になりがちと個人的に考えているのが、ある程度四則演算が織り交ぜられた計算を伴う場合です。
他の言語で計算アルゴリズムを作りdll化してそれをLabVIEWで読み込んで・・・ということもできると思いますが、ここではLabVIEW内で完結させられるフォーミュラノードを使用してみました。
計算の例として、学生の時の数学の問題を考えてみました。
「放物線y=ax^2+bx+cに接し、点P(p,q)を通る直線は何か」という問題です。よく学生時代にこの点Pが移動するという問題を見たことがある人も多いと思います。
問題を解かせる目的ではなくこれをLabVIEW上でグラフとして表現する、という場面を例に、これを四則演算の関数を組み合わせた場合とフォーミュラノードを使用した場合とで比べてみました。
どんな結果になるか
フロントパネルはどちらも変わりません。結果をXYグラフに表します。

さて、今回の問題の場合、放物線に接する直線はy=A(x-p)+qで表すことができます。このAとは
A=2a(p±√(p^2+(bp-q+c)/a))+b
と表されます。この結果を表わすと下の図のようになります。

例えば、点Pを自由に動かせるようにカスタマイズした場合にはこのようになるかと思います。

プログラムの構造
この記事では四則演算を和や差の関数を一つずつ置いた場合とフォーミュラノードを使用した場合とで比べるために二つの方法で実装したブロックダイアグラムをお見せします。
まずは関数を一つずつ置いた場合のブロックダイアグラムです。左上のForループで放物線を、右のForループで直線を、それぞれ処理しています。どちらも、Xの値の配列をランプ関数で生成し、それぞれのXに対してaやbなどの変数とともに演算しています。

もちろんもう少し見た目よくワイヤを配線させることもできると思いますが、それでも煩雑さはあまり変わらないと思います。
なお、イベントストラクチャは停止ボタン以外のいずれかの値が変更したときに実行するように指定し、他に停止ボタンが押されるとWhileループを停止させるイベント(停止ボタンの値変更イベント)を設定しています。
つづいてフォーミュラノードを使用した場合にはこのようになります。

だいぶすっきりしていると思います。
関数を並べて作る場合だと、計算結果が予想と違う場合にデバッグもやりにくいのですが、フォーミュラノードであれば途中の計算結果も出力させることができるのでデバッグもやりやすいです。
フォーミュラノードは右クリックして「入力を追加」もしくは「出力を追加」で外部からパラメタを追加することができます。

入力を追加した場合、その入力には必ず何か値を定数あるいは制御器でフォーミュラノードの外から渡す必要があります。一方、出力を追加した場合そこに表示器を付けていなくてもプログラムは動きます。もっとも、表示器を付けない出力は追加する必要はないはずですが。
フォーミュラノードの規則はいくつかありますが、上記のような単純な演算をするだけなら覚えることはそんなに多くはありません。
まず、各行の終わりには「;」セミコロンをつけます。
出力したい変数、あるいはノード内だけで使用するものの出力はしない文字はデータタイプを指定する必要があります。

入力はもちろんノードの中で使用することもできますが、そのまま出力することもできます。フォーミュラノードを使ったプログラムの画像の例ではワイヤを一直線にするために入力したaなどの変数をわざと出力させていました。
フォーミュラノードでforループなど使用することもできるのですが、そうしなくても外部から配列をforループに渡して一つ一つの要素を渡すといった使い方であれば実装も特に難しくありません。

ヘルプを見るとフォーミュラノードはC言語を知っていると効果的に使用できると書いてあります。ただ、ワイヤが煩雑になりがちな部分だけでもフォーミュラノードで代用できるだけでも見た目がすっきりするので試す価値はあると思います。
変数が一つなら数式ノード
フォーミュラノードは変数を複数持つような計算をコンパクトにまとめるのに役立ちますが、変数が一つの場合にはさらに数式ノードという選択肢もあります。

こちらは出力の変数を定義する必要がないのですが、フォーミュラノード同様数学的な関数(sin、cos、tanはもちろん、expやlogなども)を組み合わせて計算させることができます。
どちらがより早く処理を行えるのか、について実験するために下のようなプログラムで確認してみました。どちらの場合も摂氏を華氏に変換するという同じ計算を行っています。

こちらを実行する限りどちらもそこまで大差はないようです。計算の複雑さにも依るかもしれませんが、そもそも数式ノードはそこまで複雑な(変数がたくさんある)式を扱うわけではないので、場合によって実装しやすい方を選ぶようにすればいいと思います。
ここまで読んでいただきありがとうございました。
コメント