Skip to content

Commit a4e5f4e

Browse files
committed
Merge pull request #348 from dronekit/release-1.5.0
Release 1.5.0
2 parents 9d5de9b + 59ddd7a commit a4e5f4e

File tree

84 files changed

+3782
-625
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+3782
-625
lines changed

ClientLib/build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ apply plugin: 'com.android.library'
22

33
ext {
44
VERSION_MAJOR = 2
5-
VERSION_MINOR = 6
6-
VERSION_PATCH = 9
5+
VERSION_MINOR = 7
6+
VERSION_PATCH = 0
77
VERSION_SUFFIX = "release"
88

99
PUBLISH_ARTIFACT_ID = 'dronekit-android'

ClientLib/src/main/java/com/o3dr/android/client/Drone.java

+1
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ private <T extends Parcelable> T getAttributeDefaultValue(String attributeType)
372372
case AttributeType.CAMERA:
373373
case SoloAttributes.SOLO_STATE:
374374
case SoloAttributes.SOLO_GOPRO_STATE:
375+
case SoloAttributes.SOLO_GOPRO_STATE_V2:
375376
default:
376377
return null;
377378
}

ClientLib/src/main/java/com/o3dr/android/client/apis/CameraApi.java

+14
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import static com.o3dr.services.android.lib.drone.action.CameraActions.ACTION_START_VIDEO_STREAM;
1515
import static com.o3dr.services.android.lib.drone.action.CameraActions.ACTION_STOP_VIDEO_STREAM;
1616
import static com.o3dr.services.android.lib.drone.action.CameraActions.EXTRA_VIDEO_DISPLAY;
17+
import static com.o3dr.services.android.lib.drone.action.CameraActions.EXTRA_VIDEO_ENABLE_LOCAL_RECORDING;
18+
import static com.o3dr.services.android.lib.drone.action.CameraActions.EXTRA_VIDEO_LOCAL_RECORDING_FILENAME;
1719
import static com.o3dr.services.android.lib.drone.action.CameraActions.EXTRA_VIDEO_PROPS_UDP_PORT;
1820
import static com.o3dr.services.android.lib.drone.action.CameraActions.EXTRA_VIDEO_TAG;
1921
import static com.o3dr.services.android.lib.drone.action.CameraActions.EXTRA_VIDEO_PROPERTIES;
@@ -39,6 +41,18 @@ public CameraApi build(Drone drone) {
3941
*/
4042
public static final String VIDEO_PROPS_UDP_PORT = EXTRA_VIDEO_PROPS_UDP_PORT;
4143

44+
/**
45+
* Key to specify whether to enable/disable local recording of the video stream.
46+
* @since 2.7.0
47+
*/
48+
public static final String VIDEO_ENABLE_LOCAL_RECORDING = EXTRA_VIDEO_ENABLE_LOCAL_RECORDING;
49+
50+
/**
51+
* Key to specify the filename to use for the local recording.
52+
* @since 2.7.0
53+
*/
54+
public static final String VIDEO_LOCAL_RECORDING_FILENAME = EXTRA_VIDEO_LOCAL_RECORDING_FILENAME;
55+
4256
/**
4357
* Retrieves a camera api instance
4458
*

ClientLib/src/main/java/com/o3dr/android/client/apis/ControlApi.java

+7-11
Original file line numberDiff line numberDiff line change
@@ -170,23 +170,23 @@ public void enableManualControl(final boolean enable, final ManualControlStateLi
170170
@Override
171171
public void onSuccess() {
172172
if (enable) {
173-
listener.onManualControlEnabled();
173+
listener.onManualControlToggled(true);
174174
} else {
175-
listener.onManualControlDisabled();
175+
listener.onManualControlToggled(false);
176176
}
177177
}
178178

179179
@Override
180180
public void onError(int executionError) {
181181
if (enable) {
182-
listener.onManualControlDisabled();
182+
listener.onManualControlToggled(false);
183183
}
184184
}
185185

186186
@Override
187187
public void onTimeout() {
188188
if (enable) {
189-
listener.onManualControlDisabled();
189+
listener.onManualControlToggled(false);
190190
}
191191
}
192192
};
@@ -207,13 +207,9 @@ private static boolean isWithinBounds(float value, float lowerBound, float upper
207207
*/
208208
public interface ManualControlStateListener {
209209
/**
210-
* Manual control is enabled on the vehicle.
210+
* Manual control is toggled on the vehicle.
211+
* @param isEnabled True if manual control is enabled, false if disabled.
211212
*/
212-
void onManualControlEnabled();
213-
214-
/**
215-
* Manual control is disabled on the vehicle.
216-
*/
217-
void onManualControlDisabled();
213+
void onManualControlToggled(boolean isEnabled);
218214
}
219215
}

