【Androidでドローン(マルチコプター)を飛ばそう】 ドローンを操作するためのクラスの実装

このエントリーを Google ブックマーク に追加
Pocket
[`yahoo` not found]

前回の【Androidでドローン(マルチコプター)を飛ばそう】 ドローンを操作するためのクラスではドローンを操作するためのクラスを説明しました。
今回はこれらのクラスを使い、ドローンを操作するラッパークラスを作成します。
作成とは言ってもサンプルを説明していくだけです。
作るクラスはミニドローン操作専用クラスなのでMiniDrone.javaという名前です。
今後、ドローンに対する機能を実装していくときはこのクラスに実装していきます。

1-初期化部分

フィールドとコンストラクタです。
このクラスは以前の【Androidでドローン(マルチコプター)を飛ばそう】 ドローン探索機能を実装するの探索機能で取得したARDiscoveryDeviceServiceのインスタンスを引数にとります。
ARDiscoveryDeviceService→ARDiscoveryDevice→ARDeviceControllerの順でインスタンスを作成していきます。
ARDeviceControllerのインスタンス作成時にARDeviceController#addListenerメソッドを使いARDeviceControllerListenerを設定します。
実際の実装は「3-ARDeviceControllerのコールバックを実装」 また、ドローンは二つの状態を持っています。一つはAndroid端末との接続状態を表す制御状態とドローンの離陸・着陸・旋回等の状態を表す飛行状態です。
これらの状態は後述するMiniDrone.Listenerクラスを実装することでコールバックを得ることができます。

    /** コンテキスト*/
    private final Context mContext;

    /** リスナー一覧*/
    private final List<Listener> mListeners;

    /** ハンドラー*/
    private final Handler mHandler;

    /** ARデバイスの制御状態*/
    private ARCONTROLLER_DEVICE_STATE_ENUM mState;

    /** 製品タイプ*/
    private ARDISCOVERY_PRODUCT_ENUM mProductType;

    /** ARデバイスの飛行状態*/
    private ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_ENUM mFlyingState;

    /** 現在の飛行ID*/
    private String mCurrentRunId;

    /** ARDevice操作クラス*/
    private ARDeviceController mDeviceController;

    /** SDカード操作クラス*/
    private SDCardModule mSDCardModule;

    /**
    * コンストラクタ
    *
    * @param context       コンテキスト
    * @param deviceService ARDevice情報
    */
    public MiniDrone(Context context, @NonNull ARDiscoveryDeviceService deviceService) {
        mContext = context;
        mListeners = new ArrayList<>();
        // コールバックをメインスレッドに返却するためにハンドラーを作る
        mHandler = new Handler(context.getMainLooper());
        // ARデバイスの制御状態
        mState = ARCONTROLLER_DEVICE_STATE_ENUM.ARCONTROLLER_DEVICE_STATE_STOPPED;
        // プロダクトIDからプロダクトタイプを識別する
        mProductType = ARDiscoveryService.getProductFromProductID(deviceService.getProductID());
        // プロダクトタイプからプロダクト種類を識別する
        ARDISCOVERY_PRODUCT_FAMILY_ENUM family = ARDiscoveryService.getProductFamily(mProductType);
        // このクラスはMINIDRONE種類だけをサポートしているのでそれ以外の場合は終了する
        if (ARDISCOVERY_PRODUCT_FAMILY_ENUM.ARDISCOVERY_PRODUCT_FAMILY_MINIDRONE.equals(family)) {
            ARDiscoveryDevice discoveryDevice = createDiscoveryDevice(context, deviceService, mProductType);
            if (discoveryDevice != null) {
                mDeviceController = createDeviceController(discoveryDevice);
            }
        } else {
            Log.e(TAG, "DeviceService type is not supported by MiniDrone");
        }
    }

    /**
    * 接続対象製品サービスクラスから接続対象製品機器クラスを作成する
    *
    * @param context                  コンテキスト
    * @param arDiscoveryDeviceService 接続対象の製品
    * @param productType              製品種別
    * @return 製品機器
    */
    private ARDiscoveryDevice createDiscoveryDevice(Context context, @NonNull ARDiscoveryDeviceService arDiscoveryDeviceService, ARDISCOVERY_PRODUCT_ENUM productType) {
        ARDiscoveryDevice arDiscoveryDevice = null;
        try {
            arDiscoveryDevice = new ARDiscoveryDevice();
            ARDiscoveryDeviceBLEService arDiscoveryDeviceBLEService = (ARDiscoveryDeviceBLEService) arDiscoveryDeviceService.getDevice();
            arDiscoveryDevice.initBLE(productType, context.getApplicationContext(), arDiscoveryDeviceBLEService.getBluetoothDevice());
        } catch (ARDiscoveryException e) {
            Log.e(TAG, "Exception", e);
            Log.e(TAG, "Error: " + e.getError());
        }
        return arDiscoveryDevice;
    }

    /**
    * 接続対象製品機器クラスから接続対象製品機器操作クラスを作成する
    *
    * @param discoveryDevice 接続対象製品機器クラス
    * @return 接続対象製品機器操作クラス
    */
    private ARDeviceController createDeviceController(@NonNull ARDiscoveryDevice discoveryDevice) {
        ARDeviceController deviceController = null;
        try {
            deviceController = new ARDeviceController(discoveryDevice);
            deviceController.addListener(mDeviceControllerListener);
        } catch (ARControllerException e) {
            Log.e(TAG, "Exception", e);
        }
        return deviceController;
    }

    /**
    * 現在の接続状態を返却する
    *
    * @return 現在の接続状態
    */
    public ARCONTROLLER_DEVICE_STATE_ENUM getConnectionState() {
        return mState;
    }

    /**
    * 現在の飛行状態を返却する
    *
    * @return 現在の飛行状態
    */
    public ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_ENUM getFlyingState() {
        return mFlyingState;
    }

 

