Skip to content

Commit

Permalink
Added ability to modify the GUIDED SCAN follow mode roi altitude.
Browse files Browse the repository at this point in the history
  • Loading branch information
m4gr3d committed Jan 30, 2015
1 parent 217b46b commit 6f94de0
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 46 deletions.
9 changes: 9 additions & 0 deletions Android/res/layout/fragment_mode_follow.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,13 @@
style="@style/missionItemDetailCard"
android:text="@string/radius_label"/>

<org.droidplanner.android.widgets.spinnerWheel.CardWheelHorizontalView
android:id="@+id/roi_height_spinner"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
style="@style/missionItemDetailCard"
android:text="@string/roi_height_label"/>

</LinearLayout>
1 change: 1 addition & 0 deletions Android/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@
<string name="telemetry_default_value">0.0</string>
<string name="climb_rate_label">Climb Rate</string>
<string name="altitude_label">Altitude</string>
<string name="roi_height_label">ROI Height</string>
<string name="meter_unit">m</string>
<string name="speed_unit">m/s</string>
<string name="speed_label">Speed</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -51,17 +54,21 @@ 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;
private Spinner spinner;
private ArrayAdapter<FollowType> adapter;

private CardWheelHorizontalView<LengthUnit> mRadiusWheel;
private CardWheelHorizontalView<LengthUnit> roiHeightWheel;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Expand All @@ -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<LengthUnit>) 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<LengthUnit>) 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);
Expand All @@ -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());
Expand All @@ -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;
Expand All @@ -155,32 +182,32 @@ 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());
FollowApi.updateFollowParams(drone, params);
}
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);
Expand All @@ -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) {
}
Expand All @@ -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<FollowType> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,36 @@
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;

/**
* Created by Fredia Huya-Kouadio on 1/27/15.
*/
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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 6f94de0

Please sign in to comment.