[openrtm-users 03222] ECの実装についての提案

1 post / 0 new
tmsimiz
Offline
Last seen: 8 years 4 months ago
Joined: 2011-05-23 10:15
[openrtm-users 03222] ECの実装についての提案

OpenRTM-aist開発者各位

静岡大の清水です。

コンポーネントのonExecute()から自身をdeactivateした場合、
現行のECの実装では、deactivate_component()がタイムアウト付きの
同期呼び出しになっているため、必ずタイムアウト時間(10秒)
待たせられます。

さらに、deactivate_component()の戻り値がERRORとなります。

基本的には、deactivate_component()は同期呼び出しの方が
よいと思いますが、上記のように、コンポーネント内部から
自分をdeactivateしたい場合はデッドロックの問題が発生します。

そこで、対処策を考えてみました。
デッドロックが起きるケースは、
あるECが駆動しているRTCの内部から、
そのECが駆動しているRTCのdeactivateを行った場合のみです。
すなわち、deactivate_component()の呼び出し元のスレッドと、
ECのスレッドが同一である場合のみデッドロックが起きます。

よって、deactivate_component()の呼び出し元のスレッドIDと
ECのスレッドIDが一致するかを確認して、
一致する場合は非同期呼び出し、
一致しない場合は同期呼び出しとなるように実装すれば
問題を回避できるはずです。

試しに、Linux(POSIX)環境で上記の実装を行ってみました。
OpenRTM1.1.1のC++ソースとの差分を添付します。
見てもらえればわかりますが、実装は簡単です。

とりあえず、POSIX用しか実装していませんが、
Windowsでも同様の実装ができるはずです。
また、OSによる実装の違いはcoilで吸収できるので、
RTMコアの汎用性やportabilityは保証されます。

上記の実装が上手く機能するか、
以下のようなRTCでテストしてみました。
onExecute()が10000回呼ばれたら自動でdeactivateするという実装です。

onExecute(UniqueId ec_id)
{
   ReturnCode_t ret(RTC_OK);
  

   m_tick++;

   if (m_tick > 10000) {
       ExecutionContext_var ec;
       ec = this->get_context(ec_id);
       ret = ec->deactivate_component(this->getObjRef());

   }

   return ret;

}

テストした結果、上記のパッチを当てたRTMでは、
タイムアウト待ちなしでdeactivateに成功しました。

また、RTSEからdeactivateした場合(別プロセスからdeactivateした場合)は
deactivate_component()は同期呼び出しとなり、
この場合も問題なくdeactivateできました。

以上、deactivate_component()の実装を検討してもらえると幸いです。

清水

Undefined

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