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次,這個可以根據后續要求進行獲?。?/p>
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文章
520瀏覽量
27123 -
多媒體
+關注
關注
0文章
516瀏覽量
38555 -
遙控器
+關注
關注
18文章
877瀏覽量
71832 -
無人機
+關注
關注
235文章
11298瀏覽量
195595 -
SDK
+關注
關注
3文章
1101瀏覽量
51713
原文標題:基于Mobile SDK V5版固件開發大疆無人機手機端遙控器(5)
文章出處:【微信號:美男子玩編程,微信公眾號:美男子玩編程】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
【Aworks申請】開放式無人機地面基站
COCOFLY 教程 ——瘋殼無人機·系列·快速上手【5】遙控器固件燒寫
COCOFLY 教程 ——瘋殼無人機·系列【5】遙控器固件燒寫
CES 2019:大疆推出帶屏無人機遙控器 便攜式無線電源Yoolox亮相
音圈馬達裝置在大疆無人機的應用
基于Mobile SDK V4版固件開發大疆無人機手機端遙控器(3)
基于Mobile SDK V5版固件開發大疆無人機手機端遙控器(5)
評論