Initial Commit

This commit is contained in:
2012-01-22 13:53:19 -05:00
commit 2b3f9f8954
19 changed files with 1512 additions and 0 deletions

9
IOIOTruck/.classpath Normal file
View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<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>

33
IOIOTruck/.project Normal file
View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>IOIOTruck</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.TwentyCodes.android.IOIOTruck"
android:versionCode="8"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<application
android:icon="@drawable/icon"
android:label="@string/app_name" >
<activity
android:name="Main"
android:configChanges="keyboard|keyboardHidden|orientation"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Holo.Light.NoActionBar" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="TestActivity"
android:configChanges="keyboard|keyboardHidden|orientation"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Holo.Light.NoActionBar" >
</activity>
<activity
android:name="com.TwentyCodes.android.exception.ExceptionReportActivity"
android:configChanges="keyboard|keyboardHidden|orientation"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Holo.Light.NoActionBar" >
</activity>
<activity
android:name="NavigationActivity"
android:configChanges="keyboard|keyboardHidden|orientation"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Holo.Light.NoActionBar" >
</activity>
<uses-library android:name="com.google.android.maps" />
</application>
</manifest>

View File

@@ -0,0 +1,19 @@
# exceptionhandler.properties
# This is the default Twenty Codes, LLC Exception Handler properties file
#
# @author Twenty Codes, LLC
# @author ricky barrette
# The following is for using our custom server based exception handler web application
# HTTP ONLY
# server is the physical web address for your server
# file is the path to your filing script
# get is the path to your json retrieval script
server = http://powers.doesntexist.com:666/testing
file = /index.php?post=1
#get = /index.php?get=1
# uncomment the following if you want your application to use email to file reports.
# if this is uncommented, email will always be used.
#email = twentycodes@gmail.com

3
IOIOTruck/lint.xml Normal file
View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<lint>
</lint>

40
IOIOTruck/proguard.cfg Normal file
View File

@@ -0,0 +1,40 @@
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}

View File

@@ -0,0 +1,15 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "ant.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=Google Inc.:Google APIs:15
android.library.reference.3=../LocationLib
android.library.reference.4=../../git/ioiolib
android.library.reference.1=../ExceptionHandlerLib
android.library.reference.2=../Joystick

BIN
IOIOTruck/res/drawable/icon.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,98 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/app_name"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="@string/by"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
<Button
android:id="@+id/test_activity_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/test_activity" />
<Button
android:id="@+id/nav_activity_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/nav_activity" />
<RelativeLayout
android:id="@+id/relativeLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="@string/about"
android:textAppearance="?android:attr/textAppearanceLarge" />
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dip"
android:text="@string/version"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/version_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
<ScrollView
android:id="@+id/scrollView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/linearLayout2"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/textView3" >
<TextView
android:id="@+id/textView4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/about_msg" />
</ScrollView>
</RelativeLayout>
</LinearLayout>

View File

@@ -0,0 +1,100 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<RelativeLayout
android:id="@+id/relativeLayout1"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="2" >
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/map_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.TwentyCodes.android.IOIOTruck.MapFragment" >
<!-- Preview: layout=@layout/map_fragment -->
</fragment>
<TextView
android:id="@+id/accuracy_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:textColor="#FF0000" />
<TextView
android:id="@+id/time_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@id/accuracy_textview"
android:textColor="#FF0000" />
<ImageButton
android:id="@+id/mark_my_lcoation_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:src="@drawable/mark_my_location_action_bar" />
<ImageButton
android:id="@+id/my_location_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/mark_my_lcoation_button"
android:layout_alignParentRight="true"
android:src="@drawable/my_location_action_bar" />
</RelativeLayout>
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/log"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Switch
android:id="@+id/scrolling_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="40dip"
android:checked="true"
android:text="@string/scrolling" />
</LinearLayout>
<ScrollView
android:id="@+id/scrollview"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1" >
<TextView
android:id="@+id/log_textView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</ScrollView>
<Button
android:id="@+id/go_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/go" />
</LinearLayout>

View File

