1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-12-11 19:24:10 +01:00

Added some missing files. Improved object browser to use ListView.

ExpandableListView next.
This commit is contained in:
James Cotton 2011-03-20 06:09:06 -05:00
parent 6505507230
commit e2a90b2265
12 changed files with 202 additions and 59 deletions

Binary file not shown.

View File

@ -0,0 +1,31 @@
------- TELEMETRY ---------
The Telemetry system has been implemented, and is composed of a few
major components:
Telemetry.java - receives command to transmit objects through telemetry and
also emits notification when transactions are completed
TelemetryMonitor.java - monitors the FlightTelemetryStats and GCSTelemetryStats
to establish when a working connection is in place. Also initiates downloading
all the objects on a new connection.
UAVObjectManager.java - the central data store. The data is actually stored
within objects, but this maintains the handles to all of them.
UAVTalk.java - the actual communication layer. Can packetize an object and
insert into stream and process the incoming stream and update objects
accordingly.
---- MESSAGE PASSING ----
The current implementation/analog to the slots/sockets in QT are Observers
which are registered as added to an Observable. This is used extensibly within
the telemetry system. I will continue to use this _within_ the Telemetry
module so it doesn't depend on any android features.
In android there is a constraint that UI operations should all be done from the
UI thread. The most common way to do this is for the UI object (such as
Activity) to instantiate a Handler to which messages or runnables are posted.
So for external objects they will register a runnable somehow...

View File

@ -1,13 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_width="fill_parent" android:layout_height="match_parent">
android:layout_height="fill_parent" <ListView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/object_list"></ListView>
> </RelativeLayout>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView android:text="TextView" android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
<ToggleButton android:text="ToggleButton" android:id="@+id/toggleButton1" android:layout_width="wrap_content" android:layout_height="wrap_content"></ToggleButton>
</LinearLayout>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp" >
</TextView>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="@string/menu_item_settings" android:id="@+id/menu_settings"></item>
<item android:title="@string/menu_item_connect" android:id="@+id/menu_connect"></item>
<item android:title="@string/menu_item_disconnect" android:id="@+id/menu_disconnect"></item>
</menu>

View File

@ -1,4 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name">OpenPilot GCS</string> <string name="app_name">OpenPilot GCS</string>
<string name="menu_item_settings">Settings</string>
<string name="menu_item_connect">Connect</string>
<string name="menu_item_disconnect">Disconnect</string>
<string name="object_browser_title">OpenPilot Object Browser</string>
</resources> </resources>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android">
android:minWidth="294dp"
android:minHeight="72dp"
android:updatePeriodMillis="86400000"
android:initialLayout="@layout/telemetry_widget">
<!-- android:configure="com.example.android.ExampleAppWidgetConfigure" -->
</appwidget-provider>

View File

