[openrtm-users 00961] Re: OpenRTM-aist-1.0.0-RC1 (C++) DataPort型データのTimeStamp不具合

Ando Noriaki n-ando @ aist.go.jp
2009年 9月 28日 (月) 12:35:40 JST


中島様、金広様、OpenRTM MLの皆様

産総研 安藤です

これに関しては、MLに参加していただいている皆さんにも
お聞きしたいトピックです。ぜひご意見ください。

> 産総研の中島です。
>
> OpenRTM-aist-1.0.0-RC1 (C++) をUbuntu8.04環境で使用していますが、
> データポート送信における、タイムスタンプの扱いに不具合があるよう
> ですので報告します。

> DataPort型データを送信する際に、例えば「Timed〜〜」型で定義していると、
> 「tm」がも送信されますが、0.4.2では確か「空っぽ」でユーザーが自らセット
> する仕様だったと思いますが、1.0.0では、自動でCPU時刻が付与されているようです。
>
> これは仕様でしょうか?またどのタイミングの時刻でしょうか?

ドキュメントに書いてないので、不具合といわれるとそうなのかもしれませんが、
私としては仕様のつもりでした。申し訳ございません。
基本的に、データポートのデータのタイムスタンプは、
「OutPortに対してwrite()された時刻」というルールになっております。

OutPort.h の write() の中で以下のように時刻を代入しております。

      // set timestamp
      coil::TimeValue tm(coil::gettimeofday());
      value.tm.sec  = tm.sec();
      value.tm.nsec = tm.usec() * 1000;


> 上記を踏まえて、利用していると以下2点問題があります。
>
> ===
>
> 【1】同一データを複数のRTC間を経由する際のタイムスタンプの上書き
>
> テスト用に、RTCを3つ用意し、「testA」->「testB」->「testC」
> という順に、「testA」で作成したデータを送信し、「testB」で受信し、
> そのまま送信用にコピーし再送信、「testC」で受信という一連の処理を
> する場合をテストしました。
> 「testA」内部で"tm.sec","tm.nsec"に値を入れて送信しても、「testB」で受信
> し、中身を見ると、"tm.sec","tm.nsec"はCPU時刻にて上書きされています。
> (どのタイミングでの時刻か不明ですが・・)
> さらに、上書きされたデータを「testB」が「testC」に送信し、「testC」が受
> 信し、中身を見ると、"tm.sec","tm.nsec"は「testB」で見た時刻とは異なり、
> 新たに時刻が上書きされていることが判明しています。
> つまり、唯一のでデータが送信の度に変更されてしまっている状態。

これは、
「testA」->「testB」->「testC」
という構成において、testBのInPortとOutPortは、データが唯一のものである
という前提を知る由もないので致し方ないのではないでしょうか?
そもそも、testBはInPortから来たデータに何か処理を施して、OutPort
から出すわけですので、その時点で元々のデータとは異なるデータになるので
おっしゃるような「唯一のデータ」というのは前提として正しくはないと思います。

また、たとえば下の例のように、

「testA」-->「testB」->「testC」
「testA’」-/

testBがtestA, testA' からのデータを受け取り
testCにデータを出力する場合、testCに出力されるデータのタイムスタンプ
はtestAのタイムスタンプでしょうか?testA'のタイムスタンプでしょうか?

中島さんのあげられたフィルタ型のRTCは代表的なタイプですが、
それ以外の入出力のRTCも存在するので、上記のような前提を設ける
のは難しいかと思います。

> 【2】シミュレータ(OpenHRP3など)との兼ね合い
>
> 0.4.2までは、自動付与がないため、OpenHRP3からシミュレーション上の時刻を
> タイムスタンプとして取得可能でしたが、現在公開中のOpenHRP3.1.0_beta3では、
> どうやら、この時刻もCPU時刻に上書きされているようです。
> つまり、シミュレーション上の正確なデータを取得不可となっている状態。
>
> ===
>
> この辺り、影響が大きいと思われますので、対応をお願いいたします。

具体的にはどのようにすればよろしいでしょうか?

タイムスタンプに関する仕様は、使用状況によってさまざまなものが
要求されることは理解しています。しかしながら、OpenHRPやその他
タイムスタンプを前提としたアプリケーションでは、すべてのRTCが
統一されたルールに従う必要があります。でないと、RTCの再利用性が
なくなってしまいますので。

たとえば、上記の例 「testA」-->「testB」->「testC」 では、
testA のみがタイムスタンプを打刻し、testBとtestCは打刻しない
という2つのルールが存在します。
そこに、タイムスタンプを打刻するtestBとほぼ同等のtestB'というRTCを
代わりに挿入すると、上記の前提が崩れてしまいます。

OpenHRPの構造として、ここのルールを統一することは不可能でしょうか?>金広さん
たとえば、上記のタイムスタンプの時刻を与えている coil::gettimeofday() を
シミュレータが乗っ取り、任意の時刻を返すようにできるだけではだめですか?

OutPortにwrite()された時点の「時刻を打刻する」というのは、
ある意味簡潔で、比較的誰でも納得できる妥当なルールかなと
思うのですがいかがでしょうか?

あとは、データポート接続時に、OutPort側もしくはInPort側でタイムスタンプを
打刻する・しないを選択できるようにするという手もあります。
実装はできないことはないですが、いちいち指定するのはめんどうですよね。
デフォルトを打刻するにしておいて、打刻しない場合のみ指定する、
ということにしておく手も考えられますが。

ご意見などいただけましたら幸いです。
-- 
安藤慶昭@独立行政法人産業技術総合研究所 研究員
                  知能システム研究部門 統合知能研究グループ
                  〒305-8568 茨城県つくば市梅園1-1-1 中央第2
                  TEL: 029-861-5981 FAX: 029-862-6631
                  n-ando @ aist.go.jp, n-ando @ ieee.org



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