LabVIEWでステートマシンのプログラムを作成し、条件に応じた状態遷移を実現する

更新しました Feb 19, 2021

環境

ソフトウェア

  • LabVIEW

LabVIEWにおけるプログラミングで状態遷移を記述する最も基本的な方法はステートマシンです。状態遷移図を作成し、LabVIEWでステートマシンを作成し、予定通りの状態遷移をする挙動を確認します。
 

状態遷移図を作成する


1. プログラムを作成する前に、実行する必要のあるタスク、評価すべき項目、それらの実行順序を検討し、状態遷移図を作成します。ここでは電源の状態確認を行う事を目的として下記の状態遷移図を使用します。
 
遷移図1.png

プログラム開始後に電源の確認を行い、電源がONの状態の場合はプログラムが終了します。一方、電源がONでない場合は5秒間待機し、再度電源確認を行います。


 

LabVIEWでステートマシンのプログラムを作成する


1. LabVIEWを起動し、ファイル>新規VIを選択します。ブロックダイアグラムにおいて、関数パレットからWhileループを選択し、下記の図のように配置します。Whileループの中にケースストラクチャを作成します。ブロックダイアグラムが表示されていない場合、Ctrl + Eで表示する事ができます。関数パレットはブロックダイアグラム上で右クリックする事で表示できます。また、Ctrl + Hで詳細ヘルプを表示する事でLabVIEWの関数についての説明、使用時に必要な入力とそのデータタイプを確認する事ができます。
 
1vi.png

2. 関数パレットから列挙定数を選択し、ブロックダイアグラムに配置します。列挙定数を右クリックし、「項目を編集」を選択すると、項目の入力・変更・削除を行えます。状態遷移図を確認し、状態遷移図で定義されている「開始」、「電源確認」、「待機」、「終了」の4つの状態を下記の様に作成します。
 
2列挙対.png

3. 列挙定数をケースストラクチャに配線し、ケースストラクチャのセレクタラベルを右クリックし、「すべての値にケースを追加」を選択すると、2で設定した4つの状態がセレクタラベルに読み込まれ、「開始」、「電源確認」、「待機」、「終了」の4つのケースが作成されます。
 
3全ての値にケースを追加.png

4. 列挙定数をタイプ定義に変更し、*.ctlファイルを保存します。下記の様に、列挙定数を右クリックし、タイプ定義に指定した後、タイプ定義を開き、表示される*.ctlファイルをファイル>保存で名前を付けて保存します。ここでは状態.ctlとして保存しました。列挙定数をタイプ定義にすることにより、ステートマシンに状態の追加・削除・変更を効率よく行うことができます。状態の追加・削除・変更の手順は後述します。
 
5タイプ定義.png

5. 列挙定数のループトンネルをシフトレジスタに変更します。ループトンネルを右クリックし、「シフトレジスタと置換」を選択し、ループトンネルをシフトレジスタに変更します。シフトレジスタはループの初回実行時にはループに入力されている値(ここでは「開始」の列挙定数)を初期値として保持します。ループの左側のシフトレジスタから出力される値は、最後にループの右側のシフトレジスタに入力された値となります。ループの1周目の実行時にはシフトレジスタから初期値が出力され、2周目以降はその前の周にループの右側のシフトレジスタに書き込まれた値が出力されます。
 
7シフトレジスタ.png

6. 「開始」のケースストラクチャの内容を作成します。まず、「開始」の状態では「プログラムを開始します。」という1ボタンダイアログを表示します。状態遷移図を確認すると「開始」の状態は「電源確認」の状態に遷移する事が分かります。この遷移は列挙定数をコピーし、下記の様に張り付け、列挙定数の中から「電源確認」を選択し、シフトレジスタに入力する事で実現します。シフトレジスタで次の状態を受け渡す事で、このWhileループの初回実行時は「開始」のケースが実行され、「開始」のケースが実行された後、2周目の実行が開始された際に「電源確認」のケースが実行されます。
 
8state.png

