void UAVObjectUtilManager::saveNextObject() { if (queue.isEmpty()) { return; } Q_ASSERT(saveState == IDLE); // Get next object from the queue UAVObject *obj = queue.head(); qDebug() << "Send save object request to board " << obj->getName(); ObjectPersistence *objper = dynamic_cast<ObjectPersistence *>(getObjectManager()->getObject(ObjectPersistence::NAME)); connect(objper, SIGNAL(transactionCompleted(UAVObject *, bool)), this, SLOT(objectPersistenceTransactionCompleted(UAVObject *, bool))); connect(objper, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(objectPersistenceUpdated(UAVObject *))); saveState = AWAITING_ACK; if (obj != NULL) { ObjectPersistence::DataFields data; data.Operation = ObjectPersistence::OPERATION_SAVE; data.Selection = ObjectPersistence::SELECTION_SINGLEOBJECT; data.ObjectID = obj->getObjID(); data.InstanceID = obj->getInstID(); objper->setData(data); objper->updated(); } // Now: we are going to get two "objectUpdated" messages (one coming from GCS, one coming from Flight, which // will confirm the object was properly received by both sides) and then one "transactionCompleted" indicating // that the Flight side did not only receive the object but it did receive it without error. Last we will get // a last "objectUpdated" message coming from flight side, where we'll get the results of the objectPersistence // operation we asked for (saved, other). }
void UAVObjectBrowserWidget::onTreeItemExpanded(QModelIndex currentProxyIndex) { QModelIndex currentIndex = proxyModel->mapToSource(currentProxyIndex); TreeItem *item = static_cast<TreeItem*>(currentIndex.internalPointer()); TopTreeItem *top = dynamic_cast<TopTreeItem*>(item->parent()); //Check if current tree index is the child of the top tree item if (top) { ObjectTreeItem *objItem = dynamic_cast<ObjectTreeItem*>(item); //If the cast succeeds, then this is a UAVO if (objItem) { UAVObject *obj = objItem->object(); // Check for multiple instance UAVO if(!obj){ objItem = dynamic_cast<ObjectTreeItem*>(item->getChild(0)); obj = objItem->object(); } Q_ASSERT(obj); UAVObject::Metadata mdata = obj->getMetadata(); // Determine fastest update quint16 tmpUpdatePeriod = MAXIMUM_UPDATE_PERIOD; int accessType = UAVObject::GetGcsTelemetryUpdateMode(mdata); if (accessType != UAVObject::UPDATEMODE_MANUAL){ switch(accessType){ case UAVObject::UPDATEMODE_ONCHANGE: tmpUpdatePeriod = 0; break; case UAVObject::UPDATEMODE_PERIODIC: case UAVObject::UPDATEMODE_THROTTLED: tmpUpdatePeriod = std::min(mdata.gcsTelemetryUpdatePeriod, tmpUpdatePeriod); break; } } accessType = UAVObject::GetFlightTelemetryUpdateMode(mdata); if (accessType != UAVObject::UPDATEMODE_MANUAL){ switch(accessType){ case UAVObject::UPDATEMODE_ONCHANGE: tmpUpdatePeriod = 0; break; case UAVObject::UPDATEMODE_PERIODIC: case UAVObject::UPDATEMODE_THROTTLED: tmpUpdatePeriod = std::min(mdata.flightTelemetryUpdatePeriod, tmpUpdatePeriod); break; } } expandedUavoItems.insert(obj->getName(), tmpUpdatePeriod); if (tmpUpdatePeriod < updatePeriod){ updatePeriod = tmpUpdatePeriod; treeView->updateTimerPeriod(updatePeriod); } } } }
void UAVObjectBrowserWidget::onTreeItemCollapsed(QModelIndex currentProxyIndex) { QModelIndex currentIndex = proxyModel->mapToSource(currentProxyIndex); TreeItem *item = static_cast<TreeItem*>(currentIndex.internalPointer()); TopTreeItem *top = dynamic_cast<TopTreeItem*>(item->parent()); //Check if current tree index is the child of the top tree item if (top) { ObjectTreeItem *objItem = dynamic_cast<ObjectTreeItem*>(item); //If the cast succeeds, then this is a UAVO if (objItem) { UAVObject *obj = objItem->object(); // Check for multiple instance UAVO if(!obj){ objItem = dynamic_cast<ObjectTreeItem*>(item->getChild(0)); obj = objItem->object(); } Q_ASSERT(obj); //Remove the UAVO, getting its stored value first. quint16 tmpUpdatePeriod = expandedUavoItems.value(obj->getName()); expandedUavoItems.take(obj->getName()); // Check if this was the fastest UAVO if (tmpUpdatePeriod == updatePeriod){ // If so, search for the new fastest UAVO updatePeriod = MAXIMUM_UPDATE_PERIOD; foreach(tmpUpdatePeriod, expandedUavoItems) { if (tmpUpdatePeriod < updatePeriod) updatePeriod = tmpUpdatePeriod; } treeView->updateTimerPeriod(updatePeriod); } } }
/** * @brief UAVObjectUtilManager::saveNextObject * * Processes the save queue. */ void UAVObjectUtilManager::saveNextObject() { if ( queue.isEmpty() ) { return; } Q_ASSERT(saveState == IDLE); // Get next object from the queue (don't dequeue yet) UAVObject* obj = queue.head(); Q_ASSERT(obj); qDebug() << "Send save object request to board " << obj->getName(); ObjectPersistence * objectPersistence = ObjectPersistence::GetInstance(getObjectManager()); Q_ASSERT(objectPersistence); // "transactionCompleted" is emitted once the objectPersistence object is sent over the telemetry link. // Since its metadata state that it should be ACK'ed on flight telemetry, the transactionCompleted signal // will be triggered once the GCS telemetry manager receives an ACK from the flight controller, or times // out. the success value will reflect success or failure. connect(objectPersistence, SIGNAL(transactionCompleted(UAVObject*,bool)), this, SLOT(objectPersistenceTransactionCompleted(UAVObject*,bool))); // After we update the objectPersistence UAVO, we need to listen to its "objectUpdated" event, which will occur // once the flight controller sends this object back to the GCS, with the "Operation" field set to "Completed" // or "Error". connect(objectPersistence, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(objectPersistenceUpdated(UAVObject *))); saveState = AWAITING_ACK; qDebug() << "[saveObjectToFlash] Moving on to AWAITING_ACK"; ObjectPersistence::DataFields data; data.Operation = ObjectPersistence::OPERATION_SAVE; data.Selection = ObjectPersistence::SELECTION_SINGLEOBJECT; data.ObjectID = obj->getObjID(); data.InstanceID = obj->getInstID(); objectPersistence->setData(data); objectPersistence->updated(); // Now: we are going to get the following: // - two "objectUpdated" messages (one coming from GCS, one coming from Flight, which will confirm the object // was properly received by both sides). This is because the metadata of objectPersistence has "FlightUpdateOnChange" // set to true. // - then one "transactionCompleted" indicating that the Flight side did not only receive the object but it did // receive it without error (that message will be triggered by reception of the ACK). // - Last we will get one last "objectUpdated" message coming from flight side, where we'll get the results of // the objectPersistence operation we asked for (saved, other). }
foreach (QString objStr, strList) { // Add defaults UAVObject *obj = objManager->getObject(objStr); Q_ASSERT(obj); UAVObject::Metadata mdataDefault = obj->getDefaultMetadata(); QModelIndex index = schedulerModel->index(rowIndex,0, QModelIndex()); schedulerModel->setData(index, QString("%1ms").arg(mdataDefault.flightTelemetryUpdatePeriod)); // Save default metadata for later use defaultMdata.insert(obj->getName().append("Meta"), mdataDefault); // Connect live values to the "Current" column UAVDataObject *dobj = dynamic_cast<UAVDataObject*>(obj); Q_ASSERT(dobj); UAVMetaObject *mobj = dobj->getMetaObject(); connect(mobj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(updateCurrentColumn(UAVObject*))); // Updates the "Current" column with the live value updateCurrentColumn(mobj); rowIndex++; }