Compare commits

..

14 Commits

Author SHA1 Message Date
36aa1d360a Fixed imports in CameraFragment
Signed-off-by: Ricky Barrette <rickbarrette@gmail.com>
2012-12-11 11:47:46 -05:00
b10f5d1c85 Added Joy stick classes and resources
Signed-off-by: Ricky Barrette <rickbarrette@gmail.com>
2012-12-11 11:47:12 -05:00
2c30e39eaa Added IOIO Lib sub module
Signed-off-by: Ricky Barrette <rickbarrette@gmail.com>
2012-12-11 11:19:53 -05:00
190acba99a Fixed call to GeoUtils.calculateBearing()
I had to compensate the bearing being feed into the method. It
was exspecting a float 0-360 and was receiving a float -180 to
180.

This simple fix increased the robot's navivation accuracy

Change-Id: I9f29d8c36a2d2e840bb3ee68303d2c77f6c0e5be
Signed-off-by: Ricky Barrette <rickbarrette@gmail.com>
2012-03-14 14:16:33 -04:00
57d885c3fc Improved GPS heading compensation
Change-Id: I63324db2649fd557a244c6133d38e72ce8988929
Signed-off-by: Ricky Barrette <rickbarrette@gmail.com>
2012-03-14 13:40:42 -04:00
500c7162e3 increased the radius from 16 feet to 30 feet
Change-Id: I2f4dc970df2fcb47bf396a0dccceb1341cd0a185
Signed-off-by: Ricky Barrette <rickbarrette@gmail.com>
2012-03-14 11:15:46 -04:00
7362d1701f Updated import for CompassListener
Change-Id: I11c1bf1b4263a83783fb2ca9c864b4d443e7f33a
Signed-off-by: Ricky Barrette <rickbarrette@gmail.com>
2012-03-14 11:14:14 -04:00
47f35c141e Commented out mIOIO as its not being used
Change-Id: I5a308a3d7b83196b93012923d148a8eea30e4203
Signed-off-by: Ricky Barrette <rickbarrette@gmail.com>
2012-03-12 11:46:54 -04:00
c762d9e2f4 Updated to meet api 3.22RC
Change-Id: I1577dedaef5b0267a6abdebcc1cf72eeb0b8d3db
Signed-off-by: Ricky Barrette <rickbarrette@gmail.com>
2012-03-12 11:44:57 -04:00
8b67f26ace Merge branch 'feature/multi-pointNav'
Conflicts:
	IOIOTruck/src/com/TwentyCodes/android/IOIOTruck/MapFragment.java
	IOIOTruck/src/com/TwentyCodes/android/IOIOTruck/NavigationActivity.java

Change-Id: If4178355445843f8bf082747942e3be547e3bfa8
Signed-off-by: Ricky Barrette <rickbarrette@gmail.com>
2012-03-11 18:08:31 -04:00
f6b9f664d0 Finished path navigation
Change-Id: Ibfba63ac41ae9e701851be58eff6ec984ae12e72
Signed-off-by: Ricky Barrette <rickbarrette@gmail.com>
2012-03-11 17:59:04 -04:00
b2475f8474 Updated onLocationChanged() to be synchronous and tweaked the waypoit
algorithm.

Change-Id: I1e29bfa072239dca7e4592f1de4db8e65537da73
Signed-off-by: Ricky Barrette <rickbarrette@gmail.com>
2012-03-10 12:11:11 -05:00
9174336fc9 Added waypoint dots to drawn path (overlay)
added a calls to set the compass's dest point when directions are
generated, and when a waypoint is changed.

refactored NavigationActivity (sorted)

Change-Id: Ibbb0a5651a12b00dcce4b3973609adf1c1648632
Signed-off-by: Ricky Barrette <rickbarrette@gmail.com>
2012-03-10 11:39:21 -05:00
e5f274993c Inital Commit of my mulitiple point navigation changes
Change-Id: I33996d4aaf6200b25cd46e95aba78330494c09a9
Signed-off-by: Ricky Barrette <rickbarrette@gmail.com>
2012-03-10 10:03:17 -05:00
21 changed files with 1397 additions and 288 deletions

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "ioiolib"]
path = ioiolib
url = git://rickbarrette.org/ioiolib

View File

@@ -4,6 +4,5 @@
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry kind="lib" path="/home/ricky/App/android-sdk-linux_86/extras/android-support-v4-r6-googlemaps.jar"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

View File

@@ -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

View File

@@ -8,8 +8,7 @@
# project structure.
# Project target.
target=Google Inc.:Google APIs:15
target=Google Inc.:Google APIs:17
android.library.reference.1=../../exception_handler_library/ExceptionHandlerLib
android.library.reference.2=../ioiolib/IOIOLib
android.library.reference.3=../../location_library/LocationLib
android.library.reference.1=../../ioiolib/IOIOLib
android.library.reference.2=../../exception_handler_library/ExceptionHandlerLib
android.library.reference.4=../../../workspace/Joystick

View File

