特定フォーマットのコマンドを読み込んで処理を進める | マーブルルール

特定フォーマットのコマンドを読み込んで処理を進める

Tips

スポンサーリンク

この記事で扱っていること

  • 特定フォーマットのコマンドを読み込んで処理を進める方法

を紹介しています。

LabVIEWでプログラムを書く時の、プログラム全体のデザインのテンプレートとなる組み方の一つにステートマシンがあります。

ステートマシンはユーザーが都度操作をすることでその操作(イベント)に応じて処理を進めるという形がとられることもありますが、場合によってはLabVIEW外で専用のシーケンスファイルのようなものを用意し、そこに書かれた一連のコマンドに沿って実行させたい、という要望もあるかと思います。

当然、どのようなコマンドがありうるかはアプリケーションによって違うとはいえ、仕組みを設ければ、シーケンスファイルの中身を変えるだけで自動的に処理が進むようなプログラムを組むことができます。

この記事では、大まかな実装のアイデアと、その応用例としての具体的なプログラムを一つ紹介していきます。

スポンサーリンク

どんな結果になるか

実装のアイデアとしては次の章で紹介するとして、応用例として考えた、パラメータの変更や測定を行う一連の処理をシーケンスファイルを読み込ませることで行うプログラムの画面を紹介します。

とはいってもファイルを読み込むだけで最初から最後までの処理は全て終わるので、フロントパネルにあるのはシーケンスファイルの指定のためのファイルパス制御器や停止ボタン、そして結果を表示するための表示器だけです。

シーケンスファイルを選択して実行すると、そのファイルの内容に従って各処理(変数や測定条件の設定、実際の測定および結果表示等)が行われます。

さきほどから書いている、「シーケンスファイル」としては以下の図のようなものを考えています。

