blog
ブログ
2016.04.13

Pepper技術ブログ:Dialog機能とQiChatスクリプト

こんにちは!
日本システムデザイン Pepper担当のスエヨシです。
今回は Pepper の対話処理の応用として、 Dialog 機能と QiChat スクリプトについて紹介します。

◆Dialog とは?

前回まで連載していた「はじめてのPepperアプリ開発」シリーズで作成したアプリでは、Say ボックスと SpeechReco ボックス、さらに SwitchCase ボックスを組み合わせる形で Pepper と人との対話を実現していました。しかし、この方法で Pepper と人との間で複数回の対話を往復させようとすると、SpeechReco で認識した言葉に応じて SwitchCase で処理を分岐した後 Say で回答し、更にそれぞれの分岐から SpeechReco → SwitchCase → Say を配置して分岐、更にその先も同様に………というふうに大量のボックスを配置していかなければならない(*1)ことになります。また、よりリアルな対話をさせようとすると、SpeechReco で認識させたい言葉を大量に指定しなければならなくなる、といったことも考えられます。

このように、Say ボックスと SpeechReco ボックスの組み合わせは、簡単な受け答えに使うのであれば便利ですが、複数回の会話の往復や幅広い言葉への受け答え等、より柔軟で自然な対話を行うのには向いていません。
そこで便利なのが、今回紹介する Dialog という機能です。

20160412_chrg_dialog_box
Dialog ボックス

Dialog は、Pepper に対話機能を実装する為の機能の一つです。
ALDialog – Aldebaran documentation(公式ドキュメント ※英語)

Dialog は特殊な機能で、ビヘイビア上のフローとしては他と同様のボックスとして表されますが、その実態はビヘイビアとは別の専用ファイル(*.dlg、*.top)に保存されており、実行内容は後述する QiChat スクリプトと呼ばれる専用のスクリプトにて記述するようになっています。

Dialog を作成するには、まずプロジェクトファイルビューのプラスアイコンから「新規ダイアログトピック…」を選択します(*2)

20160413_chrg_dialog_create_topic
ダイアログトピック作成

Dialog の名前と対応言語(*3)を設定して追加ボタンを押下します。尚、ダイアログトピックの設定値に「コラボラティブとしてパッケージに追加」のチェックボックスがありますが、今は無視してください(*4)。これで Dialog のファイルが作成されます。プロジェクトファイルビューにて Dialog のディレクトリとファイル(*.dlg、*.top)が作成されているのが確認できます。ダイアログファイル(*.dlg)は Dialog 全体の定義となっており、一つの Dialog に対して1ファイルが作成されます。トピックファイル(*.top)は各対応言語ごとのスクリプトファイルとなっており、一つの Dialog に対して設定している対応言語の数だけ作成されます。(今回の例では日本語のみなので1ファイルです)

20160413_chrg_dialog_drop
Dialog ボックスの設置

Dialog 作成後、プロジェクトファイルビューからダイアログファイル(*.dlg)をドラッグ&ドロップすると、Dialog ボックスが設置できます。後は、設置した Dialog ボックスをいつも通りビヘイビア root の onStart、onStopped に接続すれば、アプリへの組み込みは完了です。

(*1) ちなみに、Say ボックスと SpeechReco ボックスの組み合わせだけでn往復の会話(1往復につき2種類以上の受け答え)を実装しようとすると、おおよそ2のn乗個程度のボックスが必要になります。単純計算でも5回往復させるなら32個、10回往復させるなら1024個。大変ですね。(厳密には間に SwitchCase ボックスが挟まる為、もっと数が増えることになりますが。)
(*2) この他にも、エディタのコンテキストメニューからボックスの新規作成にて追加する方法や、ボックスライブラリからドラッグ&ドロップで設置する方法でも作成できます。
(*3) デフォルトでは manifest.xml にて設定されているアプリの対応言語が選択されます。ここで設定した対応言語の数だけトピックファイル(*.top)が作成され、各言語ごとにスクリプトを作成することができます。
(*4) 「コラボラティブとしてパッケージに追加」にチェックを入れると、対象のダイアログがコラボラティブダイアログ(協調的対話ダイアログ)として作成されます。コラボラティブダイアログで定義された内容は、オートノマスライフモード時の会話の中に組み込まれ、アプリを起動しなくても自律動作中の自然な対話として動作するようになります。これに関しては今回は割愛しますが、いずれ別途記事にしたいと思います。

◆QiChat スクリプト

前項で Dialog の作成と Dialog ボックスの設置まで完了しましたので、続いて Dialog の中身を見ていきます。
Dialog ボックスは、定義で紐づけられたトピックファイル(*.top)に QiChat スクリプトと呼ばれる専用の言語で一連の処理を記載することで、このスクリプトの記述に沿った対話処理を実行するボックスとして機能します。

