Skip to content
Browse files

add GPS estimation too

add auto start and stop.
  • Loading branch information...
1 parent cfc77a0 commit 92d6a9da9641a7f8236f227e749e96d53de10879 Marije Baalman committed Feb 17, 2012
View
14 app/AndroidManifest.xml
@@ -8,7 +8,9 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<!-- <uses-permission android:name="android.permission.WAKE_LOCK" /> -->
-<!-- <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> -->
+<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+
<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
<activity android:name=".GuesstimateVelocityBetter"
@@ -22,17 +24,17 @@
</intent-filter>
</activity>
- <service android:name=".VelocityEstimator" android:label="VelocityEstimator"></service>
-
- <!--
+ <service android:enabled="true" android:name=".VelocityEstimator" android:label="VelocityEstimator"></service>
+
<receiver android:name=".GVBBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
- <receiver android:name=".GVBAlarmReceiver" />
- -->
+<!-- <service android:enabled="true" android:name=".GVBAlarmReceiver" /> -->
+ <receiver android:enabled="true" android:name=".GVBAlarmStopReceiver" />
+
<!-- activity android:name="org.achartengine.GraphicalActivity" /> -->
</application>
View
17 app/res/layout/guesstimator.xml
@@ -35,11 +35,16 @@
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/GXStdDevTextView" android:text="0.0 m/s^2"></TextView>
</TableRow>
<TableRow>
- <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/OffsetStatusLabelTextView" android:text="Offset/still"></TextView>
+ <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/OffsetStatusLabelTextView" android:text="Offset/GPS"></TextView>
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/OffsetTextView" android:text="0.0 m/s"></TextView>
- <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/StillTextView" android:text="0.0"></TextView>
- </TableRow>
-
+ <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/GPSPrecTextView" android:text="0.0"></TextView>
+ </TableRow>
+ <TableRow>
+ <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/OffsetStatusLabelTextView" android:text="GPS"></TextView>
+ <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/GPSTextView" android:text="0.0 m/s"></TextView>
+ <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/GPSKmHTextView" android:text="0.0 km/h"></TextView>
+ </TableRow>
+
</TableLayout>
</LinearLayout>
@@ -186,8 +191,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="create a log on phone" />
- <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/UpdateLabelTextView3" android:text="dt (ms)"></TextView>
- <EditText android:id="@+id/editUpdateLog" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:inputType="numberDecimal" android:text="500" ></EditText>
+<!-- <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/UpdateLabelTextView3" android:text="dt (ms)"></TextView> -->
+<!-- <EditText android:id="@+id/editUpdateLog" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:inputType="numberDecimal" android:text="500" ></EditText> -->
</LinearLayout>
</LinearLayout>
View
24 app/src/com/steim/nescivi/android/gvb/GVBAlarmStopReceiver.java
@@ -0,0 +1,24 @@
+package com.steim.nescivi.android.gvb;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+//import android.app.IntentService;
+import android.util.Log;
+
+
+
+
+import android.os.PowerManager;
+
+
+public class GVBAlarmStopReceiver extends BroadcastReceiver {
+
+ // onReceive must be very quick and not block, so it just fires up a Service
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ //public void onHandleIntent(Intent intent) {
+ Log.i( "GVB", "GVBAlarmStopReceiver invoked, stopping VelocityEstimator in background");
+ context.stopService(new Intent(context, VelocityEstimator.class));
+ }
+}
View
53 app/src/com/steim/nescivi/android/gvb/GVBBootReceiver.java
@@ -0,0 +1,53 @@
+package com.steim.nescivi.android.gvb;
+
+import java.util.Calendar;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+import android.os.SystemClock;
+
+public class GVBBootReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.i( "GVB", "GVBBootReceiver invoked, configuring AlarmManager");
+ AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+
+ PendingIntent pendingIntent =
+ PendingIntent.getBroadcast(context, 0, new Intent(context, GVBAlarmReceiver.class), 0);
+
+ // start now once, and then each day at a certain time
+ // and stop service each day at a certain time
+
+ // use inexact repeating which is easier on battery (system can phase events and not wake at exact times)
+ alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ SystemClock.elapsedRealtime() + 30000, // start 30 seconds from now
+ //AlarmManager.INTERVAL_HOUR, // each hour ; INTERVAL_DAY for each hour
+ pendingIntent);
+
+// AlarmManager alarmMgr = (AlarmManager) context.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( context, 0, new Intent(context, GVBAlarmReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
+ PendingIntent pi1 = PendingIntent.getService( context, 0, new Intent(context, VelocityEstimator.class), PendingIntent.FLAG_UPDATE_CURRENT);
+ alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi1);
+
+ // 21:00 off
+ calendar2.set(Calendar.HOUR_OF_DAY, 21);
+ calendar2.set(Calendar.MINUTE, 0);
+ calendar2.set(Calendar.SECOND, 0);
+ PendingIntent pi2 = PendingIntent.getBroadcast(context, 1, new Intent(context, GVBAlarmStopReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
+ alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar2.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi2);
+ }
+}
View
95 app/src/com/steim/nescivi/android/gvb/GuesstimateVelocityBetter.java
@@ -32,13 +32,10 @@
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 android.app.AlarmManager;
+import android.app.PendingIntent;
/*
import java.util.Timer;
@@ -87,6 +84,14 @@ public void handleMessage(Message msg)
TextView tv;
switch (msg.what)
{
+ case VelocityEstimator.MSG_GPS_LOC:
+ tv = (TextView) findViewById(R.id.GPSTextView);
+ tv.setText(String.format("%.1f m/s", msg.getData().getFloat( "gps_speed" ) ) );
+ tv = (TextView) findViewById(R.id.GPSKmHTextView);
+ tv.setText(String.format("%.1f km/h", msg.getData().getFloat( "gps_speed" ) * 3.6f ) );
+ tv = (TextView) findViewById(R.id.GPSPrecTextView);
+ tv.setText(String.format("%.3f", msg.getData().getFloat( "gps_precision" ) ) );
+ break;
case VelocityEstimator.MSG_SERVER_UPDATE_MSG:
tv = (TextView) findViewById(R.id.TransmitterStatusTextView);
tv.setText( msg.getData().getString("status") );
@@ -766,13 +771,13 @@ public void send_estimate_settings(){
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);
- }
+// 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);
@@ -801,7 +806,7 @@ public void send_estimate_settings(){
b.putFloat("offsetma", offsetma );
b.putInt("signForward", signForward );
b.putBoolean( "makeLocalLog", cb.isChecked() );
- b.putInt("updateLogTime", logUpdateTime );
+ //b.putInt("updateLogTime", logUpdateTime );
msg.setData(b);
try {
@@ -850,13 +855,13 @@ public void send_server_settings(){
System.out.println("Could not parse " + nfe);
}
- 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);
- }
+// 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);
+// }
CheckBox cb = (CheckBox) findViewById(R.id.localLog);
@@ -869,7 +874,7 @@ public void send_server_settings(){
b.putInt("bufferSize", bufferSize );
b.putInt("updateServerTime", updateServerTime * 1000 );
b.putBoolean( "makeLocalLog", cb.isChecked() );
- b.putInt("updateLogTime", logUpdateTime );
+ //b.putInt("updateLogTime", logUpdateTime );
msg.setData(b);
try {
@@ -1108,8 +1113,8 @@ public void readPreferences(){
cb.setChecked( localLog );
cb = (CheckBox) findViewById(R.id.signForward);
cb.setChecked( signForward );
- ed = (EditText) findViewById(R.id.editUpdateLog );
- ed.setText( Integer.toString( updateLogTime ) );
+ //ed = (EditText) findViewById(R.id.editUpdateLog );
+ //ed.setText( Integer.toString( updateLogTime ) );
}
public void storePreferences(){
@@ -1325,13 +1330,13 @@ public void storePreferences(){
System.out.println("Could not parse " + nfe);
}
- 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);
- }
+// 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);
+// }
CheckBox cb = (CheckBox) findViewById(R.id.localLog);
mPrefsEdit.putBoolean("localLog", cb.isChecked() );
@@ -1343,7 +1348,7 @@ public void storePreferences(){
mPrefsEdit.putInt("client", client );
mPrefsEdit.putInt("bufferSize", bufferSize );
mPrefsEdit.putInt("updateServerTime", updateServerTime );
- mPrefsEdit.putInt("updateLogTime", logUpdateTime );
+ //mPrefsEdit.putInt("updateLogTime", logUpdateTime );
mPrefsEdit.putInt("sensor", sensorid );
mPrefsEdit.putInt("forward", forwardid );
@@ -1376,11 +1381,39 @@ protected void onStart() {
readPreferences();
// Prepare UI elements
setButtonsListeners();
+ setupAlarmManager();
// Enable UI buttons
toggleUIStatus(false);
}
+ private void setupAlarmManager(){
+ Context context = GuesstimateVelocityBetter.this;
+ AlarmManager alarmMgr = (AlarmManager) context.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);
+
+ Intent intent = new Intent(GuesstimateVelocityBetter.this, VelocityEstimator.class);
+ //startService(intent);
+
+ PendingIntent pi1 = PendingIntent.getService( context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+ alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi1);
+
+ // 21:00 off
+ calendar2.set(Calendar.HOUR_OF_DAY, 21);
+ calendar2.set(Calendar.MINUTE, 0);
+ calendar2.set(Calendar.SECOND, 0);
+ PendingIntent pi2 = PendingIntent.getBroadcast(context, 1, new Intent(context, GVBAlarmStopReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
+ alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar2.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi2);
+
+ }
+
@Override
protected void onStop(){
super.onStop();
View
183 app/src/com/steim/nescivi/android/gvb/VelocityEstimator.java
@@ -28,6 +28,7 @@
import android.widget.CheckBox;
import android.widget.Toast;
+import java.util.Iterator;
import java.util.Timer;
import java.util.TimerTask;
import java.net.Socket;
@@ -38,14 +39,33 @@
import java.io.PrintWriter;
import java.io.IOException;
+import android.hardware.SensorEventListener;
+import android.location.GpsSatellite;
+import android.location.GpsStatus;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.location.LocationProvider;
+
+
//import com.steim.nescivi.android.gvb.VelocityTransmitter.IncomingHandler;
-public class VelocityEstimator extends Service {
+public class VelocityEstimator extends Service implements LocationListener, GpsStatus.Listener {
private Messenger mGuiClient = null;
// private Messenger mTransmitService = null;
private SharedPreferences mPrefs;
+
+ private LocationManager mLocationManager;
+ private GpsStatus mGpsStatus = null;
+
+// private float mVelocity_at_last_gps_fix;
+ private long mGps_prev_fix_time = 0;
+ private float mGps_prev_fix_accuracy = 1000.f;
+ private float mGps_precision = 0.f;
+ private float mGps_speed = 0.f;
+
// private Messenger mIncomingMessenger;
@@ -67,6 +87,8 @@
static final int MSG_SERVER_UPDATE_MSG = 14;
static final int MSG_GUI_UPDATE_MSG = 15;
+
+ static final int MSG_GPS_LOC = 16;
// static final int MSG_REGISTER_VS_SRV = 5;
// static final int MSG_UNREGISTER_VS_SRV = 6;
@@ -233,6 +255,8 @@ public void onCreate()
mContext = getApplicationContext();
// mRunning = false;
+ // Get an instance of the LocationManager (for GPS)
+ mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
this.mLastTime = System.currentTimeMillis();
@@ -248,6 +272,8 @@ public void onCreate()
startEstimation();
startServerAndLog();
+ mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0L, 0.f, this);
+
Toast.makeText(mContext, "VelocityEstimator created", Toast.LENGTH_SHORT).show();
}
@@ -383,13 +409,160 @@ public void onDestroy()
Toast.makeText(mContext, "VelocityEstimator stopping", Toast.LENGTH_SHORT).show();
mListener.stopListening();
- closeLocalLog();
if (timer != null){
- mCalcTimerTask.cancel();
+ mCalcTimerTask.cancel();
timer.cancel();
- }
+ }
+ if (timer2 != null){
+ mUploadTimerTask.cancel();
+ timer2.cancel();
+ }
+
+ closeLocalLog();
+ unregister_GPS();
+
+ }
+
+ private void register_with_GPS()
+ {
+ try
+ {
+ if(mLocationManager.addGpsStatusListener(this)) // && mLocationManager.addNmeaListener(this))
+ {
+ Toast.makeText(mContext, "GPS Connected", Toast.LENGTH_SHORT).show();
+ }
+ }
+ catch (SecurityException e)
+ {
+ Toast.makeText(mContext, "No permission to use GPS", Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ private void unregister_GPS()
+ {
+ mLocationManager.removeGpsStatusListener(this);
+ // mLocationManager.removeNmeaListener(this);
+ }
+
+ /*
+ private void compute_speed()
+ {
+ float tot_weight = mGps_precision + mVelocity_precision;
+ float gps_weight = mGps_precision / tot_weight;
+ float vel_weight = mVelocity_precision / tot_weight;
+
+ float speed_ms = (mVelocity_vec.mag() * vel_weight) + (mGps_speed * gps_weight);
+ mSpeed = speed_ms * 3.6f; // change scale to km/h
+ }
+ */
+
+ public void onStatusChanged(String provider, int status, Bundle extras)
+ {
+ Log.d("VelocityServie", "onStatusChanged - " + provider);
+
+ switch (status)
+ {
+ case LocationProvider.OUT_OF_SERVICE:
+ Toast.makeText(mContext, provider + " out of service", Toast.LENGTH_SHORT).show();
+ break;
+ case LocationProvider.AVAILABLE:
+ Toast.makeText(mContext, provider + " available", Toast.LENGTH_SHORT).show();
+ break;
+ case LocationProvider.TEMPORARILY_UNAVAILABLE:
+ Toast.makeText(mContext, provider + " temporarily unavailable", Toast.LENGTH_SHORT).show();
+ break;
+ }
+ }
+
+ public void onProviderEnabled(String provider)
+ {
+ Log.d("VelocityServie", "onProviderEnabled - " + provider);
+ Toast.makeText(mContext, provider + " enabled", Toast.LENGTH_SHORT).show();
+ register_with_GPS();
+ }
+
+ public void onProviderDisabled(String provider)
+ {
+ Log.d("VelocityServie", "onProviderDisabled - " + provider);
+ Toast.makeText(mContext, provider + " disabled", Toast.LENGTH_SHORT).show();
+ unregister_GPS();
+ }
+
+ public void onLocationChanged(Location location)
+ {
+ Log.d("VelocityService", "onLocationChanged");
+
+ long time = location.getTime();
+ float dt = (time - mGps_prev_fix_time) / 1000.f;
+ mGps_prev_fix_time = time;
+
+ float accuracy = location.getAccuracy();
+ mGps_precision = Math.min(8.f / (dt * (mGps_prev_fix_accuracy + accuracy)), 1.f);
+ mGps_prev_fix_accuracy = accuracy;
+
+ mGps_speed = location.getSpeed();
+
+// mVelocity_at_last_gps_fix = mVelocity_vec.mag();
+
+ send_location_msg(location);
+ }
+
+ public void onGpsStatusChanged(int status)
+ {
+ Log.d("VelocityServie", "onGpsStatusChanged");
+ mGpsStatus = mLocationManager.getGpsStatus(mGpsStatus);
+
+ switch (status)
+ {
+ case GpsStatus.GPS_EVENT_STARTED:
+ Toast.makeText(mContext, "GPS on", Toast.LENGTH_SHORT).show();
+ break;
+ case GpsStatus.GPS_EVENT_STOPPED:
+ Toast.makeText(mContext, "GPS off", Toast.LENGTH_SHORT).show();
+ break;
+ case GpsStatus.GPS_EVENT_FIRST_FIX:
+ Toast.makeText(mContext, "Have GPS fix", Toast.LENGTH_SHORT).show();
+ break;
+ case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
+ Iterator<GpsSatellite> sats = mGpsStatus.getSatellites().iterator();
+// String satlist = "GPS sats:\n";
+// int satcount = 0;
+ while (sats.hasNext())
+ {
+ GpsSatellite sat = sats.next();
+// satlist += String.format("%d: %.1f\n", sat.getPrn(), sat.getSnr());
+// satcount++;
+ Log.d("VelocityService", String.format("GPS sat %d: %.1f", sat.getPrn(), sat.getSnr()));
+ }
+/* if (satcount > 0)
+ {
+ Toast.makeText(mContext, satlist, Toast.LENGTH_SHORT).show();
+ } */
+ break;
+ }
+ }
+
+ private void send_location_msg(Location location)
+ {
+ Bundle b = new Bundle();
+ Message msg = Message.obtain(null, MSG_GPS_LOC );
+ b.putFloat("gps_precision", mGps_precision );
+ b.putFloat("gps_speed", mGps_speed );
+
+ if (mGuiClient != null)
+ {
+ try
+ {
+ mGuiClient.send(msg);
+ }
+ catch (RemoteException e)
+ {
+ mGuiClient = null;
+ }
+ }
}
+
@Override
public IBinder onBind(Intent intent)
@@ -407,7 +580,7 @@ private void readPreferences(){
mPort = mPrefs.getInt("port", 5858 );
mClientID = mPrefs.getInt("client", 1 );
set_buffer_size( mPrefs.getInt("bufferSize", 60 ) );
- mUpdateServerTime = mPrefs.getInt("updateServerTime", 30 );
+ mUpdateServerTime = mPrefs.getInt("updateServerTime", 30 ) * 1000;
//mLogUpdateTime = mPrefs.getInt("updateLogTime", 500 );
mMakeLocalLog = mPrefs.getBoolean( "localLog", false );

0 comments on commit 92d6a9d

Please sign in to comment.
Something went wrong with that request. Please try again.