LoginSignup
9
8

More than 5 years have passed since last update.

Cylon.jsでBB-8を動かす

Posted at

Cylon.jsとは

Cylon.jsはJavascriptから、(2016年5月現在で)43ものハードウェアデバイスをコントロールすることができるフレームワークで、npmモジュールとして提供されています。
Cylon.js
利用するには

$ npm install cylon

とするだけ。

対応デバイスもたくさんあります。以下一部抜粋です。

  • AR Drone
  • Arduino
  • Bebop
  • Crazyfile
  • Imp
  • Intel Galileo
  • Intel Edison
  • Joystick
  • Keyboard
  • Leap Motion
  • MiP
  • Nest
  • Neurosky
  • Philips Hue
  • Raspberry Pi
  • Sphero
  • etc...

動かしてみる

実際にCylon.jsでハードウェアデバイスを扱ってみます。

Keyboard

まずはキーボード。PCのキーボードも当然ハードウェアデバイスです。
とはいっても、もちろんキーボード自体が動くわけではありません。
入力装置として、何かを動かすためのコントローラーとして使うことができそうです。

今回は矢印キーの検出をしてみます。
* 「↑」キー:「UP PRESSED!」と出力
* 「←」キー:「LEFT PRESSED!」と出力
* 「↓」キー:「DOWN PRESSED!」と出力
* 「→」キー:「RIGHT PRESSED!」と出力

※ このエントリーで紹介するコードはここにおいてあります。
https://github.com/donkeykey/bb8_cylon

keyboard.js
var Cylon = require('cylon');

Cylon.robot({
    connections: {
        keyboard: { adaptor: 'keyboard' }
    },

    devices: {
        keyboard: { driver: 'keyboard' }
    },

    work: function(my) {
        my.keyboard.on('up', function(key) {
            console.log("UP PRESSED!");
        });
        my.keyboard.on('down', function(key) {
            console.log("DOWN PRESSED!");
        });
        my.keyboard.on('left', function(key) {
            console.log("LEFT PRESSED!");
        });
        my.keyboard.on('right', function(key) {
            console.log("RIGHT PRESSED!");
        });
    }
}).start();

仕様を見るとキーボードの大半のキーをイベントとして扱うことができるようです。(ファンクションキーもOK)

実行してみると、、、

$ node keyboard.js
UP PRESSED!
RIGHT PRESSED!
DOWN PRESSED!
LEFT PRESSED!

何の問題も無く、キーボードからの入力を検知することができました。
同じようにCylon.jsでは入力装置系のデバイスを扱うことができます。
Leap Motionとか持ってたら試してみたいところです。

BB-8 (Sphero)

BB-8はスターウォーズ最新作「フォースの覚醒」に登場するロボットで、
Spheroというボール型のラジコンロボットを作っているメーカーが、BB-8のラジコンを作っています。

こいつです。あざとい…
IMG_0194 のコピー 2.JPG

BB-8はスマホからBLE通信でコントロールすることができて、専用のアプリから動かすことができるようになっています。
ちなみに「Sphero」として売られているものはBluetooth接続ですが、BB-8はBLE接続です。
Spheroは公式でSDKが公開されているのですが、接続方式の違いによってこのSDKがBB-8では使えないのです。
Cylon.jsではそれまでもSpheroをサポートしていたようなのですが、2016年1月くらいにBB-8にも対応したので、Node.jsからBB-8を動かすことができるようになったのです。

とりあえず動かしてみたいと思います。
以下の動作をする様にコードを書きました。

  • 0秒〜 赤く光る & 0°の向きで前進(スピード60%)
  • 〜1秒 90°の向きで前進(スピード60%)
  • 〜2秒 180°の向きで前進(スピード60%)
  • 〜3秒 270°の向きで前進(スピード60%)
  • 〜4秒 ストップ & 右回転(スピード100%)
  • 〜5秒 左回転(スピード100%)
  • 〜6秒 ストップ & ランダムに色を変更
bb8.js
var bb8Key = require('./bb8.json');
var Cylon = require('cylon');

Cylon.robot({
    connections: {
        bluetooth: { adaptor: 'central', uuid: bb8Key.uuid, module: 'cylon-ble'}
    },

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

    work: (my) => {
        my.bb8.color(0xFF0000);
        my.bb8.roll(60, 0);
        after(1000, function() {
            my.bb8.roll(60, 90);
        });
        after(2000, function() {
            my.bb8.roll(60, 180);
        });
        after(3000, function() {
            my.bb8.roll(60, 270);
        });
        after(4000, function() {
            my.bb8.stop();
            my.bb8.spin('right', 100);
        });
        after(5000, function() {
            my.bb8.spin('left', 100);
        });
        after(6000, function() {
            my.bb8.stop();
            my.bb8.randomColor();
        });
    }
}).start();

キーボードからBB-8を動かしてみる

先程のキーボード入力の例と組み合わせて、キーボード入力からBB-8を操作してみます。

操作方法は、以下のようにします。

  • 「↑」キー:0°の向きで前進(スピード60%)
  • 「←」キー:90°の向きで前進(スピード60%)
  • 「↓」キー:180°の向きで前進(スピード60%)
  • 「→」キー:270°の向きで前進(スピード60%)
  • 「l」キー:左向きに回転(スピード100%)
  • 「r」キー:右向きに回転(スピード100%)
  • 「c」キー:ランダムにLEDの色を変更
  • 「s」キー:停止

コードはこんな感じ。

bb8_keyboard.js
var Cylon = require('cylon');
var bb8Key = require('./bb8.json');
var bb;

