"); //-->
概要
相较与V4版本开发,V5版本有了更方便简介的方式。V5不仅再功能上与V4增加更多的功能,而且在功能的使用及API的调用也做了优化。虽然V5现在很新也在不断地迭代,但是不免会出现对一些飞行或者遥控器出现bug,大疆的开发人员也在不断的完善这整个V5开发包,已提供更全更优的开发模式。下面是使用V5开发包进行的大疆无人机飞控系统的开发过程。
整体架构流程DJI Mobile SDK V5拥有更加简洁易用的无人机硬件控制接口和软件服务接口,开放全开源的生产代码及 Sample 和丰富的教程,为开发者提供了具有竞争力的无人机移动端解决方案,极大的提升开发体验和效率。现目前所支持的飞机有以下几种:
Matrice 300 RTK
Matrice 30 Series
DJI Mavic 3 Enterprise Series
DJI Mavic 3M
DJI Mini 3
DJI Mini 3 Pro
现目前V5 SDK 有下面几种功能:
Mobile SDK的体系结构被设计为高度可扩展的,其中使用了抽象产品类和组件类,以便应用程序可以使用相同的代码控制不同的产品。对于一些没法在不同产品中保持一致性的功能可以在运行时被查询调用,对于一些能保持一致性的功能则直接可以工作了。
例如,Phantom和Inspire系列产品的绝大多数功能是一致的。因此,为适配Phantom 4而编写的应用程序,除Inspire 1的一些独特功能外,将可以直接在Inspire 1机型上使用。
这也意味着当新产品发布时,就已经可以与现有的应用程序一起使用了(需要使用支持该新产品的最新SDK)。新产品中的任何新功能都需要添加到应用程序中,但是所有现有功能都不需要做修改了。
层级架构移动应用程序一般通过下图所示的几个主要类来访问Mobile SDK:
智能任务可以轻松实现飞行自动化。其中基于航点和航点动作定义的航点飞行任务(WaypointMission)可以使无人机沿着定义好的航点和航点动作来自动飞行,使用WaypointMissionManager来控制航点任务的执行过程,航点动作和航点任务可以由KMZ文件定义。基于实时命令的虚拟摇杆飞行功能,也可以让飞机实现自动飞行,开发者可以基于自己的算法,调用VirtualStickManager中的接口来控制无人机进行自主飞行。
空白项目集成 MSDK新建空白项目1、在 Android Studio 启动页,选择 New Project > Phone and Tablet > Empty Activity。
2、完成配置。
3、compileSdkVersion 和 targetSdkVersion 为 29。
新建 MyApplication.kt 文件1、新建 MyApplication.kt 文件。
2、参照 MSDK V5 Sample 的 DJIAllApplication 编辑成如下内容。代码的作用是引入 SDK 的解密加固包。
package com.dji.myapplication修改 build.gradle(Module) 文件
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)
}
}
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 {修改 AndroidManifest.xml 文件
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"
}
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>修改 MainActivity.kt 文件
<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" />
添加 MSDK 的 init 函数即可。
package com.dji.myapplication导入 UXSDK 开源框架
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")
}
})
}
}
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)等。
DJIKey差异说明DJIKey注意:目前MSDK 4.X和5.X还不兼容,不能一起使用。MSDK 5.X 目前支持机型查看版本发布中的“支持产品列表和固件版本”,且未来只计划支持部分DJI的新机型。
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。区别:
在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)。
参数说明:
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。