ysuga.net

This page is my hobby page! Robots, Inline skates, Rugby, and more!!

初めてのRTコンポーネント作成

これからRTコンポーネントの作成方法について解説します。自分のロボットを作ためには、RTコンポーネント作成しなくてはなりません。この作業自体はインストールが出来ていれば実は超かんたんです.

概要

RTコンポーネントを作成する手順としては、

  • RTC Builderでスケルトンコードを生成する
  • スケルトンコードを編集する
  • ビルドして実行する

という感じです。

スケルトンコードを生成する時点で殆どの手間が省かれちゃいますので、特定の関数(イベントハンドラ)を編集するのが作業の中心です。

スケルトンコードの生成

まず,骨格(スケルトン)となるソースコードを作ります.これにはEclipseを使います.というのもRTCのプログラムコードのテンプレートを作成してくれるツール,RTC BuilderをEclipseで使うのが正解.またeclipseはRTCの起動状態をRT System Editorというツールを使って操作するときにも使うので,しばらくは起動しっぱなしだと思います.

Eclipse(RTツール全部入り)のインストールについては,インストール編を参考にすると良いでしょう.

RTC Builder

まず,Eclipse(ツール全部入り)を起動します.
メニューの「Window(ウィンドウ)」>「Perspective(パースペクティブ)」を選択し,「RtcBuilder」を選択します.これでRTC Builderが使える状態です.

RTC Builder perspective

RTC Builder perspective

File(ファイル)から,「Open new Builder Editor」を選びます.図のようなエディタが起動します.コレを順番に設定していって,プログラムのテンプレートを作成するのです.

RTC Builder Editor

RTC Builder Editor

まずは超かんたんなコンポーネントを作ってみましょう.

PERIODICなコンポーネントの作成

RTC Builderのコンフィグ

ただ単純にコンソールに文字を出力するだけのプログラムを作成してみましょう.
基本的に下図のタブを選択しながら大まかなカテゴリごとに設定を勧めます.

Tabs

以下のように設定して下さい.ほかの部分には何も記入しないで下さい.

タブ 変数 設定値
基本 Module name PeriodicConsoleOut
Module description Periodic Console Out Component
Module version 0.0.1
Module vender あなたの名前(半角英数字で)
Module category すきなカテゴリ名(とりあえずTest)
Component type STATIC
Component Kind Data Flow
Component’s activity type PERIODIC
Number of maximum instance 1
Execution Type Periodic Execution Context
Execution Rate 1.0
Abstract 不要
RTC Type 不要
Output Project PeriodicConsoleOut
アクティビティ on_execute チェックボックスをONに
言語・環境 言語 C++ / Java / Python
Use old build environment チェックボックスをONに

これまでのバージョンとの大きな変更点は,下図のようにアクティビティのタブで,イベントハンドラを実装することが出来る点です.

注意:Visual C++で開発される方

Visual Studioのソリューションファイルを生成するには,言語タブの「Use old build environment」というチェックボックスをOnにする必要があります.
このサイトのC++の開設ではVisual C++を使っていますので,チェックボックスをONにしてください.

