基于MobileSDKV5版固件开发大疆无人机手机端遥控器(4)

原创 美男子玩编程 2023-06-25 12:00

点击上方蓝色字体,关注我们




相较与V4版本开发,V5版本有了更方便简介的方式。V5不仅再功能上与V4增加更多的功能,而且在功能的使用及API的调用也做了优化。虽然V5现在很新也在不断地迭代,但是不免会出现对一些飞行或者遥控器出现bug,大疆的开发人员也在不断的完善这整个V5开发包,已提供更全更优的开发模式。下面是使用V5开发包进行的大疆无人机飞控系统的开发过程。

整体架构流程

DJI Mobile SDK V5拥有更加简洁易用的无人机硬件控制接口和软件服务接口,开放全开源的生产代码及 Sample 和丰富的教程,为开发者提供了具有竞争力的无人机移动端解决方案,极大的提升开发体验和效率。现目前所支持的飞机有以下几种:

Matrice 300 RTKMatrice 30 Series

DJI Mavic 3 Enterprise Series

DJI Mavic 3MDJI 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文件定义。基于实时命令的虚拟摇杆飞行功能,也可以让飞机实现自动飞行,开发者可以基于自己的算法,调用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 需要的最基础权限。

"android.permission.ACCESS_NETWORK_STATE" />
"android.permission.ACCESS_WIFI_STATE" />
"android.permission.INTERNET" />
"android.permission.ACCESS_COARSE_LOCATION" />
"android.permission.ACCESS_FINE_LOCATION" />
"android.permission.KILL_BACKGROUND_PROCESSES"/>
"android.permission.WRITE_EXTERNAL_STORAGE" />
"android.permission.READ_EXTERNAL_STORAGE" />
"android.permission.READ_PHONE_STATE" />

2、参照 MSDK V5 Sample 的 AndroidManifest.xml 添加 USB 相关权限,为了连接遥控器使用。

    android:name="android.hardware.usb.host"
    android:required="false"/>
    android:name="android.hardware.usb.accessory"
    android:required="true"/>

3、在 application 标签下添加 Myapplication 文件的声明,启动的时候需要加载。

    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。

    android:name="com.dji.sdk.API_KEY"
    android:value="X"/>

5、在 activity 标签下添加 intent-filter 和 meta-data。


    "android.intent.action.MAIN" />
    "android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
    "android.intent.category.LAUNCHER" />


    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)。

参数说明:

往期推荐
点击阅读原文,更精彩~

