mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-17 02:52:12 +01:00
Works on Nook, but recursive loop too deep in registering objects
This commit is contained in:
parent
06f583ff75
commit
bd0a599e96
@ -5,8 +5,18 @@
|
||||
android:versionName="1.0">
|
||||
<uses-sdk android:minSdkVersion="7" />
|
||||
|
||||
<application android:icon="@drawable/icon" android:label="@string/app_name">
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||
|
||||
<application android:icon="@drawable/icon" android:label="@string/app_name" >
|
||||
|
||||
<activity android:name="ObjectBrowser"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
</application>
|
||||
</manifest>
|
@ -8,4 +8,4 @@
|
||||
# project structure.
|
||||
|
||||
# Project target.
|
||||
target=android-7
|
||||
target=android-10
|
||||
|
@ -7,6 +7,5 @@
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hello"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
@ -1,5 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="hello">Hello World!</string>
|
||||
<string name="app_name">OpenPilot GCS</string>
|
||||
</resources>
|
||||
|
129
androidgcs/src/org/openpilot/androidgcs/ObjectBrowser.java
Normal file
129
androidgcs/src/org/openpilot/androidgcs/ObjectBrowser.java
Normal file
@ -0,0 +1,129 @@
|
||||
package org.openpilot.androidgcs;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothSocket;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import org.openpilot.androidgcs.*;
|
||||
import org.openpilot.uavtalk.Telemetry;
|
||||
import org.openpilot.uavtalk.TelemetryMonitor;
|
||||
import org.openpilot.uavtalk.UAVObjectManager;
|
||||
import org.openpilot.uavtalk.UAVTalk;
|
||||
import org.openpilot.uavtalk.uavobjects.UAVObjectsInitialize;
|
||||
|
||||
public class ObjectBrowser extends Activity {
|
||||
|
||||
private final String TAG = "ObjectBrower";
|
||||
private final String DEVICE_NAME = "RN42-222D";
|
||||
private final int REQUEST_ENABLE_BT = 0;
|
||||
private UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
|
||||
BluetoothAdapter mBluetoothAdapter;
|
||||
UAVObjectManager objMngr;
|
||||
UAVTalk uavTalk;
|
||||
|
||||
/** Called when the activity is first created. */
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main);
|
||||
|
||||
Log.d(TAG, "Launching Object Browser");
|
||||
|
||||
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
if (mBluetoothAdapter == null) {
|
||||
// Device does not support Bluetooth
|
||||
Log.d(TAG, "Device does not support Bluetooth");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mBluetoothAdapter.isEnabled()) {
|
||||
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
|
||||
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
|
||||
} else {
|
||||
queryDevices();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if(requestCode == REQUEST_ENABLE_BT && resultCode == RESULT_OK) {
|
||||
Log.d(TAG, "Bluetooth started succesfully");
|
||||
queryDevices();
|
||||
}
|
||||
if(requestCode == REQUEST_ENABLE_BT && resultCode != RESULT_OK)
|
||||
Log.d(TAG, "Bluetooth could not be started");
|
||||
|
||||
}
|
||||
|
||||
public void queryDevices() {
|
||||
Log.d(TAG, "Searching for devices");
|
||||
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
|
||||
// If there are paired devices
|
||||
if (pairedDevices.size() > 0) {
|
||||
// Loop through paired devices
|
||||
for (BluetoothDevice device : pairedDevices) {
|
||||
// Add the name and address to an array adapter to show in a ListView
|
||||
//mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
|
||||
Log.d(TAG, "Paired device: " + device.getName());
|
||||
if(device.getName().compareTo(DEVICE_NAME) == 0) {
|
||||
openTelmetryBluetooth(device);
|
||||
openTelmetryBluetooth(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void openTelmetryBluetooth(BluetoothDevice device) {
|
||||
Log.d(TAG, "Opening conncetion to " + device.getName());
|
||||
BluetoothSocket socket = null;
|
||||
try {
|
||||
socket = device.createInsecureRfcommSocketToServiceRecord(MY_UUID);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG,"Unable to create Rfcomm socket");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
mBluetoothAdapter.cancelDiscovery();
|
||||
|
||||
try {
|
||||
socket.connect();
|
||||
}
|
||||
catch (IOException e) {
|
||||
Log.e(TAG,"Unable to connect to requested device", e);
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e2) {
|
||||
Log.e(TAG, "unable to close() socket during connection failure", e2);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
objMngr = new UAVObjectManager();
|
||||
UAVObjectsInitialize.register(objMngr);
|
||||
|
||||
try {
|
||||
uavTalk = new UAVTalk(socket.getInputStream(), socket.getOutputStream(), objMngr);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG,"Error starting UAVTalk");
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
Thread inputStream = uavTalk.getInputProcessThread();
|
||||
inputStream.start();
|
||||
|
||||
Telemetry tel = new Telemetry(uavTalk, objMngr);
|
||||
TelemetryMonitor mon = new TelemetryMonitor(objMngr,tel);
|
||||
|
||||
}
|
||||
}
|
@ -12,8 +12,12 @@ import java.util.TimerTask;
|
||||
|
||||
import org.openpilot.uavtalk.UAVObject.Acked;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class Telemetry {
|
||||
|
||||
private final String TAG = "Telemetry";
|
||||
|
||||
public class TelemetryStats {
|
||||
public int txBytes;
|
||||
public int rxBytes;
|
||||
@ -133,7 +137,7 @@ public class Telemetry {
|
||||
/**
|
||||
* Register a new object for periodic updates (if enabled)
|
||||
*/
|
||||
private void registerObject(UAVObject obj)
|
||||
private synchronized void registerObject(UAVObject obj)
|
||||
{
|
||||
// Setup object for periodic updates
|
||||
addObject(obj);
|
||||
@ -145,7 +149,7 @@ public class Telemetry {
|
||||
/**
|
||||
* Add an object in the list used for periodic updates
|
||||
*/
|
||||
private void addObject(UAVObject obj)
|
||||
private synchronized void addObject(UAVObject obj)
|
||||
{
|
||||
// Check if object type is already in the list
|
||||
ListIterator<ObjectTimeInfo> li = objList.listIterator();
|
||||
@ -169,7 +173,7 @@ public class Telemetry {
|
||||
/**
|
||||
* Update the object's timers
|
||||
*/
|
||||
private void setUpdatePeriod(UAVObject obj, int periodMs)
|
||||
private synchronized void setUpdatePeriod(UAVObject obj, int periodMs)
|
||||
{
|
||||
// Find object type (not instance!) and update its period
|
||||
ListIterator<ObjectTimeInfo> li = objList.listIterator();
|
||||
@ -186,7 +190,7 @@ public class Telemetry {
|
||||
/**
|
||||
* Connect to all instances of an object depending on the event mask specified
|
||||
*/
|
||||
private void connectToObjectInstances(UAVObject obj, int eventMask)
|
||||
private synchronized void connectToObjectInstances(UAVObject obj, int eventMask)
|
||||
{
|
||||
List<UAVObject> objs = objMngr.getObjectInstances(obj.getObjID());
|
||||
ListIterator<UAVObject> li = objs.listIterator();
|
||||
@ -235,7 +239,7 @@ public class Telemetry {
|
||||
/**
|
||||
* Update an object based on its metadata properties
|
||||
*/
|
||||
private void updateObject(UAVObject obj)
|
||||
private synchronized void updateObject(UAVObject obj)
|
||||
{
|
||||
// Get metadata
|
||||
UAVObject.Metadata metadata = obj.getMetadata();
|
||||
@ -287,12 +291,12 @@ public class Telemetry {
|
||||
/**
|
||||
* Called when a transaction is successfully completed (uavtalk event)
|
||||
*/
|
||||
private void transactionCompleted(UAVObject obj)
|
||||
private synchronized void transactionCompleted(UAVObject obj)
|
||||
{
|
||||
// Check if there is a pending transaction and the objects match
|
||||
if ( transPending && transInfo.obj.getObjID() == obj.getObjID() )
|
||||
{
|
||||
// qDebug() << QString("Telemetry: transaction completed for %1").arg(obj->getName());
|
||||
Log.d(TAG,"Telemetry: transaction completed for " + obj.getName());
|
||||
// Complete transaction
|
||||
transTimer.cancel();
|
||||
transPending = false;
|
||||
@ -302,16 +306,16 @@ public class Telemetry {
|
||||
processObjectQueue();
|
||||
} else
|
||||
{
|
||||
// qDebug() << "Error: received a transaction completed when did not expect it.";
|
||||
Log.e(TAG,"Error: received a transaction completed when did not expect it.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a transaction is not completed within the timeout period (timer event)
|
||||
*/
|
||||
private void transactionTimeout()
|
||||
private synchronized void transactionTimeout()
|
||||
{
|
||||
// qDebug() << "Telemetry: transaction timeout.";
|
||||
Log.d(TAG,"Telemetry: transaction timeout.");
|
||||
transTimer.cancel();
|
||||
// Proceed only if there is a pending transaction
|
||||
if ( transPending )
|
||||
@ -340,11 +344,11 @@ public class Telemetry {
|
||||
/**
|
||||
* Start an object transaction with UAVTalk, all information is stored in transInfo
|
||||
*/
|
||||
private void processObjectTransaction()
|
||||
private synchronized void processObjectTransaction()
|
||||
{
|
||||
if (transPending)
|
||||
{
|
||||
// qDebug() << tr("Process Object transaction for %1").arg(transInfo.obj->getName());
|
||||
Log.d(TAG, "Process Object transaction for " + transInfo.obj.getName());
|
||||
// Initiate transaction
|
||||
if (transInfo.objRequest)
|
||||
{
|
||||
@ -366,17 +370,17 @@ public class Telemetry {
|
||||
}
|
||||
} else
|
||||
{
|
||||
// qDebug() << "Error: inside of processObjectTransaction with no transPending";
|
||||
Log.e(TAG,"Error: inside of processObjectTransaction with no transPending");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the event received from an object
|
||||
*/
|
||||
private void processObjectUpdates(UAVObject obj, int event, boolean allInstances, boolean priority)
|
||||
private synchronized void processObjectUpdates(UAVObject obj, int event, boolean allInstances, boolean priority)
|
||||
{
|
||||
// Push event into queue
|
||||
// qDebug() << "Push event into queue for obj " << QString("%1 event %2").arg(obj->getName()).arg(event);
|
||||
Log.d(TAG, "Push event into queue for obj " + obj.getName() + " event " + event);
|
||||
ObjectQueueInfo objInfo = new ObjectQueueInfo();
|
||||
objInfo.obj = obj;
|
||||
objInfo.event = event;
|
||||
@ -391,7 +395,7 @@ public class Telemetry {
|
||||
{
|
||||
++txErrors;
|
||||
obj.transactionCompleted(false);
|
||||
//qxtLog->warning(tr("Telemetry: priority event queue is full, event lost (%1)").arg(obj->getName()));
|
||||
Log.w(TAG,"Telemetry: priority event queue is full, event lost " + obj.getName());
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -410,25 +414,26 @@ public class Telemetry {
|
||||
// If there is no transaction in progress then process event
|
||||
if (!transPending)
|
||||
{
|
||||
// qDebug() << "No transaction pending, process object queue...";
|
||||
|
||||
processObjectQueue();
|
||||
|
||||
} else
|
||||
{
|
||||
// qDebug() << "Transaction pending, DO NOT process object queue...";
|
||||
Log.d(TAG,"Transaction pending, DO NOT process object queue...");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process events from the object queue
|
||||
*/
|
||||
private void processObjectQueue()
|
||||
private synchronized void processObjectQueue()
|
||||
{
|
||||
// qDebug() << "Process object queue " << tr("- Depth (%1 %2)").arg(objQueue.length()).arg(objPriorityQueue.length());
|
||||
Log.d(TAG, "Process object queue - Depth " + objQueue.size() + " priority " + objPriorityQueue.size());
|
||||
|
||||
// Don nothing if a transaction is already in progress (should not happen)
|
||||
if (transPending)
|
||||
{
|
||||
// qxtLog->error("Telemetry: Dequeue while a transaction pending!");
|
||||
Log.e(TAG,"Dequeue while a transaction pending");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ public class TelemetryMonitor {
|
||||
/**
|
||||
* Initiate object retrieval, initialize queue with objects to be retrieved.
|
||||
*/
|
||||
public void startRetrievingObjects()
|
||||
public synchronized void startRetrievingObjects()
|
||||
{
|
||||
// Clear object queue
|
||||
queue.clear();
|
||||
@ -108,7 +108,7 @@ public class TelemetryMonitor {
|
||||
/**
|
||||
* Retrieve the next object in the queue
|
||||
*/
|
||||
public void retrieveNextObject()
|
||||
public synchronized void retrieveNextObject()
|
||||
{
|
||||
// If queue is empty return
|
||||
if ( queue.isEmpty() )
|
||||
@ -120,7 +120,12 @@ public class TelemetryMonitor {
|
||||
// Get next object from the queue
|
||||
UAVObject obj = queue.remove(0);
|
||||
|
||||
// Log.d(TAG, "Retrieving object: " + obj.getName()) ;
|
||||
if(obj == null) {
|
||||
Log.e(TAG, "Got null object forom transaction queue");
|
||||
return;
|
||||
}
|
||||
|
||||
Log.d(TAG, "Retrieving object: " + obj.getName()) ;
|
||||
// Connect to object
|
||||
obj.addTransactionCompleted(new Observer() {
|
||||
public void update(Observable observable, Object data) {
|
||||
@ -137,10 +142,12 @@ public class TelemetryMonitor {
|
||||
/**
|
||||
* Called by the retrieved object when a transaction is completed.
|
||||
*/
|
||||
public void transactionCompleted(UAVObject obj, boolean success)
|
||||
public synchronized void transactionCompleted(UAVObject obj, boolean success)
|
||||
{
|
||||
//QMutexLocker locker(mutex);
|
||||
// Disconnect from sending object
|
||||
Log.d(TAG,"transactionCompleted");
|
||||
// TODO: Need to be able to disconnect signals
|
||||
//obj->disconnect(this);
|
||||
objPending = null;
|
||||
|
||||
|
@ -17,12 +17,16 @@ public abstract class UAVObject {
|
||||
}
|
||||
|
||||
public void event () {
|
||||
setChanged();
|
||||
notifyObservers(parent);
|
||||
synchronized(this) {
|
||||
setChanged();
|
||||
notifyObservers(parent);
|
||||
}
|
||||
}
|
||||
public void event (Object data) {
|
||||
setChanged();
|
||||
notifyObservers(data);
|
||||
synchronized(this) {
|
||||
setChanged();
|
||||
notifyObservers(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user