今日の一言
2009/09/18(Fri) 利用ユーザ限定され過ぎなメモ [長年日記] 2:30現在曇 21℃
_ [FC][Ubuntu][Linux][OpenRTM][プロジェクト実習]OpenRTMにおけるRTコンポーネントの作り方(やっつけ仕事版)
本家のHP(http://www.is.aist.go.jp/rt/OpenRTM-aist/html/)がわかりにくいので、自分なりに「適当に」まとめた。
インストールやらなんやら思いっきり省いているので、そこは本家HPを見て頑張れ。気が向いたら書くかもしれんが。
基本的にはダウンロードのページからOSにあったパッケージをダウンロードしてインストールする。
ライブラリのバージョンに依存するようなコンポーネントを使う予定がある場合はひとつずつ手動で入れた方がいい。(ACEとかomniあたりは特に)
注)OpenRTMの最新版は1.0だが、1.0はバグだらけなので、0.42を使うのが賢明。なんでやねん!
OpenRTM本体の他にも、
eclipse + RTC Link + System Editor(もしくはRTCBuilder) + RtcTemplate
が必要だが、これもダウンロード->GUIツール関係からDLする。
基本的には全部入りパッケージをDLして好きな場所に解凍するだけでいいはず。
Javaの切り替えについては以前に書いた通り。
ちなみにLinux(Ubuntu,FC)でしか試してないので、他の環境で通じるかは不明。
rtc-template(CUI)を使ってコンポーネントのテンプレートを作成。
適当な作業ディレクトリを作成。
$ mkdir TextInput
エディタで以下のような内容のシェルスクリプト(gen.sh)を作る。
rtc-template -bcxx \ --module-name=TextInput --module-type='Input' \ --module-desc='Text Input Component' \ --module-version=0.1 --module-vendor='NAIST_robotics' \ --module-category=Generic \ --module-comp-type=DataFlowComponent --module-act-type=SPORADIC \ --module-max-inst=1 \ --outport=outstr:TimedString \
で、実行。
$ sh gen.sh
これでTimedString型のoutstrという名前を持ったoutportを1つだけ持つコンポーネントが出来あがる。
また、別の名前を与えれば、複数のinport、outPort、servicePortを持つことも可能。
詳しい説明はコンソールで
$ rtc-template --help
を打てば表示される。
ヘッダファイルの修正
ヘッダファイル(TextInput.h)を開き、使用したい関数に関する部分をコメントから出す。
<例>
// The finalize action (on ALIVE->END transition) // formaer rtc_exiting_entry() // virtual RTC::ReturnCode_t onFinalize();
を
// The finalize action (on ALIVE->END transition) // formaer rtc_exiting_entry() virtual RTC::ReturnCode_t onFinalize();
にする。
基本的には次の5つを使うだけでいいはず。
onInitialize (起動時の処理)
onFinalize (終了時の処理)
onActivated (System Editerでアクティブにした時の処理)
onDeactivated (System Editerでディアクティブにしたときの処理)
onExecute (アクティブ中の処理)
ちなみに、rtc-templateで指定した入出力用の変数もここで宣言されている。
<例>
// DataOutPort declaration // <rtc-template block="outport_declare"> TimedString m_outstr; OutPort<TimedString> m_outstrOut;
ソースファイルの修正
ソースファイル(末尾にCompが付かない方。TextInputComp.cppではなく、TextInput.cppの方)を修正する。
ヘッダファイルでコメントから出した関数をコメントから出し、そこにやりたい処理を書く。
*コンポーネントの入出力に関しては上に示した変数を使えばいい。
出力については、m_outstrにデータを書きこみ,m_outstrOutでデータをOutPortからネットワークに送り出す。
例、
RTC::ReturnCode_t TextInput::onExecute(RTC::UniqueId ec_id) { std::string str; std::cin >> str; m_outstr.data=str.c_str(); m_outstrOut.write(); return RTC::RTC_OK; }
入力については出力のほぼ逆で、最初に
if(m_inStrTalkIn.isNew) { m_inStrTalkIn.read(); }
みたいな形で、更新された入力データを読み込むことで、入力値を変数m_inStrTalkとして扱えるようになる。
コンパイルする
コンパイルにはrtc-templateで作られるMakefile.TextInputを使う。
$ make -f Makefile.TextInput
コンポーネントを実行する前に
コンポーネントの実行前に、ネームサーバを立ち上げる。
$ rtm-naming 9876
rtm-namingの後に続く数字は任意でいいが、
実行にはrtc.confが必要となる。
最低限、以下のようなネームサーバーのURLと命名規則だけ書いていれば動く。
<例>
corba.nameservers: 127.0.0.1:9876 naming.formats: %n.rtc
ちなみに、
corba.nameservers: localhost
と書くと、ローカルホスト(大体の場合は127.0.0.1)の9876(デフォルト値)につながる。
さらに言うと、コンポーネントをフォルダ分けして表示したい場合は、
naming.formats: hogehoge./%n.rtc
とすればいい。(hogehogeがフォルダ名)
実行してみる。
_ コンポーネントの実行
こんな感じで実行する。
$ TextInputComp -f rtc.conf
注1)onInitializeに何も書かれていない場合、当然なんの反応も帰ってこない。
ぱっと見、フリーズしているようにも見えるので、最初はちょっと焦る。
注2)1つのコンポーネントにつき、1つのコンソールが必要。正直うざい。