はじめに
このページでは、AGB65−ANDROIDとAGB65-RSC2及びRCサーボを使い、スマートフォンから音声認識でRCサーボを動かすプログラムの作り方を説明します。
音声認識というとしきいが高い技術に聞こえますが、ANDROIDのAPIを使えば簡単に実装することができます。
※以下の情報は2012年7月現在のものです。ご注意ください。
AGB65-ANDROIDについてはこちらを参照願います。
以降は、前ページに書いたことは省略していますので、音声認識以外のこまかいことについてはソース又は前ページを参照願います。
スマートフォンとの通信部分は「スマートフォンとの接続」を参照願います。
RCサーボ駆動の部分は「スマートフォンからRCサーボを動かしてみる」を参照願います。
前に作ったAGB65-ANDROID用のアプリと今回のアプリを1つのスマホに混在させるとエラーが起きますので、前に作ったAGB65-ANDROIDのアプリがインストールされている場合は、「設定」−>「アプリ」からアプリを選択し、「アンインストール」しておいてください。
サンプルプログラム
サンプルプログラムはこちらになります。
サンプルプログラムのダウンロード
ダウンロードしたファイルを解凍〜スマートフォンへ書き込み、まではスマートフォンと接続のページを参照願います。
スマートフォンにプログラムを書き込んだら、下記の構成でスマートフォンをUSB接続します。
アクセサリを認識すると、次の画面が出ます。
OKを押すと接続となります。尚、この時、「このUSB...」の横のチェックボックスにチェックを入れると、次回からはこのウィンドウは出ずに自動的にアプリが立ち上がります。
アプリの画面です。灰色のところで Device connedted と出ているのがわかりますでしょうか。接続時にはこのような表示を出しています。画面左上のステータス表示のところにUSBマークが出て、ハード的にUSB接続されていることも表示されます。
チェックボックスにチェックを入れると認識を開始します。「右」と言えば右に、「左」と言えば左にサーボが回転します。
これは「右」の認識画面です。認識結果はテキストで表示します。認識候補は何個か出てきます。
雑音(口笛を吹いたり、ものがドンッと落ちたりとか)の場合は言葉と認識できなくて、「no match」と表示します。
一定時間音が無いとタイムアウトエラーになります。今回のプログラムではエラーが出ても、エラーを表示した後すぐに再度認識を開始します。チェックボックスのチェックを外すまで認識は繰り返されます。
ケーブルを外すとタイトルには Device not connected と表示されます。
動作の様子
動画
最後から二番目の「右」は、「虹」と認識されてしまいましたので反応しませんでした。しかし、普通の室内用途であれば、まず意図したとおりの認識結果が得られますので実用的なシステムを作ることもできると思います。
プロジェクトの構成
プロジェクトはこのような構成になっています。ファイルは6つ。
−ソースファイル−
AGB65_ANDROID_VRActiviti.java : アクティビティのソース
AccessoryManager.java : アクセサリとの通信関連のソース。UsbAccessoryライブラリを使用。
−アクセサリフィルタ−
accessory_filter.xml : 接続するアクセサリの情報を設定します。
−マニフェスト−
AndroidManifest.xml : ライブラリの使用の指定、USBが検知されたときに通知されるインテントの設定、など。
−画面定義ファイル−
main.xml :画面を定義するxmlファイル
−文字列定義ファイル−
strings.xml :ボタンの文字などを定義するファイル
AndroidManifest.xml / accessory_filter.xml
/ AccessoryManager.java の3つはUSB接続に関するファイルです。これらについてはスマートフォンと接続のページを参照願います。
画面の構成
以下、画面構成の main.xml の中身です。
チェックボックスは認識をするかどうかのスイッチの役割をしています。結果はtextview1に表示させます。
string.xmlはチェックボックスの文字列を設定しているだけです。
音声認識
音声認識はSpeechRecognizerというクラスがあります。これを使うと簡単に音声認識ができます。音声認識は(現在のところ)、スマートフォンに入力された音声をGoogleのサーバに送り、認識結果をテキストで返すようになっています。ということで、スマートフォンはインターネットアクセスが必要です。
尚、今後のANDROIDのバージョンでは、サーバにアクセスしなくても、スマートフォン単体で音声認識をする機能も付けられるようです。
マニフェスト
SpeechRecognizerを使うときは、マニフェストでRECORD_AUDIOパーミッションを設定する必要があります。
書籍やネット情報では、このパーミッションの設定は<application>タグの下に書かれている場合もありますが、筆者の環境では上に書かないとエラーが出ましたので<application>タグの上に書いてます。
アクティビティ
アクティビティを説明します。
今回はチェックボックスとテキストビューを配置しますのでそれらをonCreate時に生成しています。また、肝心のSpeechRecognizerも生成しています。
行49でSpeechRecognizerを実体化して、行50でイベントリスナー(割り込みベクターのようなもの)を登録しています。このリスナーは
mRecognitionListener と名前をつけましたが、 mSpeechRecognizerにイベントが発生するとここが実行されます。
途中はサーボの駆動のところで説明しましたので省略します。
チェックボックスのイベント部分ですが、単純にフラグRecEnableを切り替えてるだけです。このフラグで音声認識を継続するかどうかの判定を後の部分でしています。尚、チェックを入れた一回目はここの行158で音声認識を実行しています。 startVr(
)メソッドは、音声認識を始めさせるメソッドです。
startVr( )メソッドの中身です。
行171〜174で音声認識のインテントを設定し、これを引数に行175のstartListening( )メソッドを実行すると音声認識が始まります。認識が終了するとイベントが発生し、行50で登録したmRecognitionListenerが実行されます。
mRecognitionListener、つまりイベント部の構成です。RecognitionListenerクラスを継承しており、これらの9個のメソッドを実装する必要があります。使わないイベントでも書いておく必要があります。それぞれ詳しくはandroidのRecognitionListenerの説明ページに書いてあります(英語ですが)。
今回はエラー時と、正常認識時のイベントだけ使います。行214以降と、行262以降の部分です。
認識中、雑音が入って音声と認識されなかったらERROR_NO_MATCHというエラーが出ます。これはよく発生します。また、しばらく音を入力しないとERROR_SPEECH_TIMEOUTといエラーになります。このれらのエラーが出た場合は、再度startVr()メソッドを実行して、認識が途切れないようにしています。その他、テスト中に出たエラーのところにもstartVr()メソッドで再認識を実行させています。エラーの種類の意味についてはこちらに書いてあります(英語ですが)。
インテントが投げられ、サーバから正常な認識結果が返ってくると、onResultsが実行されます。
得られた結果は、SpeechRecognizer.RESULTS_RECOGNITION の中にStringの配列で格納されています。行267ではこれを取り出しています。
行270〜行283で、得られたString配列の中から、「右」か「左」の認識結果があるかを調べています。
行285〜295で、右なら位置を+30、左なら−30し、サーボを駆動しています。
行297で、サーバから帰ってきた認識結果を全部表示させてます。
行299で、正常終了なのでもう一度認識を再開しています。ということで認識はずっと続けれます。
さいごに
音声認識のプログラムを作ろうとして、「上手くいっても1日、ハマったら数日かかるだろうな」と思ってましたが、やってみると2時間ぐらいでできてしまいました。簡単簡単。ANDROIDのこういった機能はすばらしいですね。
次もAndroidで用意されている機能をなにか使ってみます。
2012年7月9日
|