前書き
PepperやNAOの開発をするにあたって、Pythonの知識は必須といえるでしょう。
そこで、簡単にですが、NaoqiにおけるPythonボックスの説明をしたいと思います。
開発環境
機種名 : MacBook Pro
OS : Yosemite 10.10.3
プロセッサ名 : Intel Core i5 2.6 GHz
メモリ : 16 GB
グラフィック : Intel Iris 1536MB
Choreographe : 2.3.1
本題
Pythonボックス
Pythonボックスとは
まずはPythonボックスについて簡単に説明したいと思います。
Pythonボックスは、ボックスライブラリの以下のところにあります。
なければ虫眼鏡マークから検索かけてください。
[Programming]->[Template]->Pythonボックス
input : "onStart" "onStop"
output : "onStopped"
から成るボックスです。
スクリプト
Choreographe内のボックスは基本的に全て以下の構成を元に作成されています。
スクリプトは以下のようになっています。
# GeneratedClassの派生クラスがMyClassとなっていることがわかります。
class MyClass(GeneratedClass):
#まずbehaviorが読み込まれた際に初めて呼び出されるのが__init__(self)です。
def __init__(self):
#GeneratedClassの__init__(self)をオーバーライドしていることがわかります。
GeneratedClass.__init__(self)
#ここにはbehaviorが読み込まれた際に呼び出されるものを入れましょう。
def onLoad(self):
#put initialization code here
#ここでは初期化処理を入れましょう。
#behaviorが読み込まれ、すべてのinitが呼び出されたあとに呼ばれます。
pass
def onUnload(self):
#put clean-up code here
#アプリケーション終了時、onInput_onStopに入力があったときに呼ばれます。
pass
def onInput_onStart(self):
#self.onStopped() #activate the output of the box
#onStartに入力があった時に呼ばれます。
#self.onStopped()を記述しないと出力がなされません、注意しましょう。
pass
def onInput_onStop(self):
#onStopに入力があった時に呼ばれます。
self.onUnload() #it is recommended to reuse the clean-up as the box is stopped
self.onStopped() #activate the output of the box
検証
Pythonボックスの呼び出され方を確認します。
それぞれの関数にLoggerを仕込んで実行順序を確認しました。
[INFO] init 0
[INFO] init 1
[INFO] init 2
[INFO] init 3
[INFO] onLoad 0
[INFO] onLoad 1
[INFO] onLoad 2
[INFO] onLoad 3
ここでrootのonStopをダブルクリック
[INFO] onUnload 0
[INFO] onUnload 1
[INFO] onUnload 2
[INFO] onUnload 3
```
initが呼ばれ、onLoadが呼ばれていることがわかります。
そののちに、onUnloadが順番に呼ばれ終了します。
2. 直列で結線してみました。
```
[INFO] init 0
[INFO] init 1
[INFO] init 2
[INFO] init 3
[INFO] onLoad 0
[INFO] onLoad 1
[INFO] onLoad 2
[INFO] onLoad 3
[INFO] onInput_onStart 0
```
上でも書きましたが"onInput_onStart"メソッドにself.onStopped()を追記しないとアウトプットがなされません。
なので、次はself.onStopped()を入れたもので検証します。
3. 2にself.onStopped()を入れたもの。
"onInput_onStart"メソッドにself.onStopped()を追記しました。
```
[INFO] init 0
[INFO] init 1
[INFO] init 2
[INFO] init 3
[INFO] onLoad 0
[INFO] onLoad 1
[INFO] onLoad 2
[INFO] onLoad 3
[INFO] onInput_onStart 0
[INFO] onInput_onStart 1
[INFO] onInput_onStart 2
[INFO] onInput_onStart 3
[INFO] onUnload 0
[INFO] onUnload 1
[INFO] onUnload 2
[INFO] onUnload 3
```
正しく最後まで出力されました。
4. スクリプトはそのままで、☓に結線しました。
```
[INFO] init 0
[INFO] init 1
[INFO] init 2
[INFO] init 3
[INFO] onLoad 0
[INFO] onLoad 1
[INFO] onLoad 2
[INFO] onLoad 3
[INFO] onInput_onStop 0
[INFO] onUnload 0
[INFO] onInput_onStop 1
[INFO] onUnload 1
[INFO] onInput_onStop 2
[INFO] onUnload 2
注目
[INFO] onUnload 3
[INFO] onInput_onStop 3
[INFO] onUnload 0
[INFO] onUnload 1
[INFO] onUnload 2
[INFO] onUnload 3
```
注目と記述したところですが、onInput_onStopとonUnloadの順番が逆転して呼び出されていることがわかります。
何度か繰り返してみましたが、書きだされる順序が逆転するのか、呼び出される順序が逆転するのかわかりませんが、0~2の時のように正しい順序で動くときもあれば、3の時のように逆転する場合もあります。
**原因は不明です。**Choreographeのバグかもしれませんね。
またonUnloadが二回呼び出されていることにも注目です。☓にinputした時とbehaviorが終了するときの2度呼び出されます。
感想
続きの記事として、自作関数の活用方と外部ライブラリを利用する方法を書いていきたいと思います。