大疆 DJI Mobile SDK 开发:模拟器调试
目錄
創建飛行控制器界面
1.新建Activiity
2.MainActivity
activity_main.xml
MainActivity.java
3.FlightActivity
activity_flight.xml
FlightActivity.java
4.AndroidManifest
DJI Mobile SDK的回調方法
?起飛、降落與返航的實現
獲取控制器
API Reference:FlightController()
起飛與取消起飛
API Reference:startTaskoff()、cancelTaskoff()
降落與取消降落
API Reference:startLanding()、cancelLanding()
返航與取消返航
API Reference: startGoHome()、cancelGoHome()
返航高度的設置與獲取
?API Reference: setGoHomeHeightInMeters()、getGoHomeHeightInMeters()
自定義提示
?
創建飛行控制器界面
1.新建Activiity
????????在 “com.dji.importSDKDemo” 包上單擊右鍵,新建一個名稱為 FlightActivity、布局名為 activity_flight 的活動。
2.MainActivity
activity_main.xml
????????在 MainActivity 布局文件 activity_main.xml 中添加一個名為 “飛行控制器” 的按鈕
<Buttonandroid:id="@+id/fight_controller"android:layout_width="match_parent"android:layout_height="wrap_content"app:layout_constraintTop_toTopOf="parent"app:layout_constraintBottom_toBottomOf="parent"android:layout_marginTop="15dp"android:text="飛行控制器"android:textSize="25sp"/>MainActivity.java
????????要在 MainActivity 中實現單擊 “飛行控制器” 按鈕跳轉到 FlightActivity 頁面的代碼,即在 MainActivity.java 文件中的 initUI() 函數的最后加入如下代碼
private void initUI() {…………Button fight_controller = (Button) findViewById(R.id.fight_controller);fight_controller.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {if (checkDroneConnection() == false) {return;}//彈出FlightActivityIntent i = new Intent(MainActivity.this, FlightActivity.class);startActivity(i);}});}? ? ? ? ?在單擊 “飛行控制器” 按鈕跳轉到 FlightActivity 頁面前,需要判斷應用程序激活注冊、狀態,以及無人機綁定、連接等是否正常。故在 initUI() 方法后添加 checkDroneConnection() 方法來判斷,代碼如下
private boolean checkDroneConnection() {//應用程序激活管理器AppActivationManager mgrActivation = DJISDKManager.getInstance().getAppActivationManager();//判斷應用程序是否注冊if (!DJISDKManager.getInstance().hasSDKRegistered()) {showToast("應用程序未注冊");return false;}//判斷應用程序是否激活if (mgrActivation.getAppActivationState() != AppActivationState.ACTIVATED) {showToast("應用程序未激活");return false;}//判斷無人機是否綁定if (mgrActivation.getAircraftBindingState() != AircraftBindingState.BOUND) {showToast("無人機未綁定");return false;}//判斷無人機是否連接//if ((DJISDKManager.getInstance().getProduct() == null) || !(DJISDKManager.getInstance().getProduct().isConnected())) {BaseProduct product = DJISDKManager.getInstance().getProduct();if (product == null || !product.isConnected()) {showToast("無人機連接失敗");return false;}return true;}3.FlightActivity
activity_flight.xml
????????在 FlightActivity UI界面添加名為 “起飛”、“取消起飛”、“降落”、“取消降落”、“設置返航高度”、“獲取返航高度”、“返航”、“取消返航” 按鈕,界面與代碼如下:
FlightActivity UI界面 <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_margin="10dp" ><TextViewandroid:id="@+id/DJI_fly"style="?android:listSeparatorTextViewStyle"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="飛行控制"android:textSize="15sp"app:layout_constraintTop_toTopOf="parent"android:layout_marginTop="10dp" /><Buttonandroid:id="@+id/btn_takeoff"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="起飛"app:layout_constraintTop_toBottomOf="@+id/DJI_fly"android:layout_marginTop="10dp"android:textSize="25sp"android:padding="15dp" /><Buttonandroid:id="@+id/btn_takeoff_cancel"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="取消起飛"app:layout_constraintTop_toBottomOf="@+id/btn_takeoff"android:layout_marginTop="10dp"android:textSize="25sp"android:padding="15dp" /><Buttonandroid:id="@+id/btn_landing"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="降落"app:layout_constraintTop_toBottomOf="@+id/btn_takeoff_cancel"android:layout_marginTop="10dp"android:textSize="25sp"android:padding="15dp" /><Buttonandroid:id="@+id/btn_landing_cancel"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="取消降落"app:layout_constraintTop_toBottomOf="@+id/btn_landing"android:layout_marginTop="10dp"android:textSize="25sp"android:padding="15dp" /><Buttonandroid:id="@+id/btn_set_home_height"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="設置返航高度"app:layout_constraintTop_toBottomOf="@+id/btn_landing_cancel"android:layout_marginTop="10dp"android:textSize="25sp"android:padding="15dp" /><Buttonandroid:id="@+id/btn_get_home_height"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="獲取返航高度"app:layout_constraintTop_toBottomOf="@+id/btn_set_home_height"android:layout_marginTop="10dp"android:textSize="25sp"android:padding="15dp" /><Buttonandroid:id="@+id/btn_home"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="返航"app:layout_constraintTop_toBottomOf="@+id/btn_get_home_height"android:layout_marginTop="10dp"android:textSize="25sp"android:padding="15dp" /><Buttonandroid:id="@+id/btn_home_cancel"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="取消返航"app:layout_constraintTop_toBottomOf="@+id/btn_home"android:layout_marginTop="10dp"android:textSize="25sp"android:padding="15dp" /> </androidx.constraintlayout.widget.ConstraintLayout>FlightActivity.java
????????在上一步添加的按鈕,要使其實現功能,需要在 FlightActivity.java 中獲取上述8個按鈕的對象,并監聽其單擊方法,代碼如下:
public class FlightActivity extends AppCompatActivity implements View.OnClickListener {private Button mBtnTakeoff, mBtnCancelTakeoff, mBtnLanding, mBtnCancelLanding;private Button mBtnSetHomeHeight, mBtnGetHomeHeight, mBtnHome, mBtnCancelHome;public FlightActivity() {}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_flight);//初始化UI界面initUI();//初始化監聽器initListener();}private void initUI() {mBtnTakeoff = findViewById(R.id.btn_takeoff);mBtnCancelTakeoff = findViewById(R.id.btn_takeoff_cancel);mBtnLanding = findViewById(R.id.btn_landing);mBtnCancelLanding = findViewById(R.id.btn_landing_cancel);mBtnSetHomeHeight = findViewById(R.id.btn_set_home_height);mBtnGetHomeHeight = findViewById(R.id.btn_get_home_height);mBtnHome = findViewById(R.id.btn_home);mBtnCancelHome = findViewById(R.id.btn_home_cancel);}private void initListener() {mBtnTakeoff.setOnClickListener(this);mBtnCancelTakeoff.setOnClickListener(this);mBtnLanding.setOnClickListener(this);mBtnCancelLanding.setOnClickListener(this);mBtnSetHomeHeight.setOnClickListener(this);mBtnGetHomeHeight.setOnClickListener(this);mBtnHome.setOnClickListener(this);mBtnCancelHome.setOnClickListener(this);}@Overridepublic void onClick(View view) {switch (view.getId()) {case R.id.btn_takeoff: {takeoff();break;}case R.id.btn_takeoff_cancel: {cancelTakeoff();break;}case R.id.btn_landing: {landing();break;}case R.id.btn_landing_cancel: {cancelLanding();break;}case R.id.btn_set_home_height: {setHomeHeight();break;}case R.id.btn_get_home_height: {getHomeHeight();break;}case R.id.btn_home: {home();break;}case R.id.btn_home_cancel: {cancelHome();break;}default:break;}}//起飛private void takeoff() {}//取消起飛private void cancelTakeoff() {}//降落private void landing() {}//取消降落private void cancelLanding() {}//設置返航高度private void setHomeHeight() {}//獲取返航高度private void getHomeHeight() {}//返航private void home() {}//取消返航private void cancelHome() {}//在主線程中顯示提示private void showToast(final String toastMsg) {runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(getApplicationContext(), toastMsg, Toast.LENGTH_LONG).show();}});} }4.AndroidManifest
????????在 AndroidManifest.xml 文件中,配置 MainActivity 和 FlightActivity 之間的關系,以便于在?FlightActivity 中返回到?MainActivity,界面與代碼如下:
<activityandroid:name=".MainActivity"android:configChanges="orientation"android:launchMode="singleTop"android:screenOrientation="portrait"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter> </activity><activityandroid:name=".FlightActivity"android:configChanges="orientation"android:parentActivityName=".MainActivity"android:screenOrientation="portrait" />DJI Mobile SDK的回調方法
無人機的監控操作需要通過LightBridge、OcuSync等鏈路進行信息傳遞。
受信號衰減和環境干擾的影響,信息傳遞通常要消耗一定時間完成。因此對無人機的各類操作均需要通過回調的方法來介入處理。
?在 Android Mobile SDK 中,回調函數的接口通過 CommonCallbacks 定義。
- CompletionCallback :僅包括 onResult(DJIError? error) 抽象方法。當 error 為空時,任務執行成功;當 error 不為空時,通過其 getDescription() 方法詳細錯誤信息。
- CompletionCallbackWith<T>:包括 onSuccess(T? val) 和 onFailure(DJIError? error) 兩個方法。當任務執行成功時,回調 onSuccess(…) 方法,且返回參數 val ;當任務執行失敗時,回調 onFailure(…) 方法,且其中的 error 對象包含了錯誤描述。
- CompletionCallbackWithTwoParam<X, Y>:與?CompletionCallbackWith<T> 類似,包括 onSuccess(X?val1, Y val2) 和 onFailure(DJIError? error) 兩個方法,方法執行成功時返回 val1 和 val2 兩個參數。
?起飛、降落與返航的實現
獲取控制器
API Reference:FlightController()?
“點擊API可跳轉DJI Developer官網API相應位置?”
創建獲取飛行控制器的 getFlightController() 方法
大疆Mobile SDK API中對FlightController() 類的描述飛行控制器的功能由飛行控制器類定義,飛行控制器對象可通過以下步驟獲取:
(1)通過 DJISDKManager 獲取產品基類(BaseProduct)對象,并判斷是否為無人機對象
(2)在 Android 中需要通過飛行控制器對象的 isConnected() 方法判斷是否與無人機成功連接
具體代碼實現:
//獲取無人機的飛行控制器private FlightController getFlightController() {BaseProduct product = DJISDKManager.getInstance().getProduct();if (product != null && product.isConnected()) {if (product instanceof Aircraft) {return ((Aircraft) product).getFlightController();}}return null;}起飛與取消起飛
API Reference:startTaskoff()、cancelTaskoff()
“點擊API可跳轉DJI Developer官網API相應位置?”
有關 startTakeoff(…) 方法的描述 有關 cancelTakeoff(…) 方法的描述題通過飛行控制器的自動起飛和自動精準起飛方法可實現無人機的起飛動作。
自動起飛方法必須在電機關閉時調用,并在起飛后0.5m左右懸停并回調。對于具有下方視覺定位的無人機,可通過自動精準起飛方法在起飛的6m之內獲得其周圍視覺定位記憶,當無人機再次降落時即可降落到相對更加準確的位置。
具體代碼實現:
? ? ? ? 實現 takeoff() 和 cancelTakeoff() 方法,通過飛行控制器對象的 startTakeoff(…) 方法實現起飛功能,通過飛行控制器對象的?cancelTakeoff(…)?方法實現取消起飛功能
//起飛private void takeoff() {FlightController flightController = getFlightController();if (flightController != null) {flightController.startTakeoff(new CommonCallbacks.CompletionCallback() {@Overridepublic void onResult(DJIError djiError) {if (djiError != null) {showToast(djiError.toString());} else {showToast("開始起飛!");}}});} else {showToast("飛行控制器獲取失敗,請檢查飛行控制器是否連接正常!");}}//取消起飛private void cancelTakeoff() {FlightController flightController = getFlightController();if (flightController != null) {flightController.cancelTakeoff(new CommonCallbacks.CompletionCallback() {@Overridepublic void onResult(DJIError djiError) {if (djiError != null) {showToast(djiError.toString());} else {showToast("取消起飛成功!");}}});} else {showToast("飛行控制器獲取失敗,請檢查飛行控制器是否連接正常!");}}降落與取消降落
API Reference:startLanding()、cancelLanding()
“點擊API可跳轉DJI Developer官網API相應位置?”
有關 startLanding(…) 方法的描述 有關 cancelLanding(…) 方法的描述通過飛行控制器的自動降落方法可實現無人機的降落動作。
對于具有降落保護功能(下方避障功能)的無人機,無人機在距離地面 0.3m 時會對地面進行檢測。如果檢測通過,則自動進行降落;如果檢測不通過,則需要通過確認自動降落的方法繼續執行降落程序。
????????實現 landing() 和 cancelLanding() 方法,通過飛行控制器對象的 startLanding(…) 方法實現降落功能,通過飛行控制器的 cancelLanding(…) 方法實現取消降落功能。
具體代碼實現:?
//降落private void landing() {FlightController flightController = getFlightController();if (flightController != null) {flightController.startLanding(new CommonCallbacks.CompletionCallback() {@Overridepublic void onResult(DJIError djiError) {if (djiError != null) {showToast("開始降落!");} else {showToast(djiError.toString());}}});} else {showToast("飛行控制器獲取失敗,請檢查飛行控制器是否連接正常!");}}//取消降落private void cancelLanding() {FlightController flightController = getFlightController();if (flightController != null) {flightController.cancelLanding(new CommonCallbacks.CompletionCallback() {@Overridepublic void onResult(DJIError djiError) {if (djiError != null) {showToast("取消降落成功!");} else {showToast(djiError.toString());}}});} else {showToast("飛行控制器獲取失敗,請檢查飛行控制器是否連接正常!");}}????????在 Android 中,是否需要確認降落需要通過飛行控制器狀態(FlightControllerState)的isLandingConfirmationNeeded() 方法獲取。如需要確認降落,則可通過飛行控制器類的confirmLanding(…)?方法繼續降落。
返航與取消返航
API Reference: startGoHome()、cancelGoHome()
“點擊API可跳轉DJI Developer官網API相應位置?”
有關 startGoHome(…) 方法的描述 有關 cancelGoHome(…) 方法的描述????????實現 home() 和 cancelhome() 方法,通過飛行控制器對象的 startGoHome(…) 方法實現返航功能,通過飛行控制器的 cancelGoHome(…) 方法實現取消返航功能。?
具體代碼實現:
//返航private void home() {FlightController flightController = getFlightController();if (flightController != null) {flightController.startGoHome(new CommonCallbacks.CompletionCallback() {@Overridepublic void onResult(DJIError djiError) {if (djiError != null) {showToast("開始返航!");} else {showToast(djiError.toString());}}});} else {showToast("飛行控制器獲取失敗,請檢查飛行控制器是否連接正常!");}}//取消返航private void cancelHome() {FlightController flightController = getFlightController();if (flightController != null) {flightController.cancelGoHome(new CommonCallbacks.CompletionCallback() {@Overridepublic void onResult(DJIError djiError) {if (djiError != null) {showToast("取消返航成功!");} else {showToast(djiError.toString());}}});} else {showToast("飛行控制器獲取失敗,請檢查飛行控制器是否連接正常!");}}返航高度的設置與獲取
?API Reference: ?setGoHomeHeightInMeters()、getGoHomeHeightInMeters()
?“點擊API可跳轉DJI Developer官網API相應位置?”
有關 setGoHomeHeightInMeters(…) 方法的描述返航高度應設置在20~500m 的范圍內,切不超過得醒的最大高度。
當返航高度設置過低時,會返回類 “The go home altitude is too low (lower than 20m)” 的錯誤提示;當設置的返航高度過高時,會返回類似 “The go home altitude is too high (higher than max flight height)” 的錯誤提示。
有關 getGoHomeHeightInMeters(…) 方法的描述????????實現 setGoHomeHeight() 和 getGoHomeHeight() 方法,通過飛行控制器對象的 setGoHomeHeightInMeters(…) 方法實現設置返航高度功能,通過飛行控制器的 getGoHomeHeightInMeters(…) 方法實現獲取返航高度功能。?
具體代碼實現:
//設置返航高度private void setHomeHeight() {//設置返航高度文本里final EditText editText = new EditText(this);//限定只能輸入數字editText.setInputType(InputType.TYPE_CLASS_NUMBER);new AlertDialog.Builder(this).setTitle("請輸入返航高度(m)").setView(editText).setPositiveButton("確定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialogInterface, int i) {int height = Integer.parseInt(editText.getText().toString());final FlightController flightController = getFlightController();if (flightController != null) {flightController.setGoHomeHeightInMeters(height, new CommonCallbacks.CompletionCallback() {@Overridepublic void onResult(DJIError djiError) {if (djiError != null) {showToast(djiError.toString());} else {showToast("返航高度設置成功!");}}});} else {showToast("飛行控制器獲取失敗,請檢查飛行控制器是否連接正常!");}}}).setNegativeButton("取消", null).show();}//獲取返航高度private void getHomeHeight() {final FlightController flightController = getFlightController();if (flightController != null) {flightController.getGoHomeHeightInMeters(new CommonCallbacks.CompletionCallbackWith<Integer>() {@Overridepublic void onSuccess(Integer integer) {showToast("返航高度為:" + integer + "米");}@Overridepublic void onFailure(DJIError djiError) {showToast("獲取返航高度失敗:" + djiError.toString());}});} else {showToast("飛行控制器獲取失敗,請檢查飛行控制器是否連接正常!");}}????????在?setGoHomeHeight() 方法中,通過 AlertDialog 類彈出對話框,用于用戶輸入返航高度,由于 setView(editText) 語句,將輸入內容限定為整形數字。
設置返航高度對話框?????????在關閉對話框后,調用飛行控制器的 setGoHomeHeightInMeters(…) 方法,并傳入返航高度和回調函數。在 getGoHomeHeight() 方法中,其回調方法 onSuccess(Integer?height) 中的 height 參數返回了無人機的返航高度。
自定義提示
????????代碼中均使用 showToast() 方法來實現在主線程中顯示提示的功能,也可直接使用 Toast()?提示,將文中代碼涉及 showToast() 的部分更換為 Toast()?
//在主線程中顯示提示private void showToast(final String toastMsg) {runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(getApplicationContext(), toastMsg, Toast.LENGTH_LONG).show();}});}按住鍵盤的 Crtl 鍵,鼠標左鍵單擊Toast方法,即可在 Android Studio 中跳轉到 Toast 類?
public class Toast {public static final int LENGTH_LONG = 1;public static final int LENGTH_SHORT = 0;public Toast(Context context) {throw new RuntimeException("Stub!");}public void show() {throw new RuntimeException("Stub!");}public void cancel() {throw new RuntimeException("Stub!");}/** @deprecated */@Deprecatedpublic void setView(View view) {throw new RuntimeException("Stub!");}/** @deprecated */@Deprecated@Nullablepublic View getView() {throw new RuntimeException("Stub!");}public void setDuration(int duration) {throw new RuntimeException("Stub!");}public int getDuration() {throw new RuntimeException("Stub!");}public void setMargin(float horizontalMargin, float verticalMargin) {throw new RuntimeException("Stub!");}public float getHorizontalMargin() {throw new RuntimeException("Stub!");}public float getVerticalMargin() {throw new RuntimeException("Stub!");}public void setGravity(int gravity, int xOffset, int yOffset) {throw new RuntimeException("Stub!");}public int getGravity() {throw new RuntimeException("Stub!");}public int getXOffset() {throw new RuntimeException("Stub!");}public int getYOffset() {throw new RuntimeException("Stub!");}public void addCallback(@NonNull Toast.Callback callback) {throw new RuntimeException("Stub!");}public void removeCallback(@NonNull Toast.Callback callback) {throw new RuntimeException("Stub!");}public static Toast makeText(Context context, CharSequence text, int duration) {throw new RuntimeException("Stub!");}public static Toast makeText(Context context, int resId, int duration) throws NotFoundException {throw new RuntimeException("Stub!");}public void setText(int resId) {throw new RuntimeException("Stub!");}public void setText(CharSequence s) {throw new RuntimeException("Stub!");}public abstract static class Callback {public Callback() {throw new RuntimeException("Stub!");}public void onToastShown() {throw new RuntimeException("Stub!");}public void onToastHidden() {throw new RuntimeException("Stub!");}} }總結
以上是生活随笔為你收集整理的大疆 DJI Mobile SDK 开发:模拟器调试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 个性化电脑3D桌面软件选择方案
- 下一篇: 【cut命令】