0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于Mobile SDK V4版固件开发大疆无人机手机端遥控器(1)

jf_Vqngj70R 来源:美男子玩编程 作者:美男子玩编程 2023-06-07 09:53 次阅读

刚刚结束了项目交付,趁热打铁分享一下这次遇到的新东西。首先了解一下大疆无人机,它大致可以分为三级。

入门级:适合新手,没事干在野外飞一飞拍拍风景啥的。操作也简单,基本上看飞行教程都能懂,也不需要太高的专业性,飞机也相对较小安全系数相对较高。如:御2系列的一些飞机。

消费级:形体上会比入门级的大一点,但是飞机搭载了一些高精度的东西,比如RTK、高精度摄像头、红外镜头等。这类飞机则需要飞手具备一定的专业知识,并且需要考取大疆的初级飞手证书才能上手飞行。如:精灵系列、悟系列的一些飞机。

专业级:形体上更大,操作不当会出现一些严重后果。它的优势在于高续航、高精度定位、热成像镜头、搭载第三方喊话器等。一般用于大型工程作业,使用这个级别的飞机则需要考取大疆专业飞手证书,一般这个会在你购买专业级飞机的时候赠送你培训课程,一般全部听完就能考过。这类飞机的典型代表有:M30系列、M300系列。

1SDK开发包

大疆的SDK开发包目前分为两个大版本:

v4版

Mobile SDK是一款软件开发套件,旨在让开发者能够访问DJI无人机和手持相机产品的丰富功能。该SDK通过兼顾更底层的功能,诸如飞行稳定,电池管理信号传输和通信等,简化了应用程序开发的过程。这样,开发者就不需要具备丰富的机器人嵌入式系统背景知识,而可以专注于DJI产品相关的行业应用开发。

该SDK包括:

可导入AndroidiOS应用程序的库/框架,用于访问DJI产品的功能。

飞行模拟器和可视化工具。

适用于iOS的调试工具和远程logger。

示例代码和教程。

开发者指南和API文档。

功能概述

开发者可以通过SDK访问许多DJI产品的功能。开发者可以实现自主飞行,控制相机和云台,接收实时视频图传和传感器数据,下载保存好的媒体文件,以及监听其他组件的状态。

飞行控制

Mobile SDK提供三种控制无人机飞行的方式:

手动操控: 用户使用遥控器操控无人机,而SDK支持监控实时视频流和传感器数据。虚拟摇杆命令: SDK支持产生模拟遥控器摇杆的控制指令。

智能任务: 方便,易于实现无人机的高级控制。例如,可以通过航点任务,让无人机按预定义的飞行路径飞行。

虚拟摇杆命令和智能任务允许对DJI无人机进行简单而功能强大的自主飞行控制。

相机

相机和云台的功能都支持编程调用, 例如:

相机模式: 视频和静态图像拍摄。

曝光: 快门,ISO,光圈和曝光补偿均支持定制,以实现最大的灵活性。

图像参数: 屏幕长宽比,对比度,色相,清晰度,饱和度和滤镜。

视频参数: 分辨率和帧频。

方向: 使用云台时,相机的朝向和运动可以自动控制。

实时视频流

开发者可以通过Mobile SDK获取无人机主摄像头的实时视频流。即使摄像头正在将图像或视频捕获到存储介质中,也可以获取实时视频流。

传感器数据

开发者可以通过SDK获得丰富的传感器数据。GPS位置,指南针,气压计,飞行速度和海拔高度都是通过Mobile SDK获取的一些传感器数据,频率最高可达10 Hz。

下载媒体文件

开发者通过Mobile SDK可以查看和下载保存在相机存储介质(SD卡或固态硬盘)中的照片和视频。预览图和完整的图像数据都可以被访问。

遥控器,电池和无线链路

遥控器,电池和无线链路都可以通过SDK进行访问。通常,这些组件会提供相关的状态信息,但开发者也可以对它们进行一些控制。

连接应用程序和产品

