diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 9b84410..2c0bf3b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -3,7 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"
package="uk.org.openseizuredetector"
android:versionCode="115"
- android:versionName="4.1.3n">
+ android:versionName="4.1.3m">
diff --git a/app/src/main/java/uk/org/openseizuredetector/CircBuf.java b/app/src/main/java/uk/org/openseizuredetector/CircBuf.java
new file mode 100644
index 0000000..27cb597
--- /dev/null
+++ b/app/src/main/java/uk/org/openseizuredetector/CircBuf.java
@@ -0,0 +1,99 @@
+package uk.org.openseizuredetector;
+
+import android.util.Log;
+
+import java.util.ArrayList;
+
+public class CircBuf {
+ /*
+ * A circular buffer used to calculate rolling averages
+ * Based loosely on https://gist.github.com/hardik-vala/dc2d19fa7c5108536fbbff96b4fcf105
+ */
+ private final static String TAG = "CircBuf";
+
+ private double[] mBuff;
+ private double mErrVal;
+ private int mBuffLen;
+ private int mHead;
+ private int mTail;
+ private boolean mIsFull;
+
+ public CircBuf(int n, double errVal) {
+ /**
+ * Create a circular buffer of doubles, of length n members.
+ */
+ Log.i(TAG, "CircBuf Constructor");
+ mBuff = new double[n];
+ mBuffLen = n;
+ mErrVal = errVal;
+ mHead = 0;
+ mTail = 0;
+ mIsFull = false;
+ }
+
+ public void add(double val) {
+ /**
+ * Add value val to the circular buffer.
+ */
+ Log.d(TAG,"add() - before: mHead="+mHead+", mTail="+mTail);
+ //System.out.println(TAG+" add() - before: mHead="+mHead+", mTail="+mTail);
+ if (mIsFull)
+ mHead = (mHead + 1) % mBuffLen;
+
+ mBuff[mTail] = val;
+ mTail = (mTail + 1) % mBuffLen;
+ if (mTail == mHead)
+ mIsFull = true;
+ Log.d(TAG,"add() - after: mHead="+mHead+", mTail="+mTail);
+ //System.out.println(TAG+" add() - before: mHead="+mHead+", mTail="+mTail);
+ }
+
+ public int getNumVals() {
+ int numElements;
+ if (mIsFull) {
+ numElements = mBuffLen;
+ } else {
+ // Not sure if this is necessary - why would mHead be greater than mTail if the buffer is not full?
+ if (mHead > mTail) {
+ numElements = (mTail + mBuffLen) - mHead;
+ } else {
+ numElements = mTail-mHead;
+ }
+ }
+ return numElements;
+ }
+
+ /**
+ * Returns a double array of buffer items in order of their insertion time
+ * @return double[] of buffer items
+ */
+ public double[] getVals () {
+ int numElements = getNumVals();
+ System.out.println(TAG+" getVals() - numElements=" + numElements);
+ double[] retArr = new double[numElements];
+ for (int i = 0; i < numElements; i++) {
+ retArr[i] = mBuff[(mHead + i) % mBuffLen];
+ }
+ return retArr;
+ }
+
+ public double getAverageVal() {
+ double hrSum = 0.;
+ int hrCount = 0;
+ double valArr[] = getVals();
+ double retVal;
+ for (int n=0; n0) {
+ retVal = hrSum / hrCount;
+ } else {
+ retVal = -1;
+ }
+ return(retVal);
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/uk/org/openseizuredetector/SdAlgHr.java b/app/src/main/java/uk/org/openseizuredetector/SdAlgHr.java
index e6b7ed9..8edf04f 100644
--- a/app/src/main/java/uk/org/openseizuredetector/SdAlgHr.java
+++ b/app/src/main/java/uk/org/openseizuredetector/SdAlgHr.java
@@ -25,13 +25,15 @@ public class SdAlgHr {
private double mAverageHrAlarmThreshMin;
private double mAverageHrAlarmThreshMax;
- private ArrayList mHrHist;
+ private CircBuf mAdaptiveHrBuff;
+ private CircBuf mAverageHrBuff;
public SdAlgHr(Context context) {
Log.i(TAG, "SdAlgHr Constructor");
mContext = context;
- mHrHist = new ArrayList();
updatePrefs();
+ mAdaptiveHrBuff = new CircBuf(mAdaptiveHrAlarmWindowDp, -1.0);
+ mAverageHrBuff = new CircBuf(mAverageHrAlarmWindowDp, -1.0);
}
public void close() {
@@ -93,15 +95,7 @@ public class SdAlgHr {
}
- private void addToHist(double hrVal) {
- /**
- * Add value hrVal to the heart rate history list, truncating the list if it is
- * longer than the required length.
- */
- Log.d(TAG,"addToHist() - length before="+mHrHist.size());
- mHrHist.add(hrVal);
- Log.d(TAG,"addToHist() - length before="+mHrHist.size());
- }
+
private boolean checkSimpleHr(double hrVal) {
/**
@@ -118,33 +112,42 @@ public class SdAlgHr {
}
private boolean checkAdaptiveHr(double hrVal) {
- // FIXME Make this do something
- return(false);
+ boolean retVal;
+ double hrThreshMin;
+ double hrThreshMax;
+ double avHr = mAdaptiveHrBuff.getAverageVal();
+ hrThreshMin = avHr - mAdaptiveHrAlarmThresh;
+ hrThreshMax = avHr + mAdaptiveHrAlarmThresh;
+
+ retVal = false;
+ if (hrVal < hrThreshMin) {
+ retVal = true;
+ }
+ if (hrVal > hrThreshMax) {
+ retVal = true;
+ }
+ Log.d(TAG, "checkAdaptiveHr() - hrVal="+hrVal+", avHr="+avHr+", thresholds=("+hrThreshMin+", "+hrThreshMax+"): Alarm="+retVal);
+
+ return(retVal);
}
private boolean checkAverageHr(double hrVal) {
- // FIXME Make this do something
- return(false);
- }
+ boolean retVal;
+ double avHr = mAdaptiveHrBuff.getAverageVal();
- public double getAverageHrVal() {
- double hrSum = 0.;
- int hrCount = 0;
- double retVal;
- for (int n=0; n -1) {
- hrSum += mHrHist.get(n);
- hrCount++;
- }
+ retVal = false;
+ if (hrVal < mAverageHrAlarmThreshMin) {
+ retVal = true;
}
- if (hrCount>0) {
- retVal = hrSum / hrCount;
- } else {
- retVal = -1;
+ if (hrVal > mAverageHrAlarmThreshMax) {
+ retVal = true;
}
+ Log.d(TAG, "checkAverageHr() - hrVal="+hrVal+", avHr="+avHr+", thresholds=("+mAverageHrAlarmThreshMin+", "+mAverageHrAlarmThreshMin+"): Alarm="+retVal);
return(retVal);
}
+
+
public ArrayList checkHr(double hrVal) {
/**
* Checks the current Heart Rate reading hrVal against the
@@ -153,7 +156,8 @@ public class SdAlgHr {
* true=ALARM, false=OK.
*/
Log.v(TAG, "checkHr("+hrVal+")");
- addToHist(hrVal);
+ mAdaptiveHrBuff.add(hrVal);
+ mAverageHrBuff.add(hrVal);
ArrayList retVal = new ArrayList();
retVal.add(checkSimpleHr(hrVal));
retVal.add(checkAdaptiveHr(hrVal));
diff --git a/app/src/test/java/uk/org/openseizuredetector/CircBufTest.java b/app/src/test/java/uk/org/openseizuredetector/CircBufTest.java
new file mode 100644
index 0000000..32573d7
--- /dev/null
+++ b/app/src/test/java/uk/org/openseizuredetector/CircBufTest.java
@@ -0,0 +1,103 @@
+package uk.org.openseizuredetector;
+
+import junit.framework.TestCase;
+
+public class CircBufTest extends TestCase {
+ private CircBuf mCb;
+
+ public void setUp() throws Exception {
+ super.setUp();
+ mCb = new CircBuf(10, -1);
+ }
+
+ public void tearDown() throws Exception {
+ }
+
+ public void printArr(double[] arr) {
+ for (int n=0; n