From 385a7bf00fab2e4edad1bf7edd6b56ceca70eb90 Mon Sep 17 00:00:00 2001 From: Aleksey Parfyonov Date: Thu, 16 Dec 2021 19:23:11 +0500 Subject: [PATCH 1/8] add GPS logging into csv --- .../opencamera/ExtendedAppInterface.java | 7 +- .../sensorlogging/RawSensorInfo.java | 91 ++++++++++++++++--- 2 files changed, 82 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/net/sourceforge/opencamera/ExtendedAppInterface.java b/app/src/main/java/net/sourceforge/opencamera/ExtendedAppInterface.java index 931217de6..81a13c894 100644 --- a/app/src/main/java/net/sourceforge/opencamera/ExtendedAppInterface.java +++ b/app/src/main/java/net/sourceforge/opencamera/ExtendedAppInterface.java @@ -129,11 +129,16 @@ public void startImu(boolean wantAccel, boolean wantGyro, boolean wantMagnetic, } } - //mRawSensorInfo.startRecording(mMainActivity, mLastVideoDate, get Pref(), getAccelPref()) + if (!mRawSensorInfo.enableSensor(mRawSensorInfo.TYPE_GPS, 0)) { + mMainActivity.getPreview().showToast(null, "GPS unavailable"); + } + + //mRawSensorInfo.startRecording(mMainActivity, mLastVideoDate, get Pref(), getAccelPref()) Map wantSensorRecordingMap = new HashMap<>(); wantSensorRecordingMap.put(Sensor.TYPE_ACCELEROMETER, getAccelPref()); wantSensorRecordingMap.put(Sensor.TYPE_GYROSCOPE, getGyroPref()); wantSensorRecordingMap.put(Sensor.TYPE_MAGNETIC_FIELD, getMagneticPref()); + wantSensorRecordingMap.put(mRawSensorInfo.TYPE_GPS, true); mRawSensorInfo.startRecording(mMainActivity, currentDate, wantSensorRecordingMap); } diff --git a/app/src/main/java/net/sourceforge/opencamera/sensorlogging/RawSensorInfo.java b/app/src/main/java/net/sourceforge/opencamera/sensorlogging/RawSensorInfo.java index 9b12f3c85..f28cff2b4 100644 --- a/app/src/main/java/net/sourceforge/opencamera/sensorlogging/RawSensorInfo.java +++ b/app/src/main/java/net/sourceforge/opencamera/sensorlogging/RawSensorInfo.java @@ -5,8 +5,13 @@ import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.location.LocationProvider; import android.net.Uri; import android.os.ParcelFileDescriptor; +import android.os.Bundle; import android.util.Log; import net.sourceforge.opencamera.MainActivity; @@ -32,11 +37,12 @@ * Assumes all the used sensor types are motion or position sensors * and output [x, y, z] values -- the class should be updated if that changes */ -public class RawSensorInfo implements SensorEventListener { +public class RawSensorInfo implements SensorEventListener, LocationListener { private static final String TAG = "RawSensorInfo"; private static final String CSV_SEPARATOR = ","; + public static final int TYPE_GPS = 0xabcd; private static final List SENSOR_TYPES = Collections.unmodifiableList( - Arrays.asList(Sensor.TYPE_ACCELEROMETER, Sensor.TYPE_GYROSCOPE, Sensor.TYPE_MAGNETIC_FIELD) + Arrays.asList(TYPE_GPS, Sensor.TYPE_ACCELEROMETER, Sensor.TYPE_GYROSCOPE, Sensor.TYPE_MAGNETIC_FIELD) ); private static final Map SENSOR_TYPE_NAMES; static { @@ -44,16 +50,18 @@ public class RawSensorInfo implements SensorEventListener { SENSOR_TYPE_NAMES.put(Sensor.TYPE_ACCELEROMETER, "accel"); SENSOR_TYPE_NAMES.put(Sensor.TYPE_GYROSCOPE, "gyro"); SENSOR_TYPE_NAMES.put(Sensor.TYPE_MAGNETIC_FIELD, "magnetic"); + SENSOR_TYPE_NAMES.put(TYPE_GPS, "location"); } final private SensorManager mSensorManager; + private final LocationManager mLocationManager; /* final private Sensor mSensorGyro; final private Sensor mSensorAccel; final private Sensor mSensorMagnetic; private PrintWriter mGyroBufferedWriter; private PrintWriter mAccelBufferedWriter;*/ private boolean mIsRecording; - private final Map mUsedSensorMap; + private final Map mUsedSensorMap; private final Map mSensorWriterMap; private final Map mLastSensorFilesMap; @@ -67,12 +75,17 @@ public boolean isSensorAvailable(int sensorType) { public RawSensorInfo(MainActivity context) { mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); + mLocationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE); mUsedSensorMap = new HashMap<>(); mSensorWriterMap = new HashMap<>(); mLastSensorFilesMap = new HashMap<>(); for (Integer sensorType : SENSOR_TYPES) { - mUsedSensorMap.put(sensorType, mSensorManager.getDefaultSensor(sensorType)); + if (sensorType != TYPE_GPS) { + mUsedSensorMap.put(sensorType, mSensorManager.getDefaultSensor(sensorType)); + } else { + mUsedSensorMap.put(sensorType, new Object()); + } } /* mSensorGyro = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE); mSensorAccel = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); @@ -91,20 +104,59 @@ public RawSensorInfo(MainActivity context) { } public int getSensorMinDelay(int sensorType) { - Sensor sensor = mUsedSensorMap.get(sensorType); + Object sensor = mUsedSensorMap.get(sensorType); if (sensor != null) { - return sensor.getMinDelay(); - } else { - // Unsupported sensorType - if (MyDebug.LOG) { - Log.d(TAG, "Unsupported sensor type was provided"); + if (sensor instanceof Sensor) { + return ((Sensor)sensor).getMinDelay(); } - return 0; + } + // Unsupported sensorType + if (MyDebug.LOG) { + Log.d(TAG, "Unsupported sensor type was provided"); + } + return 0; + } + + @Override + public void onProviderEnabled(String provider) { + } + + @Override + public void onProviderDisabled(String provider) { + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + } + + private class MyEvent { + public int accuracy; + public Sensor sensor; + public long timestamp; + public float[] values; + } + + @Override + public void onLocationChanged(Location location) { + if( location != null && ( location.getLatitude() != 0.0d || location.getLongitude() != 0.0d ) ) { + MyEvent event = new MyEvent(); + event.timestamp = location.getElapsedRealtimeNanos(); + event.values = new float[]{(float) location.getLatitude(), (float) location.getLongitude(), (float) location.getAltitude()}; + _onSensorChanged(event); } } @Override public void onSensorChanged(SensorEvent event) { + MyEvent e = new MyEvent(); + e.accuracy = event.accuracy; + e.sensor = event.sensor; + e.timestamp = event.timestamp; + e.values = event.values; + _onSensorChanged(e); + } + + private void _onSensorChanged(MyEvent event) { if (mIsRecording) { StringBuilder sensorData = new StringBuilder(); for (int j = 0; j < 3; j++) { @@ -112,9 +164,9 @@ public void onSensorChanged(SensorEvent event) { } sensorData.append(event.timestamp).append("\n"); - Sensor sensor = mUsedSensorMap.get(event.sensor.getType()); + Object sensor = mUsedSensorMap.get(event.sensor != null ? event.sensor.getType() : TYPE_GPS); if (sensor != null) { - PrintWriter sensorWriter = mSensorWriterMap.get(event.sensor.getType()); + PrintWriter sensorWriter = mSensorWriterMap.get(event.sensor != null ? event.sensor.getType() : TYPE_GPS); if (sensorWriter != null) { sensorWriter.write(sensorData.toString()); } else { @@ -288,9 +340,17 @@ public boolean enableSensor(int sensorType, int sampleRate) { Log.d(TAG, "enableSensor"); } - Sensor sensor = mUsedSensorMap.get(sensorType); + Object sensor = mUsedSensorMap.get(sensorType); if (sensor != null) { - mSensorManager.registerListener(this, sensor, sampleRate); + if (sensorType != TYPE_GPS) { + mSensorManager.registerListener(this, (Sensor)sensor, sampleRate); + } else { + try { + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); + } catch (SecurityException e) { + return false; + } + } return true; } else { return false; @@ -313,5 +373,6 @@ public void disableSensors() { Log.d(TAG, "disableSensors"); } mSensorManager.unregisterListener(this); + mLocationManager.removeUpdates(this); } } From fc0c3906d719ebd5938289abf1f1e8fc5b7e035a Mon Sep 17 00:00:00 2001 From: arakh Date: Wed, 22 Dec 2021 07:54:26 +0300 Subject: [PATCH 2/8] Add gravity and rotation --- app/src/main/assets/server_config.properties | 2 +- .../opencamera/ExtendedAppInterface.java | 30 +++++++++++++++-- .../opencamera/PreferenceKeys.java | 8 +++++ .../sensorlogging/RawSensorInfo.java | 6 +++- .../sensorremote/RemoteRpcRequestHandler.java | 6 ++-- .../sensorremote/RemoteRpcServer.java | 12 +++++-- app/src/main/res/xml/preferences.xml | 32 +++++++++++++++++++ 7 files changed, 87 insertions(+), 9 deletions(-) diff --git a/app/src/main/assets/server_config.properties b/app/src/main/assets/server_config.properties index b502bb34d..02a941da9 100644 --- a/app/src/main/assets/server_config.properties +++ b/app/src/main/assets/server_config.properties @@ -1,5 +1,5 @@ RPC_PORT=6969 -SERVER_VERSION=v.0.1.1 +SERVER_VERSION=v.0.1.2 VIDEO_START_REQUEST=video_start VIDEO_STOP_REQUEST=video_stop GET_VIDEO_REQUEST=get_video diff --git a/app/src/main/java/net/sourceforge/opencamera/ExtendedAppInterface.java b/app/src/main/java/net/sourceforge/opencamera/ExtendedAppInterface.java index 931217de6..eb5c7824a 100644 --- a/app/src/main/java/net/sourceforge/opencamera/ExtendedAppInterface.java +++ b/app/src/main/java/net/sourceforge/opencamera/ExtendedAppInterface.java @@ -86,6 +86,14 @@ private boolean getMagneticPref() { return mSharedPreferences.getBoolean(PreferenceKeys.MagnetometerPrefKey, true); } + private boolean getRotationPref() { + return mSharedPreferences.getBoolean(PreferenceKeys.RotationPreferenceKey, true); + } + + private boolean getGravityPref() { + return mSharedPreferences.getBoolean(PreferenceKeys.GravityPreferenceKey, true); + } + /** * Retrieves gyroscope and accelerometer sample rate preference and converts it to number */ @@ -109,7 +117,11 @@ public boolean getSaveFramesPref() { return mSharedPreferences.getBoolean(PreferenceKeys.saveFramesPreferenceKey, false); } - public void startImu(boolean wantAccel, boolean wantGyro, boolean wantMagnetic, Date currentDate) { + public void startImu( + boolean wantAccel, boolean wantGyro, + boolean wantMagnetic, boolean wantGravity, + boolean wantRotation, Date currentDate + ) { if (wantAccel) { int accelSampleRate = getSensorSampleRatePref(PreferenceKeys.AccelSampleRatePreferenceKey); if (!mRawSensorInfo.enableSensor(Sensor.TYPE_ACCELEROMETER, accelSampleRate)) { @@ -129,6 +141,20 @@ public void startImu(boolean wantAccel, boolean wantGyro, boolean wantMagnetic, } } + if (wantRotation) { + int rotationSampleRate = getSensorSampleRatePref(PreferenceKeys.RotationSampleRatePreferenceKey); + if (!mRawSensorInfo.enableSensor(Sensor.TYPE_ROTATION_VECTOR, rotationSampleRate)) { + mMainActivity.getPreview().showToast(null, "Rotation vector unavailable"); + } + } + + if (wantGravity) { + int gravitySampleRate = getSensorSampleRatePref(PreferenceKeys.GravitySampleRatePreferenceKey); + if (!mRawSensorInfo.enableSensor(Sensor.TYPE_GRAVITY, gravitySampleRate)) { + mMainActivity.getPreview().showToast(null, "Gravity unavailable"); + } + } + //mRawSensorInfo.startRecording(mMainActivity, mLastVideoDate, get Pref(), getAccelPref()) Map wantSensorRecordingMap = new HashMap<>(); wantSensorRecordingMap.put(Sensor.TYPE_ACCELEROMETER, getAccelPref()); @@ -146,7 +172,7 @@ public void startingVideo() { // Extracting sample rates from shared preferences try { mMainActivity.getPreview().showToast("Starting video with IMU recording...", true); - startImu(getAccelPref(), getGyroPref(), getMagneticPref(), mLastVideoDate); + startImu(getAccelPref(), getGyroPref(), getMagneticPref(), getGravityPref(), getRotationPref(), mLastVideoDate); // TODO: add message to strings.xml } catch (NumberFormatException e) { if (MyDebug.LOG) { diff --git a/app/src/main/java/net/sourceforge/opencamera/PreferenceKeys.java b/app/src/main/java/net/sourceforge/opencamera/PreferenceKeys.java index 4c91b33ba..1b1a3a82e 100644 --- a/app/src/main/java/net/sourceforge/opencamera/PreferenceKeys.java +++ b/app/src/main/java/net/sourceforge/opencamera/PreferenceKeys.java @@ -313,6 +313,10 @@ public static String getVideoQualityPreferenceKey(int cameraId, boolean high_spe public static final String GyroPreferenceKey = "preference_gyro"; + public static final String GravityPreferenceKey = "preference_gravity"; + + public static final String RotationPreferenceKey = "preference_rotation"; + public static final String MagnetometerPrefKey = "preference_magnetometer"; public static final String SupportsMagnetometerKey = "preference_supports_magnetometer"; @@ -329,6 +333,10 @@ public static String getVideoQualityPreferenceKey(int cameraId, boolean high_spe public static final String MagneticSampleRatePreferenceKey = "preference_magnetic_sample_rate"; + public static final String GravitySampleRatePreferenceKey = "preference_gravity_sample_rate"; + + public static final String RotationSampleRatePreferenceKey = "preference_rotation_sample_rate"; + public static final String FlashStrobeFreqPreferenceKey = "preference_strobe_freq"; public static String getVideoFPSPreferenceKey(int cameraId) { diff --git a/app/src/main/java/net/sourceforge/opencamera/sensorlogging/RawSensorInfo.java b/app/src/main/java/net/sourceforge/opencamera/sensorlogging/RawSensorInfo.java index 9b12f3c85..6bda92871 100644 --- a/app/src/main/java/net/sourceforge/opencamera/sensorlogging/RawSensorInfo.java +++ b/app/src/main/java/net/sourceforge/opencamera/sensorlogging/RawSensorInfo.java @@ -36,7 +36,9 @@ public class RawSensorInfo implements SensorEventListener { private static final String TAG = "RawSensorInfo"; private static final String CSV_SEPARATOR = ","; private static final List SENSOR_TYPES = Collections.unmodifiableList( - Arrays.asList(Sensor.TYPE_ACCELEROMETER, Sensor.TYPE_GYROSCOPE, Sensor.TYPE_MAGNETIC_FIELD) + Arrays.asList( + Sensor.TYPE_ACCELEROMETER, Sensor.TYPE_GYROSCOPE, + Sensor.TYPE_MAGNETIC_FIELD, Sensor.TYPE_GRAVITY, Sensor.TYPE_ROTATION_VECTOR) ); private static final Map SENSOR_TYPE_NAMES; static { @@ -44,6 +46,8 @@ public class RawSensorInfo implements SensorEventListener { SENSOR_TYPE_NAMES.put(Sensor.TYPE_ACCELEROMETER, "accel"); SENSOR_TYPE_NAMES.put(Sensor.TYPE_GYROSCOPE, "gyro"); SENSOR_TYPE_NAMES.put(Sensor.TYPE_MAGNETIC_FIELD, "magnetic"); + SENSOR_TYPE_NAMES.put(Sensor.TYPE_GRAVITY, "gravity"); + SENSOR_TYPE_NAMES.put(Sensor.TYPE_ROTATION_VECTOR, "rotation"); } final private SensorManager mSensorManager; diff --git a/app/src/main/java/net/sourceforge/opencamera/sensorremote/RemoteRpcRequestHandler.java b/app/src/main/java/net/sourceforge/opencamera/sensorremote/RemoteRpcRequestHandler.java index 97c5a12d7..0072f8e20 100644 --- a/app/src/main/java/net/sourceforge/opencamera/sensorremote/RemoteRpcRequestHandler.java +++ b/app/src/main/java/net/sourceforge/opencamera/sensorremote/RemoteRpcRequestHandler.java @@ -63,7 +63,9 @@ RemoteRpcResponse handleInvalidRequest() { return mResponseBuilder.error("Invalid request", mContext); } - RemoteRpcResponse handleImuRequest(long durationMillis, boolean wantAccel, boolean wantGyro, boolean wantMagnetic) { + RemoteRpcResponse handleImuRequest(long durationMillis, boolean wantAccel, + boolean wantGyro, boolean wantMagnetic, + boolean wantGravity, boolean wantRotation) { if (mRawSensorInfo != null && !mRawSensorInfo.isRecording()) { // TODO: custom rates? Callable recStartCallable = () -> { @@ -75,7 +77,7 @@ RemoteRpcResponse handleImuRequest(long durationMillis, boolean wantAccel, boole // prefEditor.apply(); Date currentDate = new Date(); - mContext.getApplicationInterface().startImu(wantAccel, wantGyro, wantMagnetic, currentDate); + mContext.getApplicationInterface().startImu(wantAccel, wantGyro, wantMagnetic, wantGravity, wantRotation, currentDate); return null; }; diff --git a/app/src/main/java/net/sourceforge/opencamera/sensorremote/RemoteRpcServer.java b/app/src/main/java/net/sourceforge/opencamera/sensorremote/RemoteRpcServer.java index 456ae0c7b..aa7a6b483 100644 --- a/app/src/main/java/net/sourceforge/opencamera/sensorremote/RemoteRpcServer.java +++ b/app/src/main/java/net/sourceforge/opencamera/sensorremote/RemoteRpcServer.java @@ -26,7 +26,7 @@ import java.util.regex.Pattern; /** - * OpenCamera Sensors server v. 0.0 + * OpenCamera Sensors server v. 0.1.2 * * Accepted message types: * - get IMU (accelerometer/gyroscope) @@ -39,7 +39,8 @@ public class RemoteRpcServer extends Thread { private static final String TAG = "RemoteRpcServer"; private static final int SOCKET_WAIT_TIME_MS = 1000; - private static final String IMU_REQUEST_REGEX = "(imu\\?duration=)(\\d+)(&accel=)(\\d)(&gyro=)(\\d)(&magnetic=)(\\d)"; + private static final String IMU_REQUEST_REGEX = + "(imu\\?duration=)(\\d+)(&accel=)(\\d)(&gyro=)(\\d)(&magnetic=)(\\d)(&gravity=)(\\d)(&rotation=)(\\d)"; private static final Pattern IMU_REQUEST_PATTERN = Pattern.compile(IMU_REQUEST_REGEX); private final Properties mConfig; @@ -77,11 +78,16 @@ private void handleRequest(String msg, PrintStream outputStream, BufferedOutputS boolean wantAccel = Integer.parseInt(imuRequestMatcher.group(4)) == 1; boolean wantGyro = Integer.parseInt(imuRequestMatcher.group(6)) == 1; boolean wantMagnetic = Integer.parseInt(imuRequestMatcher.group(8)) == 1; + boolean wantGravity = Integer.parseInt(imuRequestMatcher.group(10)) == 1; + boolean wantRotation = Integer.parseInt(imuRequestMatcher.group(12)) == 1; + if (MyDebug.LOG) { Log.d(TAG, "received IMU control request, duration = " + duration); } - RemoteRpcResponse imuResponse = mRequestHandler.handleImuRequest(duration, wantAccel, wantGyro, wantMagnetic); + RemoteRpcResponse imuResponse = mRequestHandler.handleImuRequest( + duration, wantAccel, wantGyro, wantMagnetic, wantGravity, wantRotation + ); outputStream.println(imuResponse.toString()); if (MyDebug.LOG) { diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index da66c9eb3..85e4e0915 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -125,6 +125,18 @@ android:defaultValue="true" /> + + + + + + + + + + Date: Mon, 27 Dec 2021 22:45:51 +0500 Subject: [PATCH 3/8] add orientation angles recording --- .../opencamera/ExtendedAppInterface.java | 2 + .../sensorlogging/RawSensorInfo.java | 96 +++++++++++++------ 2 files changed, 69 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/net/sourceforge/opencamera/ExtendedAppInterface.java b/app/src/main/java/net/sourceforge/opencamera/ExtendedAppInterface.java index 81a13c894..d96c1d818 100644 --- a/app/src/main/java/net/sourceforge/opencamera/ExtendedAppInterface.java +++ b/app/src/main/java/net/sourceforge/opencamera/ExtendedAppInterface.java @@ -133,12 +133,14 @@ public void startImu(boolean wantAccel, boolean wantGyro, boolean wantMagnetic, mMainActivity.getPreview().showToast(null, "GPS unavailable"); } + //mRawSensorInfo.startRecording(mMainActivity, mLastVideoDate, get Pref(), getAccelPref()) Map wantSensorRecordingMap = new HashMap<>(); wantSensorRecordingMap.put(Sensor.TYPE_ACCELEROMETER, getAccelPref()); wantSensorRecordingMap.put(Sensor.TYPE_GYROSCOPE, getGyroPref()); wantSensorRecordingMap.put(Sensor.TYPE_MAGNETIC_FIELD, getMagneticPref()); wantSensorRecordingMap.put(mRawSensorInfo.TYPE_GPS, true); + wantSensorRecordingMap.put(Sensor.TYPE_ROTATION_VECTOR, true); mRawSensorInfo.startRecording(mMainActivity, currentDate, wantSensorRecordingMap); } diff --git a/app/src/main/java/net/sourceforge/opencamera/sensorlogging/RawSensorInfo.java b/app/src/main/java/net/sourceforge/opencamera/sensorlogging/RawSensorInfo.java index f28cff2b4..4320e6255 100644 --- a/app/src/main/java/net/sourceforge/opencamera/sensorlogging/RawSensorInfo.java +++ b/app/src/main/java/net/sourceforge/opencamera/sensorlogging/RawSensorInfo.java @@ -42,14 +42,28 @@ public class RawSensorInfo implements SensorEventListener, LocationListener { private static final String CSV_SEPARATOR = ","; public static final int TYPE_GPS = 0xabcd; private static final List SENSOR_TYPES = Collections.unmodifiableList( - Arrays.asList(TYPE_GPS, Sensor.TYPE_ACCELEROMETER, Sensor.TYPE_GYROSCOPE, Sensor.TYPE_MAGNETIC_FIELD) + Arrays.asList( + TYPE_GPS, + Sensor.TYPE_ACCELEROMETER, + Sensor.TYPE_GYROSCOPE, + Sensor.TYPE_MAGNETIC_FIELD, + Sensor.TYPE_ROTATION_VECTOR + ) ); + + private final float[] accelerometerReading = new float[3]; + private final float[] magnetometerReading = new float[3]; + + private final float[] rotationMatrix = new float[9]; + private final float[] orientationAngles = new float[3]; + private static final Map SENSOR_TYPE_NAMES; static { SENSOR_TYPE_NAMES = new HashMap<>(); SENSOR_TYPE_NAMES.put(Sensor.TYPE_ACCELEROMETER, "accel"); SENSOR_TYPE_NAMES.put(Sensor.TYPE_GYROSCOPE, "gyro"); SENSOR_TYPE_NAMES.put(Sensor.TYPE_MAGNETIC_FIELD, "magnetic"); + SENSOR_TYPE_NAMES.put(Sensor.TYPE_ROTATION_VECTOR, "rotation"); SENSOR_TYPE_NAMES.put(TYPE_GPS, "location"); } @@ -131,7 +145,8 @@ public void onStatusChanged(String provider, int status, Bundle extras) { private class MyEvent { public int accuracy; - public Sensor sensor; + public int type; +// public Sensor sensor; public long timestamp; public float[] values; } @@ -140,6 +155,7 @@ private class MyEvent { public void onLocationChanged(Location location) { if( location != null && ( location.getLatitude() != 0.0d || location.getLongitude() != 0.0d ) ) { MyEvent event = new MyEvent(); + event.type = TYPE_GPS; event.timestamp = location.getElapsedRealtimeNanos(); event.values = new float[]{(float) location.getLatitude(), (float) location.getLongitude(), (float) location.getAltitude()}; _onSensorChanged(event); @@ -148,25 +164,47 @@ public void onLocationChanged(Location location) { @Override public void onSensorChanged(SensorEvent event) { - MyEvent e = new MyEvent(); - e.accuracy = event.accuracy; - e.sensor = event.sensor; - e.timestamp = event.timestamp; - e.values = event.values; - _onSensorChanged(e); + { + MyEvent e = new MyEvent(); + e.accuracy = event.accuracy; + e.type = event.sensor.getType(); + e.timestamp = event.timestamp; + e.values = event.values; + _onSensorChanged(e); + } + if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { + SensorManager.getRotationMatrix(rotationMatrix, null, accelerometerReading, magnetometerReading); + SensorManager.getOrientation(rotationMatrix, orientationAngles); + + MyEvent e = new MyEvent(); + e.accuracy = event.accuracy; + e.type = Sensor.TYPE_ROTATION_VECTOR; + e.timestamp = event.timestamp; + e.values = orientationAngles; + _onSensorChanged(e); + + } } private void _onSensorChanged(MyEvent event) { if (mIsRecording) { + if (event.type == Sensor.TYPE_ACCELEROMETER) { + System.arraycopy(event.values, 0, accelerometerReading, + 0, accelerometerReading.length); + } else if (event.type == Sensor.TYPE_MAGNETIC_FIELD) { + System.arraycopy(event.values, 0, magnetometerReading, + 0, magnetometerReading.length); + } + StringBuilder sensorData = new StringBuilder(); for (int j = 0; j < 3; j++) { sensorData.append(event.values[j]).append(CSV_SEPARATOR); } sensorData.append(event.timestamp).append("\n"); - Object sensor = mUsedSensorMap.get(event.sensor != null ? event.sensor.getType() : TYPE_GPS); + Object sensor = mUsedSensorMap.get(event.type); if (sensor != null) { - PrintWriter sensorWriter = mSensorWriterMap.get(event.sensor != null ? event.sensor.getType() : TYPE_GPS); + PrintWriter sensorWriter = mSensorWriterMap.get(event.type); if (sensorWriter != null) { sensorWriter.write(sensorData.toString()); } else { @@ -310,25 +348,25 @@ public boolean isRecording() { return mIsRecording; } - public void enableSensors(Map sampleRateMap) { - if (MyDebug.LOG) { - Log.d(TAG, "enableSensors"); - } - for (Integer sensorType : mUsedSensorMap.keySet()) { - Integer sampleRate = sampleRateMap.get(sensorType); - if (sampleRate == null) { - // Assign default value if not provided - sampleRate = 0; - } - - if (sensorType != null) { - enableSensor(sensorType, sampleRate); - } - - } - /*enableSensor(Sensor.TYPE_GYROSCOPE, gyroSampleRate); - enableSensor(Sensor.TYPE_ACCELEROMETER, accelSampleRate);*/ - } +// public void enableSensors(Map sampleRateMap) { +// if (MyDebug.LOG) { +// Log.d(TAG, "enableSensors"); +// } +// for (Integer sensorType : mUsedSensorMap.keySet()) { +// Integer sampleRate = sampleRateMap.get(sensorType); +// if (sampleRate == null) { +// // Assign default value if not provided +// sampleRate = 0; +// } +// +// if (sensorType != null) { +// enableSensor(sensorType, sampleRate); +// } +// +// } +// /*enableSensor(Sensor.TYPE_GYROSCOPE, gyroSampleRate); +// enableSensor(Sensor.TYPE_ACCELEROMETER, accelSampleRate);*/ +// } /** From b78f34fb6be32b74cf0ed6c68d8bc823e6812696 Mon Sep 17 00:00:00 2001 From: azaat Date: Tue, 28 Dec 2021 04:36:51 +0300 Subject: [PATCH 4/8] Put new sensors to the parameters of startRecording --- .../java/net/sourceforge/opencamera/ExtendedAppInterface.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/net/sourceforge/opencamera/ExtendedAppInterface.java b/app/src/main/java/net/sourceforge/opencamera/ExtendedAppInterface.java index eb5c7824a..6995ff399 100644 --- a/app/src/main/java/net/sourceforge/opencamera/ExtendedAppInterface.java +++ b/app/src/main/java/net/sourceforge/opencamera/ExtendedAppInterface.java @@ -160,6 +160,8 @@ public void startImu( wantSensorRecordingMap.put(Sensor.TYPE_ACCELEROMETER, getAccelPref()); wantSensorRecordingMap.put(Sensor.TYPE_GYROSCOPE, getGyroPref()); wantSensorRecordingMap.put(Sensor.TYPE_MAGNETIC_FIELD, getMagneticPref()); + wantSensorRecordingMap.put(Sensor.TYPE_GRAVITY, getGravityPref()); + wantSensorRecordingMap.put(Sensor.TYPE_ROTATION_VECTOR, getRotationPref()); mRawSensorInfo.startRecording(mMainActivity, currentDate, wantSensorRecordingMap); } From ce667f9c65938b753b8c6155d585c3a40ccc4ccd Mon Sep 17 00:00:00 2001 From: azaat Date: Thu, 30 Dec 2021 02:56:20 +0300 Subject: [PATCH 5/8] Cleanup after merge --- .../java/net/sourceforge/opencamera/ExtendedAppInterface.java | 4 ++-- .../sourceforge/opencamera/sensorlogging/RawSensorInfo.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/net/sourceforge/opencamera/ExtendedAppInterface.java b/app/src/main/java/net/sourceforge/opencamera/ExtendedAppInterface.java index c46530182..bb93a2f8b 100644 --- a/app/src/main/java/net/sourceforge/opencamera/ExtendedAppInterface.java +++ b/app/src/main/java/net/sourceforge/opencamera/ExtendedAppInterface.java @@ -141,7 +141,7 @@ public void startImu( } } - if (!mRawSensorInfo.enableSensor(mRawSensorInfo.TYPE_GPS, 0)) { + if (!mRawSensorInfo.enableSensor(RawSensorInfo.TYPE_GPS, 0)) { mMainActivity.getPreview().showToast(null, "GPS unavailable"); } @@ -168,7 +168,7 @@ public void startImu( wantSensorRecordingMap.put(Sensor.TYPE_MAGNETIC_FIELD, getMagneticPref()); wantSensorRecordingMap.put(Sensor.TYPE_GRAVITY, getGravityPref()); wantSensorRecordingMap.put(Sensor.TYPE_ROTATION_VECTOR, getRotationPref()); - wantSensorRecordingMap.put(mRawSensorInfo.TYPE_GPS, true); + wantSensorRecordingMap.put(RawSensorInfo.TYPE_GPS, true); mRawSensorInfo.startRecording(mMainActivity, currentDate, wantSensorRecordingMap); } diff --git a/app/src/main/java/net/sourceforge/opencamera/sensorlogging/RawSensorInfo.java b/app/src/main/java/net/sourceforge/opencamera/sensorlogging/RawSensorInfo.java index 03ea1f0f2..c21e49e66 100644 --- a/app/src/main/java/net/sourceforge/opencamera/sensorlogging/RawSensorInfo.java +++ b/app/src/main/java/net/sourceforge/opencamera/sensorlogging/RawSensorInfo.java @@ -37,7 +37,7 @@ * Assumes all the used sensor types are motion or position sensors * and output [x, y, z] values -- the class should be updated if that changes */ -public class RawSensorInfo implements SensorEventListener { +public class RawSensorInfo implements SensorEventListener, LocationListener { private static final String TAG = "RawSensorInfo"; private static final String CSV_SEPARATOR = ","; public static final int TYPE_GPS = 0xabcd; From 56815f16662dee947839fe8f6ddc7298e6a83df1 Mon Sep 17 00:00:00 2001 From: azaat Date: Thu, 30 Dec 2021 07:21:11 +0300 Subject: [PATCH 6/8] Update location permisson for android 10 --- app/src/main/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1c5451007..2eccc300e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -16,7 +16,7 @@ - + From 636d7d94f300a55fd249fb332fb51c4297de0807 Mon Sep 17 00:00:00 2001 From: azaat Date: Thu, 30 Dec 2021 07:28:53 +0300 Subject: [PATCH 7/8] Add formats of new data --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 638f3d7b1..7dc42d788 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,9 @@ This project is based on [Open Camera](https://opencamera.org.uk/) — a popul -```{VIDEO_NAME}_gyro.csv```, data format: ```X-data, Y-data, Z-data, timestamp (ns)``` - ```{VIDEO_NAME}_accel.csv```, data format: ```X-data, Y-data, Z-data, timestamp (ns)``` - ```{VIDEO_NAME}_magnetic.csv```, data format: ```X-data, Y-data, Z-data, timestamp (ns)``` + - ```{VIDEO_NAME}_location```, data format: ```latitude, lognitude, altitude, timestamp (ns)``` + - ```{VIDEO_NAME}_rotation```, data format: ```azimuth, pitch, roll, timestamp (ns)``` + - ```{VIDEO_NAME}_gravity```, data format: ```X-data, Y-data, Z-data, timestamp (ns)``` - ```{VIDEO_NAME}_timestamps.csv```, data format: ```timestamp (ns)``` - ```{VIDEO_NAME}_flash.csv```, data format: ```timestamp (ns)``` (timestamps of when the flash fired) From 0f6a6ea4ef07cea4aa84ff216ee45b03618f0aa2 Mon Sep 17 00:00:00 2001 From: azaat Date: Tue, 25 Jan 2022 16:16:50 +0300 Subject: [PATCH 8/8] Change RemoteControl.py to support new sensors --- api_client/async_imu_example.py | 4 ++-- api_client/src/RemoteControl.py | 17 +++++++++++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/api_client/async_imu_example.py b/api_client/async_imu_example.py index f85e40061..1ed2607f4 100644 --- a/api_client/async_imu_example.py +++ b/api_client/async_imu_example.py @@ -9,13 +9,13 @@ def main(): remote = RemoteControl(HOST) with ThreadPoolExecutor(max_workers=1) as executor: - future = executor.submit(remote.get_imu, 10000, True, False) + future = executor.submit(remote.get_imu, 10000, True, True, False, False, False) # Do something else print("doing other stuff...") time.sleep(10) print("done doing other stuff") # Get result when needed - accel_data, gyro_data = future.result() + accel_data, gyro_data, _, _ = future.result() # Process result somehow (here just file output) print("Accelerometer data length: %d" % len(accel_data)) with open("accel.csv", "w+") as accel: diff --git a/api_client/src/RemoteControl.py b/api_client/src/RemoteControl.py index b57bb940c..ab1ac5c0b 100644 --- a/api_client/src/RemoteControl.py +++ b/api_client/src/RemoteControl.py @@ -6,9 +6,9 @@ BUFFER_SIZE = 4096 PROPS_PATH = '../app/src/main/assets/server_config.properties' SUPPORTED_SERVER_VERSIONS = [ - 'v.0.1.1' + 'v.0.1.2' ] -NUM_SENSORS = 3 +NUM_SENSORS = 5 class RemoteControl: """ @@ -40,18 +40,23 @@ def get_imu(self, duration_ms, want_accel, want_gyro, want_magnetic): :param want_accel: (boolean) request accelerometer recording :param want_gyro: (boolean) request gyroscope recording :param want_gyro: (boolean) request magnetometer recording - :return: Tuple (accel_data, gyro_data, magnetic_data) - csv data strings + :param want_gravity: (boolean) request gravity recording + :param want_rotation: (boolean) request rotation recording + :return: Tuple (accel_data, gyro_data, magnetic_data, gravity_data, rotation_data) - csv data strings If one of the sensors wasn't requested, the corresponding data is None """ accel = int(want_accel) gyro = int(want_gyro) magnetic = int(want_magnetic) status, socket_file = self._send_and_get_response_status( - 'imu?duration=%d&accel=%d&gyro=%d&magnetic=%d\n' % (duration_ms, accel, gyro, magnetic) + 'imu?duration=%d&accel=%d&gyro=%d&magnetic=%d&gravity=%d&rotation=%d\n' + % (duration_ms, accel, gyro, magnetic, gravity, rotation) ) accel_data = None gyro_data = None magnetic_data = None + gravity_data = None + rotation_data = None for i in range(NUM_SENSORS): # read filename or end marker @@ -74,6 +79,10 @@ def get_imu(self, duration_ms, want_accel, want_gyro, want_magnetic): gyro_data = data elif msg.endswith("magnetic.csv"): magnetic_data = data + elif msg.endswith("gravity.csv"): + gravity_data = data + elif msg.endswith("rotation.csv"): + rotation_data = data socket_file.close() return accel_data, gyro_data, magnetic_data