博客专栏

EEPW首页 > 博客 > 基于Mobile SDK V4版固件开发大疆无人机手机端遥控器(3)

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

发布人:美男子玩编程 时间:2023-06-21 来源:工程师 发布文章

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

1

航线规划

航线打点 

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


图片


航点设置 

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

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

航线上传

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


图片


航线执行 

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

航线管理

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

图片


获取航线 

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

图片


2

主要功能代码

创建activity_setting_route.xml及SettingRouteActivity文件。

activity_setting_route.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".ui.SettingRouteActivity">

    <include
        android:id="@+id/layout_route"
        layout="@layout/activity_toolbar">
</include>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.amap.api.maps.MapView
            android:id="@+id/map"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_centerInParent="true"
            android:layout_marginTop="5dp">

            <Button
                android:id="@+id/btn_delete"
                android:layout_width="60dp"
                android:layout_height="30dp"
                android:visibility="gone"
                android:text="删除"
                android:textColor="@color/white"
                android:background="@drawable/button_task_background">
</Button>
            <Button
                android:id="@+id/btn_finish"
                android:layout_width="60dp"
                android:layout_height="30dp"
                android:visibility="gone"
                android:textColor="@color/white"
                android:background="@drawable/button_task_background"
                android:text="完成">
</Button>
            <Button
                android:id="@+id/btn_setting"
                android:layout_width="60dp"
                android:layout_height="30dp"
                android:visibility="gone"
                android:textColor="@color/white"
                android:background="@drawable/button_task_background"
                android:text="设置">
</Button>
            <Button
                android:id="@+id/btn_upload"
                android:layout_width="60dp"
                android:layout_height="30dp"
                android:visibility="gone"
                android:textColor="@color/white"
                android:background="@drawable/button_task_background"
                android:text="上传">
</Button>
            <Button
                android:id="@+id/btn_start"
                android:layout_width="60dp"
                android:layout_height="30dp"
                android:visibility="gone"
                android:textColor="@color/white"
                android:background="@drawable/button_task_background"
                android:text="开始">
</Button>
            <Button
                android:id="@+id/btn_stop"
                android:layout_width="60dp"
                android:layout_height="30dp"
                android:visibility="gone"
                android:textColor="@color/white"
                android:background="@drawable/button_task_background"
                android:text="暂停">
</Button>
        </LinearLayout>
        <LinearLayout
            android:id="@+id/ll_information"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_centerInParent="true"
            android:layout_marginBottom="5dp"
            android:padding="10dp"
            android:visibility="gone"
            android:background="@color/color_nav_Item_unselected">

            <TextView
                android:id="@+id/tv_height"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="高度:"
                android:textColor="@color/white"
                >
</TextView>
            <TextView
                android:id="@+id/tv_speed"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="速度:"
                android:textColor="@color/white"
                android:layout_marginLeft="10dp"
                >
</TextView>
            <TextView
                android:id="@+id/tv_count"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="航点数:"
                android:textColor="@color/white"
                android:layout_marginLeft="10dp"
                >
</TextView>
            <TextView
                android:id="@+id/tv_distance"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="总距离:"
                android:textColor="@color/white"
                android:layout_marginLeft="10dp"
                >
</TextView>
            <TextView
                android:id="@+id/tv_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="总时间:"
                android:textColor="@color/white"
                android:layout_marginLeft="10dp"
                >
</TextView>
        </LinearLayout>
    </RelativeLayout>
</LinearLayout>

SettingRouteActivity