下图说明了Mobile SDK如何与移动应用程序进行融合以及如何与DJI飞行器进行连接。548a82da-046b-11ee-90ce-dac502259ad0.png对于手持摄像机产品,遥控器已替换为手持控制器,并且没有飞行器或其他无线链路。

移动应用程序由Mobile SDK,平台SDK(iOS或Android)构建而成,并在移动设备(Apple iPhone,iPad,Nexus手机,Nexus平板电脑等)上运行。

移动设备可以通过WiFi无线连接到DJI产品上,也可以通过USB线缆连接到DJI产品上。

v5版

v5版现在只适用于M30、M300系列,目前还在持续更新,因为是新版的SDK,大疆的工程师也是在不断地再完善里面的内容,这里就不详细说了,之后的文章会详细说这个v5版的SDK。

2V4版SDK 二次开发

多的不说少的不唠,上主菜。“工欲善其事,必先利其器”,首先准备好开发软件,因为我们使用的是Android版的SDK所以开发软件我们使用Android Studio,本人使用的是Android Studio Fox版,版本之间感觉都一样没有什么开发上的区别。准备好工具之后,先去大疆无人机的开发者官网注册一个开发者账号,并且注册好自己的应用,拿到sdk的专用Key值,申请的方法大疆官网有我就不赘述了。给大家个地址【大疆开发者官网】自己看吧,挺简单的。

注册成为DJI开发者

在注册过程中,需要您提供电子邮件信息和信用卡或手机号码用于注册验证。您所提供的任何信用卡信息将仅用于验证,不会收取任何费用。

本指南假定您使用 Xcode 7.3 以及 Android Studio 2.1.1 以上版本。

生成 App Key

每个应用程序都需要一个唯一的应用程序密钥(App Key)来初始化SDK。

要创建一个应用程序App Key:

请访问DJI开发者网站的 开发者中心

选择左侧栏的 "应用 "。

选择右侧的 “创建应用” 按钮。

输入应用程序的名称, 开发平台, Package Name,分类和描述信息。

会收到一封应用程序激活邮件,以完成App Key的生成。

可以在开发者中心中找到AppKey,复制粘贴到应用程序配置中。

Android 示例代码配置

下载或者克隆Github上的Android示例代码工程。

在Android Studio中打开项目工程,将生成的App Key字符串粘贴到 "AndroidManifest.xml" 文件中 "com.dji.sdk.API_KEY" meda-data element下的 android:value。

 

3Android Studio项目集成

本节中的屏幕截图是使用Android Studio 4.1生成的。

创建一个新的应用

可以使用一个新的应用程序来演示如何将DJI SDK集成到Android Studio项目中。

打开Android Studio,然后在初始屏幕上选择Start a new Android Studio project

549d4a14-046b-11ee-90ce-dac502259ad0.png

在 New Project 界面:

设置 Application name 为 "ImportSDKDemo"。

设置 Company Domain 和Package name 为 "com.dji.ImportSDKDemo"。

54c93aac-046b-11ee-90ce-dac502259ad0.png

注意:Package name是 生成App Key 所需的标识字符串。在这个工程中Package name为“com.dji.ImportSDKDemo”

54f365b6-046b-11ee-90ce-dac502259ad0.png

在 Target Android Devices 界面:

选择 Phone and Tablet 尺寸。

选择API 23:Android 6.0 (Marshmallow)。

在 Add an Activity to Mobile 界面选择 Empty Activity。

551fdf74-046b-11ee-90ce-dac502259ad0.png

在Configure Activity 界面:

设置 Activity Name: 为 "MainActivity"。

确认勾选Generate Layout File 。

设置Layout Name: 为"activity_main"。

点击Finish 。555dd8ec-046b-11ee-90ce-dac502259ad0.png

配置Gradle 脚本

在Gradle Scripts 中双击 build.gradle (Module: app)5587e844-046b-11ee-90ce-dac502259ad0.png

使用以下内容进行更新:

applyplugin:'com.android.application'

