Watson TJBotをつくりました【４】マイク・スピーカーを使ってTJBOTと手を振って会話

PDF資料はこちらからどうぞ。
http://seahorse-inc.com/QIITA/TJBot-4/Wavingセットアップ全手順_20170724.pdf

# 1.   はじめに
<font color="blue"><strong>TJBot</strong></font>は声を文字、文字を声にしたり、話しかけられた意図(意味)を理解してお話したり、色々な情報から欲しい情報を探してくれるといった、「IBM WatsonコグニティブAPI」をこれからやってみようという人にはうってつけのキットです。

厚紙や3Dプリンターでホディを作り、小さく低価格のコンピュータ(Raspberry PI)で頭脳を組み込みます。手を振ったり、LEDの色を変えたり、話しかけると答えてくれます。
機能的にはシンプルですが、反応してくれるとワクワクして楽しく、ボディは簡単に組み立てられるようになっています。

TJBotはすでに、色々な「IBM WatsonコグニティブAPI」を組み合わせた「レシピ」があります。

本投稿は、できあがっている「レシピ」を参考に、実際に作ってみた手順となっています。
使用するパーツなどの関係で、そのままの「レシピ」ではうまくいかないところや分からない点がありましたが、試行錯誤の末、ちゃんと動作することができました。
さらに、おまけとして日本語対応しました。
![00.png](http://seahorse-inc.com/QIITA/TJBot-4/00.png)
尚、厚紙でTJBotのボディ作成は割愛させていただきますが、下記URLを参考に作ってみてください。
https://www.youtube.com/watch?v=UEnuF--LA-0
https://www.instructables.com/id/Build-TJ-Bot-Out-of-Cardboard/

厚紙、３Dプリンター用の図面は下記URLです。
https://ibmtjbot.github.io/#gettj

ちなみに私は、A2サイズ２mmの厚紙にpdf印刷出力の図面を貼り、デザインナイフでカットしました。
デザインナイフでカットすると、かなり時間と労力を要しますので、レーザーカットをお勧めします。
レーザーカッターを時間制で使えるサービスもあるようです。

厚紙とRaspberry Pi、マイク、スピーカー、LED、モーターでTJBotを組み立て、Watson Cognitive APIを使って、色々なレシピが生まれています。
本投稿は、各レシピを実際に作成し、日本語化を行ってみた際の手順内容となっています。

# ２.  TJBotについて
TJBotは、IBM ResearchのMaryam Ashooriによって、認知対象の設計と実装におけるベストプラクティスを見つけるための実験として作成されました。
https://www.ibm.com/blogs/research/2016/11/calling-makers-meet-tj-bot/

TJBotは、楽しい方法でWatsonサービスを理解するために生まれた、オープンソースプロジェクトです。
https://ibmtjbot.github.io/


# ３.   今回作成するレシピ
Watson 「Speech to Text」、「Text to Speech」とRaspberry Pi、USBマイク、Bluetoothスピーカー、LED、サーボモータを使って、Watsonと簡単な会話をします。

使用させていただいたレシピのサイト情報：
https://www.instructables.com/id/Build-a-Waving-Robot-Using-Watson-Services/

# ４.  材料
価格は変わる可能性があります。
![01.png](http://seahorse-inc.com/QIITA/TJBot-4/01.png)
厚紙は、ミューズ　ＫＭＫケントボード　ＳＳ－Ａ２２ｍｍ厚を使いました。　


# ５.  H/Wセットアップ
Raspberry Pi用のOS Rasbianのインストールは割愛させていただきます。
http://qiita.com/Mitsu-Murakita/items/90907782b6aec9959328
の「3. Raspbian関連のインストール」などを参考にしてください。

## ５-１.   LED
スイッチサイエンス社 NeoPixel スルーホールLED
![02.png](http://seahorse-inc.com/QIITA/TJBot-4/02.png)
LEDは平らにカットされている方から
　　1.--- 使用しない
　　2.--- GND　	⇒  6番ピン
　　3.--- +3.3V 	⇒  1番ピン
　　4.--- Data in	⇒ 12番ピン
になっているが、
（注意！）RaspberryPiに接続する際は、２⇒４⇒３の順番に接続する
![03.png](http://seahorse-inc.com/QIITA/TJBot-4/03.png)


## ５-２.   サーボモータ
マイクロサーボ SG92R![04.png](http://seahorse-inc.com/QIITA/TJBot-4/04.png)
配線は：茶＝ＧＮＤ、赤＝電源［＋］、橙＝制御信号
　　1.--- GND　	⇒14
　　2.--- +5V 	⇒2
　　3.--- Data in	⇒26
になっている。
（注意！）RaspberryPiに接続する際は、１⇒３⇒２の順番に接続する
![05.png](http://seahorse-inc.com/QIITA/TJBot-4/05.png)


## ５-３.   USBマイク
BU-Bauty PC Mac用USBマイク　超小型　超ミニ 22mmx18mmx5mmを使用しました。
![06.png](http://seahorse-inc.com/QIITA/TJBot-4/06.png)

コマンドで認識されているか確認します。

```Command:
$ lsusb ⏎
```

![07.png](http://seahorse-inc.com/QIITA/TJBot-4/07.png)
“Bus 001 Device 004: ID 0d8c:0016 C-Media Electronics, Inc”で認識されています。
カード番号は１です。

マイクの感度を調整します。(-cに続く番号はcard番号です)
![08.png](http://seahorse-inc.com/QIITA/TJBot-4/08.png)
81％の値がマイク感度です。

録音してみます。

```Command:
$ arecord -D plughw:1,0 -d 10 -f cd test.wav ⏎
```
(plughw:1,0はarecoed –l のカード番号とデバイス番号です。生成する音声ファイルはtest.wav)
PCなどに転送して音を確認してください。

## ５-４.   Bluetoothスピーカー
Anker SoundCore mini コンパクト Bluetoothスピーカーを使用します。

<strong>・パッケージPulseAudioパッケージをインストール</strong>

```Command:
$ sudo apt-get update ⏎
$ sudo apt-get dist-upgrade ⏎
$ sudo apt-get install bluetooth  ⏎
$ sudo apt-get install pulseaudio-module-bluetooth ⏎
```

<strong>・PulseAudioをsystemdに登録</strong>
nanoを使って<font color="blue">「pulseaudio.service」</font>に書込みます。

```Command:
$ sudo nano /etc/systemd/system/pulseaudio.service ⏎
```
![09.png](http://seahorse-inc.com/QIITA/TJBot-4/09.png)

![10.png](http://seahorse-inc.com/QIITA/TJBot-4/10.png)

<strong>・pulseaudio-bluetooth.confファイルを作成します。</strong>
nanoを使って<font color="blue">「pulseaudio-bluetooth.conf」</font>に書込みます。

```Command:
$ sudo nano /etc/dbus-1/system.d/pulseaudio-bluetooth.conf ⏎
```
![11.png](http://seahorse-inc.com/QIITA/TJBot-4/11.png)
![12.png](http://seahorse-inc.com/QIITA/TJBot-4/12.png)

<strong>・system.paファイルを編集</strong>

```Command:
$ sudo nano /etc/pulse/system.pa ⏎
```
![13.png](http://seahorse-inc.com/QIITA/TJBot-4/13.png)
![14.png](http://seahorse-inc.com/QIITA/TJBot-4/14.png)

<strong>・pulseaudioサービスを起動</strong>

```Command:
$ sudo systemctl start pulseaudio.service ⏎
```

<strong>・pulseaudioサービスを自動起動するよう設定</strong>

```Command:
$ sudo systemctl enable pulseaudio.service ⏎
```

<strong>・root、piユーザがPulseAudioで音を出せるようにします</strong>

```Command:
$ sudo gpasswd -a root pulse-access ⏎
$ sudo gpasswd -a pi pulse-access ⏎
```
![15.png](http://seahorse-inc.com/QIITA/TJBot-4/15.png)

ここまででPulseAudo関連の設定が完了しましたので、次にbluetoothctlでBluetoothデバイスを接続します。
スピーカーの電源をオン。

```Command:
$ sudo bluetoothctls ⏎
```

```Command:
[bluetooth]# power on ⏎
```
デバイスをスキャンし、スピーカーを探します。

```Command:
[bluetooth]# scan on ⏎
```
Blutoothスピーカーが見つかったら、スキャンを停止します。

```Command:
[bluetooth]# scan off ⏎
```
![16.png](http://seahorse-inc.com/QIITA/TJBot-4/16.png)

[NEW] Device 00:E0:4C:58:6C:EC SoundCore mini
でBlutoothスピーカーのデバイス情報が入手できました。

```Command:
[bluetooth]# trust 00:E0:4C:58:6C:EC ⏎
[bluetooth]# pair 00:E0:4C:58:6C:EC ⏎
[bluetooth]# connect 00:E0:4C:58:6C:EC ⏎
```
<font color="orange">「ピロリン」</font>という音が鳴ると、接続完了です。

bluetoothctlから抜けます。

```Command:
[bluetooth]# exit ⏎
```

<strong>・なかなか接続できない場合</strong>
https://raspberrypi.stackexchange.com/questions/44497/having-an-issue-with-bluetooth-manager-pairing-on-the-pi

Syslogを確認します。

```Command:
$ cat /var/log/syslog ⏎
```

<font color="red">“bluetoothd[794]: a2dp-sink profile connect failed for 00:E0:4C:58:6C:EC: Protocol not available”</font>というエラーの場合下記手順を試してください。

(1) PulseAudio Bluetooth ライブラリーがインストールされているか確認

```Command:
$ sudo apt-get install pulseaudio-module-bluetooth ⏎
```

(2) Pulse Audio serverが稼働しているか確認
まず停止します。

```Command:
$ sudo killall pulseaudio ⏎
```
起動します。

```Command:
$ pulseaudio --start ⏎
```

(3)bluetoothctlでconnectします。

```Command:
[bluetooth]# connect 00:E0:4C:58:6C:EC ⏎
```


# ６. Watson「Speech to Text」、「Text to Speech」サービスの作成
Bluemixにログイン
https://console.bluemix.net/
![17.png](http://seahorse-inc.com/QIITA/TJBot-4/17.png)
![18.png](http://seahorse-inc.com/QIITA/TJBot-4/18.png)
![19.png](http://seahorse-inc.com/QIITA/TJBot-4/19.png)


（１）カタログより<font color="blue">「Speech to Text」</font>を選択
![20.png](http://seahorse-inc.com/QIITA/TJBot-4/20.png)

<font color="blue">「作成」</font>をクリック
![21.png](http://seahorse-inc.com/QIITA/TJBot-4/21.png)

<font color="blue">「サービス資格情報」</font>をクリック
![22.png](http://seahorse-inc.com/QIITA/TJBot-4/22.png)

<font color="blue">「資格情報の表示」</font>をクリック
![23.png](http://seahorse-inc.com/QIITA/TJBot-4/23.png)

<font color="red">「username」「password」を後程使用しますので、メモ帳などにコピー保存してください。</font>
![24.png](http://seahorse-inc.com/QIITA/TJBot-4/24.png)
![25.png](http://seahorse-inc.com/QIITA/TJBot-4/25.png)


（２）カタログより<font color="blue">「Text to Speech」</font>を選択
![26.png](http://seahorse-inc.com/QIITA/TJBot-4/26.png)

<font color="blue">「作成」</font>をクリック
![27.png](http://seahorse-inc.com/QIITA/TJBot-4/27.png)

<font color="blue">「サービス資格情報」</font>をクリック
![28.png](http://seahorse-inc.com/QIITA/TJBot-4/28.png)

<font color="blue">「資格情報の表示」</font>をクリック
![29.png](http://seahorse-inc.com/QIITA/TJBot-4/29.png)


<font color="red">「username」「password」を後程使用しますので、メモ帳などにコピー保存してください。</font>
![30.png](http://seahorse-inc.com/QIITA/TJBot-4/30.png)
![31.png](http://seahorse-inc.com/QIITA/TJBot-4/31.png)


# ７. Rasbianの最新化とNode.js、npm、のインストール
TeratermなどでSSH接続します。ID、パスワードの初期値は、
　　<font color="blue">ID:pi
　　Password: raspberry</font> です。
![32.png](http://seahorse-inc.com/QIITA/TJBot-4/32.png)

以下のコマンドを実行してください。

```Command:
$ sudo apt-get update ⏎
$ sudo apt-get dist-upgrade ⏎
$ curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash - ⏎
$ sudo apt-get install -y nodejs ⏎
```


# ８. コードのダウンロードとインストール

```Command:
$ git clone https://github.com/victordibia/tjwave ⏎
$ cd ~/tjwave ⏎
$ npm install ⏎
$ sudo apt-get install alsa-base alsa-utils ⏎
$ sudo apt-get install libasound2-dev ⏎
$ sudo apt-get install pigpio ⏎
```
![33.png](http://seahorse-inc.com/QIITA/TJBot-4/33.png)


# ９. 「Speech to Text」、「Text to Speech」、構成情報の設定
ディレクトリを　<font color="blue">cd ~/tjwave</font> に移動します。

```Command:
$ cd ~/tjwave ⏎
```

インストールされたデフォルト構成ファイル<font color="blue">「config.defaule.js」</font>を<font color="blue">「config.js」</font>という名でコピーし、<font color="blue">「config.js」</font>を編集します。

```Command:
$ cp config.default.js config.js ⏎
$ sudo nano config.js ⏎
```

■<font color="green">“６．Watson「Speech to Text」、「Text to Speech」サービスの作成”</font>で取得した、<font color="blue">「username」「password」</font>を登録します。
ここではnanoエディターを使用しました。
![34.png](http://seahorse-inc.com/QIITA/TJBot-4/34.png)
各項目を登録し、<font color="blue">Ctrl+x</font> ⇒<font color="blue"> y</font> ⇒<font color="blue">⏎</font>で保存します。


# １０. USBマイクの設定
<font color="blue">~/tjwave/wave.js</font>
の<font color="blue">wave.js</font>で、USBマイクの設定値を追加します。
まず、USBマイクはのカード番号、デバイス番号を調べます。

```Command:
$ arekorod –l ⏎
```
![35.png](http://seahorse-inc.com/QIITA/TJBot-4/35.png)
この例では、<font color="blue">カード番号1、デバイス番号0</font>ですので、<font color="blue">plughw:1,0</font>を追加します。

<strong>wave.jsの56行あたり</strong>
var micInstance = mic({ 'rate': '44100', 'channels': '2', 'debug': false,,'exitOnSilence': 6 });
<font color="blue">⇒</font>
var micInstance = mic({ 'rate': '44100', 'channels': '2', 'debug': false,<font color="blue"> 'device': 'plughw:1,0'</font>,'exitOnSilence': 6 });
![36.png](http://seahorse-inc.com/QIITA/TJBot-4/36.png)

# １１. プログラムの実行

```Command:
$ cd ~/tjwave ⏎
$ sudo node wave.js ⏎
```
![37.png](http://seahorse-inc.com/QIITA/TJBot-4/37.png)
<font color="blue">「raise arm」
「weave arm」
「wave arm」
「leave arm」</font>

<font color="blue">「「intorduce yourself」
「what your name」</font>

<font color="blue">「「can you dance」</font>
と話しかけると、手を振ったり、自己紹介したり、ダンスをしてくれます。

発音が悪く、なかなか認識してくれませんが、Google翻訳の音声を使うとよく反応しました。


# １２. 日本語対応に変更
<strong>・wave.js 71行あたり</strong>
console.log("TJ is listening, you may speak now.");
<font color="blue">⇒</font>
console.log(<font color="red">"TJは聞いてます。何か話しかけてください"</font>);

<strong>・wave.js 81行あたり</strong>
content_type: 'audio/l16; rate=44100; channels=2'
<font color="blue">⇒</font>
<font color="red">model: 'ja-JP_BroadbandModel'</font>,  content_type: 'audio/l16; rate=44100; channels=2'

<strong>・wave.js 106～109行あたり</strong>
var containsWaveArm = (str.indexOf("raise") >= 0 || str.indexOf("weave") >= 0 || str.indexOf("wave") >= 0 || str.indexOf("leave") >= 0 ) && (  str.indexOf$
var introduceYourself = str.indexOf("introduce") >= 0 && str.indexOf("yourself") >= 0  ;
var whatisYourname = str.indexOf("what") >= 0 && str.indexOf("your") >= 0 && str.indexOf("name") >= 0  ;
var canYouDance = str.indexOf("can") >= 0 && str.indexOf("you") >= 0 && str.indexOf("dance") >= 0  ;
<font color="blue">⇒</font>
var containsWaveArm = (str.indexOf(<font color="red">"あげる"</font>) >= 0 || str.indexOf(<font color="red">"振る"</font>) >= 0 || str.indexOf(<font color="red">"振る"</font>) >= 0 || str.indexOf(<font color="red">"下ろす"</font>) >= 0 ) && (  str.indexOf(<font color="red">"手"</font>) >= 0) ;
var introduceYourself = str.indexOf(<font color="red">"自己"</font>) >= 0 && str.indexOf(<font color="red">"紹介"</font>) >= 0  ;
var whatisYourname = str.indexOf(<font color="red">"あなたの"</font>) >= 0 && str.indexOf(<font color="red">"名前"</font>) >= 0 && str.indexOf(<font color="red">"は"</font>) >= 0  ;
var canYouDance = str.indexOf(<font color="red">"ダンス"</font>) >= 0 && str.indexOf(<font color="red">"できます"</font>) >= 0   ;

<strong>・wave.js 113行あたり</strong>
speak("Ok, I will wave my arm. Just for you.");
<font color="blue">⇒</font>
speak(<font color="red">"はい。手を振ります。"</font>);

<strong>・wave.js 116行あたり</strong>
speak(" Hi, my name is TJ. I'm an open source project designed to help you access Watson Services in a fun way. You can 3D print me or laser cut me, then use one of my recipes to bring me to life. I can't wait to see what we do together. ");
<font color="blue">⇒</font>
speak(<font color="red">"こんにちは、私の名前はTJです。 あなたが楽しい方法でWatson Servicesを使うのを手助けするように設計されたオープンソースプロジェクトです。 あなたは3Dプリントをしたり、レーザーカットしたりして、レシピの1つを使って私を作ります。 一緒に何かやりましょう！ "</font>);

<strong>・wave.js 118行あたり</font>
speak(" My name is TJ. You can call me TJ Bot");
<font color="blue">⇒</font>
speak(<font color="red">"私の名前はTJです。 TJ Botと呼んでください。"</font>);

<strong>・wave.js 123行あたり</strong>
speak("sorry, I haven't been taught to understand that.")
<font color="blue">⇒</font>
speak(<font color="red">"すみません。よくわからないです。"</font>)

<strong>・wave.js 195行あたり</strong>
voice: config.voice,
<font color="blue">⇒</font>
voice: <font color="red">'ja-JP_EmiVoice'</font>,

<strong>・wave.js 238行あたり</strong>
speak("Sure. I am decoding a sound file that I will dance to. This may take a couple of seconds.") ;
<font color="blue">⇒</font>
speak(<font color="red">"確かに。 私は踊るサウンドファイルをデコードしています。 これには数秒かかります。"</font>) ;


# １３. 日本語対応版プログラムの実行

```Command:
$ cd ~/tjwave
$ sudo node wave.js ⏎
```
![38.png](http://seahorse-inc.com/QIITA/TJBot-4/38.png)

<font color="blue">「手をあげる」
「手を振る」
「手を下す」</font>

<font color="blue">「自己紹介」
「あなたの名前は？</font>

<font color="blue">「ダンスできます？」</font>
と話しかけると、手を振ったり、自己紹介したり、ダンスをしてくれます。