Help us understand the problem. What is going on with this article?

ミニドローンをRaspberry Piと接続してLeap Motionで飛ばす

More than 1 year has passed since last update.

Tangoアプリ開発の裏で密かに進めていたドローン制御プロジェクトが(物理的な意味で)ようやく動き始めたので、投稿します。

目的

当座の目標は、プログラム制御でドローンを自由自在に飛ばすこと。
最終的なゴールとしては、自律飛行とサイコミュによる操作ができるようになることですかね。

システム構成

ハードウェア

  • Parrot MAMBO
  • Raspberry Pi3 Model B
  • BUFFALO WLI-UC-GNME
  • MacBook Pro (13-inch, Mid 2010)
  • Leap Motion

ソフトウェア

  • Raspbian Jessie with PIXEL
  • Node.js v6.9.4
  • noble 1.7.0
  • rolling-spider 1.5.2
  • leapjs 0.6.4

開発記録

ドローンを手に入れる

兎にも角にもドローンが必要です。

色々調べたところ、首都圏ではドローンを飛ばせる場所がほとんどないらしく、規制の対象外となる200g未満のミニドローンから始めるのが良いらしい。
さらに調べると、Parrot社のドローンはエントリーモデルもSDKで操作でき、Node.jsからBluetooth接続した実績も報告されています。
http://qiita.com/tkyko13/items/02f74180daac05254367
https://liginc.co.jp/187633

上記を踏まえ、ドローン初号機は以下を購入することにしました。
Parrot MAMBO

IMG_1395.jpg

換装可能なキャノン砲ロボットアームがロマンです。

MacBookから操作する・・・はずだった

ドローンを調達できたので、まずは公式のiOSアプリで動作確認。
https://itunes.apple.com/jp/app/freeflight-mini/id1137022728

アプリだからかもしれないけど、意外と操作が難しい・・・。
プロペラがウィンウィン鳴ってます。

しばらく触って、基本的な動きを理解したところで、次はいよいよNode.jsからの操作。
さくっと動かす・・・つもりが、nobleが以下のエラーを出している。

$ sudo node find.js 
/Users/shigemitsu/drone/node_modules/noble/lib/noble.js:76
      throw error;
      ^

Error: Could not start scanning, state is unsupported (not poweredOn)
    at Noble.startScanning (/Users/shigemitsu/drone/node_modules/noble/lib/noble.js:71:17)
    at Noble.start (/Users/shigemitsu/drone/find.js:14:9)
    at emitOne (events.js:96:13)
    at Noble.emit (events.js:188:7)
    at Noble.onStateChange (/Users/shigemitsu/drone/node_modules/noble/lib/noble.js:60:8)
    at emitOne (events.js:96:13)
    at NobleBindings.emit (events.js:188:7)
    at NobleBindings.<anonymous> (/Users/shigemitsu/drone/node_modules/noble/lib/mac/yosemite.js:78:8)
    at emitOne (events.js:96:13)
    at NobleBindings.emit (events.js:188:7)

調査結果:
MacBookが古すぎて、Bluetooth 4.0に対応していません。

なんてこった…(´・ω・`)

プロジェクトは一時中断を余儀なくされます。

仕方ないので、Raspberry Piを買う

まあ、前から欲しかったし。ここでBluetoothドングルに逃げたら、負けかなと思った。
IMG_1388.jpg

WiFiドングルは、ラズパイでの動作実績が報告されているBUFFALO WLI-UC-GNMEを装着。他に、USBマウス、キーボード、電源とモニタを繋いで使っています。
IMG_1397.jpg

OSインストールはNOOBSを使って、滞りなく完了。
日本語化やWiFiへの接続も簡単にできました。

改めて、Node.jsでドローンを飛ばす

ラズパイでNode.jsの環境を作ります。
apt-getでインストールしたらバージョンが古かったので、以下の記事を参考にして最新版にアップデートしました。
http://qiita.com/da1fujimoto/items/8f66accafb6b86bf8d56

$ sudo apt-get update
$ sudo apt-get install -y nodejs npm
$ node -v
v0.10.29
$ curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
$ sudo apt-get install -y nodejs
$ node -v
v6.9.4

作業用ディレクトリを作成して、npm installで必要なライブラリをインストールします。

$ mkdir -p work/drone
$ cd work/drone
$ npm install noble rolling-spider keypress

WARNがいくつか出ましたが、細かいことは気にしない強靭なメンタルで動作確認してみます。

$ sudo node find.js
------1台目:
 xxxxxxxxxxxx Mambo_XXXXXX
1: Mambo_XXXXXX (xxxxxxxxxxxx), RSSI -62

無事、デバイスを見つけることができました。
上記のUUIDに接続して、keypressイベントで操作。

$ sudo node app.js
Configured for Rolling Spider! Mambo_XXXXXX
Mambo_XXXXXX => SESSION START
got "keypress" => { name: 't',
  ctrl: false,
  meta: false,
  shift: false,
  sequence: 't' }
takeoff

飛びました!ヽ(=´▽`=)ノ