public class SettingRouteActivity extends BaseActivity implements AMap.OnMarkerClickListenerView.OnClickListenerAMap.OnMapClickListenerLocationSourceAMapLocationListenerAMap.InfoWindowAdapter {
    @BindView(R.id.layout_route)
        View mViewLayoutToolbar;
        @BindView(R.id.ll_route)
        LinearLayout mLinearLayout;
        @BindView(R.id.tv_toolbar_title)
        TextView mTextViewToolbarTitle;
    //    @BindView(R.id.map)
    //    MapView mMapView;
        @BindView(R.id.btn_delete)
        Button mButtonDelete;
        @BindView(R.id.btn_finish)
        Button mButtonFinish;
        @BindView(R.id.btn_setting)
        Button mButtonSetting;
        @BindView(R.id.btn_upload)
        Button mButtonUpload;
        @BindView(R.id.btn_start)
        Button mButtonStart;
        @BindView(R.id.btn_stop)
        Button mButtonStop;
        @BindView(R.id.ll_information)
        LinearLayout mLinearLayoutInformation;
        @BindView(R.id.tv_height)
        TextView mTextViewHeight;
        @BindView(R.id.tv_speed)
        TextView mTextViewSpeed;
        @BindView(R.id.tv_count)
        TextView mTextViewCount;
        @BindView(R.id.tv_distance)
        TextView mTextViewDistance;
        @BindView(R.id.tv_time)
        TextView mTextViewTime;
        private MapView mMapView;
        private OnLocationChangedListener mListener;
        private AMapLocationClient mlocationClient;
        private AMapLocationClientOption mLocationOption;
        private double D_latitude, D_longitude;
        private UiSettings mUiSettings;
        private AMap aMap;
        private Marker droneMarker = null;
        private float altitude = 100.0f;
        private float mSpeed = 10.0f;
        private boolean isAdd = false;
        private final Map<Integer, Marker> mMarkers = new ConcurrentHashMap<Integer, Marker>();
        private Marker mClickMarker;
        private List<Waypoint> waypointList = new ArrayList<>();
        private List<LatLng> mLatLng = new ArrayList<>();
        private List<PointInfo> mPointInfo = new ArrayList<>();
        public static WaypointMission.Builder waypointMissionBuilder;
        private FlightController mFlightController;
        private WaypointMissionOperator instance;
        private WaypointMissionFinishedAction mFinishedAction = WaypointMissionFinishedAction.NO_ACTION;
        private WaypointMissionHeadingMode mHeadingMode = WaypointMissionHeadingMode.AUTO;
        private SQLiteHelper mSQLiteHelper;
        private String FinishedAction, HeadingMode;
        //自定义窗体
        View infoWindow = null;
        int speed_RG_id = 0;
        int actionAfterFinished_RG_id = 0;
        int heading_RG_id = 0;
        //kim
        static ReadKml readKml = new ReadKml();
        private static List<Coordinate> sampleList = readKml.getCoordinateList();
        @Override
        public void initViews() {
            mLinearLayout.setVisibility(View.VISIBLE);
            mTextViewToolbarTitle.setText("航线规划");
            IntentFilter filter = new IntentFilter();
            filter.addAction(ReceiverApplication.FLAG_CONNECTION_CHANGE);
            registerReceiver(mReceiver, filter);
            mMapView = findViewById(R.id.map);
            mMapView.onCreate(InstanceState);
            initMapView();
            addListener();
            onProductConnectionChange();
        }
        @Override
        protected void onResume() {
            super.onResume();
            initFlightController();
            mMapView.onResume();
        }
        /**
         * 方法必须重写
         */

