Processingで超簡単にAR.Droneの制御プログラムが作れちゃいます!

2010年9月16日,そいつは日本にやってきた.4つのローターを備え,空を縦横無尽に駆け巡る. 前面にカメラを備え,カメラからのリアルタイムの映像は,まるでそれに乗っているかのような感覚にさえ陥れる. 高い操縦性と安定性を備え操縦者を虜にする.そう,それはAR.Drone.近未来のマシーン.

ARDroneForP5は,AR.Droneのソフトウェアをより簡単にプログラミングできるようにするために作られたライブラリです. Processingを通して,AR.Droneの操縦や,カメラ情報やセンサ情報の取得が簡単にできるようになっています. このライブラリを使ってクリエイターやアーティストの方々が何か面白いものを作ってくださればとても嬉しいです.

ここではARDroneForP5を配布し,その機能と使い方を紹介します.

ENGLISH PAGE IS HERE.
 吉田 成朗 (公開:2011年02月26日/最終更新:2011年6月21日)

目次

AR.Droneとは

フランスのParrot社が開発・販売しているiPhone,iPad,iPod touchから操作できる4翼のヘリコプターです. 無線LANを使い,アドホック通信して操縦し,屋内でも屋外でも飛ばして遊ぶことができます. 操作はシンプル.プロポみたいに複雑な操作方法ではなく,iPhoneを傾けて操作できます. さらに標準でカメラが2つ(前面と腹面)ついており,そのカメラを通して操縦中にAR.Droneからの視点が楽しめます.



これがAR.Droneだ!!

AR.Droneは無線LAN通信なので,PCからも操縦することができます. また,センサ類が充実していて,ジャイロセンサ(2軸(X,Y)と1軸(Z)),三軸加速度センサ,超音波センサが搭載されています. APIを通してこれらのセンサ情報から,高度と,x・y方向速度,ピッチ・ロール・ヨー角を取得することが出来ます.

そして,AR(Augmented Reality,拡張現実感)の名前は伊達ではありません.ARこそがこのヘリコプターの見せどころです. iPhoneアプリとしてARを使ったゲームが提供されており, ARを使った他のAR.Droneとの空中戦や追跡ゲームが楽しめます. また,提供されているSDKを使ってAR.Droneを使った独自のARアプリを開発をすることも可能なのです.

なんと,これが,Amazonで3万円ぐらいで購入できちゃいます(2011年2月26日現在).



iPhoneでの操作画面

AR.Droneのプログラミング環境

AR.DroneにはParrot社から提供されているSDKがあり,PC用とiPhone用のプログラムを作ることが出来ます(工学ナビのブログ参照). しかし,橋本さんがこちらで述べているように,SDKの中のソースはなかなか癖があり, プログラミング初心者(私も含め)には読めたもんじゃありません. とても初心者が簡単にAR.Droneをいじれるような状況ではありません. そこで・・・

Processing用AR.Droneライブラリ ARDroneForP5

ARDroneForP5はProcessingで使えるAR.Drone制御ライブラリです. ARDroneForP5の「P5」はProcessingの別表記「Proce55ing」に由来します. このライブラリを使うことによりProcessing上で簡単にAR.Droneを操縦したり, センサ情報を取得したり,さらにはカメラ映像まで取得できちゃいます. 以下で詳しく説明したいと思います.


Processingとは

Processingは初心者でも簡単に扱えるプログラミング環境です. ビジュアライズに優れており,簡単にグラフィックをプログラミングできたり, 画像,音声,シリアル通信,ビデオ入出力なども簡単に扱え,サンプルも豊富です. また,メディアアート系での実績が多く,プロトタイピングにも使われていたりします. もちろんオープンソースで,MacやWindows,Linuxから使えます. Processingを使ってこんなのが作れちゃいます.


動作環境

Mac(OSX),Windows,LinuxなどのProcessingが動いている環境であれば, ダウンロードしたjarファイルを追加すればすぐに使えます. Processingのダウンロードはこちらの公式サイトから. AR.Droneのfirmwareは1.6.6で動作しているのを確認しています.(2011年6月21日現在)


ダウンロード

ARDroneForP5は以下のリンクからダウンロードしてください.

 https://github.com/shigeodayo/ARDroneForP5

