[openrtm-users 00265] サービスポートのRTC以外からの利用に関して

10 posts / 0 new
Last post
root
Offline
Last seen: 9 hours 59 min ago
Joined: 2009-06-23 14:31
[openrtm-users 00265] サービスポートのRTC以外からの利用に関して

金広@産総研です。

サービスポートに定義されているIDLのインタフェースをRTC以外の
通常のCORBAクライアントから呼び出す方法はありますでしょうか?
どのようにするとサービスの参照を取得できるでしょうか?

Undefined
root
Offline
Last seen: 9 hours 59 min ago
Joined: 2009-06-23 14:31
[openrtm-users 00266] サービスポートのRTC以外からの利用に関して

金広様

安藤です

> サービスポートに定義されているIDLのインタフェースをRTC以外の
> 通常のCORBAクライアントから呼び出す方法はありますでしょうか?
> どのようにするとサービスの参照を取得できるでしょうか?

RTCのPortにconnectをする際に、そのポート自身のオブジェクトリファレンスのみ
をConnectorProfileにセットしてconnectしてください。
そうすると、戻ってきたConnectorProfile::propertiesの中に、
port.[Service Type].[Service Name] というキーでCORBA::Any型で
オブジェクトリファレンスが入っています。
それを、使用したいサービスの型にnarrowして使用してください。

ちょっとごちゃごちゃしてますが、おおよそ以下のようになります。

このファイルとMakefileを添付します。
添付のtar-ballをexamples/SimpleServiceの下で展開しmakeしてください。
make -f Makefile.clientでmakeできます。

このプログラムを試す手順は以下の通りです。
MyServiceProviderのサービスポートがProvideしてるMyServiceインターフェースを
取得して、MyServiceインターフェースのオペレーションであるecho()を呼んでいます。

1. ネームサーバをローカルに立ち上げる
2. MyServiceProviderをterminal1で立ち上げる
3. terminal2で下のプログラムをコンパイルしたものを起動
4. terminal1で以下のように表示される
MyService::echo() was called.
Message: hogehoge

プログラム中にはクラスリファレンスおよびIDLリファレンスへのURLも
書いてありますので適宜参照しながらごらんください。

------------------
#include
#include
#include "MyService.hh"
#include

int main(int argc, char** argv)
{
CORBA::ORB_var orb;
orb = CORBA::ORB_init(argc, argv);

// RTC::CorbaNaming を使用してネームサーバにアクセス
// http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/ClassReference/classRTC_1_1CorbaNaming.html
RTC::CorbaNaming ns(orb, "localhost");

// RTObjectを取得
// http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/IDLReference/interfaceRTC_1_1RTObject.html
CORBA::Object_var obj = ns.resolve("MyServiceProvider0.rtc");
RTC::RTObject_var rtc = RTC::RTObject::_narrow(obj);

// ComponentProfileを取得
// http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/IDLReference/structRTC_1_1ComponentProfile.html
RTC::ComponentProfile* prof;
prof = rtc->get_component_profile();
std::cout << "RTC name: " << prof->instance_name << std::endl;

// PortProfileを取得
// http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/IDLReference/structRTC_1_1PortProfile.html
RTC::PortProfileList port_prof;
port_prof = prof->port_profiles;
for (CORBA::ULong i(0), len(port_prof.length()); i < len; ++i)
{
std::cout << "name: " << port_prof[i].name << std::endl;

// インターフェースを表示してみる
// http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/IDLReference/structRTC_1_1PortInterfaceProfile.html
RTC::PortInterfaceProfileList ifs(port_prof[i].interfaces);
for (CORBA::ULong j(0), jlen(ifs.length()); j < jlen; ++j)
{
std::cout << "IF name: " << ifs[j].instance_name << std::endl;
std::cout << "IF type: " << ifs[j].type_name << std::endl;
const char* pol;
pol = ifs[j].polarity == RTC::PROVIDED ? "Provided" : "Required";
std::cout << "IF polarity: " << pol << std::endl;
}
}

RTC::Port_var port;
port = port_prof[0].port_ref;

//
// ConnectorProfile のportメンバに自分自身のリファレンスのみ入れて
// connect する。戻ってきたConnectorProfileのpropertiesの中には
// サービスのObjectReferenceが入っているので取得する。
//
// サービスの接続に関する情報はクラスリファレンスのCorbaPortを参照
// http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/ClassReference/classRTC_1_1CorbaPort.html
//
// ConnectorProfile
// http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/IDLReference/structRTC_1_1ConnectorProfile.html
RTC::ConnectorProfile con_prof;
con_prof.name = CORBA::string_dup("tekitouna_namae0");
con_prof.connector_id = "";
con_prof.ports.length(1);
con_prof.ports[0] = port;
con_prof.properties.length(0);
if (CORBA::is_nil(port))
{
std::cout << "nil reference" << std::endl;
return 0;
}

if (port->connect(con_prof) != RTC::RTC_ERROR)
{
// エラーは無視
std::cout << "ignore error" << std::endl;
}
std::cout << "connect OK" << std::endl;

CORBA::Object_ptr aobj;
MyService_var mysvc;

// NVUtilでpropertiesの中からサービスのオブジェクトリファレンスを取得
// http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/ClassReference/namespaceNVUtil.html
if (NVUtil::find(con_prof.properties, "port.MyService.myservice0")
>>= CORBA::Any::to_object(aobj))
{
mysvc = MyService::_narrow(aobj);
}

// サービスを呼ぶ
mysvc->echo("hogehoge");
// MyServiceProviderを実行した画面で以下のように表示されるはず
//
// MyService::echo() was called.
// Message: hogehoge

}

