RTC개발의 흐름

이 페이지에서는 RT미들웨어:OpenRTM-aist를 이용한, RT컴포넌트의 개발 방법에 대해 설명합니다.

개발의 흐름

OpenRTM-aist는 컴포넌트화를 위한 프레임 워크와 컴포넌트를 관리·실행하기 위한 미들웨어로 구성되어 있습니다.

OpenRTM-aist는 컴포넌트를 개발하고 싶은 유저(컴포넌트 디벨로퍼)가 갖는 기존의 소프트웨어 자산 혹은 새롭게 작성한 소프트웨어를 용이하게 RTC화하기 위한 프레임 워크를 제공합니다. 컴포넌트 작성의 흐름은 은 아래와 같습니다.

rtc_devel_flow_ko.png
RTC 및 RT시스템 개발의 흐름

위에서 설명한 처럼, RT컴포넌트가 갖는 공통 인터페이스에 관한 코드 및 다른 컴포넌트와의 데이터의 교환의 처리 등은 RT컴포넌트 프레임 워크에 의해 은폐 되고 있습니다. 이러한 처리는 공통이기 때문에 많은 부분은 라이브러리화나 자동 생성이 가능합니다. OpenRTM-aist에서는 RTC의 모형을 생성하기 위한 툴로서 RTCBuilder를 제공하고 있습니다.

RTC 개발자는 자신이 개발한 기존의 프로그램을 컴포넌트 프레임 워크에 짜넣는 것으로 RT컴포넌트를 작성하여 복수의 RTC를 조합해 로봇 시스템을 구축합니다. 기존의 소프트웨어 자원을 소프트웨어 부품인 RT 컴포넌트로서 작성해 두면, 여러가지 상황에서 재사용이 용이하게 됩니다. 작성된 RTC는 네트워크상의 적당한 장소에 배치해, 임의의 장소로부터 이용 할 수 있습니다.

RTC프레임 워크에 준거해 작성된 RTC는 크게 나누어 2 종류의 형태가 있습니다. 스탠드얼론 RTC(Standalone RT-Component)는 단일의 실행 형식의 바이너리, loadable module RTC(Loadable Module RT-Component)는 동적으로 로드 가능한 바이너리 파일이며, 하나의 프로세스로 복수 종류의 RTC를 동시기동 할 때 등에 이용됩니다.

RTCBuilder에 의한 형태 코드의 작성

RTCBuilder는 RT컴포넌트의 형태 코드를 자동 생성하는 개발툴입니다. RTC의 기본 프로파일이나 데이터포트, 서비스 포트, 컨피그레이션에 관한 정보를 입력하는 것으로 대부분의 코드를 자동 생성합니다. 대응하고 있는 언어는 C++, Java, Python, C#입니다. 컴포넌트를 작성하기 전에, 대략 이하를 결정해야 합니다.

  • 프로파일(이름, 카테고리명, 버젼등)
  • 데이터포트(InPort·OutPort, 포트명, 데이터형)
  • 서비스 포트(포트명, 서비스 인터페이스)
  • 컨피그레이션(변수의 이름, 변수의 형태)

Eclipse 메뉴의 「파일」-「신규」로 다이얼로그를 열어, 「그 외」에서 「RTCBUilder」프로젝트를 선택해 프로젝트명을 입력하면, 아래 그림의 화면이 나타납니다. RTCBuilder에는 「기본」 「액티비티」 「데이터 포트」 「서비스 포트」 「컨피그레이션」 「문서 생성」 「언어· 환경」 「RTC.xml」의 탭이 있어, 「기본」으로부터 「언어·환경」까지의 탭으로 순서로 필요에 따라서 항목을 묻고 있으며, 마지막으로 「기본」탭에 있는 Output Project로 방금전 입력한 프로젝트명을 선택해, 「Code Generation」버튼을 클릭함으로 형태 코드가 생성됩니다. 생성된 코드는 Eclipse 기동시에 지정한 워크 스페이스내의 프로젝트명 디렉토리에 보존됩니다.

rtcbuilder_ja.png
RTCBuilder의 개발 화면