ClientLib/src/main/java/com/o3dr/android/client/apis/solo/SoloCameraApi.java

+92-17
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,21 @@
33
import android.os.Bundle;
44
import android.view.Surface;
55

6+
import com.MAVLink.enums.GOPRO_COMMAND;
67
import com.o3dr.android.client.Drone;
78
import com.o3dr.android.client.apis.CameraApi;
89
import com.o3dr.android.client.apis.CapabilityApi;
910
import com.o3dr.services.android.lib.drone.action.CameraActions;
1011
import com.o3dr.services.android.lib.drone.attribute.error.CommandExecutionError;
1112
import com.o3dr.services.android.lib.drone.companion.solo.tlv.SoloGoproConstants;
1213
import com.o3dr.services.android.lib.drone.companion.solo.tlv.SoloGoproRecord;
14+
import com.o3dr.services.android.lib.drone.companion.solo.tlv.SoloGoproSetExtendedRequest;
1315
import com.o3dr.services.android.lib.drone.companion.solo.tlv.SoloGoproSetRequest;
1416
import com.o3dr.services.android.lib.model.AbstractCommandListener;
1517

18+
import java.text.SimpleDateFormat;
19+
import java.util.Date;
20+
import java.util.Locale;
1621
import java.util.concurrent.ConcurrentHashMap;
1722