root
Offline
Last seen: 9 hours 59 min ago
Joined: 2009-06-23 14:31
[openrtm-users 00269] サービスポートのRTC以外からの利用に関して

安藤様、

金広@産総研です。

いただいたサンプルが動作することを確認しました。
ありがとうございました。

07/11/16 に Ando Noriaki さんは書きました:
> 金広様
>
> 安藤です
>
> > サービスポートに定義されているIDLのインタフェースをRTC以外の
> > 通常のCORBAクライアントから呼び出す方法はありますでしょうか?
> > どのようにするとサービスの参照を取得できるでしょうか?
>
> RTCのPortにconnectをする際に、そのポート自身のオブジェクトリファレンスのみ
> をConnectorProfileにセットしてconnectしてください。
> そうすると、戻ってきたConnectorProfile::propertiesの中に、
> port.[Service Type].[Service Name] というキーでCORBA::Any型で
> オブジェクトリファレンスが入っています。
> それを、使用したいサービスの型にnarrowして使用してください。
>
> ちょっとごちゃごちゃしてますが、おおよそ以下のようになります。
>
> このファイルとMakefileを添付します。
> 添付のtar-ballをexamples/SimpleServiceの下で展開しmakeしてください。
> make -f Makefile.clientでmakeできます。
>
> このプログラムを試す手順は以下の通りです。
> MyServiceProviderのサービスポートがProvideしてるMyServiceインターフェースを
> 取得して、MyServiceインターフェースのオペレーションであるecho()を呼んでいます。
>
> 1. ネームサーバをローカルに立ち上げる
> 2. MyServiceProviderをterminal1で立ち上げる
> 3. terminal2で下のプログラムをコンパイルしたものを起動
> 4. terminal1で以下のように表示される
> MyService::echo() was called.
> Message: hogehoge
>
> プログラム中にはクラスリファレンスおよびIDLリファレンスへのURLも
> 書いてありますので適宜参照しながらごらんください。
>
>
> ------------------
> #include
> #include
> #include "MyService.hh"
> #include
>
> int main(int argc, char** argv)
> {
> CORBA::ORB_var orb;
> orb = CORBA::ORB_init(argc, argv);
>
> // RTC::CorbaNaming を使用してネームサーバにアクセス
> // http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/ClassReference/classRTC_1_1CorbaNaming.html
> RTC::CorbaNaming ns(orb, "localhost");
>
> // RTObjectを取得
> // http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/IDLReference/interfaceRTC_1_1RTObject.html
> CORBA::Object_var obj = ns.resolve("MyServiceProvider0.rtc");
> RTC::RTObject_var rtc = RTC::RTObject::_narrow(obj);
>
> // ComponentProfileを取得
> // http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/IDLReference/structRTC_1_1ComponentProfile.html
> RTC::ComponentProfile* prof;
> prof = rtc->get_component_profile();
> std::cout << "RTC name: " << prof->instance_name << std::endl;
>
> // PortProfileを取得
> // http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/IDLReference/structRTC_1_1PortProfile.html
> RTC::PortProfileList port_prof;
> port_prof = prof->port_profiles;
> for (CORBA::ULong i(0), len(port_prof.length()); i < len; ++i)
> {
> std::cout << "name: " << port_prof[i].name << std::endl;
>
> // インターフェースを表示してみる
> // http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/IDLReference/structRTC_1_1PortInterfaceProfile.html
> RTC::PortInterfaceProfileList ifs(port_prof[i].interfaces);
> for (CORBA::ULong j(0), jlen(ifs.length()); j < jlen; ++j)
> {
> std::cout << "IF name: " << ifs[j].instance_name << std::endl;
> std::cout << "IF type: " << ifs[j].type_name << std::endl;
> const char* pol;
> pol = ifs[j].polarity == RTC::PROVIDED ? "Provided" : "Required";
> std::cout << "IF polarity: " << pol << std::endl;
> }
> }
>
> RTC::Port_var port;
> port = port_prof[0].port_ref;
>
>
>
> //
> // ConnectorProfile のportメンバに自分自身のリファレンスのみ入れて
> // connect する。戻ってきたConnectorProfileのpropertiesの中には
> // サービスのObjectReferenceが入っているので取得する。
> //
> // サービスの接続に関する情報はクラスリファレンスのCorbaPortを参照
> // http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/ClassReference/classRTC_1_1CorbaPort.html
> //
> // ConnectorProfile
> // http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/IDLReference/structRTC_1_1ConnectorProfile.html
> RTC::ConnectorProfile con_prof;
> con_prof.name = CORBA::string_dup("tekitouna_namae0");
> con_prof.connector_id = "";
> con_prof.ports.length(1);
> con_prof.ports[0] = port;
> con_prof.properties.length(0);
> if (CORBA::is_nil(port))
> {
> std::cout << "nil reference" << std::endl;
> return 0;
> }
>
> if (port->connect(con_prof) != RTC::RTC_ERROR)
> {
> // エラーは無視
> std::cout << "ignore error" << std::endl;
> }
> std::cout << "connect OK" << std::endl;
>
> CORBA::Object_ptr aobj;
> MyService_var mysvc;
>
> // NVUtilでpropertiesの中からサービスのオブジェクトリファレンスを取得
> // http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/ClassReference/namespaceNVUtil.html
> if (NVUtil::find(con_prof.properties, "port.MyService.myservice0")
> >>= CORBA::Any::to_object(aobj))
> {
> mysvc = MyService::_narrow(aobj);
> }
>
> // サービスを呼ぶ
> mysvc->echo("hogehoge");
> // MyServiceProviderを実行した画面で以下のように表示されるはず
> //
> // MyService::echo() was called.
> // Message: hogehoge
>
>
>
> }
>
>
>

