MyScheduler RTC を作る

MyScheduler は、VisionManipulation にモデルIDを送るだけの、シンプルなRTコンポーネントです。
ここでは、EclipseやRTC Builderのチュートリアルも兼ねて、画面キャプチャつきで詳細に説明します。

PyDev プロジェクトを作成する

新規プロジェクトとして、PyDevの下にあるPyDev Project を選び、「次へ」。
NewProject.png

PyDev Project は、
• Project name: MyScheduler
• Project contents: use default
• Project type: Python
• Grammer Version: 2.6
• Interpreter: Default
• Don't configure PYTHONPATH
PyDevProject.png
とします。ほとんどデフォルトのままだと思いますが、Project name と Grammer Version には注意してください。
PyDev パースペクティブを開きますか?と尋ねられますが、すぐに RTC Builder パースペクティブを開くので、いいえで済ませましょう。

PyDev Project を作成すると、workspace ディレクトリに新しく MyScheduler ディレクトリができます。

IDL ファイルを用意する

workspace の下に idl ディレクトリを作り、そこに VisionManipulation.idl をコピーします。

RtcBuilder を使う

Eclipse で、RTC Builder パースペクティブを開きます。
メニューバーの「ウィンドウ(W)」~「パースペクティブを開く」~「その他」を選ぶと、下のような画面が開きます。
OpenPerspective.png
ここでRTC Builder を選びます。RTCBuilderPerspective_0.png
ツールバーのトンカチアイコンをクリックすると、空のRTC Builderが開きます。
EmptyRTCBuilder.png

最初は基本タブが表示されていますが、この画面は RtcBuilderのエディタ画面の下にあるタブで、切り替えることができます。
このタブを切り替えながら、必要な項目を入力していくことになります。

基本タブ

RT-Component Basic Profile 内の項目を以下のように設定します。

RT-Component Basic Profile セクション

  • モジュール名: MyScheduler
  • モジュール概要: Scheduler for test
  • バージョン: 1.0.0
  • ベンダ名: AIST
  • モジュールカテゴリ: VMRG

Output Project セクション

Output Project セクションでは、参照ボタンをクリックして、さきほど作成した MyScheduler プロジェクトを選びます。
Basic.png

アクティビティタブ

利用するアクションコールバック関数をONにします。
今回は onExecute のみを使います。
各コールバック関数の名前がアクションごとに並んでいますが、
「Dataflow型コンポーネントのアクション」のコーナーの左端にある「onExecute」をクリックして、Documentation セクションのアクティビティ名: onExecute となっている右側のスイッチで、ONを選択します。
アクティビティセクションのonExecuteのバックに色がつきます。
Activity.png

サービスポートタブ

ServicePort.png
Add Port ボタンを押すと、新しいポート sv_name が出現します。sv_nameをクリックすると 右側に RT-Component Service Port Profile 画面が開きます。
  • ポート名: Scheduler
  • 表示位置: RIGHT

と設定したら、今度はインターフェースの設定です。
AddPort.png

Add Interfaceボタンを押すと、Scheduer ポートに if_name インターフェースが現れます。if_nameをクリックすると、RT-Component Service Port Interface Profile 画面が開きます。
AddInterface.png

  • インターフェース名: scheduler
  • 方向: Required
  • インスタンス名: scheduler
  • 変数名: scheduler
  • IDLファイル: /home/asahi/workspace/idl/VisionManipulation.idl
  • インターフェース型: SchedulerService
  • IDLパス: /home/asahi/workspace/idl/

ポートとインターフェースの設定は、下のBuildViewに反映します。
BuildView.png

言語・環境タブ

これが最後の設定部分です。
言語セクションで、Python を選択してください。

コード生成

設定がすべて終わったので、基本タブに戻ります。

「コード生成とパッケージ化」セクションのコード生成ボタンをクリックしてください。
「Generate success.」というダイアログが出れば無事完了です。

ここで、「'SchedulerService' is not found in IDL」というエラーが出ることがあります。
そのときは、VisionManipulation.idl を編集して、一行目の #include 文をコメントアウトしてください。

 //#include <rtm/idl/BasicDataType.idl>

もう一度コード生成ボタンを押せば、「Generate success.」というダイアログが出るでしょう。

