AquesTalk と Node-RED と ラズパイで おしゃべりティラノくん作製
最近、長男くんがハマっているYouTubeチャンネルが以下になります。
なんか青鬼のアニメばかり見ててナレや歌が耳について耳について。。。
お母ちゃん
「早く寝なさい」とかね。
こりゃいいぞ!ということでAquesTalkで喋って動くお人形を作ろうということに相成りました。
目次
おしゃべりティラノくん
しゃべるときに口パクパクさせたいよねと思い。
前にダイソーで買ったニギニギするとパクパクするティラノのおもちゃを使いました。もう歯も取れて、目も剥げてボロボロだったしね。。リメイク!
ラズパイにAquesTalk導入してモータでパクパクしてみました。
新しい家族なのですが。長男くんドン引きです。。。 pic.twitter.com/ucOTGEVtah
— HomeMadeGarbage (@H0meMadeGarbage) 2018年10月31日
しりとりで仲直り pic.twitter.com/kCyEox5qvt
— HomeMadeGarbage (@H0meMadeGarbage) 2018年10月31日
一緒に遊んでなんとか仲良しに。。。
IoT pic.twitter.com/Co5eBsdt1n
— HomeMadeGarbage (@H0meMadeGarbage) 2018年10月31日
専用のウェブページを作ってスマホやPCで発話入力できるようにしてます。
最初はラズパイ3とUSBスピーカをつかってみましたがでかいので、ラズパイゼロWで小型化しました。
↓これをこう!
以下に制作の詳細記載します。
構成
AquesTalkをインストールしたラズパイゼロWにアンプMAX98357Aとサーボを接続しました。
部品
- Raspberry Pi Zero W
-
マイクロサーボ SG90
-
MAX98357A搭載 I2S 3W D級アンプボード
- スピーカー
長女ちゃんの昔使ってた音の鳴るおもちゃ(プリキュアかなんかの)を分解してスピーカを拝借。小さいけどパワーあってGoodでした。
- ティラノ顔
ダイソーのパクパク恐竜を分解
配線・組み立て
ティラノの頭とサーボをグルーガンで貼り付けて部品を配線。JCOMでもらった升を筐体として使用しましたw。
枡に穴を開けてスピーカを埋め込みました。
サーボとティラノの頭を紐でつないで、発話中のパクパクを実現します。
AquesTalk
AquesTalkとはテキスト入力で発話させることができr日本語音声合成エンジンです。今回はこれをラズパイに導入して発話させます。
インストール
ラジパイ用の実行モジュールをコピーするだけです。簡単!
以下でtgzファイルをダウンロードします。
ファイルをラズパイ上で解凍します。
1 |
$ tar xzvf aquestalkpi-20130827.tar.gz |
解凍したフォルダに移動して以下を実行するだけで音声データが作られ再生されます。
1 |
$ ./AquesTalkPi "発話内容を入力" | aplay |
アンプMAX98357A 設定
小型化のためにラズパイゼロを採用しましたがオーディオ出力端子はついていません。ですのでアンプボードMAX98357Aを使用しました。
I2Sという規格で3線で音声データをシリアル転送します。ラズパイとの配線は以下の通り
- アンプ Vin to Raspbery Pi 5V
- アンプ GND to Raspbery Pi GND
- アンプ DIN to Raspbery Pi GPIO21
- アンプ BCLK to Raspbery Pi GPIO18
- アンプ LRCLK to Raspbery Pi GPIO19
以下をラズパイのターミナルで実行するだけでアンプを使用するためのセットアップができます。
1 |
curl -sS https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/i2samp.sh | bash |
スピーカを接続して音声出力設定は終了です。
参考
Node-RED
ラズパイ上でコマンド打って発話だとちょっと使いづらいので、ブラウザで別端末から発話できるようにするべくNode-Redで設定しました。ついでに発話中の口パクパク用サーボの制御もNode-REDで実施します。
インストール
最近のラズパイOSには Node-REDはインストールされていません。以下実行でインストールできます。
1 |
bash <(curl -sL https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/update-nodejs-and-nodered) |
Node-RED設定
以下が今回のフローとなります。
- httpノード
URLを指定してメッセージをGETできるようにしました。
以下をブラウザ送信すると発話文が受信されます
1http://[ローカルIPアドレス]:1880/aooni?発話メッセージ入力 - jsonノード
jsonノードを挿入してブラウザからのメッセージをString型に変換しています
- execノード
コマンド実行してくれるexecノードでブラウザからのメッセージを受け取って、AquesTalkのコマンドを実行します。
- triggerノード
ブラウザからメッセージを受けると”1″を200msec毎に出力し続けます。
“0”が入力されるとトリガがリセットされて止まるようにしました。
- randomノード
triggerノードからの200msec毎の出力を受けて12.0〜15.0の間で値を生成して出力します。
- rpi-gpio outノード
サーボモータを動かすためにGPIO2ピンにPWM信号を出力させます。
“サーボの制御にPWMモードが利用でき、入力に小数値も含む 10 から 20 の値が指定可能です。”とのことで今回はrandomノードから12.0〜15.0の間で値がランダムに入力されてサーボをコントロールします。
- functionノード
execノードからの発話再生終了出力信号を受けて”0″を出力します。
“0”出力をrandomノードに入力して値出力を止めます。更にrpi-gpio outノードにも入力してサーボを完全に止めます。
以上でブラウザから発話メッセージを受けて再生し、音声再生の間はサーボが動いて口がパクパクします。再生が止まるとパクパクも止まります。
Node-red自動起動設定
以下のコマンドの実行でラズパイ起動で自動的にNode-REDも起動します。
1 |
$ sudo systemctl enable nodered.service |
参考
ブラウザページの作成
発話文章を入力するページはお母ちゃん
表示
入力エリアと送信ボタンだけのシンプルな画面です。
ソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
<!doctype html> <html lang="en"> <head> <meta name="viewport" content="width=device-width,initial-scale=1"> <meta charset="utf-8"> <link rel="shortcut icon" href="favicon.png"> <title>ティラノ</title> <style> textarea { width: 100%; } </style> </head> <body> <textarea rows="8" cols="80"></textarea><br> <button type="button">送信</button> <script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous"></script> <script> var jqxhr = null; var sendText = function() { var obj = {}; var t = $('textarea').val().replace(/\r?\n/g, '。');; obj[t] = ''; // 連続送信を防ぐ if (jqxhr) { jqxhr.abort(); } jqxhr = $.ajax({ url: 'Node-REDのエンドポイントを指定する', type: 'get', data: obj, timeout: 500, dataType: 'text' }) .done(function(returnData) { }) .always(function() { // テキストエリアをクリア $('textarea').val(''); }); } $('button').click(function(event) { sendText(); }); // Shift + Enter で送信 $(window).keydown(function(e){ if(event.shiftKey){ if(e.keyCode === 13){ sendText(); } } }); </script> </body> </html> |
Node-RED のエンドポイントに ajax で送信しました。
終わりに
新しい家族が増えました。
おしゃべりティラノくん。新しい家族です。#ラズパイ #AquesTalk pic.twitter.com/WqHEhToGev
— HomeMadeGarbage (@H0meMadeGarbage) 2018年10月31日
長男くん
「ちゃんとご飯食べなさい」とか
「もう寝なさい」とか
言わせてますww ビビって結構いう事聞いてくれるのよ。これが。
うちのティラノくんは今日もおしゃべり pic.twitter.com/avt21cJcyb
— HomeMadeGarbage (@H0meMadeGarbage) 2018年11月1日
ロボットとお友達とか冗談抜きで未来じゃなくなってる。Amazon Echoも子どもたちはほとんど人として接しているしね。
今度はティラノくんを目覚ましにしたり、リマインダにしたりしたいな。
「宿題やった?」と「歯磨きしなさい」とかね。
追記
定期発話機能追加 (2018/11/4)
Node-REDのinjectノードの繰り返し機能で時刻と曜日が指定できることを知り、目覚ましとリマインダ発話を追加しました。
目覚ましや「宿題やった?」とか「もう寝なさい」とか時間でしゃべるようにしました。いやーNode-REDマジ便利!
Raspberry Pi Zero (2019/4/23)
Raspberry Pi Zero WからRaspberry Pi Zero + WiFiドングルに変更しました。SDカード差し替えるだけで問題なく動きました。
どうしてもほかの用途で必要なのでティラノくんのRaspberry Pi Zero WをRaspberry Pi Zero + WiFiドングルに差し替えます。 SDカード入れ替えるだけでいいのね。楽でした。 pic.twitter.com/8vhCszBktL
— HomeMadeGarbage (@H0meMadeGarbage) 2019年4月23日
Raspberry Pi Zero Wはまた別用途で使用します!