@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon" />
<Switch
android:id="@+id/led_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/led" />
</LinearLayout>
<SeekBar
android:id="@+id/skeekbar1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:max="1000"
android:progress="500" />
<com.MobileAnarchy.Android.Widgets.Joystick.JoystickView
android:id="@+id/joystick"
android:layout_width="300dip"
android:layout_height="300dip"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dip" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal" >
<TextView
android:id="@+id/tv_drive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dip"
android:text="@string/drive"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="@+id/tv_steer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dip"
android:text="@string/steer"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="@+id/tv_shifter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dip"
android:text="@string/shifter"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
</LinearLayout>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, Main!</string>
<string name="app_name">IOIOTruck</string>
<string name="wait_ioio">Waiting for IOIO to connect…</string>
<string name="ioio_connected">IOIO connected!</string>
<string name="led">Led</string>
<string name="drive">Drive: </string>
<string name="steer">Steer: </string>
<string name="shifter">Shifter: </string>
<string name="test_activity">Function Test Activity</string>
<string name="nav_activity">Navigation Activity</string>
<string name="log">Log</string>
<string name="go">Go…</string>
<string name="stop">Stop…</string>
<string name="scrolling">Scrolling</string>
<string name="last_update">Last Update: </string>
<string name="ms">ms</string>
<string name="m">m</string>
<string name="by">by Twenty Codes, LLC</string>
<string name="version">Version</string>
<string name="about">About</string>
<string name="about_msg">This application is used to demonstrate the power of an Android phone coupled with the IOIO bord can autonomously drive a remote controlled truck or car to a point selected on a map.\n There is two parts of this application, the first is a Funtion Test activity and the second is the Navigation activity. The Function Test activity allows you to test all the featuers of your rc truck and the IOIO. The Navigation activity allows you to select a point on the map and hit Go. The truck will drive to the point selected on the map and stop once it is there. \n\nSpeed controller Port: 3 \nSteering servo Port: 5 \nShifter servo Port: 4</string>
<string name="build">build</string>
<string name="no_gps_signal">No GPS signal at this time, please try agian</string>
<string name="point_selected">Location Selected: </string>
<string name="dest_reached">Destination reached</string>
</resources>

View File

@@ -0,0 +1,30 @@
/**
* Debug.java
* @date Jan 7, 2012
* @author ricky barrette
* @author Twenty Codes, LLC
*/
package com.TwentyCodes.android.IOIOTruck;
/**
* This class will hold constants used for debuging
* @author ricky barrette
*/
public class Debug {
/**
* Allows the application to print to the system log
*/
public static final boolean DEBUG = true;
/**
* Sets the size of the radius of a user selected point in km
*/
public static final float RADIUS = .010f;
/**
* Sets the amount of kilometers that a radius needs to be penetrated by an accuracy circle in km
*/
public static final float FUDGE_FACTOR = .005f;
}

View File

