Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

now calculate stats as sensor data comes in, rather than at time inte…

…rvals.

and fix calculation of stats.

some stuff for alarm managament
  • Loading branch information...
commit e15ee6546370609adcda4fe3fc8aee7bb9640b12 1 parent 1bc0d64
Marije Baalman authored
4 app/src/com/steim/nescivi/android/gvb/CircularFloatArrayBuffer.java
View
@@ -75,7 +75,7 @@ public int getSize() {
}
}
for ( int axis = 0; axis < 3; axis++ ){
- means[axis] = means[axis] / this.mSize;
+ means[axis] = means[axis] / (float) this.mSize;
}
// standard deviation
@@ -89,7 +89,7 @@ public int getSize() {
for ( int axis = 0; axis < 3; axis++ ){
stats[0][axis] = (float) means[axis];
- stats[1][axis] = (float) Math.sqrt( stds[axis] / this.mSize );
+ stats[1][axis] = (float) Math.sqrt( stds[axis] / (float) this.mSize );
}
/*
151 app/src/com/steim/nescivi/android/gvb/CircularFloatArrayBuffer2.java
View
@@ -0,0 +1,151 @@
+package com.steim.nescivi.android.gvb;
+
+import java.lang.Math;
+
+public class CircularFloatArrayBuffer2 {
+ private int mSize, mNewestElement;
+ private double mBuffer[][];
+ private int mDim;
+
+ public CircularFloatArrayBuffer2(int dim, int size) {
+ if (size < 1) {
+ throw new IllegalArgumentException();
+ }
+ if (dim < 1) {
+ throw new IllegalArgumentException();
+ }
+
+ // Create buffer
+ mBuffer = new double[dim][size];
+
+ // Initialize pointers
+ mNewestElement = size - 1;
+ mSize = 0;
+ mDim = dim;
+ }
+
+ public void add(float elem[]) {
+ int victim = (mNewestElement + 1) % mBuffer.length;
+
+ for ( int i=0; i<mDim; i++ ){
+ mBuffer[i][victim] = elem[i];
+ }
+
+ mNewestElement = victim;
+
+ if (mSize < mBuffer.length) {
+ mSize++;
+ }
+
+ }
+
+ public int getSize() {
+ return mSize;
+ }
+
+ public int getDim() {
+ return mDim;
+ }
+
+ public float[][] getContents() {
+ float result[][] = new float[mDim][mSize];
+
+ if (mSize == mBuffer.length) {
+ int oldestElement = (mNewestElement + 1) % mBuffer.length;
+
+ for ( int j=0; j<mDim; j++ ){
+ for (int i = 0; i < result.length; i++) {
+ result[j][i] = (float) mBuffer[j][oldestElement];
+
+ if (++oldestElement == mBuffer.length)
+ oldestElement = 0;
+ }
+ }
+ }
+ else {
+ for ( int j=0; j<mDim; j++ ){
+ // special case here: buffer is not filled yet (so just dump the buffer)
+ for (int i = 0; i < result.length; i++) {
+ result[j][i] = (float) mBuffer[j][i];
+ }
+ }
+ }
+
+ return result;
+ }
+
+ public static double sum(double[] a) {
+ double sum = 0.0;
+ for (int i = 0; i < a.length; i++) {
+ sum += a[i];
+ }
+ return sum;
+ }
+
+ float[][] getStats(){
+ double vart;
+ double[] stds = {0.0, 0.0, 0,0};
+ double[] means = {0.0, 0.0, 0,0};
+ float[][] stats = { {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f} };
+ /*
+ for ( int axis = 0; axis < 3; axis++ ){
+ stats[0][axis] = (float) 0.0;
+ }
+ */
+
+ // mean
+ for ( int axis = 0; axis < 3; axis++ ){
+ means[axis] = sum( this.mBuffer[axis] ) / this.mSize;
+ }
+ /*
+ for (int i = 0; i < this.mSize; i++){
+
+ means[axis] += this.mBuffer[i][axis];
+ }
+ }
+ for ( int axis = 0; axis < 3; axis++ ){
+ means[axis] = means[axis] / (float) this.mSize;
+ }
+ */
+
+ // standard deviation
+ // std = sqrt(mean( abs(x - x.mean())**2) )
+
+ if ( this.mSize > 1 ){
+ for ( int axis = 0; axis < 3; axis++ ){
+ for (int i = 0; i < this.mSize; i++) {
+ vart = this.mBuffer[axis][i] - means[axis];
+ stds[axis] += vart * vart;
+ }
+ stds[axis] = stds[axis] / (this.mSize-1);
+ }
+ }
+
+ for ( int axis = 0; axis < 3; axis++ ){
+ stats[0][axis] = (float) means[axis];
+ stats[1][axis] = (float) Math.sqrt( stds[axis] );
+ }
+
+ /*
+ //float delta;
+ //int n = 0;
+ //float[] M2 = { (float) 0.0,(float) 0.0, (float) 0.0 };
+
+ for (int i = 0; i < this.mSize; i++){
+ n = n + 1;
+ for ( int axis = 0; axis < 3; axis++ ){
+ delta = this.mBuffer[i][axis] - stats[0][axis];
+ stats[0][axis] = stats[0][axis] + delta/n;
+ if ( n > 1 ){
+ M2[axis] = M2[axis] + delta*(this.mBuffer[i][axis] - stats[0][axis]);
+ }
+ }
+ }
+ for ( int axis = 0; axis < 3; axis++ ){
+ stats[1][axis] = (float) Math.sqrt( M2[axis]/(n - 1) );
+ }
+ */
+ return stats;
+ }
+
+}
92 app/src/com/steim/nescivi/android/gvb/GuesstimateVelocityBetter.java
View
@@ -32,6 +32,14 @@
import android.view.WindowManager;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.os.PowerManager;
+
+import java.util.Calendar;
+
+
/*
import java.util.Timer;
import java.util.TimerTask;
@@ -726,7 +734,17 @@ public void send_estimate_settings(){
if (cb.isChecked() ){
signForward = -1;
}
+
+ ed = (EditText) findViewById(R.id.editUpdateLog );
+ int logUpdateTime = 500;
+ try {
+ logUpdateTime = Integer.parseInt(ed.getText().toString());
+ } catch(NumberFormatException nfe) {
+ System.out.println("Could not parse " + nfe);
+ }
+ cb = (CheckBox) findViewById(R.id.localLog);
+
if (mVelService != null) {
Bundle b = new Bundle();
Message msg = Message.obtain(null, VelocityEstimator.MSG_ESTIMATE_SETTINGS );
@@ -745,6 +763,8 @@ public void send_estimate_settings(){
b.putFloat("stilltime", stilltime );
b.putFloat("offsetma", offsetma );
b.putInt("signForward", signForward );
+ b.putBoolean( "makeLocalLog", cb.isChecked() );
+ b.putInt("updateLogTime", logUpdateTime );
msg.setData(b);
try {
@@ -758,9 +778,9 @@ public void send_estimate_settings(){
public void send_server_settings(){
EditText ed = (EditText) findViewById(R.id.editUpdateServer );
- int updateServerTime = 30000;
+ int updateServerTime = 30;
try {
- updateServerTime = Integer.parseInt(ed.getText().toString()) * 1000;
+ updateServerTime = Integer.parseInt(ed.getText().toString());
} catch(NumberFormatException nfe) {
System.out.println("Could not parse " + nfe);
}
@@ -810,7 +830,7 @@ public void send_server_settings(){
b.putInt("port", port );
b.putInt("client", client );
b.putInt("bufferSize", bufferSize );
- b.putInt("updateServerTime", updateServerTime );
+ b.putInt("updateServerTime", updateServerTime * 1000 );
b.putBoolean( "makeLocalLog", cb.isChecked() );
b.putInt("updateLogTime", logUpdateTime );
msg.setData(b);
@@ -853,8 +873,8 @@ public void onServiceConnected(ComponentName class_name, IBinder service) {
set_update_server();
*/
- send_estimate_settings();
send_server_settings();
+ send_estimate_settings();
/*
@@ -1021,7 +1041,7 @@ public void readPreferences(){
ed.setText( Integer.toString( updateTime ) );
ed = (EditText) findViewById(R.id.editUpdateServer );
- ed.setText( Float.toString( updateServerTime ) );
+ ed.setText( Integer.toString( updateServerTime ) );
ed = (EditText) findViewById(R.id.editHost);
ed.setText( host );
ed = (EditText) findViewById(R.id.editPort );
@@ -1185,9 +1205,9 @@ public void storePreferences(){
}
ed = (EditText) findViewById(R.id.editUpdateServer );
- int updateServerTime = 30000;
+ int updateServerTime = 30;
try {
- updateServerTime = Integer.parseInt(ed.getText().toString()) * 1000;
+ updateServerTime = Integer.parseInt(ed.getText().toString());
} catch(NumberFormatException nfe) {
System.out.println("Could not parse " + nfe);
}
@@ -1237,7 +1257,7 @@ public void storePreferences(){
mPrefsEdit.putInt("port", port );
mPrefsEdit.putInt("client", client );
mPrefsEdit.putInt("bufferSize", bufferSize );
- mPrefsEdit.putInt("updateServerTime", updateServerTime / 1000 );
+ mPrefsEdit.putInt("updateServerTime", updateServerTime );
mPrefsEdit.putInt("updateLogTime", logUpdateTime );
mPrefsEdit.putInt("sensor", sensorid );
@@ -1432,5 +1452,61 @@ public void closeLocalLog(){
}
*/
+ /*
+ void setupDayRhythm(){
+ AlarmManager am = (AlarmManager) GuesstimateVelocityBetter.this.getSystemService(Context.ALARM_SERVICE);
+ Calendar calendar = Calendar.getInstance();
+ Calendar calendar2 = Calendar.getInstance();
+
+ // 9:00 on
+ calendar.set(Calendar.HOUR_OF_DAY, 9);
+ calendar.set(Calendar.MINUTE, 0);
+ calendar.set(Calendar.SECOND, 0);
+ PendingIntent pi1 = PendingIntent.getService(GuesstimateVelocityBetter.this, 0, new Intent(GuesstimateVelocityBetter.this, VelocityEstimator.class), PendingIntent.FLAG_UPDATE_CURRENT);
+ am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi1);
+
+ // 21:00 off
+ calendar.set(Calendar.HOUR_OF_DAY, 21);
+ calendar.set(Calendar.MINUTE, 0);
+ calendar.set(Calendar.SECOND, 0);
+ PendingIntent pi2 = PendingIntent.getService(GuesstimateVelocityBetter.this, 1, new Intent(GuesstimateVelocityBetter.this, VelocityEstimator.class), PendingIntent.FLAG_UPDATE_CURRENT);
+ am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi2);
+
+ }
+ */
}
+/*
+public class Alarm extends BroadcastReceiver
+{
+ @Override
+ public void onReceive(Context context, Intent intent)
+ {
+ PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+ PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "YOUR TAG");
+ wl.acquire();
+
+ // Put here YOUR code.
+ Toast.makeText(context, "WAKE UP, the TRAM starts!", Toast.LENGTH_LONG).show(); // For example
+
+ wl.release();
+ }
+
+ public void SetAlarm(Context context)
+ {
+ AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
+ Intent i = new Intent(context, Alarm.class);
+ PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
+ am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * 10, pi); // Millisec * Second * Minute
+ }
+
+ public void CancelAlarm(Context context)
+ {
+ Intent intent = new Intent(context, Alarm.class);
+ PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
+ AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+ alarmManager.cancel(sender);
+ }
+
+}
+ */
38 app/src/com/steim/nescivi/android/gvb/SensorListener.java
View
@@ -29,7 +29,12 @@
private int mSideways;
private int mGravity;
+ private CircularFloatArrayBuffer2 mBuffer;
+ private int mWindow;
+ private int mDim;
+
private float [] currentValues = {(float) 0.0, (float) 0.0, (float) 0.0};
+ private float [][] currentStats = { {(float) 0.0, (float) 0.0, (float) 0.0}, {(float) 0.0, (float) 0.0, (float) 0.0} };
// private SensorOutputWriter mAccelerometerLog, mLinearAccelerometerLog, mOrientationLog, mMagneticLog, mGyroLog, mLightLog;
private SensorManager mSensorManager;
@@ -40,7 +45,7 @@ public SensorListener(Context context) {
mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
}
- public void startListening( int type, int rate, int forward, int sideways, int gravity) {
+ public void startListening( int type, int rate, int forward, int sideways, int gravity, int dim, int window) {
this.mType = type; // true is linear_acceleration, false is acceleromater
this.mRecordingRate = rate;
this.mRunning = true;
@@ -48,6 +53,11 @@ public void startListening( int type, int rate, int forward, int sideways, int g
this.mForward = forward;
this.mSideways = sideways;
this.mGravity = gravity;
+
+ this.mWindow = window;
+ this.mDim = dim;
+
+ mBuffer = new CircularFloatArrayBuffer2( this.mDim, this.mWindow );
// Start recording thread
mThread = new Thread(this);
@@ -118,15 +128,29 @@ public void storeValues(float readings[]) {
// long newtime = System.currentTimeMillis();
// this.mTimeInterval = newtime - mLastTime;
// this.mLastTime = newtime;
-
- this.currentValues[ 0 ] = readings[ this.mForward ];
- this.currentValues[ 1 ] = readings[ this.mSideways ];
- this.currentValues[ 2 ] = readings[ this.mGravity ];
-
+ synchronized ( this ){
+ this.currentValues[ 0 ] = readings[ this.mForward ];
+ this.currentValues[ 1 ] = readings[ this.mSideways ];
+ this.currentValues[ 2 ] = readings[ this.mGravity ];
+ mBuffer.add( currentValues );
+ }
+ }
+
+ float [][] getCurrentStats(){
+ float [][] curStats;
+ synchronized (this){
+ this.currentStats = mBuffer.getStats();
+ curStats = this.currentStats;
+ }
+ return curStats;
}
float [] getCurrentValues(){
- return this.currentValues;
+ float [] vals;
+ synchronized (this){
+ vals = this.currentValues;
+ }
+ return vals;
}
21 app/src/com/steim/nescivi/android/gvb/SensorOutputWriter.java
View
@@ -32,7 +32,7 @@ public SensorOutputWriter(String type) throws StorageErrorException {
ensureOutputDirectoryExists();
- mBuffer = new CircularFloatArrayBuffer(BUFFER_SIZE);
+ // mBuffer = new CircularFloatArrayBuffer(BUFFER_SIZE);
try {
startLog();
@@ -51,16 +51,21 @@ public void writeReadings(float readings[]) throws StorageErrorException {
// Construct string to write in output and array to store in buffer
sb.append(timeOffset);
- float toBuffer[] = new float[readings.length + 1];
- toBuffer[0] = timeOffset;
+ // float toBuffer[] = new float[readings.length + 1];
+ // toBuffer[0] = timeOffset;
for (int i = 0; i < readings.length; i ++) {
sb.append(" " + readings[i]);
- toBuffer[i+1] = readings[i];
+ // toBuffer[i+1] = readings[i];
}
- // Write string in output and add to buffer
- writeLine(sb.toString());
- mBuffer.add(toBuffer);
+ try{
+ // Write string in output and add to buffer
+ writeLine(sb.toString());
+ } catch (StorageErrorException e) {
+ throw new StorageErrorException("Could not write to output: " + e.getLocalizedMessage());
+ }
+
+ //mBuffer.add(toBuffer);
}
@@ -149,6 +154,7 @@ private String formatDate(Date date, boolean forFilePath) {
return formatter.format(date);
}
+
public float[][] getBuffer() {
if (mBuffer.getSize() == 0) {
return new float[0][0];
@@ -159,4 +165,5 @@ private String formatDate(Date date, boolean forFilePath) {
}
}
+
}
63 app/src/com/steim/nescivi/android/gvb/VelocityEstimator.java
View
@@ -88,11 +88,11 @@
private Timer timer = new Timer();
- private Thread myThread;
- private boolean mRunning;
+ //private Thread myThread;
+ //private boolean mRunning;
private SensorListener mListener;
- private CircularFloatArrayBuffer mBuffer;
+ private CircularFloatArrayBuffer2 mBuffer;
// timing:
private long mLastTime;
@@ -174,6 +174,8 @@ public void handleMessage(Message msg)
set_threshold_still( msg.getData().getFloat("still1"), msg.getData().getFloat("still2"), msg.getData().getFloat( "stilltime") );
set_offset_macoef( msg.getData().getFloat("offsetma") );
set_sign_forward( msg.getData().getInt("signForward") );
+ mMakeLocalLog = msg.getData().getBoolean("makeLocalLog");
+ mLogUpdateTime = msg.getData().getInt("updateLogTime");
startEstimation();
break;
case MSG_SERVER_SETTINGS:
@@ -266,14 +268,14 @@ public void onCreate()
Log.d("VelocityEstimator", "onCreate");
mContext = getApplicationContext();
- mRunning = false;
+ // mRunning = false;
this.mLastTime = System.currentTimeMillis();
// Prepare members
mListener = new SensorListener(this);
- mBuffer = new CircularFloatArrayBuffer( this.mWindowSize );
+// mBuffer = new CircularFloatArrayBuffer2( 3, this.mWindowSize );
this.mUpdateTime = 10;
this.mUpdateServerTime = 30000;
this.mUploadBuffer = new CircularStringArrayBuffer( this.mBufferSize );
@@ -291,11 +293,30 @@ public int onStartCommand(Intent intent, int flags, int startId)
}
public void startEstimation(){
- mListener.startListening( this.mType, 0, this.mForward, this.mSideways, this.mGravity );
+ mListener.startListening( this.mType, 0, this.mForward, this.mSideways, this.mGravity, 3, this.mWindowSize );
+
+ if ( mMakeLocalLog ){
+ createLocalLog();
+ }
+
mCalcTimerTask = new TimerTask() {
public void run() {
updateVelocityMeasurement();
- }
+ if ( mWritingLocalLog ){
+ float [] currentReadings = mListener.getCurrentValues();
+ float [] logdata = {
+ (float) mState,
+ mSpeed, mSpeed * 3.6f,
+ mCurrentStats[0][0], mCurrentStats[1][0],
+ mCurrentStats[0][1], mCurrentStats[1][1],
+ mCurrentStats[0][2], mCurrentStats[1][2],
+ mOffsets[0],mOffsets[1],mOffsets[2],
+ mStillTime,
+ currentReadings[0],currentReadings[1], currentReadings[2]
+ };
+ writeLogData( logdata );
+ }
+ }
};
/*
mUploadTimerTask = new TimerTask() {
@@ -317,7 +338,7 @@ public void run(){
mCurrentStats[0][0], mCurrentStats[1][0],
mCurrentStats[0][1], mCurrentStats[1][1],
mCurrentStats[0][2], mCurrentStats[1][2],
- mOffsets[1],mOffsets[2],mOffsets[3],
+ mOffsets[0],mOffsets[1],mOffsets[2],
mStillTime,
currentReadings[0],currentReadings[1], currentReadings[2]
};
@@ -361,6 +382,7 @@ public void run() {
}
};
+ /*
if ( mMakeLocalLog ){
createLocalLog();
mLogTimerTask = new TimerTask() {
@@ -382,8 +404,9 @@ public void run(){
}
};
}
+ */
- timer.scheduleAtFixedRate( mLogTimerTask, 0, mLogUpdateTime );
+ //timer.scheduleAtFixedRate( mLogTimerTask, 0, mLogUpdateTime );
timer.scheduleAtFixedRate( mUploadTimerTask, 0, mUpdateServerTime );
Toast.makeText(mContext, "VelocityEstimator sender and logger starting", Toast.LENGTH_SHORT).show();
@@ -511,10 +534,12 @@ private void set_sign_forward( int sign ){
}
private void set_window( int windowsize ){
+ /*
if ( this.mWindowSize != windowsize ){
mBuffer = null;
- mBuffer = new CircularFloatArrayBuffer( windowsize );
+ mBuffer = new CircularFloatArrayBuffer2( 3, windowsize );
}
+ */
this.mWindowSize = windowsize;
}
@@ -702,14 +727,15 @@ public void updateVelocityMeasurement(){
this.mLastTime = newtime;
// get readings
- float [] currentReadings = this.mListener.getCurrentValues();
+ //float [] currentReadings = this.mListener.getCurrentValues();
// put readings in circular buffer
- mBuffer.add( currentReadings );
+ //mBuffer.add( currentReadings );
// calculate mean and standard deviation of buffers
- float [][] curStats = mBuffer.getStats();
- //mCurrentStats = mBuffer.getStats();
+ //float [][] curStats = mBuffer.getStats();
+ //mCurrentStats = mBuffer.getStats();
+ float [][] curStats = this.mListener.getCurrentStats();
// reset offsets when we are in still:
if ( this.mState == 0 ) {
@@ -729,19 +755,26 @@ public void updateVelocityMeasurement(){
mStillTime = 0.0f;
if ( curStats[1][0] > threshold_acceleration ){
this.mState = 2;
+ mStillTime = 0.0f;
}
break;
case 1: // steady motion
if ( curStats[1][0] > threshold_decel_std && curStats[0][0] < threshold_decel_mean ){
this.mState = 3;
+ mStillTime = 0.0f;
}
break;
case 2: // accelerating
if ( curStats[1][0] < threshold_steady ){
this.mState = 1;
+ mStillTime = 0.0f;
}
break;
case 3: // decelerating
+ if ( curStats[1][0] > threshold_steady ){
+ this.mState = 2;
+ mStillTime = 0.0f;
+ }
default:
break;
}
@@ -801,7 +834,7 @@ public void uploadDataTCP(){
// print the circular buffer
String[][] bufContents = mUploadBuffer.getContents();
- output.println( mClientID ); // FIXME - should be setting - client ID
+ output.println( mClientID );
for (String[] item: bufContents) {
output.print( item[0]);
output.print( " " );
Please sign in to comment.
Something went wrong with that request. Please try again.