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

    文章

    515

    浏览量

    26344
  • 遥控器
    +关注

    关注

    18

    文章

    815

    浏览量

    64255
  • 无人机
    +关注

    关注

    224

    文章

    9887

    浏览量

    174827
  • SDK
    SDK
    +关注

    关注

    3

    文章

    966

    浏览量

    44727
  • 大疆无人机
    +关注

    关注

    13

    文章

    108

    浏览量

    29749

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

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

收藏 人收藏

    评论

    相关推荐

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

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

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

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

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

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

    【ELF灵翼自拍无人机测评】-3 飞行篇

    ` 本帖最后由 cztqwan 于 2016-5-3 14:22 编辑 【ELF灵翼自拍无人机测评】-3 飞行篇一、综合评价: 操控手感:使用手机APP作为
    发表于 05-03 11:22

    无人机遥控方向控制问题

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

    stm32四轴无人机遥控器资料

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

    无人机怎么悬停

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

    DJI大创新推出首款农业无人机

    全球飞行影像系统的开拓者和领导者DJI大创新今日宣布推出一款智能农业喷洒防治无人机——大MG-1农业植保机,标志着大创新正式进入农业无人机
    发表于 05-12 07:22

    怎么实现STM32采集无人机遥控器PPM信号?

    怎么实现STM32采集无人机遥控器PPM信号?
    发表于 11-18 06:10

    【快速上手教程6】疯壳·开源编队无人机-遥控器固件烧写

    COCOFLY 教程——疯壳·无人机·系列遥控器固件烧写 图1 一、遥控器固件烧写 这里的固件
    发表于 05-25 11:49

    【快速上手教程6】疯壳·开源编队无人机-遥控器固件烧写

    COCOFLY 教程——疯壳·无人机·系列遥控器固件烧写 图1 一、遥控器固件烧写 这里的固件
    发表于 07-07 10:05

    【疯壳·无人机教程6】开源编队无人机-遥控器固件烧写

    COCOFLY 教程——疯壳·无人机·系列遥控器固件烧写图1 一、遥控器固件烧写 这里的固件
    发表于 08-23 17:49

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

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

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

    上一篇文章(基于Mobile SDK V4固件开发大疆无人机手机
    的头像 发表于 06-09 11:33 635次阅读
    基于<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>(2)

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

    相较与V4版本开发,V5版本有了更方便简介的方式。V5不仅再功能上与V4增加更多的功能,而且在功能的使用及API的调用也做了优化。虽然V5现在很新也在不断地迭代,但是不免会出现对一些飞行或者
    的头像 发表于 06-25 12:24 1348次阅读
    基于<b class='flag-5'>Mobile</b> <b class='flag-5'>SDK</b> V5版<b class='flag-5'>固件</b><b class='flag-5'>开发</b>大疆<b class='flag-5'>无人机手机</b>端<b class='flag-5'>遥控器</b>(4)