diff --git a/android/ConductorsPhone/app/build.gradle b/android/ConductorsPhone/app/build.gradle
index 993b6df..550f728 100644
--- a/android/ConductorsPhone/app/build.gradle
+++ b/android/ConductorsPhone/app/build.gradle
@@ -11,8 +11,8 @@ android {
minSdkVersion 24
targetSdkVersion 26
//sdk 2 | product version 3 | build num 2 | multi-apk 2
- versionCode 260120100
- versionName "0.1.2"
+ versionCode 260130300
+ versionName "0.1.3.2"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
@@ -33,12 +33,12 @@ dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
- implementation 'com.google.android.support:wearable:2.1.0'
+ 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'
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support:support-v4:26.1.0'
implementation 'com.android.support:recyclerview-v7:26.1.0'
- compileOnly 'com.google.android.wearable:wearable:2.1.0'
+ compileOnly 'com.google.android.wearable:wearable:2.2.0'
}
diff --git a/android/ConductorsPhone/app/src/main/AndroidManifest.xml b/android/ConductorsPhone/app/src/main/AndroidManifest.xml
index 4c4f298..2f506e6 100644
--- a/android/ConductorsPhone/app/src/main/AndroidManifest.xml
+++ b/android/ConductorsPhone/app/src/main/AndroidManifest.xml
@@ -3,13 +3,12 @@
package="de.tonifetzer.conductorswatch">
-
diff --git a/android/ConductorsPhone/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/ConductorsPhone/app/src/main/res/mipmap-hdpi/ic_launcher.png
index a2f5908..3ed96df 100644
Binary files a/android/ConductorsPhone/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/android/ConductorsPhone/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/android/ConductorsPhone/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/ConductorsPhone/app/src/main/res/mipmap-mdpi/ic_launcher.png
index ff10afd..ad5136b 100644
Binary files a/android/ConductorsPhone/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/android/ConductorsPhone/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/android/ConductorsPhone/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/ConductorsPhone/app/src/main/res/mipmap-xhdpi/ic_launcher.png
index dcd3cd8..0989114 100644
Binary files a/android/ConductorsPhone/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/android/ConductorsPhone/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/android/ConductorsPhone/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/ConductorsPhone/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
index 8ca12fe..a46541b 100644
Binary files a/android/ConductorsPhone/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/android/ConductorsPhone/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/android/ConductorsPhone/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/ConductorsPhone/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
index b824ebd..2f2c97c 100644
Binary files a/android/ConductorsPhone/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/android/ConductorsPhone/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/android/ConductorsWatch/app/build.gradle b/android/ConductorsWatch/app/build.gradle
index 129c2f4..51b4425 100644
--- a/android/ConductorsWatch/app/build.gradle
+++ b/android/ConductorsWatch/app/build.gradle
@@ -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'
}
diff --git a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/Estimator.java b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/Estimator.java
index 5bb93f0..c63e38e 100644
--- a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/Estimator.java
+++ b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/Estimator.java
@@ -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();
diff --git a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/bpmEstimation/AccelerometerWindowBuffer.java b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/bpmEstimation/AccelerometerWindowBuffer.java
index 5f666a9..f9ec264 100644
--- a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/bpmEstimation/AccelerometerWindowBuffer.java
+++ b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/bpmEstimation/AccelerometerWindowBuffer.java
@@ -12,35 +12,49 @@ public class AccelerometerWindowBuffer extends ArrayList {
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;
}
diff --git a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/bpmEstimation/BpmEstimator.java b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/bpmEstimation/BpmEstimator.java
index e9dac56..824687e 100644
--- a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/bpmEstimation/BpmEstimator.java
+++ b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/bpmEstimation/BpmEstimator.java
@@ -58,13 +58,16 @@ public class BpmEstimator {
//just look at the newest 512 samples
//List 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();
diff --git a/android/ConductorsWatch/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/ConductorsWatch/app/src/main/res/mipmap-hdpi/ic_launcher.png
index cde69bc..f6efd77 100644
Binary files a/android/ConductorsWatch/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/android/ConductorsWatch/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/android/ConductorsWatch/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/ConductorsWatch/app/src/main/res/mipmap-mdpi/ic_launcher.png
index c133a0c..004197e 100644
Binary files a/android/ConductorsWatch/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/android/ConductorsWatch/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/android/ConductorsWatch/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/ConductorsWatch/app/src/main/res/mipmap-xhdpi/ic_launcher.png
index bfa42f0..ec1d0fe 100644
Binary files a/android/ConductorsWatch/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/android/ConductorsWatch/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/android/ConductorsWatch/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/ConductorsWatch/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
index 324e72c..10388b5 100644
Binary files a/android/ConductorsWatch/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/android/ConductorsWatch/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/android/ConductorsWatch/build.gradle b/android/ConductorsWatch/build.gradle
index e6b32bc..3c64aec 100644
--- a/android/ConductorsWatch/build.gradle
+++ b/android/ConductorsWatch/build.gradle
@@ -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()
}
}
diff --git a/android/ConductorsWatch/gradle.properties b/android/ConductorsWatch/gradle.properties
index aac7c9b..7abc0b5 100644
--- a/android/ConductorsWatch/gradle.properties
+++ b/android/ConductorsWatch/gradle.properties
@@ -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
diff --git a/java/src/main/java/Main.java b/java/src/main/java/Main.java
index 659a841..f5f124a 100644
--- a/java/src/main/java/Main.java
+++ b/java/src/main/java/Main.java
@@ -16,7 +16,8 @@ import java.util.stream.IntStream;
public class Main {
public static void main(String [ ] args) {
- File folder = new File("/home/toni/Documents/programme/dirigent/measurements/wearR");
+ //File folder = new File("/home/toni/Documents/programme/dirigent/measurements/lgWear");
+ File folder = new File("/home/toni/Documents/programme/dirigent/measurements/peter_failed");
File[] listOfFiles = folder.listFiles();
Utils.ShowPNG windowRaw = new Utils.ShowPNG();
@@ -30,7 +31,8 @@ public class Main {
for (File file : listOfFiles) {
if (file.isFile() && file.getName().contains(".csv")) {
- AccelerometerWindowBuffer accWindowBuffer = new AccelerometerWindowBuffer(1024, 256);
+ //TODO: mach Fenster genau 6 sekunden groß. Egal wie viele Samples.
+ AccelerometerWindowBuffer accWindowBuffer = new AccelerometerWindowBuffer(6000, 1500);
BpmEstimator bpmEstimator = new BpmEstimator(accWindowBuffer, 0, 5000);
//read the file line by line
@@ -40,7 +42,7 @@ public class Main {
String[] measurement = line.split(";");
//if linear acc
- if(measurement[1].equals("2")){
+ if(measurement[1].equals("10")){
long ts = Long.parseLong(measurement[0]);
double x = Double.parseDouble(measurement[2]);
double y = Double.parseDouble(measurement[3]);
@@ -54,8 +56,9 @@ public class Main {
double curBpm = bpmEstimator.estimate();
//System.out.println("BPM: " + curBpm);
-
- AccelerometerInterpolator acInterp = new AccelerometerInterpolator(accWindowBuffer, 5);
+ double sampleRate = 20;
+ AccelerometerInterpolator acInterp = new AccelerometerInterpolator(accWindowBuffer, sampleRate);
+ int peakWidth = (int) Math.round(250 / sampleRate);
//print raw x,y,z
double[] dTs = IntStream.range(0, accWindowBuffer.getTs().length).mapToDouble(i -> accWindowBuffer.getTs()[i]).toArray();
@@ -70,9 +73,9 @@ public class Main {
windowRaw.set(plotRaw.draw());
//auto corr
- double[] xAutoCorr = new AutoCorrelation(acInterp.getX(), 512).getCorr();
- double[] yAutoCorr = new AutoCorrelation(acInterp.getY(), 512).getCorr();
- double[] zAutoCorr = new AutoCorrelation(acInterp.getZ(), 512).getCorr();
+ double[] xAutoCorr = new AutoCorrelation(acInterp.getX(), accWindowBuffer.size()).getCorr();
+ double[] yAutoCorr = new AutoCorrelation(acInterp.getY(), accWindowBuffer.size()).getCorr();
+ double[] zAutoCorr = new AutoCorrelation(acInterp.getZ(), accWindowBuffer.size()).getCorr();
//print autocorr
int[] tmp = IntStream.rangeClosed(-((xAutoCorr.length - 1)/2), ((xAutoCorr.length - 1)/2)).toArray();
@@ -86,10 +89,11 @@ public class Main {
windowAuto.set(plotCorr.draw());
- Peaks pX = new Peaks(xAutoCorr, 50, 0.1f, 0, false);
+ Peaks pX = new Peaks(xAutoCorr, peakWidth, 0.1f, 0, false);
+ int xOffset = xAutoCorr.length / 2;
LinkedList peaksX = pX.getPeaksIdx();
- double[] dPeaksXX = IntStream.range(0, peaksX.size()).mapToDouble(i -> (peaksX.get(i) - 512)).toArray();//peaks.stream().mapToDouble(i->i).toArray();
+ double[] dPeaksXX = IntStream.range(0, peaksX.size()).mapToDouble(i -> (peaksX.get(i) - xOffset)).toArray();//peaks.stream().mapToDouble(i->i).toArray();
double[] dPeaksXY = IntStream.range(0, peaksX.size()).mapToDouble(i -> (xAutoCorr[peaksX.get(i)])).toArray();
Plot plotPeaksX = Plot.plot(Plot.plotOpts().
title("Peak Detection on X").
@@ -100,10 +104,11 @@ public class Main {
windowPeaksX.set(plotPeaksX.draw());
- Peaks pY = new Peaks(yAutoCorr, 50, 0.1f, 0, false);
+ Peaks pY = new Peaks(yAutoCorr, peakWidth, 0.1f, 0, false);
+ int yOffset = yAutoCorr.length / 2;
LinkedList peaksY = pY.getPeaksIdx();
- double[] dPeaksYX = IntStream.range(0, peaksY.size()).mapToDouble(i -> (peaksY.get(i) - 512)).toArray();//peaks.stream().mapToDouble(i->i).toArray();
+ double[] dPeaksYX = IntStream.range(0, peaksY.size()).mapToDouble(i -> (peaksY.get(i) - yOffset)).toArray();//peaks.stream().mapToDouble(i->i).toArray();
double[] dPeaksYY = IntStream.range(0, peaksY.size()).mapToDouble(i -> (yAutoCorr[peaksY.get(i)])).toArray();
Plot plotPeaksY = Plot.plot(Plot.plotOpts().
title("Peak Detection on Y").
@@ -114,10 +119,11 @@ public class Main {
windowPeaksY.set(plotPeaksY.draw());
- Peaks pZ = new Peaks(zAutoCorr, 50, 0.1f, 0, false);
+ Peaks pZ = new Peaks(zAutoCorr, peakWidth, 0.1f, 0, false);
+ int zOffset = zAutoCorr.length / 2;
LinkedList peaksZ = pZ.getPeaksIdx();
- double[] dPeaksZX = IntStream.range(0, peaksZ.size()).mapToDouble(i -> (peaksZ.get(i) - 512)).toArray();//peaks.stream().mapToDouble(i->i).toArray();
+ double[] dPeaksZX = IntStream.range(0, peaksZ.size()).mapToDouble(i -> (peaksZ.get(i) - zOffset)).toArray();//peaks.stream().mapToDouble(i->i).toArray();
double[] dPeaksZY = IntStream.range(0, peaksZ.size()).mapToDouble(i -> (zAutoCorr[peaksZ.get(i)])).toArray();
Plot plotPeaksZ = Plot.plot(Plot.plotOpts().
title("Peak Detection on Z").
@@ -142,10 +148,10 @@ public class Main {
}
// line is not visible here.
- double meanBPM = bpmEstimator.getMeanBpm();
- double medianBPM = bpmEstimator.getMedianBPM();
+ //double meanBPM = bpmEstimator.getMeanBpm();
+ //double medianBPM = bpmEstimator.getMedianBPM();
//System.out.println("MEAN BPM: " + Math.round(meanBPM));
- System.out.println("MEDIAN BPM: " + Math.round(medianBPM));
+ //System.out.println("MEDIAN BPM: " + Math.round(medianBPM));
} catch (IOException e) {
e.printStackTrace();
diff --git a/java/src/main/java/bpmEstimation/AccelerometerWindowBuffer.java b/java/src/main/java/bpmEstimation/AccelerometerWindowBuffer.java
index 889ce95..09103a8 100644
--- a/java/src/main/java/bpmEstimation/AccelerometerWindowBuffer.java
+++ b/java/src/main/java/bpmEstimation/AccelerometerWindowBuffer.java
@@ -8,14 +8,14 @@ import java.util.ArrayList;
*/
public class AccelerometerWindowBuffer extends ArrayList {
- private static int mWindowSize;
- private static int mOverlapSize;
- private int mOverlapCounter;
+ private static int mWindowSize; // in ms
+ private static int mOverlapSize; // in ms
+ private long mOverlapCounter;
public AccelerometerWindowBuffer(int windowSize, int overlap){
mWindowSize = windowSize;
mOverlapSize = overlap;
- mOverlapCounter = 1;
+ mOverlapCounter = 0;
}
//TODO: add exception handling. falseArgument if ad has no numeric x,y,z
@@ -26,20 +26,33 @@ public class AccelerometerWindowBuffer extends ArrayList {
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;
}
diff --git a/java/src/main/java/bpmEstimation/BpmEstimator.java b/java/src/main/java/bpmEstimation/BpmEstimator.java
index ac90867..8440bdd 100644
--- a/java/src/main/java/bpmEstimation/BpmEstimator.java
+++ b/java/src/main/java/bpmEstimation/BpmEstimator.java
@@ -51,13 +51,15 @@ public class BpmEstimator {
AccelerometerInterpolator interp = new AccelerometerInterpolator(mBuffer, sampleRate);
- double[] xAutoCorr = new AutoCorrelation(interp.getX(), 1024).getCorr();
- double[] yAutoCorr = new AutoCorrelation(interp.getY(), 1024).getCorr();
- double[] zAutoCorr = new AutoCorrelation(interp.getZ(), 1024).getCorr();
+ double[] xAutoCorr = new AutoCorrelation(interp.getX(), mBuffer.size()).getCorr();
+ double[] yAutoCorr = new AutoCorrelation(interp.getY(), mBuffer.size()).getCorr();
+ double[] zAutoCorr = new AutoCorrelation(interp.getZ(), mBuffer.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));
@@ -80,9 +82,12 @@ 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();
+
+ mBuffer.clear();
+ mMvg.clear();
mResetCounter = 0;
}
return -1;
diff --git a/java/src/main/java/utilities/MovingFilter.java b/java/src/main/java/utilities/MovingFilter.java
index e4f883d..5263ed9 100644
--- a/java/src/main/java/utilities/MovingFilter.java
+++ b/java/src/main/java/utilities/MovingFilter.java
@@ -30,4 +30,9 @@ public class MovingFilter {
public double getMedian() {
return Utils.median(mSamples);
}
+
+ public void clear(){
+ mSamples.clear();
+ mTotal = 0d;
+ }
}
diff --git a/matlab/AutoCorrMethodNew_Watch.m b/matlab/AutoCorrMethodNew_Watch.m
index 90f9c5a..ed967e9 100644
--- a/matlab/AutoCorrMethodNew_Watch.m
+++ b/matlab/AutoCorrMethodNew_Watch.m
@@ -42,7 +42,8 @@
%files = dir(fullfile('../../measurements/lgWear/', '*.csv'));
-files = dir(fullfile('../../measurements/wearR/', '*.csv'));
+%files = dir(fullfile('../../measurements/wearR/', '*.csv'));
+files = dir(fullfile('../../measurements/peter_failed/', '*.csv'));
for file = files'
@@ -51,7 +52,7 @@ for file = files'
%draw the raw acc data
m_idx = [];
- m_idx = (measurements(:,2)==2);
+ m_idx = (measurements(:,2)==10);
m = measurements(m_idx, :);
%Interpolate to generate a constant sample rate to 250hz (4ms per sample)
@@ -76,13 +77,15 @@ for file = files'
figure(3);
plot(m(:,1),m(:,5)) %z
legend("z", "location", "eastoutside");
+
+ waitforbuttonpress();
%save timestamps
timestamps = m(:,1);
data = m(:,3); %only z
%TODO: Different window sizes for periods under 16.3 s
- window_size = 4096; %about 2 seconds using 2000hz, 16.3 s using 250hz
+ window_size = 2048; %about 2 seconds using 2000hz, 16.3 s using 250hz
overlap = 256;
bpm_per_window_ms = [];
bpm_per_window = [];