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

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

3天内不再提示

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

jf_Vqngj70R 来源:美男子玩编程 2023-06-15 12:22 次阅读

第三篇文章准备单独拿出来写,因为在大疆为人机的所有功能中,航线规划的功能最为复杂,也相当的繁琐,这里需要说仔细一点,可能会将代码进行多步分解。

1航线规划

航线打点

在地图中手动选择点位选择完成航线打点;若打点位置错了可进行点位删除。

efff7e88-0b31-11ee-962d-dac502259ad0.png

航点设置

可对航线点位进行设置,如飞行高度,速度(慢速:3m/s;中速: 7m/s;高速:10 m/s)、任务结束后操作及航向,点击[设置]按钮完成设置。

f05eb5ce-0b31-11ee-962d-dac502259ad0.png

设置完成后会显示总距离及飞行总时间。

f0958e64-0b31-11ee-962d-dac502259ad0.png

航线上传

点击[上传]按钮,进行航线上传。可以进入本地存储中选择航线文件进行上传,航线文件为 .kml结尾。

f0aeac32-0b31-11ee-962d-dac502259ad0.png

航线执行

点击 [开始]按钮,则可对航线进行执行。若中途需要暂停也可点击[暂停]安装进行暂停操作。

f0cd745a-0b31-11ee-962d-dac502259ad0.png

航线管理

按钮即可进入航线管理界面。

efff7e88-0b31-11ee-962d-dac502259ad0.pngf131a1aa-0b31-11ee-962d-dac502259ad0.png

获取航线

点击[获取]按钮,即可将航线信息展示到地图界面中。

f131a1aa-0b31-11ee-962d-dac502259ad0.png

2主要功能代码

创建activity_setting_route.xml及SettingRouteActivity文件。

activity_setting_route.xml
























SettingRouteActivity