各パラメータの説明(読み飛ばしても出来る!)

  • 基本タグ
    • Module name・・・コンポーネントの名前.スペースを含まない方がいい.
    • Module description・・・コンポーネントの説明.
    • Module version・・・コンポーネントのバージョン.最初は低めで・・・
    • Module vendor・・・コンポーネントのベンダー.あなたの名前を書きましょう.これであなたもRTCベンダーの仲間入り.
    • Module category・・・とりあえずTESTとしておきます.複数のRTCを作るようになれば,これを使って管理する必要が出てくるかもしれませんが,個人でやるレベルでは必要ないと思います.
    • Component type・・・STATIC,UNIQUE,COMMUNICATIVEの3種類がありますが,まだ対応していないようです.
    • Component’s activity type・・・PERIODIC,SPORADIC,EVENT_DRIVENがありますが,PERIODICしか対応していません.
    • Component Kind・・・「Data Flow」「FSM」「Multimode」の3種類があります.RTコンポーネントの仕様で,3つのコンポーネントの種類が定義されていますが,OpenRTM-aistではまだData Flowコンポーネントのみの対応です.
    • Number of maximum instance・・・コンポーネントの同時生成可能数
    • Execution type・・・実行コンテキストのタイプです.実行コンテキストによって,イベントハンドラ「on_execute」の実行タイミングの制御方式が変わります.PeriodicExecutionContext(周期実行)とExtTrigExecutionContext(外部トリガによる実行)があります.通常はPeriodicExecutionContextを選びます.
    • Execution rate・・・実行周期です.単位はHz.
    • Abstract・・・コンポーネントの説明.
    • RTC type・・・RTCのタイプ.PERIODICとか.不要.
    • Output Project・・・Eclipse上のプロジェクト名.コンポーネントと同じで十分.
  • アクティビティ
    • on_execute・・・PERIODIC実行の場合,周期的に実行されるイベントハンドラ.
  • 言語・環境
    • 言語・・・OpenRTM-aistでは,C++,Java,Python,.Netに対応しています.Rubyにも対応予定?

生成

ここで「コード生成」というボタンを押すと「プロジェクトがワークスペース内に存在しません」と言われますが,OKとします.「Generate success」というメッセージが出て,ワークスペースにコンポーネントのテンプレートが生成されています.

Generated Project

Generated Project

言語ごとの開発

タブを選んでください.




生成されたファイルを確認するときは,ワークスペースとして設定したフォルダに移動します.「ファイル>ワークスペースの切り替え」と選択すれば,ワークスペースになっているフォルダを確認できると思います.
生成されたファイルは以下の通りです(ここも読み飛ばしていいよ).

  • .project ・・・Eclipseのプロジェクトファイル.不要
  • copyprops.bat ・・・ホスト固有のコンフィグをコピーするためのバッチファイル
  • Makefile.PeriodicConsoleOut・・・Makeファイル
  • PeriodicConsoleOut.conf・・・コンフィグレーションパラメータ.今回は不要.
  • PeriodicConsoleOut.cpp・・・コンポーネント本体.
  • PeriodicConsoleOut.h・・・コンポーネントのヘッダーファイル
  • PeriodicConsoleOut_vc8.sln・・・VC2005用のソリューション.今回は不要.
  • PeriodicConsoleOut_vc8.vcproj・・・VC2005用のプロジェクト.今回は不要.
  • PeriodicConsoleOut_vc9.sln・・・VC2008用のソリューション.
  • PeriodicConsoleOut_vc9.vcproj・・・VC2008用のプロジェクト.
  • PeriodicConsoleOutComp.cpp・・・コンポーネントを実行ファイル形式で実装するためのmain関数があるファイル.
  • PeriodicConsoleOutComp_vc8.vcproj・・・VC2005用のプロジェクト.
  • PeriodicConsoleOutComp_vc9.vcproj・・・VC2008用のプロジェクト.
  • README.PeriodicCOnsoleOut・・・READMEファイル.
  • rtc.conf・・・コンフィグ.後述.
  • RTC.xml・・・RTC Builderの設定を保存したXMLファイル.RTCProfile形式.
  • user_config.vcprops・・・VC用コンフィグ.

注:開発そのまえに!

copyprops.batファイルをダブルクリックして実行します.すると,rtm_config.vcpropsというファイルがフォルダ内に作成されます.
これはユーザの皆さんがインストールした環境に合わせた設定ファイルです.copyprops.batが環境変数などから自動的に取得してきます.便利ですね.

VC++2008による編集

さて,ここからVC++2008で開発をします.エクスプローラでワークスペースのフォルダに移動し,からPeriodicConsoleOutフォルダを開き,「PeriodicConsoleOut_vc9.sln」を開きます.

つぎにCPPファイルの編集ですが,onExecute関数に,コンソールに周期的に出力するコードを記入します.PeriodicConsoleOut.cppファイルを選択してください.

