[openrtm-users 00740] Re: コンポーネントの複数起動に関して

Ando Noriaki n-ando @ aist.go.jp
2009年 1月 15日 (木) 12:33:24 JST


安藤です

続き(実装について)です

実は、0.4.0にはAPIとしてユーザには解放されていませんが、
コンポーネントの名前付けのポリシーを変えられる仕組みが用意されています。

これは、コンポーネントのFactoryクラスです。
http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/ClassReference/classRTC_1_1FactoryCXX.html

コンストラクタの最後の引数に NumberingPolicy が渡されていますが、
これがインスタンスの名前付けの方法を決めています。
デフォルトでは DefaultNumberingPolicy オブジェクトが渡されますが、
別のPolicyオブジェクトを渡すと任意の名前の付け方に変更することができます。

ただし、現在の0.4.0では
http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/ClassReference/classRTC_1_1Manager.html#09c70d1b01c1f1969abe64d928c435ee

のregisterFactoryの引数にNumberingPolicyがないのを見てもお分かりいただけるように
Policyを変更するすべはありません。

今、手元にソースがないので嘘を書いているかも知れませんが、registerFactory関数はたぶん中で、

registerFactory(....)
{
 :
 // Factoryのリストに新しいファクトリを登録する
 m_factory_list.push_back(new FactoryCXX(property, newfunc, delfunc))
 :
}

のようになっているのではないかと思いますが、これを

registerFactory(Properties, NewFunc, DeleteFunc, NumberingPolicy)
{
 :
 m_factory.list.push_back(new FactoryCXX(property, newfunc, delfunc, policy))
 :
}
のようにpolicyを渡せるようにした上で、各コンポーネントのナントカInit()関数内の
registerFactoryの呼び出しで、独自のNumberingPolicyを渡してあげれば、
任意の命名方法を与えることができます。


NumberingPolicyの具体的な実装方法ですが、

http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/ClassReference/classNumberingPolicy.html

のNumberingPolicyクラスを継承して、onCreate (void *obj)関数を実装するだけです。
先ほどのメールで提案した、以下の2種類の命名方法を実現する方法を書きます。

1. [ノード(ホスト)名]/[カテゴリ名]/[RTC型名]/[インスタンス名]

std::string onCreate(void* obj)
{
  names = 同一マシン上の他のマネージャ上でインスタンス化されている
       同一カテゴリ・型名のインスタンス名を取得
  namesから当該RTCの次のインスタンス名を計算

  return 新しいRTCのインスタンス名;
}

このようになると思います。
ここで、「同一マシン上の他のマネージャ上のインスタンス名」を取得するのが
現状では難しいです。同一マシン別プロセスのマネージャ同士が、どういう
RTCのインスタンスを持っているかの情報を交換できる必要があります。
今のところそのようなことはできませんが、1.0では少なくとも同一ノード上の
のマネージャ同士がこれらの情報を共有できるようにはするつもりです。

この方法は、同一ノード上で一意なナンバリングをするだけでよいので、
Managerを少々拡張するだけで実現可能です。

2.[カテゴリ名]/[RTC型名]/[インスタンス名]

std::string onCreate(void* obj)
{
  typename = obj->getTypeName(); //とりあえずベースとなる型名を取得
  nmformats = Manager::instaqnce().getConfig()["naming.formats"]; //
名前付けのフォーマットを取得
  nss = Manager::instaqnce().getConfig()["corba.name_servers; // ネームサーバ名を取得

  for (各ネームサーバ毎に) {
    # 当該 [ノード(ホスト)名]/[カテゴリ名]/[RTC型名]/[インスタンス名] で登録されている名前を取得
  }
#ネームサーバに登録済みコンポーネント名から、次に生成するRTCのインスタンス名を決める
#たとえば、すでに MyComponent0, MyComponent1, ..., MyComponentNがネームサーバ上に登録されて
#いるのであれば、次のコンポーネントの名前は MyComponent(N+1) のようになる。

 return "MyComnponent(N+1)";
}

以上、こんな感じで実装すれば、菅さんがご希望の名前付けが実現できるのですが、
0.4.0のときにはそこまでやる余裕がなかったので、DefaultNumberingPolicyのみとなっています。

最後の末廣さんのメールにもありましたように、OpenRTM-aistに
あまりたくさん機能を詰め込まないほうがいいというのも同意です。
最近、OpenRTMをuITRONに移植したのですが、uITRONでRTCを
動かしたいようなターゲットは、上記のような複雑な名前付けをさせるのは
メモリ的にも、CPUパワー的にもしんどそうです。

安藤個人の意見としては、各コンポーネントの*Init()内でPolicyを渡すのではなく、
いくつかのタイプのNumberingPolicyをあらかじめ用意しておいて、
(かつ、それがDLLでローダブルだともっといいかも。)
confファイルから各コンポーネント毎に適当なNumberingPolicyを指定する
というやり方が良いのではないかと考えています。

これなら、菅案、清水案、末廣案にも何とか対応できるでしょうし、
将来的に別のユースケースが現れた時にも対応可能です。

いかがでしょうか。
-- 
安藤慶昭@独立行政法人産業技術総合研究所 研究員
                  知能システム研究部門 タスクインテリジェンス研究グループ
                  〒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 メーリングリストの案内