From 6f94de0684a8b332e886117be646e44f04fbd53a Mon Sep 17 00:00:00 2001 From: ne0fhyk Date: Fri, 30 Jan 2015 03:37:17 -0800 Subject: [PATCH] Added ability to modify the GUIDED SCAN follow mode roi altitude. --- Android/res/layout/fragment_mode_follow.xml | 9 ++ Android/res/values/strings.xml | 1 + .../fragments/mode/ModeFollowFragment.java | 122 ++++++++++++------ .../graphic/map/GuidedScanROIMarkerInfo.java | 18 ++- .../utils/prefs/DroidPlannerPrefs.java | 1 - 5 files changed, 105 insertions(+), 46 deletions(-) diff --git a/Android/res/layout/fragment_mode_follow.xml b/Android/res/layout/fragment_mode_follow.xml index e93a93c593..6a17122f4d 100644 --- a/Android/res/layout/fragment_mode_follow.xml +++ b/Android/res/layout/fragment_mode_follow.xml @@ -35,4 +35,13 @@ style="@style/missionItemDetailCard" android:text="@string/radius_label"/> + + \ No newline at end of file diff --git a/Android/res/values/strings.xml b/Android/res/values/strings.xml index 115cbe6fe2..bf84d15917 100644 --- a/Android/res/values/strings.xml +++ b/Android/res/values/strings.xml @@ -337,6 +337,7 @@ 0.0 Climb Rate Altitude + ROI Height m m/s Speed diff --git a/Android/src/org/droidplanner/android/fragments/mode/ModeFollowFragment.java b/Android/src/org/droidplanner/android/fragments/mode/ModeFollowFragment.java index 9ea5de1d79..a589ed2209 100644 --- a/Android/src/org/droidplanner/android/fragments/mode/ModeFollowFragment.java +++ b/Android/src/org/droidplanner/android/fragments/mode/ModeFollowFragment.java @@ -18,6 +18,7 @@ import com.o3dr.android.client.Drone; import com.o3dr.android.client.apis.gcs.FollowApi; import com.o3dr.services.android.lib.coordinate.LatLong; +import com.o3dr.services.android.lib.coordinate.LatLongAlt; import com.o3dr.services.android.lib.drone.attribute.AttributeEvent; import com.o3dr.services.android.lib.drone.attribute.AttributeType; import com.o3dr.services.android.lib.gcs.follow.FollowState; @@ -34,6 +35,8 @@ public class ModeFollowFragment extends ModeGuidedFragment implements OnItemSelectedListener, DroneMap.MapMarkerProvider { + private static final double DEFAULT_MIN_RADIUS = 2; //meters + private static final int ROI_TARGET_MARKER_INDEX = 0; private static final IntentFilter eventFilter = new IntentFilter(AttributeEvent.FOLLOW_UPDATE); @@ -51,10 +54,13 @@ public void onReceive(Context context, Intent intent) { } }; + private final GuidedScanROIMarkerInfo roiMarkerInfo = new GuidedScanROIMarkerInfo(); + + private final MarkerInfo[] emptyMarkers = {}; private final MarkerInfo[] markers = new MarkerInfo[1]; { - markers[ROI_TARGET_MARKER_INDEX] = new GuidedScanROIMarkerInfo(); + markers[ROI_TARGET_MARKER_INDEX] = roiMarkerInfo; } private TextView modeDescription; @@ -62,6 +68,7 @@ public void onReceive(Context context, Intent intent) { private ArrayAdapter adapter; private CardWheelHorizontalView mRadiusWheel; + private CardWheelHorizontalView roiHeightWheel; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -72,17 +79,25 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa public void onViewCreated(View parentView, Bundle savedInstanceState) { super.onViewCreated(parentView, savedInstanceState); + modeDescription = (TextView) parentView.findViewById(R.id.ModeDetail); + final Context context = getContext(); final LengthUnitProvider lengthUP = getLengthUnitProvider(); + final LengthWheelAdapter radiusAdapter = new LengthWheelAdapter(context, R.layout.wheel_text_centered, lengthUP.boxBaseValueToTarget(2), lengthUP.boxBaseValueToTarget(200)); - modeDescription = (TextView) parentView.findViewById(R.id.ModeDetail); - mRadiusWheel = (CardWheelHorizontalView) parentView.findViewById(R.id.radius_spinner); mRadiusWheel.setViewAdapter(radiusAdapter); mRadiusWheel.addScrollListener(this); + final LengthWheelAdapter roiHeightAdapter = new LengthWheelAdapter(context, R.layout.wheel_text_centered, + lengthUP.boxBaseValueToTarget(0), lengthUP.boxBaseValueToTarget(200)); + + roiHeightWheel = (CardWheelHorizontalView) parentView.findViewById(R.id.roi_height_spinner); + roiHeightWheel.setViewAdapter(roiHeightAdapter); + roiHeightWheel.addScrollListener(this); + spinner = (Spinner) parentView.findViewById(R.id.follow_type_spinner); adapter = new FollowTypesAdapter(context, getAppPrefs().isAdvancedMenuEnabled()); spinner.setAdapter(adapter); @@ -103,7 +118,7 @@ public void onApiConnected() { super.onApiConnected(); final FollowState followState = getDrone().getAttribute(AttributeType.FOLLOW_STATE); - if(followState != null){ + if (followState != null) { final FollowType followType = followState.getMode(); spinner.setSelection(adapter.getPosition(followType)); onFollowTypeUpdate(followType, followState.getParams()); @@ -113,29 +128,41 @@ public void onApiConnected() { getBroadcastManager().registerReceiver(eventReceiver, eventFilter); } - private void onFollowTypeUpdate(FollowType followType, Bundle params){ + private void onFollowTypeUpdate(FollowType followType, Bundle params) { updateModeDescription(followType); if (followType.hasParam(FollowType.EXTRA_FOLLOW_RADIUS)) { - showRadiusPicker(); - updateCurrentRadius(); + double radius = DEFAULT_MIN_RADIUS; + if (params != null) { + radius = params.getDouble(FollowType.EXTRA_FOLLOW_RADIUS, DEFAULT_MIN_RADIUS); + } + + mRadiusWheel.setVisibility(View.VISIBLE); + mRadiusWheel.setCurrentValue((getLengthUnitProvider().boxBaseValueToTarget(radius))); } else { - hideRadiusPicker(); + mRadiusWheel.setVisibility(View.GONE); } - if(!followType.hasParam(FollowType.EXTRA_FOLLOW_ROI_TARGET)) - markers[ROI_TARGET_MARKER_INDEX].setPosition(null); - else if(params != null){ - params.setClassLoader(LatLong.class.getClassLoader()); - LatLong roiTarget = params.getParcelable(FollowType.EXTRA_FOLLOW_ROI_TARGET); - if(roiTarget != null){ - updateROITargetMarker(roiTarget); + double roiHeight = GuidedScanROIMarkerInfo.DEFAULT_FOLLOW_ROI_ALTITUDE; + LatLong roiTarget = null; + if (followType.hasParam(FollowType.EXTRA_FOLLOW_ROI_TARGET)) { + roiTarget = roiMarkerInfo.getPosition(); + + if (params != null) { + params.setClassLoader(LatLong.class.getClassLoader()); + roiTarget = params.getParcelable(FollowType.EXTRA_FOLLOW_ROI_TARGET); } + + if (roiTarget instanceof LatLongAlt) + roiHeight = ((LatLongAlt) roiTarget).getAltitude(); } + + roiHeightWheel.setCurrentValue(getLengthUnitProvider().boxBaseValueToTarget(roiHeight)); + updateROITargetMarker(roiTarget); } - private void updateModeDescription(FollowType followType){ - switch(followType){ + private void updateModeDescription(FollowType followType) { + switch (followType) { case GUIDED_SCAN: modeDescription.setText(R.string.mode_follow_guided_scan); break; @@ -155,9 +182,9 @@ public void onApiDisconnected() { @Override public void onScrollingEnded(CardWheelHorizontalView cardWheel, LengthUnit oldValue, LengthUnit newValue) { + final Drone drone = getDrone(); switch (cardWheel.getId()) { case R.id.radius_spinner: - final Drone drone = getDrone(); if (drone.isConnected()) { Bundle params = new Bundle(); params.putDouble(FollowType.EXTRA_FOLLOW_RADIUS, newValue.toBase().getValue()); @@ -165,22 +192,22 @@ public void onScrollingEnded(CardWheelHorizontalView cardWheel, LengthUnit oldVa } break; + case R.id.roi_height_spinner: + if (drone.isConnected()) { + final LatLongAlt roiCoord = roiMarkerInfo.getPosition(); + if (roiCoord != null) { + roiCoord.setAltitude(newValue.toBase().getValue()); + pushROITargetToVehicle(drone, roiCoord); + } + } + break; + default: super.onScrollingEnded(cardWheel, oldValue, newValue); break; } } - private void updateCurrentRadius() { - final Drone drone = getDrone(); - if (mRadiusWheel != null && drone.isConnected()) { - final FollowState followState = getDrone().getAttribute(AttributeType.FOLLOW_STATE); - Bundle params = followState.getParams(); - double radius = params.getDouble(FollowType.EXTRA_FOLLOW_RADIUS, 2); - mRadiusWheel.setCurrentValue((getLengthUnitProvider().boxBaseValueToTarget(radius))); - } - } - @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { final FollowType type = adapter.getItem(position); @@ -193,14 +220,6 @@ public void onItemSelected(AdapterView parent, View view, int position, long onFollowTypeUpdate(type, null); } - private void hideRadiusPicker() { - mRadiusWheel.setVisibility(View.GONE); - } - - private void showRadiusPicker() { - mRadiusWheel.setVisibility(View.VISIBLE); - } - @Override public void onNothingSelected(AdapterView arg0) { } @@ -212,23 +231,42 @@ public void onGuidedClick(LatLong coord) { if (followState != null && followState.isEnabled() && followState.getMode().hasParam(FollowType.EXTRA_FOLLOW_ROI_TARGET)) { Toast.makeText(getContext(), R.string.guided_scan_roi_set_message, Toast.LENGTH_LONG).show(); - Bundle params = new Bundle(); - params.putParcelable(FollowType.EXTRA_FOLLOW_ROI_TARGET, coord); - FollowApi.updateFollowParams(drone, params); + final double roiHeight = roiHeightWheel.getCurrentValue().toBase().getValue(); + final LatLongAlt roiCoord = new LatLongAlt(coord.getLatitude(), coord.getLongitude(), roiHeight); + + pushROITargetToVehicle(drone, roiCoord); updateROITargetMarker(coord); } else { super.onGuidedClick(coord); } } - private void updateROITargetMarker(LatLong target){ - markers[ROI_TARGET_MARKER_INDEX].setPosition(target); + private void pushROITargetToVehicle(Drone drone, LatLongAlt roiCoord) { + if (roiCoord == null) + return; + + Bundle params = new Bundle(); + params.putParcelable(FollowType.EXTRA_FOLLOW_ROI_TARGET, roiCoord); + FollowApi.updateFollowParams(drone, params); + } + + private void updateROITargetMarker(LatLong target) { + roiMarkerInfo.setPosition(target); getBroadcastManager().sendBroadcast(new Intent(DroneMap.ACTION_UPDATE_MAP)); + + if (target == null) { + roiHeightWheel.setVisibility(View.GONE); + } else { + roiHeightWheel.setVisibility(View.VISIBLE); + } } @Override public MarkerInfo[] getMapMarkers() { - return markers; + if (roiMarkerInfo.isVisible()) + return markers; + else + return emptyMarkers; } private static class FollowTypesAdapter extends ArrayAdapter { diff --git a/Android/src/org/droidplanner/android/graphic/map/GuidedScanROIMarkerInfo.java b/Android/src/org/droidplanner/android/graphic/map/GuidedScanROIMarkerInfo.java index fd7ae9f866..7eb4f314b4 100644 --- a/Android/src/org/droidplanner/android/graphic/map/GuidedScanROIMarkerInfo.java +++ b/Android/src/org/droidplanner/android/graphic/map/GuidedScanROIMarkerInfo.java @@ -5,8 +5,10 @@ import android.graphics.BitmapFactory; import com.o3dr.services.android.lib.coordinate.LatLong; +import com.o3dr.services.android.lib.coordinate.LatLongAlt; import org.droidplanner.android.R; +import org.droidplanner.android.fragments.mode.ModeFollowFragment; import org.droidplanner.android.maps.MarkerInfo; /** @@ -14,15 +16,25 @@ */ public class GuidedScanROIMarkerInfo extends MarkerInfo.SimpleMarkerInfo { - private LatLong roiCoord; + public static final double DEFAULT_FOLLOW_ROI_ALTITUDE = 10; //meters + private LatLongAlt roiCoord; @Override public void setPosition(LatLong coord){ - this.roiCoord = coord; + if(coord == null || coord instanceof LatLongAlt){ + roiCoord = (LatLongAlt) coord; + } + else { + double defaultHeight = DEFAULT_FOLLOW_ROI_ALTITUDE; + if(roiCoord != null) + defaultHeight = roiCoord.getAltitude(); + + this.roiCoord = new LatLongAlt(coord.getLatitude(), coord.getLongitude(), defaultHeight); + } } @Override - public LatLong getPosition(){ + public LatLongAlt getPosition(){ return roiCoord; } diff --git a/Android/src/org/droidplanner/android/utils/prefs/DroidPlannerPrefs.java b/Android/src/org/droidplanner/android/utils/prefs/DroidPlannerPrefs.java index 69a36f1a0b..84cda5faac 100644 --- a/Android/src/org/droidplanner/android/utils/prefs/DroidPlannerPrefs.java +++ b/Android/src/org/droidplanner/android/utils/prefs/DroidPlannerPrefs.java @@ -37,7 +37,6 @@ public class DroidPlannerPrefs { private static final boolean DEFAULT_OFFLINE_MAP_ENABLED = false; private static final String DEFAULT_MAP_TYPE = ""; private static final AutoPanMode DEFAULT_AUTO_PAN_MODE = AutoPanMode.DISABLED; - private static final boolean DEFAULT_GUIDED_MODE_ON_LONG_PRESS = true; public static final boolean DEFAULT_PREF_UI_LANGUAGE = false; public static final String DEFAULT_SPEECH_PERIOD = "0"; public static final boolean DEFAULT_TTS_CEILING_EXCEEDED = true;