LabVIEWを触ったことがない方に向けて、それなりのプログラムが書けるようになるところまで基本的な事柄を解説していこうという試みです。
シリーズ27回目としてバリアントデータタイプを紹介しています。
この記事は、以下のような方に向けて書いています。
- バリアントって何?
- バリアントはどのように使用するのか
- バリアントを使ったデザインパターンとは?
もし上記のことに興味があるよ、という方には参考にして頂けるかもしれません。
なお、 前回の記事はこちらです。
バリアントとは
これまでの記事で、LabVIEWでプログラムを書く際の様々なトピックを紹介してきました。やりたいことをやるにはもう今まで紹介してきた内容だけで十分、という方もいると思います。
でも、知っていると便利、さらにプログラムの幅が広がる、というものはまだまだあるので、そんな内容を今後取り扱っていこうと思います。
というわけで今回新たに扱うのはバリアントデータタイプです。
LabVIEWでは様々なデータタイプがあることはこれまでに紹介してきたとおりです。数値、文字列、ブールなどは特に頻繁に登場します。それ以外にも配列、クラスタ、波形、ダイナミックデータというデータタイプがあります。
ブロックダイアグラム上で関数パレットを開くと様々なデータタイプごとに関数がまとまっているのはもうすでに知っていると思いますが、その中にあって今まで登場させていなかったのがバリアントです。このバリアントというデータタイプ、一見すると何の役に立つの?という性質を持ちます。
バリアントは、簡単に書いてしまうと、「いろいろなデータタイプに化けることのできるデータタイプ」です。ここで言ういろいろとは、数値とか文字列、ブールはもちろん、配列、クラスタ、波形データなども含みます。
使い方としては、別のデータタイプをバリアントに変換する、あるいはバリアントから復元する、といった使い方になります。
例えば、以下のように数値をバリアントに変換するとします。
このバリアントは、元のデータに戻すことができます。元のデータに戻した際、元々そのデータが持っていた値も復元されます。
数値が3.14という値を持っていたとして、これをバリアントへ変換、バリアントになったものに対してバリアントからデータに変換の関数で復元します。
数値に限らず、あるデータタイプをバリアントへ変換し、その元々のデータタイプを指定してバリアントから変換関数で復元する、という使い方をするという以上に特別覚えておくことはないと思います。とりあえず性質としてはこんなもんです。
いつバリアントを使うのか
ここまでの話だと、そんなことわざわざする必要があるのか?と聞きたくもなるかと思います。私も最初はなぜこんなことをわざわざするのかよくわからなかったです。
実際、バリアントはLabVIEWの基本的な使い方を知るだけであれば使う機会はあまりないと思います。
使う機会が多い用途としては、
- どんなデータでも受け付けられるようにしたいとき
- 一つのクラスタの定義で複数のデータ形式を扱いたいとき
といった場面が挙げられます。それぞれ紹介していきます。
どんなデータでも受け付けられるようにしたいとき
どんなデータでも受け付けられるようにしたいときなんてあるのかというと、実は最近のLabVIEWでは標準関数としてそういうものがちらほら増えています。
一番わかりやすいのは、データフローを一時停止という関数です。これの実体はサブVIなのですが、中身を見ると、単にバリアントからバリアントへ渡しているだけという構造になっていて、これと待機関数が組み合わされています。
バリアントはどんなデータタイプにも化けられるので、基本的なデータワイヤなら何でもつなげることができます。この関数の場合、何でもいいので入力側につなげると、出力側も自動的に同じデータタイプとなります。
そのため、どんなワイヤであっても、この関数を使うことでその時点で任意の時間プログラムを止めることができます。
この関数がなくても同じようなプログラムを書くことはできますが、せっかくある機能なので使える場面では積極的に使っていきます。
別の例としては、同期パレットにある、データフローを同期関数も同様です。この中身はさらに単純で、フラットシーケンスストラクチャがあるだけです。そうであっても、LabVIEWのデータフローの構造上、この関数への入力が全てそろわないとこの関数は実行されず、したがってプログラムも先に進みません。
言い換えれば、この関数に入力した複数のワイヤ値はこの関数によっていったん実行を待機させられ、入力値がそろったらまた出力することで、入力された値の一部が他の値よりも早く実行されるような状態を防ぎたいときに利用できます。
あるいは、ファイル操作にも例を見ることができます。TDMSというファイル形式でデータを保存する際に、そのデータの属性をプロパティとして設定することができます。このプロパティ、数値や文字列、タイムスタンプなど複数の種類に対応するのですが、そう、このように複数のデータタイプを受け付けられるような場面でもバリアントデータタイプが活躍します。
LabVIEWの配列は、全て同じデータタイプでしかデータをまとめることができませんでした。そこで、「何でもあり」のバリアントデータの配列とし、各要素はそれぞれ別のデータタイプの情報を内包しているといった組み方ができます。
一つのクラスタの定義で複数のデータ形式を扱いたいとき
もう一つの使い方、一つのクラスタで複数のデータ形式を扱うとは、もう少し複雑な状況で使用するのですが、キュー関数との相性がいいので実例を紹介します。
あまり意味はないプログラムですが、どういった形で使用できるかの例をお見せします。
このサンプルでは、フロントパネルの数値というボタンを押すとチャートに乱数が一つ渡されます。一方、文字列というボタンが押されると、文字列表示器にその文字列に「_test」という文字がついて表示されます。また、ブールというボタンを押すことで、LEDが5回点灯します。
もしこのようなプログラムをバリアントを使用しないで作る場合、キューをそれぞれのデータに対して用意するか、あるいは乱数、文字列、ブールの情報すべてを包括したクラスタをキューのデータタイプに指定する必要があります。
それはそれでできるのですが、ブロックダイアグラムがごちゃごちゃしてしまうことになると思います。特にキューをたくさん使用するときには、その性質上ワイヤ配線が多くなるので注意が必要です。
それを、一つのキューで柔軟に対応することができるようになるのがバリアントの強みです。どのデータタイプであるかの識別を行う文字列とそのデータタイプの具体的な値をバリアントにしたものをセットとしてキューを使用してループ間でデータを受け渡しさせれば、キューは一つで様々なデータタイプに対応できるようになります。
バリアントを知らなくても組めるプログラムも多いです。ただ、ある程度の大きさのプログラムを作る場合に、プログラムの構造を複雑にさせすぎないためにもこうした便利なデータタイプがあることを知っておくに越したことはありません。知らなければアイデアも出て起用がないですが、知っていれば「あ、ここはバリアントを使って簡単に書けるかも」といった選択肢が増えることになると思いますので頭の片隅にでも覚えておくことをオススメします。
キューメッセージハンドラのデザインパターン
バリアントデータタイプを使用して、ある程度規模の大きいプログラムを作るのに適したデザインパターンがキューメッセージハンドラです。
「まずこれ」という内容としては高度な部類になるので詳しくは扱いませんが、仕組み自体は今までに紹介してきた内容から成り立っています。
一つのプログラムで必要になる様々な機能(データを測定する、そのデータを外部に送る、フロントパネルの表示を変える、など)を各個Whileループで並列処理させながら、それぞれのWhileループに指示を出すための司令塔のような部分(実体はイベントストラクチャが入ったWhileループ)があります。
各Whileループへの指令は「メッセージ」と呼ばれ、そのメッセージを様々なWhileループ間で連携させるのにキューとバリアントが活躍します。
もちろん、機能どうしの連携もキューを使用して実装できます。ある機能ループで取得したデータを別の機能ループで保存したり、解析したり、といった具合です。
ただし、どのようなデータとして受け渡すのかなどよくよく考えないといけないため、プログラムを組む前には入念な「設計」が必要になります。
もし興味があるよ、という方はプロジェクトテンプレートやサンプルに例があるので見てみると思います。プログラムで実現したい内容によってはオーバースペックかもしれませんが、様々なプログラムの組み方を知ることで実現できる内容も増えるはずです。
LabVIEWでプログラムを作った経験がまだあまりなく、今は「バリアントデータタイプの性質はわかったけれど結局使いそうにないな」、という方もいるかと思います。
今はそれでも全くいいと思います。でも今後LabVIEWでプログラムを作っていく中で必要になったときに「そういえばこんなものがあったな」と思い出せるために頭の片隅にでもいれておけば役に立つことがあると思います。
知らないものはいくら考えても思いつきません。でも何となくでも知っていればこのデータタイプを思いついて活用できるようになることがある、そんなときに思い出してもらえればうれしいです。
もしよろしければ次の記事も見ていってもらえると嬉しいです。
ここまで読んでいただきありがとうございました。
コメント