デザイン会社 btrax > Freshtrax > ドローンをハック!Swiftで...
ドローンをハック!SwiftでiPhoneの専用コントローラをプログラミングしてみよう
ドローンと言えば今最も注目を集めるテクノロジーの1つだ。Amazon.comがドローンを宅配システムに使う実験をしているし、空撮や測量用のドローンのサービスを提供するスタートアップも誕生している。今後、様々なところでドローンの利用が進んでいくだろう。
一方で、首相官邸にドローンが落下するなどの事件が起こり、日本では危険という印象も強いと聞く。2015年12月には、アメリカ連邦航空局(FAA)はドローン(約250g以上)を所有者に登録を義務づける制度を発表した。このような法規制は徐々に進んで行くだろう。
ラジコン飛行機とは違う
ラジコンとどう違うの?という疑問を持つ人も多い。ドローンに空撮用の小型カメラを取り付けて、ラジコンと同じような形のコントローラーから操作するだけでは、正直ラジコンとの違いもよくわからない。
しかし、ドローンはセンサ、カメラを駆使して自律飛行ができたり、プログラミングを組んで操作できるという特徴があり、コンピュータが空を飛んでいると言った方が正しい。今回は、この空飛ぶコンピュータを操作するオリジナルのiPhoneアプリを作ってみよう。
高性能手のひらドローン パロット ミニ ドローン エアボーン ナイト
今回使用したのは、パロット ミニ ドローン エアボーン ナイト (Parrot Airborne Night MiniDrone)というドローン。手のひらに乗る小型で、重さはわずか60gほど。 15,000円前後で買える安価なドローンだ。飛行の安定性は高く、iPhoneやAndroidのアプリから簡単に操作することができる。日本でも購入できるようだ。
実は、Parrotのドローンは、SDKが提供されており、簡単にプログラミングすることができる。自分だけのオリジナルのiPhoneコントローラアプリを作ることはもちろん、IoTと連携させたり、ラズベリーパイなどを使って専用のコントローラを作ることや、Webブラウザから操作するなど様々なことが可能になる。しかも、制御プログラムはいたって簡単に書ける。4つの羽を制御するプログラムを書く必要はもちろんなく、離陸、着陸、回転、前進などの簡単な命令を実行するだけでドローンを思うように動かすことができる。今回は、まずiPhoneからドローンを制御して、ジェスチャーで飛ばしてみよう。
作るのはジェスチャーコントロールが可能なシンプルドローンコントローラ
FreeFlight3というアプリを使って操作できるのだが、左の円で左右の回転と上下の移動、右の円で前後左右の移動を行うため、操作が少し難しい。羽を4つ持つクアッドコプターは、前後左右という概念はその原理上はなく、360度、真後ろにも進むことができる。
そこで今回は、
・離陸(take off)
・着陸(land)
・宙返り(flip)
だけを行うことができるコントローラを作る。iPhoneを縦に振り上げると、宙返り(flip)する機能を実装した。
プロジェクトの作成
XCodeを開き、新しいプロジェクトを作成する。テンプレートは、Single View Applicationで構わない。
SDKのダウンロード
Parrotが提供しているチュートリアルに沿って進めていく。まず、SDKをダウンロードする。この記事の執筆段階では、Version 3.7.5だ。
SDK version 3.7.5 frameworks というリンクをクリックして、SDKをダウンロードする。ZIPファイルを解凍して、すべてのFrameworkをプロジェクト内にコピーするのだが、その後にuthashとmavlinkを削除する。この時、ゴミ箱に移動するのではなく、Remove Referenceを選択してほしい。
試しにビルドしようとしても、以下のようなエラーが出てビルドができない場合がある。これは、ParrotのフレームワークがBitcodeに対応していないためだ。Build Settings から Enable Bitcode を Noにすれば良い。これでSDKを使う準備は整った。
ld: '<プロジェクトのパス>/ARSDK3_iOS_3_7_5/libARDiscovery.framework/libARDiscovery(ARDISCOVERY_BonjourDiscovery.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture armv7 clang: error: linker command failed with exit code 1 (use -v to see invocation)
近くのドローンを見つける
早速近くのドローンを見つけるプログラムを書いてみよう。チュートリアルはObjective-Cで書かれているが、可読性を高めるためになるべくSwiftで書いていく。ライブラリもObjective-Cなので、Bridging-Header.hを作成して、swiftからObjective-Cのソースコードを呼べるようにする。
#import <libARDiscovery/ARDISCOVERY_BonjourDiscovery.h> #import <libARDiscovery/ARDISCOVERY_Device.h>
ドローンを探すコードは、以下のように簡単に書ける。BLEでデバイスを見つけた時に、discoveryDidUpdateServicesが呼ばれる。複数台のドローンが周囲にある時には、複数台の情報を取得できる。
class ViewController: UIViewController { override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) registerReceivers() startDiscovery() } func startDiscovery() { ARDiscovery.sharedInstance().start() } func registerReceivers() { NSNotificationCenter.defaultCenter().addObserver( self, selector: Selector("discoveryDidUpdateServices:"), name: kARDiscoveryNotificationServicesDevicesListUpdated, object: nil ) } func discoveryDidUpdateServices(notification: NSNotification) { if let userInfo = notification.userInfo { let deviceList = userInfo[kARDiscoveryServicesList] // デバイスを発見したら呼ばれる print(deviceList) } } }
お作法として、ViewControllerが非表示になるタイミングでレシーバーを解除する。
class ViewController: UIViewController { .... (中略) .... override func viewDidDisappear(animated: Bool) { super.viewDidDisappear(animated) unregisterReceivers() stopDiscovery() } func unregisterReceivers() { NSNotificationCenter.defaultCenter().removeObserver(self, name: kARDiscoveryNotificationServicesDevicesListUpdated, object: nil) } func stopDiscovery() { ARDiscovery.sharedInstance().stop() } }
この状態で実機にビルドしてドローンに電池を入れると、10秒ほどでドローンを検知し、以下のようなログが出力される。
2015-12-14 16:57:59.531 drone-tutorial[1107:339869] New device Blaze_012778 Optional(( "<ARService: 0x15d8d6e0>" ))
ドローンへ接続
デバイスを発見した後に、ドローンに接続する。
サンプルコードも、チュートリアルも記述がObjective-Cで、メモリのアクセスを多用しているので、swiftに直すのが面倒だ。そこで、Drone用のクラスをDTDroneをObjective-Cで作り、ViewControllerから呼び出すことにする。
Swiftから呼び出せるように、DTDrone.hをBridging-Headerに追加する。
#import <libARDiscovery/ARDISCOVERY_BonjourDiscovery.h> #import <libARDiscovery/ARDISCOVERY_Device.h> #import "DTDrone.h"
簡単のため、見つかったデバイスの1台目に自動的に接続することにする。
class ViewController: UIViewController { var isConnected = false ....(中略).... func discoveryDidUpdateServices(notification: NSNotification) { if let userInfo = notification.userInfo { let deviceList = userInfo[kARDiscoveryServicesList] // 未接続状態なら、1つ目のデバイスに接続する if isConnected == false { let serviceList = deviceList as! [ARService] isConnected = DTDrone.sharedInstance().connectWithService(serviceList[0]) } } } ....(中略).... }
ドローンを見つけるまでは待機画面を表示させておき、ドローンを見つけた段階で、離陸、着陸、一回転のボタンを表示させることにした。
ドローンを飛ばす
デバイスに接続すると、ドローンを操作できるようになる。以下のコードをボタンタップなどのイベントで呼び出せば良い。
DTDrone.sharedInstance().takeoff() // 離陸 DTDrone.sharedInstance().land() // 着陸 DTDrone.sharedInstance().flip() // 一回転
デバイスに接続できた時点で、TakeOffやLandのボタンを表示するようにする。ドローンに接続した状態で、TakeOffのメソッドを呼び出すとDroneが離陸する。その後、Landのメソッドを呼び出すと着陸する。これで、離陸と着陸、宙返りだけできるコントローラが完成した。
ジェスチャーで操作する
ここまでこれば分かるが、iOSのAPIから取得したイベントや、他のシステムと連携してドローンを動かすことも簡単だ。そこで、ジェスチャーでドローンを操作してみよう。
iOSを振り上げるとフリップを決めてみよう。加速度を取得し、z方向の加速度の絶対値が一定以上になった時にFlipのメソッドを呼び出す。
class ViewController: UIViewController { .... (中略) ... override func viewDidAppear(animated: Bool) { .... (中略) ... motionManager.accelerometerUpdateInterval = 0.1 let accelerometerHandler:CMAccelerometerHandler = { (data: CMAccelerometerData?, error: NSError?) -> Void in if self.succeeded && abs(data!.acceleration.z) > 3.5 { DTDrone.sharedInstance().flip() } } motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue.currentQueue()!, withHandler: accelerometerHandler) }
たった1万5千円程度の安価なドローンでも、簡単なコードで制御することができる。今回はiPhoneアプリから制御したが、画像認識と組み合わせたり、インターネット上のシステムと連携させたりと、いろいろなことができる。ぜひドローンを買って遊んでみてほしい。なお、ドローンの一回転のアクションは、墜落してそのままドローンが壊れてしまうことがあるので、あまり多用しないでください。
ソースコードはこちら
【イベント開催!】Beyond Borders: Japan Market Success for Global Companies
日本市場特有のビジネス慣習や顧客ニーズ、効果的なローカライゼーション戦略について、実際に日本進出を成功に導いたリーダーたちが、具体的な事例とノウハウを交えながら解説いたします。市場参入の準備から事業拡大まで、実践的なアドバイスと成功の鍵をお届けします。
■開催日時:
日本時間:2024年12月6日(金)9:00
米国時間:12月5日(木)16:00 PST / 19:00 EST
*このイベントはサンフランシスコで開催します。
■参加方法
- オンライン参加(こちらよりご登録いただけます。)
- 会場参加(限定席数) *サンフランシスコでの会場参加をご希望の方は下記までお申し込みまたはご連絡ください。(会場収容の関係上、ご希望に添えない場合がございます。予めご了承ください。)
- 対面申し込み:luma
- Email(英語):sf@btrax.com
世界有数の市場規模を誇る日本でのビジネス展開に向けて、貴重な学びの機会となりましたら幸いです。皆様のご参加を心よりお待ち申し上げております。