@@ -0,0 +1,37 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.MobileAnarchy.Android.Widgets.Joystick.DualJoystickView
android:id="@+id/dualjoystickView" android:layout_gravity="center_horizontal"
android:layout_marginTop="5dip" android:layout_width="fill_parent"
android:layout_height="175dip" />
<TableLayout android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_gravity="center_horizontal"
android:layout_marginTop="10dip">
<TableRow>
<TextView android:text="X" android:layout_width="50dip"
android:layout_height="wrap_content"></TextView>
<TextView android:text="" android:id="@+id/TextViewX1"
android:layout_width="150dip" android:layout_height="wrap_content"></TextView>
<TextView android:text="X" android:layout_width="50dip"
android:layout_height="wrap_content"></TextView>
<TextView android:text="" android:id="@+id/TextViewX2"
android:layout_width="100dip" android:layout_height="wrap_content"></TextView>
</TableRow>
<TableRow>
<TextView android:text="Y" android:layout_width="wrap_content"
android:layout_height="wrap_content"></TextView>
<TextView android:text="" android:id="@+id/TextViewY1"
android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
<TextView android:text="Y" android:layout_width="wrap_content"
android:layout_height="wrap_content"></TextView>
<TextView android:text="" android:id="@+id/TextViewY2"
android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
</TableRow>
</TableLayout>
</LinearLayout>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.MobileAnarchy.Android.Widgets.Joystick.JoystickView
android:id="@+id/joystickView" android:layout_gravity="center_horizontal"
android:layout_marginTop="20dip" android:layout_width="175dip"
android:layout_height="175dip" />
<TableLayout android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_gravity="center_horizontal"
android:layout_marginTop="10dip">
<TableRow>
<TextView android:text="X" android:layout_width="50dip"
android:layout_height="wrap_content"></TextView>
<TextView android:text="" android:id="@+id/TextViewX"
android:layout_width="100dip" android:layout_height="wrap_content"></TextView>
</TableRow>
<TableRow>
<TextView android:text="Y" android:layout_width="wrap_content"
android:layout_height="wrap_content"></TextView>
<TextView android:text="" android:id="@+id/TextViewY"
android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
</TableRow>
</TableLayout>
</LinearLayout>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="DockPanel">
<attr name="handleButtonDrawableId" format="reference" />
<attr name="contentLayoutId" format="reference" />
<attr name="dockPosition" format="enum" />
<attr name="isOpen" format="boolean" />
<attr name="animationDuration" format="integer" />
</declare-styleable>
<declare-styleable name="ThresholdEditText">
<attr name="threshold" format="integer" />
<attr name="disableThresholdOnEmptyInput" format="boolean" />
</declare-styleable>
</resources>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2009 The Android Open Source Project Licensed under the
Apache License, Version 2.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for
the specific language governing permissions and limitations under the
License.
-->
<resources>
<!-- height of a normal list item in edit playlist mode -->
<dimen name="normal_height">66dip</dimen>
<!-- height of an expanded list item in edit playlist mode -->
<dimen name="expanded_height">132dip</dimen>
</resources>

View File

@@ -0,0 +1,156 @@
package com.MobileAnarchy.Android.Widgets.Joystick;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
public class DualJoystickView extends LinearLayout {
@SuppressWarnings("unused")
private static final String TAG = DualJoystickView.class.getSimpleName();
private final boolean D = false;
private Paint dbgPaint1;
private JoystickView stickL;
private JoystickView stickR;
private View pad;
public DualJoystickView(Context context) {
super(context);
stickL = new JoystickView(context);
stickR = new JoystickView(context);
initDualJoystickView();
}
public DualJoystickView(Context context, AttributeSet attrs) {
super(context, attrs);
stickL = new JoystickView(context, attrs);
stickR = new JoystickView(context, attrs);
initDualJoystickView();
}
private void initDualJoystickView() {
setOrientation(LinearLayout.HORIZONTAL);
if (D) {
dbgPaint1 = new Paint(Paint.ANTI_ALIAS_FLAG);
dbgPaint1.setColor(Color.CYAN);
dbgPaint1.setStrokeWidth(1);
dbgPaint1.setStyle(Paint.Style.STROKE);
}
pad = new View(getContext());
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
removeView(stickL);
removeView(stickR);
float padW = getMeasuredWidth() - (getMeasuredHeight() * 2);
int joyWidth = (int) ((getMeasuredWidth() - padW) / 2);
LayoutParams joyLParams = new LayoutParams(joyWidth,
getMeasuredHeight());
stickL.setLayoutParams(joyLParams);
stickR.setLayoutParams(joyLParams);
stickL.TAG = "L";
stickR.TAG = "R";
stickL.setPointerId(JoystickView.INVALID_POINTER_ID);
stickR.setPointerId(JoystickView.INVALID_POINTER_ID);
addView(stickL);
ViewGroup.LayoutParams padLParams = new ViewGroup.LayoutParams(
(int) padW, getMeasuredHeight());
removeView(pad);
pad.setLayoutParams(padLParams);
addView(pad);
addView(stickR);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
stickR.setTouchOffset(stickR.getLeft(), stickR.getTop());
}
public void setAutoReturnToCenter(boolean left, boolean right) {
stickL.setAutoReturnToCenter(left);
stickR.setAutoReturnToCenter(right);
}
public void setOnJostickMovedListener(JoystickMovedListener left,
JoystickMovedListener right) {
stickL.setOnJostickMovedListener(left);
stickR.setOnJostickMovedListener(right);
}
public void setOnJostickClickedListener(JoystickClickedListener left,
JoystickClickedListener right) {
stickL.setOnJostickClickedListener(left);
stickR.setOnJostickClickedListener(right);
}
public void setYAxisInverted(boolean leftYAxisInverted,
boolean rightYAxisInverted) {
stickL.setYAxisInverted(leftYAxisInverted);
stickL.setYAxisInverted(rightYAxisInverted);
}
public void setMovementConstraint(int movementConstraint) {
stickL.setMovementConstraint(movementConstraint);
stickR.setMovementConstraint(movementConstraint);
}
public void setMovementRange(float movementRangeLeft,
float movementRangeRight) {
stickL.setMovementRange(movementRangeLeft);
stickR.setMovementRange(movementRangeRight);
}
public void setMoveResolution(float leftMoveResolution,
float rightMoveResolution) {
stickL.setMoveResolution(leftMoveResolution);
stickR.setMoveResolution(rightMoveResolution);
}
public void setUserCoordinateSystem(int leftCoordinateSystem,
int rightCoordinateSystem) {
stickL.setUserCoordinateSystem(leftCoordinateSystem);
stickR.setUserCoordinateSystem(rightCoordinateSystem);
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if (D) {
canvas.drawRect(1, 1, getMeasuredWidth() - 1,
getMeasuredHeight() - 1, dbgPaint1);
}
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean l = stickL.dispatchTouchEvent(ev);
boolean r = stickR.dispatchTouchEvent(ev);
return l || r;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
boolean l = stickL.onTouchEvent(ev);
boolean r = stickR.onTouchEvent(ev);
return l || r;
}
}

