Pepperに何か情報を保存したり、取り出したりする際にはALMemoryを利用するのが王道なわけですが、ちょっとサイズ大き目のテキストとかをアプリケーションで保存して開発用PCで取り出そうとか考えるとファイルのほうが都合よかったりする場面もあります。
そんな際の処理として、テキストファイルを書き出すボックスを作ってみて、Pepperからローカル環境にそのファイルを取り出すということをお試し的にやってみたのでメモ。
#テキストファイルの書き出しボックス
ボックスは https://github.com/yacchin1205/pepper-web-boxes のweb-boxes
ディレクトリにあります。
cloneするなりDownload ZIPするなりして、ボックスライブラリの読み込みの手順でボックスライブラリを読み込むと使えるようになります。
作ったボックスはボックスライブラリの IO
フォルダにあり、以下のような感じ。ボックスのドキュメント生成ツール的なものはどこかにないものか・・・
##IO > Write Textボックス
ファイルにテキストを書き出します。
###onStart入力
書き出すテキストを入力します。
この入力が発火すると、後述のFile pathパラメータで指示されたファイルに入力された文字列を書き出します。
###onStopped出力
書き出し成功時に出力します。
###onFailure出力
書き出し失敗時に、エラーの内容を示す文字列を出力します。
###File pathパラメータ
読み込むテキストファイルのパスを指定します。ビヘイビア実行中のカレントディレクトリを基準に作成されます。
###Encodingパラメータ
読み込むテキストファイルの文字エンコードを指定します。デフォルトは utf8
です。どのような値を指定できるのかは http://docs.python.jp/2.7/library/codecs.html を参考にしてください。
##ハマった: Pythonボックスでのunicodeの扱い
このWrite Textボックスではないのだけど、一緒に作っていたRead Textボックスの以下のコードでUnicodeの罠にハマった。
with codecs.open(self.getParameter("File path"), "r", self.getParameter("Encoding")) as f:
text = f.read()
self.onStopped(text.encode("utf8"))
onStoppedのタイプには文字列
を指定しているのだけど、read()
で得られたunicode型の文字列をそのまま引数として与えると、次の入力には None
が渡されてしまうよう。
いくつかテストコード書いてみたけど、どうもChoregrapheのドキュメントで String というと、Pythonのstr型しか考慮しておらず、unicode型は処理できていないような感じが。とりあえず encode("utf8")
でバイト配列化して与えることで回避しているけど、このChoregrapheの挙動はPythonの文字列の考え方と合致しておらず、混乱を招きそうという点であまりイケていない感じがする。
日本人的にはこういうのは明確にしておいたほうがいい感じがするので、Aldebaran Communityで聞いてみた(String in Choregraphe's python box)けど、今はunicode型はサポートしてないよという回答・・・ううむ。
##テスト
とりあえず簡単なテストをリポジトリの tests/test-io-text/
で記述している。たとえば、以下のようにRead Textボックスで得られた内容が予期した内容になっているかといったレベルでテスト。たとえばRead Textのテストはこんな感じ。
考え方はPepperボックスライブラリのテスト考あたりを、参考まで。
#ファイルのローカル環境への取り出し
これらのボックスで保存したファイルをどう取り出すかについていくつか。
##Choregrapheを使う
Pepperのファイルシステムに対しては、Choregrapheでファイルをアップロード、ダウンロードすることができる。
上級向けメニューにファイルの転送という機能があるのでそれを使うのが王道。
##HTTPを使ってPepperからファイルダウンロード
自動化とか考えると、Choregrapheがない環境でもファイルを取り出したくなったりする。ドキュメントの NAOqi Developer guide > Programming > Connecting Choregraphe / your robot > Connection Management とか見ると、FTPが動いていることは前提として考えてよさそうなのだけど、あえてHTTPを使ってみようとか思って試してみた。
プロジェクト内にhtmlというディレクトリを作るとタブレットから見えるようになるのだけど、この状態で http://(Pepperの名前.local.もしくはIPアドレス)/apps/.lastUploadedChoregrapheBehavior/
とかするとこのhtmlディレクトリの内容が見える。たぶん、Webサーバとかでホームディレクトリに public_html
ディレクトリを置くのと同じ考え方なんだと思われる。
そんなわけで、html
ディレクトリに、ダウンロード可能にしたいファイルを生成してあげればいいのではないか?と思って作ったのが、リポジトリの samples/dump-info
プロジェクト。ここでは、ALMemoryの内容すべてとPreferencesの内容すべてをダンプしてテキストファイルに保存、外部PCからダウンロードみたいなことを実装している。
ポイントは以下の2点。
- Write Textボックスに与えるFile pathパラメータを独自のGet HTML Fileボックスの出力値で設定している(これも
web-boxes
に置いてある)。Get HTML Fileボックスでは、自身のアプリケーション内のhtmlディレクトリの絶対パスに基づき、出力先ファイルパスを生成している。 - html/index.htmlでは、Get HTML Fileボックスに指定したファイルへのリンクを張っている。
このアプリケーションを実行後、http://PepperのIP/apps/.lastUploadedChoregrapheBehavior/
のようなURLを、Pepperと同じLANにつながっているPCなどで開く。するとプロジェクトのindex.htmlをPCから確認することができる。ここで、ファイルへのリンク(2.)をクリックするとWrite Textボックスで書き出されたファイル(1.)をダウンロードすることができる。
こんな感じで、プロジェクトで何かファイルを作ってPCから引っ張り出したければ、プロジェクトのhtmlディレクトリ内にファイルを作ればいいんでは、という話。しばらくこれで使ってみよう・・・