RTCBuilderで設定するアクティビティのタブでon_executeのチェックボックスをonにしておくと,onExecute関数のコメントアウトが自動的に外れています.手動でこのコメントをはずすことも可能ですが,後に説明するRTCプロファイル(RTC.xml)という,RTC Builderの設定を保存しているファイルとの整合性が取れなくなります.今のところあまりデメリットはありませんが・・・

/*
RTC::ReturnCode_t PeriodicConsoleOut::onDeactivated(RTC::UniqueId ec_id)
{
  return RTC::RTC_OK;
}
*/
RTC::ReturnCode_t PeriodicConsoleOut::onExecute(RTC::UniqueId ec_id) { 
  std::cout << "Hello RTC (ver. 1.0)!!!!" << std::endl;
  return RTC::RTC_OK; 
} 
/*
RTC::ReturnCode_t PeriodicConsoleOut::onAborting(RTC::UniqueId ec_id)
{
  return RTC::RTC_OK;
}
*/

周期の変更に関して

*2010年3月23日現在,ソースコード中のデフォルト値が,rtc.confの値よりも優先されるバグが残っています.ソースコード中のデフォルト値に対応する,構造体のメンバのペアを削除することで解決します.

具体的には,PeriodicConsoleOut.cppファイルの最初の方で宣言されている文字列(periodicconsoleout_spec)から,対応する部分を削除します.
// Module specification

// &lt;rtc-template block="module_spec"&gt;
static const char* directinputcomponent_spec[] =
{
  "implementation_id", "DirectInput",
  "type_name", "DirectInput",
  "description", "DirectInput Component",
  "version", "0.1.0",
  "vendor", "ysuga_net",
  "category", "Test",
  "activity_type", "PERIODIC",
  "kind", "DataFlowComponent",
  "max_instance", "1",
  "language", "C++",
  "lang_type", "compile",
  "exec_cxt.periodic.rate", "100.0", このペアを削除
  "conf.default.debug", "0",
  ""
};

ただしこの方法では,rtc.confに実行周期の記述がないと,自動的に1000Hzになります(OpenRTM-aistのデフォルト値)


Java言語を選択すると,自動的にJavaパースペクティブに移行してます.
生成されたプロジェクトのsrcフォルダにプロジェクトの生成物が表示されます.

  • src
    • (デフォルトパッケージ)
      • PeriodicConsoleOut.java
      • PeriodicConsoleOutComp.java
      • PeriodicConsoleOutImpl.java
  • build_PeriodicConsoleOut.xml
  • PeriodicConsoleOut.conf
  • rtc.conf
  • RTC.xml

さて,生成されたファイルがたくさんありますが,変更するのは基本的に**Impl.javaファイルです.
しかし,最初はImplファイルがビルドできないことに気づくと思います.
OpenRTM-aistのJarファイルがインポート出来ていないからです.

これにはインストールのときに設定したユーザーライブラリーを使います.
プロジェクトのプロパティーを開き,「ビルドパス」を選択します.
さらに「ライブラリー」のタブをクリックして,「ライブラリーの追加」を選択します.

ここで「ユーザーライブラリー」を選択し,インストールのときに設定した「OpenRTM-aist」を選択しましょう.

ここで選択後にOKを押していくと,なぜかjavaファイルがsrcフォルダの外に出てしまいます.

マジふざけんな,と思いますが,ここはぐっとこらえてjavaファイルの3つをsrcフォルダにやさしく戻してあげます.

また,プロジェクトを右クリックして追加することも出来ますが,なぜかJREのデフォルトのライブラリーがインポート出来ない場合があるので,上記の手順なら確実です.

まだ×印が付いている場合は,プロジェクトを右クリックして「プロジェクトのビルド」を選択するとビルド出来ると思います.

さて,「*.impl」ファイルの中にonExecuteという関数があります.この中身を書きかえると,RTCがActive状態であれば,
設定した周期ごとにonExecute関数が呼ばれるってスンポーです.