publicclassSettingRouteActivityextendsBaseActivityimplementsAMap.OnMarkerClickListener,View.OnClickListener,AMap.OnMapClickListener,LocationSource,AMapLocationListener,AMap.InfoWindowAdapter{
@BindView(R.id.layout_route)
ViewmViewLayoutToolbar;
@BindView(R.id.ll_route)
LinearLayoutmLinearLayout;
@BindView(R.id.tv_toolbar_title)
TextViewmTextViewToolbarTitle;
//@BindView(R.id.map)
//MapViewmMapView;

@BindView(R.id.btn_delete)
ButtonmButtonDelete;
@BindView(R.id.btn_finish)
ButtonmButtonFinish;
@BindView(R.id.btn_setting)
ButtonmButtonSetting;
@BindView(R.id.btn_upload)
ButtonmButtonUpload;
@BindView(R.id.btn_start)
ButtonmButtonStart;
@BindView(R.id.btn_stop)
ButtonmButtonStop;

@BindView(R.id.ll_information)
LinearLayoutmLinearLayoutInformation;
@BindView(R.id.tv_height)
TextViewmTextViewHeight;
@BindView(R.id.tv_speed)
TextViewmTextViewSpeed;
@BindView(R.id.tv_count)
TextViewmTextViewCount;
@BindView(R.id.tv_distance)
TextViewmTextViewDistance;
@BindView(R.id.tv_time)
TextViewmTextViewTime;

privateMapViewmMapView;
privateOnLocationChangedListenermListener;
privateAMapLocationClientmlocationClient;
privateAMapLocationClientOptionmLocationOption;
privatedoubleD_latitude,D_longitude;
privateUiSettingsmUiSettings;
privateAMapaMap;
privateMarkerdroneMarker=null;

privatefloataltitude=100.0f;
privatefloatmSpeed=10.0f;

privatebooleanisAdd=false;

privatefinalMapmMarkers=newConcurrentHashMap();
privateMarkermClickMarker;
privateListwaypointList=newArrayList<>();
privateListmLatLng=newArrayList<>();
privateListmPointInfo=newArrayList<>();

publicstaticWaypointMission.BuilderwaypointMissionBuilder;
privateFlightControllermFlightController;
privateWaypointMissionOperatorinstance;
privateWaypointMissionFinishedActionmFinishedAction=WaypointMissionFinishedAction.NO_ACTION;
privateWaypointMissionHeadingModemHeadingMode=WaypointMissionHeadingMode.AUTO;

privateSQLiteHelpermSQLiteHelper;
privateStringFinishedAction,HeadingMode;

//自定义窗体
ViewinfoWindow=null;

intspeed_RG_id=0;
intactionAfterFinished_RG_id=0;
intheading_RG_id=0;

//kim
staticReadKmlreadKml=newReadKml();
privatestaticListsampleList=readKml.getCoordinateList();

@Override
publicvoidinitViews(){
mLinearLayout.setVisibility(View.VISIBLE);
mTextViewToolbarTitle.setText("航线规划");
IntentFilterfilter=newIntentFilter();
filter.addAction(ReceiverApplication.FLAG_CONNECTION_CHANGE);
registerReceiver(mReceiver,filter);
mMapView=findViewById(R.id.map);
mMapView.onCreate(InstanceState);
initMapView();
addListener();
onProductConnectionChange();

}

@Override
protectedvoidonResume(){
super.onResume();
initFlightController();
mMapView.onResume();
}

/**
*方法必须重写
*/
@Override
protectedvoidonSaveInstanceState(BundleoutState){
super.onSaveInstanceState(outState);
mMapView.onSaveInstanceState(outState);
}

@Override
protectedvoidonPause(){
super.onPause();
mMapView.onPause();
deactivate();
}

@Override
protectedvoidonDestroy(){
super.onDestroy();
unregisterReceiver(mReceiver);
removeListener();
mMapView.onDestroy();
if(null!=mlocationClient){
mlocationClient.onDestroy();
}

}

@Override
publicvoidinitDatas(){

}

@Override
protectedvoidrequestData(){

}

privatevoidinitMapView(){
if(aMap==null){
aMap=mMapView.getMap();
mUiSettings=aMap.getUiSettings();
mUiSettings.setMyLocationButtonEnabled(true);
mUiSettings.setScaleControlsEnabled(true);
aMap.setOnMapClickListener(this);//addthelistenerforclickforamapobject
aMap.setLocationSource(this);
aMap.setMyLocationEnabled(true);
aMap.setInfoWindowAdapter(this);
aMap.setOnMarkerClickListener(this);
setupLocationStyle();
}
}

privatevoidsetupLocationStyle(){
//自定义系统定位蓝点
MyLocationStylemyLocationStyle=newMyLocationStyle();
//自定义定位蓝点图标
myLocationStyle.myLocationIcon(BitmapDescriptorFactory.
fromResource(R.mipmap.icv_gps_point_36dp));
//自定义精度范围的圆形边框颜色
myLocationStyle.strokeColor(Color.parseColor("#00000000"));
//自定义精度范围的圆形边框宽度
myLocationStyle.strokeWidth(5);
//设置圆形的填充颜色
myLocationStyle.radiusFillColor(Color.parseColor("#00000000"));
//将自定义的myLocationStyle对象添加到地图上
aMap.setMyLocationStyle(myLocationStyle);
}

@OnClick({R.id.img_kml_input,R.id.img_setting_route,R.id.img_start_fly,R.id.btn_delete,
R.id.img_setting_clear,R.id.btn_finish,R.id.btn_setting,R.id.btn_upload,
R.id.btn_start,R.id.btn_stop,R.id.img_back})
@Override
publicvoidonClick(Viewv){
switch(v.getId()){
caseR.id.img_back:
SettingRouteActivity.this.finish();
break;
caseR.id.img_kml_input:
Intentintent=newIntent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");//设置类型,我这里是任意类型,任意后缀的可以这样写。
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent,MyStatic.REQUEST_CODE_FILE);
break;
caseR.id.img_setting_route:
enableDisableAdd();
break;
caseR.id.img_setting_clear:
runOnUiThread(newRunnable(){
@Override
publicvoidrun(){
aMap.clear();
mMarkers.clear();
mPointInfo.clear();
mLinearLayoutInformation.setVisibility(View.GONE);
mButtonFinish.setVisibility(View.GONE);
mButtonSetting.setVisibility(View.GONE);
mButtonUpload.setVisibility(View.GONE);
mButtonStart.setVisibility(View.GONE);
mButtonStop.setVisibility(View.GONE);
}
});
waypointList.clear();
waypointMissionBuilder.waypointList(waypointList);
break;
caseR.id.img_start_fly:
atyAction(WaypointActivity.class,MyStatic.REQUEST_CODE_ID);
break;
caseR.id.btn_delete:
runOnUiThread(newRunnable(){
@Override
publicvoidrun(){
aMap.clear();
}
});
for(inti=0;i< mMarkers.size(); i++) {
                        if (mMarkers.get(i).getTitle().equals(mClickMarker.getTitle())) {
                            for (int j = i; j < mMarkers.size() - 1; j++) {
                                mMarkers.put(j, mMarkers.get(j + 1));
                            }
                            mMarkers.remove(mMarkers.size() - 1);
                        }
                    }
                    for (int i = 0; i < mMarkers.size(); i++) {
                        mMarkers.get(i).setTitle("航点" + (i + 1));
                    }
                    updateMarkWaypoint();
                    break;
                case R.id.btn_finish:
                    MyLog.d("航点数:" + waypointMissionBuilder.getWaypointCount());
                    MyLog.d("总距离:" + waypointMissionBuilder.calculateTotalDistance());
                    MyLog.d("总时间:" + waypointMissionBuilder.calculateTotalTime());
                    isAdd = false;
                    mButtonFinish.setVisibility(View.GONE);
                    mButtonSetting.setVisibility(View.VISIBLE);
                    mButtonUpload.setVisibility(View.VISIBLE);
                    showSettingDialog();
                    break;
                case R.id.btn_setting:
                    showSettingDialog();
                    break;
                case R.id.btn_upload:
                    uploadWayPointMission();
                    break;
                case R.id.btn_start:
                    startWaypointMission();
                    break;
                case R.id.btn_stop:
                    stopWaypointMission();
                    break;
            }
        }

        private void enableDisableAdd() {
            if (isAdd == false) {
                isAdd = true;
                mButtonFinish.setVisibility(View.VISIBLE);
            } else {
                isAdd = false;
            }
        }

        private void initFlightController() {
            BaseProduct product = ReceiverApplication.getProductInstance();
            if (product != null && product.isConnected()) {
                if (product instanceof Aircraft) {
                    mFlightController = ((Aircraft) product).getFlightController();
                }
            }
            if (mFlightController != null) {
                mFlightController.setStateCallback(
                        new FlightControllerState.Callback() {
                            @Override
                            public void onUpdate(FlightControllerState
                                                         djiFlightControllerCurrentState) {
                                if (djiFlightControllerCurrentState.getAircraftLocation().getLatitude() != 0.0 && djiFlightControllerCurrentState.getAircraftLocation().getLongitude() != 0.0) {
                                    D_latitude = djiFlightControllerCurrentState.getAircraftLocation().getLatitude();
                                    D_longitude = djiFlightControllerCurrentState.getAircraftLocation().getLongitude();
                                }
                                updateDroneLocation();
                            }
                        });
            }
        }

        private void updateDroneLocation() {
            LatLng pos = new LatLng(D_latitude, D_longitude);
            //Create MarkerOptions object
            final MarkerOptions markerOptions = new MarkerOptions();
            markerOptions.position(pos);
            markerOptions.icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_aircraft_write_36dp));
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (droneMarker != null) {
                        droneMarker.remove();
                    }

                    if (checkGpsCoordination(D_latitude, D_longitude)) {
                        droneMarker = aMap.addMarker(markerOptions);
                    }
                }
            });
        }

        public static boolean checkGpsCoordination(double latitude, double longitude) {
            return (latitude >-90&&latitude< 90 && longitude >-180&&longitude< 180) && (latitude != 0f && longitude != 0f);
        }

        protected BroadcastReceiver mReceiver = new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, Intent intent) {
                onProductConnectionChange();
            }
        };

        private void onProductConnectionChange() {
            initFlightController();
        }

        private void addListener() {
            if (getWaypointMissionOperator() != null) {
                getWaypointMissionOperator().addListener(eventNotificationListener);
            }
        }

        private void removeListener() {
            if (getWaypointMissionOperator() != null) {
                getWaypointMissionOperator().removeListener(eventNotificationListener);
            }
        }

        private WaypointMissionOperatorListener eventNotificationListener = new WaypointMissionOperatorListener() {
            @Override
            public void onDownloadUpdate(WaypointMissionDownloadEvent downloadEvent) {

            }

            @Override
            public void onUploadUpdate(WaypointMissionUploadEvent uploadEvent) {

            }

            @Override
            public void onExecutionUpdate(WaypointMissionExecutionEvent executionEvent) {

            }

            @Override
            public void onExecutionStart() {

            }

            @Override
            public void onExecutionFinish(@Nullable final DJIError error) {
                showToasts("Execution finished: " + (error == null ? "Success!" : error.getDescription()));
            }
        };

        public WaypointMissionOperator getWaypointMissionOperator() {
            if (instance == null) {
                instance = DJISDKManager.getInstance().getMissionControl().getWaypointMissionOperator();
            }
            return instance;
        }

        @Override
        public void onMapClick(LatLng point) {
            if (isAdd == true) {
                markWaypoint(point);
                Waypoint mWaypoint = new Waypoint(point.latitude, point.longitude, altitude);
                //Add Waypoints to Waypoint arraylist;
                if (waypointMissionBuilder != null) {
                    waypointList.add(mWaypoint);
                    waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());
                } else {
                    waypointMissionBuilder = new WaypointMission.Builder();
                    waypointList.add(mWaypoint);
                    waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());
                }
                mTextViewCount.setText("航点数:" + waypointMissionBuilder.getWaypointCount());
                mTextViewDistance.setText("总距离:" + Math.round(waypointMissionBuilder.calculateTotalDistance()) + "m");
                mTextViewTime.setText("总时间:" + Math.round(waypointMissionBuilder.calculateTotalTime()) + "min");
            } else {
                if (mClickMarker != null && mClickMarker.isInfoWindowShown()) {
                    mClickMarker.hideInfoWindow();
                    mButtonDelete.setVisibility(View.GONE);
                }
                //            showToasts("当前未开启增加点模式");
            }

        }

        private void markWaypoint(LatLng point) {
            MarkerOptions markerOptions = new MarkerOptions();
            markerOptions.position(point);
            mPointInfo.add(new PointInfo(point.latitude, point.longitude));
            markerOptions.title("航点" + (mMarkers.size() + 1));
            markerOptions.snippet("事件:");
            markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
            markerOptions.infoWindowEnable(true);
            Marker marker = aMap.addMarker(markerOptions);
            mMarkers.put(mMarkers.size(), marker);
            marker.showInfoWindow();
            if (mMarkers.size() >0){
mLatLng.clear();
PolylineOptionsPolylineOptions=newPolylineOptions();
for(inti=0;i< mMarkers.size(); i++) {
                    mLatLng.add(mMarkers.get(i).getPosition());
                }
                PolylineOptions.addAll(mLatLng);
                PolylineOptions.width(10);
                PolylineOptions.color(Color.argb(255, 1, 1, 1));
                aMap.addPolyline(PolylineOptions);
            }
        }

        private void updateMarkWaypoint() {
            mLatLng.clear();
            waypointList.clear();
            mPointInfo.clear();
            waypointMissionBuilder.waypointList(waypointList);
            for (int i = 0; i < mMarkers.size(); i++) {
                mPointInfo.add(new PointInfo(mMarkers.get(i).getPosition().latitude, mMarkers.get(i).getPosition().longitude));
                MarkerOptions markerOptions = new MarkerOptions();
                Waypoint mWaypoint = new Waypoint(mMarkers.get(i).getPosition().latitude, mMarkers.get(i).getPosition().longitude, altitude);
                waypointList.add(mWaypoint);
                markerOptions.position(mMarkers.get(i).getPosition());
                markerOptions.title(mMarkers.get(i).getTitle());
                markerOptions.snippet(mMarkers.get(i).getSnippet());
                markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
                aMap.addMarker(markerOptions);
                mLatLng.add(mMarkers.get(i).getPosition());
            }
            if (mMarkers.size() >0){
PolylineOptionsPolylineOptions=newPolylineOptions();
PolylineOptions.addAll(mLatLng);
PolylineOptions.width(10);
PolylineOptions.color(Color.argb(255,1,1,1));
aMap.addPolyline(PolylineOptions);
}
waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());
mTextViewCount.setText("航点数:"+waypointMissionBuilder.getWaypointCount());
mTextViewDistance.setText("总距离:"+Math.round(waypointMissionBuilder.calculateTotalDistance())+"m");
mTextViewTime.setText("总时间:"+Math.round(waypointMissionBuilder.calculateTotalTime())+"min");
MyLog.d("航点数:"+waypointMissionBuilder.getWaypointCount());
MyLog.d("总距离:"+waypointMissionBuilder.calculateTotalDistance());
MyLog.d("总时间:"+waypointMissionBuilder.calculateTotalTime());
mButtonDelete.setVisibility(View.GONE);
}


