[openrtm-users 00815] Re: EC の実装に関して

Ando Noriaki n-ando @ aist.go.jp
2009年 6月 4日 (木) 10:19:00 JST


清水様

安藤です

> 下記の説明でさらに疑問点が出てきたので
> 教えてください。
>
> ExtTrigECを駆動するリソースは、
> 周期的なタイミングリソース(周期タイマなど)
> に限定されていて、
> それ以外では駆動してはいけないという
> ことでしょうか?
> 実装を見る限りではそういう制限はないように
> 思っていたのですが。

いけないということはないと思います。
OMGの仕様的にはそこまで厳密に決められてません

単に、
周期実行:EC Kind = PERIODIC RTCはDataflowComponent
イベント実行: EC Kind = EVENT_DRIVEN RTCはFsm

という区別になっています。

> 私が議論していたExtTrigECの使い方は、
> 例えば、GUIパネルのボタンをクリックした
> ときに駆動する、というような、
> 不定期のイベントに同期するケースです。
> もちろん、OpenHRPのように、
> 周期的に駆動されるものに関しては、
> rateも意味を持ちますし、
> 安藤様の説明に何ら異論はありません。

> しかし、ユーザインタフェースRTCのように、
> ユーザからの不定期なコマンドイベントに
> 同期して動作するものを作ろうと思うと、
> ExtTrigECのような任意のタイミングで
> ECを駆動できるものが必要ですし、
> そういう用途にExtTrigECが使われることも
> 想定していると私は考えていました。
> なので、その場合はrateの意味が
> わかりづらい、と言ったつもりでした。

GUIへの入力をイベントとしてExtTrigECを駆動するというのは
あまり想定していませんでした。

GUIとの連携はOMGの仕様を決めるときにも議論になりました。
僕はとくにそういう使い方は想定していなかったのですが、
もう一方の提案者であるRTIは一つのRTCが周期の早いECで
制御などの計算をしつつ、GUIのイベントループに相当する遅い
ECでGUI関連の処理もするという使い方も想定していたようです。

こんな感じ↓

ReturnCode_t on_execute(EcId ec_id)
{
  if (ec_id == REALTIME_EC)
  {
     do_control();
  }
  else if (ec_id == GUI_EC)
  {
     do_something_related_to_gui();
  }
  return RTC::RTC_OK;
}

こういう使いかたをしたいというのが意見としてあったので、
RTCは複数のECと関連付けられるようになっています。
#でも、これってあまりOO的ではないですよね。

でも、たいていのGUIツールキットはタイマコールバックを
登録できるので、それでECをトリガするというのもありといえばありですが。。。

> 上記のような、不定期イベントに同期させたい
> 場合は、ExtTrigECを使ってはいけない、
> という理解でよろしいでしょうか?
> また、そうだとすると、不定期イベント同期型の
> RTCはどのECを使うのがよいのでしょうか?
> RTC仕様を読んでないので、
> 変なことを言っていたら指摘してください。

僕はGUIとRTCをくっつける場合は、RTC側にデータを
入出力するための関数を追加してそれを呼んだりして、
周期実行を乱さないように作ったりします。

C++であれば、たとえば

class MyInterface {
  virtual MyInterface() {};
  DataStruct getData() = 0;
};

などと定義しておいて、RTCにこのインターフェースを継承させgertData()を実装します。
もちろん、onExecuteで触る変数に変数に触る場合はmutexで保護します。
で、これをとりあえずsoまたはDLL形式にコンパイルしてしまいます。

GUIのプログラムの方は全く別に作成しておいて、初期化の部分で、

Manager::instance().load("MyComponent.sO");
RTObject_impl* rtc = Manager::instance().createComponent("MyComponent");
m_myrtc = dynamic_cast<MyInterface>(rtc);

m_myrtc は MyInterface* 型

で、タイマコールバック関数や適当なイベント関数など、データがほしいところで、

void OnTimer()
{
  DataStruct data(m_myrtc->getData());

  updateGuiDisplay(data);
}

などのようにします。

データをRTCに送りつける場合もこれとほぼ同様にできます。

Python何かだと、別にインターフェースを定義しなくても追加したメンバ関数が
いつでも呼べるのでもっと簡単ですね。
ただし、TkInterのイベントループのスレッドとPythonのスレッド(ECのスレッド)
の相性が悪いので、うろ覚えですがTkInterのスレッド側がデータを取りに行く
または渡しにいくように書かないと落ちたような気がします。
これについては、Pythonのサンプルをご覧ください。

以上で答えになってますでしょうか?


-- 
安藤慶昭@独立行政法人産業技術総合研究所 研究員
                  知能システム研究部門 統合知能研究グループ
                  〒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 メーリングリストの案内