のびすけと鉄人兵団

『スター・ウォーズ』ファン必見!映画に登場したドロイド「BB-8」をブラウザから動かしてみた!


『スター・ウォーズ』ファン必見!映画に登場したドロイド「BB-8」をブラウザから動かしてみた!

こんにちは、ガジェット好きなエンジニアののびすけです。

みなさんは、映画『スター・ウォーズ』の最新作『スター・ウォーズ/フォースの覚醒(エピソード7)』をもう見ましたか? ファン待望の続編が昨年12月18日に全世界で封切りされてから、ものすごい盛り上がりを見せましたよね。最近やっと熱気が落ち着いてきた気がします。

僕も12月に見てきましたが、かなり面白かったです。2016年2月上旬の今でもまだ放映しているみたいなので、見ていない方はぜひ映画館へ行ってみてください! ネタバレは良くないので本編の内容は書きません!(笑)

前段はこれくらいにして、今日はJavaScriptを使い、エピソード7に新しく登場したドロイド「BB-8」をプログラムから制御してみたいと思います。

BB-8とは?

BB-8は『スター・ウォーズ/フォースの覚醒(エピソード7)』で初登場したドロイド(ロボット)です。従来の『スター・ウォーズ』シリーズで登場するドロイドといえば、C-3POやR2-D2が代表的でした。エピソード7では心機一転して新型ドロイドのBB-8が登場し、その可愛らしい姿からかなりの人気を博しています。

そんなBB-8ですが、なんとAmazonで購入することができます。

http://amzn.to/1UFyP8v

劇中のBB-8は人間の膝上ほどのサイズですが、販売されているBB-8は手の平サイズの小型でになっています。スマートフォンと連携して操作できるので、ラジコンのような感覚で扱うことができるんです。

一時は3万円くらいの値段でしたが、最近は2万円弱まで値下がりしたようです。

BB-8はどうやって作られたの?

『スター・ウォーズ』の世界から離れて現実世界の話に移ります。BB-8はSphero Japanが販売しているロボティクスボール「Sphero」というプロダクトが元となっています。

ロボティクスボール「Sphero」とは

「Sphero」とは、Sphero社が販売しているロボティクスボールです。ロボティクスボールが何なのかと言われると実は明確な答えがないのですが、スマホで操作可能なボール型のおもちゃという認識を持ってもらえれば大丈夫です。

こちらの「Sphero」の紹介動画を見ると雰囲気をつかみやすいかと思います!

http://www.sphero.jp/

つまり、BB-8はSpheroなの?

スターウォーズに登場するBB-8はSpheroと同じ機構を採用していて、実際に映画内で登場するBB-8も原点を辿るとSpheroなんだそうです。

確かに、改めて見てみると、Spheroに頭が付くとBB-8になるのが分かりますね。

今回つかうのは「Cylon.js」!

https://cylonjs.com/

少し話は変わりますが、最近JavaScriptでロボットやマイコンボードなどのハードウェアを制御しようという動きの「JavaScript Robotics」という言葉が最近流行ってきています。Node.jsからさまざまなハードウェアを制御できるライブラリとして有名です。

余談ですが、僕も過去にJavaScriptがだいすきな男たちが集まるイベント「JSオジサン」で「Cylon.js」について発表しているので、よかったら上記スライドをご覧になってみてください。概要がつかめるかと思います。

Cylon.jsはSphero対応している

Cylon.jsはさまざまなガジェットやマイコンボードの制御に対応しているのですが、今回の記事に登場した「Sphero」にも対応しています。BB-8はSpheroが元になっているという話を先ほどしましたが、発売時からBB-8をCylon.jsで動かせないかなと思っていました。

実際に手元に届いてから試そうとしたところ、通信方式の違いでBB-8には非対応になっていました。 ところが先月(2016年1月)に対応されて、Node.jsからBB-8を制御することができるようになったんです。

https://github.com/orbotix/sphero.js/issues/26

Githubではこんなissueも立っていて、みんな待ち望んでいたと分かります。

僕が毎月主催しているイベント「#IoTLT」のvol.11で話をしてきたので、そのときLTしてきた資料も掲載します。タイミングから考えておそらくBB-8をJavaScriptで動かしたLTをしたのは日本で初めてだったと思います。

BB-8をブラウザから動かしてみよう!

さてさて話が長くなりましたが、BB-8はJavaScript制御ができるんです。では、実際に動かしてみましょう!

ざっくりとした構成図

BB-8はBLE(Bluetooth Low Enegy)でスマートフォンと連携しています。今回はMac上のNode.js+Cylon.jsでBLEを使いBB-8を制御した上で、Milkcocoaを使いブラウザとの連携もしてみようと思います。