android{

...
defaultConfig{
...
}

...

packagingOptions{
doNotStrip"*/*/libdjivideo.so"
doNotStrip"*/*/libSDKRelativeJNI.so"
doNotStrip"*/*/libFlyForbid.so"
doNotStrip"*/*/libduml_vision_bokeh.so"
doNotStrip"*/*/libyuv2.so"
doNotStrip"*/*/libGroudStation.so"
doNotStrip"*/*/libFRCorkscrew.so"
doNotStrip"*/*/libUpgradeVerify.so"
doNotStrip"*/*/libFR.so"
doNotStrip"*/*/libDJIFlySafeCore.so"
doNotStrip"*/*/libdjifs_jni.so"
doNotStrip"*/*/libsfjni.so"
exclude'META-INF/rxjava.properties'
}
}

dependencies{
...
implementation('com.dji4.15',{

excludemodule:'library-anti-distortion'

})
compileOnly'com.dji4.15
}

主要变更为:

添加 packagingOptions以防止应用程序意外崩溃。

添加compile和provided依赖项以导入最新的DJIAndroid SDK Maven依赖项。

559e65ce-046b-11ee-90ce-dac502259ad0.png

选择 Tools -> Android -> Sync Project with Gradle Files 然后等待Gradle项目同步完成。

再次确认 Maven 依赖

在Android Studio菜单中选择File->Project Structure,以打开"Project Structure"界面。然后选择“app”模块,然后单击Dependencies选项卡。55def08a-046b-11ee-90ce-dac502259ad0.png

实现应用注册和SDK回调

右键单击com.dji.importSDKDemo,然后选择 New->Java Class以创建一个新的Java类,并将其命名为“MApplication”。

55f89b48-046b-11ee-90ce-dac502259ad0.png

打开MApplication.java文件,并将内容替换为以下内容:

packagecom.dji.importSDKDemo;

importandroid.app.Application;
importandroid.content.Context;

importcom.secneo.sdk.Helper;

publicclassMApplicationextendsApplication{

@Override
protectedvoidattachBaseContext(ContextparamContext){
super.attachBaseContext(paramContext);
Helper.install(MApplication.this);
}
}

在这里,重写了attachBaseContext()方法,添加了Helper.install(MApplication.this);代码。

注意:由于某些SDK类现在需要在使用之前进行加载,因此加载过程由Helper.install()完成。开发人员需要在使用任何SDK功能之前调用此方法, 否则可能会导致意外崩溃。

561c9c96-046b-11ee-90ce-dac502259ad0.png

修改完成后需要在AndroidManifest中 配置 Application name。56370874-046b-11ee-90ce-dac502259ad0.png

双击app模块中的MainActivity.java。56585b46-046b-11ee-90ce-dac502259ad0.png

MainActivity类需要注册应用程序以获得使用Mobile SDK的授权。它还需要实现SDK回调方法。

首先将MainActivity类修改为包括几个类变量,其中包括mProduct,它是代表连接到移动设备的DJI产品的对象。

另外,onCreate方法将被修改以调用checkAndRequestPermissions方法来检查和请求运行时权限。同样,checkAndRequestPermissions方法将有助于调用startSDKRegistration()方法来注册应用程序。此外,重写onRequestPermissionsResult方法将有助于检查应用程序是否具有足够的权限,如果有,请调用startSDKRegistration()方法来注册应用程序。

最后,将MainActivity类替换为:

publicclassMainActivityextendsAppCompatActivity{

privatestaticfinalStringTAG=MainActivity.class.getName();
publicstaticfinalStringFLAG_CONNECTION_CHANGE="dji_sdk_connection_change";
privatestaticBaseProductmProduct;
privateHandlermHandler;

privatestaticfinalString[]REQUIRED_PERMISSION_LIST=newString[]{
Manifest.permission.VIBRATE,
Manifest.permission.INTERNET,
Manifest.permission.ACCESS_WIFI_STATE,
Manifest.permission.WAKE_LOCK,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.CHANGE_WIFI_STATE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE,
};
privateListmissingPermission=newArrayList<>();
privateAtomicBooleanisRegistrationInProgress=newAtomicBoolean(false);
privatestaticfinalintREQUEST_PERMISSION_CODE=12345;

@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);

