本体の音声認識機能について

PaPeRo i 本体の音声認識機能は、

  • 単語のみ
  • 認識に一呼吸間が空く
  • 認識語は数十語が限度?

ということでクラウド利用に比べると非力で、人と「会話」するアプリにはちょっと難しいかも知れませんが、「音声による指示」を行うアプリならば工夫次第で使えると思います。

Pythonから使用する手順

音声認識を開始するには基本的には以下の順でAPIを呼びます(標準辞書の場合)。

(1) send_read_dictionary(‘/opt/papero/lib/Standard.mrg’)
(2) send_add_speech_recognition_rule(‘Standard’)
(3) send_start_speech_recognition()

これらはレスポンスを待たずに立て続けに呼んでしまって大丈夫なようです。
これにより、detectPhraseイベントが発生するようになります。
detectPhraseイベントではキー=”Expression”に認識した言葉が入ってきます。
正しく認識出来なかった場合は”Expression”に”Reject”が入ってきます。
また、音声認識を有効にしたまま発話させるとそれを認識してしまうため、発話させたい場合には発話前に

send_stop_speech_recognition()

を呼び、発話終了後に

send_start_speech_recognition()

を呼んで再開させる必要があります。

複数の音声認識辞書を切り替える

あらかじめ複数の音声認識辞書用意しておき、それを場面場面で切り替えれば、アプリの幅をぐっと広げることが出来そうです。
APIの呼び順を間違えると二度と音声認識できない状態に陥ったりするのですが、試したところ以下の手順であれば、状態が、初めて、音声認識が有効、一度有効にした後無効にした場合、いずれの場合でも辞書を切り替えて正常に音声認識を開始できました。

(1) send_stop_speech_recognition()
(2) send_free_dictionary(”)
(3) send_read_dictionary(音声認識辞書ファイルパス)
(4) send_add_speech_recognition_rule(‘Standard’)
(5) send_start_speech_recognition()

サンプルプログラム

音声を認識すると認識した言葉を画面に表示し、向かって左ボタンで標準辞書、右ボタンでカスタム辞書(標準では搭載されていません)に切り替えるサンプルプログラムです。
ここでは発話はさせていませんが、上記の通り、発話もさせたい場合には発話状態を管理して音声認識停止・再開の制御を入れる必要がありますのでご注意ください。

import sys
from logging import (getLogger, Formatter, debug, info, warn, error, critical,
                     DEBUG, INFO, WARN, ERROR, CRITICAL, basicConfig)

import pypapero

logger = getLogger(__name__)


RECOG_DIC_STD = '/opt/papero/lib/Standard.mrg'
RECOG_DIC_ADD1 = '/opt/papero/lib/Standard_stdadd20180418.mrg'

def speech_recog_init(papero, dn=RECOG_DIC_STD):
    logger.info('dictionary={}'.format(dn))
    papero.send_stop_speech_recognition()
    papero.send_free_dictionary('')
    papero.send_read_dictionary(dn)
    papero.send_add_speech_recognition_rule('Standard')
    papero.send_start_speech_recognition()
    papero.send_turn_led_on('ear', ["W2W2", str(int(2000 / 100)), "NN", str(int(2000 / 100))], repeat=True)


def speech_recog_fin(papero):
    logger.info('recog fin')
    papero.send_stop_speech_recognition()
    #papero.send_delete_speech_recognition_rule('Standard')
    papero.send_free_dictionary('')
    papero.send_turn_led_on('ear', ["NN", str(int(1000 / 100))], repeat=False)


if __name__ == "__main__":
    basicConfig(level=INFO, format='%(asctime)s %(levelname)s %(name)s %(funcName)s %(message)s')
    simulator_id, robot_name, ws_server_addr = pypapero.get_params_from_commandline(sys.argv)
    papero = pypapero.Papero(simulator_id, robot_name, ws_server_addr)
    if papero.errOccurred == 0:
        papero.send_start_speech("音声認識デモ")
        speech_recog_init(papero)
        while True:
            messages = papero.papero_robot_message_recv(1.0)
            if messages is  None:
                continue
            if 0 == len(messages):
                continue
            msg0 = messages[0]
            nm = msg0.get("Name")
            if nm == "detectButton":
                status = msg0["Status"]
                if status == "R":
                    speech_recog_init(papero)
                elif status == "L":
                    speech_recog_init(papero, RECOG_DIC_ADD1)
                elif status == "C":
                    break
            elif nm == "detectPhrase":
                if "Expression" in msg0:
                    phrase = msg0["Expression"]
                    if phrase != "Reject":
                        logger.info(phrase)
                    else:
                        pass
    speech_recog_fin(papero)
    papero.papero_cleanup()