Pepper の自律モード（オートノマスライフ）のカスタマイズ（１）ーカスタムサービスを常駐させる

ここでは自律モード（オートノマスライフ）をカスタマイズする方法を紹介します。
ここでは、Pepper 頭の後ろ側を触ることでオートノマスライフの会話モードに自動移行、またこの状態の時、再度頭を触ることでこの会話モードから抜けるという機能をオートノマスライフに追加してみます。

> 『注意』 
公式にはカスタマイズ方法についてガイドがあるわけではないので、NAOqi の機能を使って「うまくいった方法」を紹介しています。試した環境は NAOqi 2.4.2 です。自律モードの機能は日々進化しており、将来的にここで紹介した方法がうまく動かないことも考えられます。ご自身で行う場合は、内容をよく理解したうえで、自己責任でお願いします。

**2016/1/6 サンプルの会話モードへの移行方法をサービスから直接移行させる方法から、アプリを経由させる方法に改めました**

**2016/4/17 カスタムサービスの作り方に関しては次も参考にしてください。 autoload.ini を編集する以外の、サービスの常駐のさせかたが紹介されています [Choregraphe プロジェクトの中にカスタムサービスを組み込む](http://qiita.com/tkawata1025/items/541f72074c80523c0848)**

#前提（対象）

この記事は、Pepper を所有されている方で、オートノマスライフなどの基本的な Pepper の動作仕様を理解されている方を対象としています。

#オートノマスライフのカスタマイズ、３つの手法

起動時に自動的に立ち上がり、会話などをこなしてくれるオートノマスライフ、自分用にカスタマイズしたいと思われたことはないでしょうか？　思いつくところでは次の３つの方法でカスタマイズすることができます。

- カスタムサービスを常駐させる
- コラボラティブダイアログをインストールする
- 自分のアプリをデフォルトアプリとして登録する

今回、これらの手法の中で一つ目「カスタムサービスを常駐させる」について、実例を使って紹介します。３つある手法の中で最も複雑な手法ですが、NAOqi の基本的な機能を利用した手法であり、プラットフォームとしての Pepper の機能を理解する上で知っておいて損はなしです。

#サービスとは

Pepper 上で動くロボット OS NAOqi は分散オブジェクトの思想に基づいて構築されています。
NAOqi が提供する各機能は、「サービス」という形で常駐しており、各アプリは、この「サービス」内の「メソッド」にリクエストを送ることで各機能にアクセスしています。「サービス」は Pepper ロボアプリ開発を始めるとやがて耳にする「ALMemory」がその代表的なものの一つ、これ以外に例えば Pepper を喋らせるためのサービス「ALTextToSpeech」などがあります。
この「サービス」、自分で作り、常駐させることも可能です。自分で作り、常駐させた「サービス」も他の「サービス」と同様、いろいろなアプリに機能を提供することができます。通常のアプリとの違いは常駐して常に動いているかどうか。Choregraphe で作るロボアプリは自信が起動する時、他のアプリが停止しますが、「サービス」はいろいろなアプリが動いている、その間、常時裏で動いています。

#サービスの作り方

次のドキュメントを参考にしています。
[Python - How to write a qimessaging service](https://cloud.aldebaran-robotics.com/naoqidoc/2-4/dev/libqi/guide/py-service.html#guide-py-service)

#サービスの例

サンプルコードです。

```py:MyCustomPepperService.py
# -*- coding: utf-8 -*-

import qi
import sys

class MyCustomPepperService:
  def __init__(self, session):

    self.session = session

    self.logger = self.session.service("ALLogger")

    self.logger.info("MyCustomPepperService","Starting MyCustomPepperService...")
    self.memory = self.session.service("ALMemory")
    self.rearhead_subscriber = self.memory.subscriber("RearTactilTouched")
    self.rearhead_subscriber.signal.connect(self._rearHeadCallback)

  def _rearHeadCallback(self,value):
    if int(value) > 0:
      self.logger.info("MyCustomPepperService", "RearHead touched")
      if self.memory.getData("AutonomousLife/State") == "solitary":
        self.logger.info("MyCustomPepperService", "starting autonomous Dialog...")
        al = self.session.service("ALAutonomousLife")
        al.switchFocus("mycustompepper_1/behavior_1")

if __name__ == "__main__":
    app = qi.Application(sys.argv)

    app.start()
    app.session.registerService("MyCustomPepperService", MyCustomPepperService(app.session))

    app.run()   # will exit when the connection is over

```

このサービスは、頭の後ろの接触センサーを監視しています。オートノマスライフがソリタリー状態のとき、頭の接触センサーが触れられると mycustompepper_1/behavior_1 というビヘービアを起動します。 mycustompepper_1/behavior_1 は会話モードを開始するアプリです。このアプリの作り方は「サービスから起動されるアプリを作る」のセクションで説明します。

#サービスの起動について

サービスは PC上で動かすことも、Pepper 本体上で動かすことも可能です。分散オブジェクトの思想ゆえの非常にユニークな特徴です。PC上でサービスを動かすためには NAOqi Python SDK をインストールしておく必要があります。　ここでは Pepper 本体で動かす方法を見ていきます。

#サービスを Pepper 本体に送る

- 「サービスの例」のセクションに載せた、サンプルプログラム MyCustomPepperService.py をテキストファイルとして PC上で作成、保存。
- FTP などのツールを使って Pepper 本体に転送。ここでは Choregraphe を使ったファイルの転送方法を説明します。
    1. Choregraphe を Pepper 本体に接続
    2. メニュー [接続] -> [アドバンスト] -> [ファイルの転送...] を選択 
    <img width="971" alt="img1.png" src="https://qiita-image-store.s3.amazonaws.com/0/81650/943cbc68-03e0-d01a-309c-eb4c7c04bd3e.png">
    3. ファイル転送のためのダイアログウィンドウが開かれます。[アップロード]ボタンを押すと、ファイル選択ダイアログウィンドウが開かれるので、作成したファイル選択し、Pepper 本体に送ります。ファイルは保存場所を移動しなければ /home/nao 配下に保存されることになります。
    <img width="600" alt="img2.png" src="https://qiita-image-store.s3.amazonaws.com/0/81650/f6788b58-a6fe-60bd-b697-0fb5d1441c32.png">

> 次のセクションで、サービスを自動起動するための設定をしますが、とりあえずちゃんと動くか確認したい場合は ssh で Pepper 本体にアクセス。次に 
`python MyCustomPepperService.py`
とコマンドを実行することで、サービスを起動させることができます。起動したサービスの停止は [Ctrl] + c です。

#サービスが自動起動するように設定する

自作サービスを Pepper 起動時に自動起動させるための設定ファイルが Pepper本体の中 /home/nao/naoqi/preferences/autoload.ini にあります。このファイルを変更することで今回作成したサービスが次回 Pepper 起動時に自動起動されるようにします。

- ファイルのバックアップ（設定ファイルをリカバリーできるようにするために、オリジナルをバックアップしておきます。
    1. Choregraphe を Pepper 本体に接続
    2. メニュー [接続] -> [アドバンスト] -> [ファイルの転送...] を選択 
    <img width="971" alt="img1.png" src="https://qiita-image-store.s3.amazonaws.com/0/81650/943cbc68-03e0-d01a-309c-eb4c7c04bd3e.png">
    3. ファイル一覧から、[naoqi] -> [preferences] を開き、autoload.ini を選択、[ダウンロード]ボタンを押して、autoload.ini ファイルを PCに転送します。
    <img width="600" alt="img3.png" src="https://qiita-image-store.s3.amazonaws.com/0/81650/cb5aafb0-a243-c36f-1cd5-21bb38c55ae2.png">
 
- 上記で取得したファイルをバックアップした上、次のように変更
（Python セクションの /home/nao/MyCustomPepperService.py の行が追加した部分になります。）

```text:autoload.ini
# autoload.ini
#
# Use this file to list the cross-compiled modules that you wish to load.
# You must specify the full path to the module, python module or program.

[user]
#the/full/path/to/your/liblibraryname.so  # load liblibraryname.so

[python]
#the/full/path/to/your/python_module.py   # load python_module.py
/home/nao/MyCustomPepperService.py

[program]
#the/full/path/to/your/program            # load program
```   
- 変更したファイルを本体にアップロード
    1. Choregraphe を Pepper 本体に接続
    2. メニュー [接続] -> [アドバンスト] -> [ファイルの転送...] を選択 
    <img width="971" alt="img1.png" src="https://qiita-image-store.s3.amazonaws.com/0/81650/943cbc68-03e0-d01a-309c-eb4c7c04bd3e.png">
    3. ファイル一覧から、[naoqi] -> [preferences] を開き、[アップロード]ボタンを押して、変更した autoload.ini ファイルを Pepper本体に転送します。
    <img width="600" alt="img4.png" src="https://qiita-image-store.s3.amazonaws.com/0/81650/84878c49-2d2c-71eb-27dc-650b46996ab3.png">

#サービスから起動されるアプリを作る

サービスは常時 Pepper 上で動いていますが、このサービスの中に音声認識処理などユーザーと直接やり取りするような処理を書くのはあまり良くないようです。サービスがそれら処理をしている間に、アプリが起動され、ユーザーとやり取りをする処理が開始された場合、競合し、システムの状態が不安定になる可能性があります。今回の例では、オートノマスライフの会話モードを起動したいわけですが、これを直接サービスから起動するのではなく、アプリに制御を移し、そこから会話モードに入るようにします。以下、会話モードに入るアプリの作成手順を示します。

次の図の通りアプリを作ります。

   <img width="1174" alt="img1.png" src="https://qiita-image-store.s3.amazonaws.com/0/81650/e039e86c-cae1-c7c0-2e30-88064e8ca720.png">

Python Script ボックスのコードは次の通りです。

```py
class MyClass(GeneratedClass):
    def __init__(self):
        GeneratedClass.__init__(self)

    def onLoad(self):
        self.dialog = ALProxy("ALDialog")

    def onUnload(self):
        self.dialog.stopDialog()

    def onInput_onStart(self):
        self.dialog.runDialog()

    def onInput_onStop(self):
        self.onUnload() 
        self.onStopped() 
```

次に、プロジェクトのプロパティーを開き、ロボアプリ名「MyCustomPepperApp」、アプリケーションID「mycustompepper_1」を設定、また対応言語を Japanese に設定します。特にアプリケーションID は間違えないようにしてください。この名前でサービスからこのアプリを呼び出しています。

<img width="1170" alt="img2.png" src="https://qiita-image-store.s3.amazonaws.com/0/81650/2eec18f6-fc33-27f8-ccc9-40c9639e7005.png">
 
次に behavior_1 を選択して、「ユーザのリクエストより開始」のチェックを外します。これが付いていると、タブレットにアプリ名が表示されますが、このアプリはタブレットから起動される必要はないからです。

<img width="1171" alt="img3.png" src="https://qiita-image-store.s3.amazonaws.com/0/81650/23d0c809-b348-8a73-dd8d-7a7e0959a668.png">

最後に「ロボアプリ一覧ビュー」のインストールボタンを押して作成したアプリを保存します。

<img width="402" alt="img4.png" src="https://qiita-image-store.s3.amazonaws.com/0/81650/a174d36d-a0cf-d93b-2648-50f778fb61ff.png">


#本体を再起動する

本体を再起動すると、自動的にサービスがロードされます。
正しく起動されていれば、頭を触った時、バックバンパーを押した時に、カテゴリー MyCustomPepperService からのログが記録されるとともに、ソリタリー状態であれば会話モードの開始、停止をコントロールできるはずです。

#最後に

手順は以上です。
どうでしょう？　うまくいきましたか？
サービスの作り方について詳しくはまた別の機会に解説できればと思います！

また、「コラボラティブダイアログ」、「デフォルトアプリ」によるオートノマスライフのカスタマイズの方法も今後紹介の予定です！