/**
*定位成功后回调函数
*/
@Override
publicvoidonLocationChanged(AMapLocationamapLocation){
if(mListener!=null&&amapLocation!=null){
if(amapLocation!=null
&&amapLocation.getErrorCode()==0){
D_latitude=amapLocation.getLatitude();//获取纬度
D_longitude=amapLocation.getLongitude();//获取经度
mListener.onLocationChanged(amapLocation);//显示系统小蓝点
aMap.moveCamera(CameraUpdateFactory.zoomTo(18));
}else{
StringerrText="定位失败,"+amapLocation.getErrorCode()+":"+amapLocation.getErrorInfo();
Log.e("AmapErr",errText);
}
}
}

@Override
publicvoidactivate(OnLocationChangedListenerlistener){
mListener=listener;
if(mlocationClient==null){
try{
mlocationClient=newAMapLocationClient(this);
}catch(Exceptione){
e.printStackTrace();
}
mLocationOption=newAMapLocationClientOption();
//设置定位监听
mlocationClient.setLocationListener(this);
//设置为高精度定位模式
mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
//设置定位参数
mLocationOption.setOnceLocation(true);
mlocationClient.setLocationOption(mLocationOption);
//此方法为每隔固定时间会发起一次定位请求,为了减少电量消耗或网络流量消耗,
//注意设置合适的定位时间的间隔(最小间隔支持为2000ms),并且在合适时间调用stopLocation()方法来取消定位请求
//在定位结束后,在合适的生命周期调用onDestroy()方法
//在单次定位情况下,定位无论成功与否,都无需调用stopLocation()方法移除请求,定位sdk内部会移除
mlocationClient.startLocation();
}
}

