diff --git a/IOIOTruck/assets/exceptionhandler.properties b/IOIOTruck/assets/exceptionhandler.properties index 910dadd..0d0db1f 100644 --- a/IOIOTruck/assets/exceptionhandler.properties +++ b/IOIOTruck/assets/exceptionhandler.properties @@ -13,7 +13,7 @@ # get is the path to your json retrieval script # app is the redmine project name # tracker is the redmine tracker -server = http://rickbarrette.dyndns.org:8080/redmine/exceptionhandler +server = http://rickbarrette.dyndns.org:8888 app = IOIO Truck tracker = Development Bug diff --git a/IOIOTruck/src/com/TwentyCodes/android/IOIOTruck/Main.java b/IOIOTruck/src/com/TwentyCodes/android/IOIOTruck/Main.java index b2e4c43..bab5fa8 100644 --- a/IOIOTruck/src/com/TwentyCodes/android/IOIOTruck/Main.java +++ b/IOIOTruck/src/com/TwentyCodes/android/IOIOTruck/Main.java @@ -47,6 +47,8 @@ public class Main extends Activity implements OnClickListener { Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this)); setContentView(R.layout.main); +// Integer.parseInt("poop"); + findViewById(R.id.test_activity_button).setOnClickListener(this); findViewById(R.id.nav_activity_button).setOnClickListener(this); findViewById(R.id.camera_activity_button).setOnClickListener(this); diff --git a/IOIOTruck/src/com/TwentyCodes/android/IOIOTruck/MapFragment.java b/IOIOTruck/src/com/TwentyCodes/android/IOIOTruck/MapFragment.java index 0f55ff6..d9a6146 100644 --- a/IOIOTruck/src/com/TwentyCodes/android/IOIOTruck/MapFragment.java +++ b/IOIOTruck/src/com/TwentyCodes/android/IOIOTruck/MapFragment.java @@ -21,10 +21,18 @@ */ package com.TwentyCodes.android.IOIOTruck; +import java.io.IOException; + +import org.apache.http.client.ClientProtocolException; +import org.json.JSONException; + import android.util.Log; +import com.TwentyCodes.android.fragments.UserOverlayMapFragment; import com.TwentyCodes.android.location.MapView; import com.TwentyCodes.android.location.OnLocationSelectedListener; +import com.TwentyCodes.android.overlays.DirectionsOverlay; +import com.TwentyCodes.android.overlays.DirectionsOverlay.OnDirectionsCompleteListener; import com.TwentyCodes.android.overlays.RadiusOverlay; import com.google.android.maps.GeoPoint; @@ -34,12 +42,13 @@ import com.google.android.maps.GeoPoint; * Specifically this map view will allow user to select a point on the map via RadiusOverlay * @author ricky barrette */ -public class MapFragment extends com.TwentyCodes.android.fragments.UserOverlayMapFragment implements OnLocationSelectedListener { +public class MapFragment extends UserOverlayMapFragment implements OnLocationSelectedListener, OnDirectionsCompleteListener { private final String TAG = "MapFragment"; - private RadiusOverlay mRadiusOverlay; private OnLocationSelectedListener mLocationSelectedListener; + private OnDirectionsCompleteListener mDirectionsCompleteListener; + private DirectionsOverlay mDirectionsOverlay; /** * Creates a new MapFragment @@ -49,13 +58,49 @@ public class MapFragment extends com.TwentyCodes.android.fragments.UserOverlayMa super(); } + /** + * Called whrn the directions overlay is finished getting the directions. + * (non-Javadoc) + * @see com.TwentyCodes.android.overlays.DirectionsOverlay.OnDirectionsCompleteListener#onDirectionsComplete(com.TwentyCodes.android.overlays.DirectionsOverlay) + */ + @Override + public void onDirectionsComplete(DirectionsOverlay directionsOverlay) { + mDirectionsOverlay = directionsOverlay; + if(mDirectionsCompleteListener != null) + mDirectionsCompleteListener.onDirectionsComplete(directionsOverlay); + } + /** * Called when a point is selected on the map * (non-Javadoc) * @see com.TwentyCodes.android.location.LocationSelectedListener#onLocationSelected(com.google.android.maps.GeoPoint) */ @Override - public void onLocationSelected(GeoPoint point) { + public void onLocationSelected(final GeoPoint point) { + + if(mDirectionsCompleteListener != null) + new Thread( new Runnable(){ + @Override + public void run(){ + try { + new DirectionsOverlay(getMap(), getUserLocation(), point, MapFragment.this); + } catch (IllegalStateException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ClientProtocolException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + }).start(); + + removePath(); setDestination(point); @@ -72,7 +117,7 @@ public class MapFragment extends com.TwentyCodes.android.fragments.UserOverlayMa } else if(Debug.DEBUG) Log.d(TAG, "onLocationSelected() Location was null"); } - + /** * (non-Javadoc) * @see com.TwentyCodes.android.location.UserOverlayMapFragment#onMapViewCreate(com.TwentyCodes.android.location.MapView) @@ -86,6 +131,24 @@ public class MapFragment extends com.TwentyCodes.android.fragments.UserOverlayMa super.onMapViewCreate(map); } + /** + * Removes the path if displayed + * @author ricky barrette + */ + public void removePath(){ + if(mDirectionsOverlay != null) + mDirectionsOverlay.removePath(); + } + + /** + * sets the distener for the directions overlay + * @param listener + * @author ricky barrette + */ + public void setDirectionsCompleteListener(OnDirectionsCompleteListener listener){ + mDirectionsCompleteListener = listener; + } + /** * @param listener * @author ricky barrette @@ -93,7 +156,7 @@ public class MapFragment extends com.TwentyCodes.android.fragments.UserOverlayMa public void setLocationSelectedListener(OnLocationSelectedListener listener){ mLocationSelectedListener = listener; } - + /** * @param radius meters * @author ricky barrette @@ -109,4 +172,4 @@ public class MapFragment extends com.TwentyCodes.android.fragments.UserOverlayMa public void setRadiusColor(int color){ mRadiusOverlay.setColor(color); } -} \ No newline at end of file +} diff --git a/IOIOTruck/src/com/TwentyCodes/android/IOIOTruck/NavigationActivity.java b/IOIOTruck/src/com/TwentyCodes/android/IOIOTruck/NavigationActivity.java index ee88e49..c855569 100644 --- a/IOIOTruck/src/com/TwentyCodes/android/IOIOTruck/NavigationActivity.java +++ b/IOIOTruck/src/com/TwentyCodes/android/IOIOTruck/NavigationActivity.java @@ -21,7 +21,10 @@ */ package com.TwentyCodes.android.IOIOTruck; +import java.util.ArrayList; + import android.content.Context; +import android.graphics.Color; import android.os.Bundle; import android.os.PowerManager; import android.os.PowerManager.WakeLock; @@ -43,6 +46,9 @@ import com.TwentyCodes.android.location.CompassListener; import com.TwentyCodes.android.location.GeoPointLocationListener; import com.TwentyCodes.android.location.GeoUtils; import com.TwentyCodes.android.location.OnLocationSelectedListener; +import com.TwentyCodes.android.overlays.DirectionsOverlay; +import com.TwentyCodes.android.overlays.DirectionsOverlay.OnDirectionsCompleteListener; +import com.TwentyCodes.android.overlays.PathOverlay; import com.google.android.maps.GeoPoint; @@ -57,28 +63,7 @@ import com.google.android.maps.GeoPoint; * + drive the truck forward or reverse to best navigate to the selected point * @author ricky barrette */ -public class NavigationActivity extends FragmentActivity implements CompassListener, GeoPointLocationListener, OnLocationSelectedListener, OnClickListener, OnCheckedChangeListener, IOIOTruckThreadListener { - - private static final String TAG = "NavigationActivity"; - private IOIOTruckManager mIOIOManager; - private MapFragment mMap; - private TextView mLog; - private GeoPoint mPoint; - private ProgressBar mProgress; - private int mMaxDistance = 0; //meters - private boolean isRunning = false; - private Button mGoButton; - private float mBearing; - private ScrollView mScrollView; - - private boolean isScrollingEnabled = true; - private int mDistance; - private LogUpdater mLoggerThread; - private TextView mAccuracyTextView; - private TextView mLastUpdateTextView; - private long mLast; - private WakeLock mWakeLock; - private int mCount; +public class NavigationActivity extends FragmentActivity implements CompassListener, GeoPointLocationListener, OnLocationSelectedListener, OnClickListener, OnCheckedChangeListener, IOIOTruckThreadListener, OnDirectionsCompleteListener { /** * This thread will be used to update all the informational displays @@ -92,23 +77,21 @@ public class NavigationActivity extends FragmentActivity implements CompassListe * aborts the thread * @author ricky barrette */ - public void abort() { + public synchronized void abort() { isAborted = true; } @Override public void run(){ - while (true) { - if (isAborted) - break; + while (!isAborted) { updateLog("\nDistance: "+ mDistance +getString(R.string.m) +"\nDrive: "+mIOIOManager.getDriveValue() +"\nSteering: "+mIOIOManager.getSteerValue() +"\nBearing: "+mBearing +"\nisRunning: "+isRunning); - - updateLastUpdateTextView(); - + if(mPoints != null) + updateLog("Point = "+mIndex +" of "+ mPoints.size()); + updateLastUpdateTextView(); try { sleep(1000); } catch (InterruptedException e) { @@ -133,6 +116,27 @@ public class NavigationActivity extends FragmentActivity implements CompassListe } } + private static final String TAG = "NavigationActivity"; + private IOIOTruckManager mIOIOManager; + private MapFragment mMap; + private TextView mLog; + private ProgressBar mProgress; + private boolean isRunning = false; + private Button mGoButton; + private float mBearing; + private ScrollView mScrollView; + private boolean isScrollingEnabled = true; + private int mDistance; + private LogUpdater mLoggerThread; + private TextView mAccuracyTextView; + private TextView mLastUpdateTextView; + private long mLast; + private WakeLock mWakeLock; + private int mCount = 0; + private ArrayList mPoints; + private int mIndex = 0; + private GeoPoint mDestPoint; + private ArrayList mWayPoints; /** * Called when the scrolling switch is checked @@ -161,7 +165,7 @@ public class NavigationActivity extends FragmentActivity implements CompassListe break; case R.id.mark_my_lcoation_button: - GeoPoint point = mMap.getUserLocation(); + final GeoPoint point = mMap.getUserLocation(); if(point != null){ mMap.onLocationSelected(point); @@ -170,7 +174,7 @@ public class NavigationActivity extends FragmentActivity implements CompassListe break; case R.id.my_location_button: - GeoPoint user = mMap.getUserLocation(); + final GeoPoint user = mMap.getUserLocation(); if(user != null){ mMap.setMapCenter(user); @@ -181,6 +185,230 @@ public class NavigationActivity extends FragmentActivity implements CompassListe } } + /** + * Called when there is an update from the compass + * (non-Javadoc) + * @see com.TwentyCodes.android.location.CompassListener#onCompassUpdate(float) + */ + @Override + public void onCompassUpdate(float bearing) { + bearing = GeoUtils.calculateBearing(mMap.getUserLocation(), mMap.getDestination(), bearing); + + if(bearing > 355 || bearing < 5) + mIOIOManager.setSteerValue(IOIOTruckValues.STEER_STRAIGHT); + + if(bearing < 355 && bearing > 180) + mIOIOManager.setSteerValue(IOIOTruckValues.STEER_RIGHT); + + if(bearing < 180 && bearing > 5) + mIOIOManager.setSteerValue(IOIOTruckValues.STEER_LEFT); + + mBearing = bearing; + } + + /** + * (non-Javadoc) + * @see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle) + */ + @Override + protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + setContentView(R.layout.nav_activity); + /* + * init UI + */ + mLog = (TextView) findViewById(R.id.log_textView); + mGoButton = (Button) findViewById(R.id.go_button); + mProgress = (ProgressBar) findViewById(R.id.progressBar); + mScrollView = (ScrollView) findViewById(R.id.scrollview); + Switch scrollSwitch = (Switch) findViewById(R.id.scrolling_switch); + mAccuracyTextView = (TextView) findViewById(R.id.accuracy_textview); + mLastUpdateTextView = (TextView) findViewById(R.id.time_textview); + + /* + * init listeners + */ + scrollSwitch.setOnCheckedChangeListener(this); + mGoButton.setOnClickListener(this); + findViewById(R.id.mark_my_lcoation_button).setOnClickListener(this); + findViewById(R.id.my_location_button).setOnClickListener(this); + findViewById(R.id.map_button).setOnClickListener(this); + } + + /** + * called when the directions overlay is generated + * (non-Javadoc) + * @see com.TwentyCodes.android.overlays.DirectionsOverlay.OnDirectionsCompleteListener#onDirectionsComplete(com.TwentyCodes.android.overlays.DirectionsOverlay) + */ + @Override + public void onDirectionsComplete(DirectionsOverlay directionsOverlay) { + ArrayList path = directionsOverlay.getPath(); + + if(path.size() > 0){ + mWayPoints = new ArrayList(); + ArrayList points = new ArrayList(); + points.add(path.get(0).getStartPoint()); + for(PathOverlay item : path) + if(item.getEndPoint() != null) { + points.add(item.getEndPoint()); + mWayPoints.add(new PathOverlay(item.getEndPoint(), 5, Color.GRAY)); + } + + mPoints = points; + mMap.setDestination(points.get(0)); + mWayPoints.add(new PathOverlay(points.get(0), 5, Color.MAGENTA)); + mMap.getMap().getOverlays().addAll(mWayPoints); + mWayPoints.addAll(path); + } + } + + @Override + public void onFirstFix(boolean isFirstFix) { + mMap.disableGPSProgess(); + } + + /** + * Called when android's location services have an update + * (non-Javadoc) + * @see com.TwentyCodes.android.location.GeoPointLocationListener#onLocationChanged(com.google.android.maps.GeoPoint, int) + */ + @Override + public synchronized void onLocationChanged(final GeoPoint point, final int accuracy) { + mLast = System.currentTimeMillis(); + mAccuracyTextView.setText(accuracy+getString(R.string.m)); + mDistance = updateProgress(point); + final GeoPoint currentDest = mMap.getDestination(); + + /* + * if we have a destination, check to see if we are there yet + * if we are then increment mCount + */ + if(point != null) + if(currentDest != null) + + + /* + * are we closer than 15 feet? + */ + if (GeoUtils.distanceKm(point, currentDest) < 0.009144) { +// if(GeoUtils.isIntersecting(point, (float) (accuracy / 1E3), currentDest, Debug.RADIUS, Debug.FUDGE_FACTOR)) { + updateLog("Count = "+ (++mCount)); + /* + * if we get 6 positives, we are problay at our waypoint/dest + */ + if(mCount == 6){ + + mCount = 0; + + /* + * if the points list is null, or there are no more waypoints + */ + if(mPoints == null || mIndex == mPoints.size()){ + mIOIOManager.setDriveValue(IOIOTruckValues.DRIVE_STOP); + updateGoButton(true); + updateLog(R.string.dest_reached); + mMap.setDestination(null); + } else { + updateLog("Index = " + (++mIndex)); + + /* + * if there are more waypoints, then move on to the next + * otherwise move on to the dest + */ + if(mIndex < mPoints.size()) { + updateLog("Waypoint reached, moving to next"); + mMap.setDestination(mPoints.get(mIndex)); + } else { + updateLog("last Waypoint reached, moving to dest"); + mMap.setDestination(mDestPoint); + } + + updateLog("New dest = "+ mMap.getDestination().toString()); + } + } + + } else { + Log.v(TAG, "Driving Forward"); + mCount = 0; + mIOIOManager.setDriveValue(IOIOTruckValues.DRIVE_FORWARD); + } + else { + updateLog("Lost GPS signal (point was null), stopping"); + mIOIOManager.setDriveValue(IOIOTruckValues.DRIVE_STOP); + } + + } + + /** + * Called when the user selects a point for the truck to drive to + * (non-Javadoc) + * @see com.TwentyCodes.android.location.LocationSelectedListener#onLocationSelected(com.google.android.maps.GeoPoint) + */ + @Override + public void onLocationSelected(GeoPoint point) { + if(mWayPoints != null) + mMap.getMap().getOverlays().removeAll(mWayPoints); + mDestPoint = point; + mDistance = updateProgress(mMap.getUserLocation()); + updateLog(getString(R.string.point_selected)+point.toString()); + mIndex = 0; + mCount = 0; + } + + /** + * Called when the IOIOTruckThread has a log it wants to display + * (non-Javadoc) + * @see com.TwentyCodes.android.IOIOTruck.IOIOTruckManager.IOIOTruckThreadListener#onLogUpdate(java.lang.String) + */ + @Override + public void onLogUpdate(String log) { + updateLog(log); + } + + /** + * Called when the application is paused. We want to disconnect with the + * IOIO at this point, as the user is no longer interacting with our + * application. + * @author ricky barrette + */ + @Override + protected void onPause() { + try { + mIOIOManager.abort(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + if(mLoggerThread != null) + mLoggerThread.abort(); + + if(mWakeLock.isHeld()) + mWakeLock.release(); + super.onPause(); + } + + /** + * (non-Javadoc) + * @see android.support.v4.app.FragmentActivity#onResume() + */ + @Override + protected void onResume() { + super.onResume(); + mMap = (MapFragment) this.getSupportFragmentManager().findFragmentById(R.id.map_fragment); + mMap.setCompassListener(this); + mMap.setGeoPointLocationListener(this); + mMap.setLocationSelectedListener(this); + mMap.setDirectionsCompleteListener(this); + mMap.setRadius((int) (Debug.RADIUS * 1E3)); + mMap.enableGPSProgess(); + mIOIOManager = new IOIOTruckManager(this, this); + mIOIOManager.start(); + + PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE); + mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG); + mWakeLock.acquire(); + } + /** * updates the go/stop button based on isRunning * thread safe @@ -189,7 +417,7 @@ public class NavigationActivity extends FragmentActivity implements CompassListe private void updateGoButton() { updateGoButton(isRunning); } - + /** * Sets the go/stop button to the provided value * thread safe @@ -219,149 +447,6 @@ public class NavigationActivity extends FragmentActivity implements CompassListe }); } - /** - * Called when there is an update from the compass - * (non-Javadoc) - * @see com.TwentyCodes.android.location.CompassListener#onCompassUpdate(float) - */ - @Override - public void onCompassUpdate(float bearing) { - bearing = GeoUtils.calculateBearing(mMap.getUserLocation(), mPoint, bearing); - - if(bearing > 355 || bearing < 5) - mIOIOManager.setSteerValue(IOIOTruckValues.STEER_STRAIGHT); - - if(bearing < 355 && bearing > 180) - mIOIOManager.setSteerValue(IOIOTruckValues.STEER_RIGHT); - - if(bearing < 180 && bearing > 5) - mIOIOManager.setSteerValue(IOIOTruckValues.STEER_LEFT); - - mBearing = bearing; - } - - /** - * (non-Javadoc) - * @see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle) - */ - @Override - protected void onCreate(Bundle icicle) { - super.onCreate(icicle); - setContentView(R.layout.nav_activity); - /* - * init UI - */ - mLog = (TextView) findViewById(R.id.log_textView); - mGoButton = (Button) findViewById(R.id.go_button); - mProgress = (ProgressBar) findViewById(R.id.progressBar); - mScrollView = (ScrollView) findViewById(R.id.scrollview); - Switch scrollSwitch = (Switch) findViewById(R.id.scrolling_switch); - mAccuracyTextView = (TextView) findViewById(R.id.accuracy_textview); - mLastUpdateTextView = (TextView) findViewById(R.id.time_textview); - - /* - * init listeners - */ - scrollSwitch.setOnCheckedChangeListener(this); - mGoButton.setOnClickListener(this); - findViewById(R.id.mark_my_lcoation_button).setOnClickListener(this); - findViewById(R.id.my_location_button).setOnClickListener(this); - findViewById(R.id.map_button).setOnClickListener(this); - } - - /** - * Called when android's location services have an update - * (non-Javadoc) - * @see com.TwentyCodes.android.location.GeoPointLocationListener#onLocationChanged(com.google.android.maps.GeoPoint, int) - */ - @Override - public void onLocationChanged(GeoPoint point, int accuracy) { - mLast = System.currentTimeMillis(); - mAccuracyTextView.setText(accuracy+getString(R.string.m)); - - mDistance = updateProgress(point); - - /* - * here we will update the progress bar - * - */ - if(mPoint != null) - if(GeoUtils.isIntersecting(point, (float) (accuracy / 1E3), mPoint, Debug.RADIUS, Debug.FUDGE_FACTOR)) { - - mCount++; - - if(mCount > 5){ - Log.v(TAG, "Dest Reached, Stopping"); - mIOIOManager.setDriveValue(IOIOTruckValues.DRIVE_STOP); - updateGoButton(true); - updateLog(R.string.dest_reached); - } - } else { - Log.v(TAG, "Driving Forward"); - mCount = 0; - mIOIOManager.setDriveValue(IOIOTruckValues.DRIVE_FORWARD); - } - else{ - Log.v(TAG, "Lost GPS signal, stopping"); - mIOIOManager.setDriveValue(IOIOTruckValues.DRIVE_STOP); - } - - } - - /** - * Called when the user selects a point for the truck to drive to - * (non-Javadoc) - * @see com.TwentyCodes.android.location.LocationSelectedListener#onLocationSelected(com.google.android.maps.GeoPoint) - */ - @Override - public void onLocationSelected(GeoPoint point) { - mPoint = point; - mDistance = updateProgress(mMap.getUserLocation()); - updateLog(getString(R.string.point_selected)+point.toString()); - } - - /** - * Called when the application is paused. We want to disconnect with the - * IOIO at this point, as the user is no longer interacting with our - * application. - * @author ricky barrette - */ - @Override - protected void onPause() { - try { - mIOIOManager.abort(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - if(mLoggerThread != null) - mLoggerThread.abort(); - - if(mWakeLock.isHeld()) - mWakeLock.release(); - super.onPause(); - } - - /** - * (non-Javadoc) - * @see android.support.v4.app.FragmentActivity#onResume() - */ - @Override - protected void onResume() { - super.onResume(); - mMap = (MapFragment) this.getSupportFragmentManager().findFragmentById(R.id.map_fragment); - mMap.setCompassListener(this); - mMap.setGeoPointLocationListener(this); - mMap.setLocationSelectedListener(this); - mMap.setRadius((int) (Debug.RADIUS * 1E3)); - mIOIOManager = new IOIOTruckManager(this, this); - mIOIOManager.start(); - - PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE); - mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG); - mWakeLock.acquire(); - } - /** * updates the log with the provided string res * thread safe @@ -403,29 +488,10 @@ public class NavigationActivity extends FragmentActivity implements CompassListe * @author ricky barrette */ private int updateProgress(GeoPoint point) { - int distance = (int) (GeoUtils.distanceKm(point, mPoint) * 1000); - if (distance > mMaxDistance) { - mMaxDistance = distance; + int distance = (int) (GeoUtils.distanceKm(point, mMap.getDestination()) * 1000); + if (distance > mProgress.getMax()) mProgress.setMax(distance); - } mProgress.setProgress(distance); return distance; } - - /** - * Called when the IOIOTruckThread has a log it wants to display - * (non-Javadoc) - * @see com.TwentyCodes.android.IOIOTruck.IOIOTruckManager.IOIOTruckThreadListener#onLogUpdate(java.lang.String) - */ - @Override - public void onLogUpdate(String log) { - updateLog(log); - } - - @Override - public void onFirstFix(boolean isFirstFix) { - // TODO Auto-generated method stub - - } - -} \ No newline at end of file +}