Creating RTCs on OpenRTM-aist Python for Windows
Windows OS上のOpenRTM-aist Python版でRTコンポーネントを作成する方法を解説します。
▶ 更新履歴
-
22/12/2013 ソースコードの説明を行ごとに指示するよう変更しました。また、ソースコードの誤記を修正しました。

3. テンプレートの生成
まずは「ConsoleIn」のテンプレートを生成しましょう。
テンプレートの生成には、RTミドルウェアの統合開発環境環境であるOpenRTPを使用します。
OpenRTPはeclipseのプラグインとして実装されています。
OpenRTPを解凍するとeclipseというフォルダがあり、その中のeclipse.exeをダブルクリックして起動して下さい。
*eclipseの動作にはJavaが必要となります。Javaがインストールされていない場合はインストールして下さい。
1. はじめに
OpenRTM-aistの動作確認に使用したConsoleInとConsoleOutを作成しながら、RTコンポーネントの作成方法を学びます。
RTコンポーネントの作成手順は以下のようになります。
(1) テンプレートの生成
(2) ビルド環境の設定
(3) コーディング
(4) 動作確認
RTコンポーネントの基本的な機能である、RTコンポーネント間の通信やRTコンポーネントの状態遷移などのRTMの基本となる処理に関しては、テンプレート生成時に自動的に記述されます。
そのため、開発者はRTコンポーネントのコアロジックの記述に集中することができます。
それでは早速、RTコンポーネントを作成してみましょう。
2. 必要なソフトウェア
RTコンポーネントの作成に必要なソフトウェアを以下に示します。
・OpenRTP 1.1.0-RC4
eclipse381-openrtp110rc4v20130216-ja-win32-x86_64.zip
OpenRTPはインストールは不要です。圧縮ファイルを適当な場所に解凍してください。
はじめて起動すると以下のように、ワークスペースを選択するダイアログが表示されます。
今後OpenRTMの開発に使用するフォルダを指定して下さい。
また、「この選択をデフォルトとして使用し、今後この質問を表示しない」にチェックをつければ、起動時に毎回聞かれずに済みます。

OpenRTPが起動すると以下の画面が起動します。
この画面はRT System Editorとなっ ています。
以下のどちらかの方法で、RTC Builderにパースペクティブを切り替えます。
①の「「RTC Builder」 パースペクティブ」ボタンを押します。
②の「パースペクティブを開く」から「その他」を選択し、「RTC Builder」を選択します。

RTC Builderにパースペクティブを切り替えると、以下のような画面となります。
①の「Open New RtcBuilder Editor」ボタンを押します。
すると新しいプロジェクト名を指定するダイアログが立ち上がります。
まずは、ConsoleInを作成するので、プロジェクト名は「ConsoleIn」として下さい。

新規プロジェクトを立ち上げると、以下の画面が表示されます。
① 作成しているパッケージが参照できます。
② 編集中のパッケージや起動中のSystem Editorを切り替えることができます。
③ RTコンポーネントのテンプレート作成に必要な情報を入力します。
④ 入力する情報を切り替えるタブです。
⑤ 作成中のRTコンポーネントの形状(データポートの数や種類)を確認することができます。
②の領域に情報を入力することでテンプレートを作成できます。


3.1 基本情報の入力
まずは基本情報を入力します。以下の図の①の部分に次の情報を入力して下さい。
-
モジュール名:RTコンポーネントを識別する名前です。
ConsoleIn
-
ベンダ名:RTコンポーネントの製作者の名前です。信頼できるベンダかどうかユーザは確認することができます。
あなたの名前
-
モジュールカテゴリ:RTコンポーネントのカテゴリを入力します。使用方法は未定だそうです。
TEST
-
実行周期:RTコンポーネントの実行周期を指定します。単位はHzです。
100
3.2 アクションコールバックの設定
①のアクティビティタグを選択し、RTコンポーネントのアクションコールバックを設定します。
アクションコールバックはコンポーネントの状態に合わせて呼ばれる関数です。
今回は以下のアクションコールバックを使用します。
②の領域からアクティビティを選択して、それぞれ③のONボタンを押します。
このボタンはアクティビティを選択するごとに、その都度押して下さい。
-
onInitialize
コンポーネントの初期化時に呼ばれます。初期化に必要な処理を記述します。
-
onActivated
Inactive状態からActive状態になるときに呼ばれます。ループの前処理に使用します。
-
onDeactivated実行周期:RTコンポーネントの実行周期を指定します。単位はHzです。
Active状態からInactive状態になるときに呼ばれます。ループの後処理に使用します。
-
onExecute
RTコンポーネントがActive状態のときに周期的に呼ばれます。
RTコンポーネントの周期で設定した値は、onExecuteが呼び出される周期となります。
ほんとどの場合、RTシステムには繰り返し処理が必要となりますので、メインの処理をここに記述することになります。

