[openrtm-users 00405] Re: リングバッファからのデータ取得につきまして

Yusuke Nakajima y.nakajima @ aist.go.jp
2008年 3月 28日 (金) 15:42:42 JST


栗原様

産総研の中島です。

情報提供ありがとうございました。
結果は、栗原様の指摘された通りでした。

早速コールバックの実装をしてトライしたところ、
[dataInComp]側INPORTのバッファにはデータが正常に
入っており[dataOutComp]からの書き込みには問題が
無いことが分かりました。
[dataInComp]の実行サイクルが必ずしも[dataOutComp]より早いわけではなく、
read()-read()の間に複数回のwrite()があり、データの取得が出来ず結果的に
欠落した状態でした。

また、コールバック実装サンプルのページを記載のある、以下の2行

 #include <rtm/RingBuffer.h> 
  InPort<TimedLong, RTC::RingBuffer> m_inIn;

を追記が必要と知らず、デフォルトでリングバッファを使用しているものと
思い込んでおりました。
(昨日までは、通常のFIFOバッファを使用していた?)

今回コールバックの実装に併せて追記しましたが、通常のバッファ/リングバッファ
の両方でテストしても、結果は同じでした。


---
少し話しがRTMのMLの趣旨からずれますが、今回は、

[OpenHRP3]----------[dataOutComp]---[dataInComp]---[他のコンポーネント]
           ↑ControllBridgeで接続

の構成でコンポーネントを走らせてシミュレーション値をデータポートで取得し
ようとしておりましたが、

[dataInComp]実行周期は、”rtc.conf”内で「exec_cxt.periodic.rate」の値を
調整できると思いますが(今回はデフォルト1000で実施)

[dataOutComp]は”rtc.conf”内で「exec_cxt.periodic.type」に
'OpenHRPExecutionContext'を指定し使用していたので、実行周期は
[dataInComp]と同期せず、デバッグしている限りでは、シミュレーションが
軽い場合(例えば何も処理しなかった)ではサイクルが早く、不定期にデータ
をwrite()しているように思えました。そのため、[dataInComp]側が定周期で
read()していては、データ待ちをしたり、取りこぼしたりという状態が発生
するものかと思われます。

もし、OpenHRPを同じ用に使用している方で、何か情報がありましたら、お願いします。



