DJI Mobile SDK ことはじめ

#はじめに

センシンロボティクスの山本です。
ドローンの自動航行のためのWebシステム、アプリ開発に関わっています。
今回は、DJI Mobile SDK( Android 版 ) について、改めて公式マニュアルをしっかり読み直そうと思います。


# 概要

実際に動かす場合、DJIのドローンが必要です、Mobile SDK の対応機種は以下のページ (公式) に記載されています。
https://developer.dji.com/products/#!/mobile

version 4.13 からMavic mini が対応されたので、個人&ホビーでもやりやすくなったと思います ( ... 実際に飛ばすとなるとそうでも無いか。 )
githubに公式チュートリアルが公開されているので、作りたいアプリの機能に応じて参考にすることが出来ます。一通り、動かしてみると良いですが、個人的に参考になったのは以下のチュートリアルです。


|  Url  |  概要  |
| --- | --- |
| [Getting Started with DJI UX SDK](https://developer.dji.com/mobile-sdk/documentation/android-tutorials/UXSDKDemo.html)| とりあえず、このチュートリアルのコードでマニュアル飛行用に使えそうなデモ、ユーザインターフェース仕上がってます |
| [Creating a MapView and Waypoint Application](https://developer.dji.com/mobile-sdk/documentation/android-tutorials/GSDemo-Google-Map.html) | GoogleMap上でポイントを打って、飛行させるデモ。 WaypointV2 (Matrice 300が対応)のサンプルコードも含まれています| 
| [DJI Simulator Tutorial](https://developer.dji.com/mobile-sdk/documentation/android-tutorials/SimulatorDemo.html)| DJISimulatorのデモ。DJI Assistant2 のシミュレータとは違い( [公式ドキュメント](https://developer.dji.com/mobile-sdk/documentation/application-development-workflow/workflow-testing.html#dji-assistant-2-simulator)) PCつなげる必要は無いので、他のチュートリアルにこのチュートリアルを参考に組み込むと便利。 |

(参考) [チュートリアル一覧](https://developer.dji.com/mobile-sdk/documentation/android-tutorials)

# UX SDK 

UX SDK は、飛行中のUIの部品です、利用したい部品がwidgetとして定義されているので、飛行中の画面を提供するアプリであれば、使うのはMUSTです、そのまま利用できる部品が揃っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/914750/9379e848-4703-930f-063b-8eb699f44314.png)

( 引用 ) https://developer.dji.com/mobile-sdk/documentation/android-tutorials/UXSDKDemo.html

※ こちらは、今回主役ではないので省略

# Mobile SDK 

ドローンへのコマンドの送信、ミッションの作成等、ドローンの操作はこれを使います。
今回はこちらのSDKのマニュアルの中から、Waypoint ミッションについて深堀りしてみます。
( GoogleMap のチュートリアルが、Waypoint ミッションです )

* Waypoint ★ 
* Hot Point 
* Follow Me 
* ActiveTrack 
* TapFly 

Waypoint ミッションは、中継地点の緯度・経度・高さ等を指定してドローンを飛行させる方法です。


(参考) https://developer.dji.com/mobile-sdk/documentation/introduction/component-guide-missions.html

## 登場するクラス

以下をおさえておけば、おそらく、自由自在にドローン飛ばせます。( 実世界でなかなか飛ばせないですが。)

* WaypointMissionOperator
* WaypointMission
* Waypoint
* WaypointAction
* WaypointActionType
 
## WaypointMissionOperator

waypointミッションの開始や、ミッションのアップロードするために利用します。

```java
    public WaypointMissionOperator getWaypointMissionOperator() {
        return DJISDKManager.getInstance().getMissionControl().getWaypointMissionOperator();
    }

    public void startMission() {
        // ミッションの作成
        ... (中略)
        getWaypointMissionOperator().loadMission(waypointMissionBuilder.build());

        // ミッションのアップロード
        getWaypointMissionOperator().uploadMission(new CommonCallbacks.CompletionCallback() {
            @Override
            public void onResult(DJIError error) {}
        });
        // ミッション開始 
        getWaypointMissionOperator().startMission(new CommonCallbacks.CompletionCallback() {
            @Override
            public void onResult(DJIError error) {}
        });
    }
```

## WaypointMission

WaypointMissionの本体、Waypoint のリストと、各Waypointのアクションを設定する。
各種設定は、WaypointMission.Builderを利用する。

(参考) https://developer.dji.com/api-reference/android-api/Components/Missions/DJIWaypointMission_Builder.html
 

|  設定項目  |  説明  |
| --- | --- |
| waypointList | Waypointのリスト(各ポイントに設定できるアクションは後述) |
| gotoFirstWaypointMode | 1つ目のポイントへの到達方法 SAFTYの場合、同じ高度まで上昇してからポイントに進む |
| finishedAction | 終了後の動作<ul><li>NO_ACTION(待機) <li> GO_HOME(ホームに戻る) <li> AUTO_LAND(着陸) <li>GO_FIRST_WAYPOINT(1つ目のポイントに戻り待機) <li>CONTINUE_UNTIL_END(stopボタン押すまで継続)</ul> |
| headingMode | ドローンの機首方向 <br/> <ul><li>AUTO(進行方向) <li>USING_INITIAL_DIRECTION(1つめのポイントの方向) <li>CONTROL_BY_REMOTE_CONTROLLER(プロポ操作) <li> USING_WAYPOINT_HEADING (ポイント間で徐々に方向が変わる) <li>TOWARD_POINT_OF_INTEREST( POIの地点を向く ) </ul> |
| flightPathMode | コーナーの曲がり方の設定 NORMAL(直線) / CURVED(曲線)、コーナー半径は各ウェイポイントで指定可能 |
| setExitMissionOnRCSignalLostEnabled | プロポとドローンの信号が切れた場合にミッションを停止するかのフラグ。デフォルト false ...だと。 |
| setGimbalPitchRotationEnabled | ミッション中にジンバルのピッチ(上下方向)の操作を有効にするかのフラグ|
| repeatTimes | ミッションを繰り返す回数。ミッションの停止コマンドで中断可能。 |
| setPointOfInterest | Point of Interest の緯度・経度を設定(LocationCoordinate2D) |

... 使ったことのない操作がある、ふむふむ。
POI は、WaypointMission に設定するので、複数のPOIの座標は1つのWaypointMissionに1つとなる(気になるので、後日深追い)。

[DJIWaypointV2](https://developer.dji.com/api-reference/android-api/Components/Missions/DJIWaypointV2_Builder.html) の場合、Waypoint 毎にPOIの設定が入れられる( Altitudeもset可能、設定した場合にどの様に動くか ...  )。

## Waypoint 

|  設定項目  |  説明  |
| --- | --- |
|coordinate | 座標(緯度、経度) |
| altitude | 高度。なお、離陸地点からの相対的な高度となる。ポイント間の高度が異なる場合は、ポイント移動中に徐々に高度が変わる |
|heading | ドローンの方向(角度) -180 - 180, 0は True North。USING_WAYPOINT_HEADINGモードの場合、ポイント移動中に徐々に角度が変わる |
| cornerRadiusInMeters| コーナリング時の半径 |
| gimbalPitch| ジンバルのピッチ。ジンバルの角度はWayPointではピッチしか設定できないようだ。( 飛行中にプロポ操作で変更はできる ) |
| speed| 速度、0〜15 m/s、以下の優先順位で決まる。 <ul><li>プロポ操作で調整した速度<li>speed で設定した速度<li>WaypointMissionOperatorで設定したautoFlightSpeed <li>getAutoFlightSpeed (※ [詳細は公式マニュアルを](https://developer.dji.com/api-reference/android-api/Components/Missions/DJIWaypointMission.html#djiwaypointmission_autoflightspeed_inline))|
| shootPhotoTimeInterval| 等時間撮影の設定（秒数）、0の場合は OFF  |
| shootPhotoDistanceInterval| 等間隔撮影の設定(m)、0の場合は OFF  |
| waypointActions| ウェイポイントに設定したアクション |

だんだん、力尽きてきました。説明が短めになってますがご容赦を。

## WaypointAction

actionType / actionParam でウェイポイントで動作させるアクションを指定する。

## WaypointActionType 

|  設定項目  |  説明  |
| --- | --- |
| STAY |ホバリングする。 [0, 32767] milliseconds. ミリ秒っ! |
| START_TAKE_PHOTO |カメラ撮影、6秒までに完了しない場合は次のアクションに移るとのこと。|
| START_RECORD |動画撮影の開始。同じく最大6秒。 |
| STOP_RECORD |動画撮影の停止。同じく最大6秒|
| ROTATE_AIRCRAFT |ドローンを回転させる。 [-180, 180] ウェイポイントのTurnMode(右回り/左回り)の方向に回転する|
| GIMBAL_PITCH | ジンバルのピッチ（上下）角度の変更、 [-90, 0] |

Waypointで指定するピッチと、アクションで指定するピッチがあるようだ。

(参考) https://developer.dji.com/api-reference/android-api/Components/Missions/DJIWaypoint_DJIWaypointAction.html#djiwaypoint_djiwaypointactiontype_inline

# まとめ

改めて読んでみると、新しい発見や、そんな仕様があったのか。。。と、なかなか有意義でした。Matrice 300 用には[DJIWaypointV2Mission](https://developer.dji.com/api-reference/android-api/Components/Missions/DJIWaypointV2MissionOperator.html) が利用できるため、こちらも近い内に。

# 参考資料

* https://developer.dji.com/mobile-sdk/documentation
* https://github.com/DJI-Mobile-SDK-Tutorials