10-08-2020 03:38 AM
大変お世話になっております。
NIcRIO9066とNI9505を用いて、モータ制御を行っており、エンコーダからのデータをFPGAからHost.viにグローバル変数で渡し、
Host.viのほうでモータの回転を制御、配列にした後、TDMSデータとして出力しています。
しかしながら、FPGAからのエンコーダからのデータがおおよそ0.1秒間隔でしか送られておらず、0.01秒間隔でデータを出力したい場合はFPGAサイクルのどこを調節すればよいのかを教えていただきたいです。
10-08-2020 06:10 PM
こんにちは
プロジェクトファイルやハードウェアがないので私の環境ではいろいろviが壊れてて、あまり良いディスカスができないかもしれませんが。。
Target側のエンコーダ位置カウントしているループはシングルサイクルで作ってあるようですが、気になるのはEncoderLoopTimeやdisplayTimeが想定時間で回っているかです。こちらが全開で回っていたとして、次に気になるのはホスト側のエンコーダ位置を読み取ってTDMSへ保存いるところ。タイミングループで回していますがここが多分10msで回っていない気がします。もし回っていなかったら想定するボトルネックはターゲットからホストへ値を送るグローバル変数。ターゲットからFIFO経由でホストにデータ渡してホスト側は配列受けで処理しないとダメな気がします。
乱文でごめんなさい。こんな風に感じました。
10-09-2020 03:40 AM
ご返信誠にありがとうございます
また複数のご指摘大変ありがとうございます。
一つ一つ対応していこうと思います。
加えて、こちらの配慮が足りずに大変申し訳ありません
つきましては、zipファイルとしてプロジェクトを添付させていただきます。
解凍いただきますとM2とProgram Files (x86)と追加資料というファイルがあります
まずは追加資料の中のプロジェクトディレクトリ+時間データについてのPDFの中にプロジェクトディレクトリの写真がございます。
モータ回転結果のexcelデータはこのプログラムを作動させたときのTDMSデータをexcelデータにしたものです。
時間データにはプロジェクトディレクトリ+時間データ内で、実測で設定した時間データについての補足がございます。
至らない点が多いとは思いますが、ご教授いただければ幸いです。
また、初歩的な質問で申し訳ないのですがEncoderLoopTimeやdisplayTimeが想定時間で回っているか、ということを確かめるのは、
ストップウォッチ等で時間を測って確かめるのか、vi上で表示器等でやるやり方を想定されているのでしょうか。
お忙しいところ大変申し訳ありませんが、ご連絡いただけますと幸いです。
10-11-2020 12:31 AM
9505 Brushed Servo (Position Setpoint) - FPGA.viの一番下のエンコーダ位置をカウントしているループにあるDisplayTime変数がこのループの回っている速さになるかと思います。この値を実行時にモニタします。ティックカウントとティックカウント2のカウンタ単位がミリ秒になっていますが、これをu秒またはティックにすると分解能が上がります(ダブルクリックすると変更できます)多分、この感じだと1ティックで回ってそうなので問題の本質はここじゃない感がします。
Power Assist SYSTEM (NI9505:Position Brushed Servo 2 Setpoint) - Host.viのTDMSに保存しているループに添付のElapsedTime.viを試験的に入れてループ速度を測ってみてください。多分ここがおよそ100msecで回っている気がします。タイミングループの中にある遅れて終了[i-1]出力端子が実行中Trueになってませんか?(設定で回れていないとTrueになる)
もし回ってなければ、このループの中のだれかがボトルネックになっているのですが、エンコーダ値を読み込むだけのループにしたとき期待した速度で回れば、TDMSファイルに書き込むところがボトルネック。回らなければエンコーダ値を読んでくるところ自体と予想します。
この先の対策話ですが、前者なら、ファイルシステムへのアクセスがボトルネックと想定できるので、データを配列にしてから保存するなどオーバーヘッドを少なくする方法を考える。後者ならターゲットからのデータ転送をDMAを使って転送する感じになるかと思います。
10-11-2020 10:14 PM
ご連絡ありがとうございます。
また、viも送ってくださり誠にありがとうございます。
これから頂いたviを使って試していこうと思います。
また、わからないことが出来た場合はこちらに投稿させていただきますので、
その際はよろしくお願い致します。
以上、お忙しいところ恐縮ですが、確認よろしくお願い致します。
10-26-2020 05:34 AM
大変お世話になっております
ご教授いただきました通り、Power Assist SYSTEM (NI9505:Position Brushed Servo 2 Setpoint) - Host.viのTDMSに保存しているループに添付のElapsedTime.viを試験的に入れてループ速度を測ったところ、ご指摘の通り100msecでプログラムが回っておりました。
また、タイミングループの中にある遅れて終了[i-1]出力端子が実行中Trueになっており
本来の意図していない値でプログラムが回っていることも確認いたしました
ボトルネックについてですが、エンコーダ値を読み込むだけのループにした設定時でも、遅れて終了[i-1]出力端子が実行中Trueになっておりましたので、データ転送がボトルネックになっていると考えられます。
DMA転送について質問がございます。
いまはユーザ定義変数を用いてデータ転送を行っておりますが、FIFOを使う際はユーザ定義変数のみをFIFOから転送する形か、Encoder Position やEncoder VelocityもFIFO転送に変更したらよいのか教えていただきたいです。また手順を用いて教えていただきますと幸いです。
添付資料にFPGA.vi側のユーザ定義変数のループの写真を添付させていただきます
FIFOを用いてプログラムを変更するのは初めてであり、検討違いな質問をしてしまっているかもしれませんがご回答宜しくお願い致します。
10-26-2020 05:43 PM - 編集済み 10-26-2020 05:47 PM
以下ちょっと強引な表現でDMA転送を説明します。
〇変数での転送はホスト側(PC)がターゲット(FPGA)の値をソフトウェアタイミングで回収しに行きます。よって転送(回収)タイミングがソフトウェアタイミングになり、結果遅くなったり、回収時間に正確性がなくなります。
〇DMA(DirectMemoryAccess)転送はホストとターゲットの間にDMAというベルトコンベアを用意して、ターゲット側がコンベアに値を乗せると勝手に(というかDMAコントローラがやってくれる)ホスト側(PC)のメモリーのどこかに送られ溜まります。
〇ターゲット側はDMAにデータを入れる。ホスト側はDMAに溜まったデータを回収する。送る側であるターゲットの方が圧倒的にデータを入れる手数が早いので、ホスト側の回収というオーバーヘッドを少なくして時間的バランスを取るという手法になります。
ざっくりこんな感じなのですが、このDMA転送をちゃんとやるにはホスト、ターゲット双方にちょっとした仕組みが必要になります。
ヘルプ→サンプルを検索→真ん中のリストの「ツールキットとモジュール」→FPGA→CompactRIO→基本機能→データ転送およびストレージ→FPGAからホストの中にある4つのサンプルが参考になります。多分貴殿の用途に一番近いのは循環バッファサンプリングでしょうか。
DMA転送は、いきなり組み込むと確実に訳わからなくなりますので(笑)合点がいくまでサンプルをいじり倒してからの実践組み込みをお勧めします。ファイト!
10-26-2020 09:44 PM
ご連絡ありがとうございます。
サンプルを参考にFPGAプログラムの修正を行いたいと考えております。
また、わからないことが出来た場合はこちらに投稿させていただきますので、
その際はよろしくお願い致します。
以上、お忙しいところ恐縮ですが、確認よろしくお願い致します。
11-17-2020 01:59 AM
大変お世話になっております。
ご教授いただいた通り、EncoderデータをFIFOで受け取るDMA転送を実装したところ
データ自体はFPGAからHost側にデータの遅れなしにデータを送ることが出来るようになりました。
誠にありがとうございました。
しかしながら、問題が発生したため、再度こちらに投稿させていただきます。
モータの回転の時間を設定する運動周期という
制御器に値を入れることでモータの正転、反転の合計の運動周期を決定しているのですが
運動周期を3secなどの短い時間に設定すると出力される波形データが乱れる(正弦波で制御しているのにも関わらず、グラフが直線的なものになっている)現象が確認されてしまい、データ転送自体に問題があるのか、Host.viでのデータ通信に問題があるのか、教えていただけますと幸いです。また、代替案などもありましたら教えていただけますと幸いです。
添付資料に改良したプログラムとプロジェクトファイルのディレクトリの写真を添付させていただきます。
運動周期を3秒に設定し、モータを回転させた際のエクセルデータも添付させていただきます。
お忙しいところ大変申し訳ありませんが、ご対応宜しくお願い致します。
11-17-2020 04:59 PM
DMA転送できたのですね。さすがです。お疲れさまでした。
で本題ですが、これはなかなか難しそうです。
多分思うにHost側もTarget側も複数のループがあって、それぞれでデータのやり取りを行っていますが、動きの順番性に何か不都合が出ている気がしています。たとえばTarget.viのPositionSetpointLoopにあるタイムアウトで前の値を再利用するようなところとか、いろいろ工夫されているようですが、ここがタイムアウトする状況はHost側が送信に間に合っていないから発生していると思います。
運動周期変数は駆動用波形の形状を変えているだけのようなので、どうして小さくするとおかしくなるかの理由にはたどり着けませんでした。あまりこれだけを注視するとはまりそうな予感です。
前回送りましたループの時間を測るviを使ったりしてそれぞれのループが期待した速度で回っているか、データの順番は正しく受け渡されているか、FIFOのタイムアウトが頻発していないか、保存データを取りこぼしていないか。
このあたりから手を付けていってはいかがでしょう。要所に表示器を付けたりタイムアウトしたらラッチするブールや変数を仕掛けたり。。方法はいろいろです。
ハードの動きはうまくいっているが保存データだけがおかしいならHost.viのファイル保存している一番上のループをまず見てみる感じでしょうか。。。
ごめんなさい。雲をつかむような残念な文章になってしまいました。