@Override
publicvoiddeactivate(){
mListener=null;
if(mlocationClient!=null){
mlocationClient.stopLocation();
mlocationClient.onDestroy();
}
mlocationClient=null;
}

@Override
publicViewgetInfoWindow(Markermarker){
if(infoWindow==null){
infoWindow=LayoutInflater.from(this).inflate(R.layout.amap_info_window,null);
}
render(marker,infoWindow);
returninfoWindow;
}

/**
*自定义infoWindow窗口
*/
privatevoidrender(Markermarker,ViewinfoWindow){
TextViewtitle=infoWindow.findViewById(R.id.info_window_title);
TextViewcontent=infoWindow.findViewById(R.id.info_window_content);
title.setText(marker.getTitle());
content.setText(marker.getSnippet());
}


@Override
publicViewgetInfoContents(Markermarker){
returnnull;
}

@Override
publicbooleanonMarkerClick(Markermarker){
marker.showInfoWindow();
mClickMarker=marker;
mButtonDelete.setVisibility(View.VISIBLE);
//aMap.moveCamera(CameraUpdateFactory.newCameraPosition(newCameraPosition(marker.getPosition(),18,0,0)));
returntrue;
}

privatevoidshowSettingDialog(){
LinearLayoutwayPointSettings=(LinearLayout)getLayoutInflater().inflate(R.layout.dialog_waypointsetting,null);

finalTextViewwpAltitude_TV=(TextView)wayPointSettings.findViewById(R.id.altitude);
RadioGroupspeed_RG=(RadioGroup)wayPointSettings.findViewById(R.id.speed);
RadioGroupactionAfterFinished_RG=(RadioGroup)wayPointSettings.findViewById(R.id.actionAfterFinished);
RadioGroupheading_RG=(RadioGroup)wayPointSettings.findViewById(R.id.heading);
wpAltitude_TV.setText(Math.round(altitude)+"");
if(speed_RG_id!=0){
RadioButtonradioButton=(RadioButton)speed_RG.findViewById(speed_RG_id);
radioButton.setChecked(true);
}
if(actionAfterFinished_RG_id!=0){
RadioButtonradioButton=(RadioButton)actionAfterFinished_RG.findViewById(actionAfterFinished_RG_id);
radioButton.setChecked(true);
}
if(heading_RG_id!=0){
RadioButtonradioButton=(RadioButton)heading_RG.findViewById(heading_RG_id);
radioButton.setChecked(true);
}
speed_RG.setOnCheckedChangeListener(newRadioGroup.OnCheckedChangeListener(){
@Override
publicvoidonCheckedChanged(RadioGroupgroup,intcheckedId){
if(checkedId==R.id.lowSpeed){
mSpeed=3.0f;
}elseif(checkedId==R.id.MidSpeed){
mSpeed=5.0f;
}elseif(checkedId==R.id.HighSpeed){
mSpeed=10.0f;
}
speed_RG_id=checkedId;
}

});

actionAfterFinished_RG.setOnCheckedChangeListener(newRadioGroup.OnCheckedChangeListener(){

@Override
publicvoidonCheckedChanged(RadioGroupgroup,intcheckedId){
MyLog.d("选择动作完成");
if(checkedId==R.id.finishNone){
mFinishedAction=WaypointMissionFinishedAction.NO_ACTION;
FinishedAction="0";
}elseif(checkedId==R.id.finishGoHome){
mFinishedAction=WaypointMissionFinishedAction.GO_HOME;
FinishedAction="1";
}elseif(checkedId==R.id.finishAutoLanding){
mFinishedAction=WaypointMissionFinishedAction.AUTO_LAND;
FinishedAction="2";
}elseif(checkedId==R.id.finishToFirst){
mFinishedAction=WaypointMissionFinishedAction.GO_FIRST_WAYPOINT;
FinishedAction="3";
}
actionAfterFinished_RG_id=checkedId;
}
});

heading_RG.setOnCheckedChangeListener(newRadioGroup.OnCheckedChangeListener(){
@Override
publicvoidonCheckedChanged(RadioGroupgroup,intcheckedId){
MyLog.d("选择标题");
if(checkedId==R.id.headingNext){
mHeadingMode=WaypointMissionHeadingMode.AUTO;
HeadingMode="0";
}elseif(checkedId==R.id.headingInitDirec){
mHeadingMode=WaypointMissionHeadingMode.USING_INITIAL_DIRECTION;
HeadingMode="1";
}elseif(checkedId==R.id.headingRC){
mHeadingMode=WaypointMissionHeadingMode.CONTROL_BY_REMOTE_CONTROLLER;
HeadingMode="2";
}elseif(checkedId==R.id.headingWP){
mHeadingMode=WaypointMissionHeadingMode.USING_WAYPOINT_HEADING;
HeadingMode="3";
}
heading_RG_id=checkedId;
}
});

newAlertDialog.Builder(this)
.setTitle("航点设置")
.setView(wayPointSettings)
.setNeutralButton("设置",newDialogInterface.OnClickListener(){
publicvoidonClick(DialogInterfacedialog,intid){
StringaltitudeString=wpAltitude_TV.getText().toString();
altitude=Integer.parseInt(nulltoIntegerDefalt(altitudeString));
MyLog.e("altitude"+altitude);
MyLog.e("speed"+mSpeed);
MyLog.e("mFinishedAction"+mFinishedAction);
MyLog.e("mHeadingMode"+mHeadingMode);
configWayPointMission();
}
})
.setCancelable(false)
.create()
.show();
}