> 産総研 中島様
> 
> 産総研タスクグループ 栗原です。
> 
> > [dataOutComp]が急にサイクルが早くなり、データを2度書き終えてしまった可能
> > 性もありますが、これは考えにくいため、
> > [dataOutComp]側がバッファへのデータ書き込みに失敗していると考えているの
> > ですが、”ロック”がかかる状況が発生したのでしょうか?
> dataOutCompの方が実行サイクルが早く、dataInComp側でread()から次回のread()ま
> でにdataOutCompがwrite()を2回行う事がない事が保証されている場合は別ですが、
> もし保証されていない(なんらかの原因で2回write()が行われる可能性がある)場合、
> OpenRTM-aist-0.4.1のRingBufferの実装では、1回目のwrite()で書き込まれたデー
> タは2回目のwirte()以降read()する事ができません。
> ですので、データが欠落する事となります。
> 
> 問題の切り分けのために、dataInComp側にOnWriteコールバックオブジェクトを実装
> し、OnWriteオブジェクトの中でもタイムスタンプデータをファイル等に出力し、
> read()で得られるデータと比較する事でread()-read()間にwrite()が複数回行われ
> たかどうかを判定する事ができますので、お試し頂ければと思います。
> なお、コールバックオブジェクトの実装方法は、OpenRTMオフィシャルサイトのマニ
> ュアル > RTコンポーネント作成 > データポートのあるコンポーネント > ConsoleOut
> の実装 > コールバックオブジェクト に記述されております。
> 
> また、質問内容にあります"ロックがかかる状況"に関してですが、OutPortのwrite()
> からInPortのread()までの間にOpenRTMでは相互排除のロック機構は実装されており
> ません。
> 
> 以上、宣しくお願い致します。
> 
> 
> 
> > 安藤様
> > 
> > 産総研の中島です。
> > 
> > 2つのRTC間でデータポートでのデータ送受信を行う際に、
> > 以下に示しますようにデータ取得にて欠落が発生するため、
> > 原因or対処法についてご教示願います。
> > 
> > 
> > <現象>
> >   [dataOutComp][dataInComp]の2つコンポーネントがあり、データポートにて
> > TimedDoubleSeqのデータを[dataOutComp]-->[dataInComp]方向に送信しており、
> > 実行サイクルは「dataInComp」の方が早いため、何回かonExecuteがループして
> > から「dataOutComp」よりデータを取得できているのですが、稀に、データを取
> > 得していない状態が発生します。(以下のサンプルソースとデバッグ参照)
> > 
> >   データの取得は、まず、isNew()でバッファに新たなデータが入っていないか
> > 確認し、なければ今回のonExecuteは何も処理せず、データがあればそれをread()
> > しています。
> > サイクルが早い[dataInComp]がデータを取得し損ねているのは、その時だけ
> > [dataOutComp]が急にサイクルが早くなり、データを2度書き終えてしまった可能
> > 性もありますが、これは考えにくいため、
> > [dataOutComp]側がバッファへのデータ書き込みに失敗していると考えているの
> > ですが、”ロック”がかかる状況が発生したのでしょうか?
> > たとえば、[dataInComp]がisNew()でバッファにアクセスしている最中に、丁度
> > [dataOutComp]がデータ書き込みを試みて、ロックがかかっているため失敗した
> > など。
> > 
> >  ちなみに、[dataOutComp]はOpenHRP3のシミュレータとControllBridgeを介し
> >  て、毎シミュレーションstep毎(0.002sec)にデータをもらい、そのまま、
> > [ dataInComp]にスルーさせる構成です。
> > 
> > 
> > 情報、よろしくお願いします。
> > 
> > 
> > 
> > ----------------------------------------------------------------
> > [[dataOutComp側のonExecute部(必要部のみ記述)]]
> > 
> > onExecute(){
> > 
> >   //データセット
> >   unsigned long sec,nsec;
> > 
> >    ・・・
> >      「省略(0.002[sec]毎にシミュレータからデータ取得し、時刻をセット)」
> >    ・・・
> > 
> >   m_dataOut.tm.sec = sec;
> >   m_dataOut.tm.nsec = nsec;
> > 
> >   //データ出力
> >   m_dataOut.write();
> > 
> >   //時刻デバッグ
> >   double time = sec + 1.0e-9*nsec;
> >   std::cout << "--[送信][TIME]: " << time << std::endl;
> > 
> >   return RTC::RTC_OK;
> > }
> > 
> > 
> > 
> > [[dataInComp側のonExecute部(必要部のみ記述)]]
> > 
> > onExecute(){
> > 
> >   //新しいデータが得られたら実行
> >   if (m_dataIn.isNew()) {
> > 
> >     //データ取得
> >     m_dataIn.read();
> > 
> >     //データセット
> >     unsigned long sec,nsec;
> >     sec = m_dataIn.tm.sec;
> >     nsec = m_dataIn.tm.nsec;
> > 
> >     //時刻デバッグ
> >     double time = sec + 1.0e-9*nsec;
> >     std::cout << "--[受信][TIME]: " << time << std::endl;
> > 
> >   } else {
> >     //新しいデータが得られていないので処理をスキップ
> >     std::cout << "---[SKIP] " << std::endl;			
> >   } 
> > 
> >   return RTC::RTC_OK;
> > 
> > }
> > 
> > 
> > 
> > ----------------------------------------------------------------
> > <dataOutComp側のデバッグ>
> > ・・・
> > [送信][TIME]: 0.788 
> > [送信][TIME]: 0.79 
> > [送信][TIME]: 0.792   <- このデータを送信はきちんとしているはず
> > [送信][TIME]: 0.794 
> > ・・・
> > 
> > <dataInComp側のデバッグ>
> > ・・・
> > [受信][TIME]: 0.788 
> > ---[SKIP]
> > ---[SKIP]
> > ---[SKIP] 
> > ---[SKIP] 
> > [受信][TIME]: 0.79 
> > ---[SKIP]
> > ---[SKIP]
> > ---[SKIP] 
> > ---[SKIP] 
> > ---[SKIP] 
> >          <--  しかし、この部分のデータの取得が出来ていない(time:0.792)
> > [受信][TIME]: 0.794 
> > ---[SKIP]
> > ---[SKIP]
> > ---[SKIP] 
> > [受信][TIME]: 0.796 
> > ・・・
> > 
> > 
> 
> 
> -- 
> ----------
> 栗原 眞二
> shinji.kurihara @ aist.go.jp
> kurihara @ imagination.co.jp

-----------------------------------------------------
〒305-8568 
茨城県つくば市梅園1-1-1 つくば中央第2  2-12棟
独立行政法人 産業技術総合研究所
 知能システム研究部門 自律行動制御研究グループ

   中島 裕介 (Yusuke Nakajima)

 TEL:029-861-5080(内線55267)
 mailto:y.nakajima @ aist.go.jp
-----------------------------------------------------




openrtm-users メーリングリストの案内