>
>

root
Offline
Last seen: 9 hours 59 min ago
Joined: 2009-06-23 14:31
[openrtm-users 00459] サービスポートのRTC以外からの利用に関して

お世話になります。

root
Offline
Last seen: 9 hours 59 min ago
Joined: 2009-06-23 14:31
[openrtm-users 00460] サービスポートのRTC以外からの利用に関して

野村様

安藤です

いつもお世話になっております。

原因は、MyServiceA と MyServiceB で使用されているMyServiceSVC_implクラスの
名称(シンボル)が同じためだと思われます。

同一プロセス内に、同一名のシンボルがロードされた場合、
通常先にロードされたものが有効となります。
後からロードされたもの、(この場合は、MyServiceBのMyServiceSVC_impl)は
すでに同一名のクラスがあるため無効(無視される)となってしまいます。

したがって、MyServiceBでサービスポートに登録されたMyServiceSVC_implが
MyServcieAに付属しているMyServiceSVC_implクラスから生成された、
インスタンスをポートにバインドしてしまうものと思われます。

ためしに、CreateComp.cpp でロードする順番を以下のように変更してみました。

strcpy(szDir,
"/usr/users/n-ando/work/TwoServices/sample/MyServiceB/MyServiceProviderB.so");
manager->load(szDir, "MyServiceProviderBInit");

strcpy(szDir,
"/usr/users/n-ando/work/TwoServices/sample/MyServiceA/MyServiceProviderA.so");
manager->load(szDir, "MyServiceProviderAInit");

こうすると、

Other properties
=================================================
echo MyServiceB[ function invokation succes ! MyServiceProviderB0]
echo MyServiceB[ function invokation succes ! MyServiceProviderA0]
echo MyServiceB[ function invokation succes ! MyServiceProviderB0]
echo MyServiceB[ function invokation succes ! MyServiceProviderA0]

このように、常にMyServiceBのサービスが呼ばれるようになります。

これを避ける方法としては、MyServiceA/BそれぞれのMyServiceSVC_implに
別々の名前をつけるか、それぞれ適当なnamespace (たとえば、MyServiceAやB)
に入れてしまうなどが考えられます。

