Download
latest Releases : 2.0.0-RELESE
2.0.0-RELESE | Download page |
Number of Projects
RT-Component | 153.5 |
RT-Middleware | 35 |
Tools | 22 |
Documentation | 2 |
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
いつも御世話になります。宇田@NECシステムテクノロジーです
以前にこちらのメーリングリストで、安藤様から非同期呼び出し時の
コールバックにつきまして下記の方法をご紹介頂いたかと思いますが、
こちらで試させて頂きましたところ、コンシューマ→プロバイダ間を
多対1にリンクした場合に、必ずしも呼出元のコンシューマに対して
コールバックが掛からない状況に遭遇しました。
┌───────┐
│ │ do()→
│ コンシューマ □─────┐
│ │ │
└───────┘ │
│
┌───────┐ │ done() ┌───────┐
│ │ do()→ │ ?← │ │
│ コンシューマ □─────┼─────□ プロバイダ │
│ │ │ │ │
└───────┘ │ └───────┘
│
┌───────┐ │
│ │ do()→ │
│ コンシューマ □─────┘
│ │
└───────┘
そこで、サービスポートにCallbackサービスを登録する代りに、下記
のdo()オペレーションの引数にCallbackオブジェクトを渡し、オペレ
ーションの終了時にこのCallbackオブジェクトのdone()を呼ぶ方式を
採りたいのですが、OpenRTMのコーディングスタイルとして、このよう
に実装しても問題ございませんでしょうか?
┌───────┐
│ │ do(cb)→
│ コンシューマ □─────┐
│ │ │
└───────┘ │
│
┌───────┐ │cb->done()┌───────┐
│ │ do(cb)→ │ ← │ │
│ コンシューマ □─────┼─────□ プロバイダ │
│ │ │ │ │
└───────┘ │ └───────┘
│
┌───────┐ │
│ │ do(cb)→ │
│ コンシューマ □─────┘
│ │
└───────┘
また具体的な実装方法としては下記を想定しているのですが、実装上
まずい箇所などがございましたらご教授頂けますでしょうか?
よろしくお願い申し上げます。
Callback.idl
┌───────────┐
│interface Callback │
│{ │
│ void done(); │
│}; │
└───────────┘
MyService.idl
┌──────────────────┐
│#include "Callback.idl" │
│interface MyService │
│{ │
│ oneway void do(in Callback cb); │
│}; │
└──────────────────┘
gen.sh
┌─────────────────────────┐
│#!/bin/sh │
│rtc-template -bcxx \ │
│ ・・・ │
│ --service=MyService:myservice0:MyService \ │
│ --service-idl=MyService.idl \ │
│ --consumer-idl=Callback.idl │← 追加
│ │
│rtc-template -bcxx \ │
│ ・・・ │
│ --consumer=MyService:myservice0:MyService \ │
│ --consumer-idl=MyService.idl \ │
│ --service-idl=Callback.idl │← 追加
└─────────────────────────┘
MyServiceConsumer.h
┌─────────────────┐
│class MyServiceConsumer │
│{ │
│ ・・・ │
│ private: │
│ CallbackSVC_impl m_callback; │
│ Callback_var m_callback_ref; │
│} │
└─────────────────┘
MyServiceConsumer.cpp
┌──────────────────────────────────────┐
│MyServiceConsumer::MyServiceConsumer(RTC::Manager* manager) │
│ ・・・ │
│{ │
│ ・・・ │
│ PortableServer::ObjectId_var oid; │
│ CORBA::Object_var oref; │
│ oid = _default_POA()->activate_object(&m_callback); │
│ oref = _default_POA()->create_reference_with_id(oid, _tc_Callback->id()); │
│ m_callback_ref = Callback::_narrow(oref); │
│ ・・・ │
│} │
│ │
│ │
│RTC::ReturnCode_t MyServiceConsumer::onExecute(RTC::UniqueId ec_id) │
│{ │
│ ・・・ │
│ m_myservice0->do(m_callback_ref); │
│ ・・・ │
│} │
└──────────────────────────────────────┘
MyServiceSVC_impl.cpp
┌───────────────────────┐
│void MyServiceSVC_impl::do(Callback_ptr cb) │
│{ │
│ ・・・ │
│ cb->done(); │
│} │
└───────────────────────┘
> あるサービスポートのプロバイダ側で、
>
> interface MyService
> {
> oneway void do();
> };
>
> という、サービスプロバイダを持たせ、かつ同じポートに、
>
> interface Callback
> {
> void done();
> };
>
> のような、コンシューマを持たせます。
>
> サービスコンシューマの方は、これと逆にプロバイダとコンシューマを持たせます。
> つまり、
> - MyService のコンシューマ
> - Callbackのプロバイダ
> を持つことになります。
> これらのプロバイダとコンシューマはポートを接続することにより相互に接続されます。
>
> MyServiceのプロバイダ側では、do()の処理が終わったら、
> そのコンシューマのdone()を呼んでやることで、呼び出し側に
> 処理が終わったことを知らせることが可能です。