arrow-righthamburgerlogo-marksocial-facebooksocial-githubsocial-twitter
2019.01.30

Let's 顔面製造!第二弾! 歌うサンタ顔面ロボットを作ろう

へっぽこまるこ

まるこのロボット制作
   このエントリーをはてなブックマークに追加  

みなさん、こんにちは!へっぽこまるこです!

今回は、クリスマスをいい感じに盛り上げてくれるサンタ(っぽい)ロボットを obnizとgoogle home miniでつくってみました!

少し遅めの(めっちゃ早めの)サンタクロースをご覧あれ〜!

以前に「Let’s 顔面製造!ダンボールとサーボモータで喋る顔面ロボットを作ろう」でつくった顔面ロボット(的なもの)を改造して作ってみます!

完成イメージ

画像が表示できません

※LEDが結構強めに光っているので閲覧にはご注意ください

obnizでgoogle-home-notifierを使ってgoogle home miniから音源を再生します。 google-home-notifierは、スキル開発なしでgoogle homeにテキストを読ませたり、MP3などの音源が再生できたりするnode.jsのライブラリです。

再生された曲に連動して下唇に仕込んだサーボモータを動かして、 歌ってる感じにしてみます。

つくってみよう

### + obniz + sg90(顔面ロボの流用) + LED(顔面ロボの流用) + 顔デバイス(顔面ロボの流用) + ジャンパワイヤー(顔面ロボの流用) + 切ないクリスマスソングの音源 + 白のファー生地や赤いフェルトなど(デバイス装飾用)

macOS High Sierraの環境で進めます。

サンタデバイス準備

顔面デバイスをデコります。 毛足10cm程度のファー生地を裂いたものと、 赤いフェルトで適当につくった帽子をくっつけます。 IMG_2790.JPG

サーボモータとLEDをobnizに接続します。

obniz_servo_led.png

ライブラリやら準備

node.jsがインストールされてる前提で進めます。

ターミナルで以下のコマンドを叩きます。

//ディレクトリ作成&移動
$ mkdir santa
$ cd santa

//google-home-notifierとobnizのライブラリをインストール
$ npm install google-home-notifier
$ npm install obniz

//メインのプログラムファイルを作成
$ touch face.js

//音源格納用ディレクトリを作成
$ mkdir audio 

audioフォルダには音源のkurisumasusong.mp3を格納しておきます。

音源準備

google-home-notifierを使って簡単に曲を再生するには、 クリスマスソングが入ったMP3をネットにアップして、 URLを取得する必要があります。

今回は、n0bisuk先生のハンズオンで教えてもらった ngork+pythonを使った方法でホスティングします。

santa ディレクトリ配下で作業します。

$ python -m SimpleHTTPServer 8080

別タブで以下を実行します。

$ cd santa
$ ngrok http 8080

実行結果です。

ngrok by @inconshreveable                                                                                                                (Ctrl+C to quit)

Session Status                online
Account                       nougami (Plan: Free)
Version                       2.2.8
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://84019d5b.ngrok.io -> localhost:8080
Forwarding                    https://84019d5b.ngrok.io -> localhost:8080

Connections                   ttl     opn     rt1     rt5     p50     p90
                              57      0       0.00    0.00    6.51    8.91

HTTP Requests

https://84019d5b.ngrok.io/audio/kurisumasusong.mp3 が音源ファイルのURLになります。

へっぽこプログラム

node.jsでプログラムを書きます。 (async/awaitはまだ勉強中・・・)


const googlehome = require('google-home-notifier');
const language = 'ja';
const Obniz = require("obniz");

const obniz = new Obniz("××××-××××");

