[openrtm-users 00040] Re: RTコンポーネントとプロセスの関係について
Noriaki Ando
n-ando @ aist.go.jp
2005年 11月 26日 (土) 16:35:44 JST
宇田様
> はじめまして。宇田@NECシステムテクノロジーと申します。
はじめまして
安藤@産総研です
> OpenRTMコンポーネントとプロセスの関係について、少し詳しく教えて
> 頂けますでしょうか?
>
> 例えば既存のロボット用のソフトウェア資産をOpenRTMで活用する場合、
> 普通に考えると頭、腕、足などのパーツごとにコンポーネント化するの
> が自然かと思います。
>
> OpenRTMから見たロボットソフトウェア
> +---------------------------------------------+
> | システム |
> | +-----------+ +-----------+ +-----------+ |
> | | 頭制御 | | 腕制御 | | 足制御 | |
> | | Component | | Component | | Component | |
> | +-----------+ +-----------+ +-----------+ |
> +---------------------------------------------+
>
> これらのパーツの制御用ソフトウェアは、元々がロボット・システムで
> あるという経緯から、通常は1プロセス内で動いていることが想定され
> ます。
>
> ロボットソフトウェアの内部構造
> +---------------------------------------------+
> | 単一プロセス |
> | +-----------+ +-----------+ +-----------+ |
> | | 頭制御部 | | 腕制御部 | | 足制御部 | |
> | +-----------+ +-----------+ +-----------+ |
> +---------------------------------------------+
>
> そこで、最も簡単なコンポーネント化の方法は、これら3種類のコンポー
> ネントを1つの実行ファイルにまとめる方法かと思うのですが、デベロッ
> パーズガイドの3.1.1.1によると、スタンドアロンコンポーネントは原則と
> して1プロセスにつき1種類のコンポーネントにのみ対応するとあります。
> これは何か技術的な理由による制約でしょうか?
そのようなコンポーネントをスタンドアロンコンポーネントと呼んでいるだけです。
> またローダブルモジュールコンポーネントであれば複数種類のコンポーネ
> ントに対応可能なようですが、それらのロード先を1プロセスに制限する
> ことは可能でしょうか?(上記のように、ベースになるソフトウェア資産
> が単一プロセスで動いている場合、それを基に作成したコンポーネントも
> 同一プロセス内で動かすのが最もシンプルかと思うのですが)
rtc-template で作成されるスタンドアロンコンポーネント("なんとかComp.cpp")は、
あくまで一例で、当該コンポーネントを1個だけ作成するための実行ファイルです。
全部のコンポーネントを同じプロセスで動かしたい場合、
同一のマネージャでそれらのコンポーネントを作成すれば可能です。
仮に、上記の3つのコンポーネントが下記のようなソースからできているとします。
Head.cpp, Head.h, HeadComp.cpp
Arm.cpp, Arm.h, ArmComp.cpp
Leg.cpp, Leg.h, LegComp.cpp
ここで、全部のコンポーネントをいっぺんに作成する新しい
実行ファイル (AllComp) を作成します。
------------------------------------------------------------
AllComp.cpp
------------------------------------------------------------
#include <rtm/RtcManager.h>
#include "Head.h"
#include "Arm.h"
#include "Leg.h"
// この関数は、main 無いの、manager.initModuleProc(MyModuleInit) で
// 一度だけ実行される。
void MyModuleInit(RtcManager* manager)
{
HeadInit(manager); // Head.h 内に定義されている。
ArmInit(manager); // Arm.h 内に定義されている。
LegInit(manager); // Leg.h 内に定義されている。
std::string name;
// コンポーネントを作成する
// Headコンポーネント: 名前 "Head", カテゴリ "Generic" とする。
manager->createComponent("Head", "Generic", name);
// Armコンポーネント: 名前 "Arm", カテゴリ "Generic" とする。
manager->createComponent("Arm", "Generic", name);
// Legコンポーネント: 名前 "Leg", カテゴリ "Generic" とする。
manager->createComponent("Leg", "Generic", name);
return;
}
int main ()
: つづく
------------------------------------------------------------
これを、Head.o, Arm.o, Leg.o とリンクすれば、
ご希望の実行ファイルになると思います。
実は、もう少し柔軟な方法もあります。
コンポーネントをビルドすると、Head.so, Arm.so, Leg.so
といった共有オブジェクトファイルも一緒に作成されますが、
これを使うこともできます。
------------------------------------------------------------
AllComp.cpp
------------------------------------------------------------
#include <rtm/RtcManager.h>
void MyModuleInit(RtcManager* manager)
{
// 共有ライブラリをロード
manager->load("Head.so", "HeadInit");
manager->load("Arm.so", "ArmInit");
manager->load("Leg.so", "LegInit");
std::string name;
// コンポーネントを作成する
manager->createComponent("Head", "Generic", name);
manager->createComponent("Arm", "Generic", name);
manager->createComponent("Leg", "Generic", name);
return;
}
int main ()
: つづく
------------------------------------------------------------
このように、マネージャにsoファイルをロードさせて、
コンポーネントを作成することもできます。
あまり違いがないように見えますが、こちらの方法では、
Head.h, Arm.h, Leg.h をincludeしていません。
この方法だと、どれかひとつのコンポーネントに変更があっても、
この実行ファイルをコンパイル・リンクしなおす必要がありません。
> コンポーネントサーバがこのロード・実行の役割を担っているようですが、
> デベロッパーズガイドにはあまり解説がないようですので、もし関連する
> 資料などがありましたら公開して頂けると助かります。
今のところ、公開できるような資料はありませんが、
付属のクラスリファレンス RTM::RtcManager の項を読んでいただければ、
おそらくお分かりになるのではないかと思います。
次のバージョンのマニュアルでは、使い方等記載しようと考えております。
安藤慶昭@独立行政法人産業技術総合研究所 研究員
知能システム研究部門 タスクインテリジェンス研究グループ
〒305-8568 茨城県つくば市梅園1-1-1 中央第2
TEL: 029-861-5981 FAX: 029-861-5971
n-ando @ aist.go.jp, n-ando @ ieee.org
openrtm-users メーリングリストの案内