ARTLinux상에서 OpenRTM-aist-0.4.0으로 작성한 RT컴포넌트를 리얼타임으로 실행하기 위한 방법을 설명합니다. OpenRTM-aist에서는 loadable module로서 작성한 실행 컨텍스트(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)
{
// File open
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)
{
// File close
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를 이용해 기존의 컴포넌트를 리얼타임화할 수 있습니다.