//Whenthecompileandtargetversionishigherthan22,pleaserequestthefollowingpermissionatruntimetoensuretheSDKworkswell.
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
checkAndRequestPermissions();
}

setContentView(R.layout.activity_main);

//InitializeDJISDKManager
mHandler=newHandler(Looper.getMainLooper());

}

/**
*Checksifthereisanymissingpermissions,and
*requestsruntimepermissionifneeded.
*/
privatevoidcheckAndRequestPermissions(){
//Checkforpermissions
for(StringeachPermission:REQUIRED_PERMISSION_LIST){
if(ContextCompat.checkSelfPermission(this,eachPermission)!=PackageManager.PERMISSION_GRANTED){
missingPermission.add(eachPermission);
}
}
//Requestformissingpermissions
if(missingPermission.isEmpty()){
startSDKRegistration();
}elseif(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
showToast("Needtograntthepermissions!");
ActivityCompat.requestPermissions(this,
missingPermission.toArray(newString[missingPermission.size()]),
REQUEST_PERMISSION_CODE);
}

}

/**
*Resultofruntimepermissionrequest
*/
@Override
publicvoidonRequestPermissionsResult(intrequestCode,
@NonNullString[]permissions,
@NonNullint[]grantResults){
super.onRequestPermissionsResult(requestCode,permissions,grantResults);
//Checkforgrantedpermissionandremovefrommissinglist
if(requestCode==REQUEST_PERMISSION_CODE){
for(inti=grantResults.length-1;i>=0;i--){
if(grantResults[i]==PackageManager.PERMISSION_GRANTED){
missingPermission.remove(permissions[i]);
}
}
}
//Ifthereisenoughpermission,wewillstarttheregistration
if(missingPermission.isEmpty()){
startSDKRegistration();
}else{
showToast("Missingpermissions!!!");
}
}
}

DJISDKManager的registerApp()方法具有一个回调,该回调需要处理两种方法:一、用于处理应用程序注册结果。二、用于通知硬件产品和移动设备的连接变更。

继续添加如下所示的 startSDKRegistration() 方法,并实现 onRegister(), onProductDisconnect(), onProductConnect(), onComponentChange(), onInitProcess() and onDatabaseDownloadProgress() 和SDKManagerCallback方法:

privatevoidstartSDKRegistration(){
if(isRegistrationInProgress.compareAndSet(false,true)){
AsyncTask.execute(newRunnable(){
@Override
publicvoidrun(){
showToast("registering,plswait...");
DJISDKManager.getInstance().registerApp(MainActivity.this.getApplicationContext(),newDJISDKManager.SDKManagerCallback(){
@Override
publicvoidonRegister(DJIErrordjiError){
if(djiError==DJISDKError.REGISTRATION_SUCCESS){
showToast("RegisterSuccess");
DJISDKManager.getInstance().startConnectionToProduct();
}else{
showToast("Registersdkfails,pleasecheckthebundleidandnetworkconnection!");
}
Log.v(TAG,djiError.getDescription());
}

@Override
publicvoidonProductDisconnect(){
Log.d(TAG,"onProductDisconnect");
showToast("ProductDisconnected");
notifyStatusChange();

}
@Override
publicvoidonProductConnect(BaseProductbaseProduct){
Log.d(TAG,String.format("onProductConnectnewProduct:%s",baseProduct));
showToast("ProductConnected");
notifyStatusChange();

}
@Override
publicvoidonComponentChange(BaseProduct.ComponentKeycomponentKey,BaseComponentoldComponent,
BaseComponentnewComponent){

if(newComponent!=null){
newComponent.setComponentListener(newBaseComponent.ComponentListener(){

@Override
publicvoidonConnectivityChange(booleanisConnected){
Log.d(TAG,"onComponentConnectivityChanged:"+isConnected);
notifyStatusChange();
}
});
}
Log.d(TAG,
String.format("onComponentChangekey:%s,oldComponent:%s,newComponent:%s",
componentKey,
oldComponent,
newComponent));

}
@Override
publicvoidonInitProcess(DJISDKInitEventdjisdkInitEvent,inti){

}

@Override
publicvoidonDatabaseDownloadProgress(longl,longl1){

}
});
}
});
}
}