接続方法

AR.Droneへの接続は,AR.Droneにバッテリーを装填した状態で,PCの無線LANの接続先を"ardrone_******"にすればOKです.



例:Macだとこんな感じ


起動方法

ファイルをダウンロードしたら解凍して,出てきたフォルダを適当な場所に移動してください. sketchesフォルダ以下にARDroneForP5_Sampleというスケッチがありますので, それをProcessingで開いて実行してください.そうすると,以下のような画面が表示されます.



Processingでスケッチを開く
   

実行画面



起動

フラ

フラ

こんな感じで操作します

このサンプルでは,このようなキー操作になっています. あと,画面に,AR.Droneのカメラ視点と,AR.Droneのピッチ角・ロール角・ヨー角・高度,x方向速度・y方向速度,バッテリー残量を表示しています.


shiftキー離陸
ctrlキー着陸
↑キー前方向に移動
↓キー後方向に移動
→キー右方向に移動
←キー左方向に移動
Sキー停止
Uキー上昇
Dキー下降
Lキー左方向回転(CCW)
Rキー右方向回転(CW)
1キー前方向カメラからの視点
2キー前方向カメラ(主)+腹部カメラの視点(左上)
3キー腹部カメラの視点
4キー腹部カメラ(主)+前方向カメラの視点(左上)
5キーカメラの切り替え


サンプルプログラム

	import com.shigeodayo.ardrone.manager.*;
	import com.shigeodayo.ardrone.navdata.*;
	import com.shigeodayo.ardrone.utils.*;
	import com.shigeodayo.ardrone.processing.*;
	import com.shigeodayo.ardrone.command.*;
	import com.shigeodayo.ardrone.*;
	
	ARDroneForP5 ardrone;
	
	void setup(){
	  size(320, 240);
	  
	  ardrone=new ARDroneForP5("192.168.1.1");
	  ardrone.connect();       // AR.Droneに接続,操縦するために必要
	  ardrone.connectNav();    // AR.Droneからのセンサ情報を取得するために必要
	  ardrone.connectVideo();  // AR.Droneからの画像情報を取得するために必要
	  ardrone.start();         // これを宣言すると上でconnectした3つが使えるようになる
	}
	
	void draw(){
	  background(204);  
	
	  // AR.Droneからの画像を取得
	  PImage ardrone.getVideoImage(false);
	
	  if (img==null)
	    return;
	  image(img, 0, 0);
	
	  // AR.Droneからのセンサ情報を標準出力する.
	  // ardrone.printARDroneInfo();
	
	  // 各種センサ情報を取得する
	  float pitch=ardrone.getPitch();
	  float roll=ardrone.getRoll();
	  float yaw=ardrone.getYaw();
	  float altitude=ardrone.getAltitude();
	  float[] velocity=ardrone.getVelocity();
	  int battery=ardrone.getBatteryPercentage();  
	  String attitude="pitch:"+pitch+"\nroll:"+roll+"\nyaw:"+yaw+"\naltitude:"+altitude;
	  text(attitude, 20, 85);
	  String vel="vx:"+velocity[0]+"\nvy:"+velocity[1];
	  text(vel, 20, 140);
	  String bat="battery:"+battery+" %";
	  text(bat, 20, 170);
	}
	
	// PCのキーに応じてAR.Droneを操作できる.
	void keyPressed(){
	  if(key==CODED){
	    if(keyCode==UP){
	      ardrone.forward(); // 前
	    } else if (keyCode==DOWN){
	      ardrone.backward(); // 後
	    } else if (keyCode==LEFT){
	      ardrone.goLeft(); // 左
	    } else if (keyCode==RIGHT){
	      ardrone.goRight(); // 右
	    } else if (keyCode==SHIFT){
	      ardrone.takeOff(); // 離陸,離陸した状態でないと移動は出来ない.
	    } else if (keyCode==CONTROL){
	      ardrone.landing(); // 着陸
	    }
	  }else{
	    if (key=='s'){
	      ardrone.stop(); // 停止
	    } else if (key=='r'){
	     ardrone.spinRight();  // 右方向に回転
	    } else if (key=='l'){
	      ardrone.spinLeft(); // 左方向に回転
	    } else if (key=='u'){
	      ardrone.up(); // 上昇
	    } else if (key=='d'){
	      ardrone.down(); // 下降
	    } else if (key=='1'){
	      ardrone.setHorizontalCamera(); // 前カメラ
	    } else if (key=='2'){
	      ardrone.setHorizontalCameraWithVertical(); // 前カメラとお腹カメラ
	    } else if (key=='3'){
	      ardrone.setVerticalCamera(); // お腹カメラ
	    } else if (key=='4'){
	      ardrone.setVerticalCameraWithHorizontal(); // お腹カメラと前カメラ
	    } else if (key=='5'){
	      ardrone.toggleCamera(); // 次のカメラ
	    }
	  }
	}

