mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-02-06 21:54:15 +01:00
Works on Nook, but recursive loop too deep in registering objects
This commit is contained in:
parent
20a4021bd3
commit
34dfaf0023
@ -5,8 +5,18 @@
|
|||||||
android:versionName="1.0">
|
android:versionName="1.0">
|
||||||
<uses-sdk android:minSdkVersion="7" />
|
<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>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
@ -8,4 +8,4 @@
|
|||||||
# project structure.
|
# project structure.
|
||||||
|
|
||||||
# Project target.
|
# Project target.
|
||||||
target=android-7
|
target=android-10
|
||||||
|
@ -7,6 +7,5 @@
|
|||||||
<TextView
|
<TextView
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/hello"
|
|
||||||
/>
|
/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="hello">Hello World!</string>
|
|
||||||
<string name="app_name">OpenPilot GCS</string>
|
<string name="app_name">OpenPilot GCS</string>
|
||||||
</resources>
|
</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 org.openpilot.uavtalk.UAVObject.Acked;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
public class Telemetry {
|
public class Telemetry {
|
||||||
|
|
||||||
|
private final String TAG = "Telemetry";
|
||||||
|
|
||||||
public class TelemetryStats {
|
public class TelemetryStats {
|
||||||
public int txBytes;
|
public int txBytes;
|
||||||
public int rxBytes;
|
public int rxBytes;
|
||||||
@ -133,7 +137,7 @@ public class Telemetry {
|
|||||||
/**
|
/**
|
||||||
* Register a new object for periodic updates (if enabled)
|
* 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
|
// Setup object for periodic updates
|
||||||
addObject(obj);
|
addObject(obj);
|
||||||
@ -145,7 +149,7 @@ public class Telemetry {
|
|||||||
/**
|
/**
|
||||||
* Add an object in the list used for periodic updates
|
* 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
|
// Check if object type is already in the list
|
||||||
ListIterator<ObjectTimeInfo> li = objList.listIterator();
|
ListIterator<ObjectTimeInfo> li = objList.listIterator();
|
||||||
@ -169,7 +173,7 @@ public class Telemetry {
|
|||||||
/**
|
/**
|
||||||
* Update the object's timers
|
* 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
|
// Find object type (not instance!) and update its period
|
||||||
ListIterator<ObjectTimeInfo> li = objList.listIterator();
|
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
|
* 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());
|
List<UAVObject> objs = objMngr.getObjectInstances(obj.getObjID());
|
||||||
ListIterator<UAVObject> li = objs.listIterator();
|
ListIterator<UAVObject> li = objs.listIterator();
|
||||||
@ -235,7 +239,7 @@ public class Telemetry {
|
|||||||
/**
|
/**
|
||||||
* Update an object based on its metadata properties
|
* Update an object based on its metadata properties
|
||||||
*/
|
*/
|
||||||
private void updateObject(UAVObject obj)
|
private synchronized void updateObject(UAVObject obj)
|
||||||
{
|
{
|
||||||
// Get metadata
|
// Get metadata
|
||||||
UAVObject.Metadata metadata = obj.getMetadata();
|
UAVObject.Metadata metadata = obj.getMetadata();
|
||||||
@ -287,12 +291,12 @@ public class Telemetry {
|
|||||||
/**
|
/**
|
||||||
* Called when a transaction is successfully completed (uavtalk event)
|
* 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
|
// Check if there is a pending transaction and the objects match
|
||||||
if ( transPending && transInfo.obj.getObjID() == obj.getObjID() )
|
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
|
// Complete transaction
|
||||||
transTimer.cancel();
|
transTimer.cancel();
|
||||||
transPending = false;
|
transPending = false;
|
||||||
@ -302,16 +306,16 @@ public class Telemetry {
|
|||||||
processObjectQueue();
|
processObjectQueue();
|
||||||
} else
|
} 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)
|
* 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();
|
transTimer.cancel();
|
||||||
// Proceed only if there is a pending transaction
|
// Proceed only if there is a pending transaction
|
||||||
if ( transPending )
|
if ( transPending )
|
||||||
@ -340,11 +344,11 @@ public class Telemetry {
|
|||||||
/**
|
/**
|
||||||
* Start an object transaction with UAVTalk, all information is stored in transInfo
|
* Start an object transaction with UAVTalk, all information is stored in transInfo
|
||||||
*/
|
*/
|
||||||
private void processObjectTransaction()
|
private synchronized void processObjectTransaction()
|
||||||
{
|
{
|
||||||
if (transPending)
|
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
|
// Initiate transaction
|
||||||
if (transInfo.objRequest)
|
if (transInfo.objRequest)
|
||||||
{
|
{
|
||||||
@ -366,17 +370,17 @@ public class Telemetry {
|
|||||||
}
|
}
|
||||||
} else
|
} 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
|
* 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
|
// 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();
|
ObjectQueueInfo objInfo = new ObjectQueueInfo();
|
||||||
objInfo.obj = obj;
|
objInfo.obj = obj;
|
||||||
objInfo.event = event;
|
objInfo.event = event;
|
||||||
@ -391,7 +395,7 @@ public class Telemetry {
|
|||||||
{
|
{
|
||||||
++txErrors;
|
++txErrors;
|
||||||
obj.transactionCompleted(false);
|
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
|
else
|
||||||
@ -410,25 +414,26 @@ public class Telemetry {
|
|||||||
// If there is no transaction in progress then process event
|
// If there is no transaction in progress then process event
|
||||||
if (!transPending)
|
if (!transPending)
|
||||||
{
|
{
|
||||||
// qDebug() << "No transaction pending, process object queue...";
|
|
||||||
processObjectQueue();
|
processObjectQueue();
|
||||||
|
|
||||||
} else
|
} 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
|
* 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)
|
// Don nothing if a transaction is already in progress (should not happen)
|
||||||
if (transPending)
|
if (transPending)
|
||||||
{
|
{
|
||||||
// qxtLog->error("Telemetry: Dequeue while a transaction pending!");
|
Log.e(TAG,"Dequeue while a transaction pending");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ public class TelemetryMonitor {
|
|||||||
/**
|
/**
|
||||||
* Initiate object retrieval, initialize queue with objects to be retrieved.
|
* Initiate object retrieval, initialize queue with objects to be retrieved.
|
||||||
*/
|
*/
|
||||||
public void startRetrievingObjects()
|
public synchronized void startRetrievingObjects()
|
||||||
{
|
{
|
||||||
// Clear object queue
|
// Clear object queue
|
||||||
queue.clear();
|
queue.clear();
|
||||||
@ -108,7 +108,7 @@ public class TelemetryMonitor {
|
|||||||
/**
|
/**
|
||||||
* Retrieve the next object in the queue
|
* Retrieve the next object in the queue
|
||||||
*/
|
*/
|
||||||
public void retrieveNextObject()
|
public synchronized void retrieveNextObject()
|
||||||
{
|
{
|
||||||
// If queue is empty return
|
// If queue is empty return
|
||||||
if ( queue.isEmpty() )
|
if ( queue.isEmpty() )
|
||||||
@ -120,7 +120,12 @@ public class TelemetryMonitor {
|
|||||||
// Get next object from the queue
|
// Get next object from the queue
|
||||||
UAVObject obj = queue.remove(0);
|
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
|
// Connect to object
|
||||||
obj.addTransactionCompleted(new Observer() {
|
obj.addTransactionCompleted(new Observer() {
|
||||||
public void update(Observable observable, Object data) {
|
public void update(Observable observable, Object data) {
|
||||||
@ -137,10 +142,12 @@ public class TelemetryMonitor {
|
|||||||
/**
|
/**
|
||||||
* Called by the retrieved object when a transaction is completed.
|
* 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);
|
//QMutexLocker locker(mutex);
|
||||||
// Disconnect from sending object
|
// Disconnect from sending object
|
||||||
|
Log.d(TAG,"transactionCompleted");
|
||||||
|
// TODO: Need to be able to disconnect signals
|
||||||
//obj->disconnect(this);
|
//obj->disconnect(this);
|
||||||
objPending = null;
|
objPending = null;
|
||||||
|
|
||||||
|
@ -17,14 +17,18 @@ public abstract class UAVObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void event () {
|
public void event () {
|
||||||
|
synchronized(this) {
|
||||||
setChanged();
|
setChanged();
|
||||||
notifyObservers(parent);
|
notifyObservers(parent);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
public void event (Object data) {
|
public void event (Object data) {
|
||||||
|
synchronized(this) {
|
||||||
setChanged();
|
setChanged();
|
||||||
notifyObservers(data);
|
notifyObservers(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class TransactionResult {
|
public class TransactionResult {
|
||||||
public UAVObject obj;
|
public UAVObject obj;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user