美男子玩编程 多领域、有深度的开发者交流平台
评论
  • 更多生命体征指标风靡的背后都只有一个原因:更多人将健康排在人生第一顺位!“AGEs,也就是晚期糖基化终末产物,英文名Advanced Glycation End-products,是存在于我们体内的一种代谢产物” 艾迈斯欧司朗亚太区健康监测高级市场经理王亚琴说道,“相信业内的朋友都会有关注,最近该指标的热度很高,它可以用来评估人的生活方式是否健康。”据悉,AGEs是可穿戴健康监测领域的一个“萌新”指标,近来备受关注。如果站在学术角度来理解它,那么AGEs是在非酶促条件下,蛋白质、氨基酸
    艾迈斯欧司朗 2025-02-27 14:50 363浏览
  • 在2024年的科技征程中,具身智能的发展已成为全球关注的焦点。从实验室到现实应用,这一领域正以前所未有的速度推进,改写着人类与机器的互动边界。这一年,我们见证了具身智能技术的突破与变革,它不仅落地各行各业,带来新的机遇,更在深刻影响着我们的生活方式和思维方式。随着相关技术的飞速发展,具身智能不再仅仅是一个技术概念,更像是一把神奇的钥匙。身后的众多行业,无论愿意与否,都像是被卷入一场伟大变革浪潮中的船只,注定要被这股汹涌的力量重塑航向。01为什么是具身智能?为什么在中国?最近,中国具身智能行业的进
    艾迈斯欧司朗 2025-02-28 15:45 160浏览
  • RGB灯光无法同步?细致的动态光效设定反而成为产品客诉来源!随着科技的进步和消费者需求变化,电脑接口设备单一功能性已无法满足市场需求,因此在产品上增加「动态光效」的形式便应运而生,藉此吸引消费者目光。这种RGB灯光效果,不仅能增强电脑周边产品的视觉吸引力,还能为用户提供个性化的体验,展现独特自我风格。如今,笔记本电脑、键盘、鼠标、鼠标垫、耳机、显示器等多种电脑接口设备多数已配备动态光效。这些设备的灯光效果会随着音乐节奏、游戏情节或使用者的设置而变化。想象一个画面,当一名游戏玩家,按下电源开关,整
    百佳泰测试实验室 2025-02-27 14:15 132浏览
  • 一、VSM的基本原理震动样品磁强计(Vibrating Sample Magnetometer,简称VSM)是一种灵敏且高效的磁性测量仪器。其基本工作原理是利用震动样品在探测线圈中引起的变化磁场来产生感应电压,这个感应电压与样品的磁矩成正比。因此,通过测量这个感应电压,我们就能够精确地确定样品的磁矩。在VSM中,被测量的样品通常被固定在一个震动头上,并以一定的频率和振幅震动。这种震动在探测线圈中引起了变化的磁通量,从而产生了一个交流电信号。这个信号的幅度和样品的磁矩有着直接的关系。因此,通过仔细
    锦正茂科技 2025-02-28 13:30 78浏览
  • 振动样品磁强计是一种用于测量材料磁性的精密仪器,广泛应用于科研、工业检测等领域。然而,其测量准确度会受到多种因素的影响,下面我们将逐一分析这些因素。一、温度因素温度是影响振动样品磁强计测量准确度的重要因素之一。随着温度的变化,材料的磁性也会发生变化,从而影响测量结果的准确性。因此,在进行磁性测量时,应确保恒温环境,以减少温度波动对测量结果的影响。二、样品制备样品的制备过程同样会影响振动样品磁强计的测量准确度。样品的形状、尺寸和表面处理等因素都会对测量结果产生影响。为了确保测量准确度,应严格按照规
    锦正茂科技 2025-02-28 14:05 117浏览
  •         近日,广电计量在聚焦离子束(FIB)领域编写的专业著作《聚焦离子束:失效分析》正式出版,填补了国内聚焦离子束领域实践性专业书籍的空白,为该领域的技术发展与知识传播提供了重要助力。         随着芯片技术不断发展,芯片的集成度越来越高,结构也日益复杂。这使得传统的失效分析方法面临巨大挑战。FIB技术的出现,为芯片失效分析带来了新的解决方案。它能够在纳米尺度上对芯片进行精确加工和分析。当芯
    广电计量 2025-02-28 09:15 89浏览
  •           近日受某专业机构邀请,参加了官方举办的《广东省科技创新条例》宣讲会。在与会之前,作为一名技术工作者一直认为技术的法例都是保密和侵权方面的,而潜意识中感觉法律有束缚创新工作的进行可能。通过一个上午学习新法,对广东省的科技创新有了新的认识。广东是改革的前沿阵地,是科技创新的沃土,企业是创新的主要个体。《广东省科技创新条例》是广东省为促进科技创新、推动高质量发展而制定的地方性法规,主要内容包括: 总则:明确立法目
    广州铁金刚 2025-02-28 10:14 90浏览
  • 美国加州CEC能效跟DOE能效有什么区别?CEC/DOE是什么关系?美国加州CEC能效跟DOE能效有什么区别?CEC/DOE是什么关系?‌美国加州CEC能效认证与美国DOE能效认证在多个方面存在显著差异‌。认证范围和适用地区‌CEC能效认证‌:仅适用于在加利福尼亚州销售的电器产品。CEC认证的范围包括制冷设备、房间空调、中央空调、便携式空调、加热器、热水器、游泳池加热器、卫浴配件、光源、应急灯具、交通信号模块、灯具、洗碗机、洗衣机、干衣机、烹饪器具、电机和压缩机、变压器、外置电源、消费类电子设备
    张工nx808593 2025-02-27 18:04 92浏览
  • 1,微软下载免费Visual Studio Code2,安装C/C++插件,如果无法直接点击下载, 可以选择手动install from VSIX:ms-vscode.cpptools-1.23.6@win32-x64.vsix3,安装C/C++编译器MniGW (MinGW在 Windows 环境下提供类似于 Unix/Linux 环境下的开发工具,使开发者能够轻松地在 Windows 上编写和编译 C、C++ 等程序.)4,C/C++插件扩展设置中添加Include Path 5,
    黎查 2025-02-28 14:39 100浏览
  • 在物联网领域中,无线射频技术作为设备间通信的核心手段,已深度渗透工业自动化、智慧城市及智能家居等多元场景。然而,随着物联网设备接入规模的不断扩大,如何降低运维成本,提升通信数据的传输速度和响应时间,实现更广泛、更稳定的覆盖已成为当前亟待解决的系统性难题。SoC无线收发模块-RFM25A12在此背景下,华普微创新推出了一款高性能、远距离与高性价比的Sub-GHz无线SoC收发模块RFM25A12,旨在提升射频性能以满足行业中日益增长与复杂的设备互联需求。值得一提的是,RFM25A12还支持Wi-S
    华普微HOPERF 2025-02-28 09:06 101浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