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:
parent
f4164d97bd
commit
19166cc830
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user