新しくコードを書くとき

Processingを起動して,Sketch->Add File...からARDroneForP5/library/の"ARDroneForP5.jar"を追加してください.





そうすると,自動的にスケッチのあるフォルダにcodeフォルダができその中に"ARDroneForP5.jar"が追加されます.



これで,ProcessingからAR.Droneが使えるようになります.


今できないこと

応用例

Processingの他のライブラリと組み合わせればこのようなことも簡単にできます.


ARToolKitとの連携

nyatlaさんのNyAR4psgと連携させてみました. このサンプルはカメラ画像からARマーカ(Hiro)を検出して,マーカの上に立方体を重畳します. ここから発展させればARシューティングゲームも作れそうです.



前面カメラからAR

腹面カメラからAR

ARマーカ

実際に飛ばしている様子

プログラムを作成・実行するには,NyAR4psgを入手してください. NyAR2.jarとNyARToolkit.jarをスケッチにadd Fileして, camera_para.datとpatt.hiro(NyAR4psgに同梱されているカメラパラメータファイルとパターンファイル)を 作成したスケッチ(*.pde)が入っているディレクトリの中に入れてください. MQOLoaderで3Dモデルを表示してみるのも楽しいかもしれません.


Kinectとの連携

Processing用のKinectライブラリとも連携させてみました. ある深さ領域にある物体(手)をトラッキングして,画面左にあればAR.Droneが左に,画面右にあれば右に,画面上にあれば上に,画面下にあれば下に,Kinectに近づくと前に,Kinectから遠ざかると後ろに進むようにしました. ちなみにこのコードは一時間くらいで作りました.



AR.Droneからの視点.手の動き(画面の丸い点)に合わせてAR.Droneが動きます


Kinectの距離画像


こんな感じで操作します

プログラムの作成・実行には,Processing用のKinectライブラリを入手してください. openkinect.jarとlibKinect.jnilibをスケッチにadd Fileして, KinectTracker.pde(KinectライブラリのサンプルプログラムAveragePointTrackingの中に入っているpdeファイル)を 作成したスケッチ(*.pde)と同じディレクトリに入れてください.


サンプル

ARDroneForP5には以下の4つのサンプルが同梱されています(sketchesの中).

各ライブラリは以下のリンクからダウンロードして下さい.

API

//constructor
ARDroneForP5()
-一番最初に呼ぶ.

ARDroneForP5(String)
-一番最初に呼ぶ.引数で特定のIPアドレスを渡せる.

//public method
boolean connect()
-AR.Droneに接続する.
戻り値
true:接続成功
false:接続失敗

boolean connectVideo()
-AR.Droneからカメラ映像を取得する.
戻り値
true:接続成功
false:接続失敗

boolean void connectNav()
-AR.Droneからセンサ情報を取得する.
return
true:接続成功
false:接続失敗

float getPitch()
-AR.Droneのピッチ角を返す.事前にconnectNavする必要がある.

float getRoll()
-AR.Droneのロール角を返す.事前にconnectNavする必要がある.

float getYaw()
-AR.Droneのヨー角を返す.事前にconnectNavする必要がある.

float getAltitude()
-AR.Droneの高度を返す.事前にconnectNavする必要がある.

float[] getVelocity()
-AR.Droneのx方向,y方向速度(0:vx,1:vy)を返す.事前にconnectNavする必要がある.

int getBatteryPercentage()
-AR.Droneのバッテリー残量を返す.0-100%.事前にconnectNavする必要がある.

