11package com .o3dr .android .client .apis ;
22
33import android .os .Bundle ;
4- import android .support .annotation .IntDef ;
54
65import com .o3dr .android .client .Drone ;
76import com .o3dr .services .android .lib .coordinate .LatLong ;
87import com .o3dr .services .android .lib .drone .attribute .AttributeType ;
98import com .o3dr .services .android .lib .drone .attribute .error .CommandExecutionError ;
10- import com .o3dr .services .android .lib .drone .property .Attitude ;
119import com .o3dr .services .android .lib .drone .property .Gps ;
1210import com .o3dr .services .android .lib .model .AbstractCommandListener ;
1311import com .o3dr .services .android .lib .model .action .Action ;
1412
15- import java .lang .annotation .Retention ;
16- import java .lang .annotation .RetentionPolicy ;
1713import java .util .concurrent .ConcurrentHashMap ;
1814
1915import static com .o3dr .services .android .lib .drone .action .ControlActions .ACTION_DO_GUIDED_TAKEOFF ;
16+ import static com .o3dr .services .android .lib .drone .action .ControlActions .ACTION_ENABLE_MANUAL_CONTROL ;
2017import static com .o3dr .services .android .lib .drone .action .ControlActions .ACTION_SEND_GUIDED_POINT ;
2118import static com .o3dr .services .android .lib .drone .action .ControlActions .ACTION_SET_CONDITION_YAW ;
2219import static com .o3dr .services .android .lib .drone .action .ControlActions .ACTION_SET_GUIDED_ALTITUDE ;
2320import static com .o3dr .services .android .lib .drone .action .ControlActions .ACTION_SET_VELOCITY ;
2421import static com .o3dr .services .android .lib .drone .action .ControlActions .EXTRA_ALTITUDE ;
22+ import static com .o3dr .services .android .lib .drone .action .ControlActions .EXTRA_DO_ENABLE ;
2523import static com .o3dr .services .android .lib .drone .action .ControlActions .EXTRA_FORCE_GUIDED_POINT ;
2624import static com .o3dr .services .android .lib .drone .action .ControlActions .EXTRA_GUIDED_POINT ;
2725import static com .o3dr .services .android .lib .drone .action .ControlActions .EXTRA_VELOCITY_X ;
3331
3432/**
3533 * Provides access to the vehicle control functionality.
36- *
34+ * <p/>
3735 * Use of this api might required the vehicle to be in a specific flight mode (i.e: GUIDED)
38- *
36+ * <p/>
3937 * Created by Fredia Huya-Kouadio on 9/7/15.
4038 */
4139public class ControlApi extends Api {
4240
43- public static final int EARTH_NED_COORDINATE_FRAME = 0 ;
44- public static final int VEHICLE_COORDINATE_FRAME = 1 ;
45-
46- @ IntDef ({EARTH_NED_COORDINATE_FRAME , VEHICLE_COORDINATE_FRAME })
47- @ Retention (RetentionPolicy .SOURCE )
48- public @interface CoordinateFrame {}
49-
5041 private static final ConcurrentHashMap <Drone , ControlApi > apiCache = new ConcurrentHashMap <>();
5142 private static final Builder <ControlApi > apiBuilder = new Builder <ControlApi >() {
5243 @ Override
@@ -57,16 +48,17 @@ public ControlApi build(Drone drone) {
5748
5849 /**
5950 * Retrieves a control api instance.
51+ *
6052 * @param drone
6153 * @return
6254 */
63- public static ControlApi getApi (final Drone drone ){
55+ public static ControlApi getApi (final Drone drone ) {
6456 return getApi (drone , apiCache , apiBuilder );
6557 }
6658
6759 private final Drone drone ;
6860
69- private ControlApi (Drone drone ){
61+ private ControlApi (Drone drone ) {
7062 this .drone = drone ;
7163 }
7264
@@ -123,13 +115,14 @@ public void climbTo(double altitude) {
123115
124116 /**
125117 * Instructs the vehicle to turn to the specified target angle
118+ *
126119 * @param targetAngle Target angle in degrees [0-360], with 0 == north.
127- * @param turnRate Turning rate normalized to the range [-1.0f, 1.0f]. Positive values for clockwise turns, and negative values for counter-clockwise turns.
128- * @param isRelative True is the target angle is relative to the current vehicle attitude, false otherwise if it's absolute.
129- * @param listener Register a callback to receive update of the command execution state.
120+ * @param turnRate Turning rate normalized to the range [-1.0f, 1.0f]. Positive values for clockwise turns, and negative values for counter-clockwise turns.
121+ * @param isRelative True is the target angle is relative to the current vehicle attitude, false otherwise if it's absolute.
122+ * @param listener Register a callback to receive update of the command execution state.
130123 */
131- public void turnTo (float targetAngle , float turnRate , boolean isRelative , AbstractCommandListener listener ){
132- if (!isWithinBounds (targetAngle , 0 , 360 ) || !isWithinBounds (turnRate , -1.0f , 1.0f )){
124+ public void turnTo (float targetAngle , float turnRate , boolean isRelative , AbstractCommandListener listener ) {
125+ if (!isWithinBounds (targetAngle , 0 , 360 ) || !isWithinBounds (turnRate , -1.0f , 1.0f )) {
133126 postErrorEvent (CommandExecutionError .COMMAND_FAILED , listener );
134127 return ;
135128 }
@@ -141,7 +134,21 @@ public void turnTo(float targetAngle, float turnRate, boolean isRelative, Abstra
141134 drone .performAsyncActionOnDroneThread (new Action (ACTION_SET_CONDITION_YAW , params ), listener );
142135 }
143136
144- private void moveAtVelocity (float vx , float vy , float vz , AbstractCommandListener listener ){
137+ /**
138+ * Move the vehicle along the specified normalized velocity vector.
139+ *
140+ * @param vx x velocity normalized to the range [-1.0f, 1.0f]. Generally correspond to the pitch of the vehicle.
141+ * @param vy y velocity normalized to the range [-1.0f, 1.0f]. Generally correspond to the roll of the vehicle.
142+ * @param vz z velocity normalized to the range [-1.0f, 1.0f]. Generally correspond to the thrust of the vehicle.
143+ * @param listener Register a callback to receive update of the command execution state.
144+ * @since 2.6.9
145+ */
146+ public void manualControl (float vx , float vy , float vz , AbstractCommandListener listener ) {
147+ if (!isWithinBounds (vx , -1f , 1f ) || !isWithinBounds (vy , -1f , 1f ) || !isWithinBounds (vz , -1f , 1f )) {
148+ postErrorEvent (CommandExecutionError .COMMAND_FAILED , listener );
149+ return ;
150+ }
151+
145152 Bundle params = new Bundle ();
146153 params .putFloat (EXTRA_VELOCITY_X , vx );
147154 params .putFloat (EXTRA_VELOCITY_Y , vy );
@@ -150,41 +157,63 @@ private void moveAtVelocity(float vx, float vy, float vz, AbstractCommandListene
150157 }
151158
152159 /**
153- * Move the vehicle along the specified velocity vector.
154- *
155- * @param referenceFrame Reference frame to use. Can be one of
156- * {@link #EARTH_NED_COORDINATE_FRAME},
157- * {@link #VEHICLE_COORDINATE_FRAME}
160+ * [Dis|En]able manual control on the vehicle.
161+ * The result of the action will be conveyed through the passed listener.
158162 *
159- * @param vx x velocity normalized to the range [-1.0f, 1.0f].
160- * @param vy y velocity normalized to the range [-1.0f, 1.0f].
161- * @param vz z velocity normalized to the range [-1.0f, 1.0f].
162- * @param listener Register a callback to receive update of the command execution state.
163+ * @param enable True to enable manual control, false to disable.
164+ * @param listener Register a callback to receive the result of the operation.
165+ * @since 2.6.9
163166 */
164- public void moveAtVelocity (@ CoordinateFrame int referenceFrame , float vx , float vy , float vz , AbstractCommandListener listener ){
165- if (!isWithinBounds (vx , -1f , 1f ) || !isWithinBounds (vy , -1f , 1f ) || !isWithinBounds (vz , -1f , 1f )){
166- postErrorEvent (CommandExecutionError .COMMAND_FAILED , listener );
167- return ;
168- }
169-
170- float projectedX = vx ;
171- float projectedY = vy ;
172-
173- if (referenceFrame == VEHICLE_COORDINATE_FRAME ) {
174- Attitude attitude = drone .getAttribute (AttributeType .ATTITUDE );
175- double attitudeInRad = Math .toRadians (attitude .getYaw ());
167+ public void enableManualControl (final boolean enable , final ManualControlStateListener listener ) {
168+ AbstractCommandListener listenerWrapper = listener == null ? null
169+ : new AbstractCommandListener () {
170+ @ Override
171+ public void onSuccess () {
172+ if (enable ) {
173+ listener .onManualControlEnabled ();
174+ } else {
175+ listener .onManualControlDisabled ();
176+ }
177+ }
176178
177- final double cosAttitude = Math .cos (attitudeInRad );
178- final double sinAttitude = Math .sin (attitudeInRad );
179+ @ Override
180+ public void onError (int executionError ) {
181+ if (enable ) {
182+ listener .onManualControlDisabled ();
183+ }
184+ }
179185
180- projectedX = (float ) (vx * cosAttitude ) - (float ) (vy * sinAttitude );
181- projectedY = (float ) (vx * sinAttitude ) + (float ) (vy * cosAttitude );
182- }
186+ @ Override
187+ public void onTimeout () {
188+ if (enable ) {
189+ listener .onManualControlDisabled ();
190+ }
191+ }
192+ };
183193
184- moveAtVelocity (projectedX , projectedY , vz , listener );
194+ Bundle params = new Bundle ();
195+ params .putBoolean (EXTRA_DO_ENABLE , enable );
196+ drone .performAsyncActionOnDroneThread (new Action (ACTION_ENABLE_MANUAL_CONTROL , params ), listenerWrapper );
185197 }
186198
187- private static boolean isWithinBounds (float value , float lowerBound , float upperBound ){
199+ private static boolean isWithinBounds (float value , float lowerBound , float upperBound ) {
188200 return value <= upperBound && value >= lowerBound ;
189201 }
202+
203+ /**
204+ * Used to monitor the state of manual control for the vehicle.
205+ *
206+ * @since 2.6.9
207+ */
208+ public interface ManualControlStateListener {
209+ /**
210+ * Manual control is enabled on the vehicle.
211+ */
212+ void onManualControlEnabled ();
213+
214+ /**
215+ * Manual control is disabled on the vehicle.
216+ */
217+ void onManualControlDisabled ();
218+ }
190219}
0 commit comments