本节全篇为开发流程,内容较多,只记录android部分
开发流程(1)
预备知识
使用DJI Mobile SDK开发应用程序需要几个通用的和平台特定的先决条件。
生成
- 了解如何去开发一个IOS或Android应用程序
- 一个与DJI Mobile SDK兼容的DJI产品。兼容产品列表
- 信用卡或电话号码用于大疆开发者注册验证(不收费)。
- 至少一个兼容iOS或Android的移动设备。
注意: 对于iOS,可以使用两个移动设备来更轻松地进行调试和分析。
iOS
- Xcode 7.0+或更高版本
- iOS 8.1或更高版本的部署目标
- iOS开发者帐户
- 设备支持
- iPhone 5s或更高版本
- iPad Pro,iPad Air 2,iPad Mini 2或更高版本
- iPod Touch 5或更高版本
Android
- Android API等级19或更高
- Android Studio 1.5或更高版本
- 设备支持:Samsung S7, Samsung S8, Samsung tabs 705c, Samsung S6, Samsung S5, Samsung NOTE4, Samsung NOTE3, Google Pixel, Google Nexus 9, Google Nexus 7 II, Ascend Mate7, Huawei Mate 8, Nubia Z7 mini, SONY Xperia Z3, MI 3, MI PAD
注意:随着测试和开发的继续,支持更多的Android设备。
注册为DJI开发者并下载SDK
注册为开发者
注册一个DJI开发者账号在这里。
在注册过程中,需要提供电子邮件信息和信用卡或电话号码以验证注册。所提供的任何信用卡信息仅用于验证,不会收取费用。
下载DJI Mobile SDK
从这里下载适用于iOS或Android的DJI Mobile SDK:http://developer.dji.com/mobile-sdk/downloads.
集成SDK到应用程序
下面的示例将DJI SDK导入一个新的iOS和Android项目。同样的步骤也可以用于集成到现有的应用程序中。
Xcode项目集成
Android Studio 项目集成
截图使用 Android Studio 3.0
创建一个新项目
一个新的应用程序可以用来展示如何将DJI SDK集成到Android Studio项目中。
打开 Android Studio 并且在初始屏幕上选择Start a new Android Studio project
-
在New Project 框中:
- 将 Application name 设置为“ImportSDKDemo”。
- Set the Company Domain and Package name to "com.dji.importSDKDemo".(注意:大疆文档这里的import是Import,改成小写即可,见下图)
注意: Package name 是生成App Key 所必需的标识字符串。下面的
activity.java
、manifest.xml
和Gradle脚本代码假定包名为“com.dji.ImportSDKDemo”
- 在Target Android Devices中:
- 选择 Phone and Tablet
- 选择 API 19: Android 4.4 (KitKat).
在 Add an Activity to Mobile 中选择 Empty Activity.
-
在 Configure Activity 中:
- 设置 Activity Name: 为 "MainActivity".
- 勾选 Generate Layout File
- 设置 Layout Name: 为 "activity_main".
- 点击完成
配置Grade脚本
- 打开 build.gradle (Module: app)
- 更新内容如下:
apply plugin: '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"
exclude 'META-INF/rxjava.properties'
}
}
dependencies {
...
compile ('com.dji:dji-sdk:4.9')
provided ('com.dji:dji-sdk-provided:4.9')
}
-
主要变更应为:
- 添加
packagingOptions
以防止应用程序发生任何意外崩溃。 - 添加
compile
和provided
依赖来导入最新的DJI Android SDK Maven依赖。 - 点击 Sync Now 并等待Gradle项目同步完成。
note: 这里要注意的是,compile和provided会产生两个警告,声明作废:分别用implementation和compileOnly代替,本例还是继续跟随大疆文档进行,实际开发中注意修正。
- 添加
-
双重检查 Maven依赖
- 选择 File->Project Structure 来打开“Project Structure”窗口。然后选择 "app" 模块并且点击 Dependencies . 你应该看到最新的DJI SDK已经编译完成,并且提供了已经导入的依赖。
实现应用注册和SDK回调
右键点击com.dji.importSDKDemo
,并选择New->Java Class创建一个新的Java类,并将其命名为“MApplication”。
打开 MApplication.java 并替代如下内容:
package com.dji.importSDKDemo;
import android.app.Application;
import android.content.Context;
import com.secneo.sdk.Helper;
public class MApplication extends Application {
@Override
protected void attachBaseContext(Context paramContext) {
super.attachBaseContext(paramContext);
Helper.install(MApplication.this);
}
}
这里我们重写attachBaseContext()
方法来添加Helper.install(MApplication.this);
这行代码。
注意: 由于现在需要在使用之前加载一些SDK类,所以加载过程由
Helper.install()
完成。开发者需要在使用任何SDK功能之前调用此方法。如果不这样做,将导致意外的崩溃。
打开 MainActivity.java:
MainActivity类需要注册应用程序才能获得使用DJI Mobile SDK的授权。它还需要实现SDK期望的回调方法。
MainActivity类将首先被修改为包含几个类变量,包括“mProduct”,该对象表示连接到移动设备的DJI产品。
此外,onCreate
方法将被修改为调用checkAndRequestPermissions
方法来检查和请求运行时权限。此外,checkAndRequestPermissions
方法将帮助调用startSDKRegistration()
方法来注册应用程序。而且,重写onRequestPermissionsResult
方法将帮助检查应用程序是否有足够的权限,如果有,调用startSDKRegistration()
方法来注册应用程序。
现在,替换 MainActivity 类为:
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getName();
public static final String FLAG_CONNECTION_CHANGE = "dji_sdk_connection_change";
private static BaseProduct mProduct;
private Handler mHandler;
private static final String[] REQUIRED_PERMISSION_LIST = new String[]{
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,
};
private List<String> missingPermission = new ArrayList<>();
private AtomicBoolean isRegistrationInProgress = new AtomicBoolean(false);
private static final int REQUEST_PERMISSION_CODE = 12345;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// When the compile and target version is higher than 22, please request the following permission at runtime to ensure the SDK works well.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkAndRequestPermissions();
}
setContentView(R.layout.activity_main);
//Initialize DJI SDK Manager
mHandler = new Handler(Looper.getMainLooper());
}
/**
* Checks if there is any missing permissions, and
* requests runtime permission if needed.
*/
private void checkAndRequestPermissions() {
// Check for permissions
for (String eachPermission : REQUIRED_PERMISSION_LIST) {
if (ContextCompat.checkSelfPermission(this, eachPermission) != PackageManager.PERMISSION_GRANTED) {
missingPermission.add(eachPermission);
}
}
// Request for missing permissions
if (missingPermission.isEmpty()) {
startSDKRegistration();
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
showToast("Need to grant the permissions!");
ActivityCompat.requestPermissions(this,
missingPermission.toArray(new String[missingPermission.size()]),
REQUEST_PERMISSION_CODE);
}
}
/**
* Result of runtime permission request
*/
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// Check for granted permission and remove from missing list
if (requestCode == REQUEST_PERMISSION_CODE) {
for (int i = grantResults.length - 1; i >= 0; i--) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
missingPermission.remove(permissions[i]);
}
}
}
// If there is enough permission, we will start the registration
if (missingPermission.isEmpty()) {
startSDKRegistration();
} else {
showToast("Missing permissions!!!");
}
}
}
DJISDKManager
的registerApp()
方法有一个回调函数,它需要处理两个方法来处理APP注册结果,以及当连接到移动设备的产品发生变更时。
继续添加如下所示的startSDKRegistration()
方法,并实现SDKManagerCallback
的onRegister()
, onProductDisconnect()
, onProductConnect()
和 onComponentChange()
方法:
private void startSDKRegistration() {
if (isRegistrationInProgress.compareAndSet(false, true)) {
AsyncTask.execute(new Runnable() {
@Override
public void run() {
showToast("registering, pls wait...");
DJISDKManager.getInstance().registerApp(MainActivity.this.getApplicationContext(), new DJISDKManager.SDKManagerCallback() {
@Override
public void onRegister(DJIError djiError) {
if (djiError == DJISDKError.REGISTRATION_SUCCESS) {
showToast("Register Success");
DJISDKManager.getInstance().startConnectionToProduct();
} else {
showToast("Register sdk fails, please check the bundle id and network connection!");
}
Log.v(TAG, djiError.getDescription());
}
@Override
public void onProductDisconnect() {
Log.d(TAG, "onProductDisconnect");
showToast("Product Disconnected");
notifyStatusChange();
}
@Override
public void onProductConnect(BaseProduct baseProduct) {
Log.d(TAG, String.format("onProductConnect newProduct:%s", baseProduct));
showToast("Product Connected");
notifyStatusChange();
}
@Override
public void onComponentChange(BaseProduct.ComponentKey componentKey, BaseComponent oldComponent,
BaseComponent newComponent) {
if (newComponent != null) {
newComponent.setComponentListener(new BaseComponent.ComponentListener() {
@Override
public void onConnectivityChange(boolean isConnected) {
Log.d(TAG, "onComponentConnectivityChanged: " + isConnected);
notifyStatusChange();
}
});
}
Log.d(TAG,
String.format("onComponentChange key:%s, oldComponent:%s, newComponent:%s",
componentKey,
oldComponent,
newComponent));
}
});
}
});
}
}
最后,需要实现 notifyStatusChange
、Runnable
和showToast
方法:
private void notifyStatusChange() {
mHandler.removeCallbacks(updateRunnable);
mHandler.postDelayed(updateRunnable, 500);
}
private Runnable updateRunnable = new Runnable() {
@Override
public void run() {
Intent intent = new Intent(FLAG_CONNECTION_CHANGE);
sendBroadcast(intent);
}
};
private void showToast(final String toastMsg) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), toastMsg, Toast.LENGTH_LONG).show();
}
});
}
为了让DJI SDK运行,应用程序必须被授权。
- 打开 app 模块中的AndroidManifest.xml 。
- 在
package=com.dji.ImportSDKDemo
之后和<application
之前插入:
<!-- Permissions and features -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature
android:name="android.hardware.usb.host"
android:required="false" />
<uses-feature
android:name="android.hardware.usb.accessory"
android:required="true" />
<!-- Permissions and features -->
- 在
application
元素开头添加android:name=".MApplication"
<application
android:name=".MApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
- 在
android:theme="@style/AppTheme">
之后和<activity android:name=".MainActivity">
之前插入以下内容:
<!-- DJI SDK -->
<uses-library android:name="com.android.future.usb.accessory" />
<meta-data
android:name="com.dji.sdk.API_KEY"
android:value="Please enter your App Key here." /> // 这里替换为注册的App Key
<activity
android:name="dji.sdk.sdkmanager.DJIAoaControllerActivity"
android:theme="@android:style/Theme.Translucent" >
<intent-filter>
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
</intent-filter>
<meta-data
android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
android:resource="@xml/accessory_filter" />
</activity>
<service android:name="dji.sdk.sdkmanager.DJIGlobalService" >
</service>
<!-- DJI SDK -->
生成App Key, 并替换 "Please enter your App Key here."
- 在
activity
元素中插入android:configChanges="orientation"
和android:screenOrientation="portrait"
,如下图所示,防止activity在屏幕方向改变时重启,并将activity的屏幕方向设置为竖屏模式:
<activity android:name=".MainActivity"
android:configChanges="orientation"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
运行导入SDK Demo
ImportSDKDemo 项目现在可以运行了。也可以从 Github 下载这个项目的示例代码。
由于此应用程序只检查注册,而不直接与产品交互,因此不需要将任何产品连接到应用程序即可运行。因此,该应用程序既可以在移动设备上运行(连不连接DJI产品都行),也可以在Android模拟器中运行。应用程序需要网络连接才能成功地执行注册。(不知道为什么我用模拟器注册失败,sdk中间件jni报错,真机注册成功)
如果App Key生成正确,且Android模拟器或移动设备具备网络连接,则应看到:
FFmpeg License
DJI Android SDK是动态链接到LGPLv2.1许可的未修改的FFmpeg库。Github提供了这些FFmpeg库的源代码、编译说明和LGPL v2.1许可。Github提供了这些FFmpeg库的源代码、编译说明和LGPL v2.1许可。
运行APP
准备产品
应检查每个产品的用户手册以理解完整的产品设置(访问http://www.dji.com并导航到每个产品的下载页)。本节详细介绍了一些需要记住的要点。
充电电池
通常,在运行应用程序之前,应对产品的所有电池充电以获得最佳体验。这可能包括飞机电池,遥控器电池,手持云台电池和飞机安装的云台电池(用于Ronin MX)。当电池电量过低时,飞机可能会在应用程序中更早的返航或着陆,或者根本不起飞。
激活产品
在首次使用之前,任何新产品都需要通过DJI GO激活。DJI GO可在 iOS App Store 和 Google Store 上使用,可用于激活产品。
重定向到DJI Go 应用程序
如果SDK应用程序需要重定向到DJI Go Apps来做像激活DJI产品这样的操作,你可以使用以下代码来实现它:
iOS
- 重定向到DJI Go 4 App:使用URL方案
"djiVideoNew://"
- 重定向到DJI Go App:使用URL方案
"djiVideo://"
Android
- 重定向到DJI Go 4 App:
Intent launchIntent = getPackageManager().getLaunchIntentForPackage("dji.go.v4");
if (launchIntent != null) { //null pointer check in case package name was not found 空指针检查以防包名没被找到
startActivity(launchIntent);
}
- 重定向到DJI Go App:
Intent launchIntent = getPackageManager().getLaunchIntentForPackage("dji.pilot");
if (launchIntent != null) { //null pointer check in case package name was not found
startActivity(launchIntent);
}
有关更多详细信息,请查看Github示例代码: iOS SDK Github Sample, Android SDK Github Sample.
升级产品固件
飞机、遥控器和/或手持控制器固件应在开始应用程序测试和调试之前更新到最新版本。不同的产品有时会有不同的检查固件版本和升级固件的过程。在 http://www.dji.com 中每个产品页的 Downloads 模块都有升级固件的说明。
遥控器飞行模式开关
对于飞机,遥控器FAP或ASP飞行模式开关需要处于特定位置才能接收改变飞行方向和自动飞行的SDK命令。遥控器和飞机有时可以互换,因为FAP / ASP开关配置有多种选择。
Aircraft | Remote Controller | Switch |
---|---|---|
P3, Inspire (all models) | P3, Inspire (all models) | F |
P3, Inspire (all models) | P4 | A |
P4 | P3, Inspire (all models) | P |
P4 | P4 | P |
网络连接
任何SDK应用程序在首次运行时都需要互联网连接才能向DJI注册并获得使用SDK的授权。首次成功注册后,授权将存储在本地,且注册时无需网络连接。
连接移动设备并运行应用程序
移动设备和产品之间有几种连接配置:
- 移动设备 -> USB -> 遥控器 -> Lightbridge / OcuSync -> 飞机
- 移动设备 -> WiFi -> 遥控器 -> WiFi - >飞机
- 移动设备 -> WiFi -> 手持云台
有几种方法可以初始化所有产品并运行应用程序。下面给出USB和WiFi连接场景的示例。
USB连接程序
Mavic Pro,Phantom 4,Phantom 4 Professional,Phantom 3 Professional,Phantom 3 Advanced,Inspire系列,Matrice系列:
打开遥控器。
- 打开飞机并等待遥控器与飞机连接。
- 使用 Lightning(iOS)或 USB(Android)导线将 iOS / Android 移动设备连接到遥控器。
- 在移动设备上运行应用程序。
注意:
如果使用Android设备,DJI遥控器需要支持AOA . 所有最新版本的固件都支持AOA。如果Sample Application与Android设备连接,则会支持AOA,会出现类似下面的对话框:
要了解如何更改USB附件的默认应用程序,请查看以下两个常见问答:Android Device, Samsung Device.
WiFi连接程序
Phantom 3 Standard,Phantom 3 4K,Spark:
打开遥控器
- 将移动设备连接到遥控器创建的WiFi网络。
- 打开飞机并等待遥控器与飞机连接。
- 在移动设备上运行应用程序。
Osmo,Mavic Pro,Spark:
- 打开产品(Osmo或飞机)。
- 将移动设备连接到产品创建的WiFi网络。
- 在移动设备上运行应用程序
测试、分析和调试
应用程序开发需要大量的测试、分析和调试。DJI提供的工具包括飞机模拟器、无线桥接app和远程日志功能,使开发更快更方便。
飞行模拟器
DJI飞机产品包括一个驻留在飞行控制器中的模拟器,可以:
- 从遥控器(手动飞行)或应用程序(SDK命令)获取飞机控制输入
- 基于输入在模拟环境中模拟飞机行为
- 基于模拟行为输出飞机状态信息
这使得手动和自动飞行都可以模拟,而无需实际驾驶飞机。
DJI提供Windows和Mac工具,可用于初始化模拟器,并根据模拟器提供的状态信息显示飞机的行为:
- DJI Assistant 2 ( Windows 或 Mac ) 用于Spark,Mavic Pro,Phantom 4系列和Matrice系列等新型飞机。
- DJI PC Simulator ( Windows ) 用于Phantom 3系列,Inspire 1系列飞机。
此外,可以通过SDK直接控制模拟器初始化,监听和终止,从而允许在持续集成环境中进行应用程序开发。
DJI Assistant 2模拟器
DJI Assistant 2工具是专门为SDK开发人员构建的,可以初始化、终止并提供在DJI飞机飞行控制器中运行的飞机模拟器的可视化。DJI Assistant 2通过USB连接到飞机。
- 支持大疆产品:Spark、Mavic Pro、Matrice系列、Phantom 4系列、Inspire 2。
- 支持的操作系统:Mac OS X 10、Windows 7、Windows 8和Windows 8.1
注意: Windows 10不受官方支持,但通常可以工作。
安装和设置
Mac
- 从Mac下载 DJI Assistant 2
- 双击驱动程序并按照说明安装它。
- 打开下载的 DMG 文件。
- 把 Assistant.app 拖进系统的 Applications 文件夹。
Windows
- 从Windows下载 DJI Assistant 2
- 运行安装程序
- 按照说明安装
- 在安装过程中,确认安装程序的请求。
使用 DJI Assistant 2
在启动时,将出现一个请求将DJI Assistant 2连接到飞机的窗口。
通过 USB连接线 连接到Mac或PC的飞机。
打开遥控器,然后打开飞机。几秒钟后,应用程序将检测到飞机。
在连接设备页选择 "Mavic Pro" ,然后选择左侧的 Simulator 选项卡。应该看到以下屏幕:
按 Open 按钮,输入所需的起始纬度和经度以及所需的风速。
按下 Start Emulating 按钮。将会显示连接的产品,以及一些位置和速度状态信息。
Note: 正向世界坐标系X,Y和Z分别为北,东和上方向。
使用遥控器起飞和飞行以试验模拟器。
视图角度可以通过在可视化窗口中左键单击和拖动来更改。在窗口内滚动可以缩放。
飞行时,可以通过右击可视化并选择 Setup 来追踪飞行路径。
然后在模拟器UI配置选项卡下选择 show trace 显示飞行轨迹,如下图所示:
然后将飞行路径跟踪添加到可视化中。
DJI PC 模拟器
DJI PC模拟器工具是专门为SDK开发人员开发的,可以对DJI飞机飞行控制器中运行的飞机模拟器进行初始化、终止和可视化。DJI PC模拟器工具通过USB连接到飞机。
- 支持大疆产品:Phantom 3系列、Inspire 1系列。
- 支持的操作系统:Windows 7、Windows 8、Windows 8.1
Note: Windows 10不受官方支持,但通常可以工作。
安装和设置
- 下载 DJI PC模拟器安装程序和用户手册 以及 WIN驱动安装程序 :http://developer.dji.com/mobile-sdk/downloads/
- 运行 Win Driver Installer
- 对于早期产品兼容性,会出现一个显示消息内容为 Please power on MC and connect it to PC via USB! 的对话框。
- 现在不需要任何操作,按 Yes 继续。
- 按照其余的安装步骤操作。
- 运行DJI PC Simulator Installer
- 按照安装步骤完成安装。
使用 DJI PC 模拟器
该 DJI PC Simulator 既可以运行在Windows PC上,也可以运行在Mac的虚拟机上(如Parallels或VMWare)。
首先使用USB将Windows PC连接到飞机并打开飞机。
启动 DJI PC Simulator 来配置和初始化飞机模拟器。设置经度和经度进行模拟。
Note: 如果经纬度太接近或进入GEO区域,飞机将无法起飞。
如果飞机处于开机状态并与PC机连接,则序列号应显示在 ** SN:** 文本视图中。
选择 Log Settings 选项卡下的 show log window 以显示日志窗口。
返回 Simulator Control 选项卡,按 Start Simulation 启动飞机模拟器。此时,飞机将在不实际启动电机的情况下模拟飞行。
按 Display Simulation 以启动可视化。
使用遥控器起飞和飞行以试验模拟器。
可视化将显示连接的产品(在本例中为Inspire 1),以及一些位置和速度状态信息。
Note: 正向世界坐标系的X,Y和Z分别为北,东和上方向。
视图角度可以通过在可视化窗口中左击并拖动来更改。在窗口内滚动可以缩放。
While flying, the flight path can be traced by right clicking on the visualization and selecting Setup.
飞行时,可以通过右击可视化并选择 Setup 来跟踪飞行路径。
然后在模拟器UI配置选项卡下选择 show trace 以显示飞行轨迹,如下所示:
然后飞行路径轨迹将添加到可视化中。
在 Simulator Config 窗口中,可以按下 Stop Simulation 来停止模拟。
重要提示: 要在中途停止Waypoint Mission,请从应用程序中停止任务,然后停止模拟器。否则,模拟器可以在重启时继续运行先前的Waypoint Mission。
有关更多 DJI PC Simulator 的信息,请在查看下载的 DJI PC Simulator 中包含的用户手册pdf文件。
持续集成模拟
DJI Assistant 2 和 DJI PC Simulator 都提供飞机模拟器的可视化,这需要PC或Mac连接到飞机。
如果不需要可视化,DJI SDK可用于启动和停止模拟器。这意味着可以在没有飞机连接到Mac或PC的情况下执行模拟,从而允许在连续集成环境中进行自动测试。
DJIFlightController
中的 DJISimulator
类被用于控制模拟。该类提供以下功能:
- 启动和停止模拟
- 使用GPS定位进行播放模拟 Seed the simulation with a GPS location
- 检索飞机对于世界的状态信息。
在项目中使用模拟器提供示例代码:iOS | Android.
无线桥接App
对于Android和iOS,当移动设备通过USB线直接连接到Android Studio或Xcode时,应用程序开发最有效率。
然而,一些DJI飞机需要飞机的遥控器和移动设备之间的直接连接。这意味着应用程序无法通过USB直接连接到开发环境。
对于Android,ADB通过WiFi可以实现实时开发,但iOS没有这样的选项。
因此,DJI提供无线桥接App或 Bridge App。
- Bridge App直接连接到遥控器。
- 运行开发者的应用程序的移动设备已连接到Mac。
- SDK将所有飞机通信从USB重新路由到与Bridge App设备的WiFi连接。
Note: 如果只有一个移动设备可用,Bridge App也可以在iOS模拟器上运行。在这种情况下,移动设备将承载 bridge app,而开发者应用程序在iOS模拟器上运行。
SDK Bridge App由DJI提供,可以从 Apple App Store 下载。
使用 DJI Bridge App 的教程 here.
远程日志
在现场测试应用程序时,通常需要某种形式的日志记录来理解行为。
对于iOS,可以设置DJI Mobile SDK来允许远程日志记录。如果移动设备有网络连接,则可以将在飞行期间生成的消息记录到远程服务器。
这里有一个描述如何使用远程日志的教程。 here.
部署
使用DJI Mobile SDK部署Android应用程序不需要任何典型流程之外的额外步骤。
然而iOS应用程序需要适当的Xcode配置。如果支持的DJI产品是MFi附件,还需要MFi附件授权。