余談ですが、0.4.2から、rtcdというマネージャのみの実行ファイルが追加(復活)されました。
これを使用すると、CreateCompの代わりに、
MyServiceProviderA.so, MyServiceProviderB.so を同一ディレクトリに置き、
そこに以下のような rtc.conf を作成したうえで、rtcd を起動すると、
これら二つのモジュールをロードして、同一プロセスに2つのコンポーネントを
生成することができます。

corba.nameservers: 192.168.100.1
naming.formats: %n
logger.log_level: PARANOID
manager.modules.load_path: ./
manager.modules.preload: MyServiceProviderA.so, MyServiceProviderB.so
manager.components.precreate: MyServiceProviderA, MyServiceProviderB

なお、この方法でももちろん上記の問題は解決されませんが、rtc.confの書き換えだけで、
ロード順番を試すことはできます。
なお、どちらのシンボルが採用されるかはロードされるときに決まりますので、
コンポーネント生成の順番には関係ありません。

以上で回答になってますでしょうか?
よろしくお願いいたします。

> 昔、下記添付メールのような投稿があったかと思いますが、これに関連して質問があります。
> 同じようなことを、複数のサービスポートに対して、さらに同一プロセス内で動作するローダブルコンポーネントで
> 実現しようとしています。
>
> (質問)
> 同一プロセス内で同じI/Fのサービスポートが複数ある場合には、
> それぞれ異なるサービスを実装することはできないのでしょうか?
>
> (構成)
> 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
>           [サービスA]
>              ↓
>
> [コンポーネントAのサービスプロバイダA]←─(同じI/F)←─┬─[アプリ](RTCではない)
> [コンポーネントBのサービスプロバイダB]←─(同じI/F)←─┘
>              ↑
>           [サービスB]
>
> (コンポーネントAとBを同一プロセス内で立ち上げる)
> 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
>
> (構成の説明)
> インターフェースは同じで、サービス内容の異なる2つのサービスプロバイダAとBを、
> それぞれ別々のコンポーネント上に構成し、同じプロセス内でコンポーネントAとBの両方を立ち上げます。
> そこへ、コンポーネントではないアプリからそれぞれのサービスポートを呼び出す、というものです。
>
> (現象)
> このとき、アプリからA/Bどちらのサービスポートを呼び出しても、サービスAの方が呼び出されてしまいました。
> 試しにコンポーネントA/Bをスタンドアローンとして立ち上げた場合(それぞれ別プロセスで立ち上げた場合)、
> 正しく呼び出すことができました。
> (サービスプロバイダAの呼び出しでサービスAが、サービスプロバイダBの呼び出しでサービスBが呼び出されました。)
>
> (サンプルコード)
> 上記の実験に使用したプログラムをサンプルプログラムとして添付します。
> すみませんが、CreateComp.cppの最初の方に絶対パスの記述がありますので、環境に合わせて書き換えてください。
>
> [フォルダ構成]
> sample/
> ├MyServiceA/   ・・・ 上図のサービスポートAを持つコンポーネントMyServiceAのフォルダ
> ├MyServiceB/   ・・・ 上図のサービスポートBを持つコンポーネントMyServiceBのフォルダ
> ├CreateComp   ・・・ MyServiceAとMyServiceBを立ち上げるプログラム
> └MyServiceCaller ・・・ 実行時のパラメータに"A"か"B"を入力することで、MyServiceAかMyServiceBを呼び出すアプリ
>
> [使い方]
> ・ネームサービスを立ち上げておき、CreateCompを実行してMyServiceAとMyServiceBを立ち上げる。
> ・"> ./MyServiceCaller A"と入力してMyServiceAを呼び出す
> →"echo MyServiceA[〜〜〜"と表示され、MyServiceAのサービスが呼び出されていることが確認できる
> ・続いて、"> ./MyServiceCaller B"と入力してMyServiceBを呼び出す
> →"echo MyServiceA[〜〜〜"と表示され、MyServiceAのサービスが呼び出されてしまっている
> ・試しに、CreateCompを使わずに、MyServiceACompとMyServiceBCompを使って立ち上げた場合には、
>   MyServiceBの呼び出しでMyServiceBのサービスが呼び出された。
>
>
> ちなみに試験した環境はUbuntu7.10、OpenRTM-0.4.1です。
> サービスポートの実装方法が間違っているのでしょうか?
>
> 長くて読みにくくなってしまい、申し訳ありませんが、
> お分かりになる方がいらしたらご教示下さい。
> どうぞ宜しくお願いします。
>
>
>
> ----- Original Message ----- From:
> To:
> Cc:
> Sent: Friday, November 16, 2007 9:17 AM
> Subject: [openrtm-users 00266] Re: サービスポートのRTC以外からの利用に関して
>
>
>> 金広様
>>
>> 安藤です
>>
>>> サービスポートに定義されているIDLのインタフェースをRTC以外の
>>> 通常のCORBAクライアントから呼び出す方法はありますでしょうか?
>>> どのようにするとサービスの参照を取得できるでしょうか?
>>
>> RTCのPortにconnectをする際に、そのポート自身のオブジェクトリファレンスのみ
>> をConnectorProfileにセットしてconnectしてください。
>> そうすると、戻ってきたConnectorProfile::propertiesの中に、
>> port.[Service Type].[Service Name] というキーでCORBA::Any型で
>> オブジェクトリファレンスが入っています。
>> それを、使用したいサービスの型にnarrowして使用してください。
>>
>> ちょっとごちゃごちゃしてますが、おおよそ以下のようになります。
>>
>> このファイルとMakefileを添付します。
>> 添付のtar-ballをexamples/SimpleServiceの下で展開しmakeしてください。
>> make -f Makefile.clientでmakeできます。
>>
>> このプログラムを試す手順は以下の通りです。
>> MyServiceProviderのサービスポートがProvideしてるMyServiceインターフェースを
>> 取得して、MyServiceインターフェースのオペレーションであるecho()を呼んでいます。
>>
>> 1. ネームサーバをローカルに立ち上げる
>> 2. MyServiceProviderをterminal1で立ち上げる
>> 3. terminal2で下のプログラムをコンパイルしたものを起動
>> 4. terminal1で以下のように表示される
>> MyService::echo() was called.
>> Message: hogehoge
>>
>> プログラム中にはクラスリファレンスおよびIDLリファレンスへのURLも
>> 書いてありますので適宜参照しながらごらんください。
>>
>>
>> ------------------
>> #include
>> #include
>> #include "MyService.hh"
>> #include
>>
>> int main(int argc, char** argv)
>> {
>> CORBA::ORB_var orb;
>> orb = CORBA::ORB_init(argc, argv);
>>
>> // RTC::CorbaNaming を使用してネームサーバにアクセス
>> //
>> http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/ClassReference/classRTC_1_1CorbaNaming.html
>> RTC::CorbaNaming ns(orb, "localhost");
>>
>> // RTObjectを取得
>> //
>> http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/IDLReference/interfaceRTC_1_1RTObject.html
>> CORBA::Object_var obj = ns.resolve("MyServiceProvider0.rtc");
>> RTC::RTObject_var rtc = RTC::RTObject::_narrow(obj);
>>
>> // ComponentProfileを取得
>> //
>> http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/IDLReference/structRTC_1_1ComponentProfile.html
>> RTC::ComponentProfile* prof;
>> prof = rtc->get_component_profile();
>> std::cout << "RTC name: " << prof->instance_name << std::endl;
>>
>> // PortProfileを取得
>> //
>> http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/IDLReference/structRTC_1_1PortProfile.html
>> RTC::PortProfileList port_prof;
>> port_prof = prof->port_profiles;
>> for (CORBA::ULong i(0), len(port_prof.length()); i < len; ++i)
>> {
>> std::cout << "name: " << port_prof[i].name << std::endl;
>>
>> // インターフェースを表示してみる
>> //
>> http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/IDLReference/structRTC_1_1PortInterfaceProfile.html
>> RTC::PortInterfaceProfileList ifs(port_prof[i].interfaces);
>> for (CORBA::ULong j(0), jlen(ifs.length()); j < jlen; ++j)
>> {
>> std::cout << "IF name: " << ifs[j].instance_name << std::endl;
>> std::cout << "IF type: " << ifs[j].type_name << std::endl;
>> const char* pol;
>> pol = ifs[j].polarity == RTC::PROVIDED ? "Provided" : "Required";
>> std::cout << "IF polarity: " << pol << std::endl;
>> }
>> }
>>
>> RTC::Port_var port;
>> port = port_prof[0].port_ref;
>>
>>
>>
>> //
>> // ConnectorProfile のportメンバに自分自身のリファレンスのみ入れて
>> // connect する。戻ってきたConnectorProfileのpropertiesの中には
>> // サービスのObjectReferenceが入っているので取得する。
>> //
>> // サービスの接続に関する情報はクラスリファレンスのCorbaPortを参照
>> //
>> http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/ClassReference/classRTC_1_1CorbaPort.html
>> //
>> // ConnectorProfile
>> //
>> http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/IDLReference/structRTC_1_1ConnectorProfile.html
>> RTC::ConnectorProfile con_prof;
>> con_prof.name = CORBA::string_dup("tekitouna_namae0");
>> con_prof.connector_id = "";
>> con_prof.ports.length(1);
>> con_prof.ports[0] = port;
>> con_prof.properties.length(0);
>> if (CORBA::is_nil(port))
>> {
>> std::cout << "nil reference" << std::endl;
>> return 0;
>> }
>>
>> if (port->connect(con_prof) != RTC::RTC_ERROR)
>> {
>> // エラーは無視
>> std::cout << "ignore error" << std::endl;
>> }
>> std::cout << "connect OK" << std::endl;
>>
>> CORBA::Object_ptr aobj;
>> MyService_var mysvc;
>>
>> // NVUtilでpropertiesの中からサービスのオブジェクトリファレンスを取得
>> //
>> http://www.is.aist.go.jp/rt/OpenRTM-aist/doxygen/ClassReference/namespaceNVUtil.html
>> if (NVUtil::find(con_prof.properties, "port.MyService.myservice0")
>>>>
>>>> = CORBA::Any::to_object(aobj))
>>
>> {
>> mysvc = MyService::_narrow(aobj);
>> }
>>
>> // サービスを呼ぶ
>> mysvc->echo("hogehoge");
>> // MyServiceProviderを実行した画面で以下のように表示されるはず
>> //
>> // MyService::echo() was called.
>> // Message: hogehoge
>>
>>
>>
>> }
>>
>>
>>
>>
>