@@ -0,0 +1,203 @@
/**
* IOIOTruckThread.java
* @date Jan 11, 2012
* @author ricky barrette
* @author Twenty Codes, LLC
*/
package com.TwentyCodes.android.IOIOTruck;
import ioio.lib.api.IOIO;
import ioio.lib.api.PwmOutput;
import ioio.lib.api.exception.ConnectionLostException;
import android.app.Activity;
import android.util.Log;
import com.TwentyCodes.android.IOIOTruck.R;
import com.TwentyCodes.android.ioio.IOIOManager;
/**
* This IOIO thread will be used to drive a rc truck
* @author ricky barrette
*/
public class IOIOTruckManager extends IOIOManager {
/**
* This listener will be used to notify the owner of this thread to update the onscreen log
* @author ricky barrette
*/
public interface IOIOTruckThreadListener{
public void onLogUpdate(String log);
}
private static final String TAG = "IOIOTruckThread";
private Activity mActivity;
private IOIOTruckThreadListener mListener;
private PwmOutput mDrive;
private PwmOutput mSteer;
private PwmOutput mShifter;
private int mDriveValue;
private int mSteerValue;
private int mShifterValue;
private boolean mStatLedValue;
private boolean isTank = false;
/**
* Creates a new IOIOTruckThread
* @param activity
* @param listener
* @author ricky barrette
*/
public IOIOTruckManager(Activity activity, IOIOTruckThreadListener listener){
super();
mActivity = activity;
mListener = listener;
updateLog(R.string.wait_ioio);
}
private void arcadeDrive() {
int left, right;
left = (mDriveValue + mSteerValue) /2;
right = (mDriveValue - mSteerValue) / 2;
mDriveValue = left;
mSteerValue = right + 1500;
Log.d(TAG, "left: "+ mDriveValue + " right: "+ mSteerValue);
}
/**
* @return the mDriveValue
*/
public synchronized int getDriveValue() {
return mDriveValue;
}
/**
* @return the mShifterValue
*/
public synchronized int getShifterValue() {
return mShifterValue;
}
/**
* @return the mSteerValue
*/
public synchronized int getSteerValue() {
return mSteerValue;
}
/**
* @return the mStatLedValue
*/
public synchronized boolean isStatLedValue() {
return mStatLedValue;
}
/**
* Here we register and initialize each port
* (non-Javadoc)
* @throws ConnectionLostException
* @see com.TwentyCodes.android.ioio.IOIOThread#onConnected()
*/
@Override
public void onConnected(IOIO ioio) throws ConnectionLostException {
updateLog(R.string.ioio_connected);
mDrive = ioio.openPwmOutput(IOIOTruckValues.DRIVE_PORT, IOIOTruckValues.RC_PWM_FRQ);
mSteer = ioio.openPwmOutput(IOIOTruckValues.STEER_PORT, IOIOTruckValues.RC_PWM_FRQ);
mShifter = ioio.openPwmOutput(IOIOTruckValues.SHIFTER_PORT, IOIOTruckValues.RC_PWM_FRQ);
}
/**
* (non-Javadoc)
* @see com.TwentyCodes.android.ioio.IOIOThread#onDisconnect()
*/
@Override
public void onDisconnected() {
updateLog(R.string.wait_ioio);
}
/**
* (non-Javadoc)
* @throws ConnectionLostException
* @see com.TwentyCodes.android.ioio.IOIOThread#onUpdate()
*/
@Override
public void loop() throws ConnectionLostException {
this.setStatLedEnabled(mStatLedValue);
if(isTank){
arcadeDrive();
mSteer.setPulseWidth(mSteerValue);
mDrive.setPulseWidth(mDriveValue);
}
else {
/*
* if the autonomous routine is running
* then drive the truck
* else stop the truck
*/
if(mStatLedValue)
mDrive.setPulseWidth(mDriveValue);
else
mDrive.setPulseWidth(IOIOTruckValues.DRIVE_STOP);
}
mSteer.setPulseWidth(mSteerValue);
mShifter.setPulseWidth(mShifterValue);
}
/**
* @param mDriveValue the mDriveValue to set
*/
public synchronized void setDriveValue(int mDriveValue) {
this.mDriveValue = mDriveValue;
}
/**
* @param mShifterValue the mShifterValue to set
*/
public synchronized void setShifterValue(int mShifterValue) {
this.mShifterValue = mShifterValue;
}
/**
* @param mStatLedValue the mStatLedValue to set
*/
public synchronized void setStatLedValue(boolean mStatLedValue) {
this.mStatLedValue = mStatLedValue;
}
/**
* @param mSteerValue the mSteerValue to set
*/
public synchronized void setSteerValue(int mSteerValue) {
this.mSteerValue = mSteerValue;
}
/**
* @param isTankDrive
* @author ricky barrette
*/
public synchronized void setTankDrive(boolean isTankDrive){
isTank = isTankDrive;
}
/**
* updates the log listener in the UI thread
* @param resId
* @author ricky barrette
*/
private void updateLog(final int resId) {
if(mListener != null)
mActivity.runOnUiThread(new Runnable(){
@Override
public void run(){
mListener.onLogUpdate(mActivity.getString(resId));
}
});
}
}

View File

@@ -0,0 +1,88 @@
/**
* IOIOTruckValues.java
* @date Jan 21, 2012
* @author ricky barrette
* @author Twenty Codes, LLC
*/
package com.TwentyCodes.android.IOIOTruck;
import com.TwentyCodes.android.ioio.IOIOValues;
/**
* This class is used to hold values for driving an RC truck
* @author ricky barrette
*/
public class IOIOTruckValues extends IOIOValues {
/**
* stop the truck
* PWM value
*/
public static final int DRIVE_STOP = 1500;
/**
* drive the truck forward
* PWM value
*/
public static final int DRIVE_FORWARD = 1300;
/**
* drive the truck in reverse
* PWM value
*/
public static final int DRIVE_REVERSE = 1700;
/**
* IOIO port to drive the speed controller
*/
public static final int DRIVE_PORT = 3;
/**
* IOIO port to drive the shifter servo
*/
public static final int SHIFTER_PORT = 4;
/**
* IOIO port to drive the steering servo
*/
public static final int STEER_PORT = 5;
/**
* steers the truck straight
* PWM value
*/
public static final int STEER_STRAIGHT = 1500;
/**
* steers the truck left
* PWM value
*/
public static final int STEER_LEFT = 1400;
/**
* steers the truck right
* PWM value
*/
public static final int STEER_RIGHT = 1600;
/**
*
* shifts truck into first
* PWM value
*/
public static final int SHIFT_FIRST = 1500;
/**
* shifts the truck into second
* TODO verify value
* PWM value
*/
public static final int SHIFT_SECOND = 1000;
/**
* shifts the truck into 3rd
* PWM value
*/
public static final int SHIFT_THRID = 2000;
}