2-MiniDrone.Listenerの定義

ドローンの制御状態と飛行状態が変化したときにコールバックするMiniDrone.Listenerクラスを定義します。

  • Listener#onDroneConnectionChanged:操作対象のドローンの状態が変化したときのコールバック
  • Listener#onPilotingStateChanged:ドローンの飛行状態が変化したときにコールバックされる
    /**
    * ドローンのリスナー
    */
    public interface Listener {

        /**
        * 操作対象のドローンの状態が変化したときのコールバック
        * メインスレッドで呼ばれる
        * 状態一覧
        * ・eARCONTROLLER_DEVICE_STATE_UNKNOWN_ENUM_VALUE:無効な状態(code値:-2147483648)
        * ・ARCONTROLLER_DEVICE_STATE_STOPPED:操作停止状態(code値:0)
        * ・ARCONTROLLER_DEVICE_STATE_STARTING:操作開始状態(code値:1)
        * ・ARCONTROLLER_DEVICE_STATE_RUNNING:操作状態(code値:2)
        * ・ARCONTROLLER_DEVICE_STATE_PAUSED:操作中断状態(code値:3)
        * ・ARCONTROLLER_DEVICE_STATE_STOPPING:操作終了状態(code値:4)
        * ・ARCONTROLLER_DEVICE_STATE_MAX:最大コード(code値:5)
        *
        * @param state 状態
        */
        void onDroneConnectionChanged(ARCONTROLLER_DEVICE_STATE_ENUM state);

        /**
        * ドローンの飛行状態が変化したときにコールバックされる
        * メインスレッドで呼ばれる
        * ・ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_UNKNOWN_ENUM_VALUE:無効な状態(code値:-2147483648)
        * ・ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_LANDED:着陸状態(code値:0)
        * ・ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_TAKINGOFF:離陸状態(code値:1)
        * ・ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_HOVERING:ホバリング状態(code値:2)
        * ・ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_FLYING:飛行状態(code値:3)
        * ・ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_LANDING:着陸状態(code値:4)
        * ・ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_EMERGENCY:緊急状態(code値:5)
        * ・ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_ROLLING:旋回状態(code値:6)
        * ・ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_INIT:初期化状態(code値:7)
        * ・ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_MAX:最大コード(code値:8)
        *
        * @param state ドローンの飛行状態
        */
        void onPilotingStateChanged(ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_ENUM state);
    }

    /**
    * リスナーの追加
    *
    * @param listener リスナー
    */
    public void addListener(Listener listener) {
        mListeners.add(listener);
    }

    /**
    * リスナーの削除
    *
    * @param listener リスナー
    */
    public void removeListener(Listener listener) {
        mListeners.remove(listener);
    }

3-ARDeviceControllerのコールバックを実装