最后需要实现 notifyStatusChange, Runnable 和 showToast 方法:

privatevoidnotifyStatusChange(){
mHandler.removeCallbacks(updateRunnable);
mHandler.postDelayed(updateRunnable,500);
}

privateRunnableupdateRunnable=newRunnable(){

@Override
publicvoidrun(){
Intentintent=newIntent(FLAG_CONNECTION_CHANGE);
sendBroadcast(intent);
}
};

privatevoidshowToast(finalStringtoastMsg){

Handlerhandler=newHandler(Looper.getMainLooper());
handler.post(newRunnable(){
@Override
publicvoidrun(){
Toast.makeText(getApplicationContext(),toastMsg,Toast.LENGTH_LONG).show();
}
});

}

必须授予应用程序权限,DJI SDK才能运行。

双击 app 模块中的 AndroidManifest.xml 。

56996190-046b-11ee-90ce-dac502259ad0.png

在 package=com.dji.ImportSDKDemo 后,

 

在 application 元素的开发添加 android:name=".MApplication" :


在 android:theme="@style/AppTheme"> 之后,之前插入如下代码:

 




如下所示,在activity元素中插入android:configChanges ="orientation"和android:screenOrientation ="portrait",以防止在屏幕方向变更时重启activity,并将activity的屏幕方向设置为纵向模式 :






生成App Key, 然后用App Key 字符串替换AndroidManifest.xml文件内Please enter your App Key here. 字段。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Android
    +关注

    关注

    12

    文章

    3935

    浏览量

    127352
  • Mobile
    +关注

    关注

    0

    文章

    518

    浏览量

    26483
  • 遥控器
    +关注

    关注

    18

    文章

    836

    浏览量

    66065
  • SDK
    SDK
    +关注

    关注

    3

    文章

    1035

    浏览量

    45905
  • 大疆无人机
    +关注

    关注

    13

    文章

    111

    浏览量

    30208

原文标题:基于Mobile SDK V4版固件开发大疆无人机手机端遥控器(1)

