puhh. this is a big commit
- change the complete file sending / receiving process between phone and watch, we now use channels instead of simple messages. this is recommentad by google, due to some changes in google play services. - made some smaller changes in the ui, for file saving and saving of sensordata for evaluation purposes - edited the manifest and gradle script for play store. - made some change for a better performance for he huawei watch
@@ -9,8 +9,8 @@ android {
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 26
|
||||
//sdk 2 | product version 3 | build num 2 | multi-apk 2
|
||||
versionCode 260120101
|
||||
versionName "0.1.2"
|
||||
versionCode 260130301
|
||||
versionName "0.1.3.2"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
@@ -22,6 +22,7 @@ android {
|
||||
wear1 {
|
||||
dimension "minSdk"
|
||||
// Use the defaultConfig value
|
||||
minSdkVersion 23
|
||||
}
|
||||
wear2 {
|
||||
dimension "minSdk"
|
||||
@@ -36,8 +37,8 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation 'com.google.android.support:wearable:2.1.0'
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
implementation 'com.google.android.support:wearable:2.2.0'
|
||||
implementation 'com.google.android.gms:play-services-wearable:11.8.0'
|
||||
implementation 'com.android.support:percent:26.1.0'
|
||||
implementation 'com.android.support:animated-vector-drawable:26.1.0'
|
||||
@@ -45,6 +46,6 @@ dependencies {
|
||||
implementation 'com.android.support:support-v4:26.1.0'
|
||||
implementation 'com.android.support:recyclerview-v7:26.1.0'
|
||||
implementation 'com.android.support:wear:26.1.0'
|
||||
compileOnly 'com.google.android.wearable:wearable:2.1.0'
|
||||
compileOnly 'com.google.android.wearable:wearable:2.2.0'
|
||||
compile 'com.github.wendykierp:JTransforms:3.1'
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class Estimator implements SensorEventListener {
|
||||
|
||||
private SensorManager mSensorManager;
|
||||
private Sensor mAccelerometer;
|
||||
private Sensor mGyroscope;
|
||||
private Sensor mRawAccelerometer;
|
||||
private Context mContext;
|
||||
private AccelerometerWindowBuffer mAccelerometerWindowBuffer;
|
||||
private BpmEstimator mBpmEstimator;
|
||||
@@ -50,11 +50,11 @@ public class Estimator implements SensorEventListener {
|
||||
|
||||
mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
|
||||
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
|
||||
mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
|
||||
mRawAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
|
||||
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_FASTEST);
|
||||
mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_FASTEST);
|
||||
mSensorManager.registerListener(this, mRawAccelerometer, SensorManager.SENSOR_DELAY_FASTEST);
|
||||
|
||||
mAccelerometerWindowBuffer = new AccelerometerWindowBuffer(1024, 256);
|
||||
mAccelerometerWindowBuffer = new AccelerometerWindowBuffer(6000, 1500);
|
||||
mBpmEstimator = new BpmEstimator(mAccelerometerWindowBuffer, 0, 5000);
|
||||
|
||||
mTimer.scheduleAtFixedRate(new TimerTask() {
|
||||
@@ -110,9 +110,8 @@ public class Estimator implements SensorEventListener {
|
||||
mByteStreamWriterAcc.reset();
|
||||
}
|
||||
|
||||
if (se.sensor.getType() == Sensor.TYPE_GYROSCOPE) {
|
||||
//TODO: Rename AccelerometerData to SensorData3D
|
||||
mByteStreamWriterGyro.writeSensor3D(Sensor.TYPE_GYROSCOPE, se.values[0], se.values[1], se.values[2]);
|
||||
if (se.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
|
||||
mByteStreamWriterGyro.writeSensor3D(Sensor.TYPE_ACCELEROMETER, se.values[0], se.values[1], se.values[2]);
|
||||
|
||||
mStreamer.sendByteArray(mByteStreamWriterGyro.getByteArray());
|
||||
mByteStreamWriterGyro.reset();
|
||||
|
||||
@@ -12,35 +12,49 @@ public class AccelerometerWindowBuffer extends ArrayList<AccelerometerData> {
|
||||
private int mOverlapSize;
|
||||
private int mOverlapCounter;
|
||||
|
||||
public AccelerometerWindowBuffer(int windowSize, int overlap){
|
||||
mWindowSize = windowSize;
|
||||
mOverlapSize = overlap;
|
||||
mOverlapCounter = 1;
|
||||
public AccelerometerWindowBuffer(int windowSize_ms, int overlap_ms){
|
||||
mWindowSize = windowSize_ms;
|
||||
mOverlapSize = overlap_ms;
|
||||
mOverlapCounter = 0;
|
||||
}
|
||||
|
||||
//TODO: add exception handling. falseArgument if ad has no numeric x,y,z
|
||||
public boolean add(AccelerometerData ad){
|
||||
synchronized (this){
|
||||
|
||||
//do not add duplicates!
|
||||
if (!isEmpty() && getYongest().equals(ad)) {
|
||||
if(!isEmpty() && getYongest().equals(ad)){
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean r = super.add(ad);
|
||||
if (size() > mWindowSize) {
|
||||
removeRange(0, size() - mWindowSize);
|
||||
// current - last to increment overlap time
|
||||
if(!isEmpty()){
|
||||
mOverlapCounter += ad.ts - getYongest().ts;
|
||||
}
|
||||
|
||||
++mOverlapCounter;
|
||||
//add element
|
||||
boolean r = super.add(ad);
|
||||
if ((getYongest().ts - getOldest().ts) > mWindowSize){
|
||||
|
||||
long oldestTime = getYongest().ts - mWindowSize;
|
||||
for(int i = 0; i < size(); ++i) {
|
||||
if (get(i).ts > oldestTime) {
|
||||
break;
|
||||
}
|
||||
remove(i);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isNextWindowReady(){
|
||||
if((size() > mWindowSize / 2) && mOverlapCounter > mOverlapSize){
|
||||
mOverlapCounter = 1;
|
||||
if(!isEmpty()){
|
||||
if(((getYongest().ts - getOldest().ts) > mWindowSize / 2) && mOverlapCounter > mOverlapSize){
|
||||
mOverlapCounter = 0;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -58,13 +58,16 @@ public class BpmEstimator {
|
||||
//just look at the newest 512 samples
|
||||
//List<AccelerometerData> subBuffer = mBuffer.subList(mBuffer.size() - 512, mBuffer.size());
|
||||
|
||||
double[] xAutoCorr = new AutoCorrelation(interp.getX(), 512).getCorr();
|
||||
double[] yAutoCorr = new AutoCorrelation(interp.getY(), 512).getCorr();
|
||||
double[] zAutoCorr = new AutoCorrelation(interp.getZ(), 512).getCorr();
|
||||
double[] xAutoCorr = new AutoCorrelation(interp.getX(), fixedWindow.size()).getCorr();
|
||||
double[] yAutoCorr = new AutoCorrelation(interp.getY(), fixedWindow.size()).getCorr();
|
||||
double[] zAutoCorr = new AutoCorrelation(interp.getZ(), fixedWindow.size()).getCorr();
|
||||
|
||||
Peaks pX = new Peaks(xAutoCorr, 50, 0.1f, 0, false);
|
||||
Peaks pY = new Peaks(yAutoCorr, 50, 0.1f, 0, false);
|
||||
Peaks pZ = new Peaks(zAutoCorr, 50, 0.1f, 0, false);
|
||||
|
||||
//find a peak within range of 250 ms
|
||||
int peakWidth = (int) Math.round(250 / sampleRate);
|
||||
Peaks pX = new Peaks(xAutoCorr, peakWidth, 0.1f, 0, false);
|
||||
Peaks pY = new Peaks(yAutoCorr, peakWidth, 0.1f, 0, false);
|
||||
Peaks pZ = new Peaks(zAutoCorr, peakWidth, 0.1f, 0, false);
|
||||
|
||||
mBpmHistory_X.add(pX.getBPM(sampleRate));
|
||||
mBpmHistory_Y.add(pY.getBPM(sampleRate));
|
||||
@@ -88,7 +91,7 @@ public class BpmEstimator {
|
||||
//mResetCounter = 0;
|
||||
}
|
||||
else {
|
||||
int resetAfter = (int) Math.round(mResetLimit_ms / (mBuffer.getOverlapSize() * sampleRate));
|
||||
int resetAfter = (int) Math.round(mResetLimit_ms / (mBuffer.getOverlapSize()));
|
||||
if(++mResetCounter > resetAfter){
|
||||
mBpmHistory.clear();
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 12 KiB |
@@ -3,8 +3,11 @@
|
||||
buildscript {
|
||||
|
||||
repositories {
|
||||
google()
|
||||
maven {
|
||||
url "https://maven.google.com"
|
||||
}
|
||||
jcenter()
|
||||
google()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.0.1'
|
||||
@@ -17,8 +20,11 @@ buildscript {
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
maven {
|
||||
url "https://maven.google.com"
|
||||
}
|
||||
jcenter()
|
||||
google()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs=-Xmx1536m
|
||||
android.enableD8=true
|
||||
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
|
||||