最終的にはブラウザからBB-8を動かせるようにします

のびすけ(執筆者)の環境

動作しないときの参考にしてみて下さい。

下準備

BB-8の制御にはBLEを使う必要があるのですが、BLEはけっこう難しいので全てを覚える必要はありません。

参考までに僕が作成したスライドを載せます。

 

$ npm i -g cylon-ble

まずUUIDというデバイスの識別番号のようなIDを調べる必要があります。cylon-bleというパッケージをnpm経由でグローバルインストールしましょう。

$ npm i cylon-sphero-ble

また、SpheroやBB-8を扱うためにcylon-sphero-bleをインストールしておきます。 cylon-bleのインストールが完了すると cylon-ble-scanコマンド が使えるようになります。MacのBluetoothをオンにすることを忘れずに! sudoで管理者権限としてコマンドを実行する必要があります。

$ sudo cylon-ble-scan

 sudo cylon-ble-scan
Password:
Starting scan.
Peripheral discovered!
  Name: undefined
  UUID: 28f97a8aeb034db4b82c0c3e960fc09e
  rssi: -85
Peripheral discovered!
  Name: undefined
  UUID: bdc6a5526bc24d6f850d47ecccc86ca0
  rssi: -48
Peripheral discovered!
  Name: undefined
  UUID: 10a279a9999d464291b3ab00a4f5e3c1
  rssi: -81
Peripheral discovered!
  Name: BB-XXXX
  UUID: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  rssi: -57
  ・
  ・
  ・
  ・

Macがある場所を中心に周辺のデバイスが持っているUUIDが一覧として表示されます。ここで表示されるNameには製品名が入ってくることが多いので、Nameの値でデバイスを判断すると良いです。BB-XXXXのような名前を見つけたら、その下のUUIDを探します。xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxと書いたところが、今回の目当てのBB-8のUUIDになります。

サンプルコードを動かしてみる

こちらにBB-8向けのサンプルコードが掲載されています。Spheroとは若干書き方が異なるので注意しましょう。

//app.js
'use sctrict'

let Cylon = require('cylon');

Cylon.robot({
  connections: {
    bluetooth: { adaptor: 'central', uuid: 'さっき見つけたUUIDをここに記述', module: 'cylon-ble'}
  },

  devices: {
    bb8: { driver: 'bb8', module: 'cylon-sphero-ble'}
  },

  work: (my) => {
    my.bb8.color(0x00FFFF); //BB-8のライトを水色に

    after(1000, () => {
        my.bb8.color(0xFF0000); //BB-8のライトを赤に
    });

    after(3000, () => {
      my.bb8.roll(60, 0); //60のスピードで回転
    });

    after(2000, () => {
      my.bb8.roll(60, 180); //60のスピードで回転、180度ターン(?)
    });

    after(3000, () => {
      my.bb8.stop(); //停止
    });
  }
}).start();

MacとBB-8のコネクションが確立した後に、workで定義しているメソッドが実行されます。このサンプルコードだと、水色に光らせた後に1秒後に赤になり3秒後に移動……のような流れになります。さっそく実行してみましょう。

$ node app.js

キター!! 動きましたね!  

Cylon.jsとMilkcocoa連携

その次に、Cylon.jsとMilkcocoaを連携させてみましょう。

https://mlkcca.com/

Milkcocoaはリアルタイム通信やIoTデバイスとの連携を簡単に実装できるサービス・ライブラリです。Milkcocoaのサイトからユーザー登録とアプリ登録をすればアプリIDを取得できます。基本的に無料で利用可能です。では、MilkcocoaのSDKを追加してみましょう。

$ npm i milkcocoa

先ほどのapp.jsにMilkcocoaに送られてくるデータとCylon.jsを連携させて書いてみます。Milkcocoaでは一つのクライアントがsendメソッドを用いてMilkcocoaのサーバーにデータを送ることで、待ち受けしている別のクライアントにリアルタイムに情報を共有することができます。 ds.on('send')と書くことで待ち受けすることができます。

//app.js
'use strict';

let Cylon = require('cylon');
let MilkCocoa = require('milkcocoa');
let milkcocoa = new MilkCocoa('<MilkcocoaのアプリID>.mlkcca.com');
let ds = milkcocoa.dataStore('bb8');

Cylon.robot({
  connections: {
    bluetooth: { adaptor: 'central', uuid: 'さっき見つけたUUIDをここに記述', module: 'cylon-ble'}
  },

  devices: {
    bb8: { driver: 'bb8', module: 'cylon-sphero-ble'}
  },

  work: (my) => {main(my)}
}).start();

