ラズベリーパイで会話したり写真取ったりするロボットを作りたい(実践1)

基本方針

  • 前回の続き
  • Julius をモジュールモードで起動
    • julius -C _text.jconf -module 10500
  • node.js で接続してデータを待つ
  • child_processをつかって aquestalkpi で話し返す

問題点と解決方法

  • execだとパイプライン処理がうまくできなかったのでspawnを使う
  • Juliusのモジュールモードの送ってくるデータが壊れている
    • データの送り方はよくわからないけど「.」のみの行が着たら一文終わりらしい
    • .\nがくるまでバッファにためて処理するようにする
  • Juliusが何でも辞書内の言葉で解釈してしまう
    • 辞書にごみを混ぜる(あああ,いいい,...,んんん)
    • SCORE,CMの値に適当に閾値を設ける

ソース

index.js

var net=require('net');
var x2j=require('xml2js').parseString;
var spawn = require('child_process').spawn;

var t="";
var proc;

var client=net.createConnection(10500,'localhost',function(){console.log("START.");});

client.on('data',function(data){
  t+=data.toString();
  if(t.indexOf(".\n") != -1){
    var arr=t.split(".\n");
    for(var i=0;i<arr.length-1;i++){
      x2j(arr[i],{trim:true},function(err,result){
        if(result.RECOGOUT){
          var word = result.RECOGOUT.SHYPO[0].WHYPO[0].$.WORD;
          var score= result.RECOGOUT.SHYPO[0].$.SCORE;
          var cm   = result.RECOGOUT.SHYPO[0].WHYPO[0].$.CM;
          console.log(word + " : " + cm + " - " + score);
          if(cm>0.85&&score>-3500){
            if(word=="カメラ")procCmd("はいはいかめらかめら");
            if(word=="送信") procCmd("はいはい送信しましたよ");
            if(word=="ワトソン")procCmd("ワトソンくんおねがいします");
          }
            }
      });
    }
    t=arr[arr.length-1];
  }
});

client.on('end',function(data){console.log("END.");});

function procCmd(word){
  var cmd='~/voice/aquestalkpi/AquesTalkPi "'+word+'" | aplay -D plughw:1';
  proc = spawn("sh",["-c",cmd]);
  proc.stdout.on('data', function(data) {
      console.log('stdout: ' + data);
  });
  proc.stderr.on('data', function(data) {
      console.log('stderr: ' + data);
  });
  proc.on('exit', function(code) {
      console.log('exit code: ' + code);
  });
}

感想

簡単なプログラムだけで特定の単語に返事してくれるものができた。
httprequestモジュールで送受信してもいいし、
spawnからCURLでファイル送信したり、raspistillで写真とるのも簡単。
とりあえず閾値部分をどうにか自動で定めたいなぁ。