(#で示しているのはいわゆるコメントであり、実際にプログラムの中では読み込まれません)

最初にパラメータの初期値の設定、次に各コマンドが並んでいます。

つまり、このようなシーケンスをテキストファイルに書いておいてプログラムに与えれば、その処理を実行してくれるようなviを作っていきます。

上記のシーケンスファイルの中身は私が勝手に考えたオリジナルのコマンドばかりですが、似たような考えで、実用的なアプリケーションにも応用が利くと思います。

プログラムの構造

まずは実装のアイデアです。

とはいっても特別難しいことをするわけでもなく、ファイル読込と実際の処理を別々のWhileループに分けた、LabVIEWでよくみる生産者消費者の形をしています。

同じループにファイル読み取りを入れる方法も考えられますが、例えば「特定の動作を特定の時間だけ続ける」ような処理を実装したい場合、あるいは今回は実装していませんが「ファイルからの読み取りの途中にユーザーによるボタン操作を割り込ませる」ような実装とする場合には、別々のループとしていたほうが都合がよかったりします。

また、例えばQMHのような応用の効きやすいデザインパターンに慣れるためにも、各ループで専門的なことを実行させループ間でデータ(メッセージ)をやりとりする作り方、考え方は広く応用しやすいのでこのような形としました。

上側のWhileループではファイルからデータを読み取りこれをメッセージとメッセージデータとして下のWhileループに渡しています。

シーケンスファイル中にコマンドは1行ずつに書いてあるとして、それをテキストファイルから読み取るの関数でライン読み取りにチェックを入れた状態で使用します。

読み取った値はキューで別のループに渡しこちらで処理します。

なお、キューに入れる前に適切な形に変換してやる必要がありますが、これは読み取るファイルの中身やコマンドの扱い方に依って変えるものとします(あとで具体例を紹介します)。

実際の応用例

それでは上記を踏まえて実際の応用プログラムを紹介します。

まずは、応用プログラム内で呼び出される、ハードウェア操作を模したサブVI達を紹介していきます。

これらは、トップレベルVIの中の特定のケースストラクチャのケースで使用していきます。

何かハードウェアの操作をする際に必要となりうる操作へのダミーVIとして作っているので、これらのサブVIそのものに意味はなく、例えば「コマンド指定でハードウェアによる測定を行うプログラムを作る」場合の、実際にハードウェアに対する設定を行う具体的な関数(DAQであればDAQmxの関数、計測器ドライバであればそのドライバ内の各関数)があれば適宜それらに置き換えて使用してください。

まずはパラメータを設定するためのサブVI、set parameter.viです。

あくまで何かしらのパラメータを受け付けるという構造にした一例であり、以下の図のparameterの中身には特に意味はありません。

次にmeas_start.viです。

測定の開始を指定するという関数を模擬しています。

次はmeas_stop.viです。

測定を終了するという操作を模擬しています。

次はmeas_exe.viです。

測定を実行する動作を模擬しており、何か適当な値(乱数)値を使用してparameterクラスタのdata配列を更新しています。

以上の模擬サブVIを使用して、特定フォーマットのコマンドを読み取るプログラムの具体例を紹介します。

このプログラムでは、シーケンスファイルに沿った動作を行って、パラメータの変更、測定の開始、測定、測定の終了といった一連の流れを全てシーケンスファイルから読み取った情報で行っていきます。

下側のWhileループが、コマンドを受けて実行される具体的な処理をケースストラクチャで場合分けして実装している部分になりますが、この中で使用するクラスタの初期化にget initial value.viの値を使用しています。

このサブVIは、コマンドファイルの最初の方にあるinitialize valueの値を読み取って、対応するクラスタの値を初期化しています。

また、上のWhileループでコマンドファイルを一行ずつ読み取って下のWhileに渡すdata_conv_example.viは次のような形としています。

コマンドの内容によって下のWhileループに渡す必要があるデータ(message data)の種類が変わるので、以下のように場合分けをしてやります。

これらのコマンドが下のWhileループに渡って処理が進みます。

下のWhileループの各コマンドに対して実行される処理の実装例を紹介します。

まずはadd(コマンドに対する処理)です。

message dataとして受け取ったパラメータ名と具体的な値とを使用してクラスタの値を更新していきます。

次にsubです。

addと同様な考えで今度は値を引き算していきます。

次はmulです。

multiplyの略の意味で書いていますが、掛け算を行っています。

次はchg_arrvalです。

配列の値を変えるためのケースで、message dataで受け取った配列の指標番号と値の情報でパラメータcという配列を変更しています。

次はsleepケースです。

要は何も実行しない時間を作るためのケースです。

ただし単に待機関数を置いて指定の時間待つような実装とすると途中で止められなくなってしまうので、時間が経過するまではsleepケースを繰り返し実行するという処理にすることで、下のWhileループを回し続け、何か緊急的に実行しなければいけなくなった処理が割り込む余地を残しています。

次にset_paramです。

既に紹介したset parameter.viを実行します。

次にmeas_startケースです。

こちらではmeas_start.viが実行され、これ以降に呼び出されたmeas_exe.viで実際に測定結果の取得(という操作の模擬)を行います。

次のmeas_exeケースでmeas_exe.viを使用します。

今回は、時間を指定してその時間内は測定を行っているといった動作としているので、sleepケースと似たような処理が入っています。

showケースでは、クラスタの中のdata配列を波形グラフに表示することで、測定した結果を表示するという動作を模擬しています。

最後にmeas_stopケースです。

meas_stop.viによって測定を終えるという操作を模擬しています。

実際のハードウェア操作はもっと複雑だったりパラメータが多いなど、上で紹介したものをそっくりそのまま使用して各サブVIと実際の関数を置き換えるということはないと思いますが、どのように組むかの考え方の話なので、仕組みがわかったら、あとは好きなケース、好きなコマンドで実装してみてください。

本記事では特定のフォーマットのコマンドを読み込んで処理を進めるようなプログラムの概要と応用例について紹介しました。

ユーザーがどのようにアプリケーションを使いたいか、という要望は千差万別だと思いますが、中でも特定の外部ファイルを読み込ませる形で処理を進めていきたい場合には参考になればうれしいです。

ここまで読んでいただきありがとうございました。

コメント

タイトルとURLをコピーしました