From d9bbe9bd67388fca088d2a77f7c60f4d06f8a0c6 Mon Sep 17 00:00:00 2001 From: DonLakeFlyer Date: Sat, 9 Nov 2019 21:28:55 -0800 Subject: [PATCH] Separate progress bar handling for initial load, write and read batching --- src/FactSystem/ParameterManager.cc | 128 +++++++++++++++++++++++------ src/FactSystem/ParameterManager.h | 25 ++++-- 2 files changed, 123 insertions(+), 30 deletions(-) diff --git a/src/FactSystem/ParameterManager.cc b/src/FactSystem/ParameterManager.cc index 322d87e00..55fb1a35b 100644 --- a/src/FactSystem/ParameterManager.cc +++ b/src/FactSystem/ParameterManager.cc @@ -94,6 +94,63 @@ ParameterManager::~ParameterManager() delete _parameterMetaData; } +void ParameterManager::_updateProgressBar(void) +{ + int waitingReadParamIndexCount = 0; + int waitingReadParamNameCount = 0; + int waitingWriteParamCount = 0; + + for (int compId: _waitingReadParamIndexMap.keys()) { + waitingReadParamIndexCount += _waitingReadParamIndexMap[compId].count(); + } + for(int compId: _waitingReadParamNameMap.keys()) { + waitingReadParamNameCount += _waitingReadParamNameMap[compId].count(); + } + for(int compId: _waitingWriteParamNameMap.keys()) { + waitingWriteParamCount += _waitingWriteParamNameMap[compId].count(); + } + + if (waitingReadParamIndexCount == 0) { + if (_readParamIndexProgressActive) { + _readParamIndexProgressActive = false; + _setLoadProgress(0.0); + return; + } + } else { + _readParamIndexProgressActive = true; + _setLoadProgress((double)(_totalParamCount - waitingReadParamIndexCount) / (double)_totalParamCount); + return; + } + + if (waitingWriteParamCount == 0) { + if (_writeParamProgressActive) { + _writeParamProgressActive = false; + _waitingWriteParamBatchCount = 0; + _setLoadProgress(0.0); + emit pendingWritesChanged(false); + return; + } + } else { + _writeParamProgressActive = true; + _setLoadProgress((double)(qMax(_waitingWriteParamBatchCount - waitingWriteParamCount, 1)) / (double)(_waitingWriteParamBatchCount + 1)); + emit pendingWritesChanged(true); + return; + } + + if (waitingReadParamNameCount == 0) { + if (_readParamNameProgressActive) { + _readParamNameProgressActive = false; + _waitingReadParamNameBatchCount = 0; + _setLoadProgress(0.0); + return; + } + } else { + _readParamNameProgressActive = true; + _setLoadProgress((double)(qMax(_waitingReadParamNameBatchCount - waitingReadParamNameCount, 1)) / (double)(_waitingReadParamNameBatchCount + 1)); + return; + } +} + /// Called whenever a parameter is updated or first seen. void ParameterManager::_parameterUpdate(int vehicleId, int componentId, QString parameterName, int parameterCount, int parameterId, int mavType, QVariant value) { @@ -262,17 +319,8 @@ void ParameterManager::_parameterUpdate(int vehicleId, int componentId, QString qCDebug(ParameterManagerVerbose1Log) << _logVehiclePrefix(-1) << "Not restarting _waitingParamTimeoutTimer (all requests satisfied)"; } } - - // Update progress bar for waiting reads - if (readWaitingParamCount == 0) { - // We are no longer waiting for any reads to complete - if (_prevWaitingReadParamIndexCount + _prevWaitingReadParamNameCount != 0) { - // Set progress to 0 if not already there - _setLoadProgress(0.0); - } - } else { - _setLoadProgress((double)(_totalParamCount - readWaitingParamCount) / (double)_totalParamCount); - } +\ + _updateProgressBar(); // Get parameter set version if (!_versionParam.isEmpty() && _versionParam == parameterName) { @@ -389,8 +437,13 @@ void ParameterManager::_valueUpdated(const QVariant& value) _dataMutex.lock(); if (_waitingWriteParamNameMap.contains(componentId)) { - _waitingWriteParamNameMap[componentId].remove(name); // Remove any old entry - _waitingWriteParamNameMap[componentId][name] = 0; // Add new entry and set retry count + if (_waitingWriteParamNameMap[componentId].contains(name)) { + _waitingWriteParamNameMap[componentId].remove(name); + } else { + _waitingWriteParamBatchCount++; + } + _waitingWriteParamNameMap[componentId][name] = 0; // Add new entry and set retry count + _updateProgressBar(); _waitingParamTimeoutTimer.start(); _saveRequired = true; } else { @@ -466,8 +519,13 @@ void ParameterManager::refreshParameter(int componentId, const QString& name) if (_waitingReadParamNameMap.contains(componentId)) { QString mappedParamName = _remapParamNameToVersion(name); - _waitingReadParamNameMap[componentId].remove(mappedParamName); // Remove old wait entry if there + if (_waitingReadParamNameMap[componentId].contains(mappedParamName)) { + _waitingReadParamNameMap[componentId].remove(mappedParamName); + } else { + _waitingReadParamNameBatchCount++; + } _waitingReadParamNameMap[componentId][mappedParamName] = 0; // Add new wait entry and update retry count + _updateProgressBar(); qCDebug(ParameterManagerLog) << _logVehiclePrefix(componentId) << "restarting _waitingParamTimeout"; _waitingParamTimeoutTimer.start(); } else { @@ -896,7 +954,8 @@ void ParameterManager::_tryCacheHashLoad(int vehicleId, int componentId, QVarian QString ParameterManager::readParametersFromStream(QTextStream& stream) { - QString errors; + QString missingErrors; + QString typeErrors; while (!stream.atEnd()) { QString line = stream.readLine(); @@ -915,18 +974,18 @@ QString ParameterManager::readParametersFromStream(QTextStream& stream) if (!parameterExists(componentId, paramName)) { QString error; - error = QString("Skipped parameter %1:%2 - does not exist on this vehicle\n").arg(componentId).arg(paramName); - errors += error; - qCDebug(ParameterManagerLog) << error; + error += QStringLiteral("%1:%2 ").arg(componentId).arg(paramName); + missingErrors += error; + qCDebug(ParameterManagerLog) << QStringLiteral("Skipped due to missing: %1").arg(error); continue; } Fact* fact = getParameter(componentId, paramName); if (fact->type() != _mavTypeToFactType((MAV_PARAM_TYPE)mavType)) { QString error; - error = QString("Skipped parameter %1:%2 - type mismatch %3:%4\n").arg(componentId).arg(paramName).arg(fact->type()).arg(_mavTypeToFactType((MAV_PARAM_TYPE)mavType)); - errors += error; - qCDebug(ParameterManagerLog) << error; + error = QStringLiteral("%1:%2 ").arg(componentId).arg(paramName); + typeErrors += error; + qCDebug(ParameterManagerLog) << QStringLiteral("Skipped due to type mismatch: %1").arg(error); continue; } @@ -936,6 +995,16 @@ QString ParameterManager::readParametersFromStream(QTextStream& stream) } } + QString errors; + + if (!missingErrors.isEmpty()) { + errors = tr("Parameters not loaded since they are not currently on the vehicle: %1\n").arg(missingErrors); + } + + if (!typeErrors.isEmpty()) { + errors += tr("Parameters not loaded due to type mismatch: %1").arg(typeErrors); + } + return errors; } @@ -1579,11 +1648,24 @@ QString ParameterManager::_logVehiclePrefix(int componentId) void ParameterManager::_setLoadProgress(double loadProgress) { - _loadProgress = loadProgress; - emit loadProgressChanged(static_cast(loadProgress)); + if (_loadProgress != loadProgress) { + _loadProgress = loadProgress; + emit loadProgressChanged(static_cast(loadProgress)); + } } QList ParameterManager::componentIds(void) { return _paramCountMap.keys(); } + +bool ParameterManager::pendingWrites(void) +{ + for (int compId: _waitingWriteParamNameMap.keys()) { + if (_waitingWriteParamNameMap[compId].count()) { + return true; + } + } + + return false; +} diff --git a/src/FactSystem/ParameterManager.h b/src/FactSystem/ParameterManager.h index 9527b9612..be1ae4cb0 100644 --- a/src/FactSystem/ParameterManager.h +++ b/src/FactSystem/ParameterManager.h @@ -39,6 +39,7 @@ public: Q_PROPERTY(bool parametersReady READ parametersReady NOTIFY parametersReadyChanged) ///< true: Parameters are ready for use Q_PROPERTY(bool missingParameters READ missingParameters NOTIFY missingParametersChanged) ///< true: Parameters are missing from firmware response, false: all parameters received from firmware Q_PROPERTY(double loadProgress READ loadProgress NOTIFY loadProgressChanged) + Q_PROPERTY(bool pendingWrites READ pendingWrites NOTIFY pendingWritesChanged) ///< true: There are still pending write updates against the vehicle bool parametersReady (void) const { return _parametersReady; } bool missingParameters (void) const { return _missingParameters; } @@ -111,12 +112,15 @@ public: /// @return true: success, false: failure (errorString set) bool loadFromJson(const QJsonObject& json, bool required, QString& errorString); + bool pendingWrites(void); + Vehicle* vehicle(void) { return _vehicle; } signals: - void parametersReadyChanged(bool parametersReady); - void missingParametersChanged(bool missingParameters); - void loadProgressChanged(float value); + void parametersReadyChanged (bool parametersReady); + void missingParametersChanged (bool missingParameters); + void loadProgressChanged (float value); + void pendingWritesChanged (bool pendingWrites); protected: Vehicle* _vehicle; @@ -146,6 +150,7 @@ private: QString _logVehiclePrefix(int componentId); void _setLoadProgress(double loadProgress); bool _fillIndexBatchQueue(bool waitingParamTimeout); + void _updateProgressBar(void); MAV_PARAM_TYPE _factTypeToMavType(FactMetaData::ValueType_t factType); FactMetaData::ValueType_t _mavTypeToFactType(MAV_PARAM_TYPE mavType); @@ -178,9 +183,13 @@ private: QMap> _debugCacheParamSeen; // Wait counts from previous parameter update cycle - int _prevWaitingReadParamIndexCount; - int _prevWaitingReadParamNameCount; - int _prevWaitingWriteParamNameCount; + int _prevWaitingReadParamIndexCount; + int _prevWaitingReadParamNameCount; + int _prevWaitingWriteParamNameCount; + + bool _readParamIndexProgressActive = false; + bool _readParamNameProgressActive = false; + bool _writeParamProgressActive = false; static const int _maxInitialRequestListRetry = 4; ///< Maximum retries for request list int _initialRequestRetryCount; ///< Current retry count for request list @@ -197,7 +206,9 @@ private: QMap > _waitingWriteParamNameMap; ///< Key: Component id, Value: Map { Key: parameter name still waiting for, Value: retry count } QMap > _failedReadParamIndexMap; ///< Key: Component id, Value: failed parameter index - int _totalParamCount; ///< Number of parameters across all components + int _totalParamCount; ///< Number of parameters across all components + int _waitingWriteParamBatchCount = 0; ///< Number of parameters which are batched up waiting on write responses + int _waitingReadParamNameBatchCount = 0; ///< Number of parameters which are batched up waiting on read responses QTimer _initialRequestTimeoutTimer; QTimer _waitingParamTimeoutTimer; -- 2.22.0