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를 이용해 기존의 컴포넌트를 리얼타임화할 수 있습니다.