博客专栏

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


<LinearLayoutxmlns: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

publicclassSettingRouteActivityextendsBaseActivityimplementsAMap.OnMarkerClickListener,View.OnClickListener,AMap.OnMapClickListener,LocationSource,AMapLocationListener,AMap.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;
privateMapView mMapView;
privateOnLocationChangedListener mListener;
privateAMapLocationClient mlocationClient;
privateAMapLocationClientOption mLocationOption;
privatedoubleD_latitude, D_longitude;
privateUiSettings mUiSettings;
privateAMap aMap;
privateMarker droneMarker =null;
privatefloataltitude =100.0f;
privatefloatmSpeed =10.0f;
privatebooleanisAdd =false;
privatefinalMap mMarkers =newConcurrentHashMap();
privateMarker mClickMarker;
privateList waypointList =newArrayList<>();
privateList mLatLng =newArrayList<>();
privateList mPointInfo =newArrayList<>();
publicstaticWaypointMission.Builder waypointMissionBuilder;
privateFlightController mFlightController;
privateWaypointMissionOperator instance;
privateWaypointMissionFinishedAction mFinishedAction = WaypointMissionFinishedAction.NO_ACTION;
privateWaypointMissionHeadingMode mHeadingMode = WaypointMissionHeadingMode.AUTO;
privateSQLiteHelper mSQLiteHelper;
privateString FinishedAction, HeadingMode;
//自定义窗体
View infoWindow =null;
intspeed_RG_id =0;
intactionAfterFinished_RG_id =0;
intheading_RG_id =0;
//kim
staticReadKml readKml =newReadKml();
privatestaticList sampleList = readKml.getCoordinateList();
@Override
publicvoidinitViews(){
mLinearLayout.setVisibility(View.VISIBLE);
mTextViewToolbarTitle.setText("航线规划");
IntentFilter filter =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(Bundle outState){
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);// add the listener for click for amap object
aMap.setLocationSource(this);
aMap.setMyLocationEnabled(true);
aMap.setInfoWindowAdapter(this);
aMap.setOnMarkerClickListener(this);
setupLocationStyle();
}
}
privatevoidsetupLocationStyle(){
// 自定义系统定位蓝点
MyLocationStyle myLocationStyle =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(View v){
switch(v.getId()) {
caseR.id.img_back:
SettingRouteActivity.this.finish();
break;
caseR.id.img_kml_input:
Intent intent =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(intj = i; j < mMarkers.size() -1; j++) {
mMarkers.put(j, mMarkers.get(j +1));
}
mMarkers.remove(mMarkers.size() -1);
}
}
for(inti =0; i < mMarkers.size(); i++) {
mMarkers.get(i).setTitle("航点"+ (i +1));
}
updateMarkWaypoint();
break;
caseR.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;
caseR.id.btn_setting:
showSettingDialog();
break;
caseR.id.btn_upload:
uploadWayPointMission();
break;
caseR.id.btn_start:
startWaypointMission();
break;
caseR.id.btn_stop:
stopWaypointMission();
break;
}
}
privatevoidenableDisableAdd(){
if(isAdd ==false) {
isAdd =true;
mButtonFinish.setVisibility(View.VISIBLE);
}else{
isAdd =false;
}
}
privatevoidinitFlightController(){
BaseProduct product = ReceiverApplication.getProductInstance();
if(product !=null&& product.isConnected()) {
if(productinstanceofAircraft) {
mFlightController = ((Aircraft) product).getFlightController();
}
}
if(mFlightController !=null) {
mFlightController.setStateCallback(
newFlightControllerState.Callback() {
@Override
publicvoidonUpdate(FlightControllerState
djiFlightControllerCurrentState)
{
if(djiFlightControllerCurrentState.getAircraftLocation().getLatitude() !=0.0&& djiFlightControllerCurrentState.getAircraftLocation().getLongitude() !=0.0) {
D_latitude = djiFlightControllerCurrentState.getAircraftLocation().getLatitude();
D_longitude = djiFlightControllerCurrentState.getAircraftLocation().getLongitude();
}
updateDroneLocation();
}
});
}
}
privatevoidupdateDroneLocation(){
LatLng pos =newLatLng(D_latitude, D_longitude);
//Create MarkerOptions object
finalMarkerOptions markerOptions =newMarkerOptions();
markerOptions.position(pos);
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_aircraft_write_36dp));
runOnUiThread(newRunnable() {
@Override
publicvoidrun(){
if(droneMarker !=null) {
droneMarker.remove();
}
if(checkGpsCoordination(D_latitude, D_longitude)) {
droneMarker = aMap.addMarker(markerOptions);
}
}
});
}
publicstaticbooleancheckGpsCoordination(doublelatitude,doublelongitude){
return(latitude > -90&& latitude <90&& longitude > -180&& longitude <180) && (latitude !=0f&& longitude !=0f);
}
protectedBroadcastReceiver mReceiver =newBroadcastReceiver() {
@Override
publicvoidonReceive(Context context, Intent intent){
onProductConnectionChange();
}
};
privatevoidonProductConnectionChange(){
initFlightController();
}
privatevoidaddListener(){
if(getWaypointMissionOperator() !=null) {
getWaypointMissionOperator().addListener(eventNotificationListener);
}
}
privatevoidremoveListener(){
if(getWaypointMissionOperator() !=null) {
getWaypointMissionOperator().removeListener(eventNotificationListener);
}
}
privateWaypointMissionOperatorListener eventNotificationListener =newWaypointMissionOperatorListener() {
@Override
publicvoidonDownloadUpdate(WaypointMissionDownloadEvent downloadEvent){
}
@Override
publicvoidonUploadUpdate(WaypointMissionUploadEvent uploadEvent){
}
@Override
publicvoidonExecutionUpdate(WaypointMissionExecutionEvent executionEvent){
}
@Override
publicvoidonExecutionStart(){
}
@Override
publicvoidonExecutionFinish(@NullablefinalDJIError error){
showToasts("Execution finished: "+ (error ==null?"Success!": error.getDescription()));
}
};
publicWaypointMissionOperatorgetWaypointMissionOperator(){
if(instance ==null) {
instance = DJISDKManager.getInstance().getMissionControl().getWaypointMissionOperator();
}
returninstance;
}
@Override
publicvoidonMapClick(LatLng point){
if(isAdd ==true) {
markWaypoint(point);
Waypoint mWaypoint =newWaypoint(point.latitude, point.longitude, altitude);
//Add Waypoints to Waypoint arraylist;
if(waypointMissionBuilder !=null) {
waypointList.add(mWaypoint);
waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());
}else{
waypointMissionBuilder =newWaypointMission.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("当前未开启增加点模式");
}
}
privatevoidmarkWaypoint(LatLng point){
MarkerOptions markerOptions =newMarkerOptions();
markerOptions.position(point);
mPointInfo.add(newPointInfo(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 =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);
}
}
privatevoidupdateMarkWaypoint(){
mLatLng.clear();
waypointList.clear();
mPointInfo.clear();
waypointMissionBuilder.waypointList(waypointList);
for(inti =0; i < mMarkers.size(); i++) {
mPointInfo.add(newPointInfo(mMarkers.get(i).getPosition().latitude, mMarkers.get(i).getPosition().longitude));
MarkerOptions markerOptions =newMarkerOptions();
Waypoint mWaypoint =newWaypoint(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 =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(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
publicvoidactivate(OnLocationChangedListener listener){
mListener = listener;
if(mlocationClient ==null) {
try{
mlocationClient =newAMapLocationClient(this);
}catch(Exception e) {
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(Marker marker){
if(infoWindow ==null) {
infoWindow = LayoutInflater.from(this).inflate(R.layout.amap_info_window,null);
}
render(marker, infoWindow);
returninfoWindow;
}
/**
* 自定义infoWindow窗口
*/

privatevoidrender(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
publicViewgetInfoContents(Marker marker){
returnnull;
}
@Override
publicbooleanonMarkerClick(Marker marker){
marker.showInfoWindow();
mClickMarker = marker;
mButtonDelete.setVisibility(View.VISIBLE);
// aMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(marker.getPosition(),18,0,0)));
returntrue;
}
privatevoidshowSettingDialog(){
LinearLayout wayPointSettings = (LinearLayout) getLayoutInflater().inflate(R.layout.dialog_waypointsetting,null);
finalTextView 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(newRadioGroup.OnCheckedChangeListener() {
@Override
publicvoidonCheckedChanged(RadioGroup group,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(RadioGroup group,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(RadioGroup group,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(DialogInterface dialog,intid){
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();
}
StringnulltoIntegerDefalt(String value){
if(!isIntValue(value))
value ="0";
returnvalue;
}
booleanisIntValue(String val){
try{
val = val.replace(" ","");
Integer.parseInt(val);
}catch(Exception e) {
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());
}
}
privatevoiduploadWayPointMission(){
getWaypointMissionOperator().uploadMission(newCommonCallbacks.CompletionCallback() {
@Override
publicvoidonResult(DJIError error){
if(error ==null) {
runOnUiThread(newRunnable() {
@Override
publicvoidrun(){
mButtonSetting.setVisibility(View.GONE);
mButtonUpload.setVisibility(View.GONE);
mButtonStart.setVisibility(View.VISIBLE);
mButtonStop.setVisibility(View.VISIBLE);
}
});
showToasts("任务上传成功!");
mSQLiteHelper =newSQLiteHelper(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);
}
}
});
}
privatevoidstartWaypointMission(){
getWaypointMissionOperator().startMission(newCommonCallbacks.CompletionCallback() {
@Override
publicvoidonResult(DJIError error){
showToasts("任务开始: "+ (error ==null?"成功":"失败:"+ error.getDescription()));
}
});
}
privatevoidstopWaypointMission(){
getWaypointMissionOperator().stopMission(newCommonCallbacks.CompletionCallback() {
@Override
publicvoidonResult(DJIError error){
showToasts("任务暂停: "+ (error ==null?"成功":"失败"+ error.getDescription()));
}
});
}
@Override
protectedvoidonActivityResult(intrequestCode,intresultCode, Intent data){
switch(requestCode) {
case101:
intId = data.getExtras().getInt("id");
MyLog.d("返回的ID:"+ Id);
if(Id > -1) {
refreshMapPoint(Id);
}
break;
case102:
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;
}
}
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);
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(inti =0; i < mPointInfo.size(); i++) {
showWaypoint(newLatLng(mPointInfo.get(i).getLatitude(), mPointInfo.get(i).getLongitude()));
Waypoint mWaypoint =newWaypoint(mPointInfo.get(i).getLatitude(), mPointInfo.get(i).getLongitude(), altitude);
if(waypointMissionBuilder !=null) {
waypointList.add(mWaypoint);
waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());
}else{
waypointMissionBuilder =newWaypointMission.Builder();
waypointList.add(mWaypoint);
waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());
}
}
aMap.moveCamera(CameraUpdateFactory.newCameraPosition(newCameraPosition(newLatLng(mPointInfo.get(0).getLatitude(), mPointInfo.get(0).getLongitude()),18,0,0)));
ResultconfigWayPointMission();
getWaypointMissionOperator().uploadMission(newCommonCallbacks.CompletionCallback() {
@Override
publicvoidonResult(DJIError djiError){
if(djiError ==null) {
showToasts("获取任务成功!");
}
}
});
}
privatevoidshowWaypoint(LatLng point){
MarkerOptions markerOptions =newMarkerOptions();
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 =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);
}
}
privatevoidResultconfigWayPointMission(){
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);
}
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");
}
}
privatevoidaddSampleMarker(){
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(inti =0; i < sampleList.size(); i++) {
showWaypoint(newLatLng(sampleList.get(i).getX(), sampleList.get(i).getY()));
Waypoint mWaypoint =newWaypoint(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 =newWaypointMission.Builder();
waypointList.add(mWaypoint);
waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());
}
}
aMap.moveCamera(CameraUpdateFactory.newCameraPosition(newCameraPosition(newLatLng(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


<LinearLayoutxmlns: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)
publicclassWaypointActivityextendsBaseActivityimplementsView.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;
privateSQLiteHelper mSQLiteHelper;
privateList mWaypointInfo =newArrayList<>();
privateWaypointAdapter mWaypointAdapter;
privateList mWaypointId =newArrayList<>();
privateString StrId ="";
@Override
publicvoidinitViews(){
mLinearLayout.setVisibility(View.VISIBLE);
mTextViewToolbarTitle.setText("航线管理");
MyStatic.isChoose =false;
}
@Override
publicvoidinitDatas(){
mSQLiteHelper =newSQLiteHelper(WaypointActivity.this);
Cursor c = 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(BaseQuickAdapter adapter, View view,intposition){
Intent intent =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(View v){
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 =newSQLiteHelper(WaypointActivity.this);
mSQLiteHelper.doDelete(StrId);
mSQLiteHelper.close();
for(intj =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;
caseR.id.img_back:
Intent intent =newIntent();
intent.putExtra("id", -1);
setResult(RESULT_OK, intent);
finish();
break;
}
}

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


*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。



关键词:Mobile大疆无人机

相关推荐

技术专区

关闭