StringnulltoIntegerDefalt(Stringvalue){
if(!isIntValue(value))
value="0";
returnvalue;
}

booleanisIntValue(Stringval){
try{
val=val.replace("","");
Integer.parseInt(val);
}catch(Exceptione){
returnfalse;
}
returntrue;
}

privatevoidconfigWayPointMission(){

if(waypointMissionBuilder==null){

waypointMissionBuilder=newWaypointMission.Builder().finishedAction(mFinishedAction)
.headingMode(mHeadingMode)
.autoFlightSpeed(mSpeed)
.maxFlightSpeed(mSpeed)
.flightPathMode(WaypointMissionFlightPathMode.NORMAL);

}else{
waypointMissionBuilder.finishedAction(mFinishedAction)
.headingMode(mHeadingMode)
.autoFlightSpeed(mSpeed)
.maxFlightSpeed(mSpeed)
.flightPathMode(WaypointMissionFlightPathMode.NORMAL);

}

if(waypointMissionBuilder.getWaypointList().size()>0){
for(inti=0;i< waypointMissionBuilder.getWaypointList().size(); i++) {
                    waypointMissionBuilder.getWaypointList().get(i).altitude = altitude;
                }
            }

            DJIError error = getWaypointMissionOperator().loadMission(waypointMissionBuilder.build());
            if (error == null) {
                if (mLinearLayoutInformation.getVisibility() == View.GONE) {
                    mLinearLayoutInformation.setVisibility(View.VISIBLE);
                }
                mTextViewHeight.setText("高度:" + altitude + "m");
                mTextViewSpeed.setText("速度:" + mSpeed + "m/s");
                mTextViewCount.setText("航点数:" + waypointMissionBuilder.getWaypointCount());
                mTextViewDistance.setText("总距离:" + Math.round(waypointMissionBuilder.calculateTotalDistance()) + "m");
                mTextViewTime.setText("总时间:" + Math.round(waypointMissionBuilder.calculateTotalTime()) + "min");
                MyLog.d("航点数:" + waypointMissionBuilder.getWaypointCount());
                MyLog.d("总距离:" + waypointMissionBuilder.calculateTotalDistance());
                MyLog.d("总时间:" + waypointMissionBuilder.calculateTotalTime());
                showToasts("航路点配置成功");
            } else {
                showToasts("航路点配置失败 " + error.getDescription());
            }

        }

        private void uploadWayPointMission() {
            getWaypointMissionOperator().uploadMission(new CommonCallbacks.CompletionCallback() {
                @Override
                public void onResult(DJIError error) {
                    if (error == null) {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                mButtonSetting.setVisibility(View.GONE);
                                mButtonUpload.setVisibility(View.GONE);
                                mButtonStart.setVisibility(View.VISIBLE);
                                mButtonStop.setVisibility(View.VISIBLE);
                            }
                        });
                        showToasts("任务上传成功!");
                        mSQLiteHelper = new SQLiteHelper(SettingRouteActivity.this);
                        MyLog.d("航点值:" + GsonUtil.GsonString(mPointInfo));
                        mSQLiteHelper.doInsert(GsonUtil.GsonString(mPointInfo), altitude, mSpeed, HeadingMode, FinishedAction,
                                waypointMissionBuilder.getWaypointCount(), Math.round(waypointMissionBuilder.calculateTotalDistance()),
                                Math.round(waypointMissionBuilder.calculateTotalTime()), DateUtils.getCurrentDate());
                        mSQLiteHelper.close();
                    } else {
                        showToasts("任务上传失败, error: " + error.getDescription() + " retrying...");
                        getWaypointMissionOperator().retryUploadMission(null);
                    }
                }
            });

        }

        private void startWaypointMission() {

            getWaypointMissionOperator().startMission(new CommonCallbacks.CompletionCallback() {
                @Override
                public void onResult(DJIError error) {
                    showToasts("任务开始: " + (error == null ? "成功" : "失败:" + error.getDescription()));
                }
            });

        }

        private void stopWaypointMission() {

            getWaypointMissionOperator().stopMission(new CommonCallbacks.CompletionCallback() {
                @Override
                public void onResult(DJIError error) {
                    showToasts("任务暂停: " + (error == null ? "成功" : "失败" + error.getDescription()));
                }
            });
        }

        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            switch (requestCode) {
                case 101:
                    int Id = data.getExtras().getInt("id");
                    MyLog.d("返回的ID:" + Id);
                    if (Id >-1){
refreshMapPoint(Id);
}
break;
case102:
if(data.getData()!=null){
Uriuri=data.getData();//得到uri,后面就是将uri转化成file的过程。
Stringimg_path=uri.getPath();
try{
if(!TextUtils.isEmpty(img_path)){
readKml.parseKml(img_path);
addSampleMarker();
}
}catch(Exceptione){
e.printStackTrace();
}
}
break;
default:
break;
}

}

