この記事で扱っていること
- 複数の数値を同時に変更する方法
を紹介しています。
注意:すべてのエラーを確認しているわけではないので、記事の内容を実装する際には自己責任でお願いします。また、エラー配線は適当な部分があるので適宜修正してください。
LabVIEWで扱う数値制御器は、文字通り数値を扱うデータタイプであり、一つの値を扱う(スカラー)場合もあれば、配列となった状態、クラスタの中に含まれる状態もありえます。
プログラムの中で複数の数値制御器を扱う場合、それらの値を個別に変化させるのではなく、ある数値制御器を変更したら、それ以外の複数の数値制御器の値も同じだけ変化させたいという場合があります。
ただし個々の数値制御器は(配列であったとしても各要素は)独立しているので、同時に変化させるためにはそのようにプログラムを書かないといけません。
本記事では、いくつかの数値の扱い方のパターンごとに、複数の値を変える方法の例を紹介しています。
どんな結果になるか
例として4つのパターンの数値の扱い方を紹介していきます。
まずは、数値制御器だけが並んでいる状態です。
ある数値制御器の値を変更した際に、他の数値制御器も同じだけ変化させる、といったものです。
なお、変化させたい数値制御器にはブールをTrueにするようにしています(追随して変化させたくない数値制御器にはブールをFalseにすればいい状態にしています)。
上のフロントパネルのように数値制御器が並んでいる場合に、最初numの値だけを1とし、その後にnumを変更させたときに、num2とnum3も一緒に同じだけ変更させたいとします。
この場合、最初numの値を1にするときにはすべてのブール制御器をFalseにしておいて、以降numの値を変更する際にnum2とnum3に対応するブール制御器をTrueにしておくと、numの値を変えた分(例えば2プラスする)、num2とnum3の値も同じだけ変化する(元々0なのであれば2となる)ようになります。
次に、配列が混ざっている場合です。
ここでは、スカラーの数値制御器の値を変更することで、配列要素すべての値を変更する、といった処理としています。
(配列の要素の一部を変更すると、スカラーの数値制御器の値が変化する、という動作はしません)
以下の図では、num3の配列に対応するブール制御器をTrueにした状態で、num2の値を0から5にしたら、num3の配列のすべての要素に5が足されています。
次はクラスタの中に数値制御器が入っている場合です。
一般的にクラスタには複数のデータタイプが入っていることが多いので、今回は数値制御器以外のデータということで文字列データをいれています(が、本質的には文字列データタイプである必要はなく、何のデータタイプでも構いません)。
こちらも今までの例と同様、変化させたい対象であるクラスタに対応するブール制御器をTrueとし、他の数値制御器の値を変更させると、クラスタの中にある数値制御器が同じだけ変わります。
最後に、配列同士が並んでいて、自分自身の値をすべて変更するか、他の配列の要素も変えるような場合です。
例えばnum配列に対するブール制御器がTrueになっていたとすると、この配列の要素のうち一つを変化させると、残りの要素も同じだけ変化します。
またnum2にいくつか要素が定義されていて対応するブール制御器がTrueになっているときに、num配列の要素のいずれかを変化させるとnum2配列のすべての要素を変化させる、といったこともできます。
例えば以下の図では、numに対するブールをTrueにした後は、numの配列のどれか一つを変更するとその配列の他の要素も同じだけ変化します。
また、num2にも値があってnum2に対するブールをTrueにしておくと、numの配列のどれか一つの要素を変更するとnum2のすべての要素の値も同じだけ変わります。
ただし、num2に対するブールがTrueだったとしても、num2に初期化された要素が一つもない状態では何の変化もありません。
あくまで、num2に一つ以上の要素がある場合にnumの配列の影響を受けることになります。
プログラムの構造
プログラムとしては、イベントストラクチャのイベントノードで「旧値」や「新規値」が得られることを利用して、変化分を計算し、それを「変化させる」ことを許可しているブール制御器の状態によってその数値制御器(や配列、クラスタ要素)に適用するかを決めています。
以降で紹介するブロックダイアグラムで使われているイベントストラクチャには、どれも2つのイベントしかなく、片方は停止ボタンの値変更イベントになっています。
まずは1番最初の例の場合です。
数値の変更はそれぞれの数値制御器のリファレンスを取得して、値プロパティに対して変更値を与えるようにしています。
基本的に値プロパティによる値変更は推奨されない(パフォーマンスがよくない)ことが多いのですが、今回の目的の動作を行わせるにあたって、値プロパティを使用する以外の方法、例えばローカル変数などを使用するとなると実装がかなり煩雑になり、その点Forループでまとめて処理できるプロパティノードによる値変更に分があると言えます。
仮に数値制御器の数を増やしたとしても、ブロックダイアグラムで変化させるのは、リファレンスの数と、その増やした数値制御器に対する値変更イベントを追加させるだけです。
次に2番目の配列が混じっている場合です。
今回はフロントパネルに数値制御器と配列制御器という異なるデータタイプの制御器が置かれているのでリファレンスを扱う際にも値プロパティはバリアントとなるため、そのバリアントのデータタイプの情報を取得したうえで処理していきます。
Double FloatやArrayケースで最初に使用しているのは「より特定のクラスに変換」関数で、これによりリファレンスのデータタイプを特定のクラスに変換してその次にあるプロパティノードのリファレンス入力に渡しています。
次に、クラスタが混じっている場合です。
一つ前の、配列が混じっている時と似たような実装で、こちらもクラスタのリファレンスと数値制御器のリファレンスを一緒に扱っている関係上、値プロパティがバリアントで得られるので、データタイプによって処理の内容を変えるようにします。
最後に、配列どうしで値を変化させる場合です。
配列の要素のどれがどの程度変化したかを検出した後、対象となるブール制御器がTrueになっている配列の各要素に対して同じ分だけ変化させるように処理します。
異なる増減量にする場合
上で紹介したプログラムは、どの場合であっても、「同じだけ」変化させていました。
例えば、数値制御器の値を4変えると、他の(ブールがTrueになった)数値制御器やら配列やらクラスタ要素も4変わる、といった具合です。
そうではなく、変化量を数値制御器個別に設定したい場合もあるかと思うので、そんな実装時の例を一つ紹介します。
とはいってもやっていることは単純で、プロパティノードでラベルの値を調べてケースストラクチャで「変化量」をいじることで対応できます。
以下の図では、変化のさせ方を「2倍の値分変化させる」「変化した値よりも5小さい値分変化させる」などと指定しています。
本記事では、複数の数値を同時に変更する方法を紹介しました。
何かパラメータを設定するときに複数の値を同時に調整するときなどに参考になればうれしいです。
ここまで読んでいただきありがとうございました。
コメント