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
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のラジコンを作っています。
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秒 ストップ & ランダムに色を変更
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」キー:停止
コードはこんな感じ。
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と同じです。
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のデータをパースして数字を読み取ってカラーコードに変換しているという流れです。
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を動かしているようなことがしたかったのですがうまくいかず、、、