privatevoidrefreshMapPoint(intid){
aMap.clear();
mMarkers.clear();
mPointInfo.clear();
mLinearLayoutInformation.setVisibility(View.GONE);
mButtonFinish.setVisibility(View.GONE);
mButtonSetting.setVisibility(View.GONE);
mButtonUpload.setVisibility(View.GONE);
mButtonStart.setVisibility(View.GONE);
mButtonStop.setVisibility(View.GONE);
waypointList.clear();
mSQLiteHelper=newSQLiteHelper(SettingRouteActivity.this);
Cursorc=mSQLiteHelper.doSelectWaypoint(id);
if(c!=null){
if(c.moveToNext()){
MyLog.d("航点:"+"{'pointInfo':"+c.getString(1)+"}");
mPointInfo.addAll(GsonUtil.GsonToBean("{'pointInfo':"+c.getString(1)+"}",Root.class).getPointInfo());
altitude=c.getFloat(2);
mSpeed=c.getFloat(3);
switch(c.getString(4)){
case"0":
mHeadingMode=WaypointMissionHeadingMode.AUTO;
break;
case"1":
mHeadingMode=WaypointMissionHeadingMode.USING_INITIAL_DIRECTION;
break;
case"2":
mHeadingMode=WaypointMissionHeadingMode.CONTROL_BY_REMOTE_CONTROLLER;
break;
case"3":
mHeadingMode=WaypointMissionHeadingMode.USING_WAYPOINT_HEADING;
break;
case"4":
mHeadingMode=WaypointMissionHeadingMode.TOWARD_POINT_OF_INTEREST;
break;
}
switch(c.getString(5)){
case"0":
mFinishedAction=WaypointMissionFinishedAction.NO_ACTION;
break;
case"1":
mFinishedAction=WaypointMissionFinishedAction.GO_HOME;
break;
case"2":
mFinishedAction=WaypointMissionFinishedAction.AUTO_LAND;
break;
case"3":
mFinishedAction=WaypointMissionFinishedAction.GO_FIRST_WAYPOINT;
break;
case"4":
mFinishedAction=WaypointMissionFinishedAction.CONTINUE_UNTIL_END;
break;
}
}
}
for(inti=0;i< mPointInfo.size(); i++) {
                showWaypoint(new LatLng(mPointInfo.get(i).getLatitude(), mPointInfo.get(i).getLongitude()));
                Waypoint mWaypoint = new Waypoint(mPointInfo.get(i).getLatitude(), mPointInfo.get(i).getLongitude(), altitude);
                if (waypointMissionBuilder != null) {
                    waypointList.add(mWaypoint);
                    waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());
                } else {
                    waypointMissionBuilder = new WaypointMission.Builder();
                    waypointList.add(mWaypoint);
                    waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());
                }
            }
            aMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(new LatLng(mPointInfo.get(0).getLatitude(), mPointInfo.get(0).getLongitude()), 18, 0, 0)));
            ResultconfigWayPointMission();
            getWaypointMissionOperator().uploadMission(new CommonCallbacks.CompletionCallback() {
                @Override
                public void onResult(DJIError djiError) {
                    if (djiError == null) {
                        showToasts("获取任务成功!");
                    }
                }
            });
        }

        private void showWaypoint(LatLng point) {
            MarkerOptions markerOptions = new MarkerOptions();
            markerOptions.position(point);
            markerOptions.title("航点" + (mMarkers.size() + 1));
            markerOptions.snippet("事件:");
            markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
            markerOptions.infoWindowEnable(true);
            Marker marker = aMap.addMarker(markerOptions);
            mMarkers.put(mMarkers.size(), marker);
            marker.showInfoWindow();
            if (mMarkers.size() >0){
mLatLng.clear();
PolylineOptionsPolylineOptions=newPolylineOptions();
for(inti=0;i< mMarkers.size(); i++) {
                    mLatLng.add(mMarkers.get(i).getPosition());
                }
                PolylineOptions.addAll(mLatLng);
                PolylineOptions.width(10);
                PolylineOptions.color(Color.argb(255, 1, 1, 1));
                aMap.addPolyline(PolylineOptions);
            }
        }

        private void ResultconfigWayPointMission() {

            if (waypointMissionBuilder == null) {

                waypointMissionBuilder = new WaypointMission.Builder().finishedAction(mFinishedAction)
                        .headingMode(mHeadingMode)
                        .autoFlightSpeed(mSpeed)
                        .maxFlightSpeed(mSpeed)
                        .flightPathMode(WaypointMissionFlightPathMode.NORMAL);

            } else {
                waypointMissionBuilder.finishedAction(mFinishedAction)
                        .headingMode(mHeadingMode)
                        .autoFlightSpeed(mSpeed)
                        .maxFlightSpeed(mSpeed)
                        .flightPathMode(WaypointMissionFlightPathMode.NORMAL);

            }

            if (waypointMissionBuilder.getWaypointList().size() >0){
for(inti=0;i< waypointMissionBuilder.getWaypointList().size(); i++) {
                    waypointMissionBuilder.getWaypointList().get(i).altitude = altitude;
                }
            }

            DJIError error = getWaypointMissionOperator().loadMission(waypointMissionBuilder.build());
            if (error == null) {
                if (mLinearLayoutInformation.getVisibility() == View.GONE) {
                    mLinearLayoutInformation.setVisibility(View.VISIBLE);
                }
                mButtonStart.setVisibility(View.VISIBLE);
                mButtonStop.setVisibility(View.VISIBLE);
                mTextViewHeight.setText("高度:" + altitude + "m");
                mTextViewSpeed.setText("速度:" + mSpeed + "m/s");
                mTextViewCount.setText("航点数:" + waypointMissionBuilder.getWaypointCount());
                mTextViewDistance.setText("总距离:" + Math.round(waypointMissionBuilder.calculateTotalDistance()) + "m");
                mTextViewTime.setText("总时间:" + Math.round(waypointMissionBuilder.calculateTotalTime()) + "min");
            }
        }

        private void addSampleMarker() {
            if (ReadKml.addSampleSuccess) {
                aMap.clear();
                mMarkers.clear();
                mPointInfo.clear();
                waypointList.clear();
                if (mLinearLayoutInformation.getVisibility() == View.VISIBLE) {
                    mLinearLayoutInformation.setVisibility(View.GONE);
                }
                mButtonFinish.setVisibility(View.GONE);
                mButtonSetting.setVisibility(View.GONE);
                mButtonUpload.setVisibility(View.GONE);
                mButtonStart.setVisibility(View.GONE);
                mButtonStop.setVisibility(View.GONE);
                for (int i = 0; i < sampleList.size(); i++) {
                    showWaypoint(new LatLng(sampleList.get(i).getX(), sampleList.get(i).getY()));
                    Waypoint mWaypoint = new Waypoint(sampleList.get(i).getX(), sampleList.get(i).getY(), altitude);
                    //Add Waypoints to Waypoint arraylist;
                    if (waypointMissionBuilder != null) {
                        waypointList.add(mWaypoint);
                        waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());
                    } else {
                        waypointMissionBuilder = new WaypointMission.Builder();
                        waypointList.add(mWaypoint);
                        waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());
                    }
                }
                aMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(new LatLng(sampleList.get(0).getX(), sampleList.get(0).getY()), 18, 0, 0)));
                showSettingDialog();
                mButtonSetting.setVisibility(View.VISIBLE);
                mButtonUpload.setVisibility(View.VISIBLE);
            } else {
                Log.d("MainActivity", "addSampleSuccess is false or aMap is null");
            }
        }