View File

@@ -0,0 +1,7 @@
package com.MobileAnarchy.Android.Widgets.Joystick;
public interface JoystickClickedListener {
public void OnClicked();
public void OnReleased();
}

View File

@@ -0,0 +1,9 @@
package com.MobileAnarchy.Android.Widgets.Joystick;
public interface JoystickMovedListener {
public void OnMoved(int pan, int tilt);
public void OnReleased();
public void OnReturnedToCenter();
}

View File

@@ -0,0 +1,542 @@
package com.MobileAnarchy.Android.Widgets.Joystick;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.View;
public class JoystickView extends View {
public static final int INVALID_POINTER_ID = -1;
// =========================================
// Private Members
// =========================================
private final boolean D = false;
String TAG = "JoystickView";
private Paint dbgPaint1;
private Paint dbgPaint2;
private Paint bgPaint;
private Paint handlePaint;
private int innerPadding;
private int bgRadius;
private int handleRadius;
private int movementRadius;
private int handleInnerBoundaries;
private JoystickMovedListener moveListener;
private JoystickClickedListener clickListener;
// # of pixels movement required between reporting to the listener
private float moveResolution;
private boolean yAxisInverted;
private boolean autoReturnToCenter;
// Max range of movement in user coordinate system
public final static int CONSTRAIN_BOX = 0;
public final static int CONSTRAIN_CIRCLE = 1;
private int movementConstraint;
private float movementRange;
public final static int COORDINATE_CARTESIAN = 0; // Regular cartesian
// coordinates
public final static int COORDINATE_DIFFERENTIAL = 1; // Uses polar rotation
// of 45 degrees to
// calc differential
// drive paramaters
private int userCoordinateSystem;
// Records touch pressure for click handling
private float touchPressure;
private boolean clicked;
private float clickThreshold;
// Last touch point in view coordinates
private int pointerId = INVALID_POINTER_ID;
private float touchX, touchY;
// Last reported position in view coordinates (allows different reporting
// sensitivities)
private float reportX, reportY;
// Handle center in view coordinates
private float handleX, handleY;
// Center of the view in view coordinates
private int cX, cY;
// Size of the view in view coordinates
private int dimX;
// Cartesian coordinates of last touch point - joystick center is (0,0)
private int cartX, cartY;
// Polar coordinates of the touch point from joystick center
private double radial;
private double angle;
// User coordinates of last touch point
private int userX, userY;
// Offset co-ordinates (used when touch events are received from parent's
// coordinate origin)
private int offsetX;
private int offsetY;
// =========================================
// Constructors
// =========================================
public JoystickView(Context context) {
super(context);
initJoystickView();
}
public JoystickView(Context context, AttributeSet attrs) {
super(context, attrs);
initJoystickView();
}
public JoystickView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initJoystickView();
}
// =========================================
// Initialization
// =========================================
private void initJoystickView() {
setFocusable(true);
dbgPaint1 = new Paint(Paint.ANTI_ALIAS_FLAG);
dbgPaint1.setColor(Color.RED);
dbgPaint1.setStrokeWidth(1);
dbgPaint1.setStyle(Paint.Style.STROKE);
dbgPaint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
dbgPaint2.setColor(Color.GREEN);
dbgPaint2.setStrokeWidth(1);
dbgPaint2.setStyle(Paint.Style.STROKE);
bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
bgPaint.setColor(Color.GRAY);
bgPaint.setStrokeWidth(1);
bgPaint.setAlpha(80);
bgPaint.setStyle(Paint.Style.FILL_AND_STROKE);
handlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
handlePaint.setColor(Color.DKGRAY);
handlePaint.setStrokeWidth(1);
handlePaint.setStyle(Paint.Style.FILL_AND_STROKE);
innerPadding = 10;
setMovementRange(10);
setMoveResolution(1.0f);
setClickThreshold(0.4f);
setYAxisInverted(true);
setUserCoordinateSystem(COORDINATE_CARTESIAN);
setAutoReturnToCenter(true);
}
public void setAutoReturnToCenter(boolean autoReturnToCenter) {
this.autoReturnToCenter = autoReturnToCenter;
}
public boolean isAutoReturnToCenter() {
return autoReturnToCenter;
}
public void setUserCoordinateSystem(int userCoordinateSystem) {
if (userCoordinateSystem < COORDINATE_CARTESIAN
|| movementConstraint > COORDINATE_DIFFERENTIAL)
Log.e(TAG, "invalid value for userCoordinateSystem");
else
this.userCoordinateSystem = userCoordinateSystem;
}
public int getUserCoordinateSystem() {
return userCoordinateSystem;
}
public void setMovementConstraint(int movementConstraint) {
if (movementConstraint < CONSTRAIN_BOX
|| movementConstraint > CONSTRAIN_CIRCLE)
Log.e(TAG, "invalid value for movementConstraint");
else
this.movementConstraint = movementConstraint;
}
public int getMovementConstraint() {
return movementConstraint;
}
public boolean isYAxisInverted() {
return yAxisInverted;
}
public void setYAxisInverted(boolean yAxisInverted) {
this.yAxisInverted = yAxisInverted;
}
/**
* Set the pressure sensitivity for registering a click
*
* @param clickThreshold
* threshold 0...1.0f inclusive. 0 will cause clicks to never be
* reported, 1.0 is a very hard click
*/
public void setClickThreshold(float clickThreshold) {
if (clickThreshold < 0 || clickThreshold > 1.0f)
Log.e(TAG, "clickThreshold must range from 0...1.0f inclusive");
else
this.clickThreshold = clickThreshold;
}
public float getClickThreshold() {
return clickThreshold;
}
public void setMovementRange(float movementRange) {
this.movementRange = movementRange;
}
public float getMovementRange() {
return movementRange;
}
public void setMoveResolution(float moveResolution) {
this.moveResolution = moveResolution;
}
public float getMoveResolution() {
return moveResolution;
}
// =========================================
// Public Methods
// =========================================
public void setOnJostickMovedListener(JoystickMovedListener listener) {
this.moveListener = listener;
}
public void setOnJostickClickedListener(JoystickClickedListener listener) {
this.clickListener = listener;
}
// =========================================
// Drawing Functionality
// =========================================
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Here we make sure that we have a perfect circle
int measuredWidth = measure(widthMeasureSpec);
int measuredHeight = measure(heightMeasureSpec);
setMeasuredDimension(measuredWidth, measuredHeight);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
super.onLayout(changed, left, top, right, bottom);
int d = Math.min(getMeasuredWidth(), getMeasuredHeight());
dimX = d;
// dimY = d;
cX = d / 2;
cY = d / 2;
bgRadius = dimX / 2 - innerPadding;
handleRadius = (int) (d * 0.25);
handleInnerBoundaries = handleRadius;
movementRadius = Math.min(cX, cY) - handleInnerBoundaries;
}
private int measure(int measureSpec) {
int result = 0;
// Decode the measurement specifications.
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.UNSPECIFIED) {
// Return a default size of 200 if no bounds are specified.
result = 200;
} else {
// As you want to fill the available space
// always return the full available bounds.
result = specSize;
}
return result;
}
@Override
protected void onDraw(Canvas canvas) {
canvas.save();
// Draw the background
canvas.drawCircle(cX, cY, bgRadius, bgPaint);
// Draw the handle
handleX = touchX + cX;
handleY = touchY + cY;
canvas.drawCircle(handleX, handleY, handleRadius, handlePaint);
if (D) {
canvas.drawRect(1, 1, getMeasuredWidth() - 1,
getMeasuredHeight() - 1, dbgPaint1);
canvas.drawCircle(handleX, handleY, 3, dbgPaint1);
if (movementConstraint == CONSTRAIN_CIRCLE) {
canvas.drawCircle(cX, cY, this.movementRadius, dbgPaint1);
} else {
canvas.drawRect(cX - movementRadius, cY - movementRadius, cX
+ movementRadius, cY + movementRadius, dbgPaint1);
}
// Origin to touch point
canvas.drawLine(cX, cY, handleX, handleY, dbgPaint2);
int baseY = (int) (touchY < 0 ? cY + handleRadius : cY
- handleRadius);
canvas.drawText(
String.format("%s (%.0f,%.0f)", TAG, touchX, touchY),
handleX - 20, baseY - 7, dbgPaint2);
canvas.drawText(
"("
+ String.format("%.0f, %.1f", radial,
angle * 57.2957795) + (char) 0x00B0 + ")",
handleX - 20, baseY + 15, dbgPaint2);
}
// Log.d(TAG, String.format("touch(%f,%f)", touchX, touchY));
// Log.d(TAG, String.format("onDraw(%.1f,%.1f)\n\n", handleX, handleY));
canvas.restore();
}
// Constrain touch within a box
private void constrainBox() {
touchX = Math.max(Math.min(touchX, movementRadius), -movementRadius);
touchY = Math.max(Math.min(touchY, movementRadius), -movementRadius);
}
// Constrain touch within a circle
private void constrainCircle() {
float diffX = touchX;
float diffY = touchY;
double radial = Math.sqrt((diffX * diffX) + (diffY * diffY));
if (radial > movementRadius) {
touchX = (int) ((diffX / radial) * movementRadius);
touchY = (int) ((diffY / radial) * movementRadius);
}
}
public void setPointerId(int id) {
this.pointerId = id;
}
public int getPointerId() {
return pointerId;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_MOVE: {
return processMoveEvent(ev);
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP: {
if (pointerId != INVALID_POINTER_ID) {
// Log.d(TAG, "ACTION_UP");
returnHandleToCenter();
setPointerId(INVALID_POINTER_ID);
}
break;
}
case MotionEvent.ACTION_POINTER_UP: {
if (pointerId != INVALID_POINTER_ID) {
final int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
final int pointerId = ev.getPointerId(pointerIndex);
if (pointerId == this.pointerId) {
// Log.d(TAG, "ACTION_POINTER_UP: " + pointerId);
returnHandleToCenter();
setPointerId(INVALID_POINTER_ID);
return true;
}
}
break;
}
case MotionEvent.ACTION_DOWN: {
if (pointerId == INVALID_POINTER_ID) {
int x = (int) ev.getX();
if (x >= offsetX && x < offsetX + dimX) {
setPointerId(ev.getPointerId(0));
// Log.d(TAG, "ACTION_DOWN: " + getPointerId());
return true;
}
}
break;
}
case MotionEvent.ACTION_POINTER_DOWN: {
if (pointerId == INVALID_POINTER_ID) {
final int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
final int pointerId = ev.getPointerId(pointerIndex);
int x = (int) ev.getX(pointerId);
if (x >= offsetX && x < offsetX + dimX) {
// Log.d(TAG, "ACTION_POINTER_DOWN: " + pointerId);
setPointerId(pointerId);
return true;
}
}
break;
}
}
return false;
}
private boolean processMoveEvent(MotionEvent ev) {
if (pointerId != INVALID_POINTER_ID) {
final int pointerIndex = ev.findPointerIndex(pointerId);
// Translate touch position to center of view
float x = ev.getX(pointerIndex);
touchX = x - cX - offsetX;
float y = ev.getY(pointerIndex);
touchY = y - cY - offsetY;
// Log.d(TAG,
// String.format("ACTION_MOVE: (%03.0f, %03.0f) => (%03.0f, %03.0f)",
// x, y, touchX, touchY));
reportOnMoved();
invalidate();
touchPressure = ev.getPressure(pointerIndex);
reportOnPressure();
return true;
}
return false;
}
private void reportOnMoved() {
if (movementConstraint == CONSTRAIN_CIRCLE)
constrainCircle();
else
constrainBox();
calcUserCoordinates();
if (moveListener != null) {
boolean rx = Math.abs(touchX - reportX) >= moveResolution;
boolean ry = Math.abs(touchY - reportY) >= moveResolution;
if (rx || ry) {
this.reportX = touchX;
this.reportY = touchY;
// Log.d(TAG, String.format("moveListener.OnMoved(%d,%d)",
// (int)userX, (int)userY));
moveListener.OnMoved(userX, userY);
}
}
}
private void calcUserCoordinates() {
// First convert to cartesian coordinates
cartX = (int) (touchX / movementRadius * movementRange);
cartY = (int) (touchY / movementRadius * movementRange);
radial = Math.sqrt((cartX * cartX) + (cartY * cartY));
angle = Math.atan2(cartY, cartX);
// Invert Y axis if requested
if (!yAxisInverted)
cartY *= -1;
if (userCoordinateSystem == COORDINATE_CARTESIAN) {
userX = cartX;
userY = cartY;
} else if (userCoordinateSystem == COORDINATE_DIFFERENTIAL) {
userX = cartY + cartX / 4;
userY = cartY - cartX / 4;
if (userX < -movementRange)
userX = (int) -movementRange;
if (userX > movementRange)
userX = (int) movementRange;
if (userY < -movementRange)
userY = (int) -movementRange;
if (userY > movementRange)
userY = (int) movementRange;
}
}
// Simple pressure click
private void reportOnPressure() {
// Log.d(TAG, String.format("touchPressure=%.2f", this.touchPressure));
if (clickListener != null) {
if (clicked && touchPressure < clickThreshold) {
clickListener.OnReleased();
this.clicked = false;
// Log.d(TAG, "reset click");
invalidate();
} else if (!clicked && touchPressure >= clickThreshold) {
clicked = true;
clickListener.OnClicked();
// Log.d(TAG, "click");
invalidate();
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
}
}
}
private void returnHandleToCenter() {
if (autoReturnToCenter) {
final int numberOfFrames = 5;
final double intervalsX = (0 - touchX) / numberOfFrames;
final double intervalsY = (0 - touchY) / numberOfFrames;
for (int i = 0; i < numberOfFrames; i++) {
final int j = i;
postDelayed(new Runnable() {
@Override
public void run() {
touchX += intervalsX;
touchY += intervalsY;
reportOnMoved();
invalidate();
if (moveListener != null && j == numberOfFrames - 1) {
moveListener.OnReturnedToCenter();
}
}
}, i * 40);
}
if (moveListener != null) {
moveListener.OnReleased();
}
}
}
public void setTouchOffset(int x, int y) {
offsetX = x;
offsetY = y;
}
}