1823
/**
@@ -23,7 +28,7 @@
2328
*/
2429
public class SoloCameraApi extends SoloApi {
2530

26-
private static final String TAG = SoloCameraApi.class.getSimpleName();
31+
private static final SimpleDateFormat FILE_DATE_FORMAT = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss", Locale.US);
2732

2833
private static final ConcurrentHashMap<Drone, SoloCameraApi> soloCameraApiCache = new ConcurrentHashMap<>();
2934
private static final Builder<SoloCameraApi> apiBuilder = new Builder<SoloCameraApi>() {
@@ -116,21 +121,6 @@ public void stopVideoRecording(final AbstractCommandListener listener) {
116121
sendVideoRecordingCommand(SoloGoproConstants.STOP_RECORDING, listener);
117122
}
118123

119-
/**
120-
* Switches the camera capture mode.
121-
*
122-
* @param captureMode One of {@link SoloGoproConstants#CAPTURE_MODE_VIDEO},
123-
* {@link SoloGoproConstants#CAPTURE_MODE_PHOTO},
124-
* {@link SoloGoproConstants#CAPTURE_MODE_BURST},
125-
* {@link SoloGoproConstants#CAPTURE_MODE_TIME_LAPSE}
126-
* @param listener Register a callback to receive update of the command execution status.
127-
* @since 2.6.8
128-
*/
129-
public void switchCameraCaptureMode(@SoloGoproConstants.CaptureMode byte captureMode, final AbstractCommandListener listener) {
130-
final SoloGoproSetRequest captureModeRequest = new SoloGoproSetRequest(SoloGoproConstants.CAPTURE_MODE, captureMode);
131-
sendMessage(captureModeRequest, listener);
132-
}
133-
134124
private void sendVideoRecordingCommand(@SoloGoproConstants.RecordCommand final int recordCommand, final AbstractCommandListener listener) {
135125
//Set the gopro to video mode
136126
switchCameraCaptureMode(SoloGoproConstants.CAPTURE_MODE_VIDEO, new AbstractCommandListener() {
@@ -157,17 +147,22 @@ public void onTimeout() {
157147
});
158148
}
159149

150+
public void startVideoStream(final Surface surface, final String tag, final AbstractCommandListener listener) {
151+
startVideoStream(surface, tag, false, listener);
152+
}
153+
160154
/**
161155
* Attempt to grab ownership and start the video stream from the connected drone. Can fail if
162156
* the video stream is already owned by another client.
163157
*
164158
* @param surface Surface object onto which the video is decoded.
165159
* @param tag Video tag.
160+
* @param enableLocalRecording Set to true to enable local recording, false to disable it.
166161
* @param listener Register a callback to receive update of the command execution status.
167162
*
168163
* @since 2.5.0
169164
*/
170-
public void startVideoStream(final Surface surface, final String tag, final AbstractCommandListener listener) {
165+
public void startVideoStream(final Surface surface, final String tag, final boolean enableLocalRecording, final AbstractCommandListener listener) {
171166
if (surface == null) {
172167
postErrorEvent(CommandExecutionError.COMMAND_FAILED, listener);
173168
return;
@@ -182,6 +177,13 @@ public void onFeatureSupportResult(String featureId, int result, Bundle resultIn
182177
case CapabilityApi.FEATURE_SUPPORTED:
183178
final Bundle videoProps = new Bundle();
184179
videoProps.putInt(CameraApi.VIDEO_PROPS_UDP_PORT, SOLO_STREAM_UDP_PORT);
180+
181+
videoProps.putBoolean(CameraApi.VIDEO_ENABLE_LOCAL_RECORDING, enableLocalRecording);
182+
if(enableLocalRecording){
183+
String localRecordingFilename = "solo_stream_" + FILE_DATE_FORMAT.format(new Date());
184+
videoProps.putString(CameraApi.VIDEO_LOCAL_RECORDING_FILENAME, localRecordingFilename);
185+
}
186+
185187
cameraApi.startVideoStream(surface, tag, videoProps, listener);
186188
break;
187189

@@ -252,4 +254,77 @@ public void onFeatureSupportResult(String featureId, int result, Bundle resultIn
252254
}
253255
});
254256
}
257+
258+
/**
259+
* Switches the camera capture mode.
260+
*
261+
* @param captureMode One of {@link SoloGoproConstants#CAPTURE_MODE_VIDEO},
262+
* {@link SoloGoproConstants#CAPTURE_MODE_PHOTO},
263+
* {@link SoloGoproConstants#CAPTURE_MODE_BURST},
264+
* {@link SoloGoproConstants#CAPTURE_MODE_TIME_LAPSE}
265+
* @param listener Register a callback to receive update of the command execution status.
266+
* @since 2.6.8
267+
*/
268+
public void switchCameraCaptureMode(@SoloGoproConstants.CaptureMode byte captureMode, final AbstractCommandListener listener) {
269+
final SoloGoproSetRequest captureModeRequest = new SoloGoproSetRequest((short) GOPRO_COMMAND.GOPRO_COMMAND_CAPTURE_MODE, captureMode);
270+
sendMessage(captureModeRequest, listener);
271+
}
272+
273+
private void sendExtendedRequest(AbstractCommandListener listener, int command, byte value1, byte value2, byte value3, byte value4){
274+
byte[] values = {value1, value2, value3, value4};
275+
SoloGoproSetExtendedRequest extendedRequest = new SoloGoproSetExtendedRequest((short) command, values);
276+
sendMessage(extendedRequest, listener);
277+
}
278+
279+
private void sendExtendedRequest(AbstractCommandListener listener, int command, byte value){
280+
sendExtendedRequest(listener, command, value, (byte) 0, (byte) 0, (byte) 0);
281+
}
282+
283+
/**
284+
* Updates the camera video settings.
285+
* @since 2.7.0
286+
* @param resolution
287+
* @param frameRate
288+
* @param fieldOfView
289+
* @param flags
290+
*/
291+
public void updateVideoSettings(byte resolution, byte frameRate, byte fieldOfView, byte flags, AbstractCommandListener listener){
292+
sendExtendedRequest(listener, GOPRO_COMMAND.GOPRO_COMMAND_VIDEO_SETTINGS, resolution, frameRate, fieldOfView, flags);
293+
}
294+
295+
public void setCameraPhotoResolution(byte photoResolution, AbstractCommandListener listener){
296+
sendExtendedRequest(listener, GOPRO_COMMAND.GOPRO_COMMAND_PHOTO_RESOLUTION, photoResolution);
297+
}
298+
299+
public void enableCameraLowLight(boolean enable, AbstractCommandListener listener){
300+
sendExtendedRequest(listener, GOPRO_COMMAND.GOPRO_COMMAND_LOW_LIGHT, enable ? (byte) 1 : (byte) 0);
301+
}
302+
303+
public void setCameraPhotoBurstRate(byte burstRate, AbstractCommandListener listener){
304+
sendExtendedRequest(listener, GOPRO_COMMAND.GOPRO_COMMAND_PHOTO_BURST_RATE, burstRate);
305+
}
306+
307+
public void enableCameraProtune(boolean enable, AbstractCommandListener listener){
308+
sendExtendedRequest(listener, GOPRO_COMMAND.GOPRO_COMMAND_PROTUNE, enable ? (byte)1 : (byte) 0);
309+
}
310+
311+
public void setCameraProtuneWhiteBalance(byte whiteBalance, AbstractCommandListener listener) {
312+
sendExtendedRequest(listener, GOPRO_COMMAND.GOPRO_COMMAND_PROTUNE_WHITE_BALANCE, whiteBalance);
313+
}
314+
315+
public void setCameraProtuneColour(byte colour, AbstractCommandListener listener) {
316+
sendExtendedRequest(listener, GOPRO_COMMAND.GOPRO_COMMAND_PROTUNE_COLOUR, colour);
317+
}
318+
319+
public void setCameraProtuneGain(byte gain, AbstractCommandListener listener) {
320+
sendExtendedRequest(listener, GOPRO_COMMAND.GOPRO_COMMAND_PROTUNE_GAIN, gain);
321+
}
322+
323+
public void setCameraProtuneSharpness(byte sharpness, AbstractCommandListener listener) {
324+
sendExtendedRequest(listener, GOPRO_COMMAND.GOPRO_COMMAND_PROTUNE_SHARPNESS, sharpness);
325+
}
326+
327+
public void setCameraProtuneExposure(byte exposure, AbstractCommandListener listener) {
328+
sendExtendedRequest(listener, GOPRO_COMMAND.GOPRO_COMMAND_PROTUNE_EXPOSURE, exposure);
329+
}
255330
}

ClientLib/src/main/java/com/o3dr/services/android/lib/drone/action/CameraActions.java

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ private CameraActions() {
1717

1818
public static final String EXTRA_VIDEO_PROPERTIES = "extra_video_properties";
1919
public static final String EXTRA_VIDEO_PROPS_UDP_PORT = "extra_video_props_udp_port";
20+
public static final String EXTRA_VIDEO_ENABLE_LOCAL_RECORDING = "extra_video_enable_local_recording";
21+
public static final String EXTRA_VIDEO_LOCAL_RECORDING_FILENAME = "extra_video_local_recording_filename";
2022

2123
public static final String ACTION_STOP_VIDEO_STREAM = PACKAGE_NAME + ".STOP_VIDEO_STREAM";
2224
}

ClientLib/src/main/java/com/o3dr/services/android/lib/drone/companion/solo/SoloAttributes.java

+6
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,10 @@ private SoloAttributes(){}
2020
* Used to access the sololink gopro state.
2121
*/
2222
public static final String SOLO_GOPRO_STATE = PACKAGE_NAME + ".SOLO_GOPRO_STATE";
23+
24+
/**
25+
* Used to access the updated sololink gopro state.
26+
* @since 2.7.0
27+
*/
28+
public static final String SOLO_GOPRO_STATE_V2 = PACKAGE_NAME + ".SOLO_GOPRO_STATE_V2";
2329
}

ClientLib/src/main/java/com/o3dr/services/android/lib/drone/companion/solo/SoloEvents.java

+7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ private SoloEvents() {
1818
* @see {@link com.o3dr.services.android.lib.drone.companion.solo.tlv.SoloGoproState}
1919
*/
2020
public static final String SOLO_GOPRO_STATE_UPDATED = PACKAGE_NAME + ".GOPRO_STATE_UPDATED";
21+
22+
/**
23+
* Broadcasts updates to the Gopro extended state.
24+
* @see {@link com.o3dr.services.android.lib.drone.companion.solo.tlv.SoloGoproStateV2}
25+
*/
26+
public static final String SOLO_GOPRO_STATE_V2_UPDATED = PACKAGE_NAME + ".GOPRO_STATE_V2_UPDATED";
27+
2128
/**
2229
* Signals update to the sololink wifi settings
2330
*

ClientLib/src/main/java/com/o3dr/services/android/lib/drone/companion/solo/tlv/ControllerMessageInputReport.java

+10
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,14 @@ public ControllerMessageInputReport[] newArray(int size) {
7272
return new ControllerMessageInputReport[size];
7373
}
7474
};
75+
76+
@Override
77+
public String toString() {
78+
return "ControllerMessageInputReport{" +
79+
"battery=" + battery +
80+
", timestamp=" + timestamp +
81+
", gimbalY=" + gimbalY +
82+
", gimbalRate=" + gimbalRate +
83+
'}';
84+
}
7585
}

ClientLib/src/main/java/com/o3dr/services/android/lib/drone/companion/solo/tlv/SoloGoproConstants.java

+17-23
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import android.support.annotation.IntDef;
44

5+
import com.MAVLink.enums.GOPRO_CAPTURE_MODE;
6+
57
import java.lang.annotation.Retention;
68
import java.lang.annotation.RetentionPolicy;
79

@@ -14,28 +16,22 @@
1416
public class SoloGoproConstants {
1517

1618
//Private constructor to prevent instantiation.
17-
private SoloGoproConstants(){}
18-
19-
20-
@IntDef({POWER, CAPTURE_MODE})
21-
@Retention(RetentionPolicy.SOURCE)
22-
public @interface RequestCommand{}
23-
24-
public static final short POWER = 0;
25-
public static final short CAPTURE_MODE = 1;
26-
19+
private SoloGoproConstants() {
20+
}
2721

2822
@IntDef({STOP_RECORDING, START_RECORDING, TOGGLE_RECORDING})
2923
@Retention(RetentionPolicy.SOURCE)
30-
public @interface RecordCommand{}
24+
public @interface RecordCommand {
25+
}
3126

3227
public static final int STOP_RECORDING = 0;
3328
public static final int START_RECORDING = 1;
3429
public static final int TOGGLE_RECORDING = 2;
3530

3631
@IntDef({STATUS_NO_GOPRO, STATUS_INCOMPATIBLE_GOPRO, STATUS_GOPRO_CONNECTED, STATUS_ERROR_OVER_TEMPERATURE, STATUS_ERROR_NO_STORAGE})
3732
@Retention(RetentionPolicy.SOURCE)
38-
public @interface GoproStatus{}
33+
public @interface GoproStatus {
34+
}
3935

4036
public static final byte STATUS_NO_GOPRO = 0;
4137
public static final byte STATUS_INCOMPATIBLE_GOPRO = 1;
@@ -46,15 +42,18 @@ private SoloGoproConstants(){}
4642

4743
@IntDef({RECORDING_OFF, RECORDING_ON})
4844
@Retention(RetentionPolicy.SOURCE)
49-
public @interface RecordingStatus{}
45+
public @interface RecordingStatus {
46+
}
5047

5148
public static final byte RECORDING_OFF = 0;
5249
public static final byte RECORDING_ON = 1;
5350

5451

55-
@IntDef({CAPTURE_MODE_VIDEO, CAPTURE_MODE_PHOTO, CAPTURE_MODE_BURST, CAPTURE_MODE_TIME_LAPSE})
52+
@IntDef({CAPTURE_MODE_VIDEO, CAPTURE_MODE_PHOTO, CAPTURE_MODE_BURST, CAPTURE_MODE_TIME_LAPSE,
53+
CAPTURE_MODE_MULTI_SHOT, CAPTURE_MODE_PLAYBACK, CAPTURE_MODE_SETUP})
5654
@Retention(RetentionPolicy.SOURCE)
57-
public @interface CaptureMode{}
55+
public @interface CaptureMode {
56+
}
5857

5958
/**
6059
* Camera video mode.
@@ -76,12 +75,7 @@ private SoloGoproConstants(){}
7675
*/
7776
public static final byte CAPTURE_MODE_TIME_LAPSE = 3;
7877

79-
80-
@IntDef({POWER_OFF, POWER_ON,
81-
CAPTURE_MODE_VIDEO, CAPTURE_MODE_PHOTO, CAPTURE_MODE_BURST, CAPTURE_MODE_TIME_LAPSE})
82-
@Retention(RetentionPolicy.SOURCE)
83-
public @interface RequestCommandValue{}
84-
85-
public static final short POWER_OFF = 0;
86-
public static final short POWER_ON = 1;
78+
public static final byte CAPTURE_MODE_MULTI_SHOT = 4;
79+
public static final byte CAPTURE_MODE_PLAYBACK = 5;
80+
public static final byte CAPTURE_MODE_SETUP = 6;
8781
}

0 commit comments

Comments
 (0)