3

航线管理

创建activity_waypoint.xml和WaypointActivity文件。

activity_waypoint.xml






WaypointActivity

@Layout(R.layout.activity_waypoint)
publicclassWaypointActivityextendsBaseActivityimplementsView.OnClickListener{
@BindView(R.id.layout_waypoint)
ViewmViewLayoutToolbar;
@BindView(R.id.ll_waypoint)
LinearLayoutmLinearLayout;
@BindView(R.id.tv_toolbar_title)
TextViewmTextViewToolbarTitle;
@BindView(R.id.rv_waypoint)
RecyclerViewmRecyclerView;

privateSQLiteHelpermSQLiteHelper;
privateListmWaypointInfo=newArrayList<>();
privateWaypointAdaptermWaypointAdapter;

privateListmWaypointId=newArrayList<>();
privateStringStrId="";

@Override
publicvoidinitViews(){
mLinearLayout.setVisibility(View.VISIBLE);
mTextViewToolbarTitle.setText("航线管理");
MyStatic.isChoose=false;
}

@Override
publicvoidinitDatas(){
mSQLiteHelper=newSQLiteHelper(WaypointActivity.this);
Cursorc=mSQLiteHelper.doSelect();
if(c!=null){
while(c.moveToNext()){
mWaypointInfo.add(newWaypointInfo(c.getInt(0),c.getString(1),c.getFloat(2),c.getFloat(3),
c.getString(4),c.getString(5),c.getString(6),c.getInt(7),c.getInt(8),
c.getInt(9),c.getString(10)));
}
}
c.close();
mSQLiteHelper.close();
mWaypointAdapter=newWaypointAdapter(R.layout.item_waypoint);
mWaypointAdapter.setNewData(mWaypointInfo);
initRv(mRecyclerView,mWaypointAdapter);
mWaypointAdapter.setOnItemChildClickListener(newBaseQuickAdapter.OnItemChildClickListener(){
@Override
publicvoidonItemChildClick(BaseQuickAdapteradapter,Viewview,intposition){
Intentintent=newIntent();
intent.putExtra("id",mWaypointInfo.get(position).getId());
setResult(RESULT_OK,intent);
finish();
}
});
mWaypointAdapter.setOnCheckboxCheckedListener(newWaypointAdapter.OnCheckboxCheckedListener(){
@Override
publicvoidOnCheckboxChecked(booleanisCheck,intposition){
if(isCheck){
mWaypointId.add(position);
}else{
if(mWaypointId.contains(position)){
mWaypointId.remove(position);
}
}
}
});

}

@Override
protectedvoidrequestData(){

}

@OnClick({R.id.img_way_choose,R.id.img_way_delete,R.id.img_back})
@Override
publicvoidonClick(Viewv){
switch(v.getId()){
caseR.id.img_way_choose:
if(MyStatic.isChoose){
MyStatic.isChoose=false;
}else{
MyStatic.isChoose=true;
}
if(mWaypointAdapter!=null){
mWaypointAdapter.notifyDataSetChanged();
}
break;
caseR.id.img_way_delete:
if(mWaypointId.size()>0){
for(inti=0;i< mWaypointId.size(); i++){
                        StrId += mWaypointInfo.get(mWaypointId.get(i)).getId()+",";
                    }
                    if (!TextUtils.isEmpty(StrId)){
                        StrId = StrId.substring(0,StrId.length()-1);
                        mSQLiteHelper = new SQLiteHelper(WaypointActivity.this);
                        mSQLiteHelper.doDelete(StrId);
                        mSQLiteHelper.close();
                        for (int j = 0; j < mWaypointId.size(); j++){
                            mWaypointInfo.remove(mWaypointId.get(j).intValue());
                        }
                        if (mWaypointAdapter!=null){
                            mWaypointId.clear();
                            MyStatic.isChoose = false;
                            mWaypointAdapter.setNewData(mWaypointInfo);
                        }
                    }
                }else {
                    showToasts("请先选择删除的航线!");
                }
                break;
            case R.id.img_back:
                Intent intent = new Intent();
                intent.putExtra("id", -1);
                setResult(RESULT_OK, intent);
                finish();
                break;
        }
    }

以上代码仅供参考,如果想了解更多的大疆无人机二次开发过程可以私信我,源代码因为涉及到商业使用不能给大家共享,有什么问题我可以帮你解决。

审核编辑:汤梓红

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

    关注

    0

    文章

    518

    浏览量

    26484
  • 遥控器
    +关注

    关注

    18

    文章

    837

    浏览量

    66103
  • 无人机
    +关注

    关注

    230

    文章

    10434

    浏览量

    180340
  • SDK
    SDK
    +关注

    关注

    3

    文章

    1036

    浏览量

    45922
  • 大疆无人机
    +关注

    关注

    13

    文章

    111

    浏览量

    30219

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

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

收藏 人收藏

    评论

    相关推荐

    拆解大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>

    【Aworks申请】开放式无人机地面基站

    申请理由:我们是在校大学生EDA兴趣团队,正在设计制作无人机项目。我们发现,现在无人机只能通过遥控器或者电脑上位机控制飞行。所以,我们试图开发一个通用式地面基站,开放API和视频数据流
    发表于 06-27 08:59

    【云智易申请】智能无人机通信

    申请理由:本次项目是基于STM32做无人机,主要用WiFi实现无人机遥控器之间通信,无人机的电机我们可以用云智易开发板上面的电机进行调试,
    发表于 08-07 11:02

    无人机遥控方向控制问题

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

    stm32四轴无人机遥控器资料

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

    无人机怎么悬停

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

    【快速上手教程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 8042次阅读

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

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

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

    刚刚结束了项目交付,趁热打铁分享一下这次遇到的新东西。首先了解一下大无人机,它大致可以分为三级。
    的头像 发表于 06-07 09:53 1165次阅读
    基于<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>(1)

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

    上一篇文章(基于Mobile SDK V4固件开发无人
    的头像 发表于 06-09 11:33 1008次阅读
    基于<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 V5版固件开发无人机手机遥控器(4)

    相较与V4版本开发V5版本有了更方便简介的方式。V5不仅再功能上与V4增加更多的功能,而且在功能的使用及API的调用也做了优化。虽然
    的头像 发表于 06-25 12:24 2587次阅读
    基于<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 2321次阅读
    基于<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)