落下しちゃう?手作りドローンを作って、河川敷で飛ばしてみた
- 218
- 2
こんにちは、エンジニアののびすけです。
さて、今回はDrone(ドローン)の話です。注目されてますよね〜。
以前、株式会社フォークの石射さんにParrot DroneをNode.jsで制御するやり方を教わりました。その後、自分で購入して少しずつ触っています。
そして、初めてDroneを飛ばしたときに感動したので、その勢いで社内勉強会も実施しました。
参加者はディレクターやデザイナーといったエンジニア以外の職種の人のほうが多かったのですが、Droneを問題なくプログラム制御することができました。
今回は、社内勉強会でやった内容をもとに、 ノンプログラマな読者のみなさんもDroneをプログラムで制御できるようになる7つのステップを紹介してみたいと思います。
▼ テクノロジーをおもしろがれ!
落下しちゃう?手作りドローンを作って、河川敷で飛ばしてみた
WebRTC Conference JapanとROMO TSURISMOレポート【ROMOラジコンで優勝しました!】
MQTTブローカーサービス「sango」を使ってJavaScriptだけでチャットを作ってみた
ますは事例を見ておきましょう。
Droneは以下のようにインスタレーションで利用されるシーンが現状だと多いイメージです。こういったものは操縦が大変……などと言われます。たしかにリモコン経由で人間が操作すると難しいものも多いですが、プログラムで制御することで安定して動かすことが可能です。
ライゾマティクスが行ったPerfumeのライブでの演出。Droneだと真っ先に思い浮かぶくらい有名なインスタレーションです。ライゾマティクスの作品はかっこいいですよね〜。
参考:ヤバいから見てっ! ライゾマティクス真鍋大度の動画と作品(本人による解説つき):SENSORS IGNITION 2015
http://weekly.ascii.jp/elem/000/000/311/311552/
冒頭でも触れたフォークの作品です。曲にシンクロして動く2台のDroneがかっこいいです。
参考:映像クリエイティブ『SESSION』を制作してみました
http://4009.jp/post/2015-08-10-session/
それでは実際に、Droneを飛ばすためのステップを一つずつ見ていきましょう。
Droneだと、DJIやParrotという会社が有名です。今回はParrotの製品を扱ってみたいと思います。
Parrot製品にも色々とあるのですが、今回はAirborne Night Drone マクレーン(以下「マクレーン」という)を使います。マクレーンはMini Droneと言われるタイプのDroneで、わりと小型です。
なお、執筆時点では、Amazonで1万6,000円ほどで購入可能でした。
参考:LEDライト搭載で暗闇でも走行・飛行できるParrotのミニドローン「Jumping」と「Airborne」の実機11機種を発売直前レビュー
http://gigazine.net/news/20150918-parrot-minidrones/
ちなみに、使用するマクレーン以外のタイプのMini Droneでも、今回の手順でプログラム制御できますよ。
何はともあれ、まずはDroneの起動方法から学びましょう。といっても、今回利用するマクレーンは、背面にある出っ張りを押すだけで起動できます。
ここで電源のオン/オフを切り替えましょう。
1:電源オフ(消灯)
2:起動ボタンを押した(ライト赤)
3:起動中(ライト橙)
4:起動(ライト緑)
基本的に電源ボタンを押して待っていれば、上記1〜4の順番でライトの色が変わり、起動します。ライトが緑色になったら操作可能な状態です。
今回の手順としては別にやらなくても大丈夫なのですが、「箱から出してすぐに試してみたい!」という方は、スマートフォンアプリから動作確認をしてもいいかもしれません。「FreeFlight3」というアプリを使って飛ばします(アプリの使い方は本題ではないいので省略)。
こんな感じでラジコン感覚で試してみるのも良いと思います。
ParrotのDroneはWi-Fiで制御するものと、Bluetoothで制御するものがあります。手元のデバイスがどちらのタイプなのかは説明書などで確認しましょう。
ちなみに私は、すべてがWi-Fiで接続できるものだと勘違いして、Bluetoothをオフにしていたせいで「なんで動作しないの?」みたいなことがありました。
なお、今回利用するマクレーンなどのタイプはBluetooth経由で制御します。パソコン側のBluetoothがオンになっていることを確認しましょう。
これで、パソコン側でプログラムを書いて実行することによってDroneに対して命令を送ることができます。色々なプログラミング言語を使うことができるのですが、今回はWeb界隈の人にも馴染みがあるNode.jsを使ってみましょう。
前段が多くなってしまいましたが、実際に開発をしていきましょう。ちなみに私の環境は以下のような感じです。エラーが出た際などの参考にしてください。以下、説明についてはMacをもとに書いていきます。
※独り言:io.jsの時代を抜けたらNode.jsがあっという間にv4ですね〜
さて、まずはNode.jsが動く環境を用意するべく、Node.jsをインストールしましょう(Node.jsをインストール済みの方は読み飛ばしてください)。
いまアツいJavaScript!ゼロから始めるNode.js入門〜5分で環境構築編〜
Node.jsは4.1.1を入れましょう(古いバージョンだとエラーが起きる場合があります)。
$ nvm install 4.1.1
にしましょう。
$ node -v v4.1.1
ここまでできればOKです。
任意のディレクトリにNode.jsアプリケーションを構築していきましょう。
まずは必要なモジュールを揃えます。
ターミナル操作に慣れていない人も慣れてみましょう。
ターミナルを起動(Macのアプリケーションにあります)して、以下のコマンドを実行していきます。
まずはlsコマンドでディレクトリ一覧を取得。ターミナル起動直後にlsすると、自分のMacのホームディレクトリのファイルやフォルダ一覧が表示されます。
$ ls Applications Library Creative Cloud Files Movies Creative Cloud Files (unknown) Music Desktop Pictures Documents Public Downloads n0bisuke Google ドライブ
cdコマンドでディレクトリに移動。ここではDesktopに移動しています。
$ cd Desktop
mkdirコマンドで任意のディレクトリを作成。ここではdroneディレクトリを作成して、その中に移動しています。
$ mkdir drone $ cd drone
このdroneディレクトリ内でプログラムを作っていきましょう。
Node.jsでは必要な機能を使いたいときに、その機能をまとめたモジュールをインストールして使います。以下は3つのモジュールのインストールです。実行してみましょう。
$ npm i noble $ npm i keypress $ npm i rolling-spider
インストールが無事に終われば、lsコマンドで確認するとnode_modulesというフォルダができていると思います。ls node_modulesでnode_modulesフォルダ内を確認すると、3つのモジュールが入っていることが確認できるでしょう。
$ ls node_modules $ ls node_modules keypress noble rolling-spider
以下の二つはNode.jsのインストール後に使えます。
作るものは二つ。検索用のfind.jsと実際に操作するapp.jsを作成します。プログラムの作成は任意のテキストエディタなどで行ってください。
ちなみに最近、私はAtom推しです。ちなみにこのプログラムは冒頭で紹介した株式会社フォークの石射さんが書いたものをもとにしています(石射さんありがとうございます)。
・find.js
'use strict';
var noble = require('noble');
var knownDevices = [];
var counter = 0;
if (noble.state === 'poweredOn') {
start()
} else {
noble.on('stateChange', start);
}
function start () {
noble.startScanning();
noble.on('discover', function(peripheral) {
counter++;
console.log(
"------"+counter+"台目: \n",
peripheral.uuid,peripheral.advertisement.localName);
if(peripheral.advertisement.localName && peripheral.advertisement.localName.indexOf('Maclan_') === 0){
console.log(peripheral.advertisement.manufacturerData.toString('hex'));
}
var details = {
name: peripheral.advertisement.localName,
uuid: peripheral.uuid,
rssi: peripheral.rssi
};
knownDevices.push(details);
console.log(knownDevices.length + ': ' + details.name + ' (' + details.uuid + '), RSSI ' + details.rssi);
});
}
・app.js
var RollingSpider = require("rolling-spider");
var keypress = require('keypress');
keypress(process.stdin);
process.stdin.setRawMode(true);
process.stdin.resume();
var ACTIVE = true;
var STEPS = 5;
var d = new RollingSpider({uuid:"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}); //各々書き換えましょう。
function cooldown() {
ACTIVE = false;
setTimeout(function () {
ACTIVE = true;
}, STEPS);
}
d.connect(function () {
d.setup(function () {
console.log('Configured for Rolling Spider! ', d.name);
d.flatTrim();
d.startPing();
d.flatTrim();
setTimeout(function () {
console.log(d.name + ' => SESSION START');
ACTIVE = true;
}, 1000);
});
});
// listen for the "keypress" event
process.stdin.on('keypress', function (ch, key) {
console.log('got "keypress" => ', key);
if (ACTIVE && key) {
var param = {tilt:0, forward:0, turn:0, up:0};
if (key.name === 'l') {
console.log('land');
d.land();
} else if (key.name === 't') {
console.log('takeoff');
d.takeOff();
} else if (key.name === 'h') {
console.log('hover');
d.hover();
} else if (key.name === 'x') {
console.log('disconnect');
d.disconnect();
process.stdin.pause();
process.exit();
}
if (key.name === 'up') {
d.forward({ steps: STEPS });
cooldown();
} else if (key.name === 'down') {
d.backward({ steps: STEPS });
cooldown();
} else if (key.name === 'right') {
d.tiltRight({ steps: STEPS });
cooldown();
} else if (key.name === 'left') {
d.tiltLeft({ steps: STEPS });
cooldown();
} else if (key.name === 'u') {
d.up({ steps: STEPS });
cooldown();
} else if (key.name === 'd') {
d.down({ steps: STEPS });
cooldown();
}
if (key.name === 'm') {
param.turn = 90;
d.drive(param, STEPS);
cooldown();
}
if (key.name === 'h') {
param.turn = -90;
d.drive(param, STEPS);
cooldown();
}
if (key.name === 'f') {
d.frontFlip();
cooldown();
}
if (key.name === 'b') {
d.backFlip();
cooldown();
}
}
});
二つのプログラムはdroneディレクトリ内に作ってください。作成後のディレクトリ構成はこんな感じになっていると思います。
$ ls app.js find.js node_modules
Finderで見るとこんな感じです。
前述しましたが、PCのBluetoothをオンにしましょう。オンになっていないとDroneが飛びません(苦笑) nodeコマンドでfind.jsを動かしてみます。
$ node find 1: MacLan_yyyyy (xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx), RSSI -61
find.jsは周囲のBLE対応端末を検出。BLEには端末固有のUUIDという識別子があり、「xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx」となっている部分がUUIになります。
これでDroneのUUIDを発見できました。
先ほどのUUIDを使い、app.jsのxxxxxxxxxxxxとなっている部分を書き換えましょう。
その後、コマンドを実行します。このとき、前述した起動状態(緑のランプ)になっていることを確認してからコマンドを実行するようにしてください。
$ node app Configured for Rolling Spider! MacLan_yyyyy MacLan_yyyyy => SESSION START
こうなったら成功です。PCとDroneがBluetoothで接続されました。
※ SESSION STARTが表示されない場合はDroneをいったん再起動し、再実行してみましょう
このあとはキーボードで以下の基本キーを押せば操作できます。
動画だとこんな感じです。
これでJavascriptでDroneを飛ばすことができました!
おめでとうございます!
今回は「Droneを身近に感じてもらいたいなぁ」と思い、ノンプログラマ向けな内容で説明をしてみました。「まだ難しいよ!」って人はコメントください!!! 思った以上に簡単にDroneを飛ばせることが伝われば幸いです。
ちなみに、この内容で学生向けのハンズオン講師をしてきました。
さっそくレポート記事が公開されているので、こちらもチェックしてみてください。
また、10月15日に開催する「IoTLT vol.8」でもDroneを使ったネタをできればと思っています(きてねー)。
Droneに限らず、Web界隈の人たちがハードウェアを制御する敷居がすごく下がってきていますね。DevRel Labでは、Webエンジニアやエンジニア以外の人たちに対してもハードウェアやガジェットの使い方が伝わるような内容を届けていけたらと思っています。
今後も期待していてください!
それでは〜。