root
Offline
Last seen: 9 hours 59 min ago
Joined: 2009-06-23 14:31
[openrtm-users 00461] サービスポートのRTC以外からの利用に関して

お世話になります。

root
Offline
Last seen: 9 hours 59 min ago
Joined: 2009-06-23 14:31
[openrtm-users 00462] サービスポートのRTC以外からの利用に関して

野村様、

産総研 末廣です。

まず、OpenRTMのテンプレート生成rtm-templateは
同じインタフェースで異なる複数の実装のcorbaオブジェクトを
同じプロセス内に走らせることを想定して作られていないということを
お断りしておきます。

それ自身は、corbaやrtcの仕様には含まれていませんので実現可能なことです。
rtm-templateを使う場合には多少工夫が必要になります。

野村さんの検討された2つの対策ですが、「同じインタフェース」ということが
クライアントから見て同じようにアクセスできる/したいということであるならば、
同一のIDLにするべきです。したがって第2の方法は誤りだと思います。

さて、第1の方法ですが、これも多少誤解があるようなので
少し詳しく説明させていただきます。
まず、たとえば、MyService.idlで定義されたサービスを持つrtcのテンプレートを
生成すると、サービスに関しては、MyServiceSVC_impl.hと
MyServiceSVC_imple.cppの2つが作られます。

