NAV
Objective C Java C

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

  1. iOSバイナリをダウンロードします SDK version 3.12.6 iOS libs
  2. zipを解凍します。
  3. XCodeのプロジェクトナビゲーターでプロジェクトをクリックします。次にターゲットをクリックし、最後にビルド設定をクリックします。
  4. ヘッダーサーチパスに、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
    alt text

  5. ライブラリサーチパスに、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
    alt text

  6. その他のリンカー・フラッグに以下を追加します。
    -larcommands -larcontroller -lardiscoverywithouteacc -larnetwork -larnetworkal -larsal -larstream -larstream2 -larmavlink -ljson -larmedia -larutils -lcurl -lardatatransfer -lmux -lpomp -lcrypto -lssl -lz
    alt text

    注意: SkyController2に適合させたい場合は、-lardiscoverywithouteaccを-lardiscoveryに置き換え、ExternalAccessoryフレームワークをインクルードする必要があります。このフレームワークは、アプリ申請に影響します。 こちらを参照)
  7. 準備完了です!

さあ、コーディングをはじめましょう

Android

  1. app build.gradleファイルを開きます。
  2. dependenciesに以下の行を追加します。
    compile 'com.parrot:arsdk:3.12.6' alt text
  3. ネイティブライブラリをロードします(右のコードを参照)。

ネイティブライブラリをロードする。

// Not needed in Objective C

準備完了です!さあ、コーディングをはじめましょう !

サンプルを使う(Use samples)

このSDKでどんなことができるかを理解するためには、我々の提供するサンプルコードをざっと見て、使ってみることからはじめるのが良いでしょう。

サンプルリポジトリをクローン化します。
git clone https://github.com/Parrot-Developers/Samples.git

iOS用に一つ、Android用に一つ、Unix用にいくつかのサンプルがあります。 モバイル用のサンプルは、以下のようなアーキテクチャを使用しています。
alt mobile_uml

これらは、スタンドアローンとなっています。つまり、サンプルリポジトリをクローン化したら、SDKをコンパイルせずに使用できます。これを実現するために、プレコンパイルされたSDKが使われます。

モバイル用サンプルでは、ドローンとの接続、操縦、写真撮影、ビデオストリームの表示(可能な場合)、ドローンからのメディアのダウンロードが学べます。

 以下のドローンがサポートされます。

そしてリモートコントローラー

もし、BebopDroneのみに対応したアプリを作成したいのであれば 以下のファイル以外を削除してください。

前にも書いたように、それぞれのモバイルサンプルは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つのパラメータがあります。

以下は操縦角度を設定する方法です。

ドローンを前進させる(最大角度の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/に保存されます。
写真を取得するためには、以下を実行します。

以下は、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から見つかります。
または、製品でサポートされているメッセージのリファレンスだけを見たい場合は、以下の製品リストから選択してください。

より詳細に(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

このライブラリは、ネットワーク上のサポートされている全てのドローンを見つけることを可能にします。

このライブラリは、自動化された飛行ファイルの作成を可能にします。

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のビルドには、以下の外部ツールが必要です。

Linux: 任意のパッケージマネージャを使ってこれらのツールをインストールしてください。
OSX:XCodeがインストールされている必要があります。 brew を使ってこれらのツールをインストールしてください。

一般的なビルド(General Build)

ビルドは、 ./build.sh スクリプトによって実行されます。ビルドオプションについては、 ./build.sh --help で情報が得られます。
一般的なビルドの方法は以下の通りです。
./build.sh -p arsdk-VARIANT -t TASK OTHER_ARGS

利用可能な引数は以下の通りです。

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/に出力されます。

実行可能なタスクは以下の通りです。

サンプルの実行

サンプルを実行するためには、 <SDK>/out/arsdk-native/staging/usr/lib フォルダを LD_LIBRARY_PATH 環境変数に追加します。 これは、 <SDK>/out/Unix-base/staging/native-wrapper.sh スクリプトを使用して行います。 このスクリプトは以下の二通りの方法で使われます。

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/ に出力されます。

実行可能なタスクは以下の通りです。

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/ に出力されます。

実行可能なタスクは以下の通りです。

Androidでのビルド(Android Build

Linux: Ubuntu 14.04でテスト済
OSX: 10.11.6でテスト済

以下が必要です。

Androidプラットフォーム用にSDKをビルドするコマンドは以下の通りです。
./build.sh -p arsdk-android -t build-sdk -j
<SDK>/out/arsdk-android/ARCH/staging/usr/ に出力されます。

Tasks available are:

クリーン(Clean)

ビルドをクリーンするためには、 <SDK>/out/ folder を削除します。