文章出处:【微信号:美男子玩编程,微信公众号:美男子玩编程】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    拆解大Mavic Air2无人机配套遥控器

    Mavic Air2遥控器内部多使用螺丝或卡扣固定部件,伸缩式天线一体化手机支架将原来位于遥控器下方的手机移到了手机上方,方便观察
    的头像 发表于 07-21 13:37 2.8w次阅读
    拆解大<b class='flag-5'>疆</b>Mavic Air2<b class='flag-5'>无人机</b>配套<b class='flag-5'>遥控器</b>

    无人机遥控方向控制问题

    前段时间我弟弟买了个遥控无人机玩具,但是我发现一个问题。该无人机方向控制有问题,假设无人机有四个电机,分别为A,B,C,D,遥控器四个按键
    发表于 05-10 11:26

    stm32四轴无人机遥控器资料

    stm32四轴无人机遥控器资料
    发表于 06-09 23:16

    无人机怎么悬停

    `  谁能阐述下大无人机怎么悬停?`
    发表于 08-27 15:13

    【飞控教程1】开源编队无人机-开机测试

    OLED 左上角的频道开始递增时,即可松手,此时进入自动对频,对频成功后,OLED 左上角的“X”消失,变成信号格。连接上无人机后,可以查看飞机的传感是否运行正常,查看方法为:1)在遥控器
    发表于 04-20 11:48

    【快速上手教程6】疯壳·开源编队无人机-遥控器固件烧写

    COCOFLY 教程——疯壳·无人机·系列遥控器固件烧写 图1 一、遥控器固件烧写 这里的
    发表于 05-25 11:49

    【快速上手教程6】疯壳·开源编队无人机-遥控器固件烧写

    COCOFLY 教程——疯壳·无人机·系列遥控器固件烧写 图1 一、遥控器固件烧写 这里的
    发表于 07-07 10:05

    【疯壳·无人机教程6】开源编队无人机-遥控器固件烧写

    COCOFLY 教程——疯壳·无人机·系列遥控器固件烧写图1 一、遥控器固件烧写 这里的
    发表于 08-23 17:49

    CES 2019:大推出带屏无人机遥控器 便携式无线电源Yoolox亮相

    现如今航拍已成为年轻人的拍摄兴趣,但智能手机好像并不是最理想控制航拍的遥控器。作为无人机生产厂家,大在今年的国际消费类电子产品展览会上展出了专为Mavic 2航拍
    的头像 发表于 01-10 16:16 8037次阅读

    发布沉浸式飞行无人机DJI FPV

    DJI 大创新正式发售沉浸式飞行无人机DJI FPV,并以套装形式发售,其中包含飞行遥控器、飞行眼镜、1块智能飞行电池、2对桨叶等配件
    的头像 发表于 03-04 09:50 3843次阅读

    音圈马达装置在大无人机的应用

    音圈马达助力的大将发布多款新品,大家都知道大是一家专业生产无人机的厂家,就在近日,大新公布的一份专利文件中,发现大已经申请了一款新的
    发表于 08-31 15:55 731次阅读

    基于Mobile SDK V4固件开发无人机手机遥控器(2)

    上一篇文章(基于Mobile SDK V4固件开发无人
    的头像 发表于 06-09 11:33 987次阅读
    基于<b class='flag-5'>Mobile</b> <b class='flag-5'>SDK</b> <b class='flag-5'>V4</b>版<b class='flag-5'>固件</b><b class='flag-5'>开发</b>大<b class='flag-5'>疆</b><b class='flag-5'>无人机手机</b><b class='flag-5'>端</b><b class='flag-5'>遥控器</b>(2)

    基于Mobile SDK V4固件开发无人机手机遥控器(3)

    第三篇文章准备单独拿出来写,因为在大人机的所有功能中,航线规划的功能最为复杂,也相当的繁琐,这里需要说仔细一点,可能会将代码进行多步分解。
    的头像 发表于 06-15 12:22 1544次阅读
    基于<b class='flag-5'>Mobile</b> <b class='flag-5'>SDK</b> <b class='flag-5'>V4</b>版<b class='flag-5'>固件</b><b class='flag-5'>开发</b>大<b class='flag-5'>疆</b><b class='flag-5'>无人机手机</b><b class='flag-5'>端</b><b class='flag-5'>遥控器</b>(3)

    基于Mobile SDK V5版固件开发无人机手机遥控器(4)

    相较与V4版本开发V5版本有了更方便简介的方式。V5不仅再功能上与V4增加更多的功能,而且在功能的使用及API的调用也做了优化。虽然
    的头像 发表于 06-25 12:24 2575次阅读
    基于<b class='flag-5'>Mobile</b> <b class='flag-5'>SDK</b> <b class='flag-5'>V</b>5版<b class='flag-5'>固件</b><b class='flag-5'>开发</b>大<b class='flag-5'>疆</b><b class='flag-5'>无人机手机</b><b class='flag-5'>端</b><b class='flag-5'>遥控器</b>(<b class='flag-5'>4</b>)

    基于Mobile SDK V5版固件开发无人机手机遥控器(5)

    v5.x版本的功能与v4.x基本相同,都是获取飞机的姿态信息、获取无人机多媒体文件、操作多媒体文件、航线规划等。不过在上一章节中也大致说了一些两个版本的中API的差别,下面是根据一些API使用所完成的一些功能,因为项目原因只能提
    的头像 发表于 07-07 12:21 2305次阅读
    基于<b class='flag-5'>Mobile</b> <b class='flag-5'>SDK</b> <b class='flag-5'>V</b>5版<b class='flag-5'>固件</b><b class='flag-5'>开发</b>大<b class='flag-5'>疆</b><b class='flag-5'>无人机手机</b><b class='flag-5'>端</b><b class='flag-5'>遥控器</b>(5)