Leap Motionで操作した方がスタイリッシュなはずだ

Node.jsで接続できたのは良いけど、キーボード操作だけじゃ芸がないよなぁ・・・と考えていたとき、目に付いたのが、机の端に転がっていたLeap Motionです。
手の動きを検知したら、フライトコントローラには不可能な動きができるかもしれない。

Leap Motionの公式にも、ラズパイやParrot社のドローンと連携した事例が紹介されているので、利用には問題ないでしょう。
https://gallery.leapmotion.com/leap-motion-raspberry-pi-2/
https://gallery.leapmotion.com/cylon-js-parrot-ar-drone/

MacBookをWebSocket Serverとして使う

Leap Motionをラズパイに直接接続することはできないようで、結局MacBookが必要になりました。
以下のサイトを参考にして設定を行っています。
http://www.pentacreation.com/blog/2016/10/161008.html

ネットワークとしては、MacBookを有線でルータに繋いで、WiFiテザリングの設定にし、Leap MotionをUSB接続します。
ラズパイは有線接続なしで、MacBookのWiFiに接続、WiFi経由のWebSocketでLeap Motionにリモート接続しつつ、Bluetoothでドローンとペアリングします。

【2017/2/20 追記】
WiFiテザリングしなくても、同じWiFiルータに繋いで、MacBookのプライベートIPを指定すればOKでした。

Raspberry PiでLeap Motionのデータを利用する

ラズパイにleapjsを追加でnpm installします。

$ npm install leapjs

leapjsのAPIリファレンスを見ると、コンストラクタでWebSocket ServerのIPアドレスとポート番号を指定できるようになっており、接続先だけ変えればlocalhost接続時と同様に利用できます。
https://developer.leapmotion.com/documentation/javascript/api/Leap.Controller.html

gestureイベントをドローン制御に紐付ける実装で試してみます。

test.js
var RollingSpider = require("rolling-spider");
var Leap = require("leapjs");

var ACTIVE = true;
var d = new RollingSpider({uuid:"xxxxxxxxxxxx"});

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);
    });
});

var controller = new Leap.Controller({
    host: '[WebSocket ServerのIPアドレス]',
    port: 6437,
    //ラズパイではframeEventNameを無指定にした方がよい
    //frameEventName: 'deviceFrame',
    enableGestures: true
});

controller.connect();

controller.on('gesture', function (gesture) {
    switch (gesture.type) {
        case 'circle':
            onCircle(gesture);
            break;
        case 'swipe':
            onSwipe(gesture);
            break;
    }
});

function onCircle(gesture){
    if (gesture.state === 'stop') {
        console.log('circle => takeoff');
        d.takeOff();
    }
} 

function onSwipe(gesture){
    if (gesture.state === 'stop') {
        console.log('swipe => landing');
        d.land();
    }
} 

Leap Motionで飛ばしてみた

動画に撮りました。

ラズパイでNode.jsのプログラムを実行して、MacBookに接続されたLeap Motionのデータを取得、Bluetoothでドローンに命令を送っています。
指で宙に円を描くジェスチャーに何度か失敗したので、あまりスタイリッシュには見えないかも。

っていうか、急に飛ぶからビックリした(´゚д゚`)

【2017/2/20 追記】
急に飛んだように見えたのは、ジェスチャーの問題ではなく、ラグが発生していました。
frameEventNameの設定を'animationFrame(60fps)'にするとラズパイのCPUでは処理が追い付かず、'deviceFrame(処理能力に応じたfps)'にしていたのですが、この設定だと大きなラグが出ることがあります。
結果として、いずれも指定せずに接続すると反応速度が改善しました。

まとめ

察しの良い方はお気付きと思いますが、お使いのPCがBluetooth 4.0に対応していれば、Node.jsで完結するので、Leap Motionでドローンを操作するのにラズパイは要らないです。
とはいえ、ラズパイでBluetoothやWebSocketを扱う方法がわかったので、無駄ではないと信じたい。

今回は疎通確認を目的に、gestureイベントで簡単に実装しましたが、フレームごとの手の動きにドローンを追従させるようチューニングを行って、もっと自在に飛ばせるようにしたいです。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away