        @Override
        protected void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
            mMapView.onSaveInstanceState(outState);
        }
        @Override
        protected void onPause() {
            super.onPause();
            mMapView.onPause();
            deactivate();
        }
        @Override
        protected void onDestroy() {
            super.onDestroy();
            unregisterReceiver(mReceiver);
            removeListener();
            mMapView.onDestroy();
            if (null != mlocationClient) {
                mlocationClient.onDestroy();
            }
        }
        @Override
        public void initDatas() {
        }
        @Override
        protected void requestData() {
        }
        private void initMapView() {
            if (aMap == null) {
                aMap = mMapView.getMap();
                mUiSettings = aMap.getUiSettings();
                mUiSettings.setMyLocationButtonEnabled(true);
                mUiSettings.setScaleControlsEnabled(true);
                aMap.setOnMapClickListener(this);// add the listener for click for amap object
                aMap.setLocationSource(this);
                aMap.setMyLocationEnabled(true);
                aMap.setInfoWindowAdapter(this);
                aMap.setOnMarkerClickListener(this);
                setupLocationStyle();
            }
        }
        private void setupLocationStyle() {
            // 自定义系统定位蓝点
            MyLocationStyle myLocationStyle = new MyLocationStyle();
            // 自定义定位蓝点图标
            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
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.img_back:
                    SettingRouteActivity.this.finish();
                    break;
                case R.id.img_kml_input:
                    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                    intent.setType("*/*");//设置类型,我这里是任意类型,任意后缀的可以这样写。
                    intent.addCategory(Intent.CATEGORY_OPENABLE);
                    startActivityForResult(intent, MyStatic.REQUEST_CODE_FILE);
                    break;
                case R.id.img_setting_route:
                    enableDisableAdd();
                    break;
                case R.id.img_setting_clear:
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            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;
                case R.id.img_start_fly:
                    atyAction(WaypointActivity.classMyStatic.REQUEST_CODE_ID);
                    break;
                case R.id.btn_delete:
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            aMap.clear();
                        }
                    });
                    for (int i = 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();
                PolylineOptions PolylineOptions = new PolylineOptions();
                for (int i = 0; i < mMarkers.size(); i++) {
                    mLatLng.add(mMarkers.get(i).getPosition());
                }
                PolylineOptions.addAll(mLatLng);
                PolylineOptions.width(10);
                PolylineOptions.color(Color.argb(255111));
                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) {
                PolylineOptions PolylineOptions = new PolylineOptions();
                PolylineOptions.addAll(mLatLng);
                PolylineOptions.width(10);
                PolylineOptions.color(Color.argb(255111));
                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
        public void onLocationChanged(AMapLocation amapLocation) {
            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 {
                    String errText = "定位失败," + amapLocation.getErrorCode() + ": " + amapLocation.getErrorInfo();
                    Log.e("AmapErr", errText);
                }
            }
        }
        @Override
        public void activate(OnLocationChangedListener listener) {
            mListener = listener;
            if (mlocationClient == null) {
                try {
                    mlocationClient = new AMapLocationClient(this);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                mLocationOption = new AMapLocationClientOption();
                //设置定位监听
                mlocationClient.setLocationListener(this);
                //设置为高精度定位模式
                mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
                //设置定位参数
                mLocationOption.setOnceLocation(true);
                mlocationClient.setLocationOption(mLocationOption);
                // 此方法为每隔固定时间会发起一次定位请求,为了减少电量消耗或网络流量消耗,
                // 注意设置合适的定位时间的间隔(最小间隔支持为2000ms),并且在合适时间调用stopLocation()方法来取消定位请求
                // 在定位结束后,在合适的生命周期调用onDestroy()方法
                // 在单次定位情况下,定位无论成功与否,都无需调用stopLocation()方法移除请求,定位sdk内部会移除
                mlocationClient.startLocation();
            }
        }
        @Override
        public void deactivate() {
            mListener = null;
            if (mlocationClient != null) {
                mlocationClient.stopLocation();
                mlocationClient.onDestroy();
            }
            mlocationClient = null;
        }
        @Override
        public View getInfoWindow(Marker marker) {
            if (infoWindow == null) {
                infoWindow = LayoutInflater.from(this).inflate(R.layout.amap_info_window, null);
            }
            render(marker, infoWindow);
            return infoWindow;
        }
        /**
         * 自定义infoWindow窗口
         */

        private void render(Marker marker, View infoWindow) {
            TextView title = infoWindow.findViewById(R.id.info_window_title);
            TextView content = infoWindow.findViewById(R.id.info_window_content);
            title.setText(marker.getTitle());
            content.setText(marker.getSnippet());
        }
        @Override
        public View getInfoContents(Marker marker) {
            return null;
        }
        @Override
        public boolean onMarkerClick(Marker marker) {
            marker.showInfoWindow();
            mClickMarker = marker;
            mButtonDelete.setVisibility(View.VISIBLE);
            //        aMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(marker.getPosition(),18,0,0)));
            return true;
        }
        private void showSettingDialog() {
            LinearLayout wayPointSettings = (LinearLayout) getLayoutInflater().inflate(R.layout.dialog_waypointsetting, null);
            final TextView wpAltitude_TV = (TextView) wayPointSettings.findViewById(R.id.altitude);
            RadioGroup speed_RG = (RadioGroup) wayPointSettings.findViewById(R.id.speed);
            RadioGroup actionAfterFinished_RG = (RadioGroup) wayPointSettings.findViewById(R.id.actionAfterFinished);
            RadioGroup heading_RG = (RadioGroup) wayPointSettings.findViewById(R.id.heading);
            wpAltitude_TV.setText(Math.round(altitude) + "");
            if (speed_RG_id != 0) {
                RadioButton radioButton = (RadioButton) speed_RG.findViewById(speed_RG_id);
                radioButton.setChecked(true);
            }
            if (actionAfterFinished_RG_id != 0) {
                RadioButton radioButton = (RadioButton) actionAfterFinished_RG.findViewById(actionAfterFinished_RG_id);
                radioButton.setChecked(true);
            }
            if (heading_RG_id != 0) {
                RadioButton radioButton = (RadioButton) heading_RG.findViewById(heading_RG_id);
                radioButton.setChecked(true);
            }
            speed_RG.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(RadioGroup group, int checkedId) {
                    if (checkedId == R.id.lowSpeed) {
                        mSpeed = 3.0f;
                    } else if (checkedId == R.id.MidSpeed) {
                        mSpeed = 5.0f;
                    } else if (checkedId == R.id.HighSpeed) {
                        mSpeed = 10.0f;
                    }
                    speed_RG_id = checkedId;
                }
            });
            actionAfterFinished_RG.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(RadioGroup group, int checkedId) {
                    MyLog.d("选择动作完成");
                    if (checkedId == R.id.finishNone) {
                        mFinishedAction = WaypointMissionFinishedAction.NO_ACTION;
                        FinishedAction = "0";
                    } else if (checkedId == R.id.finishGoHome) {
                        mFinishedAction = WaypointMissionFinishedAction.GO_HOME;
                        FinishedAction = "1";
                    } else if (checkedId == R.id.finishAutoLanding) {
                        mFinishedAction = WaypointMissionFinishedAction.AUTO_LAND;
                        FinishedAction = "2";
                    } else if (checkedId == R.id.finishToFirst) {
                        mFinishedAction = WaypointMissionFinishedAction.GO_FIRST_WAYPOINT;
                        FinishedAction = "3";
                    }
                    actionAfterFinished_RG_id = checkedId;
                }
            });
            heading_RG.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(RadioGroup group, int checkedId) {
                    MyLog.d("选择标题");
                    if (checkedId == R.id.headingNext) {
                        mHeadingMode = WaypointMissionHeadingMode.AUTO;
                        HeadingMode = "0";
                    } else if (checkedId == R.id.headingInitDirec) {
                        mHeadingMode = WaypointMissionHeadingMode.USING_INITIAL_DIRECTION;
                        HeadingMode = "1";
                    } else if (checkedId == R.id.headingRC) {
                        mHeadingMode = WaypointMissionHeadingMode.CONTROL_BY_REMOTE_CONTROLLER;
                        HeadingMode = "2";
                    } else if (checkedId == R.id.headingWP) {
                        mHeadingMode = WaypointMissionHeadingMode.USING_WAYPOINT_HEADING;
                        HeadingMode = "3";
                    }
                    heading_RG_id = checkedId;
                }
            });
            new AlertDialog.Builder(this)
                    .setTitle("航点设置")
                    .setView(wayPointSettings)
                    .setNeutralButton("设置"new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            String altitudeString = 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();
        }
        String nulltoIntegerDefalt(String value) {
            if (!isIntValue(value))
                value = "0";
            return value;
        }
        boolean isIntValue(String val) {
            try {
                val = val.replace(" """);
                Integer.parseInt(val);
            } catch (Exception e) {
                return false;
            }
            return true;
        }
        private void configWayPointMission() {
            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 (int i = 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;
                case 102:
                    if (data.getData() != null) {
                        Uri uri = data.getData();//得到uri,后面就是将uri转化成file的过程。
                        String img_path = uri.getPath();
                        try {
                            if (!TextUtils.isEmpty(img_path)) {
                                readKml.parseKml(img_path);
                                addSampleMarker();
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                default:
                    break;
            }
        }
        private void refreshMapPoint(int id) {
            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 = new SQLiteHelper(SettingRouteActivity.this);
            Cursor c = 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 (int i = 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()), 1800)));
            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();
                PolylineOptions PolylineOptions = new PolylineOptions();
                for (int i = 0; i < mMarkers.size(); i++) {
                    mLatLng.add(mMarkers.get(i).getPosition());
                }
                PolylineOptions.addAll(mLatLng);
                PolylineOptions.width(10);
                PolylineOptions.color(Color.argb(255111));
                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 (int i = 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()), 1800)));
                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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.WaypointActivity"
    android:orientation="vertical"
    android:background="@drawable/shape_corner_eight">

    <include
        android:id="@+id/layout_waypoint"
        layout="@layout/activity_toolbar">
