From 2eac0e2e58780faea8fcff1c945ef930d60a8ba4 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 08:45:59 -0700 Subject: [PATCH] Refactoring comms code --- src/uas/QGCUASParamManager.cc | 154 ++++++++++++++++ src/uas/QGCUASParamManager.h | 16 +- src/ui/QGCParamWidget.cc | 324 +++++++++++----------------------- src/ui/QGCParamWidget.h | 16 +- 4 files changed, 278 insertions(+), 232 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index ee42aa968..2bbe1fb61 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -28,3 +28,157 @@ bool QGCUASParamManager::getParameterValue(int component, const QString& paramet return paramDataModel->getOnboardParameterValue(component,parameter,value); } + + + + +/** + * Send a request to deliver the list of onboard parameters + * to the MAV. + */ +void QGCUASParamManager::requestParameterList() +{ + if (!mav) { + return; + } + + paramDataModel->forgetAllOnboardParameters(); + received.clear(); + // Clear transmission state + transmissionListMode = true; + transmissionListSizeKnown.clear(); + foreach (int key, transmissionMissingPackets.keys()) + { + transmissionMissingPackets.value(key)->clear(); + } + transmissionActive = true; + + setParameterStatusMsg(tr("Requested param list.. waiting")); + mav->requestParameters(); + +} + + +/** + * Enabling the retransmission guard enables the parameter widget to track + * dropped parameters and to re-request them. This works for both individual + * parameter reads as well for whole list requests. + * + * @param enabled True if retransmission checking should be enabled, false else + */ +void QGCUASParamManager::setRetransmissionGuardEnabled(bool enabled) +{ + if (enabled) { + retransmissionTimer.start(retransmissionTimeout); + } else { + retransmissionTimer.stop(); + } +} + +void QGCUASParamManager::setParameterStatusMsg(const QString& msg) +{ + parameterStatusMsg = msg; +} + +void QGCUASParamManager::retransmissionGuardTick() +{ + if (transmissionActive) { + //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; + + // Check for timeout + // stop retransmission attempts on timeout + if (QGC::groundTimeMilliseconds() > transmissionTimeout) { + setRetransmissionGuardEnabled(false); + transmissionActive = false; + + // Empty read retransmission list + // Empty write retransmission list + int missingReadCount = 0; + QList readKeys = transmissionMissingPackets.keys(); + foreach (int component, readKeys) { + missingReadCount += transmissionMissingPackets.value(component)->count(); + transmissionMissingPackets.value(component)->clear(); + } + + // Empty write retransmission list + int missingWriteCount = 0; + QList writeKeys = transmissionMissingWriteAckPackets.keys(); + foreach (int component, writeKeys) { + missingWriteCount += transmissionMissingWriteAckPackets.value(component)->count(); + transmissionMissingWriteAckPackets.value(component)->clear(); + } + setParameterStatusMsg(tr("TIMEOUT! MISSING: %1 read, %2 write.").arg(missingReadCount).arg(missingWriteCount)); + } + + // Re-request at maximum retransmissionBurstRequestSize parameters at once + // to prevent link flooding + QMap*>::iterator i; + QMap*> onboardParams = paramDataModel->getOnboardParameters(); + for (i = onboardParams.begin(); i != onboardParams.end(); ++i) { + // Iterate through the parameters of the component + int component = i.key(); + // Request n parameters from this component (at maximum) + QList * paramList = transmissionMissingPackets.value(component, NULL); + if (paramList) { + int count = 0; + foreach (int id, *paramList) { + if (count < retransmissionBurstRequestSize) { + //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << id << "FROM COMPONENT #" << component; + //TODO mavlink msg type for "request parameter set" ? + emit requestParameter(component, id); + setParameterStatusMsg(tr("Requested retransmission of #%1").arg(id+1)); + count++; + } else { + break; + } + } + } + } + + // Re-request at maximum retransmissionBurstRequestSize parameters at once + // to prevent write-request link flooding + // Empty write retransmission list + QList writeKeys = transmissionMissingWriteAckPackets.keys(); + foreach (int component, writeKeys) { + int count = 0; + QMap * missingParams = transmissionMissingWriteAckPackets.value(component); + foreach (QString key, missingParams->keys()) { + if (count < retransmissionBurstRequestSize) { + // Re-request write operation + QVariant value = missingParams->value(key); + switch ((int)onboardParams.value(component)->value(key).type()) + { + case QVariant::Int: + { + QVariant fixedValue(value.toInt()); + emit parameterChanged(component, key, fixedValue); + } + break; + case QVariant::UInt: + { + QVariant fixedValue(value.toUInt()); + emit parameterChanged(component, key, fixedValue); + } + break; + case QMetaType::Float: + { + QVariant fixedValue(value.toFloat()); + emit parameterChanged(component, key, fixedValue); + } + break; + default: + //qCritical() << "ABORTED PARAM RETRANSMISSION, NO VALID QVARIANT TYPE"; + return; + } + setParameterStatusMsg(tr("Requested rewrite of: %1: %2").arg(key).arg(missingParams->value(key).toDouble())); + count++; + } else { + break; + } + } + } + } else { + //qDebug() << __FILE__ << __LINE__ << "STOPPING RETRANSMISSION GUARD GRACEFULLY"; + setRetransmissionGuardEnabled(false); + } +} diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 7f970ef6d..c6351a6c3 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -31,16 +31,29 @@ public: /** @brief Request an update for this specific parameter */ virtual void requestParameterUpdate(int component, const QString& parameter) = 0; +protected: + /** @brief Check for missing parameters */ + virtual void retransmissionGuardTick(); + /** @brief Activate / deactivate parameter retransmission */ + virtual void setRetransmissionGuardEnabled(bool enabled); + + //TODO decouple this UI message display further + virtual void setParameterStatusMsg(const QString& msg); + signals: void parameterChanged(int component, QString parameter, QVariant value); void parameterChanged(int component, int parameterIndex, QVariant value); void parameterListUpToDate(int component); + /** @brief Request a single parameter */ + void requestParameter(int component, int parameter); + /** @brief Request a single parameter by name */ + void requestParameter(int component, const QString& parameter); public slots: /** @brief Write one parameter to the MAV */ virtual void setParameter(int component, QString parameterName, QVariant value) = 0; /** @brief Request list of parameters from MAV */ - virtual void requestParameterList() = 0; + virtual void requestParameterList(); protected: @@ -60,6 +73,7 @@ protected: int retransmissionTimeout; ///< Retransmission request timeout, in milliseconds int rewriteTimeout; ///< Write request timeout, in milliseconds int retransmissionBurstRequestSize; ///< Number of packets requested for retransmission per burst + QString parameterStatusMsg; }; diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 95b58eadd..40fc49195 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -87,7 +87,7 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : QPushButton* refreshButton = new QPushButton(tr("Get")); refreshButton->setToolTip(tr("Load parameters currently in non-permanent memory of aircraft.")); refreshButton->setWhatsThis(tr("Load parameters currently in non-permanent memory of aircraft.")); - connect(refreshButton, SIGNAL(clicked()), this, SLOT(requestParameterList())); + connect(refreshButton, SIGNAL(clicked()), this, SLOT(requestParameterListUpdate())); horizontalLayout->addWidget(refreshButton, 2, 0); QPushButton* setButton = new QPushButton(tr("Set")); @@ -150,9 +150,12 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : connect(&retransmissionTimer, SIGNAL(timeout()), this, SLOT(retransmissionGuardTick())); // Get parameters - if (uas) requestParameterList(); + if (uas) { + requestParameterListUpdate(); + } } + void QGCParamWidget::loadSettings() { QSettings settings; @@ -642,38 +645,7 @@ void QGCParamWidget::receivedParameterUpdate(int uas, int component, QString par } -/** - * Send a request to deliver the list of onboard parameters - * to the MAV. - */ -void QGCParamWidget::requestParameterList() -{ - if (!mav) return; - // FIXME This call does not belong here - // Once the comm handling is moved to a new - // Param manager class the settings can be directly - // loaded from MAVLink protocol - loadSettings(); - // End of FIXME - - // Clear view and request param list - clear(); - paramDataModel->forgetAllOnboardParameters(); - received.clear(); - // Clear transmission state - transmissionListMode = true; - transmissionListSizeKnown.clear(); - foreach (int key, transmissionMissingPackets.keys()) - { - transmissionMissingPackets.value(key)->clear(); - } - transmissionActive = true; - - // Set status text - statusLabel->setText(tr("Requested param list.. waiting")); - mav->requestParameters(); -} void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) { @@ -740,133 +712,122 @@ void QGCParamWidget::loadParametersFromFile() } -/** - * Enabling the retransmission guard enables the parameter widget to track - * dropped parameters and to re-request them. This works for both individual - * parameter reads as well for whole list requests. - * - * @param enabled True if retransmission checking should be enabled, false else - */ -void QGCParamWidget::setRetransmissionGuardEnabled(bool enabled) +void QGCParamWidget::setParameterStatusMsg(const QString& msg) { - if (enabled) { - retransmissionTimer.start(retransmissionTimeout); - } else { - retransmissionTimer.stop(); + statusLabel->setText(msg); +} + + + +void QGCParamWidget::requestParameterListUpdate() +{ + if (!mav) { + return; } + + // FIXME This call does not belong here + // Once the comm handling is moved to a new + // Param manager class the settings can be directly + // loaded from MAVLink protocol + loadSettings(); + // End of FIXME + + // Clear view and request param list + clear(); + + requestParameterList(); } -void QGCParamWidget::retransmissionGuardTick() +/** + * The .. signal is emitted + */ +void QGCParamWidget::requestParameterUpdate(int component, const QString& parameter) { - if (transmissionActive) { - //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; - - // Check for timeout - // stop retransmission attempts on timeout - if (QGC::groundTimeMilliseconds() > transmissionTimeout) { - setRetransmissionGuardEnabled(false); - transmissionActive = false; - - // Empty read retransmission list - // Empty write retransmission list - int missingReadCount = 0; - QList readKeys = transmissionMissingPackets.keys(); - foreach (int component, readKeys) { - missingReadCount += transmissionMissingPackets.value(component)->count(); - transmissionMissingPackets.value(component)->clear(); - } + if (mav) mav->requestParameter(component, parameter); +} - // Empty write retransmission list - int missingWriteCount = 0; - QList writeKeys = transmissionMissingWriteAckPackets.keys(); - foreach (int component, writeKeys) { - missingWriteCount += transmissionMissingWriteAckPackets.value(component)->count(); - transmissionMissingWriteAckPackets.value(component)->clear(); - } - statusLabel->setText(tr("TIMEOUT! MISSING: %1 read, %2 write.").arg(missingReadCount).arg(missingWriteCount)); - } - // Re-request at maximum retransmissionBurstRequestSize parameters at once - // to prevent link flooding - QMap*>::iterator i; - QMap*> onboardParams = paramDataModel->getOnboardParameters(); - for (i = onboardParams.begin(); i != onboardParams.end(); ++i) { - // Iterate through the parameters of the component - int component = i.key(); - // Request n parameters from this component (at maximum) - QList * paramList = transmissionMissingPackets.value(component, NULL); - if (paramList) { - int count = 0; - foreach (int id, *paramList) { - if (count < retransmissionBurstRequestSize) { - //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << id << "FROM COMPONENT #" << component; - emit requestParameter(component, id); - statusLabel->setText(tr("Requested retransmission of #%1").arg(id+1)); - count++; - } else { - break; - } - } + +/** + * Set all parameter in the parameter tree on the MAV + */ +void QGCParamWidget::setParameters() +{ + // Iterate through all components, through all parameters and emit them + int parametersSent = 0; + QMap*> changedValues = paramDataModel->getPendingParameters(); + QMap*>::iterator i; + for (i = changedValues.begin(); i != changedValues.end(); ++i) { + // Iterate through the parameters of the component + int compid = i.key(); + QMap* comp = i.value(); + { + QMap::iterator j; + for (j = comp->begin(); j != comp->end(); ++j) { + setParameter(compid, j.key(), j.value()); + parametersSent++; } } + } - // Re-request at maximum retransmissionBurstRequestSize parameters at once - // to prevent write-request link flooding - // Empty write retransmission list - QList writeKeys = transmissionMissingWriteAckPackets.keys(); - foreach (int component, writeKeys) { - int count = 0; - QMap * missingParams = transmissionMissingWriteAckPackets.value(component); - foreach (QString key, missingParams->keys()) { - if (count < retransmissionBurstRequestSize) { - // Re-request write operation - QVariant value = missingParams->value(key); - switch ((int)onboardParams.value(component)->value(key).type()) - { - case QVariant::Int: - { - QVariant fixedValue(value.toInt()); - emit parameterChanged(component, key, fixedValue); - } - break; - case QVariant::UInt: - { - QVariant fixedValue(value.toUInt()); - emit parameterChanged(component, key, fixedValue); - } - break; - case QMetaType::Float: - { - QVariant fixedValue(value.toFloat()); - emit parameterChanged(component, key, fixedValue); - } - break; - default: - //qCritical() << "ABORTED PARAM RETRANSMISSION, NO VALID QVARIANT TYPE"; - return; - } - statusLabel->setText(tr("Requested rewrite of: %1: %2").arg(key).arg(missingParams->value(key).toDouble())); - count++; - } else { - break; - } + // Change transmission status if necessary + if (parametersSent == 0) { + statusLabel->setText(tr("No transmission: No changed values.")); + } else { + statusLabel->setText(tr("Transmitting %1 parameters.").arg(parametersSent)); + // Set timeouts + if (transmissionActive) + { + transmissionTimeout += parametersSent*rewriteTimeout; + } + else + { + transmissionActive = true; + quint64 newTransmissionTimeout = QGC::groundTimeMilliseconds() + parametersSent*rewriteTimeout; + if (newTransmissionTimeout > transmissionTimeout) { + transmissionTimeout = newTransmissionTimeout; } } - } else { - //qDebug() << __FILE__ << __LINE__ << "STOPPING RETRANSMISSION GUARD GRACEFULLY"; - setRetransmissionGuardEnabled(false); + // Enable guard + setRetransmissionGuardEnabled(true); } } - /** - * The .. signal is emitted + * Write the current onboard parameters from RAM into + * permanent storage, e.g. EEPROM or harddisk */ -void QGCParamWidget::requestParameterUpdate(int component, const QString& parameter) +void QGCParamWidget::writeParameters() { - if (mav) mav->requestParameter(component, parameter); -} + int changedParamCount = 0; + + QMap*>::iterator i; + QMap*> changedValues = paramDataModel->getPendingParameters(); + + for (i = changedValues.begin(); i != changedValues.end() , (0 == changedParamCount); ++i) + { + // Iterate through the parameters of the component + QMap* comp = i.value(); + QMap::iterator j; + for (j = comp->begin(); j != comp->end(); ++j) + { + changedParamCount++; + break;//it only takes one changed param to warrant warning the user + } + } + if (changedParamCount > 0) + { + QMessageBox msgBox; + msgBox.setText(tr("There are locally changed parameters. Please transmit them first () or update them with the onboard values () before storing onboard from RAM to ROM.")); + msgBox.exec(); + } + else + { + if (!mav) return; + mav->writeParametersToStorage(); + } +} /** * @param component the subsystem which has the parameter @@ -959,87 +920,6 @@ void QGCParamWidget::setParameter(int component, QString parameterName, QVariant setRetransmissionGuardEnabled(true); } -/** - * Set all parameter in the parameter tree on the MAV - */ -void QGCParamWidget::setParameters() -{ - // Iterate through all components, through all parameters and emit them - int parametersSent = 0; - QMap*> changedValues = paramDataModel->getPendingParameters(); - QMap*>::iterator i; - for (i = changedValues.begin(); i != changedValues.end(); ++i) { - // Iterate through the parameters of the component - int compid = i.key(); - QMap* comp = i.value(); - { - QMap::iterator j; - for (j = comp->begin(); j != comp->end(); ++j) { - setParameter(compid, j.key(), j.value()); - parametersSent++; - } - } - } - - // Change transmission status if necessary - if (parametersSent == 0) { - statusLabel->setText(tr("No transmission: No changed values.")); - } else { - statusLabel->setText(tr("Transmitting %1 parameters.").arg(parametersSent)); - // Set timeouts - if (transmissionActive) - { - transmissionTimeout += parametersSent*rewriteTimeout; - } - else - { - transmissionActive = true; - quint64 newTransmissionTimeout = QGC::groundTimeMilliseconds() + parametersSent*rewriteTimeout; - if (newTransmissionTimeout > transmissionTimeout) { - transmissionTimeout = newTransmissionTimeout; - } - } - // Enable guard - setRetransmissionGuardEnabled(true); - } -} - -/** - * Write the current onboard parameters from RAM into - * permanent storage, e.g. EEPROM or harddisk - */ -void QGCParamWidget::writeParameters() -{ - int changedParamCount = 0; - - QMap*>::iterator i; - QMap*> changedValues = paramDataModel->getPendingParameters(); - - for (i = changedValues.begin(); i != changedValues.end() , (0 == changedParamCount); ++i) - { - // Iterate through the parameters of the component - QMap* comp = i.value(); - QMap::iterator j; - for (j = comp->begin(); j != comp->end(); ++j) - { - changedParamCount++; - break;//it only takes one changed param to warrant warning the user - } - } - - if (changedParamCount > 0) - { - QMessageBox msgBox; - msgBox.setText(tr("There are locally changed parameters. Please transmit them first () or update them with the onboard values () before storing onboard from RAM to ROM.")); - msgBox.exec(); - } - else - { - if (!mav) return; - mav->writeParametersToStorage(); - } -} - void QGCParamWidget::readParameters() { if (!mav) return; diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 0b810bc5b..c49f5a55c 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -60,13 +60,13 @@ public: QString getParamInfo(const QString& param) { return paramToolTips.value(param, ""); } void setParamInfo(const QMap& paramInfo); +protected: + virtual void setParameterStatusMsg(const QString& msg); + signals: /** @brief A parameter was changed in the widget, NOT onboard */ //void parameterChanged(int component, QString parametername, float value); // defined in QGCUASParamManager already - /** @brief Request a single parameter */ - void requestParameter(int component, int parameter); - /** @brief Request a single parameter by name */ - void requestParameter(int component, const QString& parameter); + public slots: /** @brief Add a component to the list */ void addComponent(int uas, int component, QString componentName); @@ -75,7 +75,7 @@ public slots: /** @brief Add a parameter to the list */ void receivedParameterUpdate(int uas, int component, QString parameterName, QVariant value); /** @brief Request list of parameters from MAV */ - void requestParameterList(); + void requestParameterListUpdate(); /** @brief Request one single parameter */ void requestParameterUpdate(int component, const QString& parameter); /** @brief Set one parameter, changes value in RAM of MAV */ @@ -96,8 +96,7 @@ public slots: /** @brief Load parameters from a file */ void loadParametersFromFile(); - /** @brief Check for missing parameters */ - void retransmissionGuardTick(); + protected: QTreeWidget* tree; ///< The parameter tree @@ -112,8 +111,7 @@ protected: QMap paramDefault; ///< Default param values QMap paramMax; ///< Minimum param values - /** @brief Activate / deactivate parameter retransmission */ - void setRetransmissionGuardEnabled(bool enabled); + /** @brief Load settings */ void loadSettings(); /** @brief Load meta information from CSV */ -- 2.22.0