void printARDroneInfo()
-AR.Droneのセンサ情報やバッテリー残量を標準出力する.

PImage getvideoImage(boolean)
-AR.Droneのカメラ画像を取得.引数がtrueの場合は320x240に自動的に画像サイズを変更.falseの場合はそのまま.

void setHorizontalCamera()
-取得画像をAR.Droneの正面カメラに設定 (320x240).

void setVerticalCamera()
-取得画像をAR.Droneからのお腹カメラに設定 (176x144).

void setHorizontalCameraWithVertical()
-取得画像をAR.Droneからの正面カメラ(大)とお腹カメラ(小)に設定.

void setVerticalCameraWithHorizontal()
-取得画像をAR.Droneからのお腹カメラ(大)と正面カメラ(小)に設定.

void toggleCamera()
-カメラを切り替える.

void disconnect()
-AR.Droneとの接続を解除する.

void start()
-AR.Droneの制御を開始する.事前に,connect, connectNav(必要に応じて), connectVideo(必要に応じて)を呼ぶ必要がある.

void landing()
-AR.Droneを着陸させる.

void takeOff()
-AR.Droneを離陸させる.

void backward()
-AR.Droneを後進させる.

void backward(int)
-AR.Droneを特定のスピードで後進させる.

void forward()
-AR.Droneを前進させる.

void forawd(int)
-AR.Droneを特定のスピードで前進させる.

void spinLeft()
-AR.Droneを左回転させる. (CCW)

void spinLeft(int)
-AR.Droneを特定のスピードで左回転させる.(CCW)

void spinRight()
-AR.Droneを右回転させる. (CW)

void spinRight(int)
-AR.Droneを特定のスピードで右回転させる. (CW)

void stop()
-AR.Droneをホバリングさせる(停止させる).

int getSpeed()
-AR.Droneの現在の移動スピードを返す.(0-100%)

void setSpeed(int)
-AR.Droneの移動スピードを設定する. (0-100%)

void down()
-AR.Droneを下降させる

void down(int)
-AR.Droneを特定のスピードで下降させる.

void up()
-AR.Droneを上昇させる.

void up(int)
-AR.Droneを特定のスピードで上昇させる.

void goLeft()
-AR.Droneを左に動かす.

void goLeft(int)
-AR.Droneを特定のスピードで左に動かす.

void goRight()
-AR.Droneを右に動かす.

void goRight(int)
-AR.Droneを特定のスピードで右に動かす.

void reset()
-AR.Droneの緊急停止させる.

void setMaxAltitude(int)
-AR.Droneの高度を指定した値以上にならないようにする.

void setMinAltitude(int)
-AR.Droneの高度を指定した値以下にならないようにする.

謝辞

最初,ライブラリとして配布するつもりは無かったのですが,橋本さんの「you,発表しなよ!」というお声とともに, さまざまなサポートをしてくださり,さらには工学ナビの一つの記事として発表できたことに本当に感謝しております.橋本直さん,ありがとうございます.

あの人研の方々,開発のためにAR.Droneを使わせてくださりありがとうござます. 暖かく開発を見守ってくださったことに感謝いたします.

また,このライブラリを作成する際に,ARDrone API フォーラムをいつも見ていました.有益な情報ありがとうございます.
操縦部分の実装はMAPGPSさんのソースを参考にさせていただきました. Videoキャプチャの部分の実装は,daniel schmidtさんとIan Hartneyさんのソースを参考にさせていただきました. センサ情報のキャプチャの部分の実装はCliff Biffleさんのソースを参考にさせていただきました.みなさま,ありがとうございました.

東京大学工学系研究科 航空宇宙工学専攻知能工学研究室(堀・赤石研究室)の皆様にも開発に協力していただきました.ありがとうございます.


実験の様子.廊下でうるさくしてごめんなさい

ゲストライタ プロフィール

吉田成朗 (Twitter:@shigeodayo
東京大学工学部機械情報工学科 4年 廣瀬・谷川研究室 所属
JST ERATO 五十嵐デザインインタフェースプロジェクト 研究補助員
富山商船高等専門学校 情報工学科卒 (現 富山高等専門学校 射水キャンパス)
(※プロフィールは2011年6月21日現在のものです)

まだまだ未熟者ですがよろしくお願いします.