凧揚げの様子.

TL;DR:

 新年なので凧揚げをやる.
 具体的にはCylon.jsを用いてLeap MotionからRolling Spiderを操作し,ついでにSlackに通知する.
 依存関係は次の通り.

1
# npm install cylon cylon-keyboard cylon-leapmotion cylon-rolling-spider node-slack

Cylon.js

 Cylon.jsはロボティクス向けに開発されているJavaScriptのラッパーライブラリ.
 マイコンボードやドローン,スマートウォッチなど,さまざまなガジェットのSDKを統一されたインターフェイスで利用できる.反面,バグを踏み抜くと少ししんどい.
 たとえばキーボードに接続するには,次のように書く.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var Cylon = require('cylon');
Cylon.robot({
connections: {
'keyboard': { adaptor: 'keyboard' }
},
devices: {
keyboard: {driver: 'keyboard', connection: 'keyboard'}
},
work: function (my) {
my.keyboard.on('a', function(key) {
my.log("A PRESSED!");
});
}
}).start();

 これでお手軽キーロガーのできあがりだ.内部ではkeypressというモジュールが呼ばれる.

Leap Motion

 Leap Motionは人間の手の動きを入力に変換できるモーションセンサー.
 以前から研究室に転がっていたものの,これまでケツ叩きゲームにしか使われてこなかった.
 Cylon.jsで複数のガジェットを扱うときは,connectionsdevicesに追記していけばよい.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var Cylon = require('cylon');
Cylon.robot({
connections: {
'keyboard': { adaptor: 'keyboard' },
'leapmotion': { adaptor: 'leapmotion' }
},
devices: {
keyboard: {driver: 'keyboard', connection: 'keyboard'},
leapmotion: { driver: 'leapmotion', connection: 'leapmotion'},
},
work: function (my) {
my.leapmotion.on('gesture', function(g) {
my.log(g.type.toString());
if (g.type == "circle") {
...
}
});
}
}).start();

 これで手の動きが取れる.内部ではleapjsというモジュールが呼ばれる.
 次はドローンだ.

Rolling Spider

 Rolling SpiderはParrot社の小型ドローン.というとすぐドローンの定義は自律航行可能であるとかないとかクアッドコプターという呼称がどうとか言いだすやつがいるけど,ここではドローンと呼んでいる.
 それでは,Rolling SpiderをLeap Motionで操作してみよう.

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
var Cylon = require('cylon');
Cylon.robot({
connections: {
'keyboard': { adaptor: 'keyboard' },
'leapmotion': { adaptor: 'leapmotion' },
'rolling-spider': { adaptor: 'rolling-spider', uuid: '***' }
},
devices: {
keyboard: {driver: 'keyboard', connection: 'keyboard'},
leapmotion: { driver: 'leapmotion', connection: 'leapmotion'},
drone: { driver: 'rolling-spider', connection: 'rolling-spider' }
},
work: function (my) {
my.leapmotion.on('gesture', function(g) {
my.log(g.type.toString());
if (g.type == "circle") {
my.drone.takeOff();
} else if (g.type == "swipe" && !flag) {
var isHorizontal = Math.abs(g.direction[0]) > Math.abs(g.direction[1]);
if(isHorizontal){
if(g.direction[0] > 0){
my.drone.right();
} else {
my.drone.left();
}
} else {
if(g.direction[1] > 0){
my.drone.up();
} else {
my.drone.down();
}
}
} else if (g.type == "keyTap") {
my.drone.land();
}
});
my.keyboard.on("down", function() {
my.drone.land();
});
my.keyboard.on("m", function() {
my.drone.emergency();
});
my.keyboard.on("q", function() {
Cylon.halt();
});
}
}).start();

 とりあえずこれで動く.指を回すとドローンが飛び上がり,スワイプに応じて移動する.内部ではnode-rolling-spiderというモジュールが呼ばれる.
 複数台の機体に接続できるから,ドローンの編隊飛行も夢ではない.とはいえ,Bluetoothを経由した中央集権的な制御なので,自律飛行にはいたらないが.ほんとうに自律させたければ,ドローン側のファームウェアに手を入れる必要がある.Parrot社が公開しているRollingSpiderEduによると,どうやら共有ライブラリを用いてドローンのファームウェアに機能を追加できるようだ.いずれはレクサスのPVのように美しく飛ばしてみたいが,いっそドローンから自作したほうがいいかもしれないな.

 なおRolling Spiderの総重量は65gなので,空港等の周辺や人口中心地区の上空でのドローン飛行を制限する改正航空法の対象とはならない.

Slack

 凧揚げもChatOpsの時代.
 node-slackというモジュールと,ドローンのコールバック機能を用いれば,バッテリー残量をSlackに通知できる.SlackのWebHooks URLに投げるだけだ.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var Cylon = require('cylon'),
Slack = require('node-slack'),
slack = new Slack('https://hooks.slack.com/services/***');
...
work: function (my) {
...
my.drone.on('battery', function(){
slack.send({
text: ':battery:: ' + my.drone.getBatteryLevel() + '%',
channel: '#drone',
username: 'Drone'
});
});
...

 こんなふうに通知される.

 ちなみに,ドローンが移動するたびに通知なんかしていると「短期間に送信されたメッセージが多すぎるから表示しないよ!」と怒られる.

その他の凧揚げ

 Leap Motionによるドローンの操作はたぶんこの人が初.

 やっぱデカいドローンを飛ばしたいっすね.

おわりに

 ジェスチャーでドローンを操作できるようになったことだし,フォースの力みたいでかっこいいと思って,年始にRolling Spiderを多摩川の土手で飛ばしていたらドローン嫌いっぽい人にクソ怒られた.すいません.
 あとドローンといえば『伊藤計劃トリビュート』所収の藤井太洋「公正的戦闘規範」がおもしろいぞ!!!

謝辞

  • Leap Motionは@shunki9から借りた.
  • Rolling SpiderはGehirn Inc.に買ってもらった.