11-30-2018 05:43 AM
私は現在、加力実験の際に2体のアクチュエータを自動制御するためのプログラムを作成しています。
変位計2体のデータとその平均を出し(×3つ=9ch分)、また2体のアクチュエータの荷重の計11ch分のデータを保存したいと思っております。
しかしデータの保存を行うと、平均の変位が2ch分とアクチュエータの荷重2ch分の計4chは正常に保存できているのですが、残りの変位計から直に送られてくるデータ6chと平均変位の1chの計7chが遅れて保存されてしまいます。
保存はテキストファイルに保存し、Excelで開いてその後のデータ整理をしようと考えております。
また、フロントパネルで11個すべてのデータを表示器で表示して確認していますが、こちらでは遅延はなく変化に対して速やかに対応して表示しております。
なぜこのような現象が起こるのでしょうか?
宜しければご教授いただければと思います。
宜しくお願いします。
VIとデータの遅れが分かる写真を添付します。
写真を見ると変位2つの値と平均の値があっていないのがお分かりいただけると思います。
計測時間に対して正しい値が保存されているのが平均側となっております。
12-02-2018 07:53 PM
まずキューの使い方に問題があるかと思います。
たとえば「ACT2荷重」と記載のあるキューをたどってみると、
キューへの書き込みは一か所ですが、キューからの読み取りは二か所で行われています。
キューというのは、書き込まれたデータを一度読み取ると、そのデータはバッファから破棄されます。
どういった動作を想定されているかわかりませんが、
二か所の読み取りでは、一方で読み取ったデータは破棄され、もう一方は次に書き込まれるデータを読みます。
拝見すると、各ループは同期していないようなので、どちらのキューが先に読み取られるか全くわかりません。
このままでは、データの損失が発生するでしょう。
キューは基本的に1対1で使うものと覚えておいてください。
データの書き込みも読み取りも一か所で使うことが推奨されます。
(QMHなどは別ですが...)
まずはその点を改善して試されるとよいと思います。
ちなみに最上位のループでは複数キューからのデータを待機していますが、
同タイミングで測定したデータを同時に受信できているか、
誰も保障されないので動作として問題ないか心配です。
12-03-2018 01:49 AM
Emboar 様
ご回答いただきありがとうございます。
ご指摘いただいた点についてさらに質問失礼いたします。
キューは1対1で使うということですが、この場合、同じデータに対してもう1つキュー取得関数を設けるということでよろしいのでしょうか?
また、各ループの同期はどのようにしてとるのでしょうか?
12-03-2018 02:01 AM
こちらでcrossrulzが説明してくれていますが、キューではなくノーティファイアが考えられるかと思います。
Re: Difference between Queue and Notifier , how it use in LAbview Programming
が、ノーティファイアはバッファを持たないので、データがたまっている状態で次のデータが来ると、
データが損失してしまいます。
かといって同じデータに対してもう一つキューを作成するのは、冗長な気がします。
タイミングを正しく制御してノーティファイアを使用するか、またはエンキューするのは一か所に制限して、
そこで複数処理を行うほうがよいかもしれません。
ループの同期は必要でしたら、キューでもノーティファイアでもセマフォでも可能です。
Viewpointの資料はよくできています。Part1と2をどちらもご覧になることをお勧めします。
12-03-2018 02:58 AM
Emboar 様
一つのデータに対して複数送信する場合、キューではなくノーティファイアを使用するということは分かりました。
今作成していたVIのキュー関数をノーティファイア関数に置換すれば、ループ間の同期もとれるようになるのでしょうか?
理解が及んでおらず申し訳ありませんが、もう少々詳しくご教授いただければと思います。
12-04-2018 01:11 AM
説明が不足しており誠に申し訳ありません。
まずキューとノーティファイアについてそれぞれ「要素をデキュー」「ノーティフィケーション待機」
関数を用いてデータを受信しますが、それらは「要素をエンキュー」「ノーティフィケーション送信」
関数からのデータを受信するまで待機しています。(タイムアウトを設定している場合は別)
そのため、ループAからループBにキューを介してデータを送る際、ループBはループAからのデータを待ちます。
コードのイメージを作成しました。
よって、キューやノーティファイアを使用してループ間でデータをやり取りすると、
タイムアウトを設定しない限り必然的に、そのループレートはデータ生成側に依存することになります。
これを利用してループ間のループレートを同期することができます。
私が気にしたのは、一つのループで複数のキューを待機していることです。
キューAは500msedでデータが届き、キューBは10msec、キューCは1msecのように、
各キューの受信レートがバラバラでは、次第にデータがずれてしまうため気にしてお伝えしました。
なお元々の問題について原因がこれとはわかっていません。
あくまで可能性の一つとしてご提案させて頂きましたので、まずはご検討されるとよいと思います。
12-04-2018 02:22 AM
Emboar 様
詳細なご説明ありがとうございます。
ご指摘いただいた通り、使用していたキュー関数をそれぞれに対応するノーティファイア関数に置換したところ、データ保存の遅れが解消されたように思います。
試しで稼働させたのが20分ほどですが、その間遅れが発生することなく全データ時刻通りに保存できているようです。
無事、所望の動作を実現できたかなと思っております。
何度もご回答いただき大変ありがとうございました。