RaspberryPizeroぬいぐるみとおしゃべりする方法(docomoAPI利用)

  • 6
    いいね
  • 0
    コメント

ぬいぐるみと対話したい

前回RaspberryPizeroぬいぐるみの作り方の続きで

作りたいもの

  • ぬいぐるみと会話したい
  • 対話内容を作成するのは大変

音声認識から音声合成,サーボモータ制御まで行うとRaspberryPizeroではスペックが足りないと思われる

音声認識と会話内容作成はAndroidスマートフォンに任せよう

docomoAPI(雑談API)

  • docomoが開発者に提供しているアセットをAPI

  • 今回は雑談対話の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+サーボモーターで、会話っぽいものができた。

寝る。 pic.twitter.com/n6WtwxVCTP

— アキヒロ (@akihiro01051) 2016年9月20日

.@akihiro01051
たぶん音声は出てるはず。 pic.twitter.com/DK5psVUH94

— アキヒロ (@akihiro01051) 2016年9月29日

今後の課題

  • アプリの画面がサンプルのままでいまいち
  • 周りがわさわさしてると音声認識がうまくいかない(しゃべり終わりを認識できない)
  • ぬいぐるみ単体とお話したい