View File

@@ -20,7 +20,7 @@
*/
package com.TwentyCodes.android.IOIOTruck;
import com.TwentyCodes.android.IOIOTruck.IOIOTruckManager.IOIOTruckThreadListener;
import com.TwentyCodes.android.IOIOTruck.IOIOTruckConnectionManager.IOIOTruckThreadListener;
import android.content.Context;
import android.os.Bundle;
@@ -40,7 +40,7 @@ import android.widget.TextView;
public class CameraActivity extends FragmentActivity implements IOIOTruckThreadListener {
private static final String TAG = "CameraActivity";
private IOIOTruckManager mIOIOManager;
private IOIOTruckConnectionManager mIOIOManager;
private WakeLock mWakeLock;
private TextView mLogTextView;
@@ -54,6 +54,28 @@ public class CameraActivity extends FragmentActivity implements IOIOTruckThreadL
super.onCreate(icicle);
setContentView(R.layout.camera_activity);
mLogTextView = (TextView) findViewById(R.id.log_textView);
mIOIOManager = new IOIOTruckConnectionManager(this, this);
mIOIOManager.getIOIOAndroidApplicationHelper().create();
}
/**
* (non-Javadoc)
* @see android.support.v4.app.FragmentActivity#onDestroy()
*/
@Override
protected void onDestroy() {
mIOIOManager.getIOIOAndroidApplicationHelper().destroy();
super.onDestroy();
}
/**
* Called when the IOIO Manager wants to log something
* (non-Javadoc)
* @see com.TwentyCodes.android.IOIOTruck.IOIOTruckConnectionManager.IOIOTruckThreadListener#onLogUpdate(java.lang.String)
*/
@Override
public void onLogUpdate(String log) {
mLogTextView.setText(log);
}
/**
@@ -64,15 +86,20 @@ public class CameraActivity extends FragmentActivity implements IOIOTruckThreadL
@Override
protected void onPause() {
super.onPause();
try {
mIOIOManager.abort();
} catch (InterruptedException e) {
e.printStackTrace();
}
if(mWakeLock.isHeld())
mWakeLock.release();
}
/**
* (non-Javadoc)
* @see android.app.Activity#onRestart()
*/
@Override
protected void onRestart() {
mIOIOManager.getIOIOAndroidApplicationHelper().restart();
super.onRestart();
}
/**
* Called when the activity is resuming
* (non-Javadoc)
@@ -80,8 +107,6 @@ public class CameraActivity extends FragmentActivity implements IOIOTruckThreadL
*/
@Override
protected void onResume() {
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);
@@ -90,13 +115,23 @@ public class CameraActivity extends FragmentActivity implements IOIOTruckThreadL
}
/**
* Called when the IOIO Manager wants to log something
* (non-Javadoc)
* @see com.TwentyCodes.android.IOIOTruck.IOIOTruckManager.IOIOTruckThreadListener#onLogUpdate(java.lang.String)
* @see android.support.v4.app.FragmentActivity#onStart()
*/
@Override
public void onLogUpdate(String log) {
mLogTextView.setText(log);
protected void onStart() {
mIOIOManager.getIOIOAndroidApplicationHelper().start();
super.onStart();
}
/**
* (non-Javadoc)
* @see android.support.v4.app.FragmentActivity#onStop()
*/
@Override
protected void onStop() {
mIOIOManager.getIOIOAndroidApplicationHelper().stop();
super.onStop();
}
}

