博客專欄

        EEPW首頁 > 博客 > 基于Mobile SDK V5版固件開發大疆無人機手機端遙控器(4)

        基于Mobile SDK V5版固件開發大疆無人機手機端遙控器(4)

        發布人:美男子玩編程 時間:2023-06-30 來源:工程師 發布文章

        相較與V4版本開發,V5版本有了更方便簡介的方式。V5不僅再功能上與V4增加更多的功能,而且在功能的使用及API的調用也做了優化。雖然V5現在很新也在不斷地迭代,但是不免會出現對一些飛行或者遙控器出現bug,大疆的開發人員也在不斷的完善這整個V5開發包,已提供更全更優的開發模式。下面是使用V5開發包進行的大疆無人機飛控系統的開發過程。

        整體架構流程

        DJI Mobile SDK V5擁有更加簡潔易用的無人機硬件控制接口和軟件服務接口,開放全開源的生產代碼及 Sample 和豐富的教程,為開發者提供了具有競爭力的無人機移動端解決方案,極大的提升開發體驗和效率?,F目前所支持的飛機有以下幾種:

        圖片


        Matrice 300 RTK

        圖片

        Matrice 30 Series



        圖片

        DJI Mavic 3 Enterprise Series



        圖片

        DJI Mavic 3M

        圖片

        DJI Mini 3



        圖片

        DJI Mini 3 Pro


        現目前V5 SDK 有下面幾種功能:

        • 參數獲取和設置:負載參數設置、無人機參數設置、負載狀態監聽、無人機狀態監聽。
        • 飛行控制:航點自動飛行、虛擬搖桿飛行、RTK定位配置、Tracking飛行。
        • 應用數據處理:實時碼流直播、MOP數據通道、媒體文件管理、實時點云數據獲取。
        • 更多功能:健康管理、SD卡加密、升級提示、飛行記錄、網絡控制、備份鏈路。
        技術細節SDK 架構體系概述

        Mobile SDK的體系結構被設計為高度可擴展的,其中使用了抽象產品類和組件類,以便應用程序可以使用相同的代碼控制不同的產品。對于一些沒法在不同產品中保持一致性的功能可以在運行時被查詢調用,對于一些能保持一致性的功能則直接可以工作了。

        例如,Phantom和Inspire系列產品的絕大多數功能是一致的。因此,為適配Phantom 4而編寫的應用程序,除Inspire 1的一些獨特功能外,將可以直接在Inspire 1機型上使用。

        這也意味著當新產品發布時,就已經可以與現有的應用程序一起使用了(需要使用支持該新產品的最新SDK)。新產品中的任何新功能都需要添加到應用程序中,但是所有現有功能都不需要做修改了。

        層級架構

        移動應用程序一般通過下圖所示的幾個主要類來訪問Mobile SDK:

        圖片


        • SDKManager:MSDK工具包的入口類,管理MSDK的初始化,反初始化,MSDK注冊,以及監聽DJI硬件產品的連接事件。
        • KeyTools / KeyManager:MSDK V5版本使用了以Key為基礎元素的參數設置和參數獲取功能接口,KeyTools是創建Key的入口類,KeyManager是調用或者監聽Key的入口類,大多數的功能都可以通過相應的Key來控制,例如控制云臺旋轉或者控制相機拍照、錄像等。
        • MediaDataCenter:應用數據獲取功能的入口類,通過MediaDataCenter可以獲取到原始的碼流數據管理類,以及多媒體文件數據的管理類。
        • WaypointMissionManager:航點任務自動飛行的入口類,可以控制無人機基于航點的自主飛行。
        • VirtualStickManager:虛擬搖桿飛行入口類,可以控制無人機進入虛擬搖桿控制模式,進入此模式之后可以通過實時發送動作命令的形式控制無人機飛行。
        • FlightLogManager:飛行日志管理類,可以獲取手機端存儲的日志路徑。
        • DeviceHealthManager:設備健康管理模塊,通過此類可以實時獲取到設備的健康狀態以提醒無人機的操縱者。
        智能任務

        智能任務可以輕松實現飛行自動化。其中基于航點和航點動作定義的航點飛行任務(WaypointMission)可以使無人機沿著定義好的航點和航點動作來自動飛行,使用WaypointMissionManager來控制航點任務的執行過程,航點動作和航點任務可以由KMZ文件定義?;趯崟r命令的虛擬搖桿飛行功能,也可以讓飛機實現自動飛行,開發者可以基于自己的算法,調用VirtualStickManager中的接口來控制無人機進行自主飛行。

        空白項目集成 MSDK新建空白項目

        1、在 Android Studio 啟動頁,選擇 New Project > Phone and Tablet > Empty Activity。

        2、完成配置。

        • Name:My Application Package。
        • name:com.dji.myapplication。
        • Minimum SDK:23。

        3、compileSdkVersion 和 targetSdkVersion 為 29。

        新建 MyApplication.kt 文件

        1、新建 MyApplication.kt 文件。

        2、參照 MSDK V5 Sample 的 DJIAllApplication 編輯成如下內容。代碼的作用是引入 SDK 的解密加固包。

        package com.dji.myapplication
        import android.app.Application
        import android.content.Context
        class MyApplication : Application() {
            override fun attachBaseContext(base: Context?) {
                super.attachBaseContext(base)
                com.secneo.sdk.Helper.install(this)
            }
        }
        修改 build.gradle(Module) 文件

        1、在 dependencies 項里添加 MSDK 飛行器包,如只需全量包或手持包請參考 Sample 添加。

        implementation "com.dji:dji-sdk-v5-aircraft:5.2.0"
        implementation "com.dji:dji-sdk-v5-networkImp:5.2.0"
        compileOnly "com.dji:dji-sdk-v5-aircraft-provided:5.2.0"
        implementation 'com.squareup.okio:okio:1.15.0'
        implementation 'com.squareup.wire:wire-runtime:2.2.0'
        implementation 'com.airbnb.android:lottie:3.3.1'

        dji-sdk-v5-aircraft:飛機主包,提供 MSDK 對飛機控制的支持。dji-sdk-v5-networkImp:網絡庫包,為 MSDK 提供聯網能力。

        dji-sdk-v5-aircraft-provided:飛機編譯包,提供飛機包相關接口。

        2、在 android 項里添加 packagingOptions。

        packagingOptions {
            doNotStrip "*/*/libconstants.so"
            doNotStrip "*/*/libdji_innertools.so"
            doNotStrip "*/*/libdjibase.so"
            doNotStrip "*/*/libDJICSDKCommon.so"
            doNotStrip "*/*/libDJIFlySafeCore-CSDK.so"
            doNotStrip "*/*/libdjifs_jni-CSDK.so"
            doNotStrip "*/*/libDJIRegister.so"
            doNotStrip "*/*/libdjisdk_jni.so"
            doNotStrip "*/*/libDJIUpgradeCore.so"
            doNotStrip "*/*/libDJIUpgradeJNI.so"
            doNotStrip "*/*/libDJIWaypointV2Core-CSDK.so"
            doNotStrip "*/*/libdjiwpv2-CSDK.so"
            doNotStrip "*/*/libffmpeg.so"
            doNotStrip "*/*/libFlightRecordEngine.so"
            doNotStrip "*/*/libvideo-framing.so"
            doNotStrip "*/*/libwaes.so"
            doNotStrip "*/*/libagora-rtsa-sdk.so"
            doNotStrip "*/*/libc++.so"
            doNotStrip "*/*/libc++_shared.so"
            doNotStrip "*/*/libmrtc_28181.so"
            doNotStrip "*/*/libmrtc_agora.so"
            doNotStrip "*/*/libmrtc_core.so"
            doNotStrip "*/*/libmrtc_core_jni.so"
            doNotStrip "*/*/libmrtc_data.so"
            doNotStrip "*/*/libmrtc_log.so"
            doNotStrip "*/*/libmrtc_onvif.so"
            doNotStrip "*/*/libmrtc_rtmp.so"
            doNotStrip "*/*/libmrtc_rtsp.so"
        }
        修改 AndroidManifest.xml 文件

        1、參照 Sample 的 AndroidManifest.xml 添加 SDK 需要的最基礎權限。

        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
        <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.READ_PHONE_STATE" />

        2、參照 MSDK V5 Sample 的 AndroidManifest.xml 添加 USB 相關權限,為了連接遙控器使用。

        <uses-feature
            android:name="android.hardware.usb.host"
            android:required="false"/>
        <uses-feature
            android:name="android.hardware.usb.accessory"
            android:required="true"/>

        3、在 application 標簽下添加 Myapplication 文件的聲明,啟動的時候需要加載。

        <application
            android:name="com.dji.myapplication.MyApplication"

        4、參照 MSDK V5 Sample 的 AndroidManifest.xml 添加 SDK API KEY。用戶需要使用工程中的 AndroidManifest.xml 中的package,前往 開發者網站 申請 appkey,成功后將appkey替換如下代碼段中的X。本指導中 package=com.dji.myapplication。申請 appkey 時,Package Name 需填寫com.dji.myapplication。

        <meta-data
            android:name="com.dji.sdk.API_KEY"
            android:value="X"/>


        圖片

        5、在 activity 標簽下添加 intent-filter 和 meta-data。


        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <meta-data
            android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
            android:resource="@xml/accessory_filter" />
        修改 MainActivity.kt 文件

        添加 MSDK 的 init 函數即可。

        package com.dji.myapplication
        import android.os.Bundle
        import android.util.Log
        import androidx.appcompat.app.AppCompatActivity
        import dji.v5.common.error.IDJIError
        import dji.v5.common.register.DJISDKInitEvent
        import dji.v5.manager.SDKManager
        import dji.v5.manager.interfaces.SDKManagerCallback
        class MainActivity : AppCompatActivity() {
            private val TAG = "myApp"
            override fun onCreate(savedInstanceState: Bundle?) {
                super.onCreate(savedInstanceState)
                setContentView(R.layout.activity_main)
                registerApp()
            }
            private fun registerApp() {
                SDKManager.getInstance().init(this, object : SDKManagerCallback {
                    override fun onRegisterSuccess() {
                        Log.i(TAG, "myApp onRegisterSuccess")
                    }
                    override fun onRegisterFailure(error: IDJIError) {
                        Log.i(TAG, "myApp onRegisterFailure")
                    }
                    override fun onProductDisconnect(productId: Int) {
                        Log.i(TAG, "myApp onProductDisconnect")
                    }
                    override fun onProductConnect(productId: Int) {
                        Log.i(TAG, "myApp onProductConnect")
                    }
                    override fun onProductChanged(productId: Int) {
                        Log.i(TAG, "myApp onProductChanged")
                    }
                    override fun onInitProcess(event: DJISDKInitEvent, totalProcess: Int) {
                        Log.i(TAG, "myApp onInitProcess")
                        if (event == DJISDKInitEvent.INITIALIZE_COMPLETE) {
                            Log.i(TAG, "myApp start registerApp")
                            SDKManager.getInstance().registerApp()
                        }
                    }
                    override fun onDatabaseDownloadProgress(current: Long, total: Long) {
                        Log.i(TAG, "myApp onDatabaseDownloadProgress")
                    }
                })
            }
        }
        導入 UXSDK 開源框架

        1、將 UXSDK 項目(android-sdk-v5-uxsdk)整個復制到myapplication項目路徑的app/libs文件夾下。

        2、工具欄點擊 File > New > Import Module,選擇myapplication項目路徑的app/libs文件夾下的android-sdk-v5-uxsdk。

        3、修改settings.gradle文件。

        rootProject.name = "My Application"
        include ':app'':android-sdk-v5-uxsdk'
        project(':android-sdk-v5-uxsdk').projectDir = new File(rootDir, 'app/libs/android-sdk-v5-uxsdk/')

        4、修改build.gradle(:android-sdk-v5-uxsdk)文件中的配置和myApplication項目一致。

        apply plugin: 'com.android.library'
        apply plugin: 'kotlin-android'
        apply plugin: 'kotlin-android-extensions'
        apply plugin: 'kotlin-kapt'
        android {
            compileSdkVersion 32
            resourcePrefix "uxsdk_"
            defaultConfig {
                minSdkVersion 23
                targetSdkVersion 32
                versionCode 1
                versionName "1.0"
            }
            compileOptions {
                sourceCompatibility JavaVersion.VERSION_1_8
                targetCompatibility JavaVersion.VERSION_1_8
            }
            kotlinOptions{
                jvmTarget = JavaVersion.VERSION_1_8
            }
        }
        dependencies {
            implementation 'androidx.annotation:annotation:1.1.0'
            implementation 'androidx.appcompat:appcompat:1.3.1'
            implementation 'androidx.multidex:multidex:2.0.1'
            implementation 'androidx.legacy:legacy-support-v4:1.0.0'
            implementation 'androidx.recyclerview:recyclerview:1.1.0'
            implementation 'com.squareup.okio:okio:1.15.0'
            implementation 'com.squareup.wire:wire-runtime:2.2.0'
            implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
            implementation 'androidx.lifecycle:lifecycle-common-java8:2.3.1'
            implementation 'androidx.lifecycle:lifecycle-runtime:2.3.1'
            implementation 'androidx.lifecycle:lifecycle-process:2.3.1'
            implementation 'androidx.media:media:1.0.0'
            implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
            implementation "androidx.core:core-ktx:1.3.2"
            api 'io.reactivex.rxjava3:rxandroid:3.0.0'
            implementation 'com.airbnb.android:lottie:3.3.1'
            implementation 'androidx.cardview:cardview:1.0.0'
            api 'org.maplibre.gl:android-plugin-annotation-v9:1.0.0'
            api 'org.maplibre.gl:android-sdk-turf:5.9.0'
            api 'org.maplibre.gl:android-sdk:9.4.2'
            api 'com.amap.api:3dmap:7.3.0'
            api 'com.amap.api:search:7.3.0'
            api 'com.google.android.gms:play-services-places:16.0.0'
            api 'com.google.android.gms:play-services-maps:16.0.0'
            api 'com.google.android.gms:play-services-location:16.0.0'
            api 'com.google.android.gms:play-services-base:16.0.0'
            compileOnly "com.dji:dji-sdk-v5-aircraft-provided:5.2.0"
            compileOnly "com.dji:dji-sdk-v5-aircraft:5.2.0"
        }

        5、同步工程。

        4.X 和 5.X 版本差異說明

        以下內容主要目的是將MSDK 4.X版本和MSDK 5.X版本中的核心接口做對比和說明,其中主要包含了DJIKey類型接口的對比說明,和幾個核心模塊的差異點說明,例如SDK注冊管理類(SDKManager)、設備健康狀態管理類(DeviceHealthManager)等。

        注意:目前MSDK 4.X和5.X還不兼容,不能一起使用。MSDK 5.X 目前支持機型查看版本發布中的“支持產品列表和固件版本”,且未來只計劃支持部分DJI的新機型。

        DJIKey差異說明DJIKey

        MSDK 5.X 大多數與設備交互的功能,都是基于DJIKey來實現的,一個DJIKey代表指定模塊的具體功能。

        在4.X上,大部分接口的本質是對DJIKey的封裝,比如說Camera$startShootPhoto,其本質是CameraKey.START_SHOOT_PHOTO的應用。在后面對比表格中,對于4.X,只顯示DJIKey,而不是接口。如有特別需要說明的情況,會特殊處理。

        這里以FlightControllerState下的Motors中的方法areMotorsOn為例:先通過方法areMotorsOn在4.X文檔中,搜到areMotorsOn的方法說明,然后查詢到對應的4.X DJIKey.FlightControllerKey.ARE_MOTOR_ON,繼而在遷移文檔中找到方法areMotorsOn對應的5.X DJIKey。區別:

        圖片


        如何CreateKey

        在4.X上,DJIKey的create方法定義在各類模塊Key中,這里以CameraKey來舉例:

        1、創建主位置的Key:CameraKey。

        create(String paramKey, int componentIndex) 3、創建指定位置、指定鏡頭的Key:CameraKey$createLensKey(String paramKey, int componentIndex, int subComponentIndex)。

        在5.X上,DJIKey的create方法統一定義到KeyTools中,以CameraKey為例:

        只有一種方法,創建指定位置、指定鏡頭的DJIKey:KeyTools$createCameraKey(DJIKeyInfomKeyInfo, ComponentIndexType componentIndexType, CameraLensType cameraLensType),相關DJIKey如果不指明鏡頭的話,就用CameraLensType.CAMERA_LENS_DEFAULT(在Kotlin上,DJIKeyInfo有擴展方法createCamera,cameraLensType默認值就是CameraLensType.CAMERA_LENS_DEFAULT)。

        參數說明:

        圖片

        *博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。




        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 彰武县| 江山市| 寿光市| 彰化市| 北流市| 无极县| 柳州市| 喀什市| 金山区| 阆中市| 大荔县| 北川| 呼伦贝尔市| 黄平县| 西宁市| 楚雄市| 刚察县| 璧山县| 湖南省| 江西省| 襄垣县| 黄大仙区| 嘉荫县| 汉川市| 蓬安县| 安溪县| 孟州市| 综艺| 冕宁县| 伊春市| 合作市| 蚌埠市| 霍城县| 洛宁县| 龙陵县| 潼关县| 静海县| 苏州市| 许昌县| 湘阴县| 鄄城县|