Cylon.robot({
    connections: {
        keyboard: { adaptor: 'keyboard' }
    },

    devices: {
        keyboard: { driver: 'keyboard' }
    },

    work: function(my) {
        my.keyboard.on('up', function(key) {
            console.log("UP PRESSED!");
            bb.bb8.roll(60, 0);
        });
        my.keyboard.on('down', function(key) {
            console.log("DOWN PRESSED!");
            bb.bb8.roll(60, 180);
        });
        my.keyboard.on('right', function(key) {
            console.log("RIGHT PRESSED!");
            bb.bb8.roll(60, 90);
        });
        my.keyboard.on('left', function(key) {
            console.log("LEFT PRESSED!");
            bb.bb8.roll(60, 270);
        });
        my.keyboard.on('l', function(key) {
            console.log("L PRESSED!");
            bb.bb8.spin('left', 100);
        });
        my.keyboard.on('r', function(key) {
            console.log("R PRESSED!");
            bb.bb8.spin('right', 100);
        });
        my.keyboard.on('c', function(key) {
            console.log("C PRESSED!");
            bb.bb8.randomColor();
        });
        my.keyboard.on('s', function(key) {
            console.log("S PRESSED!");
            bb.bb8.stop();
        });
    }
}).start();

Cylon.robot({
    connections: {
        bluetooth: { adaptor: 'central', uuid: bb8Key.uuid, module: 'cylon-ble'}
    },

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

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

おまけ:myThingsからBB-8を動かす

その1:ボタントリガーを使って動かす

最近myThingsでボタントリガーが使えるようになったので何かに使ってみたかったんです。
ボタントリガー「ボタンが押されたら〜する」というとてもシンプルなトリガーを実装することができます。
今回は「ボタンが押されたらBB-8を動かす」をやってみます。
※ myThingsについてはこちらのエントリーでも詳しく説明しています。
ESP8266を使ってmyThings連携して今日の降水確率をLEDの色で表現してみる

まずはボタンが押されたということをIDCF上のMQTTブローカーにpublishするために
スマホのアプリ上から設定をします。
以前のエントリーでIDCF上にMQTTブローカーを構築済み&myThingsと連携済みなのでここはすんなりです。

次にnodeからpublishされたメッセージをsubscribeするように実装し、メッセージを受信したらCylon.jsでBB-8を動かします。
BB-8の挙動は先程のbb8.jsと同じです。

bb8_myThings_button.js
var myThingsKey = require('./myThingsKey.json');
var bb8Key = require('./bb8.json');
var meshblu = require('meshblu');
var Cylon = require('cylon');
var conn1 = meshblu.createConnection(myThingsKey[0]);
var bb;

Cylon.robot({
    connections: {
        bluetooth: { adaptor: 'central', uuid: bb8Key.uuid, module: 'cylon-ble'}
    },

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

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

conn1.on('ready', function(data){
    console.log('Ready1');

    conn1.on('message', function(data){
        console.log(data);
        bb.bb8.color(0xFF0000);
        bb.bb8.roll(60, 0);
        after(1000, function() {
            bb.bb8.roll(60, 90);
        });
        after(2000, function() {
            bb.bb8.roll(60, 180);
        });
        after(3000, function() {
            bb.bb8.roll(60, 270);
        });
        after(4000, function() {
            bb.bb8.stop();
            bb.bb8.spin('right', 100);
        });
        after(5000, function() {
            bb.bb8.spin('left', 100);
        });
        after(6000, function() {
            bb.bb8.stop();
            bb.bb8.randomColor();
        });
    });
});

その2:天気情報をBB-8のLEDの色と連携させる

今日の降水確率をBB-8のLEDの色で表現したいと思います。
降水確率が0%に近いと緑っぽく、100%に近いと青っぽくなるようにします。
コレが実現できれば家で静かに眠っていたBB-8のラジコンが、myThingsと連携することで本物のBB-8のように人間の生活を助けるロボットに近づけることができます。
hueのように輝度はないですが同じようにフルカラーのLEDを積んでるし、動作で情報を伝えるなんてこともできます。
なんといってもかわいいのでhueより良いかもしれません。

コードはこんな感じです。
myThingsから今日の天気情報を取得し、メッセージ内に降水確率を含むように設定しているので
送られてきたjsonのデータをパースして数字を読み取ってカラーコードに変換しているという流れです。

bb8_myThings_weather.js
var myThingsKey = require('./myThingsKey.json');
var bb8Key = require('./bb8.json');
var meshblu = require('meshblu');
var Cylon = require('cylon');
var conn3 = meshblu.createConnection(myThingsKey[2]);
var bb;

function colorGen (col) {
    var c = col.match(/\d+/g).map(function(a){return ("0" + parseInt(a).toString(16)).slice(-2)}).join("");
    return parseInt(c, 16);
}

Cylon.robot({
    connections: {
        bluetooth: { adaptor: 'central', uuid: bb8Key.uuid, module: 'cylon-ble'}
    },

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

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

conn3.on('ready', function(data){
    console.log('Ready3');

    conn3.on('message', function(data){
        console.log(data.payload);
        var b = Math.floor(Number(data.payload) * (255/100));
        var g = Math.floor(255 - b);
        var r = 0;
        var rgb = "rgb(" + r + ", " + g + ", " + b + ")";
        console.log(rgb);
        bb.bb8.color(colorGen(rgb));
    });
});

テレビの横とかにBB-8置いて自然に目に入ってくるようにしておきたいので、Raspberry PiとかでnodeとCylon.jsインストールして置いておきたいです。

ホントはコレもやりたかった

MYOというアームバンド型のデバイスをつかうと、筋電情報を計測して手の動きをセンシングできる。
「手を広げる」という動きを検知できるようなので、腕を前に伸ばして手を広げるとBB-8が動く、
とか、まるでフォースでBB-8を動かしているようなことがしたかったのですがうまくいかず、、、

9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8