ドローンを操作するARDeviceControllerから端末制御状態や飛行操作状態が変化したときに呼ばれるコールバックを実装します。

    /**
    * 操作対象からのコールバックインターフェースを実装
    */
    private final ARDeviceControllerListener mDeviceControllerListener = new ARDeviceControllerListener() {
        @Override
        public void onStateChanged(ARDeviceController deviceController, ARCONTROLLER_DEVICE_STATE_ENUM newState, ARCONTROLLER_ERROR_ENUM error) {
            mState = newState;
            if (ARCONTROLLER_DEVICE_STATE_ENUM.ARCONTROLLER_DEVICE_STATE_STOPPED.equals(mState)) {
                if (mSDCardModule != null) {
                    mSDCardModule.cancelGetFlightMedias();
                }
            }
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    notifyConnectionChanged(mState);
                }
            });
        }

        @Override
        public void onExtensionStateChanged(ARDeviceController deviceController, ARCONTROLLER_DEVICE_STATE_ENUM newState, ARDISCOVERY_PRODUCT_ENUM product, String name, ARCONTROLLER_ERROR_ENUM error) {
        }

        @Override
        public void onCommandReceived(ARDeviceController deviceController, ARCONTROLLER_DICTIONARY_KEY_ENUM commandKey, ARControllerDictionary elementDictionary) {
        if (elementDictionary == null) {
            return;
        }
        switch (commandKey) {
            case ARCONTROLLER_DICTIONARY_KEY_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED: {
                // 飛行状態が更新されたときにコールバックを実施
                ARControllerArgumentDictionary<Object> args = elementDictionary.get(ARControllerDictionary.ARCONTROLLER_DICTIONARY_SINGLE_KEY);
                if (args != null) {
                    final ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_ENUM state = ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_ENUM.getFromValue((Integer) args.get(ARFeatureMiniDrone.ARCONTROLLER_DICTIONARY_KEY_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE));
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            mFlyingState = state;
                            notifyPilotingStateChanged(state);
                        }
                    });
                }
            }
            break;
            }
        }
    };

    /**
    * 接続対象の機器状態が変わったときにすべてのコールバックリスナーにコールバックする
    *
    * @param state 機器状態
    */
    private void notifyConnectionChanged(ARCONTROLLER_DEVICE_STATE_ENUM state) {
        List<Listener> listenersCpy = new ArrayList<>(mListeners);
        for (Listener listener : listenersCpy) {
            listener.onDroneConnectionChanged(state);
        }
    }

    /**
    * 接続対象の飛行状態が変わったときにすべてのコールバックリスナーにコールバックする
    *
    * @param state 飛行状態
    */
    private void notifyPilotingStateChanged(ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_ENUM state) {
        List<Listener> listenersCpy = new ArrayList<>(mListeners);
        for (Listener listener : listenersCpy) {
            listener.onPilotingStateChanged(state);
        }
    }

4-ドローンとの接続/切断

ARDeviceController#startを呼ぶことでドローンに接続することができます。
このメソッドを呼んですぐに接続/切断するわけではなく、ARDeviceControllerに設定したARDeviceControllerListener#onStateChangedにコールバックされます。
MiniDroneクラスではコールバックをさらにListener#onDroneConnectionChangedにコールバックします。

    /**
    * ドローンに接続する
    *
    * @return 接続要求の成功可否
    * ドローンに接続に成功したからtrueが返却されるわけではないことに注意して下さい。
    * 実際に接続の成否を知るには{@link Listener#onDroneConnectionChanged}を通して知る必要があります。
    */
    public boolean connect() {
        boolean success = false;
        if ((mDeviceController != null) && (ARCONTROLLER_DEVICE_STATE_ENUM.ARCONTROLLER_DEVICE_STATE_STOPPED.equals(mState))) {
            ARCONTROLLER_ERROR_ENUM error = mDeviceController.start();
            if (error == ARCONTROLLER_ERROR_ENUM.ARCONTROLLER_OK) {
                success = true;
            }
        }
        return success;
    }

    /**
    * ドローンに切断する
    *
    * @return 切断要求の成功可否
    * ドローンに切断に成功したからtrueが返却されるわけではないことに注意して下さい。
    * 実際に切断の成否を知るには{@link Listener#onDroneConnectionChanged}を通して知る必要があります。
    */
    public boolean disconnect() {
        boolean success = false;
        if ((mDeviceController != null) && (ARCONTROLLER_DEVICE_STATE_ENUM.ARCONTROLLER_DEVICE_STATE_RUNNING.equals(mState))) {
            ARCONTROLLER_ERROR_ENUM error = mDeviceController.stop();
            if (error == ARCONTROLLER_ERROR_ENUM.ARCONTROLLER_OK) {
                success = true;
            }
        }
        return success;
    }

