/Android Development/IOIORobotics/src/IEEERobotics/IOIOAI/VT/AICode.java |
---|
0,0 → 1,99 |
package IEEERobotics.IOIOAI.VT; |
import ioio.lib.api.IOIO; |
import ioio.lib.api.exception.ConnectionLostException; |
import android.content.Context; |
import android.content.SharedPreferences; |
import android.os.Handler; |
public class AICode { |
private IOIORoboticsActivity _parent; |
private IOIO _ioio; |
private Boolean _connected = false; |
// Input classes to be implemented |
private InputInterface _lineFollowIn; |
private InputInterface _voltageIn; |
private InputInterface _waveformIn; |
private InputInterface _capacitanceIn; |
private InputInterface _temperatureIn; |
// AI thread |
private Thread _pollingThread; |
/** Class initializer */ |
public AICode(IOIORoboticsActivity parent) { |
_parent = parent; |
} |
/** Starting poing for executing AI code */ |
public void Run() { |
// Initialize the input classes |
initializeInputs(); |
setupPollingThread(); |
_pollingThread.start(); |
} |
/** Initialize input classes */ |
private void initializeInputs() { |
_parent.logMessage("Initializing inputs"); |
_ioio = IOIORoboticsActivity.IOIOInstance_; |
// Initialize each input class (opens pins) |
try { |
_lineFollowIn = new InputLineFollower(); |
_lineFollowIn.initialize(_ioio); |
_voltageIn = new InputVoltage(); |
_voltageIn.initialize(_ioio); |
_waveformIn = new InputWaveform(); |
_waveformIn.initialize(_ioio); |
_capacitanceIn = new InputCapacitance(); |
_capacitanceIn.initialize(_ioio); |
_temperatureIn = new InputTemperature(); |
_temperatureIn.initialize(_ioio); |
_connected = true; |
} catch (ConnectionLostException e) { |
} |
} |
/** Sets up the AI thread to poll for data */ |
private void setupPollingThread() { |
_pollingThread = new Thread (new Runnable() { |
@Override |
public void run() { |
///////////////////////////// |
// INSERT AI CODE HERE // |
///////////////////////////// |
} |
}); |
} |
/** Sends an interrupt signal to the thread and notifies input classes to close pins */ |
public void stopPollingThread() { |
if (_pollingThread.isAlive()) { |
_parent.logMessage("Stopping polling thread"); |
_pollingThread.interrupt(); |
} |
if (_connected) { |
_lineFollowIn.closePins(); |
_voltageIn.closePins(); |
_waveformIn.closePins(); |
_capacitanceIn.closePins(); |
_temperatureIn.closePins(); |
} |
_connected = false; |
} |
} |
/Android Development/IOIORobotics/src/IEEERobotics/IOIOAI/VT/DebugCode.java |
---|
0,0 → 1,395 |
package IEEERobotics.IOIOAI.VT; |
import java.text.DecimalFormat; |
import com.androidplot.Plot.BorderStyle; |
import com.androidplot.xy.BoundaryMode; |
import com.androidplot.xy.LineAndPointFormatter; |
import com.androidplot.xy.StepFormatter; |
import com.androidplot.xy.XYPlot; |
import com.androidplot.xy.XYStepMode; |
import android.content.Context; |
import android.content.SharedPreferences; |
import android.graphics.Color; |
import android.os.Handler; |
import android.preference.PreferenceManager; |
import android.view.View; |
import android.view.ViewGroup; |
import android.widget.LinearLayout; |
import android.widget.ScrollView; |
import android.widget.TextView; |
import android.widget.TableRow.LayoutParams; |
import ioio.lib.api.IOIO; |
import ioio.lib.api.exception.ConnectionLostException; |
public class DebugCode { |
private IOIORoboticsActivity _parent; |
private IOIO _ioio; |
private Context _appContext; |
private View _view; |
private SharedPreferences _sharedPrefs; |
private Handler _handler = new Handler(); |
private Boolean _connected = false; |
// Input classes to be implemented |
private InputInterface _lineFollowIn; |
private InputInterface _voltageIn; |
private InputInterface _waveformIn; |
private InputInterface _capacitanceIn; |
private InputInterface _temperatureIn; |
// Updater thread |
private Thread _pollingThread; |
// Labels |
private TextView _lineFollowLabel; |
private TextView _voltageLabel; |
private TextView _waveformLabel; |
private TextView _capacitanceLabel; |
private TextView _temperatureLabel; |
// Plots |
private XYPlot _lineFollowPlot; |
private XYPlot _voltagePlot; |
private XYPlot _waveformPlot; |
private XYPlot _capacitancePlot; |
private XYPlot _temperaturePlot; |
// Data for each plot |
private GenericXYSeries _lineFollowData; |
private GenericXYSeries _voltageData; |
private GenericXYSeries _waveformData; |
private GenericXYSeries _capacitanceData; |
private GenericXYSeries _temperatureData; |
// Constant values |
private static int _graphHeight = 80; // Height in dp |
private static int _textSize = 15; // TextSize for the labels |
private static int _graphLength; |
private static int _updateSleepPeriod; |
/** Class initializer */ |
public DebugCode(IOIORoboticsActivity parent) { |
_parent = parent; |
_appContext = IOIORoboticsActivity.context_; |
// Get values from shared preferences |
_sharedPrefs = PreferenceManager.getDefaultSharedPreferences(_appContext); |
_graphLength = Integer.parseInt(_sharedPrefs.getString("pref_GraphLength", "100")); |
// Create the overall view with the labels and plots |
createView(); |
} |
/** Starting poing for executing Debug code */ |
public void Run() { |
_updateSleepPeriod = Integer.parseInt(_sharedPrefs.getString("pref_UpdateInterval", "100")); |
// Initialize the input classes |
initializeInputs(); |
// Create the updater thread |
setupPollingThread(); |
_parent.logMessage("Updater thread started"); |
_pollingThread.start(); |
} |
/** Initialize input classes */ |
private void initializeInputs() { |
_parent.logMessage("Initializing inputs"); |
_ioio = IOIORoboticsActivity.IOIOInstance_; |
// Initialize each input class (opens pins) |
try { |
_lineFollowIn = new InputLineFollower(); |
_lineFollowIn.initialize(_ioio); |
_voltageIn = new InputVoltage(); |
_voltageIn.initialize(_ioio); |
_waveformIn = new InputWaveform(); |
_waveformIn.initialize(_ioio); |
_capacitanceIn = new InputCapacitance(); |
_capacitanceIn.initialize(_ioio); |
_temperatureIn = new InputTemperature(); |
_temperatureIn.initialize(_ioio); |
_connected = true; |
} catch (ConnectionLostException e) { |
} |
if (_connected) { |
// Update the status labels for each graphs |
_lineFollowLabel.setText("Pin #" + _lineFollowIn.getPinDescription()); |
_voltageLabel.setText("Pin #" + _voltageIn.getPinDescription()); |
_waveformLabel.setText("Pin #" + _waveformIn.getPinDescription()); |
_capacitanceLabel.setText("Pin #" + _capacitanceIn.getPinDescription()); |
_temperatureLabel.setText("Pin #" + _temperatureIn.getPinDescription()); |
} |
} |
/** Sets up the updater thread to poll for data */ |
private void setupPollingThread() { |
// Create a new thread to poll for new data at set interval |
_pollingThread = new Thread(new Runnable() { |
// Output decimal format |
DecimalFormat df = new DecimalFormat("#.####"); |
@Override |
public void run() { |
try { |
while (true) { |
// Run until the interrupt signal is sent to the thread |
if (Thread.currentThread().isInterrupted()) { |
break; |
} |
if (_connected) { |
// Read in values from input classes |
double ret = _lineFollowIn.getValue(); |
updateLineFollowText(_lineFollowIn.getPinDescription() + " Current Value: " + df.format(ret)); |
_lineFollowData.addDataToList(ret); |
ret = _voltageIn.getValue(); |
updateVoltageText(_voltageIn.getPinDescription() + " Current Value: " + df.format(ret)); |
_voltageData.addDataToList(ret); |
ret = _waveformIn.getValue(); |
updateWaveformText(_waveformIn.getPinDescription() + " Current Value: " + df.format(ret)); |
_waveformData.addDataToList(ret); |
ret = _capacitanceIn.getValue(); |
updateCapacitanceText(_capacitanceIn.getPinDescription() + " Current Value: " + df.format(ret)); |
_capacitanceData.addDataToList(ret); |
ret = _temperatureIn.getValue(); |
updateTemperatureText(_temperatureIn.getPinDescription() + " Current Value: " + df.format(ret)); |
_temperatureData.addDataToList(ret); |
// Redraw graph and sleep for set period of time |
redrawGraphs(); |
} |
Thread.sleep(_updateSleepPeriod); |
} |
} catch (Exception e) { |
stopPollingThread(); |
} |
} |
}); |
} |
/** Sends an interrupt signal to the thread and notifies input classes to close pins */ |
public void stopPollingThread() { |
if (_pollingThread.isAlive()) { |
_parent.logMessage("Stopping updater thread"); |
_pollingThread.interrupt(); |
} |
if (_connected) { |
_lineFollowIn.closePins(); |
_voltageIn.closePins(); |
_waveformIn.closePins(); |
_capacitanceIn.closePins(); |
_temperatureIn.closePins(); |
} |
_connected = false; |
} |
/** Create the view containing the text labels and plots */ |
private void createView() { |
_lineFollowLabel = new TextView(_appContext); |
_lineFollowLabel.setText("Line Follow Plot Label"); |
_lineFollowLabel.setTextSize(_textSize); |
_lineFollowPlot = new XYPlot(_appContext, "LineFollowPlot"); |
_lineFollowPlot.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, _graphHeight)); |
_lineFollowData = new GenericXYSeries("Line Follow", _graphLength); |
setPlotDetails(_lineFollowPlot, _lineFollowData, 3.3, true); |
_voltageLabel = new TextView(_appContext); |
_voltageLabel.setText("Voltage Plot Label"); |
_voltageLabel.setTextSize(_textSize); |
_voltagePlot = new XYPlot(_appContext, "VoltagePlot"); |
_voltagePlot.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, _graphHeight)); |
_voltageData = new GenericXYSeries("Voltage Data", _graphLength); |
setPlotDetails(_voltagePlot, _voltageData, 3.3, false); |
_waveformLabel = new TextView(_appContext); |
_waveformLabel.setText("Waveform Plot Label"); |
_waveformLabel.setTextSize(_textSize); |
_waveformPlot = new XYPlot(_appContext, "WaveformPlot"); |
_waveformPlot.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, _graphHeight)); |
_waveformData = new GenericXYSeries("Waveform Data", _graphLength); |
setPlotDetails(_waveformPlot, _waveformData, 3.3, false); |
_capacitanceLabel = new TextView(_appContext); |
_capacitanceLabel.setText("Capacitance Plot Label"); |
_capacitanceLabel.setTextSize(_textSize); |
_capacitancePlot = new XYPlot(_appContext, "CapacitancePlot"); |
_capacitancePlot.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, _graphHeight)); |
_capacitanceData = new GenericXYSeries("Capacitance Data", _graphLength); |
setPlotDetails(_capacitancePlot, _capacitanceData, 3.3, false); |
_temperatureLabel = new TextView(_appContext); |
_temperatureLabel.setText("Temperature Plot Label"); |
_temperatureLabel.setTextSize(_textSize); |
_temperaturePlot = new XYPlot(_appContext, "TemperaturePlot"); |
_temperaturePlot.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, _graphHeight)); |
_temperatureData = new GenericXYSeries("Temperature Data", _graphLength); |
setPlotDetails(_temperaturePlot, _temperatureData, 3.3, false); |
// Create the main layout and add each subview to it |
LinearLayout layout = new LinearLayout(_appContext); |
layout.setOrientation(LinearLayout.VERTICAL); |
layout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); |
layout.addView(_lineFollowLabel); |
layout.addView(_lineFollowPlot); |
addDivider(layout); |
layout.addView(_voltageLabel); |
layout.addView(_voltagePlot); |
addDivider(layout); |
layout.addView(_waveformLabel); |
layout.addView(_waveformPlot); |
addDivider(layout); |
layout.addView(_capacitanceLabel); |
layout.addView(_capacitancePlot); |
addDivider(layout); |
layout.addView(_temperatureLabel); |
layout.addView(_temperaturePlot); |
ScrollView scroller = new ScrollView(_appContext); |
scroller.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); |
scroller.addView(layout); |
_view = scroller; |
} |
/** Adds a divider to the specified layout */ |
private void addDivider(View layout) { |
View ruler = new View(_appContext); |
ruler.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, 2)); |
ruler.setBackgroundColor(Color.rgb(50, 50, 50)); |
((LinearLayout)layout).addView(ruler); |
} |
/** Associates the graph with the data and set how the graph looks */ |
private void setPlotDetails(XYPlot plot, GenericXYSeries data, double range, boolean useStep) { |
// Associate data with plot |
if (!useStep) |
plot.addSeries(data, new LineAndPointFormatter(Color.rgb(0, 0, 200), Color.rgb(0, 0, 100),Color.rgb(150, 150, 190))); |
else { |
StepFormatter stepFormatter = new StepFormatter(Color.rgb(0, 0, 0), Color.rgb(150, 190, 150)); |
stepFormatter.getLinePaint().setStrokeWidth(1); |
plot.addSeries(data, stepFormatter); |
} |
// Set boundary and ticks |
plot.setRangeBoundaries(0, range, BoundaryMode.FIXED); |
plot.setDomainBoundaries(0, _graphLength, BoundaryMode.FIXED); |
plot.setDomainStepValue(5); |
plot.setRangeStep(XYStepMode.SUBDIVIDE, 4); |
plot.setTicksPerRangeLabel(3); |
// Remove labels and legend |
plot.getLegendWidget().setVisible(false); |
plot.getDomainLabelWidget().setVisible(false); |
plot.getRangeLabelWidget().setVisible(false); |
plot.getTitleWidget().setVisible(false); |
// Remove extra margin space |
plot.getGraphWidget().setMargins(0, 10, 10, 0); |
plot.getGraphWidget().setRangeLabelWidth(30); |
plot.getGraphWidget().setDomainLabelWidth(15); |
plot.getGraphWidget().setMarginLeft(-5); |
plot.getGraphWidget().setMarginRight(25); |
plot.setPlotMargins(0, -10, 0, -5); |
plot.setPlotPadding(0, 0, 0, 0); |
// Background color for the plot and divider line colors |
plot.getGraphWidget().getGridBackgroundPaint().setColor(Color.BLACK); |
plot.getGraphWidget().getGridLinePaint().setColor(Color.GRAY); |
plot.getGraphWidget().getDomainOriginLinePaint().setColor(Color.WHITE); |
plot.getGraphWidget().getRangeOriginLinePaint().setColor(Color.WHITE); |
// Background for the widget (not the plot itself) |
plot.getGraphWidget().setBackgroundPaint(null); |
plot.setBackgroundPaint(null); |
plot.setBorderPaint(null); |
plot.setBorderStyle(BorderStyle.SQUARE, null, null); |
plot.disableAllMarkup(); |
} |
private void updateLineFollowText(final String message) { |
_handler.post(new Runnable() { |
@Override |
public void run() { |
_lineFollowLabel.setText(message); |
} |
}); |
} |
private void updateVoltageText(final String message) { |
_handler.post(new Runnable() { |
@Override |
public void run() { |
_voltageLabel.setText(message); |
} |
}); |
} |
private void updateWaveformText(final String message) { |
_handler.post(new Runnable() { |
@Override |
public void run() { |
_waveformLabel.setText(message); |
} |
}); |
} |
private void updateCapacitanceText(final String message) { |
_handler.post(new Runnable() { |
@Override |
public void run() { |
_capacitanceLabel.setText(message); |
} |
}); |
} |
private void updateTemperatureText(final String message) { |
_handler.post(new Runnable() { |
@Override |
public void run() { |
_temperatureLabel.setText(message); |
} |
}); |
} |
/** Redraws the graphs */ |
private void redrawGraphs() { |
_handler.post(new Runnable() { |
@Override |
public void run() { |
_lineFollowPlot.redraw(); |
_voltagePlot.redraw(); |
_waveformPlot.redraw(); |
_capacitancePlot.redraw(); |
_temperaturePlot.redraw(); |
} |
}); |
} |
public View getView() { |
return _view; |
} |
} |
/Android Development/IOIORobotics/src/IEEERobotics/IOIOAI/VT/GenericXYSeries.java |
---|
0,0 → 1,53 |
package IEEERobotics.IOIOAI.VT; |
import java.util.LinkedList; |
import com.androidplot.series.XYSeries; |
public class GenericXYSeries implements XYSeries { |
private int length; |
private String title; |
private LinkedList<Number> data; |
public GenericXYSeries(String str, int len) { |
title = str; |
length = len; |
data = new LinkedList<Number>(); |
} |
@Override |
public String getTitle() { |
return title; |
} |
@Override |
public int size() { |
return length; |
} |
@Override |
public Number getX(int index) { |
return index; |
} |
@Override |
public Number getY(int index) { |
if (index >= data.size()) |
return 0; |
else |
return data.get(index); |
} |
public void addDataToList(Number num) { |
if (data.size() > length) |
data.removeFirst(); |
data.addLast(num); |
} |
public void clearData() { |
data.clear(); |
} |
public LinkedList<Number> getData() { |
return data; |
} |
} |
/Android Development/IOIORobotics/src/IEEERobotics/IOIOAI/VT/GlobalPreferenceActivity.java |
---|
0,0 → 1,70 |
package IEEERobotics.IOIOAI.VT; |
import android.content.SharedPreferences; |
import android.content.SharedPreferences.OnSharedPreferenceChangeListener; |
import android.os.Bundle; |
import android.preference.CheckBoxPreference; |
import android.preference.EditTextPreference; |
import android.preference.PreferenceManager; |
import android.text.InputType; |
public class GlobalPreferenceActivity extends android.preference.PreferenceActivity implements OnSharedPreferenceChangeListener { |
private CheckBoxPreference _pref_startDebug; |
private EditTextPreference _pref_graphLength; |
private EditTextPreference _pref_updateInterval; |
private SharedPreferences sharedPrefs; |
@Override |
public void onCreate(Bundle savedInstanceState) { |
super.onCreate(savedInstanceState); |
addPreferencesFromResource(R.xml.settings); |
_pref_startDebug = (CheckBoxPreference) findPreference("pref_StartInDebug"); |
_pref_graphLength = (EditTextPreference) findPreference("pref_GraphLength"); |
_pref_updateInterval = (EditTextPreference) findPreference("pref_UpdateInterval"); |
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); |
} |
@Override |
public void onResume() { |
super.onResume(); |
// Set the summary text to the current values when the preferences page is opened |
if (sharedPrefs.getBoolean("pref_StartInDebug", true)) |
_pref_startDebug.setSummary("Currently starting in Debug Mode"); |
else |
_pref_startDebug.setSummary("Currently starting in AI Mode"); |
_pref_graphLength.setSummary("Current Value: " + sharedPrefs.getString("pref_GraphLength", "")); |
_pref_graphLength.getEditText().setInputType(InputType.TYPE_CLASS_NUMBER); |
_pref_updateInterval.setSummary("Current Value: " + sharedPrefs.getString("pref_UpdateInterval", "") + "ms"); |
_pref_updateInterval.getEditText().setInputType(InputType.TYPE_CLASS_NUMBER); |
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); |
} |
@Override |
public void onPause() { |
super.onPause(); |
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this); |
} |
@Override |
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { |
// Change the summary text when the value is changed |
if (key.compareTo("pref_StartInDebug") == 0) { |
if (sharedPrefs.getBoolean("pref_StartInDebug", true)) |
_pref_startDebug.setSummary("Currently starting in Debug Mode"); |
else |
_pref_startDebug.setSummary("Currently starting in AI Mode"); |
} else if (key.compareTo("pref_GraphLength") == 0) { |
_pref_graphLength.setSummary("Current Value: " + sharedPrefs.getString("pref_GraphLength", "100")); |
} else if (key.compareTo("pref_UpdateInterval") == 0) { |
_pref_updateInterval.setSummary("Current Value: " + sharedPrefs.getString("pref_UpdateInterval", "100") + "ms"); |
} |
} |
} |
/Android Development/IOIORobotics/src/IEEERobotics/IOIOAI/VT/IOIORoboticsActivity.java |
---|
0,0 → 1,441 |
package IEEERobotics.IOIOAI.VT; |
import ioio.lib.api.IOIO; |
import ioio.lib.api.IOIOFactory; |
import ioio.lib.api.exception.ConnectionLostException; |
import ioio.lib.api.exception.IncompatibilityException; |
import java.text.SimpleDateFormat; |
import java.util.Date; |
import java.util.LinkedList; |
import java.util.List; |
import com.viewpagerindicator.TitlePageIndicator; |
import android.app.Activity; |
import android.content.Context; |
import android.content.Intent; |
import android.os.Bundle; |
import android.os.Handler; |
import android.preference.PreferenceManager; |
import android.support.v4.view.ViewPager; |
import android.view.Menu; |
import android.view.MenuItem; |
import android.view.View; |
import android.widget.LinearLayout; |
import android.widget.ProgressBar; |
import android.widget.ScrollView; |
import android.widget.TextView; |
import android.widget.TableRow.LayoutParams; |
public class IOIORoboticsActivity extends Activity { |
// Static IOIO instance so other activities can access it |
public static IOIO IOIOInstance_; |
public static Context context_; |
public static List<String> subTitles_ = new LinkedList<String>(); |
public static List<View> subViews_ = new LinkedList<View>(); |
// Connection and activity related variables |
private static Boolean _connected = false; |
private static Handler _handler = new Handler(); |
private Boolean _connectionReset = true; |
private Thread _connectionMonitor; |
private TextView _statusText; |
private ProgressBar _statusProgressBar; |
private LinearLayout _logLayout; |
private ViewPagerAdapter _pageAdapter; |
private ViewPager _pager; |
private TitlePageIndicator _pageIndicator; |
// Debugging stuff |
private Boolean _debugMode; |
private DebugCode _debuggingCode; |
// AI stuff |
private AICode _AICode; |
// Motor Control class |
private MotorControl _motorControl; |
// Item ID for custom menu items |
private static int menuToggleDebugMonitoring = Menu.FIRST; |
private static int menuOpenSettings = Menu.FIRST+1; |
private static int menuReset = Menu.FIRST+2; |
private static int menuClearLog = Menu.FIRST+3; |
private static int _connectionCheckInterval = 500; // in ms |
// /** Called when the menu button is first pressed (creates the blank menu) */ |
// @Override |
// public boolean onCreateOptionsMenu(Menu menu) { |
// MenuInflater inflater = getMenuInflater(); |
// // Inflate a blank menu as we will populate it ourselves |
// inflater.inflate(R.menu.mainmenu, menu); |
// return true; |
// } |
/** Called when the menu button is pressed, populates the menu with options */ |
@Override |
public boolean onPrepareOptionsMenu(Menu menu) { |
// Clear existing menus and create a new one based on current state |
menu.clear(); |
if (_debugMode) |
menu.add(0, menuToggleDebugMonitoring, 0, "Turn On Robotics AI"); |
else |
menu.add(0, menuToggleDebugMonitoring, 0, "Turn On Debug Mode"); |
if (_connected) |
menu.add(0, menuReset, 0, "Reset IOIO Board"); |
else |
menu.add(0, menuReset, 0, "Remove Debug Tabs"); |
menu.add(0, menuClearLog, 0, "Clear Logs"); |
menu.add(0, menuOpenSettings, 0, "Settings"); |
return super.onPrepareOptionsMenu(menu); |
} |
/** Handles what to do when a menu item is selected */ |
@Override |
public boolean onOptionsItemSelected(MenuItem item) { |
// // Disable certain menu options if IOIO board is not connected |
// if (item.getItemId() == menuReset && |
// !_connected) { |
// Toast.makeText(this, "IOIO board not connected", Toast.LENGTH_SHORT).show(); |
// return true; |
// }; |
// Otherwise handle menu selections |
if (item.getItemId() == menuToggleDebugMonitoring) { |
if (_debugMode) { |
_debugMode = false; |
logMessage("Operating mode changed to AI"); |
if (_connected) |
hardReset(); |
} else { |
_debugMode = true; |
logMessage("Operating mode changed to Debug"); |
if (_connected) |
hardReset(); |
} |
return true; |
} else if (item.getItemId() == menuOpenSettings) { |
startActivity(new Intent(this, GlobalPreferenceActivity.class)); |
return true; |
} else if (item.getItemId() == menuReset) { |
if (_connected) |
hardReset(); |
else { |
if (_debuggingCode != null) { |
removeDebugView(); |
} |
} |
return true; |
} else if (item.getItemId() == menuClearLog) { |
_logLayout.removeAllViews(); |
return true; |
} else { |
return super.onOptionsItemSelected(item); |
} |
} |
/** Called when the application is started */ |
@Override |
public void onCreate(Bundle savedInstanceState) { |
super.onCreate(savedInstanceState); |
setContentView(R.layout.main); |
// Grab the local context so other classes can use it to create views |
context_ = this.getApplicationContext(); |
// Get local pointers to views |
_pageAdapter = new ViewPagerAdapter(this); |
_pager = (ViewPager)findViewById(R.id.viewpager); |
_pageIndicator = (TitlePageIndicator)findViewById(R.id.indicator); |
_statusText = (TextView)findViewById(R.id.statusText); |
_statusProgressBar = (ProgressBar)findViewById(R.id.progressBar); |
_pager.setAdapter(_pageAdapter); |
_pageIndicator.setViewPager(_pager); |
createLogView(); |
// Get default/saved debug mode |
if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("pref_StartInDebug", true)) |
_debugMode = true; |
else |
_debugMode = false; |
// Print out current debug status |
if (_debugMode) |
logMessage("Debug mode is currently on"); |
else |
logMessage("Debug mode is currently off"); |
// Start connection monitoring thread for the IOIO board |
connectToIOIOBoard(); |
} |
/** Called when the application is stopped */ |
@Override |
public void onDestroy() { |
super.onDestroy(); |
connectionReset(); |
if (_debuggingCode != null) { |
removeDebugView(); |
} |
_connectionMonitor.interrupt(); |
IOIOInstance_.disconnect(); |
_connected = false; |
} |
/** Starts the thread that monitors the connection to the IOIO board */ |
private void connectToIOIOBoard() { |
// Create a new thread to monitor the connection status to the IOIO board |
_connectionMonitor = new Thread(new Runnable() { |
@Override |
public void run() { |
while (true) { |
try { |
// Check if a new instance of IOIO needs to be created |
// Reset is only triggered when a disconnect happens |
if (_connectionReset) { |
updateStatus("Waiting to connect to the IOIO board..."); |
toggleProgressOn(); |
IOIOInstance_ = IOIOFactory.create(); |
_connectionReset = false; |
} |
// Check if thread should keep running |
if (Thread.currentThread().isInterrupted()) { |
break; |
} |
// Attempt to connect to the IOIO board |
// If the board was disconnected, ConnectionLostException is thrown while waiting |
IOIOInstance_.waitForConnect(); |
// Do stuff when the first connection to the board is made |
if (!_connected) { |
updateStatus("Connected to the IOIO board"); |
Thread.sleep(200); |
connectionSuccess(); |
} |
_connected = true; |
toggleProgressOff(); |
Thread.sleep(_connectionCheckInterval); |
} catch (ConnectionLostException e) { |
// Reset the connection so reconnection attempts can be made |
_connected = false; |
_connectionReset = true; |
connectionReset(); |
updateStatus("Connection to the IOIO board has be lost"); |
} catch (IncompatibilityException e) { |
// Throw error and quit |
_connected = false; |
_connectionReset = true; |
connectionReset(); |
updateStatus("Connected IOIO board is incompatible"); |
} catch (InterruptedException e) { |
break; |
} |
} |
} |
}); |
_connectionMonitor.start(); |
} |
/** Called when the connection to the IOIO board succeeds */ |
private void connectionSuccess() { |
_handler.post(new Runnable() { |
@Override |
public void run() { |
// If debug mode is enabled, run the debug code to create graphs |
if (_debugMode) { |
startDebugMode(); |
} else { |
startAIMode(); |
} |
} |
}); |
} |
/** Called when the connection to the IOIO board has been reset */ |
private void connectionReset() { |
_handler.post(new Runnable() { |
@Override |
public void run() { |
// If the debugger code was running, stop the updating thread |
if (_debuggingCode != null) |
_debuggingCode.stopPollingThread(); |
if (_AICode != null) |
_AICode.stopPollingThread(); |
if (_motorControl != null) { |
_motorControl.disconnect(); |
} |
} |
}); |
} |
/** Creates the first layout for the ViewPager */ |
private void createLogView() { |
if (subTitles_.contains("Logger")) { |
removeView(subViews_.get(subTitles_.indexOf("Logger"))); |
subTitles_.remove("Logger"); |
} |
_logLayout = new LinearLayout(this); |
_logLayout.setOrientation(LinearLayout.VERTICAL); |
_logLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); |
ScrollView scroller = new ScrollView(this); |
scroller.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); |
scroller.addView(_logLayout); |
addView("Logger", scroller); |
} |
/** Creates a new page in the ViewPager */ |
private void addView(String name, View view) { |
// Add the view and label to the lists |
subTitles_.add(subTitles_.size(), name); |
subViews_.add(subViews_.size(), view); |
// Update the screen with the new views |
_pageAdapter.notifyDataSetChanged(); |
_pageIndicator.notifyDataSetChanged(); |
} |
/** Removes a page in the ViewPager */ |
private void removeView(View view) { |
if (subViews_.contains(view)) { |
// Change the main view to the first one (logger) |
_pager.setCurrentItem(0); |
// Remove the view and label from the lists |
subTitles_.remove(subViews_.indexOf(view)); |
subViews_.remove(view); |
// Update the screen with the new views |
_pageAdapter.notifyDataSetChanged(); |
_pageIndicator.notifyDataSetChanged(); |
} |
} |
/** Start point for code to execute in Debug Mode */ |
private void startDebugMode() { |
// Run debug code to create graphs |
logMessage("Executing Debug Mode"); |
// On first run, create inputs and views |
if (_debuggingCode == null) { |
_debuggingCode = new DebugCode(this); |
addView("Graphs", _debuggingCode.getView()); |
} |
if (_motorControl == null) { |
_motorControl = new MotorControl(this); |
addView("Motor", _motorControl.getDebugView()); |
} |
_debuggingCode.Run(); |
// _motorControl.Run(); |
} |
/** Call to stop the debug code and remove all associated views */ |
private void removeDebugView() { |
removeView(_debuggingCode.getView()); |
removeView(_motorControl.getDebugView()); |
if (_debuggingCode != null) { |
// _debuggingCode.stopPollingThread(); |
_debuggingCode = null; |
} |
if (_motorControl != null) { |
_motorControl = null; |
} |
} |
/** Start point for code to execut`e in AI Mode */ |
private void startAIMode() { |
// Remove the debug views if they exist |
if (_debuggingCode != null) { |
removeDebugView(); |
} |
logMessage("Executing AI Mode"); |
_AICode = new AICode(this); |
_AICode.Run(); |
} |
/** |
* A hard reset is exactly like physically powering off the IOIO |
* board and powering it back on. As a result, the connection |
* with the IOIO will drop and the IOIO instance will become |
* disconnected and unusable. The board will perform a full reboot, |
* including going through the bootloader sequence, i.e. an attempt |
* to update the board's firmware will be made. |
*/ |
private void hardReset() { |
try { |
IOIOInstance_.hardReset(); |
} catch (ConnectionLostException e) { |
_connected = false; |
_connectionReset = true; |
connectionReset(); |
updateStatus("Hard reset executed on the IOIO board"); |
} |
} |
/** Sets the status TextView to the provided message */ |
private void updateStatus(final String message) { |
_handler.post(new Runnable() { |
@Override |
public void run() { |
logMessage(message); |
_statusText.setText("Status: " + message); |
} |
}); |
} |
/** Appends the provided message to the beginning of the log TextView */ |
public void logMessage(final String message) { |
_handler.post(new Runnable() { |
@Override |
public void run() { |
// Get the current time |
SimpleDateFormat dateFormat = new SimpleDateFormat("[HH:mm:ss]"); |
Date now = new Date(); |
String currentTime = dateFormat.format(now); |
// Log message with the current time appended to the front |
String msg = currentTime + " " + message; |
TextView tv = new TextView(context_); |
tv.setText(msg); |
_logLayout.addView(tv,0); |
} |
}); |
} |
/** Returns the current connection state */ |
public Boolean getConnected() { |
return _connected; |
} |
/** Toggles the visibility of the status ProgressBar */ |
private void toggleProgressOn() { |
_handler.post(new Runnable() { |
@Override |
public void run() { |
_statusProgressBar.setVisibility(View.VISIBLE); |
} |
}); |
} |
/** Toggles the visibility of the status ProgressBar */ |
private void toggleProgressOff() { |
_handler.post(new Runnable() { |
@Override |
public void run() { |
_statusProgressBar.setVisibility(View.GONE); |
} |
}); |
} |
} |
/Android Development/IOIORobotics/src/IEEERobotics/IOIOAI/VT/InputCapacitance.java |
---|
0,0 → 1,46 |
package IEEERobotics.IOIOAI.VT; |
import ioio.lib.api.AnalogInput; |
import ioio.lib.api.DigitalOutput; |
import ioio.lib.api.IOIO; |
import ioio.lib.api.exception.ConnectionLostException; |
public class InputCapacitance implements InputInterface { |
IOIO _ioio; |
private static int VOUT_PIN = 44; |
private static int VIN_PIN = 45; |
private AnalogInput _vin; |
private DigitalOutput _vout; |
@Override |
public void initialize(IOIO ioio) throws ConnectionLostException { |
_ioio = ioio; |
_vin = ioio.openAnalogInput(VIN_PIN); |
_vout = ioio.openDigitalOutput(VOUT_PIN); |
} |
@Override |
public double getValue() throws InterruptedException, ConnectionLostException { |
// Applies voltage to capacitor for 1 ms |
_vout.write(true); |
Thread.sleep(1); |
_vout.write(false); |
// Get voltage of capacitor |
float vc = _vin.getVoltage(); |
return vc; |
} |
@Override |
public String getPinDescription() { |
return "Pin #44-45"; |
} |
@Override |
public void closePins() { |
_vin.close(); |
_vout.close(); |
} |
} |
/Android Development/IOIORobotics/src/IEEERobotics/IOIOAI/VT/InputInterface.java |
---|
0,0 → 1,11 |
package IEEERobotics.IOIOAI.VT; |
import ioio.lib.api.IOIO; |
import ioio.lib.api.exception.ConnectionLostException; |
public interface InputInterface { |
public void initialize(IOIO ioio) throws ConnectionLostException; |
public double getValue() throws InterruptedException, ConnectionLostException; |
public String getPinDescription(); |
public void closePins(); |
} |
/Android Development/IOIORobotics/src/IEEERobotics/IOIOAI/VT/InputLineFollower.java |
---|
0,0 → 1,33 |
package IEEERobotics.IOIOAI.VT; |
import ioio.lib.api.IOIO; |
import ioio.lib.api.exception.ConnectionLostException; |
public class InputLineFollower implements InputInterface { |
IOIO _ioio; |
@Override |
public void initialize(IOIO ioio) throws ConnectionLostException { |
_ioio = ioio; |
} |
@Override |
public double getValue() { |
// TODO Auto-generated method stub |
return 0; |
} |
@Override |
public String getPinDescription() { |
// TODO Auto-generated method stub |
return "Pin #0"; |
} |
@Override |
public void closePins() { |
// TODO Auto-generated method stub |
} |
} |
/Android Development/IOIORobotics/src/IEEERobotics/IOIOAI/VT/InputTemperature.java |
---|
0,0 → 1,33 |
package IEEERobotics.IOIOAI.VT; |
import ioio.lib.api.IOIO; |
import ioio.lib.api.exception.ConnectionLostException; |
public class InputTemperature implements InputInterface { |
@Override |
public void initialize(IOIO ioio) throws ConnectionLostException { |
// TODO Auto-generated method stub |
} |
@Override |
public double getValue() throws InterruptedException, |
ConnectionLostException { |
// TODO Auto-generated method stub |
return 0; |
} |
@Override |
public String getPinDescription() { |
// TODO Auto-generated method stub |
return "Pin #0"; |
} |
@Override |
public void closePins() { |
// TODO Auto-generated method stub |
} |
} |
/Android Development/IOIORobotics/src/IEEERobotics/IOIOAI/VT/InputVoltage.java |
---|
0,0 → 1,45 |
package IEEERobotics.IOIOAI.VT; |
import ioio.lib.api.AnalogInput; |
import ioio.lib.api.IOIO; |
import ioio.lib.api.exception.ConnectionLostException; |
public class InputVoltage implements InputInterface { |
IOIO _ioio; |
private static int VNEG_PIN = 42; |
private static int VPOS_PIN = 43; |
private AnalogInput _negvolt; |
private AnalogInput _posvolt; |
@Override |
public void initialize(IOIO ioio) throws ConnectionLostException { |
_ioio = ioio; |
_negvolt = _ioio.openAnalogInput(VNEG_PIN); |
_posvolt = _ioio.openAnalogInput(VPOS_PIN); |
} |
@Override |
public double getValue() throws InterruptedException, ConnectionLostException { |
// Read in voltage |
float volt = _posvolt.getVoltage(); |
// If volt is zero, check reverse polarity |
if (volt == 0) { |
volt = _negvolt.getVoltage(); |
} |
return (double)volt; |
} |
@Override |
public String getPinDescription() { |
return "Pin #42-43"; |
} |
@Override |
public void closePins() { |
_negvolt.close(); |
_posvolt.close(); |
} |
} |
/Android Development/IOIORobotics/src/IEEERobotics/IOIOAI/VT/InputWaveform.java |
---|
0,0 → 1,31 |
package IEEERobotics.IOIOAI.VT; |
import ioio.lib.api.IOIO; |
public class InputWaveform implements InputInterface { |
@Override |
public void initialize(IOIO ioio) { |
// TODO Auto-generated method stub |
} |
@Override |
public double getValue() { |
// TODO Auto-generated method stub |
return 0; |
} |
@Override |
public String getPinDescription() { |
// TODO Auto-generated method stub |
return "Pin #0"; |
} |
@Override |
public void closePins() { |
// TODO Auto-generated method stub |
} |
} |
/Android Development/IOIORobotics/src/IEEERobotics/IOIOAI/VT/MotorControl.java |
---|
0,0 → 1,135 |
package IEEERobotics.IOIOAI.VT; |
import android.content.Context; |
import android.content.SharedPreferences; |
import android.graphics.Color; |
import android.preference.PreferenceManager; |
import android.view.View; |
import android.view.View.OnClickListener; |
import android.widget.Button; |
import android.widget.LinearLayout; |
import android.widget.TableRow.LayoutParams; |
import ioio.lib.api.IOIO; |
import ioio.lib.api.PwmOutput; |
import ioio.lib.api.exception.ConnectionLostException; |
public class MotorControl implements OnClickListener{ |
private IOIORoboticsActivity _parent; |
private IOIO _ioio; |
private Context _appContext; |
private SharedPreferences _sharedPrefs; |
private View _debugView; |
private Button _forward; |
private Button _back; |
private Button _left; |
private Button _right; |
private PwmOutput leftPWM; |
private PwmOutput rightPWM; |
private static int MOTOR_LEFT = 12; |
private static int MOTOR_RIGHT = 13; |
private static int TEXT_SIZE = 20; |
private static int SENSITIVITY = 120; |
public MotorControl(IOIORoboticsActivity parent) { |
_parent = parent; |
_ioio = IOIORoboticsActivity.IOIOInstance_; |
_appContext = IOIORoboticsActivity.context_; |
_sharedPrefs = PreferenceManager.getDefaultSharedPreferences(_appContext); |
createDebugView(); |
initializeOutputs(); |
} |
public void setSensitivity(int sensitivity) { |
SENSITIVITY = sensitivity; |
} |
public void setMotorSpeed() { |
} |
private void initializeOutputs() { |
try { |
leftPWM = _ioio.openPwmOutput(MOTOR_LEFT, SENSITIVITY); |
rightPWM = _ioio.openPwmOutput(MOTOR_RIGHT, SENSITIVITY); |
} catch (ConnectionLostException e) { |
} |
} |
public void disconnect() { |
leftPWM.close(); |
rightPWM.close(); |
} |
@Override |
public void onClick(View v) { |
Button btn = (Button)v; |
if (btn == _forward) { |
_parent.logMessage("Front"); |
} else if (btn == _back) { |
_parent.logMessage("Back"); |
} else if (btn == _left) { |
_parent.logMessage("Left"); |
} else if (btn == _right) { |
_parent.logMessage("Right"); |
} |
} |
private void createDebugView() { |
_forward = new Button(_appContext); |
_forward.setText("Forwards"); |
_forward.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, (float)0.3)); |
_forward.setBackgroundColor(Color.BLACK); |
_forward.setTextColor(Color.WHITE); |
_forward.setTextSize(TEXT_SIZE); |
_forward.setOnClickListener(this); |
_back = new Button(_appContext); |
_back.setText("Backwards"); |
_back.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, (float)0.3)); |
_back.setBackgroundColor(Color.BLACK); |
_back.setTextColor(Color.WHITE); |
_back.setTextSize(TEXT_SIZE); |
_back.setOnClickListener(this); |
_left = new Button(_appContext); |
_left.setText("Left"); |
_left.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, (float)0.5)); |
_left.setBackgroundColor(Color.BLACK); |
_left.setTextColor(Color.WHITE); |
_left.setTextSize(TEXT_SIZE); |
_left.setOnClickListener(this); |
_right = new Button(_appContext); |
_right.setText("Right"); |
_right.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, (float)0.5)); |
_right.setBackgroundColor(Color.BLACK); |
_right.setTextColor(Color.WHITE); |
_right.setTextSize(TEXT_SIZE); |
_right.setOnClickListener(this); |
LinearLayout center = new LinearLayout(_appContext); |
center.setOrientation(LinearLayout.HORIZONTAL); |
center.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, (float)0.25)); |
center.addView(_left); |
center.addView(_right); |
LinearLayout root = new LinearLayout(_appContext); |
root.setOrientation(LinearLayout.VERTICAL); |
root.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, (float)1.0)); |
root.addView(_forward); |
root.addView(center); |
root.addView(_back); |
_debugView = root; |
} |
public View getDebugView() { |
return _debugView; |
} |
} |
/Android Development/IOIORobotics/src/IEEERobotics/IOIOAI/VT/ViewPagerAdapter.java |
---|
0,0 → 1,62 |
package IEEERobotics.IOIOAI.VT; |
import android.content.Context; |
import android.support.v4.view.PagerAdapter; |
import android.support.v4.view.ViewPager; |
import android.view.View; |
import com.viewpagerindicator.TitleProvider; |
public class ViewPagerAdapter extends PagerAdapter implements TitleProvider { |
// private final Context context; |
public ViewPagerAdapter(Context context) { |
// this.context = context; |
} |
@Override |
public String getTitle(int position) { |
return IOIORoboticsActivity.subTitles_.get(position); |
} |
@Override |
public int getCount() { |
return IOIORoboticsActivity.subTitles_.size(); |
} |
@Override |
public Object instantiateItem(View pager, int position) { |
View v = IOIORoboticsActivity.subViews_.get(position); |
((ViewPager) pager).addView(v, 0); |
return v; |
} |
@Override |
public void destroyItem(View pager, int position, Object view) { |
((ViewPager) pager).removeView((View)view); |
} |
@Override |
public boolean isViewFromObject(View view, Object object) { |
return view.equals(object); |
} |
// @Override |
// public void finishUpdate(View view) { |
// |
// } |
// |
// @Override |
// public void restoreState(Parcelable p, ClassLoader c) { |
// |
// } |
// |
// @Override |
// public Parcelable saveState() { |
// return null; |
// } |
// |
// @Override |
// public void startUpdate(View view) { |
// |
// } |
} |