ここでMyServiceSVC_impl.hの最初のほうを見ていただくと分かるのですが、
MyServiceSVC_implというクラスは、POA_MyServiceというクラスを
継承しています。
これらはmakeして、omniidlを走らせた後作られるファイルで定義されます。
このPOA_MyServiceというクラスが外部からMyServiceへのアクセスに
対して窓口になります。これはサービスの実装が異なっても同じで良い、
というか同じでないと困るわけです。

したがって、2つの異なる実装を作りたい場合は、
MyServiceSVC_impl.h、MyService_impl.cppを書き換えて、
MyServiceSVC_impl_A.h、MyService_impl_A.cppおよび
MyServiceSVC_impl_B.h、MyService_impl_B.cppを作るというのが
正統的なやり方になります。
そこで、MyServiceSVC_impl_AとMyServiceSVC_impl_Bの2つの
実装クラスを定義するわけです。
この場合、AとBとの間に継承関係は不要です。
それぞれがPOA_MyServiceを継承していれば良い訳です。
もちろんA、B間にプログラムの重複がある場合は
概念的に継承関係があるなら継承させても良いですし、
それぞれ概念的に元になる他の上位クラスを継承させることも
可能です。

さて、このようにして作られた2つ実装をどのように使うかということですが、
たとえば、MyRtcというコンポーネントを作る場合、
MyRtc.hには(おそらく)、
MyServiceSVC_impl m_MyServiceA;
MyServiceSVC_impl m_MyServiceB:
などと記述されているはずです。それを実装が対応するように、
MyServiceSVC_impl_A m_MyServiceA;
MyServiceSVC_impl_B m_MyServiceB;
などと変更します。
おそらくMyRtc.cppの方は変更なしで大丈夫だと思います。