ここで MyScheduler ディレクトリを見ると、以下のファイルが生成されています。
  • MyScheduler.py: 生成されたRTコンポーネントプログラムの本体
  • MyScheduler.conf: RTコンポーネントの設定ファイルの元
  • idlcompile.bat: IDLファイルをコンパイルするためのコマンド(Windows用)
  • idlcompile.sh: IDLファイルをコンパイルするためのコマンド(Linux用)
  • RTC.xml: エクスポートされた設定

一連の設定は、MyScheduler ディレクトリの下に、RTC.xml というファイルとして保存されます。
RTコンポーネントの設定を変更する必要が出たときは、基本タブの下にある「インポート」ボタンでこのファイルを読み込み直せば、ここまでの設定が再現されます。

MyScheduler.conf は空のファイルなので、以下の内容に書き換えます。

corba.nameservers: localhost:2809
exec_cxt.periodic.rate:2

できたら、rtc.conf にシンボリックリンクを貼ります。
 % ln -s MyScheduler.conf rtc.conf

IDLコンパイル

端末を作成し、workspace/MyScheduler に chdir します。
ここで

 % sh idlcompile.sh

を実行するのですが、現状ではうまく行きません。
 VisionManipulation.idl:19: Error in look-up of 'RTC::TimedDoubleSeq': 'RTC' not found
 VisionManipulation.idl:34: Error in look-up of 'RTC::TimedDoubleSeq': 'RTC' not found
 omniidl: 2 errors.

まず、先ほど VisionManipulation.idl を変更した場合、workspace/MyScheduler に同じファイルがコピーされています。
これをもう一度編集して、一行目のコメントアウトを外してください。

そして、idlcompile.sh を次のように書き換えます。

 omniidl -bpython -I/usr/include VisionManipulation.idl 

-I/usr/include を挿入しています。

編集したファイルをすべて保存したら、あらためて

 % sh idlcompile.sh

を実行してください。
何もメッセージは出ませんが、
• _GlobalIDL_POA
• _GlobalIDL_
• VisionManipulation_idl.py
ができています。

テスト実行

実はこれでもう動きます。端末で python MyScheduler.py を実行してください。

 % python MyScheduler.py 
 comp_args: MyScheduler

プロンプトに戻らなければRTコンポーネントが動いています。
さらに、Eclipse で RT System Editor パースペクティブを開きます。
Name Service ビューの中に、MyScheduler0|rtc という項目があったら、これをSystem Diagram にドラッグ&ドロップしてください。
さらにこれをActivateして、コンポーネントが青から緑になればOKです。

端末へ戻り、Controlキーを押しながらCを押してみます。
実行中のRTコンポーネントが終了すると、System Diagram 上のRTコンポーネントも消えることを確認してください。

実装

Eclipse のパースペクティブを PyDev に切り替え、PyDev Package Explorer で MyScheduler を開きます。
アウトラインビューで、MySchedulerクラスの onExecute メソッドを見つけたら、クリックしてください。

 return RTC.RTC_OK

の前の行に、プログラムの実体を記入します。

ここでやりたいのは、Scheduler ポートの scheduler インターフェースの先に接続したRTコンポーネント(これから作成する VisionManipulation)の、setModelID メソッドを呼ぶことです。

そのためのコードはこうです。

 self._scheduler._ptr().setModelID(42)

self._scheduler が、先にRTC Builder のサービスポートタブで設定した、Schedulerポートのschedulerインターフェースのscheduler変数に当たります。(schedulerが続いてわかりにくいですが察してください)

その _scheduler が持つ、_ptr() というメソッドが、System Diagram画面で接続された先のRTコンポーネントを指しています。
このコンポーネントが持つ setModelID を呼び出しているわけです。

ついでに print 文も追加して、setModelIDを呼ぶと同時にメッセージを表示させましょう。

    def onExecute(self, ec_id):
        self._scheduler._ptr().setModelID(42)
        print "setModelID(42)"
        return RTC.RTC_OK
    

onExecute メソッド全体では以上のようになります。

python なので、再コンパイルの必要はありません。
先ほどと同じように python MyScheduler.py を実行し、エラーが出ないことを確認してください。

完成

これで MyScheduler RTC は完成しました。
引き続き、VisionManipulation RTC を作る に移ります。