ARTLinux上でOpenRTM-aist-0.4.0で作成したRTコンポーネントをリアルタイム実行するための方法を解説します。 OpenRTM-aistでは、ローダブルモジュールとして作成した実行コンテキスト(ExecutionContext)を動的にロードし、コンポーネントにバインドすることでRTコンポーネントの挙動を制御することが出来ます。
OpenRTM-aist-0.4.0 では、コンポーネントの実行主体(≒スレッド)は、ExecutionContext という明示的に分離されたオブジェクトとなっており、上記のような方法ではリアルタイム化することはできません。
手順としては、以下のようになります。以下から、ARTExecutionContext のソースをダウンロードします。
ファイルを適当なディレクトリーに解凍し、ビルドを行います。 付属の Makefileは/usr/lib/art_syscalls.o が存在するものとして記述されています。 art_syscalls.o が他の場所にある場合は Makefile を書き換えてください。
$ tar xvzf ARTExecutionContext.tgz $ cd ARTExecutionContext/ $ make
作成済みのコンポーネントの *Comp.cpp の先頭部分を変更します。
manager->load("ArtExecutionContext.so", "ArtExecutionContextInit");
setModuleInitProc(MyModuleInit);コンポーネントを再コンパイルします。
$ make -f Makefile.yourcomp
rtc.conf に以下のように(1)~(4)を追加します。
corba.nameservers: localhost:9876 naming.formats: Sample/%n.rtc logger.log_level: TRACE exec_cxt.periodic.type: ArtExecutionContext # (1) exec_cxt.periodic.rate: 200 # (2) manager.modules.load_path: ./ # (3) manager.modules.abs_path_allowed: yes # (4)
上で作成した ARTExecutionContext.so をコンポーネント実行ディレクトリーにコピーします。
$ cd YourComponentDir $ cp ARTExecutionContext/ARTExecutionContext.so .
コンポーネントを実行します。
$ YourComponentComp
ここでは、ArtExecutionContext を利用した簡単なサンプルを紹介します。(栗原氏提供)
rtc-template にてコンポーネントの雛型を生成します。
以下のように gen.sh のようなファイルを生成すると、再度雛型を生成する際に便利です。
$ mkdir ArtEcSample $ cd ArtEcSample $ vi gen.sh rtc-template -bcxx --module-name=art_ec_test --module-desc=art ec test component --module-version=1.0.0 --module-vendor=S.Kurihara --module-category=Category --module-comp-type=STATIC --module-act-type=DataFlowComponent --module-max-inst=1 $ sh gen.sh File "art_ec_test.h" was generated. File "art_ec_test.cpp" was generated. File "art_ec_testComp.cpp" was generated. File "Makefile.art_ec_test" was generated. File "README.art_ec_test" was generated.
art_ec_test.hのonExecute(),onDeactivate() のコメントを外します。
今回は、onExecute() 内にてgettimeodda() で取得した時間をファイルに書き出すだけのコンポーネントを作成します。
[art_ec_test.cpp]
// -*- C++ -*-
/*!
* @file art_ec_test.cpp
* @brief art ec test component
* @date $Date$
*
* $Id$
*/
#include "art_ec_test.h"
#include <fstream>
#include <sys/time.h>
// 時間をファイルに書き出すためのオブジェクト
ofstream out;
static const char* art_ec_test_spec[] =
{
"implementation_id", "art_ec_test",
"type_name", "art_ec_test",
"description", "art ec test component",
"version", "1.0.0",
"vendor", "S.Kurihara",
"category", "Category",
"activity_type", "DataFlowComponent",
"max_instance", "1",
"language", "C++",
"lang_type", "compile",
""
};
art_ec_test::art_ec_test(RTC::Manager* manager)
: RTC::DataFlowComponentBase(manager),
dummy(0)
{
// ファイルオープン
out.open("cycle.log");
}
art_ec_test::~art_ec_test()
{
}
/*
RTC::ReturnCode_t art_ec_test::onActivated(RTC::UniqueId ec_id)
{
return RTC::RTC_OK;
}
*/
RTC::ReturnCode_t art_ec_test::onDeactivated(RTC::UniqueId ec_id)
{
// ファイルクローズ
out.close();
return RTC::RTC_OK;
}
RTC::ReturnCode_t art_ec_test::onExecute(RTC::UniqueId ec_id)
{
/****** 時間取得とファイルへの書き出し ***********/
timeval tv;
gettimeofday(&tv,0);
out << tv.tv_usec << std::endl;
/************************************************/
return RTC::RTC_OK;
}
extern "C"
{
void art_ec_testInit(RTC::Manager* manager)
{
RTC::Properties profile(art_ec_test_spec);
manager->registerFactory(profile,
RTC::Create<art_ec_test>,
RTC::Delete<art_ec_test>);
}
};
art_ec_testComp.cppのmain()関数内のmanager->setModuleInitProc(MyModuleInit);の 上に以下の1行を追加します。
manager->load("ArtExecutionContext.so", "ArtExecutionContextInit");ART用ExecutionContext?を利用するためにはARTExecutionContext?.soがコンポーネント実行ディレクトリに在る必要があります。
$ cd ArtEcSample $ cp ~/ARTExecutionContext/ARTExecutionContext.so .
以下の方法にてコンポーネントを実行後、Activate,DeActivate を行うと cycle.log というファイルができます。
$ ./art_ec_testComp
以下は、上記コンポーネントにて計測した毎周期の差分時間のデータです。
表示されている値はマイクロ秒です。
[exec_cxt.periodic.rate: 1000] 1015 1004 997 1001 984 1033 956 1024 991 981 995 1026 1006 999 973 1009 1012 999 1010 1002
[exec_cxt.periodic.rate: 200] 4997 5022 4977 5010 4994 4998 4992 5013 4993 5004 5015 4979 5006 4996 4990 5009 4999 4998 5007 4998 4984
このように、ARTLinux を用いて既存のコンポーネントをリアルタイム化することができます。