tigergate830

Dialogflow - Pepperで喋らせてみる

Dialogflow(旧:api.ai)のチャットをPepperで喋らせてみます
Pepperアプリの作成にはChoregrapheというツールを使います
ChoregrapheのPythonブロックでPython(2.7)が書けるので、そこからなんでもAPI呼び出しできる(Dialogflowもそれ以外も)ということになります

Dialogflowの使い方については、
- Dialogflow/api.aiでチャットボットをつくってみる (ume1126さんの投稿)
- Dialogflow/api.aiで天気情報を呼び出す (ume1126さんの投稿)
- Dialogflow/api.aiをSlackに連携させる (ume1126さんの投稿)
などをご参照ください

DialogflowのAPIキーを入手しておく

  • 後述のPepperアプリから呼び出すため、DialogflowのClient API キーを入手しておきます
  • Dialogflowのコンソールを開き、画面左上の使用しているAgentを選択し、Agentの右側にある「設定」(歯車のアイコン)をクリックします

スクリーンショット 2017-12-28 16.01.00.png

  • Agentコンソールの画面下部の「Client access token」の32桁(32文字)の文字列をコピーしておきます(Developer access tokenのほうではないので注意します)

スクリーンショット 2017-12-28 15.59.39.png

Choregrapheをインストールする

スクリーンショット 2017-12-28 15.36.40.png

  • robot libraryなどを参考に、Pepper胸部タブレットからの入力を可能にするボックスを入手します
  • その他さまざまなPepperの動作はPepper Atelierなどから入手可能です

アプリを作ります

  • 「Set Language」「Say」「Table Input」「Speech Reco.」「Pythonブロック」「Say Text」の各ボックスを下記のように配置します

スクリーンショット 2018-01-09 17.22.42.png

  • 1つめの「Set Language」ボックスで日本語を設定します。

スクリーンショット 2017-12-28 15.41.57.png

  • またこのアプリで日本語を使用可能にするため、画面左上の「プロパティ」を開いて日本語も使えるように追加します(このとき、英語を削除してしまうとエラーになるようなので、日本語は英語へ追加するかたちで登録すると良いようです)

スクリーンショット 2017-12-28 15.41.40.png

  • 「Set Language」ボックスの「onReady」出力端子から、次の「Say」ボックスの「onStart」入力端子へ接続します

スクリーンショット 2017-12-28 15.44.01.png

  • 次の「Say」ボックスでは、「こんにちは、ご質問をどうぞ」など最初の挨拶を話すようにします

スクリーンショット 2017-12-28 15.42.53.png

  • 「Table Input」ボックスでは、「Say」ボックスから及び「Say Text」ボックスからの線を「Table Input」ボックスの「onStart」入力端子に接続し、「onInputed」出力端子からの出力を後段のPythonブロックの「Input」入力端子へ接続します。また、入力がループに陥るのを避けるため、「onInputed」出力端子から「onStop」入力端子へ接続しておきます

スクリーンショット 2018-01-09 17.30.14.png

  • 同様に「Speech Reco.」ボックスも接続します。ここでは(主にPepperが耳が遠いため)このSpeech Reco.ボックスは使用していませんが、必要に応じ使用可能です
  • 前項と同様に「Say」「Say Text」ボックスからおよびPythonボックスへ接続し、また入力がループに陥るのを避けるため、「onInputed」出力端子から「onStop」入力端子へ接続しておきます
  • 「Speech Reco.」ボックスの「wordRecognized」出力端子から、次のPythonブロック("test")の「input」入力端子へ接続します

スクリーンショット 2017-12-28 16.08.32.png

  • 画面のなにもないところで二本指でタップ(もしくは[Cntl]を押しながらクリック)して、「ボックスの新規作成」⇢「Python」を選択してPython用のボックスを作成します

スクリーンショット 2017-12-28 15.46.24.png

  • 新規作成されたPythonボックスを二本指でタップ(もしくは[Cntl]を押しながらクリック)して、「ボックスの編集」を選択します

スクリーンショット 2017-12-28 15.48.22.png

  • Pythonボックスに適当な名称(ここでは"to_dialogflow")を指定し、「インプット/アウトプット/パラメータ」欄の「入力」の右側の「+」を押して新しい入力を追加します

スクリーンショット 2017-12-28 15.49.42.png

  • 新しい入力に適当な名称(ここでは"input”)を指定し、「タイプ」を「文字列」を選択して「OK」を押して作成します

スクリーンショット 2017-12-28 15.49.15.png

  • 同様に、新しい出力を作成(ここでは"output")し、「タイプ」を「文字列」を選択して「OK」を押して作成します

スクリーンショット 2017-12-28 15.53.07.png

  • 「OK」を押すとPythonブロックに新しい入力(”input”)と出力(”output")が追加されているのが確認できます

  • Pythonブロックをダブルクリックしてスクリプトエディタを開きます

  • デフォルトで記入されている内容を下記で上書きします。下記のうち、CLIENT_ACCESS_TOKENを前節で入手した自分のDialogflowのAPIトークンで置き換えます

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

    def onLoad(self):
        self.framemanager = ALProxy("ALFrameManager")
        self.folderName = None

    def onUnload(self):
        #put clean-up code here
        pass

    def onInput_input(self, p):
        self.log(p)
        #self.onStopped() #activate the output of the box
        import os.path
        import sys
        import json
        self.folderName = os.path.join(self.framemanager.getBehaviorPath(self.behaviorId), "../lib")
        if self.folderName not in sys.path:
            sys.path.append(self.folderName)
        import apiai
        CLIENT_ACCESS_TOKEN = '0123456789abcdef0123456789abcdef'
        ai = apiai.ApiAI(CLIENT_ACCESS_TOKEN)
        request = ai.text_request()
        request.lang = 'ja'  # optional, default value equal 'en'
        request.session_id = "1"
        request.query = p
        response = request.getresponse()
        r = response.read()     #can be obtained only once
        json_dict = json.loads(r)
        r2 = format(json_dict['result']['fulfillment']['speech'])
        r3 = r2.encode('utf-8')
        self.log(r3)
        self.output(r3)

    def onInput_onStop(self):
        self.onUnload() #it is recommended to reuse the clean-up as the box is stopped
        self.onStopped() #activate the output of the box

スクリーンショット 2017-12-28 16.07.43.png

  • Pythonブロックの「output」出力端子から、最後の「Say Text」ボックスの「onStart」入力端子へ接続します

スクリーンショット 2017-12-28 16.09.00.png

Pepperで稼働させて確認します

  • Pepperを接続し、上記アプリケーションの稼働を確認します
  • Pepperを接続するには同一ネットワーク(同一Wifi)内に接続されていることが必要になります
  • 必要に応じてMotion(動き)などを追加します。PepperのMotionについてはpepper Atelier - モーション作成を効率化するボックスライブラリを公開などが便利です
  • Pepperあんまり安定してないですね。。
  • Good luck :-)