v5.x版本的功能與v4.x基本相同,都是獲取飛機的姿態信息、獲取無人機多媒體文件、操作多媒體文件、航線規劃等。不過在上一章節中也大致說了一些兩個版本的中API的差別,下面是根據一些API使用所完成的一些功能,因為項目原因只能提供部分代碼供參考,后續如果有這方面需求的小伙伴可以對其進行開發指導。
1獲取姿態信息
1、KeyManager調用
KeyManager類提供了一組方法來訪問硬件模塊的參數和控制硬件模塊的行為,包括DJIKey的Value設置,Value獲取,Value監聽和Action執行。通過KeyTools類提供的createKey方法可以更加方便的創建DJIKey實例。
下圖展示了使用KeyManager的接口判斷飛控正常連接并且GPS信號等級大于等于2級,然后給飛行器設置返航點,最后執行返航操作的調用流程。
此處是示例的操作方式,后面有在項目中使用的過程。
2、示例
//獲取飛機信息、云臺信息 privatevoidget3DLocation(){ KeyManager.getInstance().listen(KeyTools.createKey(FlightControllerKey.KeyAircraftLocation3D),this,newCommonCallbacks.KeyListener(){ @Override publicvoidonValueChange(@NullableLocationCoordinate3DoldValue,@NullableLocationCoordinate3DnewValue){ if(newValue!=null){ lat=newValue.latitude; lon=newValue.longitude; high=newValue.altitude; } } }); } privatevoidgetAttitude(){ KeyManager.getInstance().listen(KeyTools.createKey(FlightControllerKey.KeyAircraftAttitude),this,newCommonCallbacks.KeyListener (){ @Override publicvoidonValueChange(@NullableAttitudeoldValue,@NullableAttitudenewValue){ if(newValue!=null){ pitch=newValue.pitch; roll=newValue.roll; yaw=newValue.yaw; } } }); } privatevoidgetVelocity(){ KeyManager.getInstance().listen(KeyTools.createKey(FlightControllerKey.KeyAircraftVelocity),this,newCommonCallbacks.KeyListener (){ @Override publicvoidonValueChange(@NullableVelocity3DoldValue,@NullableVelocity3DnewValue){ if(newValue!=null){ velocity_X=newValue.x; velocity_Y=newValue.y; velocity_Z=newValue.z; } } }); } privatevoidgetIsFly(){ KeyManager.getInstance().listen(KeyTools.createKey(FlightControllerKey.KeyIsFlying),this,newCommonCallbacks.KeyListener (){ @Override publicvoidonValueChange(@NullableBooleanoldValue,@NullableBooleannewValue){ if(newValue!=null){ isFlying=newValue; } } }); } privatevoidgetGimbalAttitude(){ KeyManager.getInstance().listen(KeyTools.createKey(GimbalKey.KeyGimbalAttitude),this,newCommonCallbacks.KeyListener (){ @Override publicvoidonValueChange(@NullableAttitudeoldValue,@NullableAttitudenewValue){ if(newValue!=null){ g_pitch=newValue.pitch; g_roll=newValue.roll; g_yaw=newValue.yaw; } } }); } privatevoidgetPower(){ KeyManager.getInstance().listen(KeyTools.createKey(BatteryKey.KeyChargeRemainingInPercent),this,newCommonCallbacks.KeyListener (){ @Override publicvoidonValueChange(@NullableIntegeroldValue,@NullableIntegernewValue){ power=newValue; } }); } privatevoidgetTemperature(){ KeyManager.getInstance().listen(KeyTools.createKey(BatteryKey.KeyBatteryTemperature),this,newCommonCallbacks.KeyListener (){ @Override publicvoidonValueChange(@NullableDoubleoldValue,@NullableDoublenewValue){ temperature=newValue; } }); }
get3DLocation()方法為獲取飛機經緯度信息。
getAttitude()方法獲取飛機的姿態信息(分別是航偏角、旋轉角、俯仰角)。
getVelocity()方法獲取飛機的飛行速度(分別是X、Y、Z三個方向的速度值)。
getIsFly()方法獲取當前飛機的狀態值(是否正在飛行)。
getGimbalAttitude()方法獲取鏡頭的姿態信息(分別是航偏角、旋轉角、俯仰角)。
getPower()獲取飛機的電池電量
getTemperature()獲取飛機的電池溫度
onValueChange()方法為1秒執行10次,這個可以根據后續要求進行獲??;
2多媒體使用
1、Sample介紹
拍照、錄像是無人機的重要功能,對拍攝的照片、視頻等多媒體文件進行管理也就必不可少。多媒體文件的管理包括訪問飛機存儲空間內的多媒體文件資源、獲取多媒體文件列表與列表狀態、視頻文件播放等。
下圖為完整的接口展示以及接口調用流程示例。
多媒體文件管理調用流程
視頻文件播放調用流程
2、示例
privatevoidgetFileList(intindex){ if(MediaManager.getInstance()!=null){ //if(mMediaFileListState==MediaFileListState.UPDATING){ //DJILog.e(TAG,"媒體管理器正忙."); //}elseif(mMediaFileListState==MediaFileListState.IDLE){ MediaManager.getInstance().pullMediaFileListFromCamera((newPullMediaFileListParam.Builder()).build(),newCommonCallbacks.CompletionCallback(){ @Override publicvoidonSuccess(){ hideProgressDialog(); if(mMediaFileListState!=MediaFileListState.UP_TO_DATE){ //List.clear(); mediaFileList.clear(); lastClickViewIndex=-1; } List=MediaManager.getInstance().getMediaFileListData().getData(); switch(index){ case0: for(inti=0;i{ if(getDate(lhs.getDate())getDate(rhs.getDate())){ return-1; } return0; }); } runOnUiThread(newRunnable(){ @Override publicvoidrun(){ mListAdapter.notifyDataSetChanged(); } }); //scheduler.resume(error->{ //if(error==null){ // //} //}); getThumbnails(); } @Override publicvoidonFailure(@NonNullIDJIErrorerror){ hideProgressDialog(); showToasts("獲取媒體文件列表失敗:"+error.description()); } }); //} } } privatevoidgetThumbnails(){ if(mediaFileList.size()<=?0)?{ ????????????showToasts("沒有用于下載縮略圖的文件信息"); ????????????return; ????????} ????????for?(int?i?=?0;?i?(){ @Override publicvoidonSuccess(Bitmapbitmap){ } @Override publicvoidonFailure(@NonNullIDJIErrorerror){ } }); } privatevoiddeleteFileByIndex(finalintindex){ ArrayListfileToDelete=newArrayList (); if(mediaFileList.size()>index){ fileToDelete.add(mediaFileList.get(index)); MediaManager.getInstance().deleteMediaFiles(fileToDelete,newCommonCallbacks.CompletionCallback(){ @Override publicvoidonSuccess(){ mediaFileList.remove(index); //Resetselectview lastClickViewIndex=-1; lastClickView=null; //UpdaterecyclerView mListAdapter.notifyDataSetChanged(); } @Override publicvoidonFailure(@NonNullIDJIErrorerror){ showToasts("刪除失敗"); } }); } } privatevoiddownloadFileByIndex(finalintindex){ if((mediaFileList.get(index).getFileType()==MediaFileType.MOV)||(mediaFileList.get(index).getFileType()==MediaFileType.MP4)){ SavePath=MyStatic.FLY_FILE_VIDEO; }elseif(mediaFileList.get(index).getFileType()==MediaFileType.JPEG){ SavePath=MyStatic.FLY_FILE_PHOTO; } FiledestDir=newFile(FileUtil.checkDirPath(SavePath)); Stringpath=SavePath+"/"+mediaFileList.get(index).getFileName(); FiledestPath=newFile(path); try{ outputStream=newFileOutputStream(destPath); }catch(FileNotFoundExceptione){ e.printStackTrace(); } bos=newBufferedOutputStream(outputStream); mediaFileList.get(index).pullOriginalMediaFileFromCamera(0,newMediaFileDownloadListener(){ @Override publicvoidonStart(){ currentProgress=-1; ShowDownloadProgressDialog(); } @Override publicvoidonProgress(longtotal,longcurrent){ inttmpProgress=(int)(1.0*current/total*100); if(tmpProgress!=currentProgress){ mDownloadDialog.setProgress(tmpProgress); currentProgress=tmpProgress; } } @Override publicvoidonRealtimeDataUpdate(byte[]data,longposition){ try{ bos.write(data,0,data.length); bos.flush(); }catch(IOExceptione){ e.printStackTrace(); } } @Override publicvoidonFinish(){ HideDownloadProgressDialog(); currentProgress=-1; try{ outputStream.close(); bos.close(); }catch(Exceptione){ e.printStackTrace(); } } @Override publicvoidonFailure(IDJIErrorerror){ } }); } privatevoidplayVideo(){ mImageView.setVisibility(View.INVISIBLE); MediaFileselectedMediaFile=mediaFileList.get(lastClickViewIndex); if((selectedMediaFile.getFileType()==MediaFileType.MOV)||(selectedMediaFile.getFileType()==MediaFileType.MP4)){ MediaManager.getInstance().playVideo(selectedMediaFile,newCommonCallbacks.CompletionCallbackWithParam (){ @Override publicvoidonSuccess(IVideoFrameiVideoFrame){ videoDecoder.queueInFrame(iVideoFrame); DJILog.e(TAG,"播放成功"); runOnUiThread(newRunnable(){ @Override publicvoidrun(){ mImageViewVideoPlay.setEnabled(false); mImageViewVideoPause.setEnabled(true); } }); } @Override publicvoidonFailure(@NonNullIDJIErrorerror){ showToasts("播放失敗"+error.description()); } }); } }
getFileList()方法獲取所有媒體文件,文件包括視頻及照片,可以對照片視頻進行分類處理了
getThumbnails()方法獲取縮略圖信息,用于在界面展示縮略圖
deleteFileByIndex()方法為刪除到媒體文件(可以進行單個刪除或者多個刪除)
downloadFileByIndex()方法為多媒體文件下載
playVideo()方法為多媒體文件視頻播放
3直播的調用
1、Sample介紹
直播功能是Mobile SDK重要的功能,可支持聲網、RTMP、RTSP、GB28181 四種直播模式。在安防,公共安全,巡檢等場景都需要有直播模塊。
下圖為完整的接口展示以及接口調用流程示例。詳細的使用方法請查看Mobile SDK API 文檔中的直播管理類 ILiveStreamManager。直播管理類用于直播的參數設置和直播的開啟和停止等功能。
2、示例
項目中使用到了其中的一種方式 ,使用RTMP方式進行推流直播。代碼如下:
privatevoidstartLiveShow(){ LiveStreamSettings.Buildersettings=newLiveStreamSettings.Builder(); settings.setLiveStreamType(LiveStreamType.RTMP); RtmpSettings.BuilderrtmpSetting=newRtmpSettings.Builder(); rtmpSetting.setUrl(liveShowUrl); settings.setRtmpSettings(rtmpSetting.build()); MediaDataCenter.getInstance().getLiveStreamManager().setLiveStreamSettings(settings.build()); MediaDataCenter.getInstance().getLiveStreamManager().startStream(newCommonCallbacks.CompletionCallback(){ @Override publicvoidonSuccess(){ Log.i("LiveStreamManager","LiveStreamManager開始直播"); booleanisStream=MediaDataCenter.getInstance().getLiveStreamManager().isStreaming(); Log.i("LiveStreamManager","LiveStreamManager開始直播:"+isStream); Log.i("LiveStreamManager","LiveStreamManager直播參數:"+MediaDataCenter.getInstance().getLiveStreamManager().getLiveStreamSettings()); Log.i("LiveStreamManager","LiveStreamManager視頻質量:"+MediaDataCenter.getInstance().getLiveStreamManager().getLiveStreamQuality()); Log.i("LiveStreamManager","LiveStreamManager直播碼率:"+MediaDataCenter.getInstance().getLiveStreamManager().getLiveVideoBitrate()); Log.i("LiveStreamManager","LiveStreamManager碼流通道:"+MediaDataCenter.getInstance().getLiveStreamManager().getVideoChannelType()); Log.i("LiveStreamManager","LiveStreamManager碼率模式:"+MediaDataCenter.getInstance().getLiveStreamManager().getLiveVideoBitrateMode()); } @Override publicvoidonFailure(@NonNullIDJIErrorerror){ Log.i("LiveStreamManager","LiveStreamManager直播錯誤:"+error.description()); } }); } privatevoidstopLiveShow(){ AlertDialog.BuilderBuilder=newAlertDialog.Builder(MainActivity.this); Builder.setTitle("提示"); Builder.setMessage("是否結束推流?"); Builder.setIcon(android.R.drawable.ic_dialog_alert); Builder.setPositiveButton("確定",newDialogInterface.OnClickListener(){ @Override publicvoidonClick(DialogInterfacedialog,intwhich){ if(!isLiveStreamManagerOn()){ return; } LiveStreamManager.getInstance().stopStream(newCommonCallbacks.CompletionCallback(){ @Override publicvoidonSuccess(){ runOnUiThread(newRunnable(){ @Override publicvoidrun(){ //LiveModulemodule=newLiveModule("liveStreamStateChanged","plane",planeId,false,trajectoryId+""); mapData.put("type","liveStreamStateChanged"); mapData.put("sender","plane"); mapData.put("planeId",planeId+""); mapData.put("liveStreamOpen","false"); mapData.put("liveStreamUrl",trajectoryId+""); params.put("message",GsonUtil.GsonString(mapData)); http.getHttp(POST_LIVE_STATE,"GET",params); } }); showToast("結束推流"); } @Override publicvoidonFailure(@NonNullIDJIErrorerror){ } }); } }); Builder.setNegativeButton("取消",null); Builder.show(); }
startLiveShow()方法為開啟直播,并設置一些直播參數
stopLiveShow()方法為停止直播,進行緩存回收
4航線規劃
1、Sample介紹
航線任務管理是用于無人機自主作業的重要功能,通過MSDK提供的接口可以實現對航線任務的上傳、執行、暫停、恢復以及對航線任務執行狀態與航線信息的監聽等。
我們將航點任務定義在航線文件中,該文件遵循 DJI 自定義的航線文件格式標準(WPML)。航線文件實際為“.kmz”結尾的壓縮文件,文件結構如下:
waypoints_name.kmz └──wpmz ├──res ├──template.kml └──waylines.wpml
其中,template.kml文件為“模板文件”,waylines.wpml文件為“執行文件”,res為資源文件。詳細的介紹請閱讀航線文件格式標準。航線文件格式標準的文檔中有對template.kml文件與waylines.wpml文件的編寫說明。
2、接口調用流程
MSDK提供的航線功能相關接口較為簡單,調用方式如下圖。詳細的使用方法請查看Mobile SDK API文檔中的航線任務管理類 IWaypointMissionManager。圖中虛線框內容為可選接口。
5總結
以上內容為v5.x版本中使用到的一些內容,當然還有一些API沒有在項目中使用到,后續給大家也更新到整個專欄內容中,希望喜歡的小伙伴可以進行訂閱,如果后續有共同開發的同道中人可以聯系我幫你解決一些問題?,F階段v5.x還在持續更新中,為了適配更多的飛機它的一些功能也是在不斷的完善。
審核編輯:湯梓紅
-
Mobile
+關注
關注
0文章
518瀏覽量
26747 -
多媒體
+關注
關注
0文章
510瀏覽量
37544 -
遙控器
+關注
關注
18文章
851瀏覽量
67783 -
無人機
+關注
關注
230文章
10728瀏覽量
185526 -
SDK
+關注
關注
3文章
1065瀏覽量
47674
原文標題:基于Mobile SDK V5版固件開發大疆無人機手機端遙控器(5)
文章出處:【微信號:美男子玩編程,微信公眾號:美男子玩編程】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
【云智易申請】智能無人機通信
COCOFLY 教程 ——瘋殼無人機·系列·快速上手【5】遙控器固件燒寫
COCOFLY 教程 ——瘋殼無人機·系列【5】遙控器固件燒寫
CES 2019:大疆推出帶屏無人機遙控器 便攜式無線電源Yoolox亮相
音圈馬達裝置在大疆無人機的應用
基于Mobile SDK V4版固件開發大疆無人機手機端遙控器(3)

評論