3.3 データポートの設定
①のデータポートを選択し、RTコンポーネントのデータポートを設定します。
データポートは、RTコンポーネント同士がデータをやり取りする基本的な機能です。
ConsoleInは、ユーザがキーボードに入力した値をOutポートから出力します。
-
Outポートの追加
②のAddボタンを押して、Outポートを追加します。
③の領域にポート名を入力します。今回は「keyboard」とします。
-
Outポートの設定
④の領域からOutポート設定を行います。
データ型:データポートの型を指定します。今回はTimedLongを使用します。
これはlong型(-2147483648~2147483647)のデータと、タイムスタンプがセットになっている型です。
今回は使用しませんが、このタイムスタンプは主にシステムの同期に使用します。
変数名:データポートに名付けられる変数名を指定します。今回は「data」とします。
表示位置:ポートの位置はRT System Editor上でRTCが表示されるときに、どこにポートを表示するか選ぶことができます。
今回はRIGHTを選択します。

3.5 コードの生成
①の基本を選択し、基本情報の入力フォームに戻ります。
②のコード生成ボタンを押すと、テンプレートが生成されます。
Informationダイアログが立ち上がり、「Generate success.」と表示されれば、テンプレートの生成は完了です。


4. コーディング
ついに「ConsoleIn」のコーディングを行います。
ここでは最低限の説明だけを行い、Python言語の解説は他のサイトや書籍に譲ります。
~\ConsoleInフォルダの中にある、「ConsoleIn.py」を編集します。
コードの編集には適当なテキストエディタを使用して下さい。
Pythonをインストールしたときに付属しているIDLEを使うのが楽だと思います。
生成したテンプレートのTabは、Windows上におけるTabの設定と異なり、IDLEはうまく動作しません。
そのため、IDLEからRunさせることはできません。
コードのTabを修正すればこの問題は解決しますが、Tabを変更して正しく動作するか未検証なのでおすすめしません。
そのままコーディングして、RTコンポーネントの実行時に出力されるrtcXXXX.logを確認してデバッグするのが安全だと思います。
ConsoleIn.pyに以下のコードを記述します。
RTコンポーネントは、テンプレート内の必要な部分に記述することで作成します。
今回は、使用する4つのアクションコールバック関数の中に処理を記述します。
必要のないコードを変更したり、削除しないよう気をつけて下さい。
下のコードは編集の必要な部分だけ記しています。実際にはこれらのコールバック関数は並んでいません。
以下にコードを示します。
以下のコードは抜粋となります。生成したテンプレートに当てはめて下さい。
-
def onInitialize(self):
-
self.addOutPort("keyboard",self._keyboardOut)
-
print("onInitialize")
-
-
return RTC.RTC_OK
-
-
def onActivated(self, ec_id):
-
print("onActivated")
-
-
return RTC.RTC_OK
-
-
def onDeactivated(self, ec_id):
-
print("onDeactivated")
-
-
return RTC.RTC_OK
-
-
def onExecute(self, ec_id):
-
print("Please input number: ")
-
self._d_data.data = long(sys.stdin.readline())
-
self._keyboardOut.write()
-
-
return RTC.RTC_OK
コードの解説を行います。
-
3行目
RTコンポーネントの初期化時に「onInitilize」と表示します。
-
8行目
RTコンポーネントがInactive状態からActive状態に遷移するとき、「onActivated」と表示します。
-
13行目
RTコンポーネントがActive状態からInactive状態に遷移するとき、「onDeactivated」と表示します。
-
18行目
キー入力を促します。
-
19行目
_d_data.dataというメンバ変数に入力するデータを格納します。
変数名は以下のように命名されます。
_d_変数名
今回はd_dataとなっています。
-
20行目
_keyboardOutというOutPortオブジェクトでデータをOutPortから出力します。
_keyboardOutの~OutはOutPortの意味で、keyboardは先程命名したポート名です。
このようにして、_d_data.data内の数値をアウトポートから出力します。
以上のコーディングが終了したら、ConsoleIn.pyをダブルクリックして実行してください。
エラーが出た場合は、rtcXXXX.logを見てミスを修正して下さい。
もし実行後すぐに終了した場合は、コマンドプロンプトでConsoleInフォルダまで移動し、ConsoleIn.pyと入力して実行して下さい。
エラーメッセージが読めるはずです。
実行してエラーが出なければ、ついにRTコンポーネントの完成です。
*実際に状態遷移させてみないと本当に完成かはわかりません。
この後の動作確認で状態遷移後にエラーが出たらエラーを修正してください。
5. ConsoleOutの作成
先程までと同様の方法で「ConsoleOut」を作成します。
ConsoleOutのテンプレートの設定は以下のようになります。
-
モジュール名 ConsoleOut
-
ベンダ名 あなたの名前
-
モジュールカテゴリ TEST
-
実行周期 100
-
アクションコールバック
onInitialize
onActivated
onDeactivated
onExecute
-
ポート名(InPort) receive
-
データ型 TimedLong
-
変数名 data
-
表示位置 LEFT
-
言語 Python
ConsoleOut.pyのコードを以下に示します。
以下のコードは抜粋となります。生成したテンプレートに当てはめて下さい。
-
def onInitialize(self):
-
self.addInPort("receive",self._receiveIn)
-
print("onInitialize")
-
-
return RTC.RTC_OK
-
-
def onActivated(self, ec_id):
-
print("onActivated")
-
-
return RTC.RTC_OK
-
-
def onDeactivated(self, ec_id):
-
print("onDeactivated")
-
-
return RTC.RTC_OK
-
-
def onExecute(self, ec_id):
-
if self._receiveIn.isNew():
-
self._d_data = self._receiveIn.read()
-
print("Received: %d" %self._d_data.data)
-
-
return RTC.RTC_OK
コードの解説を行います。
-
3行目
RTコンポーネントの初期化時に「onInitilize」と表示します。
-
8行目
RTコンポーネントがInactive状態からActive状態に遷移するとき、「onActivated」と表示します。
-
13行目
RTコンポーネントがActive状態からInactive状態に遷移するとき、「onDeactivated」と表示します。
-
18-20行目
_receiveInというInPortオブジェクトのisNewメソッドで新しいデータがあるか調べます。
isNewは新しいデータがあればbool値のtrueを返します。
_receiveInの~InはInPortの意味で、receiveは先程命名したポート名です。
-
19行目
データが送られてきた場合は、_receiveInのreadメソッドでオブジェクトを読み込み、
データポートの設定時に命名した変数dataに代入しています。
-
20行目
_d_data.dataというメンバ変数に格納されているのでコンソールに受け取った値が表示されます。
受け取った値は、_d_変数名.dataに格納されています。
以上のコーディングが終了したら、ConsoleOut.pyをダブルクリックして実行してください。
エラーが出た場合は、rtcXXXX.logを見てミスを修正して下さい。
もし実行後すぐに終了した場合は、コマンドプロンプトでConsoleOutフォルダまで移動し、ConsoleOut.pyと入力して実行して下さい。
エラーメッセージが読めるはずです。
実行してエラーが出なければ、ついにRTコンポーネントの完成です。
*実際に状態遷移させてみないと本当に完成かはわかりません。
この後の動作確認で状態遷移後にエラーが出たらエラーを修正してください。
6. 動作確認
基本的には環境のインストール時に行った動作確認方法と同じです。
ただし、今回はRT System EditorはOpenRTPのパースペクティブを切り替えて使用します。
①の「「RT System Editor」パースペクティブ」のボタンを押します。
するとパースペクティブがRT System Editorに切り替わるので、あとは以前と同じです。

3.4 言語の指定
①の言語・環境タブを選択します。
②のPythonにチェックを入れます。

7. おわりに
これでOpenRTM-aist C++版でRTコンポーネントを作成することができるようになりました。
これを参考に自分のRTコンポーネントをどんどん作成してみて下さい。
ちなみにInitialize時と、Activated時、Deactivated時にそれぞれ先ほどコーディングしたメッセージが表示されましたか?
見逃した場合はもう一度RTCの実行からやり直してみて下さい。
RTCの状態が変化していることがよくわかると思います。
このように各状態に何か処理を書くことで、必要なRTシステムを構築していきます。