[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 メーリングリストの案内