//    @Override
//    protected ReturnCode_t onDeactivated(int ec_id) {
//        return super.onDeactivated(ec_id);
//    }
 
/***
*
* The execution action that is invoked periodically
* former rtc_active_do()
*
* @param ec_id target ExecutionContext Id
*
* @return RTC::ReturnCode_t
*
*
*/
@Override
protected ReturnCode_t onExecute(int ec_id) {
  System.out.println("Hello RT-Component!");
  return super.onExecute(ec_id);
}
 
/***
*
* The aborting action when main logic error occurred.
* former rtc_aborting_entry()
*
* @param ec_id target ExecutionContext Id
*
* @return RTC::ReturnCode_t
*
*
*/
//  @Override
//  public ReturnCode_t onAborting(int ec_id) {
//      return super.onAborting(ec_id);
//  }

言語をPythonで生成すると,PyDevがインストールされていれば,Pythonパースペクティブに移動して,Eclipseでそのまま開発が出来ます.

生成されたファイルは,

  • .project・・・プロジェクトの設定
  • .pydevproject・・・Pythonの設定
  • PeriodicConsoleOut.conf・・・RTCの個別設定用ファイル
  • PeriodicConsoleOut.py・・・RTCのソースコード本体
  • rtc.conf・・・一般的なRTCの設定ファイル
  • RTC.xml・・・RTC Builderへの設定ファイル.RTCプロファイルと呼ばれる

コードとしてはPeriodicConsoleOut.pyというファイルのみです.あとは後述しますが,rtc.confとPeriodicConsoleOut.confというコンフィグファイルが変更の対象です.

とりあえず,PeriodicConsoleOut.pyを開きます.

思いっきり割愛しながら書くと,コードはこんな感じ.

import sys
import time
sys.path.append(".")
import RTC
import OpenRTM_aist
 
periodicconsoleout_spec = ["implementation_id", "PeriodicConsoleOut", 
		 "type_name",         "PeriodicConsoleOut", 
		 "description",       "Periodic Console Out", 
		 "version",           "1.0.0", 
		 "vendor",            "ysuga.net", 
		 "category",          "Test", 
		 "activity_type",     "STATIC", 
		 "max_instance",      "1", 
		 "language",          "Python", 
		 "lang_type",         "SCRIPT",
		 ""]
 
class PeriodicConsoleOut(OpenRTM_aist.DataFlowComponentBase):
 
        # 思い切り中略!
 
	def onExecute(self, ec_id):
		"""
 
		The execution action that is invoked periodically
		former rtc_active_do()
 
		\param ec_id target ExecutionContext Id
 
		\return RTC::ReturnCode_t
 
		"""
 
		return RTC.RTC_OK

つまり,PeriodicConsoleOutというクラスのonExecute関数のみを見てればいいです.最初はこれだけ.

この関数が周期的に実行されるので,そこに処理を書きます.たとえば,

	def onExecute(self, ec_id):
		print "Hello RT-Component!"	
		return RTC.RTC_OK

という感じです.

ここではこれまで!

これでOK.ビルドしましょう.エラーはないですよね.

rtc.confの変更

コンポーネントを実行する前にやらなくてはならないことがもう一つ.rtc.confファイルの変更です.

このファイルには,RTCの実行に関する設定を記述できます.主な目的は

  • RTCの実行頻度などの管理
  • ネームサービスの位置(URLもしくはIPアドレス)
  • ネームサービス上の名前付けルール
  • ログの管理
  • そのほかCORBAの設定

といったところです.ここではネームサービスの実行されているPCのネットワーク上の位置を追加する必要があります.

rtc.confを秀丸やMeadowなどのテキストエディタで編集してください.

編集前

exec_cxt.periodic.rate:1.0

編集後

exec_cxt.periodic.rate:1.0
corba.nameservers: localhost

このlocalhostの部分にネームサーバーが実行されているマシンのIPアドレスを指定します.複数台のPCで分散的にRTCを実行&接続する場合に関しては後述します.