function main(my){
  ds.on('send', (sended) => {
    if(sended.value.v === 'red'){
      console.log('red');
      my.bb8.color(0xFF0000);
    }

    if(sended.value.v === 'green'){
      console.log('green');
      my.bb8.color(0x00FF00);
    }

    if(sended.value.v === 'blue'){
      console.log('blue');
      my.bb8.color(0x0000FF);
    }

    if(sended.value.v === 'forward'){
      console.log('forward');
      my.bb8.roll(60, 0);
    }
  });
}

vというキーに対してredという値が送られてきたらmy.bb8.color(0xFF0000);でライトを赤くする、といった処理になります。  

Milkcocoa連携したブラウザ側のコントローラを作ってみる

これでBB-8側の準備はOKです。次はブラウザ側のコントローラを作ってみましょう。

http://stanko.github.io/skyblue/

サクッと作るために SkyBlueというCSSフレームワークを使ってみます。
 

 
こんな雰囲気のコントローラを作りました。ブラウザ側のJavaScriptコードはこうなっています。

//controller.js
var milkcocoa = new MilkCocoa('<MilkcocoaのアプリID>.mlkcca.com');
var ds = milkcocoa.dataStore('bb8');

$('.icon-angle-up-circle').on('click',function(){
  ds.send({v:'forward'}, (err, sended) => {
    console.log(sended);
  });
});

$('.icon-angle-down-circle').on('click',function(){
  ds.send({v:'back'}, (err, sended) => {
    console.log(sended);
  });
});

$('#red').on('click',function(){
  ds.send({v:'red'}, (err, sended) => {
    console.log(sended);
  });
});

$('#green').on('click',function(){
  ds.send({v:'green'}, (err, sended) => {
    console.log(sended);
  });
});

$('#blue').on('click',function(){
  ds.send({v:'blue'}, (err, sended) => {
    console.log(sended);
  });
});

jQuery周りのコードの説明は割愛します。

 

//controller.js (ブラウザ側)
・
(省略)
・
・
  ds.send({v:'forward'}, (err, sended) => {
    console.log(sended);
  });
・
・
(省略)
・

Milkcocoaの使い方はds.send({v:'forward'}vのキーに対して’forward’という値を送ることができます。

 

//app.js (Node.js側)
・
(省略)
・
・
   if(sended.value.v === 'forward'){
      console.log('forward');
      my.bb8.roll(60, 0);
    }
・
・
(省略)
・

Node.js側ではforwardを受け取ったことを検知してBB-8へ命令を送ります。

いよいよブラウザからBB-8を動かす!

説明はこんなところで、実際に動かしてみましょう。

$ node app.js
2016-02-03T09:56:18.749Z : [Robot 1] - Starting connections.
2016-02-03T09:56:18.752Z : [Robot 1] - Starting connection 'bluetooth'.
2016-02-03T09:56:22.179Z : [Robot 1] - Starting devices.
2016-02-03T09:56:22.180Z : [Robot 1] - Starting device 'bb8'.
2016-02-03T09:56:23.505Z : [Robot 1] - Working.
・
・
・

ブラウザからBB-8制御で遊ぶ n0bisukeさん(@n0bisuke)が投稿した動画 –

はい! これでブラウザからBB-8を制御することができました!!

まとめ

『スター・ウォーズ』ファンなら、BB-8がプログラミング制御できるなんてかなり胸アツですよね。

Cylon.jsでBLEデバイス制御をしてMilkcocoaでWebとつなげる組み合わせはいろいろなデバイスに応用できると思います。ハードウェアをWebエンジニアがJavaScriptで制御する敷居もだんだん下がってきた気がしますね。

ぜひ一度試してみて下さい。それでは!

おまけ

BB-8とSpheroを同時に動かしてみました。

SpheroとBB-8を同時に

n0bisukeさん(@n0bisuke)が投稿した動画 –


この記事を書いた人

のびすけ
のびすけ バックエンドエンジニア 2014年入社
dotstudio株式会社 ( https://dotstud.io )

岩手から上京してきました。

ギークハウスを経て、現在は0円シェアハウスに住んでいます。

好きなスポーツはフットサル/雪合戦/わんこそばです。

2015年は東京Node学園で登壇してみたいです。

・milkcocoa公認エバンジェリストになりました。(https://mlkcca.com/)
・gihyo.jpで記事書いてます (http://gihyo.jp/dev/feature/01/milkcocoa-baas)
・html5experts.jpで記事書いてます。(https://html5experts.jp/n0bisuke/)