diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index f1fd085bff87d2552484aba7042afb60e152eb25..569daebb671d19db3f7b0f7eed0d556e6c366405 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -62,9 +62,10 @@ void QGCUASParamManager::setParamDescriptions(const QMap& param } -void QGCUASParamManager::setParameter(int component, QString parameterName, QVariant value) +void QGCUASParamManager::setParameter(int compId, QString paramName, QVariant value) { - paramCommsMgr->setParameter(component,parameterName,value); + //paramCommsMgr->setParameter(compId,paramName,value); + paramDataModel->updatePendingParamWithValue(compId,paramName,value); } void QGCUASParamManager::sendPendingParameters() @@ -74,7 +75,7 @@ void QGCUASParamManager::sendPendingParameters() void QGCUASParamManager::setPendingParam(int compId, QString& paramName, const QVariant& value) { - paramDataModel->setPendingParam(compId,paramName,value); + paramDataModel->updatePendingParamWithValue(compId,paramName,value); } diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 27ee774faff260d54d74173afd45460e33aabe9d..63ccac48398ee1c329ffe6682d056f2d4dd3cad5 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -27,7 +27,7 @@ UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent, UASInterface *uas) : mav, SLOT(requestParameter(int,int))); // Sending params to the UAS - connect(this, SIGNAL(parameterChanged(int,QString,QVariant)), + connect(this, SIGNAL(commitPendingParameter(int,QString,QVariant)), mav, SLOT(setParameter(int,QString,QVariant))); // Received parameter updates from UAS @@ -113,16 +113,16 @@ void UASParameterCommsMgr::clearRetransmissionLists(int& missingReadCount, int& } missingWriteCount = 0; - QList writeKeys = transmissionMissingWriteAckPackets.keys(); + QList writeKeys = missingWriteAckPackets.keys(); foreach (int compId, writeKeys) { - missingWriteCount += transmissionMissingWriteAckPackets.value(compId)->count(); - transmissionMissingWriteAckPackets.value(compId)->clear(); + missingWriteCount += missingWriteAckPackets.value(compId)->count(); + missingWriteAckPackets.value(compId)->clear(); } } -void UASParameterCommsMgr::emitParameterChanged(int compId, const QString& key, QVariant& value) +void UASParameterCommsMgr::emitPendingParameterCommit(int compId, const QString& key, QVariant& value) { int paramType = (int)value.type(); switch (paramType) @@ -130,25 +130,25 @@ void UASParameterCommsMgr::emitParameterChanged(int compId, const QString& key, case QVariant::Char: { QVariant fixedValue(QChar((unsigned char)value.toInt())); - emit parameterChanged(compId, key, fixedValue); + emit commitPendingParameter(compId, key, fixedValue); } break; case QVariant::Int: { QVariant fixedValue(value.toInt()); - emit parameterChanged(compId, key, fixedValue); + emit commitPendingParameter(compId, key, fixedValue); } break; case QVariant::UInt: { QVariant fixedValue(value.toUInt()); - emit parameterChanged(compId, key, fixedValue); + emit commitPendingParameter(compId, key, fixedValue); } break; case QMetaType::Float: { QVariant fixedValue(value.toFloat()); - emit parameterChanged(compId, key, fixedValue); + emit commitPendingParameter(compId, key, fixedValue); } break; default: @@ -190,14 +190,14 @@ void UASParameterCommsMgr::resendReadWriteRequests() // Re-request at maximum retransmissionBurstRequestSize parameters at once // to prevent write-request link flooding int requestedWriteCount = 0; - compIds = transmissionMissingWriteAckPackets.keys(); + compIds = missingWriteAckPackets.keys(); foreach (compId, compIds) { - QMap * missingParams = transmissionMissingWriteAckPackets.value(compId); + QMap * missingParams = missingWriteAckPackets.value(compId); foreach (QString key, missingParams->keys()) { if (requestedWriteCount < retransmissionBurstRequestSize) { // Re-request write operation QVariant value = missingParams->value(key); - emitParameterChanged(compId, key, value); + emitPendingParameterCommit(compId, key, value); requestedWriteCount++; } else { @@ -234,7 +234,7 @@ void UASParameterCommsMgr::retransmissionGuardTick() quint64 curTime = QGC::groundTimeMilliseconds(); //Workaround for an apparent Qt bug that causes retransmission guard timer to fire prematurely (350ms) - quint64 elapsed = (curTime - lastTimerReset); + int elapsed = (int)(curTime - lastTimerReset); if (elapsed < retransmissionTimeout) { qDebug() << "retransmissionGuardTick elapsed:" << (curTime - lastTimerReset); //reset the guard timer: it fired prematurely @@ -374,16 +374,16 @@ void UASParameterCommsMgr::setParameter(int component, QString parameterName, QV return; } - emitParameterChanged(component, parameterName, value); + emitPendingParameterCommit(component, parameterName, value); // Wait for parameter to be written back // mark it therefore as missing - if (!transmissionMissingWriteAckPackets.contains(component)) { - transmissionMissingWriteAckPackets.insert(component, new QMap()); + if (!missingWriteAckPackets.contains(component)) { + missingWriteAckPackets.insert(component, new QMap()); } // Insert it in missing write ACK list - transmissionMissingWriteAckPackets.value(component)->insert(parameterName, value); + missingWriteAckPackets.value(component)->insert(parameterName, value); // Set timeouts if (transmissionActive) { @@ -466,42 +466,42 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para bool writeMismatch = false; // Mark this parameter as received in write ACK list - QMap* map = transmissionMissingWriteAckPackets.value(compId); + QMap* map = missingWriteAckPackets.value(compId); if (map && map->contains(paramName)) { justWritten = true; - QVariant newval = map->value(paramName); if (map->value(paramName) != value) { writeMismatch = true; } map->remove(paramName); } - int missCount = 0; + int missReadCount = 0; foreach (int key, transmissionMissingPackets.keys()) { - missCount += transmissionMissingPackets.value(key)->count(); + missReadCount += transmissionMissingPackets.value(key)->count(); } int missWriteCount = 0; - foreach (int key, transmissionMissingWriteAckPackets.keys()) { - missWriteCount += transmissionMissingWriteAckPackets.value(key)->count(); + foreach (int key, missingWriteAckPackets.keys()) { + missWriteCount += missingWriteAckPackets.value(key)->count(); } //TODO simplify this if-else tree - if (justWritten && !writeMismatch && missWriteCount == 0) { - // Just wrote one and count went to 0 - this was the last missing write parameter - setParameterStatusMsg(tr("SUCCESS: WROTE ALL PARAMETERS")); - } - else if (justWritten && !writeMismatch) { - setParameterStatusMsg(tr("SUCCESS: Wrote %2 (#%1/%4): %3").arg(paramId+1).arg(paramName).arg(value.toDouble()).arg(paramCount)); - } - else if (justWritten && writeMismatch) { - // Mismatch, tell user - setParameterStatusMsg(tr("FAILURE: Wrote %1: sent %2 != onboard %3").arg(paramName).arg(map->value(paramName).toDouble()).arg(value.toDouble()), - ParamCommsStatusLevel_Warning); + if (justWritten) { + if (!writeMismatch) { + setParameterStatusMsg(tr("SUCCESS: Wrote %2 (#%1/%4): %3").arg(paramId+1).arg(paramName).arg(value.toDouble()).arg(paramCount)); + if (0 == missWriteCount) { + setParameterStatusMsg(tr("SUCCESS: WROTE ALL PARAMETERS")); + paramDataModel->commitAllPendingParams(); + } + } + else { + // Mismatch, tell user + setParameterStatusMsg(tr("FAILURE: Wrote %1: sent %2 != onboard %3").arg(paramName).arg(map->value(paramName).toDouble()).arg(value.toDouble()), + ParamCommsStatusLevel_Warning); + } } else { - QString val = QString("%1").arg(value.toFloat(), 5, 'f', 1, QChar(' ')); - if (missCount == 0) { + if (missReadCount == 0) { // Transmission done QTime time = QTime::currentTime(); QString timeString = time.toString(); @@ -509,13 +509,14 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para } else { // Transmission in progress - setParameterStatusMsg(tr("OK: %1 %2 (%3/%4)").arg(paramName).arg(val).arg(paramCount-missCount).arg(paramCount), + QString val = QString("%1").arg(value.toFloat(), 5, 'f', 1, QChar(' ')); + setParameterStatusMsg(tr("OK: %1 %2 (%3/%4)").arg(paramName).arg(val).arg(paramCount-missReadCount).arg(paramCount), ParamCommsStatusLevel_Warning); } } // Check if last parameter was received - if (missCount == 0 && missWriteCount == 0) { + if (missReadCount == 0 && missWriteCount == 0) { resetAfterListReceive(); setRetransmissionGuardEnabled(false); //all parameters have been received, broadcast to UI diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index 006d45d83fc8c17d3ce08e056ba850291f707364..d554e0021a0ee56c0beabf0b3edd9d4bf66b8e90 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -44,10 +44,10 @@ protected: void resendReadWriteRequests(); void resetAfterListReceive(); - void emitParameterChanged(int compId, const QString& key, QVariant& value); + void emitPendingParameterCommit(int compId, const QString& key, QVariant& value); signals: - void parameterChanged(int component, QString parameter, QVariant value); + void commitPendingParameter(int component, QString parameter, QVariant value); void parameterChanged(int component, int parameterIndex, QVariant value); void parameterValueConfirmed(int uas, int component,int paramCount, int paramId, QString parameter, QVariant value); @@ -93,7 +93,7 @@ protected: // Communications management QVector receivedParamsList; ///< Successfully received parameters QMap* > transmissionMissingPackets; ///< Missing packets - QMap* > transmissionMissingWriteAckPackets; ///< Missing write ACK packets + QMap* > missingWriteAckPackets; ///< Missing write ACK packets bool transmissionListMode; ///< Currently requesting list QMap transmissionListSizeKnown; ///< List size initialized? bool transmissionActive; ///< Missing packets, working on list? diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index 1806ec23fc59ace10749a22f287354238b73d20e..ab444d4962753f8f24e0aadc1f36b961619fdddb 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -18,9 +18,42 @@ UASParameterDataModel::UASParameterDataModel(QObject *parent) : +int UASParameterDataModel::countPendingParams() +{ + int totalPending = 0; + QMap*>::iterator i; + for (i = pendingParameters.begin(); i != pendingParameters.end(); ++i) { + // Iterate through the parameters of the component + QMap* paramList = i.value(); + totalPending += paramList->count(); + } + + return totalPending; +} + +void UASParameterDataModel::commitAllPendingParams() +{ + qDebug() << "commitAllPendingParams:" << countPendingParams(); + + QList allCompIds = pendingParameters.keys(); + foreach (int compId, allCompIds) { + // Iterate through the parameters of the component + QMap* compParams = pendingParameters.value(compId); + QList paramNames = compParams->keys(); + qDebug() << paramNames.count() << "committed params for component" << compId; + + foreach (QString paramName, paramNames) { + QVariant value = compParams->value(paramName); + setOnboardParamWithType( compId, paramName, value);//update the onboard value to match pending value + emit pendingParamUpdate(compId,paramName,value,false); //no longer pending + emit parameterUpdated(compId,paramName,value);//ensure the new onboard value is broadcast + } + + } +} -bool UASParameterDataModel::updatePendingParamWithValue(int compId, QString& key, QVariant& value) +bool UASParameterDataModel::updatePendingParamWithValue(int compId, QString& key, const QVariant& value) { bool pending = true; //ensure we have this component in our onboard and pending lists already @@ -44,27 +77,36 @@ bool UASParameterDataModel::updatePendingParamWithValue(int compId, QString& key return pending; } -void UASParameterDataModel::removePendingParam(int compId, QString& key) + +bool UASParameterDataModel::isParamChangePending(int compId, const QString& key) { - QMap *params = getPendingParamsForComponent(compId); - if (params) { - params->remove(key); - //broadcast the existing value - QVariant existVal; - bool ok = getOnboardParamValue(compId,key,existVal); - emit pendingParamUpdate(compId, key,existVal, false); - } + QMap* pendingParms = getPendingParamsForComponent(compId); + return ((NULL != pendingParms) && pendingParms->contains(key)); } - void UASParameterDataModel::setPendingParam(int compId, QString& key, const QVariant &value) { //ensure we have a placeholder map for this component addComponent(compId); - QMap *params = getPendingParamsForComponent(compId); - params->insert(key,value); - emit pendingParamUpdate(compId, key, value, true); + QMap *pendParams = getPendingParamsForComponent(compId); + if (pendParams) { + pendParams->insert(key,value); + emit pendingParamUpdate(compId, key, value, true); + } +} +void UASParameterDataModel::removePendingParam(int compId, QString& key) +{ + qDebug() << "removePendingParam:" << key; + + QMap *pendParams = getPendingParamsForComponent(compId); + if (pendParams) { + pendParams->remove(key); + //broadcast the existing value + QVariant existVal; + getOnboardParamValue(compId,key,existVal); + emit pendingParamUpdate(compId, key,existVal, false); + } } void UASParameterDataModel::setOnboardParam(int compId, QString& key, const QVariant& value) @@ -78,7 +120,6 @@ void UASParameterDataModel::setOnboardParam(int compId, QString& key, const QVa void UASParameterDataModel::setOnboardParamWithType(int compId, QString& key, QVariant& value) { -// switch ((int)onboardParameters.value(componentId)->value(key).type()) switch ((int)value.type()) { case QVariant::Int: @@ -209,13 +250,13 @@ void UASParameterDataModel::readUpdateParamsFromStream( QTextStream& stream) switch (paramType) { case MAV_PARAM_TYPE_REAL32: - setPendingParam(componentId,key,QVariant(valStr.toFloat())); + updatePendingParamWithValue(componentId,key,QVariant(valStr.toFloat())); break; case MAV_PARAM_TYPE_UINT32: - setPendingParam(componentId,key, QVariant(valStr.toUInt())); + updatePendingParamWithValue(componentId,key, QVariant(valStr.toUInt())); break; case MAV_PARAM_TYPE_INT32: - setPendingParam(componentId,key,QVariant(valStr.toInt())); + updatePendingParamWithValue(componentId,key,QVariant(valStr.toInt())); break; default: qDebug() << "FAILED LOADING PARAM" << key << "UNKNOWN DATA TYPE"; diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index fde760b703f28a4046aee7d070e5d5bc809f996a..f3da12f199e10c1e2366634e58596e169cb126f3 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -34,10 +34,9 @@ public: */ virtual void addComponent(int compId); - /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ - virtual void setPendingParam(int componentId, QString& key, const QVariant& value); virtual void removePendingParam(int compId, QString& key); + virtual void commitAllPendingParams();///< Called by eg params comms mgr when all pending params have been sent & acked /** @brief Save the onboard parameter with a the type specified in the QVariant as fixed */ virtual void setOnboardParamWithType(int componentId, QString& key, QVariant& value); @@ -49,10 +48,12 @@ public: /** @brief add this parameter to pending list iff it has changed from onboard value * @return true if the parameter is now pending */ - virtual bool updatePendingParamWithValue(int componentId, QString& key, QVariant& value); + virtual bool updatePendingParamWithValue(int componentId, QString& key, const QVariant &value); virtual void handleParamUpdate(int componentId, QString& key, QVariant& value); virtual bool getOnboardParamValue(int componentId, const QString& key, QVariant& value) const; + virtual bool isParamChangePending(int componentId,const QString& key); + QMap* getPendingParamsForComponent(int componentId) { return pendingParameters.value(componentId); } @@ -79,6 +80,10 @@ public: protected: virtual void setOnboardParam(int componentId, QString& key, const QVariant& value); + /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ + virtual void setPendingParam(int componentId, QString& key, const QVariant& value); + + int countPendingParams(); signals: @@ -88,6 +93,8 @@ signals: /** @brief Notifies listeners that a param was added to or removed from the pending list */ void pendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending); + void allPendingParamsCommitted(); ///< All pending params have been committed to the MAV + public slots: diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 1f4889603d14fc343ad8f6bd5dc4bd3605f209ad..571283d2d344f0164014f2d41a5cd1cc781a208b 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -206,10 +206,10 @@ void QGCParamWidget::addComponentItem(int compId, QString compName) void QGCParamWidget::handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending) { - qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock; + // qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock; if (updatingParamNameLock == paramName) { - qDebug() << "ignoring bounce from " << paramName; + //qDebug() << "ignoring bounce from " << paramName; return; } else { @@ -230,10 +230,15 @@ void QGCParamWidget::handlePendingParamUpdate(int compId, const QString& paramNa } -void QGCParamWidget::handleParameterUpdate(int componentId, const QString& paramName, QVariant value) +void QGCParamWidget::handleParameterUpdate(int compId, const QString& paramName, QVariant value) { +// qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock; + if (paramName == updatingParamNameLock) { + qDebug() << "handlePendingParamUpdate ignoring bounce from " << paramName; + return; + } updatingParamNameLock = paramName; - updateParameterDisplay(componentId, paramName, value); + updateParameterDisplay(compId, paramName, value); updatingParamNameLock.clear(); } @@ -402,10 +407,10 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column if (paramItem && column > 0) { QString key = paramItem->data(0, Qt::DisplayRole).toString(); - qDebug() << "parameterItemChanged:" << key << "with updatingParamNameLock:" << updatingParamNameLock; + //qDebug() << "parameterItemChanged:" << key << "with updatingParamNameLock:" << updatingParamNameLock; if (key == updatingParamNameLock) { - qDebug() << "ignoring parameterItemChanged" << key; + //qDebug() << "parameterItemChanged ignoring parameterItemChanged" << key; return; } else { diff --git a/src/ui/QGCPendingParamWidget.cc b/src/ui/QGCPendingParamWidget.cc index 800ca354e0cca9744f12a91e43b8e550ad9318fd..57ee57d5dba204f2967bceff05fa828ecce3209a 100644 --- a/src/ui/QGCPendingParamWidget.cc +++ b/src/ui/QGCPendingParamWidget.cc @@ -30,4 +30,33 @@ void QGCPendingParamWidget::connectSignalsAndSlots() this, SLOT(handleParamStatusMsgUpdate(QString , int ))); } +void QGCPendingParamWidget::handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending) +{ + // qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock; + + if (updatingParamNameLock == paramName) { + //qDebug() << "ignoring bounce from " << paramName; + return; + } + else { + updatingParamNameLock = paramName; + } + + QTreeWidgetItem* paramItem = updateParameterDisplay(compId,paramName,value); + + if (isPending) { + QTreeWidgetItem* paramItem = updateParameterDisplay(compId,paramName,value); + paramItem->setFlags(paramItem->flags() & ~Qt::ItemIsEditable); //disallow editing + paramItem->setBackground(0, QBrush(QColor(QGC::colorOrange))); + paramItem->setBackground(1, QBrush(QColor(QGC::colorOrange))); + tree->expandAll(); + } + else { + //we don't display non-pending items + paramItem->parent()->removeChild(paramItem); + } + + updatingParamNameLock.clear(); + +} diff --git a/src/ui/QGCPendingParamWidget.h b/src/ui/QGCPendingParamWidget.h index 91f08a522fd982ef675c77c784e5063349cbf6e2..4c6e7370c45419d3748f2747766848de0688f572 100644 --- a/src/ui/QGCPendingParamWidget.h +++ b/src/ui/QGCPendingParamWidget.h @@ -20,7 +20,8 @@ protected: signals: public slots: - + virtual void handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending); + }; #endif // QGCPENDINGPARAMWIDGET_H