Compare commits
14 Commits
f32e6eb842
...
36aa1d360a
| Author | SHA1 | Date | |
|---|---|---|---|
| 36aa1d360a | |||
| b10f5d1c85 | |||
| 2c30e39eaa | |||
| 190acba99a | |||
| 57d885c3fc | |||
| 500c7162e3 | |||
| 7362d1701f | |||
| 47f35c141e | |||
| c762d9e2f4 | |||
| 8b67f26ace | |||
| f6b9f664d0 | |||
| b2475f8474 | |||
| 9174336fc9 | |||
| e5f274993c |
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "ioiolib"]
|
||||
path = ioiolib
|
||||
url = git://rickbarrette.org/ioiolib
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
37
IOIOTruck/res/layout/dualjoystick.xml
Normal file
37
IOIOTruck/res/layout/dualjoystick.xml
Normal 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>
|
||||
28
IOIOTruck/res/layout/joystick.xml
Normal file
28
IOIOTruck/res/layout/joystick.xml
Normal 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>
|
||||
17
IOIOTruck/res/values/attr.xml
Normal file
17
IOIOTruck/res/values/attr.xml
Normal 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>
|
||||
19
IOIOTruck/res/values/dimen.xml
Normal file
19
IOIOTruck/res/values/dimen.xml
Normal 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>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.MobileAnarchy.Android.Widgets.Joystick;
|
||||
|
||||
public interface JoystickClickedListener {
|
||||
public void OnClicked();
|
||||
|
||||
public void OnReleased();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
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
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
1
ioiolib
Submodule
Submodule ioiolib added at efb63070a2
Reference in New Issue
Block a user