以上でうまくいくと思うので、お試しください。
安藤さん、どうでしょうか?

野村 琢磨 さんは書きました:
> 対策として、2つの方法について検討してみました。
>
> 1.サービスの実装クラスを継承した、異なる名前のクラスを使用する方法
> MyServiceSVC_implクラスを継承して、MyServiceSVC_impl_Aクラスを作成する
> ことで、
> インターフェースが同じで、名前の異なるクラス(=ロードモジュール?)を
> 使う案です。
> この場合は、コンポーネント内のサービスインスタンスの定義と、Makefileを
> 変更すればよいでしょうか?
> また、オブジェクト参照のnarrowで上手く行われるでしょうか?
>
> (サービスの実装クラスの例)
> class MyServiceSVC_impl_A : public MyServiceSVC_impl {
> ・・・
> };
> 〜〜〜〜〜〜〜〜〜〜
>
> 2.IDLインターフェースを継承して、異なる名前のインターフェースを使用
> する方法
> IDLで記述されたMyServiceインターフェースを継承して、MyService_Aイン
> ターフェースを作成することで、
> 異なるインターフェースを使う案です。
> この場合は、IDLの記述を変更すればよいでしょうか?
> また、異なるインターフェース(親は同じ)をCORBA経由で呼び出せるでしょ
> うか?
>
> (IDLの記述例)
> interface MyService_A : MyService {
> (子インターフェースの定義はしない=親と同じ)
> };
> 〜〜〜〜〜〜〜〜〜〜
>
> 2の方が、CORBAの仕組みを使う上では正統のように思いますが、如何でしょ
> うか?

root
Offline
Last seen: 9 hours 59 min ago
Joined: 2009-06-23 14:31
[openrtm-users 00463] サービスポートのRTC以外からの利用に関して

末廣です。

Makefile.MyRtcの方も、
IMPL_OBJ = MyServiceSVC_impl.o
となっているところを
IMPL_OBJ = MyServiceSVC_impl_A.o  MyServiceSVC_impl_B.o
などと変更する必要がありますね。

