mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-18 03:52:11 +01:00
More updates to UAVObject and Field for android app
This commit is contained in:
parent
b5e1d3bf29
commit
1c2eb1bf22
@ -1,5 +1,9 @@
|
|||||||
package org.openpilot.uavtalk;
|
package org.openpilot.uavtalk;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ListIterator;
|
||||||
|
|
||||||
public abstract class UAVObject {
|
public abstract class UAVObject {
|
||||||
|
|
||||||
|
|
||||||
@ -29,7 +33,7 @@ public abstract class UAVObject {
|
|||||||
TRUE
|
TRUE
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
final class Metadata {
|
protected final class Metadata {
|
||||||
public AccessMode flightAccess; /** Defines the access level for the local flight transactions (readonly and readwrite) */
|
public AccessMode flightAccess; /** Defines the access level for the local flight transactions (readonly and readwrite) */
|
||||||
public AccessMode gcsAccess; /** Defines the access level for the local GCS transactions (readonly and readwrite) */
|
public AccessMode gcsAccess; /** Defines the access level for the local GCS transactions (readonly and readwrite) */
|
||||||
public Acked flightTelemetryAcked; /** Defines if an ack is required for the transactions of this object (1:acked, 0:not acked) */
|
public Acked flightTelemetryAcked; /** Defines if an ack is required for the transactions of this object (1:acked, 0:not acked) */
|
||||||
@ -43,95 +47,441 @@ public abstract class UAVObject {
|
|||||||
} ;
|
} ;
|
||||||
|
|
||||||
public UAVObject(int objID, Boolean isSingleInst, String name) {
|
public UAVObject(int objID, Boolean isSingleInst, String name) {
|
||||||
assert(objID == getObjID()); // ID is in implementation code, make sure it matches object
|
this.objID = objID;
|
||||||
assert(name.equals(getName()));
|
this.instID = 0;
|
||||||
this.isSingleInst = isSingleInst;
|
this.isSingleInst = isSingleInst;
|
||||||
meta = getDefaultMetadata();
|
this.name = name;
|
||||||
|
// this.mutex = new QMutex(QMutex::Recursive);
|
||||||
};
|
};
|
||||||
|
|
||||||
public void initialize(int instID) {
|
public void initialize(int instID) {
|
||||||
|
//QMutexLocker locker(mutex);
|
||||||
this.instID = instID;
|
this.instID = instID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getInstID() { return instID; }
|
/**
|
||||||
public Boolean isSingleInstance() { return isSingleInst; }
|
* Initialize objects' data fields
|
||||||
public String getName() { return getObjName(); } // matching QT API to the current autogen code
|
* @param fields List of fields held by the object
|
||||||
|
* @param data Pointer to that actual object data, this is needed by the fields to access the data
|
||||||
public abstract int getObjID();
|
* @param numBytes Number of bytes in the object (total, including all fields)
|
||||||
public abstract String getDescription();
|
* @throws Exception When unable to unpack a field
|
||||||
public abstract String getObjName();
|
*/
|
||||||
|
public void initializeFields(List<UAVObjectField> fields, ByteBuffer data, int numBytes) throws Exception
|
||||||
int getNumBytes() {
|
{
|
||||||
return serialize().length;
|
// TODO: QMutexLocker locker(mutex);
|
||||||
|
this.numBytes = numBytes;
|
||||||
|
this.data = data;
|
||||||
|
this.fields = fields;
|
||||||
|
// Initialize fields
|
||||||
|
for (int n = 0; n < fields.size(); ++n)
|
||||||
|
{
|
||||||
|
fields.get(n).initialize(this);
|
||||||
|
}
|
||||||
|
unpack(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The name of the serializer and deserialize from the autogenerated code
|
/**
|
||||||
public abstract byte[] serialize();
|
* Get the object ID
|
||||||
public abstract void deserialize(byte[] arr,int offset);
|
*/
|
||||||
|
public int getObjID()
|
||||||
byte [] pack() {
|
{
|
||||||
return serialize();
|
return objID;
|
||||||
}
|
}
|
||||||
|
|
||||||
Boolean unpack(byte [] data) {
|
/**
|
||||||
deserialize(data, 0);
|
* Get the instance ID
|
||||||
return true;
|
*/
|
||||||
|
public int getInstID()
|
||||||
|
{
|
||||||
|
return instID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void setMetadata(Metadata obj);
|
/**
|
||||||
|
* Returns true if this is a single instance object
|
||||||
|
*/
|
||||||
|
public boolean isSingleInstance()
|
||||||
|
{
|
||||||
|
return isSingleInst;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of the object
|
||||||
|
*/
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the description of the object
|
||||||
|
* @return The description of the object
|
||||||
|
*/
|
||||||
|
public String getDescription()
|
||||||
|
{
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the description of the object
|
||||||
|
* @param The description of the object
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public void setDescription(String description)
|
||||||
|
{
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the total number of bytes of the object's data
|
||||||
|
*/
|
||||||
|
public int getNumBytes()
|
||||||
|
{
|
||||||
|
return numBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Request that this object is updated with the latest values from the autopilot
|
||||||
|
// */
|
||||||
|
// /* void UAVObject::requestUpdate()
|
||||||
|
// {
|
||||||
|
// emit updateRequested(this);
|
||||||
|
// } */
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Signal that the object has been updated
|
||||||
|
// */
|
||||||
|
// /* void UAVObject::updated()
|
||||||
|
// {
|
||||||
|
// emit objectUpdatedManual(this);
|
||||||
|
// emit objectUpdated(this);
|
||||||
|
// } */
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Lock mutex of this object
|
||||||
|
// */
|
||||||
|
// /* void UAVObject::lock()
|
||||||
|
// {
|
||||||
|
// mutex->lock();
|
||||||
|
// } */
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Lock mutex of this object
|
||||||
|
// */
|
||||||
|
// /* void UAVObject::lock(int timeoutMs)
|
||||||
|
// {
|
||||||
|
// mutex->tryLock(timeoutMs);
|
||||||
|
// } */
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Unlock mutex of this object
|
||||||
|
// */
|
||||||
|
// /* void UAVObject::unlock()
|
||||||
|
// {
|
||||||
|
// mutex->unlock();
|
||||||
|
// } */
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Get object's mutex
|
||||||
|
// */
|
||||||
|
// QMutex* UAVObject::getMutex()
|
||||||
|
// {
|
||||||
|
// return mutex;
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of fields held by this object
|
||||||
|
*/
|
||||||
|
public int getNumFields()
|
||||||
|
{
|
||||||
|
//QMutexLocker locker(mutex);
|
||||||
|
return fields.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the object's fields
|
||||||
|
*/
|
||||||
|
public List<UAVObjectField> getFields()
|
||||||
|
{
|
||||||
|
//QMutexLocker locker(mutex);
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a specific field
|
||||||
|
* @throws Exception
|
||||||
|
* @returns The field or NULL if not found
|
||||||
|
*/
|
||||||
|
public UAVObjectField getField(String name) throws Exception
|
||||||
|
{
|
||||||
|
//QMutexLocker locker(mutex);
|
||||||
|
// Look for field
|
||||||
|
ListIterator<UAVObjectField> li = fields.listIterator();
|
||||||
|
while(li.hasNext()) {
|
||||||
|
UAVObjectField field = li.next();
|
||||||
|
if(field.getName().equals(name))
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
throw new Exception("Field not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pack the object data into a byte array
|
||||||
|
* @param dataOut ByteBuffer to receive the data.
|
||||||
|
* @throws Exception
|
||||||
|
* @returns The number of bytes copied
|
||||||
|
* @note The array must already have enough space allocated for the object
|
||||||
|
*/
|
||||||
|
public int pack(ByteBuffer dataOut) throws Exception
|
||||||
|
{
|
||||||
|
// QMutexLocker locker(mutex);
|
||||||
|
if(dataOut.remaining() < getNumBytes())
|
||||||
|
throw new Exception("Not enough bytes in ByteBuffer to pack object");
|
||||||
|
int numBytes = 0;
|
||||||
|
|
||||||
|
ListIterator<UAVObjectField> li = fields.listIterator();
|
||||||
|
while(li.hasNext()) {
|
||||||
|
UAVObjectField field = li.next();
|
||||||
|
numBytes += field.pack(dataOut);
|
||||||
|
}
|
||||||
|
return numBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unpack the object data from a byte array
|
||||||
|
* @param dataIn The ByteBuffer to pull data from
|
||||||
|
* @throws Exception
|
||||||
|
* @returns The number of bytes copied
|
||||||
|
*/
|
||||||
|
public int unpack(ByteBuffer dataIn) throws Exception
|
||||||
|
{
|
||||||
|
// QMutexLocker locker(mutex);
|
||||||
|
int numBytes = 0;
|
||||||
|
ListIterator<UAVObjectField> li = fields.listIterator();
|
||||||
|
while(li.hasNext()) {
|
||||||
|
UAVObjectField field = li.next();
|
||||||
|
numBytes += field.unpack(dataIn);
|
||||||
|
}
|
||||||
|
return numBytes;
|
||||||
|
// TODO: Callbacks
|
||||||
|
//emit objectUnpacked(this); // trigger object updated event
|
||||||
|
//emit objectUpdated(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Save the object data to the file.
|
||||||
|
// * The file will be created in the current directory
|
||||||
|
// * and its name will be the same as the object with
|
||||||
|
// * the .uavobj extension.
|
||||||
|
// * @returns True on success, false on failure
|
||||||
|
// */
|
||||||
|
// bool UAVObject::save()
|
||||||
|
// {
|
||||||
|
// QMutexLocker locker(mutex);
|
||||||
|
//
|
||||||
|
// // Open file
|
||||||
|
// QFile file(name + ".uavobj");
|
||||||
|
// if (!file.open(QFile::WriteOnly))
|
||||||
|
// {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Write object
|
||||||
|
// if ( !save(file) )
|
||||||
|
// {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Close file
|
||||||
|
// file.close();
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Save the object data to the file.
|
||||||
|
// * The file is expected to be already open for writting.
|
||||||
|
// * The data will be appended and the file will not be closed.
|
||||||
|
// * @returns True on success, false on failure
|
||||||
|
// */
|
||||||
|
// bool UAVObject::save(QFile& file)
|
||||||
|
// {
|
||||||
|
// QMutexLocker locker(mutex);
|
||||||
|
// quint8 buffer[numBytes];
|
||||||
|
// quint8 tmpId[4];
|
||||||
|
//
|
||||||
|
// // Write the object ID
|
||||||
|
// qToLittleEndian<quint32>(objID, tmpId);
|
||||||
|
// if ( file.write((const char*)tmpId, 4) == -1 )
|
||||||
|
// {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Write the instance ID
|
||||||
|
// if (!isSingleInst)
|
||||||
|
// {
|
||||||
|
// qToLittleEndian<quint16>(instID, tmpId);
|
||||||
|
// if ( file.write((const char*)tmpId, 2) == -1 )
|
||||||
|
// {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Write the data
|
||||||
|
// pack(buffer);
|
||||||
|
// if ( file.write((const char*)buffer, numBytes) == -1 )
|
||||||
|
// {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Done
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Load the object data from a file.
|
||||||
|
// * The file will be openned in the current directory
|
||||||
|
// * and its name will be the same as the object with
|
||||||
|
// * the .uavobj extension.
|
||||||
|
// * @returns True on success, false on failure
|
||||||
|
// */
|
||||||
|
// bool UAVObject::load()
|
||||||
|
// {
|
||||||
|
// QMutexLocker locker(mutex);
|
||||||
|
//
|
||||||
|
// // Open file
|
||||||
|
// QFile file(name + ".uavobj");
|
||||||
|
// if (!file.open(QFile::ReadOnly))
|
||||||
|
// {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Load object
|
||||||
|
// if ( !load(file) )
|
||||||
|
// {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Close file
|
||||||
|
// file.close();
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Load the object data from file.
|
||||||
|
// * The file is expected to be already open for reading.
|
||||||
|
// * The data will be read and the file will not be closed.
|
||||||
|
// * @returns True on success, false on failure
|
||||||
|
// */
|
||||||
|
// bool UAVObject::load(QFile& file)
|
||||||
|
// {
|
||||||
|
// QMutexLocker locker(mutex);
|
||||||
|
// quint8 buffer[numBytes];
|
||||||
|
// quint8 tmpId[4];
|
||||||
|
//
|
||||||
|
// // Read the object ID
|
||||||
|
// if ( file.read((char*)tmpId, 4) != 4 )
|
||||||
|
// {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Check that the IDs match
|
||||||
|
// if (qFromLittleEndian<quint32>(tmpId) != objID)
|
||||||
|
// {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Read the instance ID
|
||||||
|
// if ( file.read((char*)tmpId, 2) != 2 )
|
||||||
|
// {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Check that the IDs match
|
||||||
|
// if (qFromLittleEndian<quint16>(tmpId) != instID)
|
||||||
|
// {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Read and unpack the data
|
||||||
|
// if ( file.read((char*)buffer, numBytes) != numBytes )
|
||||||
|
// {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// unpack(buffer);
|
||||||
|
//
|
||||||
|
// // Done
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a string with the object information
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return toStringBrief() + toStringData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a string with the object information (only the header)
|
||||||
|
*/
|
||||||
|
public String toStringBrief()
|
||||||
|
{
|
||||||
|
return String.format("%1 (ID: %2, InstID: %3, NumBytes: %4, SInst: %5)\n",
|
||||||
|
getName(),
|
||||||
|
getObjID(),
|
||||||
|
getInstID(),
|
||||||
|
getNumBytes(),
|
||||||
|
isSingleInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a string with the object information (only the data)
|
||||||
|
*/
|
||||||
|
public String toStringData()
|
||||||
|
{
|
||||||
|
String s = new String();
|
||||||
|
ListIterator<UAVObjectField> li = fields.listIterator();
|
||||||
|
while(li.hasNext()) {
|
||||||
|
UAVObjectField field = li.next();
|
||||||
|
s += field.toString();
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Emit the transactionCompleted event (used by the UAVTalk plugin)
|
||||||
|
// */
|
||||||
|
// void UAVObject::emitTransactionCompleted(bool success)
|
||||||
|
// {
|
||||||
|
// emit transactionCompleted(this, success);
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Java specific functions
|
||||||
|
*/
|
||||||
|
public UAVObject clone() {
|
||||||
|
return (UAVObject) clone();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Abstract functions
|
||||||
|
*/
|
||||||
|
public abstract void setMetadata(Metadata mdata);
|
||||||
public abstract Metadata getMetadata();
|
public abstract Metadata getMetadata();
|
||||||
public abstract Metadata getDefaultMetadata();
|
public abstract Metadata getDefaultMetadata();
|
||||||
|
public abstract UAVDataObject clone(int instID);
|
||||||
|
protected abstract void setDefaultFieldValues();
|
||||||
|
|
||||||
private Boolean isSingleInst;
|
/**
|
||||||
private int instID;
|
* Private data for the object, common to all
|
||||||
private Metadata meta;
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Unported code from QT
|
|
||||||
bool save();
|
|
||||||
bool save(QFile& file);
|
|
||||||
bool load();
|
|
||||||
bool load(QFile& file);
|
|
||||||
virtual void setMetadata(const Metadata& mdata) = 0;
|
|
||||||
virtual Metadata getMetadata() = 0;
|
|
||||||
virtual Metadata getDefaultMetadata() = 0;
|
|
||||||
void requestUpdate();
|
|
||||||
void updated();
|
|
||||||
void lock();
|
|
||||||
void lock(int timeoutMs);
|
|
||||||
void unlock();
|
|
||||||
QMutex* getMutex();
|
|
||||||
qint32 getNumFields();
|
|
||||||
QList<UAVObjectField*> getFields();
|
|
||||||
UAVObjectField* getField(const QString& name);
|
|
||||||
QString toString();
|
|
||||||
QString toStringBrief();
|
|
||||||
QString toStringData();
|
|
||||||
void emitTransactionCompleted(bool success);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void objectUpdated(UAVObject* obj);
|
|
||||||
void objectUpdatedAuto(UAVObject* obj);
|
|
||||||
void objectUpdatedManual(UAVObject* obj);
|
|
||||||
void objectUnpacked(UAVObject* obj);
|
|
||||||
void updateRequested(UAVObject* obj);
|
|
||||||
void transactionCompleted(UAVObject* obj, bool success);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void fieldUpdated(UAVObjectField* field);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
quint32 objID;
|
|
||||||
quint32 instID;
|
|
||||||
bool isSingleInst;
|
|
||||||
QString name;
|
|
||||||
QString description;
|
|
||||||
quint32 numBytes;
|
|
||||||
QMutex* mutex;
|
|
||||||
quint8* data;
|
|
||||||
QList<UAVObjectField*> fields;
|
|
||||||
|
|
||||||
void initializeFields(QList<UAVObjectField*>& fields, quint8* data, quint32 numBytes);
|
|
||||||
void setDescription(const QString& description);
|
|
||||||
*/
|
*/
|
||||||
|
protected int objID;
|
||||||
|
protected int instID;
|
||||||
|
protected boolean isSingleInst;
|
||||||
|
protected String name;
|
||||||
|
protected String description;
|
||||||
|
protected int numBytes;
|
||||||
|
// TODO: QMutex* mutex;
|
||||||
|
protected ByteBuffer data;
|
||||||
|
protected List<UAVObjectField> fields;
|
||||||
}
|
}
|
||||||
|
@ -90,8 +90,7 @@ public class UAVObjectField {
|
|||||||
* to a new ByteBuffer for UAVTalk. It also converts from the java standard (big endian)
|
* to a new ByteBuffer for UAVTalk. It also converts from the java standard (big endian)
|
||||||
* to the arm/uavtalk standard (little endian)
|
* to the arm/uavtalk standard (little endian)
|
||||||
* @param dataOut
|
* @param dataOut
|
||||||
* @return
|
* @return the number of bytes added
|
||||||
]
|
|
||||||
* @throws Exception */
|
* @throws Exception */
|
||||||
public int pack(ByteBuffer dataOut) throws Exception {
|
public int pack(ByteBuffer dataOut) throws Exception {
|
||||||
//QMutexLocker locker(obj->getMutex());
|
//QMutexLocker locker(obj->getMutex());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user