@ -1,5 +1,8 @@
package org.openpilot.androidgcs; package org.openpilot.androidgcs;
import java.util.Observable;
import java.util.Observer;
import org.openpilot.uavtalk.Telemetry; import org.openpilot.uavtalk.Telemetry;
import org.openpilot.uavtalk.TelemetryMonitor; import org.openpilot.uavtalk.TelemetryMonitor;
import org.openpilot.uavtalk.UAVDataObject; import org.openpilot.uavtalk.UAVDataObject;
@ -27,7 +30,7 @@ import android.widget.Toast;
public class OPTelemetryService extends Service { public class OPTelemetryService extends Service {
// Logging settings // Logging settings
private final String TAG = "OPTElemetryService"; private final String TAG = "OPTelemetryService";
public static int LOGLEVEL = 2; public static int LOGLEVEL = 2;
public static boolean WARN = LOGLEVEL > 1; public static boolean WARN = LOGLEVEL > 1;
public static boolean DEBUG = LOGLEVEL > 0; public static boolean DEBUG = LOGLEVEL > 0;
@ -44,10 +47,13 @@ public class OPTelemetryService extends Service {
private ServiceHandler mServiceHandler; private ServiceHandler mServiceHandler;
// Message ids // Message ids
final int MSG_START = 0; static final int MSG_START = 0;
final int MSG_CONNECT_BT = 1; static final int MSG_CONNECT_BT = 1;
final int MSG_CONNECT_FAKE = 2; static final int MSG_CONNECT_FAKE = 2;
final int MSG_TOAST = 100; static final int MSG_DISCONNECT = 3;
static final int MSG_TOAST = 100;
private boolean terminate = false;
private Thread activeTelem; private Thread activeTelem;
@ -65,12 +71,28 @@ public class OPTelemetryService extends Service {
System.out.println("HERE"); System.out.println("HERE");
stopSelf(msg.arg2); stopSelf(msg.arg2);
case MSG_CONNECT_BT: case MSG_CONNECT_BT:
terminate = false;
activeTelem = new BTTelemetryThread(); activeTelem = new BTTelemetryThread();
activeTelem.start(); activeTelem.start();
break; break;
case MSG_CONNECT_FAKE: case MSG_CONNECT_FAKE:
terminate = false;
activeTelem = new FakeTelemetryThread(); activeTelem = new FakeTelemetryThread();
activeTelem.start(); activeTelem.start();
break;
case MSG_DISCONNECT:
terminate = true;
try {
activeTelem.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
activeTelem = null;
Intent intent = new Intent();
intent.setAction(INTENT_ACTION_DISCONNECTED);
sendBroadcast(intent,null);
break; break;
case MSG_TOAST: case MSG_TOAST:
Toast.makeText(OPTelemetryService.this, (String) msg.obj, Toast.LENGTH_SHORT); Toast.makeText(OPTelemetryService.this, (String) msg.obj, Toast.LENGTH_SHORT);
@ -129,6 +151,16 @@ public class OPTelemetryService extends Service {
msg.arg1 = MSG_CONNECT_FAKE; msg.arg1 = MSG_CONNECT_FAKE;
mServiceHandler.sendMessage(msg); mServiceHandler.sendMessage(msg);
} }
public void openBTConnection() {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = MSG_CONNECT_BT;
mServiceHandler.sendMessage(msg);
}
public void stopConnection() {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = MSG_DISCONNECT;
mServiceHandler.sendMessage(msg);
}
}; };
public void toastMessage(String msgText) { public void toastMessage(String msgText) {
@ -153,7 +185,7 @@ public class OPTelemetryService extends Service {
} }
public void run() { public void run() {
System.out.println("Runnin fake thread"); System.out.println("Running fake thread");
Intent intent = new Intent(); Intent intent = new Intent();
intent.setAction(INTENT_ACTION_CONNECTED); intent.setAction(INTENT_ACTION_CONNECTED);
@ -161,7 +193,7 @@ public class OPTelemetryService extends Service {
//toastMessage("Started fake telemetry thread"); //toastMessage("Started fake telemetry thread");
UAVDataObject systemStats = (UAVDataObject) objMngr.getObject("SystemStats"); UAVDataObject systemStats = (UAVDataObject) objMngr.getObject("SystemStats");
while(true) { while( !terminate ) {
systemStats.updated(); systemStats.updated();
try { try {
Thread.sleep(1000); Thread.sleep(1000);
@ -176,7 +208,7 @@ public class OPTelemetryService extends Service {
private UAVObjectManager objMngr; private UAVObjectManager objMngr;
private UAVTalk uavTalk; private UAVTalk uavTalk;
private Telemetry tel; private Telemetry tel;
//private TelemetryMonitor mon; private TelemetryMonitor mon;
public UAVObjectManager getObjectManager() { return objMngr; }; public UAVObjectManager getObjectManager() { return objMngr; };
@ -217,10 +249,21 @@ public class OPTelemetryService extends Service {
uavTalk = bt.getUavtalk(); uavTalk = bt.getUavtalk();
tel = new Telemetry(uavTalk, objMngr); tel = new Telemetry(uavTalk, objMngr);
new TelemetryMonitor(objMngr,tel); mon = new TelemetryMonitor(objMngr,tel);
mon.addObserver(new Observer() {
public void update(Observable arg0, Object arg1) {
System.out.println("Mon updated. Connected: " + mon.getConnected() + " objects updated: " + mon.getObjectsUpdated());
if(mon.getConnected() /*&& mon.getObjectsUpdated()*/) {
Intent intent = new Intent();
intent.setAction(INTENT_ACTION_CONNECTED);
sendBroadcast(intent,null);
}
}
});
if (DEBUG) Log.d(TAG, "Entering UAVTalk processing loop"); if (DEBUG) Log.d(TAG, "Entering UAVTalk processing loop");
while(true) { while( !terminate ) {
if( !uavTalk.processInputStream() ) if( !uavTalk.processInputStream() )
break; break;
} }

View File

@ -1,42 +1,67 @@
package org.openpilot.androidgcs; package org.openpilot.androidgcs;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.Observable; import java.util.Observable;
import java.util.Observer; import java.util.Observer;
import android.database.DataSetObserver;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.util.Log; import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.SimpleExpandableListAdapter;
import android.widget.TextView; import android.widget.TextView;
import android.widget.ToggleButton; import android.widget.Toast;
import org.openpilot.uavtalk.UAVDataObject;
import org.openpilot.uavtalk.UAVObject; import org.openpilot.uavtalk.UAVObject;
public class ObjectBrowser extends ObjectManagerActivity { public class ObjectBrowser extends ObjectManagerActivity {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.menu_connect:
binder.openBTConnection();
return true;
case R.id.menu_disconnect:
binder.stopConnection();
updateText.run();
return true;
case R.id.menu_settings:
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
return true;
}
private final String TAG = "ObjectBrower"; private final String TAG = "ObjectBrower";
boolean connected; boolean connected;
final Handler uavobjHandler = new Handler(); final Handler uavobjHandler = new Handler();
final Runnable updateText = new Runnable() { final Runnable updateText = new Runnable() {
public void run() { public void run() {
ToggleButton button = (ToggleButton) findViewById(R.id.toggleButton1); Log.d(TAG,"Update");
button.setChecked(!connected); update();
Log.d(TAG,"HERE" + connected);
TextView text = (TextView) findViewById(R.id.textView1);
UAVObject obj1 = objMngr.getObject("SystemStats");
UAVObject obj2 = objMngr.getObject("AttitudeRaw");
UAVObject obj3 = objMngr.getObject("AttitudeActual");
UAVObject obj4 = objMngr.getObject("SystemAlarms");
if(obj1 == null || obj2 == null || obj3 == null || obj4 == null)
return;
Log.d(TAG,"And here");
text.setText(obj1.toString() + "\n" + obj2.toString() + "\n" + obj3.toString() + "\n" + obj4.toString() );
} }
}; };
@ -49,11 +74,10 @@ public class ObjectBrowser extends ObjectManagerActivity {
@Override @Override
void onOPConnected() { void onOPConnected() {
// Toast.makeText(this,"Telemetry estabilished",Toast.LENGTH_SHORT); Toast.makeText(this,"Telemetry estabilished",Toast.LENGTH_SHORT);
Log.d(TAG, "onOPConnected()"); Log.d(TAG, "onOPConnected()");
UAVObject obj = objMngr.getObject("SystemStats"); UAVObject obj = objMngr.getObject("SystemStats");
Log.d(TAG, ((Boolean) (obj == null)).toString());
if(obj != null) if(obj != null)
obj.addUpdatedObserver(new Observer() { obj.addUpdatedObserver(new Observer() {
public void update(Observable observable, Object data) { public void update(Observable observable, Object data) {
@ -62,4 +86,18 @@ public class ObjectBrowser extends ObjectManagerActivity {
}); });
} }
public void update() {
List<List<UAVDataObject>> allobjects = objMngr.getDataObjects();
List<UAVDataObject> linearized = new ArrayList<UAVDataObject>();
ListIterator<List<UAVDataObject>> li = allobjects.listIterator();
while(li.hasNext()) {
linearized.addAll(li.next());
}
ArrayAdapter<UAVDataObject> adapter = new ArrayAdapter<UAVDataObject>(this,R.layout.object_view, linearized);
ListView objects = (ListView) findViewById(R.id.object_list);
objects.setAdapter(adapter);
}
} }

View File

@ -85,7 +85,6 @@ public abstract class ObjectManagerActivity extends Activity {
// We've bound to LocalService, cast the IBinder and attempt to open a connection // We've bound to LocalService, cast the IBinder and attempt to open a connection
if (DEBUG) Log.d(TAG,"Service bound"); if (DEBUG) Log.d(TAG,"Service bound");
binder = (LocalBinder) service; binder = (LocalBinder) service;
binder.openFakeConnection();
} }
public void onServiceDisconnected(ComponentName name) { public void onServiceDisconnected(ComponentName name) {

View File

@ -10,10 +10,10 @@ import java.util.TimerTask;
import android.util.Log; import android.util.Log;
public class TelemetryMonitor { public class TelemetryMonitor extends Observable{
private static final String TAG = "TelemetryMonitor"; private static final String TAG = "TelemetryMonitor";
public static int LOGLEVEL = 0; public static int LOGLEVEL = 2;
public static boolean WARN = LOGLEVEL > 1; public static boolean WARN = LOGLEVEL > 1;
public static boolean DEBUG = LOGLEVEL > 0; public static boolean DEBUG = LOGLEVEL > 0;
@ -31,6 +31,12 @@ public class TelemetryMonitor {
private long lastUpdateTime; private long lastUpdateTime;
private List<UAVObject> queue; private List<UAVObject> queue;
private boolean connected = false;
private boolean objects_updated = false;
public boolean getConnected() { return connected; };
public boolean getObjectsUpdated() { return objects_updated; };
public TelemetryMonitor(UAVObjectManager objMngr, Telemetry tel) public TelemetryMonitor(UAVObjectManager objMngr, Telemetry tel)
{ {
this.objMngr = objMngr; this.objMngr = objMngr;
@ -116,8 +122,9 @@ public class TelemetryMonitor {
if ( queue.isEmpty() ) if ( queue.isEmpty() )
{ {
if (DEBUG) Log.d(TAG, "All objects retrieved: Connected Successfully"); if (DEBUG) Log.d(TAG, "All objects retrieved: Connected Successfully");
//qxtLog->debug("Object retrieval completed"); objects_updated = true;
//emit connected(); setChanged();
notifyObservers();
return; return;
} }
// Get next object from the queue // Get next object from the queue
@ -260,9 +267,9 @@ public class TelemetryMonitor {
// Force telemetry update if not yet connected // Force telemetry update if not yet connected
boolean gcsStatusChanged = !oldStatus.equals(statusField.getValue()); boolean gcsStatusChanged = !oldStatus.equals(statusField.getValue());
boolean gcsConnected = ((String) statusField.getValue()).compareTo("Connected") == 0; boolean gcsConnected = statusField.getValue().equals("Connected");
boolean gcsDisconnected = ((String) statusField.getValue()).compareTo("Disconnected") == 0; boolean gcsDisconnected = statusField.getValue().equals("Disconnected");
boolean flightConnected = ((String) flightStatsObj.getField("Status").getValue()).compareTo("Connected") == 0; boolean flightConnected = flightStatsObj.getField("Status").equals("Connected");
if ( !gcsConnected || !flightConnected ) if ( !gcsConnected || !flightConnected )
{ {
@ -275,14 +282,21 @@ public class TelemetryMonitor {
{ {
if (DEBUG) Log.d(TAG,"Connection with the autopilot established"); if (DEBUG) Log.d(TAG,"Connection with the autopilot established");
setPeriod(STATS_UPDATE_PERIOD_MS); setPeriod(STATS_UPDATE_PERIOD_MS);
connected = true;
objects_updated = false;
startRetrievingObjects(); startRetrievingObjects();
setChanged();
} }
if (gcsDisconnected && gcsStatusChanged) if (gcsDisconnected && gcsStatusChanged)
{ {
if (DEBUG) Log.d(TAG,"Trying to connect to the autopilot"); if (DEBUG) Log.d(TAG,"Trying to connect to the autopilot");
setPeriod(STATS_CONNECT_PERIOD_MS); setPeriod(STATS_CONNECT_PERIOD_MS);
//emit disconnected(); connected = false;
objects_updated = false;
setChanged();
} }
notifyObservers();
} }
private void setPeriod(int ms) { private void setPeriod(int ms) {

View File

@ -197,8 +197,7 @@ public class UAVTalk extends Observable {
return false; return false;
} }
// System.out.println("Received byte " + val + " in state + " + //System.out.println("Received byte " + val + " in state + " + rxState);
// rxState);
processInputByte(val); processInputByte(val);
return true; return true;
} }