From 70c9b80e0482deac03b55cb52625f3b0801c1b9c Mon Sep 17 00:00:00 2001 From: ne0fhyk Date: Mon, 9 Feb 2015 14:01:28 -0800 Subject: [PATCH] Implemented DO_SET_RELAY mission item. --- AidlLib/build.gradle | 4 +- .../lib/drone/mission/MissionItemType.java | 13 +++ .../drone/mission/item/command/SetRelay.java | 83 ++++++++++++++ ClientLib/mobile/build.gradle | 4 +- ClientLib/mobile/libs/AidlLib.jar | Bin 472985 -> 472982 bytes .../services/android/api/DroneApi.java | 6 +- .../services/android/utils/ProxyUtils.java | 89 +++++++++------ .../core/mission/MissionItemType.java | 108 ++++++++++-------- .../core/mission/commands/SetRelayImpl.java | 64 +++++++++++ 9 files changed, 281 insertions(+), 90 deletions(-) create mode 100644 AidlLib/src/com/o3dr/services/android/lib/drone/mission/item/command/SetRelay.java create mode 100644 dependencyLibs/Core/src/org/droidplanner/core/mission/commands/SetRelayImpl.java diff --git a/AidlLib/build.gradle b/AidlLib/build.gradle index 3678a9d249..dc26b2401c 100644 --- a/AidlLib/build.gradle +++ b/AidlLib/build.gradle @@ -7,8 +7,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 20044 - versionName '2.0.44' + versionCode 20046 + versionName '2.0.46' } defaultPublishConfig "release" diff --git a/AidlLib/src/com/o3dr/services/android/lib/drone/mission/MissionItemType.java b/AidlLib/src/com/o3dr/services/android/lib/drone/mission/MissionItemType.java index 505aea7efb..95c9fa6bfa 100644 --- a/AidlLib/src/com/o3dr/services/android/lib/drone/mission/MissionItemType.java +++ b/AidlLib/src/com/o3dr/services/android/lib/drone/mission/MissionItemType.java @@ -9,6 +9,7 @@ import com.o3dr.services.android.lib.drone.mission.item.command.ChangeSpeed; import com.o3dr.services.android.lib.drone.mission.item.command.EpmGripper; import com.o3dr.services.android.lib.drone.mission.item.command.ReturnToLaunch; +import com.o3dr.services.android.lib.drone.mission.item.command.SetRelay; import com.o3dr.services.android.lib.drone.mission.item.command.SetServo; import com.o3dr.services.android.lib.drone.mission.item.command.Takeoff; import com.o3dr.services.android.lib.drone.mission.item.command.YawCondition; @@ -194,6 +195,18 @@ public MissionItem getNewItem() { protected Creator getMissionItemCreator() { return SetServo.CREATOR; } + }, + + SET_RELAY("Set Relay") { + @Override + public MissionItem getNewItem() { + return new SetRelay(); + } + + @Override + protected Creator getMissionItemCreator() { + return SetRelay.CREATOR; + } }; private final static String EXTRA_MISSION_ITEM_TYPE = "extra_mission_item_type"; diff --git a/AidlLib/src/com/o3dr/services/android/lib/drone/mission/item/command/SetRelay.java b/AidlLib/src/com/o3dr/services/android/lib/drone/mission/item/command/SetRelay.java new file mode 100644 index 0000000000..db42b85644 --- /dev/null +++ b/AidlLib/src/com/o3dr/services/android/lib/drone/mission/item/command/SetRelay.java @@ -0,0 +1,83 @@ +package com.o3dr.services.android.lib.drone.mission.item.command; + +import android.os.Parcel; + +import com.o3dr.services.android.lib.drone.mission.MissionItemType; +import com.o3dr.services.android.lib.drone.mission.item.MissionItem; + +/** + * Set a Relay pin’s voltage high or low. + */ +public class SetRelay extends MissionItem implements MissionItem.Command, android.os.Parcelable { + + private int relayNumber; + private boolean enabled; + + public SetRelay() { + super(MissionItemType.SET_RELAY); + } + + public SetRelay(SetRelay copy) { + this(); + this.relayNumber = copy.relayNumber; + this.enabled = copy.enabled; + } + + /** + * @return relay number + */ + public int getRelayNumber() { + return relayNumber; + } + + /** + * Set the relay number + * + * @param relayNumber + */ + public void setRelayNumber(int relayNumber) { + this.relayNumber = relayNumber; + } + + /** + * @return true if relay is on, false if relay if off. + */ + public boolean isEnabled() { + return enabled; + } + + /** + * @param enabled true for relay to be on, false for relay to be off. + */ + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + @Override + public MissionItem clone() { + return new SetRelay(this); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeInt(this.relayNumber); + dest.writeByte(enabled ? (byte) 1 : (byte) 0); + } + + private SetRelay(Parcel in) { + super(in); + this.relayNumber = in.readInt(); + this.enabled = in.readByte() != 0; + } + + public static final Creator CREATOR = new Creator() { + public SetRelay createFromParcel(Parcel source) { + return new SetRelay(source); + } + + public SetRelay[] newArray(int size) { + return new SetRelay[size]; + } + }; +} diff --git a/ClientLib/mobile/build.gradle b/ClientLib/mobile/build.gradle index 1b267bd683..21d13f04e1 100644 --- a/ClientLib/mobile/build.gradle +++ b/ClientLib/mobile/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.library' ext { PUBLISH_ARTIFACT_ID = '3dr-services-lib' - PUBLISH_VERSION = '2.2.8' + PUBLISH_VERSION = '2.2.10' PROJECT_DESCRIPTION = "3DR Services Client Library" PROJECT_LABELS = ['3DR', '3DR Services', 'DroneAPI', 'Android'] PROJECT_LICENSES = ['Apache-2.0'] @@ -15,7 +15,7 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 20208 + versionCode 20210 versionName PUBLISH_VERSION } diff --git a/ClientLib/mobile/libs/AidlLib.jar b/ClientLib/mobile/libs/AidlLib.jar index 7143798fe81ba49e14a1c990d548a54232ce6625..a48ef164f4e1d38f8738a337561528b5352b98c0 100644 GIT binary patch delta 29543 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 V;=I-^>Mx(k7ZK*e&mh6}`#%8*mf`>a diff --git a/ServiceApp/src/org/droidplanner/services/android/api/DroneApi.java b/ServiceApp/src/org/droidplanner/services/android/api/DroneApi.java index 0475b52ce9..8964578e25 100644 --- a/ServiceApp/src/org/droidplanner/services/android/api/DroneApi.java +++ b/ServiceApp/src/org/droidplanner/services/android/api/DroneApi.java @@ -599,7 +599,7 @@ public void setMission(Mission mission, boolean pushToDrone) { List itemsList = mission.getMissionItems(); for (MissionItem item : itemsList) { - droneMission.addMissionItem(ProxyUtils.getMissionItem(droneMission, item)); + droneMission.addMissionItem(ProxyUtils.getMissionItemImpl(droneMission, item)); } if (pushToDrone) @@ -815,7 +815,7 @@ public void buildComplexMissionItem(Bundle itemBundle) { private Survey buildSurvey(Survey survey) { org.droidplanner.core.mission.Mission droneMission = this.droneMgr.getDrone().getMission(); - org.droidplanner.core.mission.survey.Survey updatedSurvey = (org.droidplanner.core.mission.survey.Survey) ProxyUtils.getMissionItem + org.droidplanner.core.mission.survey.Survey updatedSurvey = (org.droidplanner.core.mission.survey.Survey) ProxyUtils.getMissionItemImpl (droneMission, survey); return (Survey) ProxyUtils.getProxyMissionItem(updatedSurvey); @@ -824,7 +824,7 @@ private Survey buildSurvey(Survey survey) { private StructureScanner buildStructureScanner(StructureScanner item) { org.droidplanner.core.mission.Mission droneMission = this.droneMgr.getDrone().getMission(); org.droidplanner.core.mission.waypoints.StructureScanner updatedScan = (org.droidplanner.core.mission.waypoints.StructureScanner) ProxyUtils - .getMissionItem(droneMission, item); + .getMissionItemImpl(droneMission, item); StructureScanner proxyScanner = (StructureScanner) ProxyUtils.getProxyMissionItem(updatedScan); return proxyScanner; diff --git a/ServiceApp/src/org/droidplanner/services/android/utils/ProxyUtils.java b/ServiceApp/src/org/droidplanner/services/android/utils/ProxyUtils.java index ea8d4d861d..8f9afca5dc 100644 --- a/ServiceApp/src/org/droidplanner/services/android/utils/ProxyUtils.java +++ b/ServiceApp/src/org/droidplanner/services/android/utils/ProxyUtils.java @@ -7,6 +7,7 @@ import com.o3dr.services.android.lib.drone.mission.item.command.ChangeSpeed; import com.o3dr.services.android.lib.drone.mission.item.command.EpmGripper; import com.o3dr.services.android.lib.drone.mission.item.command.ReturnToLaunch; +import com.o3dr.services.android.lib.drone.mission.item.command.SetRelay; import com.o3dr.services.android.lib.drone.mission.item.command.SetServo; import com.o3dr.services.android.lib.drone.mission.item.command.Takeoff; import com.o3dr.services.android.lib.drone.mission.item.command.YawCondition; @@ -27,6 +28,7 @@ import org.droidplanner.core.mission.Mission; import org.droidplanner.core.mission.commands.ConditionYaw; import org.droidplanner.core.mission.commands.ReturnToHome; +import org.droidplanner.core.mission.commands.SetRelayImpl; import org.droidplanner.core.survey.CameraInfo; import org.droidplanner.core.survey.SurveyData; @@ -72,12 +74,11 @@ public static SurveyDetail getSurveyDetail(SurveyData surveyData) { return surveyDetail; } - public static org.droidplanner.core.mission.MissionItem getMissionItem(Mission mission, - MissionItem proxyItem) { + public static org.droidplanner.core.mission.MissionItem getMissionItemImpl(Mission mission, MissionItem proxyItem) { if (proxyItem == null) return null; - org.droidplanner.core.mission.MissionItem missionItem; + org.droidplanner.core.mission.MissionItem missionItemImpl; switch (proxyItem.getType()) { case CAMERA_TRIGGER: { @@ -87,7 +88,7 @@ public static org.droidplanner.core.mission.MissionItem getMissionItem(Mission m .core.mission.commands.CameraTrigger(mission, new Length(proxy.getTriggerDistance())); - missionItem = temp; + missionItemImpl = temp; break; } case CHANGE_SPEED: { @@ -96,7 +97,7 @@ public static org.droidplanner.core.mission.MissionItem getMissionItem(Mission m org.droidplanner.core.mission.commands.ChangeSpeed temp = new org.droidplanner .core.mission.commands.ChangeSpeed(mission, new Speed(proxy.getSpeed())); - missionItem = temp; + missionItemImpl = temp; break; } case EPM_GRIPPER: { @@ -105,7 +106,7 @@ public static org.droidplanner.core.mission.MissionItem getMissionItem(Mission m org.droidplanner.core.mission.commands.EpmGripper temp = new org.droidplanner .core.mission.commands.EpmGripper(mission, proxy.isRelease()); - missionItem = temp; + missionItemImpl = temp; break; } case RETURN_TO_LAUNCH: { @@ -114,7 +115,7 @@ public static org.droidplanner.core.mission.MissionItem getMissionItem(Mission m ReturnToHome temp = new ReturnToHome(mission); temp.setHeight(new Altitude(proxy.getReturnAltitude())); - missionItem = temp; + missionItemImpl = temp; break; } case SET_SERVO: { @@ -123,7 +124,7 @@ public static org.droidplanner.core.mission.MissionItem getMissionItem(Mission m org.droidplanner.core.mission.commands.SetServo temp = new org.droidplanner.core .mission.commands.SetServo(mission, proxy.getChannel(), proxy.getPwm()); - missionItem = temp; + missionItemImpl = temp; break; } case TAKEOFF: { @@ -132,7 +133,7 @@ public static org.droidplanner.core.mission.MissionItem getMissionItem(Mission m org.droidplanner.core.mission.commands.Takeoff temp = new org.droidplanner.core .mission.commands.Takeoff(mission, new Altitude(proxy.getTakeoffAltitude())); - missionItem = temp; + missionItemImpl = temp; break; } case CIRCLE: { @@ -144,7 +145,7 @@ public static org.droidplanner.core.mission.MissionItem getMissionItem(Mission m temp.setRadius(proxy.getRadius()); temp.setTurns(proxy.getTurns()); - missionItem = temp; + missionItemImpl = temp; break; } case LAND: { @@ -154,7 +155,7 @@ public static org.droidplanner.core.mission.MissionItem getMissionItem(Mission m .mission.waypoints.Land(mission, MathUtils.latLongToCoord2D(proxy .getCoordinate())); - missionItem = temp; + missionItemImpl = temp; break; } case REGION_OF_INTEREST: { @@ -164,7 +165,7 @@ public static org.droidplanner.core.mission.MissionItem getMissionItem(Mission m .droidplanner.core.mission.waypoints.RegionOfInterest(mission, MathUtils.latLongAltToCoord3D(proxy.getCoordinate())); - missionItem = temp; + missionItemImpl = temp; break; } case SPLINE_WAYPOINT: { @@ -175,7 +176,7 @@ public static org.droidplanner.core.mission.MissionItem getMissionItem(Mission m MathUtils.latLongAltToCoord3D(proxy.getCoordinate())); temp.setDelay(proxy.getDelay()); - missionItem = temp; + missionItemImpl = temp; break; } case STRUCTURE_SCANNER: { @@ -193,7 +194,7 @@ public static org.droidplanner.core.mission.MissionItem getMissionItem(Mission m if(camDetail != null) temp.setCamera(getCameraInfo(camDetail)); - missionItem = temp; + missionItemImpl = temp; break; } case WAYPOINT: { @@ -208,7 +209,7 @@ public static org.droidplanner.core.mission.MissionItem getMissionItem(Mission m temp.setOrbitalRadius(proxy.getOrbitalRadius()); temp.setYawAngle(proxy.getYawAngle()); - missionItem = temp; + missionItemImpl = temp; break; } case SURVEY: { @@ -234,7 +235,7 @@ public static org.droidplanner.core.mission.MissionItem getMissionItem(Mission m Log.e(TAG, e.getMessage(), e); } - missionItem = temp; + missionItemImpl = temp; break; } case YAW_CONDITION: { @@ -243,26 +244,31 @@ public static org.droidplanner.core.mission.MissionItem getMissionItem(Mission m ConditionYaw temp = new ConditionYaw(mission, proxy.getAngle(), proxy.isRelative()); temp.setAngularSpeed(proxy.getAngularSpeed()); - missionItem = temp; + missionItemImpl = temp; break; } + case SET_RELAY: + SetRelay proxy = (SetRelay) proxyItem; + missionItemImpl = new SetRelayImpl(mission, proxy.getRelayNumber(), proxy.isEnabled()); + break; + default: - missionItem = null; + missionItemImpl = null; break; } - return missionItem; + return missionItemImpl; } - public static MissionItem getProxyMissionItem(org.droidplanner.core.mission.MissionItem item) { - if (item == null) + public static MissionItem getProxyMissionItem(org.droidplanner.core.mission.MissionItem itemImpl) { + if (itemImpl == null) return null; MissionItem proxyMissionItem; - switch (item.getType()) { + switch (itemImpl.getType()) { case WAYPOINT: { - org.droidplanner.core.mission.waypoints.Waypoint source = (org.droidplanner.core.mission.waypoints.Waypoint) item; + org.droidplanner.core.mission.waypoints.Waypoint source = (org.droidplanner.core.mission.waypoints.Waypoint) itemImpl; Waypoint temp = new Waypoint(); temp.setCoordinate(MathUtils.coord3DToLatLongAlt(source.getCoordinate())); @@ -277,7 +283,7 @@ public static MissionItem getProxyMissionItem(org.droidplanner.core.mission.Miss } case SPLINE_WAYPOINT: { - org.droidplanner.core.mission.waypoints.SplineWaypoint source = (org.droidplanner.core.mission.waypoints.SplineWaypoint) item; + org.droidplanner.core.mission.waypoints.SplineWaypoint source = (org.droidplanner.core.mission.waypoints.SplineWaypoint) itemImpl; SplineWaypoint temp = new SplineWaypoint(); temp.setCoordinate(MathUtils.coord3DToLatLongAlt(source.getCoordinate())); @@ -288,7 +294,7 @@ public static MissionItem getProxyMissionItem(org.droidplanner.core.mission.Miss } case TAKEOFF: { - org.droidplanner.core.mission.commands.Takeoff source = (org.droidplanner.core.mission.commands.Takeoff) item; + org.droidplanner.core.mission.commands.Takeoff source = (org.droidplanner.core.mission.commands.Takeoff) itemImpl; Takeoff temp = new Takeoff(); temp.setTakeoffAltitude(source.getFinishedAlt().valueInMeters()); @@ -297,7 +303,7 @@ public static MissionItem getProxyMissionItem(org.droidplanner.core.mission.Miss break; } case RTL: { - ReturnToHome source = (ReturnToHome) item; + ReturnToHome source = (ReturnToHome) itemImpl; ReturnToLaunch temp = new ReturnToLaunch(); temp.setReturnAltitude(source.getHeight().valueInMeters()); @@ -306,7 +312,7 @@ public static MissionItem getProxyMissionItem(org.droidplanner.core.mission.Miss break; } case LAND: { - org.droidplanner.core.mission.waypoints.Land source = (org.droidplanner.core.mission.waypoints.Land) item; + org.droidplanner.core.mission.waypoints.Land source = (org.droidplanner.core.mission.waypoints.Land) itemImpl; Land temp = new Land(); temp.setCoordinate(MathUtils.coord3DToLatLongAlt(source.getCoordinate())); @@ -316,7 +322,7 @@ public static MissionItem getProxyMissionItem(org.droidplanner.core.mission.Miss } case CIRCLE: { - org.droidplanner.core.mission.waypoints.Circle source = (org.droidplanner.core.mission.waypoints.Circle) item; + org.droidplanner.core.mission.waypoints.Circle source = (org.droidplanner.core.mission.waypoints.Circle) itemImpl; Circle temp = new Circle(); temp.setCoordinate(MathUtils.coord3DToLatLongAlt(source.getCoordinate())); @@ -328,7 +334,7 @@ public static MissionItem getProxyMissionItem(org.droidplanner.core.mission.Miss } case ROI: { - org.droidplanner.core.mission.waypoints.RegionOfInterest source = (org.droidplanner.core.mission.waypoints.RegionOfInterest) item; + org.droidplanner.core.mission.waypoints.RegionOfInterest source = (org.droidplanner.core.mission.waypoints.RegionOfInterest) itemImpl; RegionOfInterest temp = new RegionOfInterest(); temp.setCoordinate(MathUtils.coord3DToLatLongAlt(source.getCoordinate())); @@ -338,7 +344,7 @@ public static MissionItem getProxyMissionItem(org.droidplanner.core.mission.Miss } case SURVEY: { - org.droidplanner.core.mission.survey.Survey source = (org.droidplanner.core.mission.survey.Survey) item; + org.droidplanner.core.mission.survey.Survey source = (org.droidplanner.core.mission.survey.Survey) itemImpl; boolean isValid = true; try { @@ -364,7 +370,7 @@ public static MissionItem getProxyMissionItem(org.droidplanner.core.mission.Miss } case CYLINDRICAL_SURVEY: { - org.droidplanner.core.mission.waypoints.StructureScanner source = (org.droidplanner.core.mission.waypoints.StructureScanner) item; + org.droidplanner.core.mission.waypoints.StructureScanner source = (org.droidplanner.core.mission.waypoints.StructureScanner) itemImpl; StructureScanner temp = new StructureScanner(); temp.setSurveyDetail(getSurveyDetail(source.getSurveyData())); @@ -379,7 +385,7 @@ public static MissionItem getProxyMissionItem(org.droidplanner.core.mission.Miss break; } case CHANGE_SPEED: { - org.droidplanner.core.mission.commands.ChangeSpeed source = (org.droidplanner.core.mission.commands.ChangeSpeed) item; + org.droidplanner.core.mission.commands.ChangeSpeed source = (org.droidplanner.core.mission.commands.ChangeSpeed) itemImpl; ChangeSpeed temp = new ChangeSpeed(); temp.setSpeed(source.getSpeed().valueInMetersPerSecond()); @@ -389,7 +395,7 @@ public static MissionItem getProxyMissionItem(org.droidplanner.core.mission.Miss } case CAMERA_TRIGGER: { - org.droidplanner.core.mission.commands.CameraTrigger source = (org.droidplanner.core.mission.commands.CameraTrigger) item; + org.droidplanner.core.mission.commands.CameraTrigger source = (org.droidplanner.core.mission.commands.CameraTrigger) itemImpl; CameraTrigger temp = new CameraTrigger(); temp.setTriggerDistance(source.getTriggerDistance().valueInMeters()); @@ -398,7 +404,7 @@ public static MissionItem getProxyMissionItem(org.droidplanner.core.mission.Miss break; } case EPM_GRIPPER: { - org.droidplanner.core.mission.commands.EpmGripper source = (org.droidplanner.core.mission.commands.EpmGripper) item; + org.droidplanner.core.mission.commands.EpmGripper source = (org.droidplanner.core.mission.commands.EpmGripper) itemImpl; EpmGripper temp = new EpmGripper(); temp.setRelease(source.isRelease()); @@ -408,7 +414,7 @@ public static MissionItem getProxyMissionItem(org.droidplanner.core.mission.Miss } case SET_SERVO: { - org.droidplanner.core.mission.commands.SetServo source = (org.droidplanner.core.mission.commands.SetServo) item; + org.droidplanner.core.mission.commands.SetServo source = (org.droidplanner.core.mission.commands.SetServo) itemImpl; SetServo temp = new SetServo(); temp.setChannel(source.getChannel()); @@ -418,7 +424,7 @@ public static MissionItem getProxyMissionItem(org.droidplanner.core.mission.Miss break; } case CONDITION_YAW: { - ConditionYaw source = (ConditionYaw) item; + ConditionYaw source = (ConditionYaw) itemImpl; YawCondition temp = new YawCondition(); temp.setAngle(source.getAngle()); @@ -429,6 +435,17 @@ public static MissionItem getProxyMissionItem(org.droidplanner.core.mission.Miss break; } + case SET_RELAY:{ + SetRelayImpl impl = (SetRelayImpl) itemImpl; + + SetRelay proxy = new SetRelay(); + proxy.setRelayNumber(impl.getRelayNumber()); + proxy.setEnabled(impl.isEnabled()); + + proxyMissionItem = proxy; + break; + } + default: proxyMissionItem = null; break; diff --git a/dependencyLibs/Core/src/org/droidplanner/core/mission/MissionItemType.java b/dependencyLibs/Core/src/org/droidplanner/core/mission/MissionItemType.java index 559110e58a..22af8ae20f 100644 --- a/dependencyLibs/Core/src/org/droidplanner/core/mission/MissionItemType.java +++ b/dependencyLibs/Core/src/org/droidplanner/core/mission/MissionItemType.java @@ -1,13 +1,12 @@ package org.droidplanner.core.mission; -import java.util.Collections; - import org.droidplanner.core.helpers.coordinates.Coord2D; import org.droidplanner.core.mission.commands.CameraTrigger; import org.droidplanner.core.mission.commands.ChangeSpeed; import org.droidplanner.core.mission.commands.ConditionYaw; import org.droidplanner.core.mission.commands.EpmGripper; import org.droidplanner.core.mission.commands.ReturnToHome; +import org.droidplanner.core.mission.commands.SetRelayImpl; import org.droidplanner.core.mission.commands.SetServo; import org.droidplanner.core.mission.commands.Takeoff; import org.droidplanner.core.mission.survey.Survey; @@ -18,54 +17,69 @@ import org.droidplanner.core.mission.waypoints.StructureScanner; import org.droidplanner.core.mission.waypoints.Waypoint; +import java.util.Collections; + public enum MissionItemType { - WAYPOINT("Waypoint"), SPLINE_WAYPOINT("Spline Waypoint"), TAKEOFF("Takeoff"), RTL( - "Return to Launch"), LAND("Land"), CIRCLE("Circle"), ROI("Region of Interest"), SURVEY( - "Survey"), CYLINDRICAL_SURVEY("Structure Scan"), CHANGE_SPEED("Change Speed"), CAMERA_TRIGGER("Camera Trigger"), EPM_GRIPPER("EPM"), SET_SERVO("Set Servo"), CONDITION_YAW("Set Yaw"); + WAYPOINT("Waypoint"), + SPLINE_WAYPOINT("Spline Waypoint"), + TAKEOFF("Takeoff"), + RTL("Return to Launch"), + LAND("Land"), + CIRCLE("Circle"), + ROI("Region of Interest"), + SURVEY("Survey"), + CYLINDRICAL_SURVEY("Structure Scan"), + CHANGE_SPEED("Change Speed"), + CAMERA_TRIGGER("Camera Trigger"), + EPM_GRIPPER("EPM"), + SET_SERVO("Set Servo"), + CONDITION_YAW("Set Yaw"), + SET_RELAY("Set Relay"); - private final String name; + private final String name; - private MissionItemType(String name) { - this.name = name; - } + private MissionItemType(String name) { + this.name = name; + } - public String getName() { - return name; - } + public String getName() { + return name; + } - public MissionItem getNewItem(MissionItem referenceItem) throws IllegalArgumentException { - switch (this) { - case WAYPOINT: - return new Waypoint(referenceItem); - case SPLINE_WAYPOINT: - return new SplineWaypoint(referenceItem); - case TAKEOFF: - return new Takeoff(referenceItem); - case CHANGE_SPEED: - return new ChangeSpeed(referenceItem); - case CAMERA_TRIGGER: - return new CameraTrigger(referenceItem); - case EPM_GRIPPER: - return new EpmGripper(referenceItem); - case RTL: - return new ReturnToHome(referenceItem); - case LAND: - return new Land(referenceItem); - case CIRCLE: - return new Circle(referenceItem); - case ROI: - return new RegionOfInterest(referenceItem); - case SURVEY: - return new Survey(referenceItem.getMission(), Collections. emptyList()); - case CYLINDRICAL_SURVEY: - return new StructureScanner(referenceItem); - case SET_SERVO: - return new SetServo(referenceItem); - case CONDITION_YAW: - return new ConditionYaw(referenceItem); - default: - throw new IllegalArgumentException("Unrecognized mission item type (" + name + ")" - + ""); - } - } + public MissionItem getNewItem(MissionItem referenceItem) throws IllegalArgumentException { + switch (this) { + case WAYPOINT: + return new Waypoint(referenceItem); + case SPLINE_WAYPOINT: + return new SplineWaypoint(referenceItem); + case TAKEOFF: + return new Takeoff(referenceItem); + case CHANGE_SPEED: + return new ChangeSpeed(referenceItem); + case CAMERA_TRIGGER: + return new CameraTrigger(referenceItem); + case EPM_GRIPPER: + return new EpmGripper(referenceItem); + case RTL: + return new ReturnToHome(referenceItem); + case LAND: + return new Land(referenceItem); + case CIRCLE: + return new Circle(referenceItem); + case ROI: + return new RegionOfInterest(referenceItem); + case SURVEY: + return new Survey(referenceItem.getMission(), Collections.emptyList()); + case CYLINDRICAL_SURVEY: + return new StructureScanner(referenceItem); + case SET_SERVO: + return new SetServo(referenceItem); + case CONDITION_YAW: + return new ConditionYaw(referenceItem); + case SET_RELAY: + return new SetRelayImpl(referenceItem); + default: + throw new IllegalArgumentException("Unrecognized mission item type (" + name + ")" + ""); + } + } } diff --git a/dependencyLibs/Core/src/org/droidplanner/core/mission/commands/SetRelayImpl.java b/dependencyLibs/Core/src/org/droidplanner/core/mission/commands/SetRelayImpl.java new file mode 100644 index 0000000000..c8c497d4a2 --- /dev/null +++ b/dependencyLibs/Core/src/org/droidplanner/core/mission/commands/SetRelayImpl.java @@ -0,0 +1,64 @@ +package org.droidplanner.core.mission.commands; + +import com.MAVLink.common.msg_mission_item; +import com.MAVLink.enums.MAV_CMD; + +import org.droidplanner.core.mission.Mission; +import org.droidplanner.core.mission.MissionItem; +import org.droidplanner.core.mission.MissionItemType; + +import java.util.List; + +/** + * Mavlink message builder for the 'SetRelay' mission item. + * Set a Relay pin’s voltage high or low. + */ +public class SetRelayImpl extends MissionCMD { + + private int relayNumber; + private boolean enabled; + + public SetRelayImpl(MissionItem item){ + super(item); + } + + public SetRelayImpl(msg_mission_item msg, Mission mission){ + super(mission); + unpackMAVMessage(msg); + } + + public SetRelayImpl(Mission mission, int relayNumber, boolean enabled){ + super(mission); + this.relayNumber = relayNumber; + this.enabled = enabled; + } + + @Override + public MissionItemType getType(){ + return MissionItemType.SET_RELAY; + } + + @Override + public void unpackMAVMessage(msg_mission_item mavMsg){ + relayNumber = (int) mavMsg.param1; + enabled = mavMsg.param2 != 0; + } + + @Override + public List packMissionItem(){ + List list = super.packMissionItem(); + msg_mission_item mavMsg = list.get(0); + mavMsg.command = MAV_CMD.MAV_CMD_DO_SET_RELAY; + mavMsg.param1 = relayNumber; + mavMsg.param2 = enabled ? 1 : 0; + return list; + } + + public int getRelayNumber() { + return relayNumber; + } + + public boolean isEnabled() { + return enabled; + } +}