ぬいぐるみと対話したい
前回RaspberryPizeroぬいぐるみの作り方の続きで
作りたいもの
- ぬいぐるみと会話したい
- 対話内容を作成するのは大変
音声認識から音声合成,サーボモータ制御まで行うとRaspberryPizeroではスペックが足りないと思われる
↓
音声認識と会話内容作成はAndroidスマートフォンに任せよう
docomoAPI(雑談API)
-
docomoが開発者に提供しているアセットをAPI
- 様々なAPIが利用可能
- 利用には登録が必要
- https://dev.smt.docomo.ne.jp/
-
今回は雑談対話のAPIを利用
- サンプルコードにAndroid用のアプリも含まれているのでそれを参考にする
作成方法
前回RaspberryPizeroぬいぐるみの作り方で作成したBluetoothChatアプリに音声認識とdocomo雑談APIの機能を追加
-
音声認識部分
- AndroidSDKにある音声認識SpeechRecognizerを利用
Recognizer.javapublic class Recognizer { private docomolibs docomo; private Context context; private SpeechRecognizer sr; private String RecognizerText=""; private boolean RecognizerFlag=false; public void initListening(Context c) { docomo =new docomolibs(); docomo.startDocomo(); context=c; } public void startListening() { if (sr == null) { sr = SpeechRecognizer.createSpeechRecognizer(context); sr.setRecognitionListener(new listener()); } RecognizerFlag=false; Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH); sr.startListening(intent); } protected void stopListening() { if (sr != null) sr.destroy(); sr = null; } public void restartListeningService() { stopListening(); startListening(); } public boolean getRecognizerFlag() { return RecognizerFlag; } public String getRecognizerText() { return RecognizerText; } public void setRecognizerFlag() { RecognizerFlag=false; } class listener implements RecognitionListener { @Override public void onReadyForSpeech(Bundle bundle) { } @Override public void onBeginningOfSpeech() { } @Override public void onRmsChanged(float v) { } @Override public void onBufferReceived(byte[] bytes) { } @Override public void onEndOfSpeech() { } @Override public void onError(int i) { restartListeningService(); } @Override public void onResults(Bundle bundle) { ArrayList results_array = bundle.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION); String resultsString = results_array.get(0).toString() ; docomo.sendDocomo(resultsString); while (true) { if (docomo.getTextFlag()==true) { RecognizerText = docomo.getText(); Random r = new Random(); int i=r.nextInt(3); if(i==0)RecognizerText= RecognizerText + ",0"; else if(i==1)RecognizerText = RecognizerText + ",1"; else RecognizerText = RecognizerText + ",2"; RecognizerFlag=true; break; } } } @Override public void onPartialResults(Bundle bundle) { } @Override public void onEvent(int i, Bundle bundle) { } } }
-
docomo雑談API部分
- docomoAPIのライブラリをインポート
- 雑談の通信部分を作成
docomolibs.javapublic class docomolibs { private DialogueRequestParam param; private String Context=""; private String Text=""; private boolean TextFlag=false; public void startDocomo(){ AuthApiKey.initializeAuth( "発行されたAPIKey"); param = new DialogueRequestParam(); param.setContext(Context); param.setNickname("デモ"); param.setNickname_y("デモ"); param.setSex("男"); param.setBloodtype("A"); param.setBirthdateY(2016); param.setBirthdateM(10); param.setBirthdateD(9); param.setAge(25); param.setConstellations("山羊座"); param.setPlace("東京"); param.setMode("dialog"); } public void sendDocomo(String text){ Text=""; TextFlag=false; param.setUtt(text); param.setContext(Context); AsyncTask<DialogueRequestParam, Void, Void> task = new AsyncTask<DialogueRequestParam, Void, Void>() { @Override protected Void doInBackground(DialogueRequestParam... dialogueRequestParams) { DialogueResultData resultData = null; DialogueRequestParam req_param = dialogueRequestParams[0]; //要求処理クラスを作成 Dialogue dialogue = new Dialogue(); //要求処理クラスにリクエストデータを渡し、レスポンスデータを取得する try { resultData = dialogue.request(req_param); } catch (SdkException e) { e.printStackTrace(); } catch (ServerException e) { e.printStackTrace(); } Text=resultData.getUtt(); Context=resultData.getContext(); TextFlag=true; return null; } }; task.execute(param); } public String getText(){ return Text; } public boolean getTextFlag() { return TextFlag; } }
- BluetoothChatで結果を送信
- タイマー機能で雑談結果をBluetoothで送信するため以下を追加
BluetoothChatFragment.java
public class MainTimerTask extends TimerTask {
@Override
public void run() {
mHandler.post( new Runnable() {
public void run() {
if(recognizer.getRecognizerFlag()==true) {
sendMessage(recognizer.getRecognizerText());
recognizer.setRecognizerFlag();
recognizer.restartListeningService();
}
}
});
}
}
実行
- Bluetoothでぬいぐるみと接続後音声認識が開始される
- 音声認識後,雑談APIと通信を行い対話内容を取得する
- テキストボックスに文字を入力しなくても,雑談APIからの返答が入力されてぬいぐるみがしゃべってくれる
スマホから音声認識→docomo雑談API→bluetooth→RaspberryPizero→OpenJTalk+サーボモーターで、会話っぽいものができた。
— アキヒロ (@akihiro01051) 2016年9月20日
寝る。 pic.twitter.com/n6WtwxVCTP
.@akihiro01051
— アキヒロ (@akihiro01051) 2016年9月29日
たぶん音声は出てるはず。 pic.twitter.com/DK5psVUH94
今後の課題
- アプリの画面がサンプルのままでいまいち
- 周りがわさわさしてると音声認識がうまくいかない(しゃべり終わりを認識できない)
- ぬいぐるみ単体とお話したい