1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-12-02 10:24:11 +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"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<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>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/object_list"></ListView>
</RelativeLayout>

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"?>
<resources>
<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>

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;
import java.util.Observable;
import java.util.Observer;
import org.openpilot.uavtalk.Telemetry;
import org.openpilot.uavtalk.TelemetryMonitor;
import org.openpilot.uavtalk.UAVDataObject;
@ -27,7 +30,7 @@ import android.widget.Toast;
public class OPTelemetryService extends Service {
// Logging settings
private final String TAG = "OPTElemetryService";
private final String TAG = "OPTelemetryService";
public static int LOGLEVEL = 2;
public static boolean WARN = LOGLEVEL > 1;
public static boolean DEBUG = LOGLEVEL > 0;
@ -44,10 +47,13 @@ public class OPTelemetryService extends Service {
private ServiceHandler mServiceHandler;
// Message ids
final int MSG_START = 0;
final int MSG_CONNECT_BT = 1;
final int MSG_CONNECT_FAKE = 2;
final int MSG_TOAST = 100;
static final int MSG_START = 0;
static final int MSG_CONNECT_BT = 1;
static final int MSG_CONNECT_FAKE = 2;
static final int MSG_DISCONNECT = 3;
static final int MSG_TOAST = 100;
private boolean terminate = false;
private Thread activeTelem;
@ -65,12 +71,28 @@ public class OPTelemetryService extends Service {
System.out.println("HERE");
stopSelf(msg.arg2);
case MSG_CONNECT_BT:
terminate = false;
activeTelem = new BTTelemetryThread();
activeTelem.start();
break;
case MSG_CONNECT_FAKE:
terminate = false;
activeTelem = new FakeTelemetryThread();
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;
case MSG_TOAST:
Toast.makeText(OPTelemetryService.this, (String) msg.obj, Toast.LENGTH_SHORT);
@ -129,8 +151,18 @@ public class OPTelemetryService extends Service {
msg.arg1 = MSG_CONNECT_FAKE;
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) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = MSG_TOAST;
@ -151,17 +183,17 @@ public class OPTelemetryService extends Service {
objMngr = new UAVObjectManager();
UAVObjectsInitialize.register(objMngr);
}
public void run() {
System.out.println("Runnin fake thread");
System.out.println("Running fake thread");
Intent intent = new Intent();
intent.setAction(INTENT_ACTION_CONNECTED);
sendBroadcast(intent,null);
//toastMessage("Started fake telemetry thread");
UAVDataObject systemStats = (UAVDataObject) objMngr.getObject("SystemStats");
while(true) {
while( !terminate ) {
systemStats.updated();
try {
Thread.sleep(1000);
@ -176,7 +208,7 @@ public class OPTelemetryService extends Service {
private UAVObjectManager objMngr;
private UAVTalk uavTalk;
private Telemetry tel;
//private TelemetryMonitor mon;
private TelemetryMonitor mon;
public UAVObjectManager getObjectManager() { return objMngr; };
@ -217,10 +249,21 @@ public class OPTelemetryService extends Service {
uavTalk = bt.getUavtalk();
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");
while(true) {
while( !terminate ) {
if( !uavTalk.processInputStream() )
break;
}

View File

@ -1,42 +1,67 @@
package org.openpilot.androidgcs;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.Observable;
import java.util.Observer;
import android.database.DataSetObserver;
import android.os.Bundle;
import android.os.Handler;
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.ToggleButton;
import android.widget.Toast;
import org.openpilot.uavtalk.UAVDataObject;
import org.openpilot.uavtalk.UAVObject;
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";
boolean connected;
final Handler uavobjHandler = new Handler();
final Runnable updateText = new Runnable() {
public void run() {
ToggleButton button = (ToggleButton) findViewById(R.id.toggleButton1);
button.setChecked(!connected);
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() );
Log.d(TAG,"Update");
update();
}
};
@ -44,16 +69,15 @@ public class ObjectBrowser extends ObjectManagerActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setContentView(R.layout.main);
}
@Override
void onOPConnected() {
// Toast.makeText(this,"Telemetry estabilished",Toast.LENGTH_SHORT);
Toast.makeText(this,"Telemetry estabilished",Toast.LENGTH_SHORT);
Log.d(TAG, "onOPConnected()");
UAVObject obj = objMngr.getObject("SystemStats");
Log.d(TAG, ((Boolean) (obj == null)).toString());
if(obj != null)
obj.addUpdatedObserver(new Observer() {
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
if (DEBUG) Log.d(TAG,"Service bound");
binder = (LocalBinder) service;
binder.openFakeConnection();
}
public void onServiceDisconnected(ComponentName name) {

View File

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

View File

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