RTCの実行

インストールのページで踏んだ手順で実行します.

  1. ネームサービスの起動
  2. Eclipse(RT System Editor)の起動
  3. ネームサービスをRTSystemEditorに登録(デフォルトで登録される場合も)
  4. RTC(今回はPeriodicConsoleOutComp)の実行 (VC2008からデバッグで実行でOK)
  5. RT System Editor上で接続(今回は無視)
  6. RT System Editorでアクティベート

Activated RTC

Activated RTC

文字がたくさん出ます.

周期の変更

先ほどのrtc.confの「exec_cxt.periodic.rate」に続く値が実行周期(単位Hz)です.これを変更すれば,文字が表示される頻度が変わります.

リアルタイムなの?リアルタイムにならないの?

OpenRTM-aistのコードを見ればわかりますが,リアルタイムではありません.つまり,周期を100とした場合でも,実行時に100Hzが補償出来ません.Windowsだとキツイです.

ただ,Linuxではカーネルプリエンプションを使ったリアルタイム周期実行が可能になります.いずれ解説します.

RTCの終了

注意!いきなりDOS窓を閉じない!!

終了時はRT System Editor上でRTCを右クリックし,非アクティブ化(deactivate)をした後,さらに右クリックして「終了(exit)」を選択してから終了させてください.現在の状態では,Exit関数を呼び出す方法が他にありません.

exit関数を呼ばずにDOS窓を閉じてしまうと,下図のようにRTCがネームサーバー上に登録されたまま実体の無い「ゾンビー状態」になります.ゾンビーってふざけているようですが,ふつうにハッカー達はゾンビーと呼んでます.

RTC ZOMBEE!

RTC ZOMBEE!

ゾンビが出来てしまってもバージョン1.0からは怖くありません.ゾンビをクリアボタンが付いています.これを押すとゾンビが消えます.

ZOMBEE KILLER!

ZOMBEE KILLER!

再度開発を行う場合

RTC Builderの設定は,RTCBuilderで自動的に生成されたRTC.xmlというファイルに,RTCProfile形式という形で記録されています.これをインポートすることによって,RTC Builderの設定を読み出し,再度スケルトンコードを生成することが出来ます.

EclipseからRTC Builderを開き,RTC Builder Editorを開きます.
基本タブからプロファイル情報のインポート・エクスポートを選び,インポートボタンをクリック!

Reading RTC Profile (RTC.xml)

Reading RTC Profile (RTC.xml)

PeriodicConsoleOutのプロジェクトフォルダからRTC.xmlファイルを選択してインポートします.

RTC.xml is RTC Profile

RTC.xml is RTC Profile

これで前回の設定が復活です.

新しい設定を追加した後に,再度「コード生成」ボタンでコードを生成します.このとき,「比較エディター」画面になります.選択肢として「Original(もとのコードを保持)」「Merge(RTCBuilderのコード生成部分のみ最新で上書き)」「Generate(最新で上書き)」の3つの選択肢があります.Mergeを選べばよいのですが,2009年7月24日現在,バグらしき箇所がありますので,基本的にGenerateを選びます.古いファイルも○○.cpp20090724・・・のようにファイル名が書きかえられて残っています.こちらから自分の手作業でコピー&ペーストしてプログラムを最新にします.

*この方法が許されるように,基本的にメインロジックをRTCコード上に書かずに,独自クラスを実装するようにしましょう.RTCのコードには最小限のコードを書く方がベター.

まとめ

いかがですか?コンポーネント作成がかなり簡単であることが分かると思います.今回はPeriodicなコンポーネントで,しかもデータの授受を全く行いませんでしたが,次回はRT
System Editorからコンフィグレーションの設定が出来るように,今回のプログラムを拡張してみましょう.

今回作成したファイル
PeriodicConsoleOut_v10(C++)
PeriodicConsoleOutJava
PeriodicConsoleOutPy

Get Adobe Flash playerPlugin by wpburn.com wordpress themes