View File

@@ -0,0 +1,66 @@
package com.TwentyCodes.android.IOIOTruck;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import com.TwentyCodes.android.exception.ExceptionHandler;
/**
* This is the main activity for this application
*
* It will be a simple menu of buttons that will start specific activitys based on the users needs
* @author ricky barrette
*/
public class Main extends Activity implements OnClickListener {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this));
setContentView(R.layout.main);
findViewById(R.id.test_activity_button).setOnClickListener(this);
findViewById(R.id.nav_activity_button).setOnClickListener(this);
/*
* Version information textview
*/
TextView version = (TextView) findViewById(R.id.version_textview);
PackageManager pm = getPackageManager();
PackageInfo pi;
try {
pi = pm.getPackageInfo(getPackageName(), 0);
} catch (NameNotFoundException eNnf) {
//doubt this will ever run since we want info about our own package
pi = new PackageInfo();
pi.versionName = "unknown";
pi.versionCode = 1;
}
version.setText(getText(R.string.version)+" "+pi.versionName+" "+getString(R.string.build)+" "+pi.versionCode);
}
/**
* Called when a view has been clicked
* (non-Javadoc)
* @see android.view.View.OnClickListener#onClick(android.view.View)
*/
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.test_activity_button:
startActivity(new Intent(this, TestActivity.class));
break;
case R.id.nav_activity_button:
startActivity(new Intent(this, NavigationActivity.class));
break;
}
}
}

View File

@@ -0,0 +1,98 @@
/**
* MapFragment.java
* @date Jan 7, 2012
* @author ricky barrette
* @author Twenty Codes, LLC
*/
package com.TwentyCodes.android.IOIOTruck;
import android.util.Log;
import com.TwentyCodes.android.location.LocationSelectedListener;
import com.TwentyCodes.android.location.MapView;
import com.TwentyCodes.android.location.RadiusOverlay;
import com.TwentyCodes.android.location.UserOverlayMapFragment;
import com.google.android.maps.GeoPoint;
/**
* This map fragment will maintain a map view and all its functions
*
* Specifically this map view will allow user to select a point on the map via RadiusOverlay
* @author ricky barrette
*/
public class MapFragment extends UserOverlayMapFragment implements LocationSelectedListener {
private final String TAG = "MapFragment";
private RadiusOverlay mRadiusOverlay;
private LocationSelectedListener mLocationSelectedListener;
/**
* Creates a new MapFragment
* @author ricky barrette
*/
public MapFragment() {
super();
}
/**
* 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) {
setDestination(point);
if(mLocationSelectedListener != null)
mLocationSelectedListener.onLocationSelected(point);
if(point != null){
if(Debug.DEBUG)
Log.d(TAG, "onLocationSelected() "+ point.toString());
if(this.mRadiusOverlay != null)
this.mRadiusOverlay.setLocation(point);
} 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)
*/
@Override
public void onMapViewCreate(MapView map) {
mRadiusOverlay = new RadiusOverlay();
mRadiusOverlay.setLocationSelectedListener(this);
map.getOverlays().add(mRadiusOverlay);
super.onMapViewCreate(map);
}
/**
* @param listener
* @author ricky barrette
*/
public void setLocationSelectedListener(LocationSelectedListener listener){
mLocationSelectedListener = listener;
}
/**
* @param radius meters
* @author ricky barrette
*/
public void setRadius(int radius){
mRadiusOverlay.setRadius(radius);
}
/**
* @param color
* @author ricky barrette
*/
public void setRadiusColor(int color){
mRadiusOverlay.setColor(color);
}
}

View File

