LoginSignup
7

More than 5 years have passed since last update.

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

Posted at

ぬいぐるみと対話したい

前回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日

今後の課題

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7