obniz.onconnect = async function () {
	var mouth = obniz.wired("ServoMotor", {signal:0, vcc:1, gnd:2});
	var leftLed = obniz.wired("LED", { anode:3, cathode:4 });
	var rigthLed = obniz.wired("LED", { anode:5, cathode:6 });

	mouthMove = async function (maxDeg, maxDegWait, minDeg, minDegWait) {
		await mouth.angle(maxDeg);
		await obniz.wait(maxDegWait);
		await mouth.angle(minDeg);
		await obniz.wait(minDegWait);
	}

	singMouth = async function () {
		//init
		await mouthMove(0.0, 1300, 0.0, 0);

		//く
		await mouthMove(40.0, 400, 0.0, 100);
		//り
		await mouthMove(40.0, 400, 0.0, 100);
		//す
		await mouthMove(40.0, 400, 0.0, 100);
		//ま
		await mouthMove(30.0, 80, 0.0, 100);
		//す
		await mouthMove(30.0, 80, 0.0, 100);
		//きゃ
		await mouthMove(50.0, 100, 0.0, 100);
		//ろ
		await mouthMove(30.0, 100, 0.0, 100);
		//る
		await mouthMove(30.0, 120, 0.0, 100);
		//が
		await mouthMove(40.0, 900, 0.0, 500);
	
		//な
		await mouthMove(40.0, 400, 0.0, 100);
		//が
		await mouthMove(40.0, 400, 0.0, 100);
		//れ
		await mouthMove(40.0, 400, 0.0, 100);
		//る
		await mouthMove(40.0, 400, 0.0, 100);
		//こ
		await mouthMove(40.0, 100, 0.0, 100);
		//ろ
		await mouthMove(40.0, 100, 0.0, 100);
		//に
		await mouthMove(40.0, 100, 0.0, 100);
		//は
		await mouthMove(50.0, 1300, 0.0, 500);
		
		//き
		await mouthMove(40.0, 100, 0.0, 100);
		//い
		await mouthMove(40.0, 100, 0.0, 100);
		//と
		await mouthMove(40.0, 200, 0.0, 100);
		//ぼ
		await mouthMove(40.0, 100, 0.0, 100);
		//く
		await mouthMove(40.0, 100, 0.0, 100);
		//の
		await mouthMove(40.0, 100, 0.0, 100);
		//こ
		await mouthMove(40.0, 170, 0.0, 100);
		//た
		await mouthMove(40.0, 170, 0.0, 100);
		//え
		await mouthMove(40.0, 170, 0.0, 100);
		//も
		await mouthMove(30.0, 1000, 0.0, 500);
		
		//き
		await mouthMove(40.0, 100, 0.0, 100);
		//い
		await mouthMove(40.0, 100, 0.0, 100);
		//と
		await mouthMove(40.0, 500, 0.0, 100);
		//で
		await mouthMove(40.0, 100, 0.0, 100);
		//て
		await mouthMove(40.0, 100, 0.0, 100);
		//い
		await mouthMove(40.0, 100, 0.0, 100);
		//る
		await mouthMove(40.0, 100, 0.0, 100);
		//だ
		await mouthMove(40.0, 100, 0.0, 100);
		//あ
		await mouthMove(40.0, 100, 0.0, 100);
		//ろ
		await mouthMove(40.0, 800, 5.0, 600);

		//く
		await mouthMove(40.0, 400, 0.0, 100);
		//り
		await mouthMove(40.0, 400, 0.0, 100);
		//す
		await mouthMove(40.0, 400, 0.0, 100);
		//ま
		await mouthMove(30.0, 80, 0.0, 100);
		//す
		await mouthMove(30.0, 80, 0.0, 100);
		//きゃ
		await mouthMove(50.0, 100, 0.0, 100);
		//ろ
		await mouthMove(30.0, 100, 0.0, 100);
		//る
		await mouthMove(30.0, 120, 0.0, 100);
		//が
		await mouthMove(40.0, 900, 0.0, 500);
	
		//な
		await mouthMove(40.0, 400, 0.0, 100);
		//が
		await mouthMove(40.0, 400, 0.0, 100);
		//れ
		await mouthMove(40.0, 400, 0.0, 100);
		//る
		await mouthMove(40.0, 400, 0.0, 100);
		//こ
		await mouthMove(40.0, 100, 0.0, 100);
		//ろ
		await mouthMove(40.0, 100, 0.0, 100);
		//に
		await mouthMove(40.0, 100, 0.0, 100);
		//は
		await mouthMove(50.0, 1300, 0.0, 500);
		
		//だ
		await mouthMove(40.0, 100, 0.0, 100);
		//れ
		await mouthMove(40.0, 100, 0.0, 100);
		//を
		await mouthMove(40.0, 400, 0.0, 100);
		//あ
		await mouthMove(40.0, 100, 0.0, 100);
		//い
		await mouthMove(30.0, 100, 0.0, 100);
		//し
		await mouthMove(30.0, 100, 0.0, 100);
		//て
		await mouthMove(30.0, 100, 0.0, 100);
		//る
		await mouthMove(30.0, 100, 0.0, 100);
		//の
		await mouthMove(40.0, 100, 0.0, 100);
		//か
		await mouthMove(30.0, 1000, 0.0, 500);
		
		//い
		await mouthMove(40.0, 100, 0.0, 100);
		//ま
		await mouthMove(40.0, 100, 0.0, 100);
		//は
		await mouthMove(40.0, 500, 0.0, 100);
		//み
		await mouthMove(40.0, 100, 0.0, 100);
		//え
		await mouthMove(40.0, 100, 0.0, 100);
		//な
		await mouthMove(20.0, 100, 0.0, 100);
		//く
		await mouthMove(20.0, 100, 0.0, 100);
		//て
		await mouthMove(40.0, 100, 0.0, 100);
		//も
		await mouthMove(40.0, 100, 0.0, 100);
		//お
		await mouthMove(50.0, 5000, 50.0, 0);
		for (i=49; i>=0; i--){
			await mouth.angle(i);
			await obniz.wait(80);
		}
	}
	
	google_home = async function() {
		googlehome.device('Google-Home', language);	
		await googlehome.play('http://×××××.ngrok.io/audio/kurisumasusong.mp3', function(res) {
			console.log(res);
			leftLed.on();
			rigthLed.on();
			singMouth();
		});
	}

	await google_home();
}

for (i=49; i>=0; i–){  await mouth.angle(i);  await obniz.wait(80); } ↑はこだわった部分なので、 注目してみてもらえると嬉しいです。

実行

サンタデバイスにgoogle home miniをそっと添えて、 以下のコマンドで実行します。

$ node face.js

サンタが歌ってる感じになります。

まとめ

哀愁漂うサンタクロースができたのではないでしょうか。

私にとって、スマートスピーカーは電子部品的存在なので、 今後も色々な作品に仕込んで、へっぽこなモノづくりに一役買ってもらおうと思っています。

よかったら是非「スマスピ + デバイス」挑戦してみてください!

   このエントリーをはてなブックマークに追加