@@ -0,0 +1,379 @@
/**
* NavigationActivity.java
* @date Jan 7, 2012
* @author ricky barrette
* @author Twenty Codes, LLC
*/
package com.TwentyCodes.android.IOIOTruck;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ProgressBar;
import android.widget.ScrollView;
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.location.GeoPointLocationListener;
import com.TwentyCodes.android.location.GeoUtils;
import com.TwentyCodes.android.location.LocationSelectedListener;
import com.google.android.maps.GeoPoint;
/**
* This activity will be used to interact with the IOIO and setup autonomous routines
*
* The end goal of this activity is to:
* + have the user select a point on the map
* + have the IOIO drive the rc truck to the point on the map when the user starts the autonomous routine
*
* TODO
* + drive the truck forward or reverse to best navigate to the selected point
* @author ricky barrette
*/
public class NavigationActivity extends FragmentActivity implements CompassListener, GeoPointLocationListener, LocationSelectedListener, OnClickListener, OnCheckedChangeListener, IOIOTruckThreadListener {
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;
/**
* This thread will be used to update all the informational displays
* @author ricky barrette
*/
class LogUpdater extends Thread {
private boolean isAborted;
/**
* aborts the thread
* @author ricky barrette
*/
public void abort() {
isAborted = true;
}
@Override
public void run(){
while (true) {
if (isAborted)
break;
updateLog("\nDistance: "+ mDistance +getString(R.string.m)
+"\nDrive: "+mIOIOManager.getDriveValue()
+"\nSteering: "+mIOIOManager.getSteerValue()
+"\nBearing: "+mBearing
+"\nisRunning: "+isRunning);
updateLastUpdateTextView();
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* updates the last update textview
* thread safe
* @author ricky barrette
*/
private void updateLastUpdateTextView() {
runOnUiThread( new Runnable(){
@Override
public void run(){
mLastUpdateTextView.setText((System.currentTimeMillis() - mLast) +getString(R.string.ms));
}
});
}
}
/**
* Called when the scrolling switch is checked
* (non-Javadoc)
* @see android.widget.CompoundButton.OnCheckedChangeListener#onCheckedChanged(android.widget.CompoundButton, boolean)
*/
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
isScrollingEnabled = isChecked;
}
/**
* Called when a button is clicked
* (non-Javadoc)
* @see android.view.View.OnClickListener#onClick(android.view.View)
*/
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.go_button:
updateGoButton();
break;
case R.id.mark_my_lcoation_button:
GeoPoint point = mMap.getUserLocation();
if(point != null){
mMap.onLocationSelected(point);
} else
Toast.makeText(this, R.string.no_gps_signal, Toast.LENGTH_SHORT).show();
break;
case R.id.my_location_button:
GeoPoint user = mMap.getUserLocation();
if(user != null){
mMap.setMapCenter(user);
} else
break;
}
}
/**
* updates the go/stop button based on isRunning
* thread safe
* @author ricky barrette
*/
private void updateGoButton() {
updateGoButton(isRunning);
}
/**
* Sets the go/stop button to the provided value
* thread safe
* @param isRunnuing true = stop, false = go
* @author ricky barrette
*/
private void updateGoButton(final boolean isRun) {
mIOIOManager.setStatLedValue(!isRun);
runOnUiThread(new Runnable() {
@Override
public void run(){
if(isRun){
mGoButton.setText(R.string.go);
isRunning = false;
updateLog(R.string.stop);
if(mLoggerThread != null)
mLoggerThread.abort();
} else {
mGoButton.setText(R.string.stop);
isRunning = true;
updateLog(R.string.go);
mLoggerThread = new LogUpdater();
mLoggerThread.start();
}
}
});
}
/**
* 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);
}
/**
* 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)) {
mIOIOManager.setDriveValue(IOIOTruckValues.DRIVE_STOP);
updateGoButton(true);
updateLog(R.string.dest_reached);
} else
mIOIOManager.setDriveValue(IOIOTruckValues.DRIVE_FORWARD);
else
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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(mLoggerThread != null)
mLoggerThread.abort();
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();
}
/**
* updates the log with the provided string res
* thread safe
* @param resId
*/
private void updateLog(final int resId) {
updateLog("\n"+getString(resId));
}
/**
* updates the log with the provided string
* thread safe
* @param id The string ID of the message to present.
*/
private void updateLog(final String log) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mLog.append("\n"+log);
/*
* Scroll the scroll view down
*/
if(isScrollingEnabled)
mScrollView.scrollTo(0, mLog.getHeight());
}
});
}
/**
* updates the progress bar
* it will roughly show the progress of the truck
*
* less = closer
* more = farther
* @param point dest
* @return distance meters
* @author ricky barrette
*/
private int updateProgress(GeoPoint point) {
int distance = (int) (GeoUtils.distanceKm(point, mPoint) * 1000);
if (distance > mMaxDistance) {
mMaxDistance = distance;
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);
}
}