View File

@@ -39,8 +39,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.TwentyCodes.android.location.R;
/**
* This camera fragment will be used to maintain the camera, display a preview on the screen, display a vanishing point overlay on the preview
* @author ricky barrette

View File

@@ -34,7 +34,7 @@ public class Debug {
/**
* Sets the size of the radius of a user selected point in km
*/
public static final float RADIUS = .005f;
public static final float RADIUS = 0.009144f;
/**
* Sets the amount of kilometers that a radius needs to be penetrated by an accuracy circle in km

View File

@@ -25,15 +25,17 @@ import ioio.lib.api.DigitalOutput;
import ioio.lib.api.IOIO;
import ioio.lib.api.PwmOutput;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.IOIOLooper;
import ioio.lib.util.IOIOLooperProvider;
import ioio.lib.util.android.IOIOAndroidApplicationHelper;
import android.app.Activity;
import com.TwentyCodes.android.ioio.IOIOManager;
import android.util.Log;
/**
* This IOIO thread will be used to drive a rc truck
* @author ricky barrette
*/
public class IOIOTruckManager extends IOIOManager {
public class IOIOTruckConnectionManager implements IOIOLooper, IOIOLooperProvider {
/**
* This listener will be used to notify the owner of this thread to update the onscreen log
@@ -55,6 +57,10 @@ public class IOIOTruckManager extends IOIOManager {
private DigitalOutput mMotorDriverStandBy;
private DigitalInput mLeftFrontBumber;
private DigitalInput mRightFrontBumber;
private boolean isStatLedEnabled;
private IOIOAndroidApplicationHelper mIOIOAndroidApplicationHelper;
// private IOIO mIOIO;
private DigitalOutput mStatLed;
/**
* Creates a new IOIOTruckThread
@@ -62,8 +68,9 @@ public class IOIOTruckManager extends IOIOManager {
* @param listener
* @author ricky barrette
*/
public IOIOTruckManager(Activity activity, IOIOTruckThreadListener listener){
public IOIOTruckConnectionManager(Activity activity, IOIOTruckThreadListener listener){
super();
mIOIOAndroidApplicationHelper = new IOIOAndroidApplicationHelper(activity, this);
mActivity = activity;
mListener = listener;
updateLog(R.string.wait_ioio);
@@ -111,9 +118,11 @@ public class IOIOTruckManager extends IOIOManager {
* @see com.TwentyCodes.android.ioio.IOIOThread#onConnected()
*/
@Override
public void onConnected(IOIO ioio) throws ConnectionLostException {
public void setup(IOIO ioio) throws ConnectionLostException,InterruptedException {
updateLog(R.string.ioio_connected);
// mIOIO = ioio;
mStatLed = ioio.openDigitalOutput(0, true);
mShifter = ioio.openPwmOutput(IOIOTruckValues.SHIFTER_PORT, IOIOTruckValues.RC_PWM_FRQ);
mLeftMotor = new TB6612FNGMotorDriver(ioio, IOIOTruckValues.MOTOR_DRIVER_PWMA, IOIOTruckValues.MOTOR_DRIVER_A1, IOIOTruckValues.MOTOR_DRIVER_A2);
mRightMotor = new TB6612FNGMotorDriver(ioio, IOIOTruckValues.MOTOR_DRIVER_PWMB, IOIOTruckValues.MOTOR_DRIVER_B1, IOIOTruckValues.MOTOR_DRIVER_B2);
@@ -133,7 +142,7 @@ public class IOIOTruckManager extends IOIOManager {
* @see com.TwentyCodes.android.ioio.IOIOThread#onDisconnect()
*/
@Override
public void onDisconnected() {
public void disconnected() {
updateLog(R.string.wait_ioio);
}
@@ -145,35 +154,40 @@ public class IOIOTruckManager extends IOIOManager {
@Override
public void loop() throws ConnectionLostException, InterruptedException {
this.setStatLedEnabled(isStatLedEnabled());
mShifter.setPulseWidth(mShifterValue);
/*
* we need to check our sensors before we can make a move.
*/
if(mLeftFrontBumber.read()){
//TODO backup, spin right, drive forward
setStatLedEnabled(false);
isStatLedEnabled = false;
} else if(mRightFrontBumber.read()){
//TODO backup, spin left, drive forward
setStatLedEnabled(false);
isStatLedEnabled = false;
}
mMotorDriverStandBy.write(isStatLedEnabled());
// mIOIO.beginBatch();
mStatLed.write(!isStatLedEnabled);
mShifter.setPulseWidth(mShifterValue);
mMotorDriverStandBy.write(isStatLedEnabled);
/*
* if the autonomous routine is running
* then drive the truck
* else stop the truck
*/
if(isStatLedEnabled()){
if(isStatLedEnabled){
arcadeDrive();
}
else{
mLeftMotor.setSpeed(0);
mRightMotor.setSpeed(0);
}
// mIOIO.endBatch();
}
/**
@@ -211,4 +225,40 @@ public class IOIOTruckManager extends IOIOManager {
}
});
}
@Override
public void incompatible() {
// TODO Auto-generated method stub
}
@Override
public IOIOLooper createIOIOLooper(String connectionType, Object extra) {
Log.v(TAG, connectionType);
return this;
}
/**
* @return the mIOIOAndroidApplicationHelper
*/
public IOIOAndroidApplicationHelper getIOIOAndroidApplicationHelper() {
return mIOIOAndroidApplicationHelper;
}
/**
* set the status of the led
* @param b
* @author ricky barrette
*/
public void setStatLedEnabled(boolean b) {
this.isStatLedEnabled = b;
}
/**
* @return state of status led
* @author ricky barrette
*/
public boolean isStatLedEnabled(){
return this.isStatLedEnabled;
}
}

View File

@@ -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);

View File

@@ -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);
}
}
}

View File

@@ -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;
@@ -38,11 +41,14 @@ import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import com.TwentyCodes.android.IOIOTruck.IOIOTruckManager.IOIOTruckThreadListener;
import com.TwentyCodes.android.location.CompassListener;
import com.TwentyCodes.android.IOIOTruck.IOIOTruckConnectionManager.IOIOTruckThreadListener;
import com.TwentyCodes.android.location.CompassSensor.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,30 @@ public class NavigationActivity extends FragmentActivity implements CompassListe
}
}
private static final String TAG = "NavigationActivity";
private IOIOTruckConnectionManager 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<GeoPoint> mPoints;
private int mIndex = 0;
private GeoPoint mDestPoint;
private ArrayList<PathOverlay> mWayPoints;
private GeoPoint mLastReportedLocation;
private float mHeading = 0;
private long mLastReportedTime;
/**
* Called when the scrolling switch is checked
@@ -161,7 +168,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 +177,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 +188,290 @@ 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) {
mBearing = bearing;
if(Debug.DEBUG)
Log.v(TAG, "Bearing ="+bearing);
/*
* used calculated bearing if the last location was updated less than a x ago
*/
if((System.currentTimeMillis() - mLastReportedTime) < 500)
mHeading = bearing;
if(Debug.DEBUG)
Log.v(TAG, "Heading ="+mHeading);
bearing = GeoUtils.calculateBearing(mMap.getUserLocation(), mMap.getDestination(), bearing < 0 ? bearing + 360 : 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);
}
/**
* (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);
mIOIOManager = new IOIOTruckConnectionManager(this, this);
mIOIOManager.getIOIOAndroidApplicationHelper().create();
}
/**
* (non-Javadoc)
* @see android.support.v4.app.FragmentActivity#onDestroy()
*/
@Override
protected void onDestroy() {
mIOIOManager.getIOIOAndroidApplicationHelper().destroy();
super.onDestroy();
}
/**
* 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<PathOverlay> path = directionsOverlay.getPath();
if(path.size() > 0){
mWayPoints = new ArrayList<PathOverlay>();
ArrayList<GeoPoint> points = new ArrayList<GeoPoint>();
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(mLastReportedLocation != null){
if(!point.equals(mLastReportedLocation)){
mLastReportedTime = mLast;
float heading = new Float(GeoUtils.bearing(mLastReportedLocation, point));
mHeading = heading > 180 ? heading -360 : heading;
if(Debug.DEBUG)
updateLog("Heading = "+ mHeading);
}
}
mLastReportedLocation = point;
if(currentDest != null)
/*
* are we closer than 30 feet?
*/
// if (GeoUtils.distanceKm(point, currentDest) < Debug.FUDGE_FACTOR) {
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.IOIOTruckConnectionManager.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() {
if(mLoggerThread != null)
mLoggerThread.abort();
if(mWakeLock.isHeld())
mWakeLock.release();
super.onPause();
}
/**
* (non-Javadoc)
* @see android.app.Activity#onRestart()
*/
@Override
protected void onRestart() {
mIOIOManager.getIOIOAndroidApplicationHelper().restart();
super.onRestart();
}
/**
* (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();
PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG);
mWakeLock.acquire();
}
/**
* (non-Javadoc)
* @see android.support.v4.app.FragmentActivity#onStart()
*/
@Override
protected void onStart() {
mIOIOManager.getIOIOAndroidApplicationHelper().start();
super.onStart();
}
/**
* (non-Javadoc)
* @see android.support.v4.app.FragmentActivity#onStop()
*/
@Override
protected void onStop() {
mIOIOManager.getIOIOAndroidApplicationHelper().stop();
super.onStop();
}
/**
* updates the go/stop button based on isRunning
* thread safe
@@ -189,7 +480,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 +510,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
@@ -380,6 +528,7 @@ public class NavigationActivity extends FragmentActivity implements CompassListe
runOnUiThread(new Runnable() {
@Override
public void run() {
mLog.append("\n"+log);
/*
@@ -403,29 +552,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
}
}
}

View File

@@ -32,7 +32,7 @@ import android.widget.TextView;
import com.MobileAnarchy.Android.Widgets.Joystick.JoystickMovedListener;
import com.MobileAnarchy.Android.Widgets.Joystick.JoystickView;
import com.TwentyCodes.android.IOIOTruck.IOIOTruckManager.IOIOTruckThreadListener;
import com.TwentyCodes.android.IOIOTruck.IOIOTruckConnectionManager.IOIOTruckThreadListener;
import com.TwentyCodes.android.exception.ExceptionHandler;
/**
@@ -50,7 +50,17 @@ public class TestActivity extends Activity implements JoystickMovedListener, OnS
private TextView mDriveTextView;
private TextView mSteerTextView;
private TextView mShifterTextView;
private IOIOTruckManager mIOIOManager;
private IOIOTruckConnectionManager mIOIOManager;
/**
* Called when the led swich is toggled
* (non-Javadoc)
* @see android.widget.CompoundButton.OnCheckedChangeListener#onCheckedChanged(android.widget.CompoundButton, boolean)
*/
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mIOIOManager.setStatLedEnabled(isChecked);
}
/**
* Called when the activity is first created
@@ -82,34 +92,28 @@ public class TestActivity extends Activity implements JoystickMovedListener, OnS
mDriveTextView.setText(getString(R.string.drive)+1500);
mSteerTextView.setText(getString(R.string.steer)+1500);
mShifterTextView.setText(getString(R.string.shifter)+1500);
mIOIOManager = new IOIOTruckConnectionManager(this, this);
mIOIOManager.getIOIOAndroidApplicationHelper().create();
}
/**
* Called when the application is resumed (also when first started). Here is
* where we'll create our IOIO thread.
* @author ricky barrette
* (non-Javadoc)
* @see android.app.Activity#onDestroy()
*/
@Override
protected void onResume() {
super.onResume();
mIOIOManager = new IOIOTruckManager(this, this);
mIOIOManager.start();
protected void onDestroy() {
mIOIOManager.getIOIOAndroidApplicationHelper().destroy();
super.onDestroy();
}
/**
* 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
* Called when the IOIOTruckThread has a log to publish
* (non-Javadoc)
* @see com.TwentyCodes.android.IOIOTruck.IOIOTruckConnectionManager.IOIOTruckThreadListener#onLogUpdate(java.lang.String)
*/
@Override
protected void onPause() {
super.onPause();
try {
mIOIOManager.abort();
} catch (InterruptedException e) {
e.printStackTrace();
}
public void onLogUpdate(String log) {
mStatusTextView.setText(log);
}
/**
@@ -127,6 +131,19 @@ public class TestActivity extends Activity implements JoystickMovedListener, OnS
mSteerTextView.setText(getString(R.string.steer)+mIOIOManager.getSteerValue());//steer);
}
/**
* Called when the shifter seekbar is adjusted
* (non-Javadoc)
* @see android.widget.SeekBar.OnSeekBarChangeListener#onProgressChanged(android.widget.SeekBar, int, boolean)
*/
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
float shifter = progress + 1000;
mIOIOManager.setShifterValue(progress + 1000);
mShifterTextView.setText(getString(R.string.shifter)+ shifter);
}
/**
* Called when the joystick is released
* (non-Javadoc)
@@ -137,6 +154,16 @@ public class TestActivity extends Activity implements JoystickMovedListener, OnS
//NOT USED
}
/**
* (non-Javadoc)
* @see android.app.Activity#onRestart()
*/
@Override
protected void onRestart() {
mIOIOManager.getIOIOAndroidApplicationHelper().restart();
super.onRestart();
}
/**
* Called when the joystick ir returned to center
* (non-Javadoc)
@@ -150,16 +177,13 @@ public class TestActivity extends Activity implements JoystickMovedListener, OnS
}
/**
* Called when the shifter seekbar is adjusted
* (non-Javadoc)
* @see android.widget.SeekBar.OnSeekBarChangeListener#onProgressChanged(android.widget.SeekBar, int, boolean)
* @see android.app.Activity#onStart()
*/
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
float shifter = progress + 1000;
mIOIOManager.setShifterValue(progress + 1000);
mShifterTextView.setText(getString(R.string.shifter)+ shifter);
protected void onStart() {
mIOIOManager.getIOIOAndroidApplicationHelper().start();
super.onStart();
}
@Override
@@ -167,28 +191,18 @@ public class TestActivity extends Activity implements JoystickMovedListener, OnS
//NOT USED
}
/**
* (non-Javadoc)
* @see android.app.Activity#onStop()
*/
@Override
protected void onStop() {
mIOIOManager.getIOIOAndroidApplicationHelper().stop();
super.onStop();
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
//NOT USED
}
/**
* Called when the led swich is toggled
* (non-Javadoc)
* @see android.widget.CompoundButton.OnCheckedChangeListener#onCheckedChanged(android.widget.CompoundButton, boolean)
*/
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mIOIOManager.setStatLedEnabled(isChecked);
}
/**
* Called when the IOIOTruckThread has a log to publish
* (non-Javadoc)
* @see com.TwentyCodes.android.IOIOTruck.IOIOTruckManager.IOIOTruckThreadListener#onLogUpdate(java.lang.String)
*/
@Override
public void onLogUpdate(String log) {
mStatusTextView.setText(log);
}
}

1
ioiolib Submodule

Submodule ioiolib added at efb63070a2