LabVIEWを触ったことがない方に向けて、それなりのプログラムが書けるようになるところまで基本的な事柄を解説していこうという試みです。
シリーズ3回目としてこの記事ではLabVIEWのプログラムを作る、見るうえでとても重要なプログラムの流れを説明していきます。
この記事は、以下のような方に向けて書いています。
- LabVIEWのプログラムはどういう順番で実行されるの?
- テキスト系の言語は上から順番だけれどLabVIEWはどう決まるの?
- プログラムの流れの順番を指定することはできるの?
もし上記のことに興味があるよ、という方には参考にして頂けるかもしれません。
なお、前回の記事はこちらです。
プログラムには実行される順番がある?
前回、ワイヤと端子の話が出てきたので、LabVIEWのプログラムの順番についてみていこうと思います。
例えば、次のように、文字列の制御器と表示器のペアが二つある場面を考えます。
ここで問題です。これらはそれぞれに、制御器から表示器にデータ(文字)が渡って、制御器にある文字列を表示器に表示させるわけですが、どちらが先に実行されるでしょうか?
答えは・・・「わからない」です。
実際、これらはほぼ同時に実行されるので、人間の目からみて「こっちが先」ということは判別できないです。が、例えスローモーションで見えたとしても、どちらが先に実行されるかはやってみないと「わからない」が答えになります。
あるときには左の処理が、別のときには右の処理が先に実行されるかもしれません。
でもそもそもこれらの順番って決まっている必要あるでしょうか?どっちが先だっていいですよね?
とにかく、それぞれの制御器から出た値がそれぞれの表示器に表示されさえすればいいので、このプログラムの場合、順番なんてどうだっていいんです。
では次に、別の例を見てみます。下の画像のプログラムはどのような順番で実行されるでしょうか?
このプログラムでは、実行される順番が一部決まっています。実はこのプログラムの流れがどうなるかを理解すると、様々なLabVIEWのプログラムについて流れを追えることができるようになります。
プログラムの流れを理解する
一見難しそうなのですが、LabVIEWのプログラムの流れを追うためのルールはとても単純で
その関数に入力される値すべてがそろってから関数が実行され、実行後に出力値が出る
と表せます。
入力、出力って何の話かなと思っている方もいるかもしれないですが、これも特に難しいことではありません。例えば、もっと簡単にこんな例を考えてみます。
これ、関数には+と書かれているので足し算だとわかると思います。「和」と呼ばれる関数になります。足し算というのは
X+Y=Z
のように、2つ(以上)の数値(XやY)があって初めて計算できますよね?一つしか数値がないのに足し算はできない、当たり前のことです。で、これらを足して答え(Z)が出ます。この式でいうところの、XとYは入力、Zが出力にあたります。
先ほどのルールに沿っていえば、
その関数(和)に入力される値(XとY)すべてがそろってから関数が実行され、実行後に出力値(Z)が出る
と言えます。
LabVIEWでは、基本的に関数の左側に入力する値を渡して、右側から出力された値を取り出します。ちなみにワイヤを接続する、入力や出力の部分をノードと呼びます。
では先ほどの四則演算のプログラムについて確かめていきます(四則演算の和とか差はあまり関数と呼ばないのかもしれませんが、ここでは便宜上どれも関数と呼ぶことにします)。
まず4つある四則演算の関数のうち、どれが最初に実行されると思いますか?答えは和です。なぜなら・・・
- 差の関数は、和の関数の出力結果がないと入力値がそろわない
- 積の関数は、差の関数の出力結果がないと入力値がそろわない
- 差の関数は、積の関数の出力結果と和の関数の出力結果がないと入力値がそろわない
からです。
差の関数にも入力が二つあり、片方は定数がついています。ですがもう一方の入力は、和の関数の右側からワイヤがつながっています。つまり、和の関数の結果が差の関数の入力の一部になっています。
くどいようですが、例のルールに従うと、
その関数(差)に入力される値(和の結果と定数)すべてがそろってから関数が実行され、実行後に出力値(引き算の結果)が出る
と表現できます。ここで言う「和の結果」は当然和の関数を実行しないと得られないため、このプログラムでは必ず順番は和の後に差が実行されるという前後関係を持ちます。
他の関数も全て同じルールとなるため、実行される順番は下の図の数字で表された順番で決まりです。
何度もくどく説明しているのは、LabVIEWのプログラムの流れを読むためのルールとしてとても大切だからです。逆に言えば、LabVIEWでプログラムを書く時にもこのルールを意識して書く必要があります。
ルールをもとに流れを確かめる
これを踏まえて、次のプログラムを見てみます。
いきなり見知らぬアイコン、関数が出てきて面くらうかもしれませんが、今はこれらの関数の意味自体を知る必要は全くありません。気にするのは「FFT」という関数と「平均DC-RMS」という関数のどちらが先に実行されるか?ということです。
先ほどのルールを踏まえて考えると、答えは・・・これも「わからない」です。
もちろん、一番最初に実行されるのは「正弦波形」です。この関数からの出力が茶色のワイヤになっていて、それが分岐して二つの関数に渡されています。
このとき、分岐された後の処理の順番は、ブロックダイアグラム上で上にあるから、とか、ワイヤの長さが短いから、などといったあいまいな基準で順番が決まるわけではなく、「わからない」が答えです。順番がわからなくても、例のルールは破っていませんね。
プログラムの流れを指定するには
ではどうしても順番を決めるにはどうすればいいか・・・・要は後から実行させたい関数に、先に実行させた関数の結果を何かしらワイヤで配線すればいいのです。
もし、「先に実行させた関数」の結果を「後から実行させたい関数」に使用するのであれば、特に何も考えずに「先に実行させた関数」の結果を「後から実行させたい関数」の入力として与えてやれば順番が決まることになります。
ただ、今回のプログラムでは、FFTという処理の結果と平均DC-RMSの結果はお互いに関係がありません(その意味ではこのプログラムもまた、どちらが先に実行されても問題ないプログラムです)。
つまり、FFTの結果を平均DC-RMSに入れる必要はない、ということです。この場合、どうやって順番を決めたらいいのか?
ここではベストプラクティスを覚えてもらえればいいと思います。それは、「エラーワイヤを配線する」ことです。
エラーワイヤは多くの関数に入力、出力できる「エラーの情報を通すワイヤ」です。もし何かしらの関数でエラーが起きた場合、そのエラーの情報を出力して、次の関数や表示器にそのエラーの情報を伝える役割を持ちます。
エラーワイヤの中身の話は一旦置いておいて、とにかくこれで順番付けが可能になります。例えば、上の図のようにプログラムを改変したとします。
3つの関数の実行順序は?正弦波生成、FFT、平均DC-RMS、この順番ですね。
なぜなら平均DC-RMSの入力の一部(エラーワイヤ)はFFTという関数から出ていて、FFTという関数の入力(エラーワイヤや信号という入力)は正弦波生成という関数から出ているものが配線されているからです。
では以下の図ではどうでしょうか?
はい、これも同じです。ワイヤをよくたどっていけば、結局正弦波生成、FFT、ピーク生成の順になっていることが分かります。でも、どっちが見やすいですか?最初の図の方ですよね?
既にお話ししたように、LabVIEWで扱う関数は基本的に左に入力、右に出力用のノードがあります。
そしてプログラムは「ある関数からの出力結果を次の関数の入力に渡す」という流れを持ちます。
この二つを考え合わせると、「ある関数の右側から別の関数の左側に配線する」ことにします。するとワイヤは一直線に並びやすくなります。これは見た目上もスッキリしますね。
敢えてワイヤを折り返す理由はありません。単にワイヤの位置が微妙にずれたときにはそのワイヤを右クリックして「ワイヤを調整」などとするとキレイに配線しなおしてくれます。
強くオススメするのは、LabVIEWでプログラムを書くときには見た目を重視することです。せっかく、「グラフィカル」言語なので、見た目にもわかりやすいプログラムを心掛けると作った本人もそして他人も流れがよくわかるようになります。
初めてLabVIEWを触ります、という方でも、このようにワイヤがきれいに一直線に並んでいる状態にしようという意識は初めのうちから身に着けておいた方が絶対にいいです。
エラーワイヤがない場合の方法
ところで、関数の中には、エラーのワイヤの入出力がないものもあります。先ほど出た四則演算がいい例です。
他にも、エラーの入出力がない関数は探せば色々見つかります。そのため「もしエラーの入出力などもない関数を、敢えて他の部分よりも先あるいは後に実行させる場合にはどうすればいいんだ?」と思った方も多いのではないでしょうか?
LabVIEWでこれを解消する方法には「フラットシーケンスストラクチャ」を使用します。
これはストラクチャと呼ばれる、プログラムの構成要素の一部です。これ以外のストラクチャなどは今後紹介していくのですが、フラットシーケンスストラクチャは覚えるのが単純なのでここで早速扱うことにします。
ブロックダイアグラム上で右クリックして現れる、関数と書かれたウインドウ(関数パレットと呼びます)の左上にストラクチャという項目があるのでこれを選択し、その中のフラットシーケンスストラクチャを選択します。
選択したら、ブロックダイアグラム上でドラッグアンドドロップすると何やら映画のフィルムのような枠ができます。
試しに、右側にマウスを合わせて右クリックすると、「後にフレームを追加」と出るのでこれをクリックします。すると、枠がもう一つ出たと思います。
このままでは枠が小さいですね。引き伸ばすこともできるのですが、ここではCtrlを押しながらドラッグすることで枠を広げられるのでこの方法で広げてみましょう。
この方法は、フラットシーケンスストラクチャだけでなく、ブロックダイアグラムやフロントパネルの至るところで使える、ドラッグした方向に空間をとるための操作です。今後のプログラム作りに役に立つのでこれも覚えておいてください。ちなみに、空間を減らしたい場合には、Ctrl + Altとドラッグで行えます。
話が少しそれましたが、フラットシーケンスストラクチャで二つの枠組みができました。この枠は「枠内にある関数すべての実行が終わらないと次の枠に進まない」という制限をかけるための機能と思ってください。
枠内には何個、どんな関数を入れても問題ありません。エラーの入力や出力がある、ないに関係ありません。
とにかく、一つの枠の中にあるすべての関数が実行されてから次の枠に進みます。なので、エラーの入出力がない関数でもこの枠の前後にそれぞれ処理をおくことで、順番付けをすることができます。
上の図の場合、左側のフレームの中の処理は正弦波形とFFT、そして和の関数があります。もちろん、このとき、和の関数がどのタイミングで実行されるのかは定まっていません。(正弦波形の前かもしれませんし、FFTの後かもしれません)
そして左側のフレームの中の処理が全て終わると、ようやく右のフレームに進みます。
何度も言いますが、枠内にはいくら関数があっても構わないものの、それらすべてが終わらないと先に進みません。これは便利な時もあれば、不便な時もあります。
例えば、枠の中に一つでもずっと止まらない処理を間違えて書いてしまった場合、LabVIEWはこのフラットシーケンスストラクチャという枠組みから抜けることができなくなります。
それは困る、という場合、実はフラットシーケンスストラクチャを使わなくても順番付けを行う方法があります(サブVI化してエラー入出力を用意する)。ただまだ現時点では少し高度な内容になるので割愛します。
それよりも、フラットシーケンスストラクチャ自体の使用をなるべくしなくてもいいようなプログラムを作ることを心掛けることの方がいいと思います。どうしても使わないといけない、という場面は0ではないですが、極力使わなくてもいいようにすべきです。
とにかく、LabVIEWではエラーの入出力といったワイヤの配線でプログラムの中の各関数の実行順番が決まります。これはこれからLabVIEWでプログラムを書いていくうえで必ず意識してください。
次回はLabVIEWにおけるエラーの扱いの基本的なところを見ていきます。プログラムを作れるようになってから覚えるのではなく、まずエラーの扱いを少し身に着けてプログラムを作って自力でデバッグを行えるようになれば、より早くエラーのないプログラムを書けるようになれると思います。
もしよろしければ次の記事も見ていってもらえると嬉しいです。
ここまで読んでいただきありがとうございました。
コメント