20160413_chrg_dialog_topic_edit
ダイアログのトピックを編集(QiChat スクリプトの記述)

Dialog で実行する QiChat スクリプトを記述するには、プロジェクトファイルビュー内の当該ダイアログのトピックファイル(*.top)をダブルクリックしてください。上記スクリーンショットのように、スクリプトエディタでトピックファイルの内容が表示されます。

QiChat スクリプトの記述形式の基本は、上記スクリーンショット中のスクリプトエディタで記載されているように、

・例1:

u:(○○○○○) ××××××
※ ○○○○○ → 人の言葉、×××××× → Pepperの言葉

と記述することで、人間からの「○○○○○」という問いかけに対して、Pepper が「××××××」と答える、という対話の流れを表現します。スクリーンショットの例では、人間からの「おはよう」という問いかけに対して、Pepper が「いい朝ですね。」と答えます。
つまり、SpeechReco と Say の組み合わせで実装していた「人間からの特定の問いかけに対して Pepper が然るべき発話を行う」という流れと同様の処理が、この1行で記述できることになるわけです。

更に、これを以下のように列挙することで、複数の対話を同時に設定し、各々の問いかけに対して該当する対話を行う、といった動作も実現できます。

・例2:

u:(おはよう) いい朝ですね。
u:(こんにちは) おなかがすきました。
u:(こんばんは) おばんです。

この例では、「おはよう」に対しては「いい朝ですね。」、「こんにちは」に対しては「おなかがすきました。」、「こんばんは」に対しては「おばんです。」の3種類の対話が同時に設定されることになります。

また、今度は以下の例の用に u → u1 → u2 と階層を分けて記述することで、特定の対話の後にだけ継続実行される対話の階層を設定することもできます。

・例3:

u:(おはよう) いい朝ですね。
u:(こんにちは) おなかがすきました。
    u1:(そうだね) 何が食べたいですか?
        u2:(うどん) 香川県の方ですか?
        u2:(そば) あたしゃあんたの蕎麦がいい、なんちゃって。
    u1:(そうでもない) そうですか。
u:(こんばんは) おばんです。

この例の場合、「こんにちは」~からの対話の後にのみ、u1 以降の階層の対話ができるようになります。(「おはよう」~からの対話に対して「そうだね」と話しかけても、u1 以降の対話は実施されません。)

このように、Dialog と QiChat スクリプトを使用することで、複数の分岐や深い階層を含む対話であっても簡単に作成することができます(*5)。使いこなせればかなり柔軟で自然な対話が実現できるのではないでしょうか。

(*5) 余談ですが、例3で示した対話の内容を SpeechReco と Say、SwitchCase の組み合わせだけで実現させようとすると、合計13個のボックスを設置して以下のような複雑なフローを作ることになります。大変ですね。

20160413_chrg_dialog_intermission
Dialog を使わない場合…

◆Dialog を終了する

Dialog ボックスは他のボックスと違って、処理が終わり次第自動的に onStopped 出力を行う、というような動作にはならず、基本的には一度呼び出されればずっと音声認識待ちのまま待機し続けるようになっています。この為、Dialog の処理を停止するには、明示的に停止処理を実装してやる必要があります。

Dialog を停止させる方法としては、大まかには、
・QiChat スクリプトから onStopped 出力を呼び出すことでボックスを停止させる
・Dialog の外部から何らかの手段で Dialog ボックスを停止(或いはアプリ自体を終了)させる
の2通りが有ります。

以前別の記事でやったように Wait ボックスを使ったタイムアウト処理を使用すれば後者の方法でも実現できますが、今回は前者の方法を紹介します。

20160413_chrg_dialog_onstopped
Dialog 処理を停止するには

QiChat スクリプトにて $onStopped=1 と記述することで、QiChat スクリプト内から Dialog ボックスの onStopped 出力を呼び出すことができます。この記述を上記スクリーンショットの例のように特定の問いかけに対する回答として設定しておくことで、特定の問いかけを契機として Dialog の処理を停止することができます。
このように Dialog を使用する場合は、何らかの形で明示的に停止処理を設定してかないと、Dialog が停止せずアプリが終了しない状態になってしまいますので、気をつけましょう。

以上、Dialog と QiChat スクリプトの紹介をさせていただきました。
本記事の中では代表的な記述のみをピックアップして紹介致しましたが、QiChat スクリプトの文法や言語仕様については公式ドキュメントに詳しく記載されておりますので、気になる方はそちらも見てみてはいかがでしょうか。
QiChat – Aldebaran documentation(公式ドキュメント ※英語)

弊社ではPepperのアプリケーション開発を行っています。
詳しくはこちらをご参照ください。

contact

ご相談・ご質問等ございましたら、お気軽にお問い合わせください。

翻訳