上記の1ボタンダイアログの入力は文字列定数で行われています。関数への入出力の定数、制御器、表示機の作成は下記の図のように関数の入力もしくは出力の端子にマウスカーソルを合わせた状態で右クリックし、「定数を作成」、「制御器を作成」、「表示器を作成」で行う事ができます。
 
9文字列入力.png

7. 「電源確認」のケースストラクチャは下記の様に作成します。電源確認のケースでは電源のオン、オフを確認します。この結果によって次に遷移する状態が変わります。2ボタンダイアグラムで「はい」(True)または「いいえ」(False)を選択する事でTrue/Falseが出力され、選択.viによりTrueの場合は「終了」、Falseの場合は「待機」が出力されます。
 
9電源確認.png

8. 「待機」の状態を作成します。この状態では下記の様にループカウンタが5以上になった時に停止するWhileループを作成します。このWhileループは待機関数により、1秒に1回転で実行されます。状態遷移図を確認するとこの状態は「電源確認」に遷移するので、シフトレジスタには「電源確認」の列挙定数を入力します。
 
10待機.png

9. 「終了」のケースストラクチャを作成します。この状態でプログラムが終了するのでWhileループのループ条件にTrueを入力します。
 
12終了.png

10. この状態でVIの実行ボタンを確認すると矢印が壊れている事が確認できます。この状態で実行すると、修正する必要のあるエラーがリストされます。エラー内容をダブルクリックすると修正する必要のある場所に飛ぶことができます。今回のプログラムでは下記の2点のトンネルに入力値の設定されていないケースが存在する事が問題となっています。
 
13error.png

今回のエラーは各トンネルに値を入力するか、下記の手順で配線されていないケースにはデフォルト値を入力するように設定する事で解決できます。列挙定数を受け渡しているトンネルについても同様に対処し、VIの実行ボタンを実行可能な状態にします。
 
15トンネルにデフォルト.png

全てのエラーを修正後、プログラムを実行すると、状態遷移図で予定した挙動を確認できます。

次のステップ

ステートマシンに機能の追加・変更・削除を行う


1. 状態遷移図を修正します。ここでは下記の状態遷移図の様に、「待機」状態からの移行先をユーザが選択し、それぞれの場合について、移行先を設定します。元の状態遷移図と比較すると「待機」の状態の編集と、「警告」の状態の追加が必要であることがわかります。
 
遷移図2.png

2. 「警告」の状態を追加します。列挙定数を右クリックし、タイプ定義を開きます。*.ctlのフロントパネルにて列挙体を右クリックし、「項目を編集」を選択し、「警告」の項目を追加します。
 
16stateadd.png

上記の編集を行った状態ではこの*.ctlファイルを使用しているVIに変更が反映されておらず、VI上の列挙定数がグレーアウトします。タイプ定義されている列挙定数は*.ctlファイルを保存後、「変更を適応」を選択する事でステートマシンのVIの全ての列挙定数に「警告」の状態が追加されます。
 
18gray.png

3. ケースストラクチャのセレクタラベルを選択し、「すべての値にケースを追加」を選択します。この方法によりケースストラクチャに「警告」の状態が追加されます。

4. 「待機」の状態を下記の様に編集します。ここではシーケンスストラクチャが使用されており、Whileループからの出力が入力として配線されています。この配線はそれぞれのループの実行順序を決めるために配線しています。LabVIEW上のループはすべての入力が揃ったときに実行され、ループが停止された時に出力値が出力される仕様になっています。その為、Whileループからの出力はWhileループの実行が完了したときに出力され、シーケンスストラクチャの入力はWhileループが停止し、その出力値が出力されるまでは入力されません。その為、下記のプログラムではWhileループの実行が完了した後にシーケンスストラクチャの実行が開始される順序となります。
 
19待機2.png

5. 「警告」のケースストラクチャを作成します。ここでは下記の様にダイアログを表示します。「警告」の状態は「終了」の状態に遷移するのでシフトレジスタには「終了」の列挙定数を入力します。
 
20警告.png

以上の編集により、ステートマシンの挙動が新たに作成した状態遷移図で指定した内容となります。