RTミドルウェアRTミドルウェアについて「ロボット知能ソフトウェアプラットフォームの開発」に関わりましたので、RTミドルウェアを使ってRTCを作成したり、軽量化を進めるようにしています。将来的には、Android版をつくろうかと思っています。RTミドルウェアについては、オフィシャルページを参照してください。参照URL:OpenRTM-aistオフィシャルRTミドルウェアとRtORB、そしてRTミドルウェアのC言語マッピングRtORBは、RTミドルウェアを軽量化するということと、他のライブラリへの依存度を少なくするために実装したCORBAです。現在は、RtORBを使ってRTミドルウェアを動作させることが出来ています。RtORBは、ほとんどCORBAの仕様に準拠していますが、コア部分をC言語で記述したため、RTミドルウェアには、C++のラッパーを実装することで対応しています。CORBAで重要となるIDLコンパイラから出力されるコードは、基本的にC言語ですので、すべてのコードをC++とコンパチに作るのは難しいですし、コード量が非常に増えてしまっていますし、メモリーリークが発生していました。CORBAの特徴でもあるスマートポインタ(_varや_ptr)の実装は非常に難しく、この部分でもメモリーリークが簡単に起こってしまいます。そのため、RtORBのRTミドルウェア(C++版)への対応は、現在のパージョン(1.1.0)で一時停止し、今後は、C言語版のRTミドルウェア実装に最適化をしていきたいと思っています。RTミドルウェアのC言語版の実装を目指して、現在の実装を見ていきたいと思います。OpenRTM-aist-1.0の基本的な動作について下記のドキュメントは、私がソースコードを読んで理解した部分ですので、今後のリリース、バグフィックによっては、動作が変わっていることがあります。正確な動作を知りたい場合には、オフィシャルサイトの文書、仕様書を参照しながら、ご自身でソースリーディングして下さい。OpenRTM-aistにおけるRTコンポーネントの基本的な動作(main関数)OpenRTM-aistのRTCをプロセスとして起動させるプログラムの基本的に下記の手続きをとる。argv);ManagerオブジェクトにRTCの初期化処理関数(activateManagerで呼び出される)を登録。maneger->setModuleInitProc(MyModuleInit);Managerオブジェクトのアクティベートとネームサーバーへの登録manager->activateManager();Managerの実行(イベント処理ループを実行させる)manager->runManager()Managerオブジェクトの詳細については、マニュアルを参照RTC::Managerオブジェクトの初期化Managerオブジェクトの生成マニュアルには、下記のように記載されている。マネージャをコマンドライン引数を与えて初期化する。呼ばなければならない。生存期間の一番最初にはinit()を呼ぶ必要がある。NamingManager(this);NameingManagerを生成して、NameServerに関する初期設定を行う。設定もここで行うが、デフォルトでは、YESに設定されていることに注意。この設定は、定期的にNameServerに自分を登録するというもの。initFactories()の呼び出し:manager->initFactories()。関数を呼び出しているだけ。FactoryInit()は、下記を順に呼び出している。manager->initExecContext()ExecutionContextの初期化。下記の3つの関数を呼び出している。manager->initComposite()PeriodicECSharedCompositeInit(this)を呼び出しているだけ。manager->initTimer()Timerを初期化すると思うのだが、現在は何もしていない。RTM::Manager::_narrow(obj);ManagerオブジェクトにRTCの初期化処理関数を登録。スロットに関数を代入している。m_initProcは、次のアクティベートの最後の方で呼び出される。RTCの初期化と生成(manager->createComponent(name)を呼び出している)。Managerを獲得し、Nilかどうかをチェック。getPOAManager()は、m_pPOAManagerを返すだけ。Managerをアクティベート:this->getPOAManager()->activate()m_config["manager.modules.preload"]をチェックしてモジュールの読み込みを行うこのとき、m_config["manager.modules.preload"]は、":"を区切りとしたモジュール名を列挙したものになっている。m_module->load(mods[i],basename);を実行している。実行config["manager.component.precreate"]をチェックして設定されたコンポネントを生成する。this->createComponent(comp[i].c_str());の呼び出し。createComponentについては、こちらを参照。Managerの実行(イベント処理ループを実行させる)引数でNonBlockingモードかどうかを指定している。OrbRunner(m_pORB);を呼び出して、Threadを生成する。その後、m_runner->open(0)で実行開始。ちなみに、OrbRunnerは、coil::Taskの子クラス。Blockingを指定m_pORB->run()を呼び出して、イベントループが実行される。RTコンポーネントの構造OpenRTM-aistにおいて、RTコンポーネントは以下のような要素から構成されている。コンポーネントプロファイルコンポーネントのメタ情報。コンポーネントの名前や所有している。アクティビティコンポーネントのコアロジック。アクティビティは状態遷移を持ち、各状態や状態間遷移時の処理(アクション)としてコアロジックが実行される。実行コンテキストスレッドの抽象表現。アクティビティのアクションを状態に応じて実行する。Centric)通信をサポートするポート。Publisher/Subscriberモデルに基づきコンポーネント間のデータの送受信を抽象化する。外部からデータを受け取りアクティビティ等コアロジックに渡すためのポート。Subscriberとしてのインターフェースを持つ。アクティビティで生成されたデータを外部に送信するためのポート。OutPortは接続毎にPublisherを持ち、データはPublisherを介してInPortに渡される。サービスポートユーザ(コンポーネント開発者)定義の任意のサービスインターフェースを持たせることができるポート。任意の数、任意の種類のインターフェースを持たせることができる。サービスを提供するためのインターフェース。通常、コンポーネントのコアロジックの詳細な機能に外部からのアクセスを提供するために作成される。サービスを利用するためのインターフェース。他のコンポーネントのサービスプロバイダを利用するため作成される。コンフィギュレーションインターフェースコンポーネントのコアロジックのパラメータを外部から参照・変更するためのインターフェース。パラメータ名と値のペアのリストと、その識別名および説明からなるコンフィギュレーションセット(ConfigurationSet)を複数持つことができ、動作中に動的に切り替えることができる。RTコンポーネントのアクティビティの詳細は、こちらを参照。OpenRTM-aistのインターフェース構造OpenRTM-aistのIDLについてOpenRTM-aistには、次のIDLがある。BasicDataType.idlDataPort.idlExtendedDataTypes.idlInterfaceDataTypes.idlManager.idlOpenRTM.idlRTC.idlSDOPackage.idlIDLで定義されているインターフェースの構成OpenRTM-aistのIDLに定義されているインタフェースの構成は、下図のようになっている。上の図で、赤の楕円で囲まれたインターフェースは、現在実装されているインターフェースである。したがって、現時点で実装されていないインターフェースを除くと下図のようになる。RTC1.0の仕様で規定されているIDLのインターフェースの構成は、下図のようになっている。OpenRTM-aistのオブジェクトOpenRTM-aistのオブジェクトの関係を下記に示す。RTC::RTObject_implである。