1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-20 10:54:14 +01:00

Added UPDATEMODE_THROTTLED to UAVObjects update modes.

This commit is contained in:
Brian Webb 2012-04-18 18:47:13 -07:00
parent f4164d97bd
commit 19166cc830
8 changed files with 92 additions and 50 deletions

View File

@ -73,7 +73,7 @@ static void telemetryTxTask(void *parameters);
static void telemetryRxTask(void *parameters);
static int32_t transmitData(uint8_t * data, int32_t length);
static void registerObject(UAVObjHandle obj);
static void updateObject(UAVObjHandle obj);
static void updateObject(UAVObjHandle obj, int32_t eventType);
static int32_t addObject(UAVObjHandle obj);
static int32_t setUpdatePeriod(UAVObjHandle obj, int32_t updatePeriodMs);
static void processObjEvent(UAVObjEvent * ev);
@ -158,14 +158,14 @@ static void registerObject(UAVObjHandle obj)
addObject(obj);
// Setup object for telemetry updates
updateObject(obj);
updateObject(obj, EV_NONE);
}
/**
* Update object's queue connections and timer, depending on object's settings
* \param[in] obj Object to updates
*/
static void updateObject(UAVObjHandle obj)
static void updateObject(UAVObjHandle obj, int32_t eventType)
{
UAVObjMetadata metadata;
UAVObjUpdateMode updateMode;
@ -180,7 +180,7 @@ static void updateObject(UAVObjHandle obj)
// Set update period
setUpdatePeriod(obj, metadata.telemetryUpdatePeriod);
// Connect queue
eventMask = EV_UPDATED_MANUAL | EV_UPDATE_REQ;
eventMask = EV_UPDATED_MANUAL | EV_UPDATE_REQ | EV_UPDATED_PERIODIC;
if (UAVObjIsMetaobject(obj)) {
eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events)
}
@ -194,6 +194,29 @@ static void updateObject(UAVObjHandle obj)
eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events)
}
UAVObjConnectQueue(obj, priorityQueue, eventMask);
} else if (updateMode == UPDATEMODE_THROTTLED) {
// If we received a periodic update, we can change back to update on change
if (eventType == EV_UPDATED_PERIODIC) {
// Set update period
setUpdatePeriod(obj, 0);
// Connect queue
eventMask = EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ;
if (UAVObjIsMetaobject(obj)) {
eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events)
}
UAVObjConnectQueue(obj, priorityQueue, eventMask);
} else {
// Otherwise, we just received an object update, so switch to periodic for the timeout period to prevent more updates
// Set update period
setUpdatePeriod(obj, metadata.telemetryUpdatePeriod);
// Connect queue
eventMask = EV_UPDATED_MANUAL | EV_UPDATE_REQ | EV_UPDATED_PERIODIC;
if (UAVObjIsMetaobject(obj)) {
eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events)
}
UAVObjConnectQueue(obj, priorityQueue, eventMask);
}
UAVObjConnectQueue(obj, priorityQueue, eventMask);
} else if (updateMode == UPDATEMODE_MANUAL) {
// Set update period
setUpdatePeriod(obj, 0);
@ -203,11 +226,6 @@ static void updateObject(UAVObjHandle obj)
eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events)
}
UAVObjConnectQueue(obj, priorityQueue, eventMask);
} else if (updateMode == UPDATEMODE_NEVER) {
// Set update period
setUpdatePeriod(obj, 0);
// Disconnect queue
UAVObjDisconnectQueue(obj, priorityQueue);
}
}
@ -217,6 +235,7 @@ static void updateObject(UAVObjHandle obj)
static void processObjEvent(UAVObjEvent * ev)
{
UAVObjMetadata metadata;
UAVObjUpdateMode updateMode;
FlightTelemetryStatsData flightStats;
int32_t retries;
int32_t success;
@ -231,10 +250,11 @@ static void processObjEvent(UAVObjEvent * ev)
if (flightStats.Status == FLIGHTTELEMETRYSTATS_STATUS_CONNECTED || ev->obj == FlightTelemetryStatsHandle()) {
// Get object metadata
UAVObjGetMetadata(ev->obj, &metadata);
updateMode = UAVObjGetTelemetryUpdateMode(&metadata);
// Act on event
retries = 0;
success = -1;
if (ev->event == EV_UPDATED || ev->event == EV_UPDATED_MANUAL) {
if (ev->event == EV_UPDATED || ev->event == EV_UPDATED_MANUAL || ((ev->event == EV_UPDATED_PERIODIC) && (updateMode != UPDATEMODE_THROTTLED))) {
// Send update to GCS (with retries)
while (retries < MAX_RETRIES && success == -1) {
success = UAVTalkSendObject(uavTalkCon, ev->obj, ev->instId, UAVObjGetTelemetryAcked(&metadata), REQ_TIMEOUT_MS); // call blocks until ack is received or timeout
@ -259,7 +279,7 @@ static void processObjEvent(UAVObjEvent * ev)
}
// If this is a metaobject then make necessary telemetry updates
if (UAVObjIsMetaobject(ev->obj)) {
updateObject(UAVObjGetLinkedObj(ev->obj)); // linked object will be the actual object the metadata are for
updateObject(UAVObjGetLinkedObj(ev->obj), ev->event); // linked object will be the actual object the metadata are for
}
}
}
@ -396,7 +416,7 @@ static int32_t setUpdatePeriod(UAVObjHandle obj, int32_t updatePeriodMs)
// Add object for periodic updates
ev.obj = obj;
ev.instId = UAVOBJ_ALL_INSTANCES;
ev.event = EV_UPDATED_MANUAL;
ev.event = EV_UPDATED_PERIODIC;
return EventPeriodicQueueUpdate(&ev, queue, updatePeriodMs);
}

View File

@ -61,8 +61,8 @@ typedef void* UAVObjHandle;
typedef enum {
UPDATEMODE_PERIODIC = 0, /** Automatically update object at periodic intervals */
UPDATEMODE_ONCHANGE = 1, /** Only update object when its data changes */
UPDATEMODE_MANUAL = 2, /** Manually update object, by calling the updated() function */
UPDATEMODE_NEVER = 3 /** Object is never updated */
UPDATEMODE_THROTTLED = 2, /** Object is updated on change, but not more often than the interval time */
UPDATEMODE_MANUAL = 3 /** Manually update object, by calling the updated() function */
} UAVObjUpdateMode;
/**
@ -72,14 +72,14 @@ typedef enum {
* The object metadata flags are packed into a single 16 bit integer.
* The bits in the flag field are defined as:
*
* Bit(s) Name Meaning
* ------ ---- -------
* 0 access Defines the access level for the local transactions (readonly=0 and readwrite=1)
* 1 gcsAccess Defines the access level for the local GCS transactions (readonly=0 and readwrite=1), not used in the flight s/w
* 2 telemetryAcked Defines if an ack is required for the transactions of this object (1:acked, 0:not acked)
* 3 gcsTelemetryAcked Defines if an ack is required for the transactions of this object (1:acked, 0:not acked)
* 4-5 telemetryUpdateMode Update mode used by the telemetry module (UAVObjUpdateMode)
* 6-7 gcsTelemetryUpdateMode Update mode used by the GCS (UAVObjUpdateMode)
* Bit(s) Name Meaning
* ------ ---- -------
* 0 access Defines the access level for the local transactions (readonly=0 and readwrite=1)
* 1 gcsAccess Defines the access level for the local GCS transactions (readonly=0 and readwrite=1), not used in the flight s/w
* 2 telemetryAcked Defines if an ack is required for the transactions of this object (1:acked, 0:not acked)
* 3 gcsTelemetryAcked Defines if an ack is required for the transactions of this object (1:acked, 0:not acked)
* 4-5 telemetryUpdateMode Update mode used by the telemetry module (UAVObjUpdateMode)
* 6-7 gcsTelemetryUpdateMode Update mode used by the GCS (UAVObjUpdateMode)
*/
typedef struct {
uint8_t flags; /** Defines flags for update and logging modes and whether an update should be ACK'd (bits defined above) */
@ -92,10 +92,12 @@ typedef struct {
* Event types generated by the objects.
*/
typedef enum {
EV_NONE = 0x00, /** No event */
EV_UNPACKED = 0x01, /** Object data updated by unpacking */
EV_UPDATED = 0x02, /** Object data updated by changing the data structure */
EV_UPDATED_MANUAL = 0x04, /** Object update event manually generated */
EV_UPDATE_REQ = 0x08 /** Request to update object data */
EV_UPDATED_PERIODIC = 0x08, /** Object update from periodic event */
EV_UPDATE_REQ = 0x10 /** Request to update object data */
} UAVObjEventType;
/**

View File

@ -251,7 +251,7 @@ void Simulator::setupOutputObject(UAVObject* obj, int updatePeriod)
mdata = obj->getDefaultMetadata();
UAVObject::SetFlightAccess(mdata, UAVObject::ACCESS_READONLY);
UAVObject::SetGcsAccess(mdata, UAVObject::ACCESS_READWRITE);
UAVObject::SetFlightTelemetryUpdateMode(mdata,UAVObject::UPDATEMODE_NEVER);
UAVObject::SetFlightTelemetryUpdateMode(mdata,UAVObject::UPDATEMODE_MANUAL);
UAVObject::SetGcsTelemetryAcked(mdata, false);
UAVObject::SetGcsTelemetryUpdateMode(mdata, UAVObject::UPDATEMODE_PERIODIC);
mdata.gcsTelemetryUpdatePeriod = updatePeriod;

View File

@ -60,8 +60,8 @@ public:
typedef enum {
UPDATEMODE_PERIODIC = 0, /** Automatically update object at periodic intervals */
UPDATEMODE_ONCHANGE = 1, /** Only update object when its data changes */
UPDATEMODE_MANUAL = 2, /** Manually update object, by calling the updated() function */
UPDATEMODE_NEVER = 3 /** Object is never updated */
UPDATEMODE_THROTTLED = 2, /** Object is updated on change, but not more often than the interval time */
UPDATEMODE_MANUAL = 3 /** Manually update object, by calling the updated() function */
} UpdateMode;
/**

View File

@ -77,7 +77,7 @@ void Telemetry::registerObject(UAVObject* obj)
addObject(obj);
// Setup object for telemetry updates
updateObject(obj);
updateObject(obj, EV_NONE);
}
/**
@ -152,7 +152,7 @@ void Telemetry::connectToObjectInstances(UAVObject* obj, quint32 eventMask)
/**
* Update an object based on its metadata properties
*/
void Telemetry::updateObject(UAVObject* obj)
void Telemetry::updateObject(UAVObject* obj, quint32 eventType)
{
// Get metadata
UAVObject::Metadata metadata = obj->getMetadata();
@ -184,6 +184,34 @@ void Telemetry::updateObject(UAVObject* obj)
}
connectToObjectInstances(obj, eventMask);
}
else if ( updateMode == UAVObject::UPDATEMODE_THROTTLED )
{
// If we received a periodic update, we can change back to update on change
if (eventType == EV_UPDATED_PERIODIC) {
// Set update period
setUpdatePeriod(obj, 0);
// Connect signals for all instances
eventMask = EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ;
if( dynamic_cast<UAVMetaObject*>(obj) != NULL )
{
eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events)
}
connectToObjectInstances(obj, eventMask);
}
else
{
// Otherwise, we just received an object update, so switch to periodic for the timeout period to prevent more updates
// Set update period
setUpdatePeriod(obj, metadata.gcsTelemetryUpdatePeriod);
// Connect signals for all instances
eventMask = EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ;
if( dynamic_cast<UAVMetaObject*>(obj) != NULL )
{
eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events)
}
connectToObjectInstances(obj, eventMask);
}
}
else if ( updateMode == UAVObject::UPDATEMODE_MANUAL )
{
// Set update period
@ -196,13 +224,6 @@ void Telemetry::updateObject(UAVObject* obj)
}
connectToObjectInstances(obj, eventMask);
}
else if ( updateMode == UAVObject::UPDATEMODE_NEVER )
{
// Set update period
setUpdatePeriod(obj, 0);
// Disconnect from object
connectToObjectInstances(obj, 0);
}
}
/**
@ -409,7 +430,7 @@ void Telemetry::processObjectQueue()
UAVMetaObject* metaobj = dynamic_cast<UAVMetaObject*>(objInfo.obj);
if ( metaobj != NULL )
{
updateObject( metaobj->getParentObject() );
updateObject( metaobj->getParentObject(), objInfo.event );
}
// The fact we received an unpacked event does not mean that

View File

@ -84,10 +84,12 @@ private:
* Events generated by objects
*/
typedef enum {
EV_NONE = 0x00, /** No event */
EV_UNPACKED = 0x01, /** Object data updated by unpacking */
EV_UPDATED = 0x02, /** Object data updated by changing the data structure */
EV_UPDATED_MANUAL = 0x04, /** Object update event manually generated */
EV_UPDATE_REQ = 0x08 /** Request to update object data */
EV_UPDATED_PERIODIC = 0x8, /** Object update event generated by timer */
EV_UPDATE_REQ = 0x010 /** Request to update object data */
} EventMask;
typedef struct {
@ -132,7 +134,7 @@ private:
void addObject(UAVObject* obj);
void setUpdatePeriod(UAVObject* obj, qint32 periodMs);
void connectToObjectInstances(UAVObject* obj, quint32 eventMask);
void updateObject(UAVObject* obj);
void updateObject(UAVObject* obj, quint32 eventMask);
void processObjectUpdates(UAVObject* obj, EventMask event, bool allInstances, bool priority);
void processObjectTransaction();
void processObjectQueue();

View File

@ -77,25 +77,22 @@ void TelemetryMonitor::startRetrievingObjects()
UAVMetaObject* mobj = dynamic_cast<UAVMetaObject*>(obj);
UAVDataObject* dobj = dynamic_cast<UAVDataObject*>(obj);
UAVObject::Metadata mdata = obj->getMetadata();
if ( UAVObject::GetGcsTelemetryUpdateMode(mdata) != UAVObject::UPDATEMODE_NEVER )
if ( mobj != NULL )
{
if ( mobj != NULL )
queue.enqueue(obj);
}
else if ( dobj != NULL )
{
if ( dobj->isSettings() )
{
queue.enqueue(obj);
}
else if ( dobj != NULL )
else
{
if ( dobj->isSettings() )
if ( UAVObject::GetFlightTelemetryUpdateMode(mdata) == UAVObject::UPDATEMODE_ONCHANGE )
{
queue.enqueue(obj);
}
else
{
if ( UAVObject::GetFlightTelemetryUpdateMode(mdata) == UAVObject::UPDATEMODE_ONCHANGE )
{
queue.enqueue(obj);
}
}
}
}
}

View File

@ -4,7 +4,7 @@
<field name="Channel" units="us" type="uint16" elements="6"/>
<access gcs="readwrite" flight="readonly"/>
<telemetrygcs acked="false" updatemode="onchange" period="0"/>
<telemetryflight acked="false" updatemode="never" period="0"/>
<telemetryflight acked="false" updatemode="manual" period="0"/>
<logging updatemode="never" period="0"/>
</object>
</xml>