</include>
    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#5B6782"
        android:layout_marginTop="1dp"
        android:layout_marginRight="20dp"
        android:layout_marginLeft="20dp"
        >
</View>
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_waypoint"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginRight="20dp"
        android:layout_marginLeft="20dp">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>

WaypointActivity

@Layout(R.layout.activity_waypoint)
public class WaypointActivity extends BaseActivity implements View.OnClickListener {
    @BindView(R.id.layout_waypoint)
    View mViewLayoutToolbar;
    @BindView(R.id.ll_waypoint)
    LinearLayout mLinearLayout;
    @BindView(R.id.tv_toolbar_title)
    TextView mTextViewToolbarTitle;
    @BindView(R.id.rv_waypoint)
    RecyclerView mRecyclerView;
    private SQLiteHelper mSQLiteHelper;
    private List<WaypointInfo> mWaypointInfo = new ArrayList<>();
    private WaypointAdapter mWaypointAdapter;
    private List<Integer> mWaypointId = new ArrayList<>();
    private String StrId = "";
    @Override
    public void initViews() {
        mLinearLayout.setVisibility(View.VISIBLE);
        mTextViewToolbarTitle.setText("航线管理");
        MyStatic.isChoose = false;
    }
    @Override
    public void initDatas() {
        mSQLiteHelper = new SQLiteHelper(WaypointActivity.this);
        Cursor c = mSQLiteHelper.doSelect();
        if (c!=null){
            while (c.moveToNext()){
                mWaypointInfo.add(new WaypointInfo(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 = new WaypointAdapter(R.layout.item_waypoint);
        mWaypointAdapter.setNewData(mWaypointInfo);
        initRv(mRecyclerView,mWaypointAdapter);
        mWaypointAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
            @Override
            public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
                Intent intent = new Intent();
                intent.putExtra("id", mWaypointInfo.get(position).getId());
                setResult(RESULT_OK, intent);
                finish();
            }
        });
        mWaypointAdapter.setOnCheckboxCheckedListener(new WaypointAdapter.OnCheckboxCheckedListener() {
            @Override
            public void OnCheckboxChecked(boolean isCheck, int position) {
                if (isCheck){
                    mWaypointId.add(position);
                }else {
                    if (mWaypointId.contains(position)){
                        mWaypointId.remove(position);
                    }
                }
            }
        });
    }
    @Override
    protected void requestData() {
    }
    @OnClick({R.id.img_way_choose,R.id.img_way_delete,R.id.img_back})
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.img_way_choose:
                if (MyStatic.isChoose){
                    MyStatic.isChoose = false;
                }else {
                    MyStatic.isChoose = true;
                }
                if (mWaypointAdapter!=null){
                    mWaypointAdapter.notifyDataSetChanged();
                }
                break;
            case R.id.img_way_delete:
                if (mWaypointId.size() > 0){
                    for (int i = 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 大疆无人机

相关推荐

技术专区

关闭