ARDroneSDK3 API Reference日本語版について
このページは ARDroneSDK3 API Referenceの著作者であるフランス Parrot S.A 社様の許諾を得て日本語に翻訳したものです。
原本の ARSDKのドキュメント『ARDroneSDK3 API Reference』は BSD 3-Clause "New" or "Revised" のライセンス下での使用が許可されています。したがいまして翻訳文章の使用や運用についてはライセンスに準じます。日本語で記載された文章の品質ついて Parrot S.A社は関知いたしません。
本翻訳文章には訳抜け、誤訳が含まれる可能性があります。
本翻訳文章の使用や運用により万が一、人身、ハードウェア機器若しくはデータ等に損害が生じた場合でも、弊社及び関係会社は一切その責任を負いません。
本ページである ARDroneSDK 日本語版は株式会社車輪の再発見の二次的著作物となり出版等物での利用、ネットでの利用や引用は弊社及びParrot S.A社の許諾が必要となる場合があります。
上記に同意いただける方のみご利用ください。
原文のリファレンスと対比しやすいようにサイトのレイアウトを踏襲させていただきました。
更新日 2017/08/06 株式会社車輪の再発見 http://www.rediscovery.co.jp/
概要(General information)
このSDKは、ドローンとの接続、操縦、ストリーム動画の受信、保存、メディア(写真、ビデオ)のダウンロード、オートパイロットプランの送信と実行、ドローンのアップデートが行えます。RollinSpider、Cargos、Mambo、Swing、JumpingSumo、JumpingSumoEvos、BebopDrone、Bebop2、Disco、SkyController、SkyController2で利用可能です。
公式アプリFreeFlight3では、このSDKを使っています。
SDKは主にCで書かれており、Unix、android、iOS用のライブラリを提供します。
ドローンシミュレータのSphinxも同梱されています。これは、実際のドローンを飛行させる前にアプリをテストするためのものです。Sphinxの情報(インストール、ユーザーマニュアル、アプリケーションノート)はこちらから入手できます。
使い方(How to use)
プロジェクトの作成(Creating a project)
このSDKを使うには、プロジェクトにライブラリを追加します。ライブラリは、リリース済みのものダウンロードするか、ソースコードをビルドするかしてください。(SDKのビルドの方法参照)
iOS
- iOSバイナリをダウンロードします SDK version 3.12.6 iOS libs
- zipを解凍します。
- XCodeのプロジェクトナビゲーターでプロジェクトをクリックします。次にターゲットをクリックし、最後にビルド設定をクリックします。
ヘッダーサーチパスに、iOSシミュレータSDK、iOS SDKアーキテクチャ(デバッグとリリース)を加えます。
そして、このアーキテクチャに以下を入力します。
シミュレータ SDK:PATH_TO_THE_UNZIPPED_FOLDER/arsdk-ios_sim/staging/usr/include
iOS SDK:PATH_TO_THE_UNZIPPED_FOLDER/arsdk-ios/staging/usr/include
ライブラリサーチパスに、iOSシミュレータSDK、iOS SDKアーキテクチャ(デバッグとリリース)を加えます。
そして、このアーキテクチャに以下を入力します。
シミュレータ SDK:PATH_TO_THE_UNZIPPED_FOLDER/arsdk-ios_sim/staging/usr/lib
iOS SDK:PATH_TO_THE_UNZIPPED_FOLDER/arsdk-ios/staging/usr/lib
- その他のリンカー・フラッグに以下を追加します。
-larcommands -larcontroller -lardiscoverywithouteacc -larnetwork -larnetworkal -larsal -larstream -larstream2 -larmavlink -ljson -larmedia -larutils -lcurl -lardatatransfer -lmux -lpomp -lcrypto -lssl -lz
注意: SkyController2に適合させたい場合は、-lardiscoverywithouteaccを-lardiscoveryに置き換え、ExternalAccessoryフレームワークをインクルードする必要があります。このフレームワークは、アプリ申請に影響します。 (こちらを参照) -
準備完了です!
Android
- app build.gradleファイルを開きます。
- dependenciesに以下の行を追加します。
compile 'com.parrot:arsdk:3.12.6'
- ネイティブライブラリをロードします(右のコードを参照)。
ネイティブライブラリをロードする。
// Not needed in Objective C
準備完了です!さあ、コーディングをはじめましょう !
サンプルを使う(Use samples)
このSDKでどんなことができるかを理解するためには、我々の提供するサンプルコードをざっと見て、使ってみることからはじめるのが良いでしょう。
サンプルリポジトリをクローン化します。
git clone https://github.com/Parrot-Developers/Samples.git
iOS用に一つ、Android用に一つ、Unix用にいくつかのサンプルがあります。
モバイル用のサンプルは、以下のようなアーキテクチャを使用しています。
これらは、スタンドアローンとなっています。つまり、サンプルリポジトリをクローン化したら、SDKをコンパイルせずに使用できます。これを実現するために、プレコンパイルされたSDKが使われます。
モバイル用サンプルでは、ドローンとの接続、操縦、写真撮影、ビデオストリームの表示(可能な場合)、ドローンからのメディアのダウンロードが学べます。
以下のドローンがサポートされます。
- Bebop 2(ビバップ2)
- Bebop (ビバップ)
- JumpingSumo (ジャンピング・スモー)
- Jumping Race(ジャンピング・レース)
- Jumping Night(ジャンピング・ナイト)
- MiniDrone Rolling Spider(ミニドローン ローリングスパイダー)
- Airborne Cargo(エアボーン・カーゴ)
- Airborne Night(エアボーン・ナイト)
- Swing(スィング)
- Mambo(マンボ)
そしてリモートコントローラー
- SkyController(スカイコントローラー)
- SkyController 2(スカイコントローラー2)
もし、BebopDroneのみに対応したアプリを作成したいのであれば 以下のファイル以外を削除してください。
- DeviceListActivity
- DroneDiscoverer
- BebopActivity
- BebopVideoView
- BebopDrone
- SDCardModule
前にも書いたように、それぞれのモバイルサンプルはSDKをビルドすることなく利用可能です(プレコンパイルされたライブラリを使います)。あなた自身でコンパイルしたSDKとともにサンプルを使うこともできます。
iOS
プレコンパイルされたSDKを使う(Github上でホストされている):
プレコンパイルされたライブラリを使う場合、buildWithPrecompiledSDKコンフィグレーションを使います(Product->Scheme->Edit Scheme)。
プレコンパイルされたSDKを初めて使ってビルドする時には、Githubからライブラリをダウンロードするので、少し時間がかかる点に注意してください。
あなた自身でコンパイルしたSDKを使う:
このサンプルをAlchemyでビルドすることができます。あなたの
iOS:./build.sh -p arsdk-ios -t build-sample -j
iOSシミュレータ: ./build.sh -p arsdk-ios_sim -t build-sample -j
もしXCodeから直接ビルドするのであれば、あなたがローカルでコンパイルしたライブラリを使うために、buildWithLocalSDKコンフィグレーションを使います(あなた自身のSDKを初めてコンパイルする場合、より詳細にを参照してください)。
そして、XCodeの中であなたがコンパイルしたばかりのSDKライブラリを使うためにbuildWithLocalSDKを使います。(Product->Scheme->Edit Scheme)
iOSのサンプルには、SDKSampleとSDKSampleForSkyController2の二つのターゲットがあることに注意してください。前者は「その他のリンカー・フラッグ」リストの中で-lardiscoverywithouteacc使っており、ExternalAccessoryフレームワークをインクルードしていません。しかし、SDKSampleForSkyController2では、-lardiscoveryを使っており、ExternalAccessoryをインクルードしています。
Android
プレコンパイルされたSDKを使う(JCenterでホストされている):
Android StudioでSDKSample/buildWithPrecompiledSDK
にあるsettings.gradle located を開く。
あなた自身でコンパイルしたSDKを使う:
このサンプルをAlchemyでビルドすることもできます。ご使用の <SDK>
で下記のコマンドを実行してください。
./build.sh -p arsdk-android -t build-sample
あるいは、Android Studioビルドを使うのであれば、 <SDK>
で最初に以下のコマンドを実行してください。
./build.sh -p arsdk-android -t build-jni
そして、Android Studioで SDKSample/buildWithLocalSDK
にあるsettings.gradleを開きます。
コーディングの開始(Start coding)
ここでは、BebopDroneをコントロールするためにどのようにSDKを使うかを紹介します。
ドローンを見つける(Discover the drones)
まず最初に、あなたのまわりにあるドローンを見つける必要があります。これには、libARDiscoveryを使います。
探索の開始
#import <libARDiscovery/ARDISCOVERY_BonjourDiscovery.h>
- (void)startDiscovery
{
[[ARDiscovery sharedInstance] start];
}
libARDiscoveryは、ネットワーク上でBLEやWifi機器が見つかった時に通知します。
- (void)registerReceivers
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(discoveryDidUpdateServices:) name:kARDiscoveryNotificationServicesDevicesListUpdated object:nil];
}
- (void)discoveryDidUpdateServices:(NSNotification *)notification
{
NSArray *deviceList = [[notification userInfo] objectForKey:kARDiscoveryServicesList];
// Do what you want with the device list (deviceList is an array of ARService*)
}
利用したいARServiceを入手したら、それをARDiscoveryDeviceに変換します (次のステップ)で必要となります。
// this should be called in background
- (ARDISCOVERY_Device_t *)createDiscoveryDeviceWithService:(ARService*)service
{
ARDISCOVERY_Device_t *device = NULL;
eARDISCOVERY_ERROR errorDiscovery = ARDISCOVERY_OK;
device = [service createDevice:&errorDiscovery];
if (errorDiscovery != ARDISCOVERY_OK)
NSLog(@"Discovery error :%s", ARDISCOVERY_Error_ToString(errorDiscovery));
return device;
}
全てをクリーンにします。
- (void)unregisterReceivers
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:kARDiscoveryNotificationServicesDevicesListUpdated object:nil];
}
- (void)stopDiscovery
{
[[ARDiscovery sharedInstance] stop];
}
デバイスコントローラーのセットアップ(SETUP A DEVICE CONTROLLER)
デバイスコントローラーは、ドローンとあなたの間のインターフェイスを構築するオブジェクトです。
デバイスコントローラーの 起動 後は、ドローンの全ての状況(ステート)と設定をコールバックによって送られてくるコマンドを通して受け取ることになります。
デバイス・コントローラーの作成
ARDISCOVERY_Device_t *discoveryDevice = [self createDiscoveryDeviceWithService:service];
eARCONTROLLER_ERROR error = ARCONTROLLER_OK;
ARCONTROLLER_Device_t *deviceController = ARCONTROLLER_Device_New (discoveryDevice, &error);
ステート変化のモニター
error = ARCONTROLLER_Device_AddStateChangedCallback(deviceController, stateChanged, (__bridge void *)(self));
// called when the state of the device controller has changed
void stateChanged (eARCONTROLLER_DEVICE_STATE newState, eARCONTROLLER_ERROR error, void *customData)
{
// SELF_TYPE is the class name of self
SELF_TYPE *selfCpy = (__bridge SELF_TYPE *)customData;
switch (newState)
{
case ARCONTROLLER_DEVICE_STATE_RUNNING:
break;
case ARCONTROLLER_DEVICE_STATE_STOPPED:
break;
case ARCONTROLLER_DEVICE_STATE_STARTING:
break;
case ARCONTROLLER_DEVICE_STATE_STOPPING:
break;
default:
break;
}
}
ドローンから送られてくるコマンドのモニター (例:バッテリーレベル)
error = ARCONTROLLER_Device_AddCommandReceivedCallback(deviceController, onCommandReceived, (__bridge void *)(self));
// called when a command has been received from the drone
void onCommandReceived (eARCONTROLLER_DICTIONARY_KEY commandKey, ARCONTROLLER_DICTIONARY_ELEMENT_t *elementDictionary, void *customData)
{
SELF_TYPE *selfCpy = (__bridge SELF_TYPE *)customData;
if (elementDictionary != NULL)
{
// if the command received is a battery state changed
if (commandKey == ARCONTROLLER_DICTIONARY_KEY_COMMON_COMMONSTATE_BATTERYSTATECHANGED)
{
ARCONTROLLER_DICTIONARY_ARG_t *arg = NULL;
ARCONTROLLER_DICTIONARY_ELEMENT_t *element = NULL;
// get the command received in the device controller
HASH_FIND_STR (elementDictionary, ARCONTROLLER_DICTIONARY_SINGLE_KEY, element);
if (element != NULL)
{
// get the value
HASH_FIND_STR (element->arguments, ARCONTROLLER_DICTIONARY_KEY_COMMON_COMMONSTATE_BATTERYSTATECHANGED_PERCENT, arg);
if (arg != NULL)
{
uint8_t batteryLevel = arg->value.U8;
// do what you want with the battery level
}
}
}
// else if (commandKey == THE COMMAND YOU ARE INTERESTED IN)
}
}
// if you want the stream to be MP4 compilant (needed if you decode with iOS hardware decoder)
error = ARCONTROLLER_Device_SetVideoStreamMP4Compliant(_deviceController, 1);
error = ARCONTROLLER_Device_SetVideoStreamCallbacks(_deviceController, configDecoderCallback, didReceiveFrameCallback, NULL , (__bridge void *)(self));
static eARCONTROLLER_ERROR configDecoderCallback (ARCONTROLLER_Stream_Codec_t codec, void *customData)
{
SELF_TYPE *selfCpy = (__bridge SELF_TYPE *)customData;
// configure your decoder
// return ARCONTROLLER_OK if configuration went well
// otherwise, return ARCONTROLLER_ERROR. In that case,
// configDecoderCallback will be called again
}
static eARCONTROLLER_ERROR didReceiveFrameCallback (ARCONTROLLER_Frame_t *frame, void *customData)
{
SELF_TYPE *selfCpy = (__bridge SELF_TYPE *)customData;
// display the frame
// return ARCONTROLLER_OK if display went well
// otherwise, return ARCONTROLLER_ERROR. In that case,
// configDecoderCallback will be called again
}
最後に、デバイス・コントローラーの起動(この後に、ARCONTROLLER_Device_AddStateChangedCallbackで設定したコールバックが呼び出されます)。.
error = ARCONTROLLER_Device_Start (deviceController);
if (error == ARCONTROLLER_OK)
{
_deviceController = deviceController;
}
ドローンのクリーンアップ
- (void)deleteDeviceController
{
// in background
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
eARCONTROLLER_ERROR error = ARCONTROLLER_OK;
// if the device controller is not stopped, stop it
eARCONTROLLER_DEVICE_STATE state = ARCONTROLLER_Device_GetState(_deviceController, &error);
if ((error == ARCONTROLLER_OK) && (state != ARCONTROLLER_DEVICE_STATE_STOPPED))
{
// after that, stateChanged should be called soon
error = ARCONTROLLER_Device_Stop (_deviceController);
if (error == ARCONTROLLER_OK)
{
dispatch_semaphore_wait(_stateSem, DISPATCH_TIME_FOREVER);
}
else
{
NSLog(@"- error:%s", ARCONTROLLER_Error_ToString(error));
}
}
// once the device controller is stopped, we can delete it
if (_deviceController != NULL)
{
ARCONTROLLER_Device_Delete(&_deviceController);
}
});
}
// dont forget to add dispatch_semaphore_signal(pilotingViewController.stateSem); in the case ARCONTROLLER_DEVICE_STATE_STOPPED of the stateChanged function
離陸(TAKING OFF)
ドローンを離陸させるためには、飛行ステータスが「着陸」であることを確認しなければなりません(着陸ステータスでない時にコマンドを送っても離陸は行いません)。
「離陸」コマンドを送ります。
これに対して、(離陸が実行されたなら)ドローンがステートが変わったことを通知します。「着陸」ステータス→「離陸」ステータス→「ホバリング」(もしくは「飛行」)ステータス
離陸
- (eARCOMMANDS_ARDRONE3_PILOTINGSTATE_FLYINGSTATECHANGED_STATE)getFlyingState {
eARCOMMANDS_ARDRONE3_PILOTINGSTATE_FLYINGSTATECHANGED_STATE flyingState = ARCOMMANDS_ARDRONE3_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_MAX;
eARCONTROLLER_ERROR error;
// get the current flying state description
ARCONTROLLER_DICTIONARY_ELEMENT_t *elementDictionary = ARCONTROLLER_ARDrone3_GetCommandElements(_deviceController->aRDrone3, ARCONTROLLER_DICTIONARY_KEY_ARDRONE3_PILOTINGSTATE_FLYINGSTATECHANGED, &error);
if (error == ARCONTROLLER_OK && elementDictionary != NULL)
{
ARCONTROLLER_DICTIONARY_ARG_t *arg = NULL;
ARCONTROLLER_DICTIONARY_ELEMENT_t *element = NULL;
HASH_FIND_STR (elementDictionary, ARCONTROLLER_DICTIONARY_SINGLE_KEY, element);
if (element != NULL)
{
// get the value
HASH_FIND_STR (element->arguments, ARCONTROLLER_DICTIONARY_KEY_ARDRONE3_PILOTINGSTATE_FLYINGSTATECHANGED_STATE, arg);
if (arg != NULL)
{
// Enums are I32
flyingState = arg->value.I32;
}
}
}
return flyingState;
}
- (void)takeoff
{
if ([self getFlyingState] == ARCOMMANDS_ARDRONE3_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_LANDED)
{
_deviceController->aRDrone3->sendPilotingTakeOff(_deviceController->aRDrone3);
}
}
ドローンはステートを変更します。「飛行」ステートは、 ARCOMMANDS_ARDRONE3_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_TAKINGOFF となり、その後 ARCOMMANDS_ARDRONE3_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_HOVERING もしくは ARCOMMANDS_ARDRONE3_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_FLYING になります。
// called when a command has been received from the drone
void onCommandReceived (eARCONTROLLER_DICTIONARY_KEY commandKey, ARCONTROLLER_DICTIONARY_ELEMENT_t *elementDictionary, void *customData)
{
// if the command received is a flying state changed
if ((commandKey == ARCONTROLLER_DICTIONARY_KEY_ARDRONE3_PILOTINGSTATE_FLYINGSTATECHANGED) && (elementDictionary != NULL))
{
ARCONTROLLER_DICTIONARY_ARG_t *arg = NULL;
ARCONTROLLER_DICTIONARY_ELEMENT_t *element = NULL;
// get the command received in the device controller
HASH_FIND_STR (elementDictionary, ARCONTROLLER_DICTIONARY_SINGLE_KEY, element);
if (element != NULL)
{
// get the value
HASH_FIND_STR (element->arguments, ARCONTROLLER_DICTIONARY_KEY_ARDRONE3_PILOTINGSTATE_FLYINGSTATECHANGED_STATE, arg);
if (arg != NULL)
{
eARCOMMANDS_ARDRONE3_PILOTINGSTATE_FLYINGSTATECHANGED_STATE flyingState = arg->value.I32;
}
}
}
}
これでドローンの操縦が可能になります。
着陸(LANDING)
飛行させたら、着陸の必要があります。以下がその方法です。着陸コマンドを送ります。
- (void)land
{
eARCOMMANDS_ARDRONE3_PILOTINGSTATE_FLYINGSTATECHANGED_STATE flyingState = [self getFlyingState];
if (flyingState == ARCOMMANDS_ARDRONE3_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_FLYING || flyingState == ARCOMMANDS_ARDRONE3_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_HOVERING)
{
_deviceController->aRDrone3->sendPilotingLanding(_deviceController->aRDrone3);
}
}
操縦(PILOTING)
ドローンは飛行角度を設定して操縦します。この角度は最大角度に対するパーセンテージで指定します。
操縦用のコマンドはデバイス・コントローラーから25ミリ秒ごとに自動的に送信されます。
接続が断たれた場合、もしくはコマンドが受信されない場合、BebopDroneは500ミリ秒後に飛行角度をゼロに設定します。これは安全上の理由によります。
操縦用のコマンドには以下の6つのパラメータがあります。
- flag (u8):ブーリアンフラッグ: ロールとピッチの値を考慮すべき場合は1、そうでなければ0。
- roll (i8): ロール角に対するパーセンテージ(符号付き)として表される 最大ピッチ/ロール角度設定のレンジは-100〜100。
-100は、左に最大ピッチ/ロール角度のロール(ドローンは左に飛行します)。
100は、右に最大ピッチ/ロール角度のロール(ドローンは右に飛行します)。
この値は、羽の傾斜可能角度に対応して、上限を設けられる場合があります。
- pitch (i8):ピッチ角に対するパーセンテージ(符号付き)として表される 最大ピッチ/ロール角度設定 のレンジは-100〜100。
-100は、上空に向かって最大ピッチ/ロール角度のピッチ(ドローンは後ろに飛行します)。
100は、地上に向かって最大ピッチ/ロール角度のピッチ(ドローンは前に飛行します)。
この値は、羽の傾斜可能角度に対応して、上限を設けられる場合があります。
- yaw (i8):ヨー角速度に対するパーセンテージ(符号付き)として表される 最大ヨー角速度設定 のレンジは-100〜100。
-100は、反時計回りの最大ヨー角速度。
100は、時計回りの最大ヨー角速度。。
この値は、羽の傾斜可能角度に対応して、上限を設けられる場合があります。。
- gaz (i8):上昇下降スロットルに対するパーセンテージ(符号付き)として表される 最大鉛直速度設定 のレンジは-100〜100。
-100は、地上に向かっての最大鉛直速度。
100は、上空に向かっての最大鉛直速度。
この値は、羽の傾斜可能角度に対応して、上限を設けられる場合があります。
着陸フェイズにある時、正のgazによって着陸はキャンセルされます。
- timestampAndSeqNum (u32):ミリ秒単位のタイムスタンプコマンド(低精度24ビット)+コマンドシークエンス番号 0;255.
以下は操縦角度を設定する方法です。
ドローンを前進させる(最大角度の50%)。
_deviceController->aRDrone3->setPilotingPCMDFlag(_deviceController->aRDrone3, 1);
_deviceController->aRDrone3->setPilotingPCMDPitch(_deviceController->aRDrone3, 50);
ドローンを右に回転させる(最大角速度の50%)。
_deviceController->aRDrone3->setPilotingPCMDYaw(_deviceController->aRDrone3, 50);
ビデオストリーミングの開始(START VIDEO STREAMING)
ビデオストリーミングを開始するために、BebopDroneにコマンドを送信しなければなりません。フレームを受信すると、 デバイスコントローラーを初期化した時に設定した コールバックが呼び出されます。
ビデオストリーミングの開始
_deviceController->aRDrone3->sendMediaStreamingVideoEnable(_deviceController- aRDrone3, 1);
ビデオストリーミングの停止
_deviceController->aRDrone3->sendMediaStreamingVideoEnable(_deviceController->aRDrone3, 0);
写真撮影(TAKING A PICTURE)
ドローンで写真を撮影します。
写真の撮影
_deviceController->aRDrone3->sendMediaRecordPicture(_deviceController->aRDrone3, 0);
画像、ビデオのダウンロード(DOWNLOAD PICTURES AND VIDEOS)
写真やビデオが撮影されると、BebopDroneは内部メモリに保存します。写真は internal_000/Bebop_Drone/media/
に保存されます。
写真を取得するためには、以下を実行します。
- ftpリクエストを行う
- port: 21
- lログイン: "anonymous"
- パスワード無し
- ftpの抽象化を行うlibARDataTransferを利用する。
以下は、libARDataTransferを使っての方法です。
libARDataTransferは保存されているメディアのリストを高速で取得します。また、メディアのリストにサムネイルを加える方法も提供します。メディアをダウンロードする機能も提供します。
まず、データ転送マネージャを作成する必要があります。
変数の宣言
#define MEDIA_FOLDER "internal_000"
@property (nonatomic, assign) ARSAL_Thread_t threadRetreiveAllMedias; // the thread that will do the media retrieving
@property (nonatomic, assign) ARSAL_Thread_t threadGetThumbnails; // the thread that will download the thumbnails
@property (nonatomic, assign) ARSAL_Thread_t threadMediasDownloader; // the thread that will download medias
@property (nonatomic, assign) ARDATATRANSFER_Manager_t *manager; // the data transfer manager
@property (nonatomic, assign) ARUTILS_Manager_t *ftpListManager; // an ftp that will do the list
@property (nonatomic, assign) ARUTILS_Manager_t *ftpQueueManager; // an ftp that will do the download
データ転送マネージャの作成
- (void)createDataTransferManager
{
eARDATATRANSFER_ERROR result = ARDATATRANSFER_OK;
_manager = ARDATATRANSFER_Manager_New(&result);
if (result == ARDATATRANSFER_OK)
{
eARUTILS_ERROR ftpError = ARUTILS_OK;
_ftpListManager = ARUTILS_Manager_New(&ftpError);
if(ftpError == ARUTILS_OK)
{
_ftpQueueManager = ARUTILS_Manager_New(&ftpError);
}
if(ftpError == ARUTILS_OK)
{
ftpError = ARUTILS_Manager_InitFtp(_ftpListManager, _discoveryDevice, ARUTILS_DESTINATION_DRONE, ARUTILS_FTP_TYPE_GENERIC);
}
if(ftpError == ARUTILS_OK)
{
ftpError = ARUTILS_Manager_InitFtp(_ftpQueueManager, _discoveryDevice, ARUTILS_DESTINATION_DRONE, ARUTILS_FTP_TYPE_GENERIC);
}
if(ftpError != ARUTILS_OK)
{
result = ARDATATRANSFER_ERROR_FTP;
}
}
// NO ELSE
if (result == ARDATATRANSFER_OK)
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths lastObject];
result = ARDATATRANSFER_MediasDownloader_New(_manager, _ftpListManager, _ftpQueueManager, MEDIA_FOLDER, [path UTF8String]);
}
}
以上で、BebopDrone上の全てのメディアのリスト(サムネイル無し)が取得可能となります。この処理は非常に高速です。
メディアリストの取得
- (void)startMediaListThread
{
// first retrieve Medias without their thumbnails
ARSAL_Thread_Create(&_threadRetreiveAllMedias, ARMediaStorage_retreiveAllMediasAsync, (__bridge void *)self);
}
static void* ARMediaStorage_retreiveAllMediasAsync(void* arg)
{
PilotingViewController *self = (__bridge PilotingViewController *)(arg);
[self getAllMediaAsync];
return NULL;
}
- (void)getAllMediaAsync
{
eARDATATRANSFER_ERROR result = ARDATATRANSFER_OK;
int mediaListCount = 0;
if (result == ARDATATRANSFER_OK)
{
mediaListCount = ARDATATRANSFER_MediasDownloader_GetAvailableMediasSync(_manager,0,&result);
if (result == ARDATATRANSFER_OK)
{
for (int i = 0 ; i < mediaListCount && result == ARDATATRANSFER_OK; i++)
{
ARDATATRANSFER_Media_t * mediaObject = ARDATATRANSFER_MediasDownloader_GetAvailableMediaAtIndex(_manager, i, &result);
NSLog(@"Media %i: %s", i, mediaObject->name);
// Do what you want with this mediaObject
}
}
}
}
リストを受信したら、サムネイルのダウンロードが開始可能になります(サムネイルを表示しないのであればこの処理は不要です。
サムネイルのダウンロード
- (void)startMediaThumbnailDownloadThread
{
// first retrieve Medias without their thumbnails
ARSAL_Thread_Create(&_threadGetThumbnails, ARMediaStorage_retreiveMediaThumbnailsSync, (__bridge void *)self);
}
static void* ARMediaStorage_retreiveMediaThumbnailsSync(void* arg)
{
PilotingViewController *self = (__bridge PilotingViewController *)(arg);
[self downloadThumbnails];
return NULL;
}
- (void)downloadThumbnails
{
ARDATATRANSFER_MediasDownloader_GetAvailableMediasAsync(_manager, availableMediaCallback, (__bridge void *)self);
}
void availableMediaCallback (void* arg, ARDATATRANSFER_Media_t *media, int index)
{
if (NULL != arg)
{
PilotingViewController *self = (__bridge PilotingViewController *)(arg);
// you can alternatively call updateThumbnailWithARDATATRANSFER_Media_t if you use the ARMediaObjectDelegate
UIImage *newThumbnail = [UIImage imageWithData:[NSData dataWithBytes:media->thumbnail length:media->thumbnailSize]];
// Do what you want with the image
}
}
次のステップはメディアのダウンロードです。
メディアのダウンロード
- (void)downloadMedias:(ARDATATRANSFER_Media_t *)medias withCount:(int)count
{
eARDATATRANSFER_ERROR result = ARDATATRANSFER_OK;
for (int i = 0 ; i < count && result == ARDATATRANSFER_OK; i++)
{
ARDATATRANSFER_Media_t *media = medias[i];
result = ARDATATRANSFER_MediasDownloader_AddMediaToQueue(_manager, media, medias_downloader_progress_callback, (__bridge void *)(self), medias_downloader_completion_callback,(__bridge void*)self);
}
if (result == ARDATATRANSFER_OK)
{
if (_threadMediasDownloader == NULL)
{
// if not already started, start download thread in background
ARSAL_Thread_Create(&_threadMediasDownloader, ARDATATRANSFER_MediasDownloader_QueueThreadRun, _manager);
}
}
}
void medias_downloader_progress_callback(void* arg, ARDATATRANSFER_Media_t *media, float percent)
{
// the media is downloading
}
void medias_downloader_completion_callback(void* arg, ARDATATRANSFER_Media_t *media, eARDATATRANSFER_ERROR error)
{
// the media is downloaded
}
メディアのダウンロードの停止
- (void)cancelCurrentDownload {
if (_threadMediasDownloader != NULL)
{
ARDATATRANSFER_MediasDownloader_CancelQueueThread(_manager);
ARSAL_Thread_Join(_threadMediasDownloader, NULL);
ARSAL_Thread_Destroy(&_threadMediasDownloader);
_threadMediasDownloader = NULL;
}
}
これ以上のデータ転送が不要であれば、全てをクリーンにすることを忘れないでください。
クリーン
- (void)clean
{
if (_threadRetreiveAllMedias != NULL)
{
ARDATATRANSFER_MediasDownloader_CancelGetAvailableMedias(_manager);
ARSAL_Thread_Join(_threadRetreiveAllMedias, NULL);
ARSAL_Thread_Destroy(&_threadRetreiveAllMedias);
_threadRetreiveAllMedias = NULL;
}
if (_threadGetThumbnails != NULL)
{
ARDATATRANSFER_MediasDownloader_CancelGetAvailableMedias(_manager);
ARSAL_Thread_Join(_threadGetThumbnails, NULL);
ARSAL_Thread_Destroy(&_threadGetThumbnails);
_threadGetThumbnails = NULL;
}
if (_threadMediasDownloader != NULL)
{
ARDATATRANSFER_MediasDownloader_CancelQueueThread(_manager);
ARSAL_Thread_Join(_threadMediasDownloader, NULL);
ARSAL_Thread_Destroy(&_threadMediasDownloader);
_threadMediasDownloader = NULL;
}
ARDATATRANSFER_MediasDownloader_Delete(_manager);
ARUTILS_Manager_CloseWifiFtp(_ftpListManager);
ARUTILS_Manager_CloseWifiFtp(_ftpQueueManager);
ARUTILS_Manager_Delete(&_ftpListManager);
ARUTILS_Manager_Delete(&_ftpQueueManager);
ARDATATRANSFER_Manager_Delete(&_manager);
}
メッセージリファレンス(Messages reference)
サポートされるメッセージの全リストは referenceから見つかります。
または、製品でサポートされているメッセージのリファレンスだけを見たい場合は、以下の製品リストから選択してください。
- Disco(ディスコ)
- Bebop Drone(ビバップドローン)
- Bebop 2(ビバップ2)
- Skycontroller(スカイコントローラー)
- SkyController 2(スカイコントローラー2)
より詳細に(Go deeper)
p>自分自身でSDKをビルドすることも可能です! 完全にオープンソース化されています。バージョン管理はrepoツールによります。 こちらに従い入手できます。
repoの使い方については、 こちら で学べます。
MacOSでは、必要なツールをインストールするために、このコマンドを実行します。
brew install bash coreutils gettext pkgconfig wget python python3 autoconf libtool
全てのソースのダウンロード(Download all sources)
SDKのソースは、 githubにホストされています。 ダウンロードするためには、arsdk_manifests urlでrepoを初期化するだけです。
repo init -u https://github.com/Parrot-Developers/arsdk_manifests.git
その後、以下のコマンドを実行することにより、全てのその他のリポジトリをダウンロードすることができます。
repo sync
そこからは、 SDKのビルドの方法に従ってください。
構成(Organisation)
SDKは以下の構成になっています。
arsdk_manifests
このgitリポジトリはSDKの一部、もしくはSDKによって必要とされるその他全てのリポジトリをリスト化します。
arsdk_products
このgitリポジトリはSDK全体をビルドするために呼び出すbuild.shを提供します。
ARSDKBuildUtils
このrepoは、SDK全体をビルドするのに必要なautotoolsを作成するための全てのツールを含みます。arsdk_productsに含まれる、build.shファイルに呼び出されます。
arsdk-xml
このリポジトリは、ドローンに送信出来るメッセージとドローンから受信出来るメッセージを記述する全てのxmlファイルを含みます。
libARCommands
このライブラリは、ドローンに送信出来るメッセージとドローンから受信出来るメッセージを含むファイルを作成します。
libARController
このライブラリは、ドローンに接続するための抽象化レベルを提供します。このライブラリを使って、ドローンの操縦、写真の撮影、ストリームの受信(ドローンによります)、その他のコマンドの送受信を可能にする、デバイスコントローラーの作成ができます。
libARDataTransfer
このライブラリはドローンとのデータ送受信を可能にします。
libARDiscovery
このライブラリは、ネットワーク上のサポートされている全てのドローンを見つけることを可能にします。
libARMavlink
このライブラリは、自動化された飛行ファイルの作成を可能にします。
libARMedia
このライブラリは、ドローンによって生成されたメディア周辺の抽象化レイヤを提供します。
libARNetwork
このライブラリは、ドローンとのパケット送受信を担当します。
libARNetworkAL
このライブラリは、異なるネットワーク周辺の抽象化レイヤを提供します(BLEもしくは、Wifiネットワーク)。
libARSAL
このライブラリは、システム抽象化レイヤを提供します。
libARStream
このライブラリは、全てのストリーミングタイプを扱います。ストリームのパック、アンパックを行います。
libARStream2
このライブラリは、新しいh264ストリームを扱います。ストリームのパック、アンパックを行い、ripストリームを扱います。
libARUpdater
このライブラリは、ドローンのアップデートを可能にします。バージョンが最新であるかテストする機能とドローンをアップデートする機能を提供します。
libARUtils
このライブラリは、ユーティリティクラスを提供します。
libmux
このライブラリは、muxを使うための機能を提供します。
libpomp
このライブラリは、printfのようなメッセージプロトコルです。
Samples
このrepo内に、iOS、android、Unixのいくつかのサンプルがあります。
SDKのビルドの方法(How to build the SDK)
最初に、 SDKの全てのソースコードをダウンロードしてください。
repo initコマンドやrepo syncコマンドを実行したルートフォルダは通知されます
必要な外部ツール(Required external tools
SDKのビルドには、以下の外部ツールが必要です。
- git
- build-essential (Unixのみ)
- autoconf
- libtool
- python
- python3
- libavahi-client-dev (特定のサンプルのみ)
- libavcodec-dev (特定のサンプルのみ))
- libavformat-dev (特定のサンプルのみ)
- libswscale-dev (特定のサンプルのみ)
- libncurses5-dev (特定のサンプルのみ)
- mplayer (特定のサンプルのみ)
Linux: 任意のパッケージマネージャを使ってこれらのツールをインストールしてください。
OSX:XCodeがインストールされている必要があります。 brew を使ってこれらのツールをインストールしてください。
一般的なビルド(General Build)
ビルドは、 ./build.sh
スクリプトによって実行されます。ビルドオプションについては、 ./build.sh --help
で情報が得られます。
一般的なビルドの方法は以下の通りです。
./build.sh -p arsdk-VARIANT -t TASK OTHER_ARGS
利用可能な引数は以下の通りです。
- ios (iOSのiPhone)
- ios_sim (iOSのiPhoneシミュレータ)
- android (Android)
- native (Unix)
Unixでのビルド(Unix Build)
Linux: ubuntu 14.04で検証済
OSX: 10.11.6で検証済
UnixプラットフォームでSDKをビルドするコマンドは以下の通りです。
./build.sh -p arsdk-native -t build-sdk -j
<SDK>/out/Unix-base/staging/usr/に出力されます。
実行可能なタスクは以下の通りです。
- build-sdk (ネイティブsdkをビルドします)
- build-sample (全てのネイティブのサンプルをビルドします)
- build-sample-SAMPLE_NAME (SAMPLE_NAMEのunix sdkサンプルをビルドします)
サンプルの実行
サンプルを実行するためには、 <SDK>/out/arsdk-native/staging/usr/lib
フォルダを LD_LIBRARY_PATH
環境変数に追加します。 これは、 <SDK>/out/Unix-base/staging/native-wrapper.sh
スクリプトを使用して行います。
このスクリプトは以下の二通りの方法で使われます。
- • シェルスクリプトとして、一つのサンプルを呼び出す:
<SDK>/out/arsdk-native/staging/native-wrapper.sh <SDK>/out/arsdk-native/staging/usr/bin/<sample> [args...]
. - • ソーススクリプトとして、
PATH
とLD_LIBRARY_PATH
環境変数をセットする:source <SDK>/out/arsdk-native/staging/native-wrapper.sh
. のスクリプトのソース化の後、あなたのパスに<SDK>/out/arsdk-native/staging/usr/bin
フォルダが追加されることにより、フルパスを指定すること無しにサンプルをその名前から直接呼び出せます。
IOSでのビルド(iOS Build)
p>OSX: 10.11.6でテスト済iOS用にSDKをビルドするコマンドは以下の通りです。
./build.sh -p arsdk-ios -t build-sdk -j
<SDK>/out/arsdk-ios/staging/usr/ に出力されます。
実行可能なタスクは以下の通りです。
- build-sdk (ios sdkをビルドします)
- build-sample (デバッグ版でビルドします)
iPhoneシミュレータでのビルド(iPhone Simulator Build)
OSX: 10.11.6でテスト済
iOS用にSDKをビルドするコマンドは以下の通りです。
./build.sh -p arsdk-ios -t build-sdk -j
<SDK>/out/arsdk-ios_sim/staging/usr/ に出力されます。
実行可能なタスクは以下の通りです。
- build-sdk (ios sdkをビルドします)
- build-sample (デバッグ版でビルドします)
Androidでのビルド(Android Build
Linux: Ubuntu 14.04でテスト済
OSX: 10.11.6でテスト済
以下が必要です。
- ava 8(1.8)をサポートする、実行可能な(working)jdk
- • androidSDKとNDK(SDKはAndroid-23用にビルドされたもの)
- • 環境変数
ANDROID_SDK_PATH
とANDROID_NDK_PATH
,を宣言。それぞれが、対応するdevキットのルートを指定します。
Androidプラットフォーム用にSDKをビルドするコマンドは以下の通りです。
./build.sh -p arsdk-android -t build-sdk -j
<SDK>/out/arsdk-android/ARCH/staging/usr/ に出力されます。
Tasks available are:
- build-sdk (全てのアーキテクチャに対応したandroidsdkをビルドします)
- build-sdk-armeabi (armeabiに対応したandroidsdkをビルドします)
- build-sdk-armeabi_v7a (armeabi_v7aに対応したandroidsdkをビルドします)
- build-sdk-mips (mipsに対応したandroidsdkをビルドします)
- build-sdk-x86 (x86に対応したandroidsdkをビルドします)
- build-jni (androidsdk と jniをビルドします)
- build-sample (デバッグ版でビルドします)
クリーン(Clean)
ビルドをクリーンするためには、 <SDK>/out/ folder を削除します。