View File

@@ -0,0 +1,172 @@
package com.TwentyCodes.android.IOIOTruck;
import android.app.Activity;
import android.os.Bundle;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Switch;
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.exception.ExceptionHandler;
/**
* This is a simple testing activity to test to main functions of the truck.
* These functions are:
* + drive forward /reverse
* + steer left / right
* + shift 1st, 2nd, 3rd
* + status LED on / off
* @author ricky barrette
*/
public class TestActivity extends Activity implements JoystickMovedListener, OnSeekBarChangeListener, OnCheckedChangeListener, IOIOTruckThreadListener {
private TextView mStatusTextView;
private TextView mDriveTextView;
private TextView mSteerTextView;
private TextView mShifterTextView;
private IOIOTruckManager mIOIOManager;
/**
* Called when the activity is first created
* (non-Javadoc)
* @see android.app.Activity#onCreate(android.os.Bundle)
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this));
setContentView(R.layout.test_activity);
mStatusTextView = (TextView) findViewById(R.id.title);
Switch ledSwitch = (Switch) findViewById(R.id.led_switch);
ledSwitch.setOnCheckedChangeListener(this);
SeekBar seekBar = (SeekBar) findViewById(R.id.skeekbar1);
seekBar.setOnSeekBarChangeListener(this);
JoystickView joyStick = (JoystickView) findViewById(R.id.joystick);
joyStick.setOnJostickMovedListener(this);
joyStick.setMovementRange(500);
mDriveTextView = (TextView) findViewById(R.id.tv_drive);
mSteerTextView = (TextView) findViewById(R.id.tv_steer);
mShifterTextView = (TextView) findViewById(R.id.tv_shifter);
mDriveTextView.setText(getString(R.string.drive)+1500);
mSteerTextView.setText(getString(R.string.steer)+1500);
mShifterTextView.setText(getString(R.string.shifter)+1500);
}
/**
* Called when the application is resumed (also when first started). Here is
* where we'll create our IOIO thread.
* @author ricky barrette
*/
@Override
protected void onResume() {
super.onResume();
mIOIOManager = new IOIOTruckManager(this, this);
mIOIOManager.start();
}
/**
* 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() {
super.onPause();
try {
mIOIOManager.abort();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* called when the joystick has been moved
* (non-Javadoc)
* @see com.MobileAnarchy.Android.Widgets.Joystick.JoystickMovedListener#OnMoved(int, int)
*/
@Override
public void OnMoved(int pan, int tilt) {
int drive = tilt + 1500;
int steer = pan + 1500;
mIOIOManager.setDriveValue(drive);
mIOIOManager.setSteerValue(steer);
mDriveTextView.setText(getString(R.string.drive)+mIOIOManager.getDriveValue());//drive);
mSteerTextView.setText(getString(R.string.steer)+mIOIOManager.getSteerValue());//steer);
}
/**
* Called when the joystick is released
* (non-Javadoc)
* @see com.MobileAnarchy.Android.Widgets.Joystick.JoystickMovedListener#OnReleased()
*/
@Override
public void OnReleased() {
//NOT USED
}
/**
* Called when the joystick ir returned to center
* (non-Javadoc)
* @see com.MobileAnarchy.Android.Widgets.Joystick.JoystickMovedListener#OnReturnedToCenter()
*/
@Override
public void OnReturnedToCenter() {
//All Stop
mIOIOManager.setDriveValue(IOIOTruckValues.DRIVE_STOP);
mIOIOManager.setSteerValue(IOIOTruckValues.STEER_STRAIGHT);
}
/**
* 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) {
int shifter = progress + 1000;
mIOIOManager.setShifterValue(shifter);
mShifterTextView.setText(getString(R.string.shifter)+shifter);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
//NOT USED
}
@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.setStatLedValue(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);
}
}