RTC의 구현

RT컴포넌트의 프로그램에는 통상의 프로그램과는 달리 main함수에 직접 처리를 구현할 것은 없습니다. 여기서는 예로 C++버전의 구현에 대해서 설명합니다.

RT컴포넌트는 어느 base class를 계승한 하나의 클래스로서 구현되어 있습니다. RT컴포넌트에 있어 로직이 실시하는 처리는 그 base class의 멤버 함수(메소드)를 오버라이드(override) 하는 형태로 기술합니다. 예를 들면 초기화시에 하는 처리는onInitialize함수안에, RTC가 액티브시에 주기적으로 처리 하고 싶은 내용은 onExecute함수에 기술합니다.

 class MyComponent
  : public DataflowComponentBase
 {
 public:
   // 초기화시에 실행하고 싶은 처리
   virtual ReturnCode_t onInitialize()
   {
     if (mylogic.init())
       return RTC::RTC_OK;
     return RTC::RTC_ERROR;
   }
 
   // 주기적으로 실행하고 싶은 처리
   virtual ReturnCode_t onExecute(RTC::UniqueId ec_id)
   {
     if (mylogic.do_someting())
       return RTC::RTC_OK;
     RTC::RTC_ERROR;
   }
 
 private:
   MyLogic mylogic;
   // 포트 등의 선언
   //   :
 };

위의 소스 코드는 C++로의 구현 예입니다. 이 예는 클래스 선언과 구현이 일체가 되고 있지만, 실제로는 헤더 파일(.h)과 구현 파일(.cpp)에 분할되어 코드가 생성됩니다. MyLogic 클래스의 오브젝트 mylogic은 이 컴포넌트가 실제로 실시하는 코어 로직이 구현된 클래스입니다. 예에서는 매우 간단하게 mylogic의 함수를 부르는 것으로 RTC가 구현되고 있습니다만, 실제의 구현에서는 코어 로직을 미리 이 정도 간단하게 이용할 수 있도록 클래스화해 두어 RTC내에서의 호출은 최저로 하는 것이 좋습니다.

RTCBuilder에 의해 동시에 생성되는 Makefile이나 프로젝트 파일로 이 코드를 컴파일 하는 것으로, 실행 파일과 공유 오브젝트(또는 DLL)가 생성됩니다.

RTC 라이프 사이클

위에서 설명한 것처럼 RTC의 구현에서는, 미리 정해놓은 함수(콜백 함수)에 처리를 기술하는 것으로 컴포넌트를 작성합니다. 어떤 함수가 어떤 타이밍에 불리는지를 알기 위해서는, RTC 상태 천이 즉 라이프 사이클을 이해할 필요가 있습니다. 아래 그림은 RTC 상태 천이도입니다.

rtc_state_machine_ko.png
RTC 라이프 사이클 (UML 상태 천이도)

컴포넌트는 기본적으로 이하 상태를 가진다.

  • 생성 상태(Created)
  • 활동 상태(Alive)
    • 비액티브 상태 (Inactive)
    • 액티브 상태 (Active)
    • 에러 상태 (Error)
  • 종료 상태

이러한 각 상태나 천이시에는 미리 정해놓은 함수 (콜백 함수)가 EC 에 의해서 불려집니다. 표는 콜백 함수와 각각이 불리는 타이밍을 나타냅니다.

함수명 개요
onInitialize 라이프 사이클 초기화시에 한번만 불린다.
onActivated 액티브화할 때에 1회불린다.
onDeactivated 비액티브화할 때에 1회불린다.
onExecute 액티브 상태에 있을 때 주기적으로 불린다.
onStateUpdate onExecute 의 뒤에 매회 불린다.
onAborting 에러 상태로 이행할 때에 1회불린다.
onError 에러 상태에 있을 때 주기적으로 불린다.
onReset 에러 상태로부터 복귀할 때에 1회불린다.
onShutdown EC의 구동이 정지할 때에 1회불린다.
onStartup EC의 구동이 개시할 때에 1회불린다.
onFinalize 라이프 사이클 종료시에 한번만 불린다.

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