ぬいぐるみと対話したい
前回RaspberryPizeroぬいぐるみの作り方の続きで
作りたいもの
- ぬいぐるみと会話したい
- 対話内容を作成するのは大変
音声認識から音声合成,サーボモータ制御まで行うとRaspberryPizeroではスペックが足りないと思われる
↓
音声認識と会話内容作成はAndroidスマートフォンに任せよう
docomoAPI(雑談API)
-
docomoが開発者に提供しているアセットをAPI
- 様々なAPIが利用可能
- 利用には登録が必要
- https://dev.smt.docomo.ne.jp/
-
今回は雑談対話のAPIを利用
- サンプルコードにAndroid用のアプリも含まれているのでそれを参考にする
作成方法
前回RaspberryPizeroぬいぐるみの作り方で作成したBluetoothChatアプリに音声認識とdocomo雑談APIの機能を追加
-
音声認識部分
- AndroidSDKにある音声認識__SpeechRecognizer__を利用
Recognizer.java
public 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.java
public 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
今後の課題
- アプリの画面がサンプルのままでいまいち
- 周りがわさわさしてると音声認識がうまくいかない(しゃべり終わりを認識できない)
- ぬいぐるみ単体とお話したい