Takashi Suehiro さんは書きました:
> 野村様、
>
> 産総研 末廣です。
>
> まず、OpenRTMのテンプレート生成rtm-templateは
> 同じインタフェースで異なる複数の実装のcorbaオブジェクトを
> 同じプロセス内に走らせることを想定して作られていないということを
> お断りしておきます。
>
> それ自身は、corbaやrtcの仕様には含まれていませんので実現可能なことです。
> rtm-templateを使う場合には多少工夫が必要になります。
>
> 野村さんの検討された2つの対策ですが、「同じインタフェース」ということが
> クライアントから見て同じようにアクセスできる/したいということであるならば、
> 同一のIDLにするべきです。したがって第2の方法は誤りだと思います。
>
> さて、第1の方法ですが、これも多少誤解があるようなので
> 少し詳しく説明させていただきます。
> まず、たとえば、MyService.idlで定義されたサービスを持つrtcのテンプレートを
> 生成すると、サービスに関しては、MyServiceSVC_impl.hと
> MyServiceSVC_imple.cppの2つが作られます。
>
> ここでMyServiceSVC_impl.hの最初のほうを見ていただくと分かるのですが、
> MyServiceSVC_implというクラスは、POA_MyServiceというクラスを
> 継承しています。
> これらはmakeして、omniidlを走らせた後作られるファイルで定義されます。
> このPOA_MyServiceというクラスが外部からMyServiceへのアクセスに
> 対して窓口になります。これはサービスの実装が異なっても同じで良い、
> というか同じでないと困るわけです。
>
> したがって、2つの異なる実装を作りたい場合は、
> MyServiceSVC_impl.h、MyService_impl.cppを書き換えて、
> MyServiceSVC_impl_A.h、MyService_impl_A.cppおよび
> MyServiceSVC_impl_B.h、MyService_impl_B.cppを作るというのが
> 正統的なやり方になります。
> そこで、MyServiceSVC_impl_AとMyServiceSVC_impl_Bの2つの
> 実装クラスを定義するわけです。
> この場合、AとBとの間に継承関係は不要です。
> それぞれがPOA_MyServiceを継承していれば良い訳です。
> もちろんA、B間にプログラムの重複がある場合は
> 概念的に継承関係があるなら継承させても良いですし、
> それぞれ概念的に元になる他の上位クラスを継承させることも
> 可能です。
>
> さて、このようにして作られた2つ実装をどのように使うかということですが、
> たとえば、MyRtcというコンポーネントを作る場合、
> MyRtc.hには(おそらく)、
> MyServiceSVC_impl m_MyServiceA;
> MyServiceSVC_impl m_MyServiceB:
> などと記述されているはずです。それを実装が対応するように、
> MyServiceSVC_impl_A m_MyServiceA;
> MyServiceSVC_impl_B m_MyServiceB;
> などと変更します。
> おそらくMyRtc.cppの方は変更なしで大丈夫だと思います。
>
> 以上でうまくいくと思うので、お試しください。
> 安藤さん、どうでしょうか?
>
> 野村 琢磨 さんは書きました:
>
>> 対策として、2つの方法について検討してみました。
>>
>> 1.サービスの実装クラスを継承した、異なる名前のクラスを使用する方法
>> MyServiceSVC_implクラスを継承して、MyServiceSVC_impl_Aクラスを作成する
>> ことで、
>> インターフェースが同じで、名前の異なるクラス(=ロードモジュール?)を
>> 使う案です。
>> この場合は、コンポーネント内のサービスインスタンスの定義と、Makefileを
>> 変更すればよいでしょうか?
>> また、オブジェクト参照のnarrowで上手く行われるでしょうか?
>>
>> (サービスの実装クラスの例)
>> class MyServiceSVC_impl_A : public MyServiceSVC_impl {
>> ・・・
>> };
>> 〜〜〜〜〜〜〜〜〜〜
>>
>> 2.IDLインターフェースを継承して、異なる名前のインターフェースを使用
>> する方法
>> IDLで記述されたMyServiceインターフェースを継承して、MyService_Aイン
>> ターフェースを作成することで、
>> 異なるインターフェースを使う案です。
>> この場合は、IDLの記述を変更すればよいでしょうか?
>> また、異なるインターフェース(親は同じ)をCORBA経由で呼び出せるでしょ
>> うか?
>>
>> (IDLの記述例)
>> interface MyService_A : MyService {
>> (子インターフェースの定義はしない=親と同じ)
>> };
>> 〜〜〜〜〜〜〜〜〜〜
>>
>> 2の方が、CORBAの仕組みを使う上では正統のように思いますが、如何でしょ
>> うか?
>>
>
>
>

root
Offline
Last seen: 9 hours 59 min ago
Joined: 2009-06-23 14:31
[openrtm-users 00525] サービスポートのRTC以外からの利用に関して

お世話になります。

root
Offline
Last seen: 9 hours 59 min ago
Joined: 2009-06-23 14:31
[openrtm-users 00530] サービスポートのRTC以外からの利用に関して

野村さま

安藤です

おっしゃる通り、以前のサンプル中にあったConponentProfile* は
ComponentProfile_varにしとかないとメモリリークしますね。

_var型はSTLのauto_ptrとほぼ同じなので、スマートポインタでググれば
どこで使うべきか、使うべきでないかなどいろいろ出てくると思います。
(boost:shared_ptr とは違います。)

でも、たしかに今へんのことについて詳しく書いてある日本語の本は
余りありませんね。私が知ってる日本語の本の中では、以下の本が一番詳しいです。
http://www.amazon.co.jp/CORBA%E5%88%86%E6%95%A3%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E2%80%95Orbix%E3%82%92%E7%94%A8%E3%81%84%E3%81%A6-%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%B3-%E3%83%99%E3%83%BC%E3%82%AB%E3%83%BC/dp/4894711583/ref=sr_1_16?ie=UTF8&s=books&qid=1216041813&sr=8-16

古いので、手に入りにくいのですが。。。。

2008/07/10 21:45 野村 琢磨 :
> お世話になります。

Log in or register to post comments

Download

latest Releases : 2.0.0-RELESE

2.0.0-RELESE Download page

Number of Projects

Choreonoid

Motion editor/Dynamics simulator

OpenHRP3

Dynamics simulator

OpenRTP

Integrated Development Platform

AIST RTC collection

RT-Components collection by AIST

TORK

Tokyo Opensource Robotics Association

DAQ-Middleware

Middleware for DAQ (Data Aquisition) by KEK