はじめに
DJI Mobile SDK V5を使用して、スクエア飛行を自動で行いました。
サンプルコードをベースに機能を追加していきます。
スクエア飛行とは
スクエア飛行とは、ドローンを、四隅を順に飛行させることであり、操縦の練習方法の一つとして用いられています。
ドローンの国家資格(免許)である無⼈航空機操縦士の実技試験でも実施されており、初心者が必ず実施する飛行の一つといってもよいでしょう。
▼スクエア飛行の図
出典: 国土交通省航空局安全部無人航空機安全課(2022)
前提条件
- Android Studio Flamingo
- DJI Mini 3
- Huawei Mate 20
- Mobile SDK V5
- サンプルコード(APIキー連携済み)
- APIキー連携の実施方法は以下を確認してください
画面の作成
ボタンのテキストの追加
android-sdk-v5-sample\module-common\src\main\res\values\strings.xml
+ <string name="btn_square" translatable="false">Square</string>
ボタンの作成
Testing Tool-> Virtual Stickの画面に起動用のボタンを追加します。
android-sdk-v5-sample\module-aircraft\src\main\res\layout\frag_virtual_stick_page.xml
<Button
android:id="@+id/btn_set_virtual_stick_speed_level"
style="@style/main_fragment_btn"
android:text="@string/btn_set_virtual_stick_speed_level"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_disable_virtual_stick" />
+ <Button
+ android:id="@+id/btn_square"
+ style="@style/main_fragment_btn"
+ android:text="@string/btn_square"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/btn_set_virtual_stick_speed_level" />
ボタンの処理を追加
ボタンを押下した際の処理を記述します。
android-sdk-v5-sample\module-aircraft\src\main\java\dji\sampleV5\moduleaircraft\pages\VirtualStickFragment.kt
private val simulatorVM: SimulatorVM by activityViewModels()
private val deviation: Double = 0.02
+ private val handler: Handler = Handler(Looper.getMainLooper())
(中略)
btn_set_virtual_stick_speed_level.setOnClickListener {
val speedLevels = doubleArrayOf(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0)
initPopupNumberPicker(Helper.makeList(speedLevels)) {
virtualStickVM.setSpeedLevel(speedLevels[indexChosen[0]])
resetIndex()
}
}
+ //メッセージをポップアップ表示した後、送信機の右スティックを操作する
+ btn_square.setOnClickListener {
+ class GotoPos(
+ val launch_message: String,
+ val right_horizontal: Float,
+ val right_vertical: Float
+ ) : Runnable {
+ override fun run() {
+ if (launch_message != "")
+ //メッセージのポップアップ
+ ToastUtils.showToast(launch_message)
+ //右スティックの状態を更新する
+ virtualStickVM.setRightPosition(
+ //垂直方向
+ (right_horizontal * Stick.MAX_STICK_POSITION_ABS).toInt(),
+ //鉛直方向
+ (right_vertical * Stick.MAX_STICK_POSITION_ABS).toInt()
+ )
+ }
+ }
+
+ //離陸
+ ToastUtils.showToast("Takeoff")
+ basicAircraftControlVM.startTakeOff(object :
+ CommonCallbacks.CompletionCallbackWithParam<EmptyMsg> {
+ override fun onSuccess(t: EmptyMsg?) {
+ ToastUtils.showToast("start takeOff onSuccess.")
+ }
+
+ override fun onFailure(error: IDJIError) {
+ ToastUtils.showToast("start takeOff onFailure,$error")
+ }
+ })
+
+ //Goto Pos1
+ handler.postDelayed(GotoPos("Go to Position1", 0f, -0.1f), 4000)
+ //停止させるために進行方向と逆方向にスティックを倒す
+ handler.postDelayed(GotoPos("", 0f, 0.01f), 8000)
+ //スティックを戻す
+ handler.postDelayed(GotoPos("", 0f, 0f), 8100)
+
+ //Goto Pos2
+ handler.postDelayed(GotoPos("Go to Position2", -0.1f, 0f), 8100)
+ handler.postDelayed(GotoPos("", 0.01f, 0f), 12100)
+ handler.postDelayed(GotoPos("", 0f, 0f), 12200)
+
+ //Goto Pos3
+ handler.postDelayed(GotoPos("Go to Position3", 0f, 0.1f), 12200)
+ handler.postDelayed(GotoPos("", 0f, -0.01f), 20200)
+ handler.postDelayed(GotoPos("", 0f, 0f), 20300)
+
+ //Goto Pos4
+ handler.postDelayed(GotoPos("Go to Position4", 0.1f, 0f), 20300)
+ handler.postDelayed(GotoPos("", -0.01f, 0f), 28300)
+ handler.postDelayed(GotoPos("", 0f, 0f), 28400)
+
+ //Goto Pos5
+ handler.postDelayed(GotoPos("Go to Position5", 0f, -0.1f), 28400)
+ handler.postDelayed(GotoPos("", 0f, 0.01f), 36400)
+ handler.postDelayed(GotoPos("", 0f, 0f), 36500)
+
+ //Goto Pos1
+ handler.postDelayed(GotoPos("Go to Position1", -0.1f, 0f), 36500)
+ handler.postDelayed(GotoPos("", 0.01f, 0f), 40500)
+ handler.postDelayed(GotoPos("", 0f, 0f), 40600)
+
+ //Goto Home
+ handler.postDelayed(GotoPos("Go to Home", 0f, 0.1f), 40600)
+ handler.postDelayed(GotoPos("", 0f, -0.01f), 44600)
+ handler.postDelayed(GotoPos("", 0f, 0f), 44700)
+
+ //着陸
+ handler.postDelayed(
+ object : Runnable {
+ override fun run() {
+ basicAircraftControlVM.startLanding(object :
+ CommonCallbacks.CompletionCallbackWithParam<EmptyMsg> {
+ override fun onSuccess(t: EmptyMsg?) {
+ ToastUtils.showToast("start landing onSuccess.")
+ }
+
+ override fun onFailure(error: IDJIError) {
+ ToastUtils.showToast("start landing onFailure,$error")
+ }
+ })
+ }
+ },
+ 48600)
+ }
動作確認
確認の都合上、上記のコードと以下の点で異なっております。
- virtual stickが削除されています
- SimulatorのON/OFFボタンが追加されています
- 「Testing Tools」->「Simulator」より同様の機能が利用できます
課題点
着陸の際に、一定の高度で停止してしまう事象が発生している。
解決しました
参考文献
国土交通省航空局安全部無人航空機安全課, 二等無⼈航空機操縦士実地試験実施細則回転翼航空機(マルチローター), 2022, p22