Pepper技術ブログ:はじめてのPepperアプリ開発(その4)
こんにちは!
日本システムデザイン Pepper担当のスエヨシです。
はじめてのPepperアプリ開発シリーズ、今回は4回目です。
前回の記事で、Pepperくんと一往復の会話ができるようになりました。ただ、前回実装した仕様のままだと、実は1つ大きな問題があります。
実際に前回の内容を実装して動かしてみた方なら、もしかするとお気付きの方もいらっしゃるかもしれませんが、SpeechReco ボックスで音声認識待ちになると、Pepperくんは人が話しかけるまで(厳密には何らかの音声を認識するまで)ずっと待ち続けてしまうのです。
今回のように試験的にアプリ開発の手順を追っている時点では、この現象が直接問題になる訳ではないのですが、実際に正式なアプリとしてリリースされてお客様がこれを利用する場面を想定する場合、もしお客様がこのアプリの仕様を知らないとすると、「アプリの終わらせ方が分からない」という状況になってしまいます。
そのような状況を回避する方法としては、
・音声認識待ち開始から一定の待ち時間が経過した際に自動終了させる
・タブレットに終了ボタンを配置し、ボタン押下で終了させる
・利用者の立ち去りを検知して自動終了させる
等が対策として考えられます。
今回は、上記対策の中で一番簡単な「タイムアウト処理」を採用することにします。
◆タイムアウト処理を仕込む
タイムアウト処理には、Wait ボックスを使用します。
Wait ボックス
Wait ボックスは、それ自体が直接 Pepper に何らかの動作をさせるわけではないですが、「onStart が呼ばれると処理を一旦停止し、パラメータで指定した時間(秒数)が経過した後に onStopped(timerOutput) へと出力を行う」という処理が定義されています。
タイムアウト処理は、この Wait ボックスを使用して、以下のように組み立てていきます。
前回の状態から一気に複雑になったように見えますが、追加対応の内容としては、
(1) Wait ボックスを追加し、待ち時間を20秒に設定する。
(2) 最初の Say ボックスの onStopped から、SpeechReco ボックスへの接続と並行して Wait ボックスへ接続
(3) Wait ボックスの onStopped(timerOutput) から SpeechReco の onStop 入力(上から2番目の入力)へと接続
(4) タイムアウト時の発話処理として Say ボックスを追加し、トーク内容を設定
(5) SpeechReco の onStopped 出力から、タイムアウト発話用 Say ボックスの onStart 入力へ接続
(6) タイムアウト発話用 Say ボックスの onStopped 出力から root の onStopped 出力へ接続
以上の6ステップとなります。
上記の追加対応では、以下の2点に気をつけましょう。
1点目として、手順(2)のように一箇所の出力から2つのボックスに並行して接続することで、処理を並行動作させることができる、という点。今回の例では出だしの発話の実行後、SpeechReco による認識待ちの開始と同時に Wait による待ち時間の計測が開始されます。
今回のようなタイムアウト処理の他にも、Pepper のメインの挙動や対話と並行してタブレットに表示した画面からの操作を受け付けたい場合や、センサーの情報を契機として別の処理を受け付けたい場合等に使用します。ただし、Pepper の仕様上、「2つの Say ボックスを同時に実行」「2つのモーションを同時に実行」等、並行して動作できないものもあります。
2点目として、手順(3)と手順(5)での Wait → SpeechReco → Say の繋ぎ方について。各ボックスに共通で定義されている onStop 入力ですが、これは実行された場合に当該ボックスで実行中の処理を終了させて onStopped を出力させるようになっています。この為、今回の例では Wait 終了後に一旦 SpeechReco の実行を onStop 入力で停止させ、そのまま SpeechReco の onStopped 出力(*1)を経由してタイムアウト用の Say ボックスを実行する、という繋ぎ方をしています。
実のところ、今回の例で使用している SpeechReco については onStop で停止させないまま別ルートの処理を進めても一応問題なく動作するのですが、ボックスによっては割り込みをかける際に onStop で処理を止めてやらないと後続の処理(特に発話等)が正常に動作しない場合があります(*2)。なので、実行中の処理に割り込みをかけて別の処理ルートへ入る、といった場合には、何らかの方法で実行中の処理ボックスへ onStop を入力して停止させるやり方が安全なようです。
(*1) SpeechReco ボックスの onStopped 出力は、onStop 入力から停止処理を実行した場合にのみ使用されるようです。通常動作の範囲内(設定した言葉が認識できた/できなかった)であれば、必ず wordRecognized か onNothing のどちらかが出力されるようです。
(*2) 一例として、Dialog を使用した会話処理に対して割り込みをかける場合等、onStop 入力で停止してからでないと、後続の Say ボックスが正しく発話されない現象が起こります。Dialog についてはいずれ別の記事にて説明する予定です。
いかがでしたでしょうか。
動作確認は省略しますが、以上の追加対応で、今回の目標であるタイムアウト処理の実装が実現できました。
次回、はじめてのPepperアプリ開発シリーズの最終回として、今回までで作成したアプリのパッケージを作成し、正式に Pepper へインストールしてみたいと思います。
弊社ではPepperのアプリケーション開発を行っています。
詳しくはこちらをご参照ください。