まとめ

今回はMiniDroneと接続するクラスMiniDroneを作成しました。

    public class MiniDrone {
        private static final String TAG = "MiniDrone";

        /**
        * ドローンのリスナー
        */
        public interface Listener {

        /**
        * 操作対象のドローンの状態が変化したときのコールバック
        * メインスレッドで呼ばれる
        * 状態一覧
        * ・ARCONTROLLER_DEVICE_STATE_UNKNOWN_ENUM_VALUE:無効な状態(code値:-2147483648)
        * ・ARCONTROLLER_DEVICE_STATE_STOPPED:操作停止状態(code値:0)
        * ・ARCONTROLLER_DEVICE_STATE_STARTING:操作開始状態(code値:1)
        * ・ARCONTROLLER_DEVICE_STATE_RUNNING:操作状態(code値:2)
        * ・ARCONTROLLER_DEVICE_STATE_PAUSED:操作中断状態(code値:3)
        * ・ARCONTROLLER_DEVICE_STATE_STOPPING:操作終了状態(code値:4)
        * ・ARCONTROLLER_DEVICE_STATE_MAX:最大コード(code値:5)
        *
        * @param state 状態
        */
        void onDroneConnectionChanged(ARCONTROLLER_DEVICE_STATE_ENUM state);

        /**
        * ドローンの飛行状態が変化したときにコールバックされる
        * メインスレッドで呼ばれる
        * ・ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_UNKNOWN_ENUM_VALUE:無効な状態(code値:-2147483648)
        * ・ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_LANDED:着陸状態(code値:0)
        * ・ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_TAKINGOFF:離陸状態(code値:1)
        * ・ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_HOVERING:ホバリング状態(code値:2)
        * ・ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_FLYING:飛行状態(code値:3)
        * ・ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_LANDING:着陸状態(code値:4)
        * ・ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_EMERGENCY:緊急状態(code値:5)
        * ・ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_ROLLING:旋回状態(code値:6)
        * ・ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_INIT:初期化状態(code値:7)
        * ・ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_MAX:最大コード(code値:8)
        *
        * @param state ドローンの飛行状態
        */
        void onPilotingStateChanged(ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_ENUM state);
    }

    /** コンテキスト*/
    private final Context mContext;

    /** リスナー一覧*/
    private final List<Listener> mListeners;

    /** ハンドラー*/
    private final Handler mHandler;

    /** ARデバイスの制御状態*/
    private ARCONTROLLER_DEVICE_STATE_ENUM mState;

    /** 製品タイプ*/
    private ARDISCOVERY_PRODUCT_ENUM mProductType;

    /** ARデバイスの飛行状態*/
    private ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_ENUM mFlyingState;

    /** 現在の飛行ID*/
    private String mCurrentRunId;

    /** ARDevice操作クラス*/
    private ARDeviceController mDeviceController;
    private static final int DEVICE_PORT = 21;

    /**
    * コンストラクタ
    *
    * @param context       コンテキスト
    * @param deviceService ARDevice情報
    */
    public MiniDrone(Context context, @NonNull ARDiscoveryDeviceService deviceService) {
        mContext = context;
        mListeners = new ArrayList<>();
        // コールバックをメインスレッドに返却するためにハンドラーを作る
        mHandler = new Handler(context.getMainLooper());
        // ARデバイスの制御状態
        mState = ARCONTROLLER_DEVICE_STATE_ENUM.ARCONTROLLER_DEVICE_STATE_STOPPED;
        // プロダクトIDからプロダクトタイプを識別する
        mProductType = ARDiscoveryService.getProductFromProductID(deviceService.getProductID());
        // プロダクトタイプからプロダクト種類を識別する
        ARDISCOVERY_PRODUCT_FAMILY_ENUM family = ARDiscoveryService.getProductFamily(mProductType);
        // このクラスはMINIDRONE種類だけをサポートしているのでそれ以外の場合は終了する
        if (ARDISCOVERY_PRODUCT_FAMILY_ENUM.ARDISCOVERY_PRODUCT_FAMILY_MINIDRONE.equals(family)) {
            ARDiscoveryDevice discoveryDevice = createDiscoveryDevice(context, deviceService, mProductType);
            if (discoveryDevice != null) {
                mDeviceController = createDeviceController(discoveryDevice);
            }
        } else {
            Log.e(TAG, "DeviceService type is not supported by MiniDrone");
        }
    }

    /**
    * 接続対象製品サービスクラスから接続対象製品機器クラスを作成する
    *
    * @param context                  コンテキスト
    * @param arDiscoveryDeviceService 接続対象の製品
    * @param productType              製品種別
    * @return 製品機器
    */
    private ARDiscoveryDevice createDiscoveryDevice(Context context, @NonNull ARDiscoveryDeviceService arDiscoveryDeviceService, ARDISCOVERY_PRODUCT_ENUM productType) {
        ARDiscoveryDevice arDiscoveryDevice = null;
        try {
            arDiscoveryDevice = new ARDiscoveryDevice();
            ARDiscoveryDeviceBLEService arDiscoveryDeviceBLEService = (ARDiscoveryDeviceBLEService) arDiscoveryDeviceService.getDevice();
            arDiscoveryDevice.initBLE(productType, context.getApplicationContext(), arDiscoveryDeviceBLEService.getBluetoothDevice());
        } catch (ARDiscoveryException e) {
            Log.e(TAG, "Exception", e);
            Log.e(TAG, "Error: " + e.getError());
        }
        return arDiscoveryDevice;
    }

    /**
    * 接続対象製品機器クラスから接続対象製品機器操作クラスを作成する
    *
    * @param discoveryDevice 接続対象製品機器クラス
    * @return 接続対象製品機器操作クラス
    */
    private ARDeviceController createDeviceController(@NonNull ARDiscoveryDevice discoveryDevice) {
        ARDeviceController deviceController = null;
        try {
            deviceController = new ARDeviceController(discoveryDevice);
            deviceController.addListener(mDeviceControllerListener);
        } catch (ARControllerException e) {
            Log.e(TAG, "Exception", e);
        }
        return deviceController;
    }

    /**
    * 現在の接続状態を返却する
    *
    * @return 現在の接続状態
    */
    public ARCONTROLLER_DEVICE_STATE_ENUM getConnectionState() {
        return mState;
    }

    /**
    * 現在の飛行状態を返却する
    *
    * @return 現在の飛行状態
    */
    public ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_ENUM getFlyingState() {
        return mFlyingState;
    }

    /**
    * リスナーの追加
    *
    * @param listener リスナー
    */
    public void addListener(Listener listener) {
        mListeners.add(listener);
    }

    /**
    * リスナーの削除
    *
    * @param listener リスナー
    */
    public void removeListener(Listener listener) {
        mListeners.remove(listener);
    }

    /**
    * ドローンに接続する
    *
    * @return 接続要求の成功可否
    * ドローンに接続に成功したからtrueが返却されるわけではないことに注意して下さい。
    * 実際に接続の成否を知るには{@link Listener#onDroneConnectionChanged}を通して知る必要があります。
    */
    public boolean connect() {
        boolean success = false;
        if ((mDeviceController != null) && (ARCONTROLLER_DEVICE_STATE_ENUM.ARCONTROLLER_DEVICE_STATE_STOPPED.equals(mState))) {
            ARCONTROLLER_ERROR_ENUM error = mDeviceController.start();
            if (error == ARCONTROLLER_ERROR_ENUM.ARCONTROLLER_OK) {
                success = true;
            }
        }
        return success;
    }

    /**
    * ドローンに切断する
    *
    * @return 切断要求の成功可否
    * ドローンに切断に成功したからtrueが返却されるわけではないことに注意して下さい。
    * 実際に切断の成否を知るには{@link Listener#onDroneConnectionChanged}を通して知る必要があります。
    */
    public boolean disconnect() {
        boolean success = false;
        if ((mDeviceController != null) && (ARCONTROLLER_DEVICE_STATE_ENUM.ARCONTROLLER_DEVICE_STATE_RUNNING.equals(mState))) {
            ARCONTROLLER_ERROR_ENUM error = mDeviceController.stop();
            if (error == ARCONTROLLER_ERROR_ENUM.ARCONTROLLER_OK) {
                success = true;
            }
        }
        return success;
    }

    /**
    * 接続対象の機器状態が変わったときにすべてのコールバックリスナーにコールバックする
    *
    * @param state 機器状態
    */
    private void notifyConnectionChanged(ARCONTROLLER_DEVICE_STATE_ENUM state) {
        List<Listener> listenersCpy = new ArrayList<>(mListeners);
        for (Listener listener : listenersCpy) {
            listener.onDroneConnectionChanged(state);
        }
    }

    /**
    * 接続対象の飛行状態が変わったときにすべてのコールバックリスナーにコールバックする
    *
    * @param state 飛行状態
    */
    private void notifyPilotingStateChanged(ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_ENUM state) {
        List<Listener> listenersCpy = new ArrayList<>(mListeners);
        for (Listener listener : listenersCpy) {
            listener.onPilotingStateChanged(state);
        }
    }

    /**
    * 操作対象からのコールバックインターフェースを実装
    */
    private final ARDeviceControllerListener mDeviceControllerListener = new ARDeviceControllerListener() {
        @Override
        public void onStateChanged(ARDeviceController deviceController, ARCONTROLLER_DEVICE_STATE_ENUM newState, ARCONTROLLER_ERROR_ENUM error) {
            mState = newState;
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    notifyConnectionChanged(mState);
                }
            });
        }

        @Override
        public void onExtensionStateChanged(ARDeviceController deviceController, ARCONTROLLER_DEVICE_STATE_ENUM newState, ARDISCOVERY_PRODUCT_ENUM product, String name, ARCONTROLLER_ERROR_ENUM error) {
        }

        @Override
        public void onCommandReceived(ARDeviceController deviceController, ARCONTROLLER_DICTIONARY_KEY_ENUM commandKey, ARControllerDictionary elementDictionary) {
            if (elementDictionary == null) {
                return;
            }
            switch (commandKey) {
                case ARCONTROLLER_DICTIONARY_KEY_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED: {
                // 飛行状態が更新されたときにコールバックを実施
                ARControllerArgumentDictionary<Object> args = elementDictionary.get(ARControllerDictionary.ARCONTROLLER_DICTIONARY_SINGLE_KEY);
                if (args != null) {
                    final ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_ENUM state = ARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_ENUM.getFromValue((Integer) args.get(ARFeatureMiniDrone.ARCONTROLLER_DICTIONARY_KEY_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE));
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            mFlyingState = state;
                            notifyPilotingStateChanged(state);
                        }
                    });
                }
            }
            break;
            case ARCONTROLLER_DICTIONARY_KEY_COMMON_RUNSTATE_RUNIDCHANGED: {
                // 現在の飛行IDを設定する
                ARControllerArgumentDictionary<Object> args = elementDictionary.get(ARControllerDictionary.ARCONTROLLER_DICTIONARY_SINGLE_KEY);
                if (args != null) {
                    final String runID = (String) args.get(ARFeatureCommon.ARCONTROLLER_DICTIONARY_KEY_COMMON_RUNSTATE_RUNIDCHANGED_RUNID);
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            mCurrentRunId = runID;
                        }
                    });
                }
            }
            break;
            }
       }
   };
}

 

【国内正規品】Parrot Minidrones Airborne Night Blaze(レッド)ドローン規制対象外200g 未満・パリデザイン・LED 付き自動安定ホバーリングクアッドコプター ・30万画素カメラ・簡単にアクロバット・スマホ・タブレットで操作 PF723132

新品価格
¥17,150から
(2017/2/28 00:50時点)


Parrot Airborne Cargo MiniDrone - Mars (White) by Parrot

新品価格
¥22,692から
(2017/2/28 00:53時点)


Parrot MiniDrones Airborne Night Drone Maclane (Blue) [並行輸入品]

新品価格
¥12,000から
(2017/2/28 00:54時点)


【国内正規品】Parrot Bebop 2 ホワイト Full HD/30fps 魚眼レンズ カメラ・25分飛行時間・8GB 内部フラッシュメモリー・自動安定ホバーリング・最高水平速度:60KM/H・パリデザイン・GNSS (GPS GLONASS)付・クワッドコプター PF726073

新品価格
¥65,701から
(2017/2/28 00:57時点)


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)