diff --git a/src/FactSystem/ParameterManager.cc b/src/FactSystem/ParameterManager.cc index d81511870089908387851b5a2b12d351123e421d..a05cb8ec935ebca2276ae38966942207a7a11b56 100644 --- a/src/FactSystem/ParameterManager.cc +++ b/src/FactSystem/ParameterManager.cc @@ -59,6 +59,7 @@ ParameterManager::ParameterManager(Vehicle* vehicle) , _prevWaitingWriteParamNameCount(0) , _initialRequestRetryCount(0) , _disableAllRetries(false) + , _indexBatchQueueActive(false) , _totalParamCount(0) { _versionParam = vehicle->firmwarePlugin()->getVersionParam(); @@ -75,7 +76,7 @@ ParameterManager::ParameterManager(Vehicle* vehicle) connect(&_initialRequestTimeoutTimer, &QTimer::timeout, this, &ParameterManager::_initialRequestTimeout); _waitingParamTimeoutTimer.setSingleShot(true); - _waitingParamTimeoutTimer.setInterval(30000); + _waitingParamTimeoutTimer.setInterval(3000); connect(&_waitingParamTimeoutTimer, &QTimer::timeout, this, &ParameterManager::_waitingParamTimeout); connect(_vehicle->uas(), &UASInterface::parameterUpdate, this, &ParameterManager::_parameterUpdate); @@ -117,11 +118,13 @@ void ParameterManager::_parameterUpdate(int vehicleId, int componentId, QString _initialRequestTimeoutTimer.stop(); #if 0 - // Handy for testing retry logic - static int counter = 0; - if (counter++ & 0x8) { - qCDebug(ParameterManagerLog) << "Artificial discard" << counter; - return; + if (!_initialLoadComplete && !_indexBatchQueueActive) { + // Handy for testing retry logic + static int counter = 0; + if (counter++ & 0x8) { + qCDebug(ParameterManagerLog) << "Artificial discard" << counter; + return; + } } #endif @@ -179,7 +182,11 @@ void ParameterManager::_parameterUpdate(int vehicleId, int componentId, QString } // Remove this parameter from the waiting lists - _waitingReadParamIndexMap[componentId].remove(parameterId); + if (_waitingReadParamIndexMap[componentId].contains(parameterId)) { + _waitingReadParamIndexMap[componentId].remove(parameterId); + _indexBatchQueue.removeOne(parameterId); + _fillIndexBatchQueue(false /* waitingParamTimeout */); + } _waitingReadParamNameMap[componentId].remove(parameterName); _waitingWriteParamNameMap[componentId].remove(parameterName); if (_waitingReadParamIndexMap[componentId].count()) { @@ -507,25 +514,39 @@ const QMap >& ParameterManager::getGroupMap(void return _mapGroup2ParameterName; } -void ParameterManager::_waitingParamTimeout(void) +/// Requests missing index based parameters from the vehicle. +/// @param waitingParamTimeout: true: being called due to timeout, false: being called to re-fill the batch queue +/// return true: Parameters were requested, false: No more requests needed +bool ParameterManager::_fillIndexBatchQueue(bool waitingParamTimeout) { - bool paramsRequested = false; - const int maxBatchSize = 10; - int batchCount = 0; + if (!_indexBatchQueueActive) { + return false; + } - qCDebug(ParameterManagerLog) << _logVehiclePrefix() << "_waitingParamTimeout"; + const int maxBatchSize = 10; - // First check for any missing parameters from the initial index based load + if (waitingParamTimeout) { + // We timed out, clear the queue and try again + qCDebug(ParameterManagerLog) << "Refilling index based batch queue due to timeout"; + _indexBatchQueue.clear(); + } else { + qCDebug(ParameterManagerLog) << "Refilling index based batch queue due to received parameter"; + } - batchCount = 0; foreach(int componentId, _waitingReadParamIndexMap.keys()) { if (_waitingReadParamIndexMap[componentId].count()) { - qCDebug(ParameterManagerLog) << _logVehiclePrefix() << "_waitingReadParamIndexMap" << _waitingReadParamIndexMap[componentId]; + qCDebug(ParameterManagerLog) << _logVehiclePrefix() << "_waitingReadParamIndexMap count" << _waitingReadParamIndexMap[componentId].count(); + qCDebug(ParameterManagerVerbose1Log) << _logVehiclePrefix() << "_waitingReadParamIndexMap" << _waitingReadParamIndexMap[componentId]; } - foreach(int paramIndex, _waitingReadParamIndexMap[componentId].keys()) { - if (++batchCount > maxBatchSize) { - goto Out; + foreach(int paramIndex, _waitingReadParamIndexMap[componentId].keys()) { + if (_indexBatchQueue.contains(paramIndex)) { + // Don't add more than once + continue; + } + + if (_indexBatchQueue.count() > maxBatchSize) { + break; } _waitingReadParamIndexMap[componentId][paramIndex]++; // Bump retry count @@ -536,13 +557,30 @@ void ParameterManager::_waitingParamTimeout(void) _waitingReadParamIndexMap[componentId].remove(paramIndex); } else { // Retry again - paramsRequested = true; + _indexBatchQueue.append(paramIndex); _readParameterRaw(componentId, "", paramIndex); qCDebug(ParameterManagerLog) << _logVehiclePrefix(componentId) << "Read re-request for (paramIndex:" << paramIndex << "retryCount:" << _waitingReadParamIndexMap[componentId][paramIndex] << ")"; } } } + return _indexBatchQueue.count() != 0; +} + +void ParameterManager::_waitingParamTimeout(void) +{ + bool paramsRequested = false; + const int maxBatchSize = 10; + int batchCount = 0; + + qCDebug(ParameterManagerLog) << _logVehiclePrefix() << "_waitingParamTimeout"; + + // Now that we have timed out for possibly the first time we can activate the index batch queue + _indexBatchQueueActive = true; + + // First check for any missing parameters from the initial index based load + paramsRequested = _fillIndexBatchQueue(true /* waitingParamTimeout */); + if (!paramsRequested && !_waitingForDefaultComponent && !_mapParameterName2Variant.contains(_vehicle->defaultComponentId())) { // Initial load is complete but we still don't have any default component params. Wait one more cycle to see if the // any show up. diff --git a/src/FactSystem/ParameterManager.h b/src/FactSystem/ParameterManager.h index a2c65c015dea67afdbf6014152eb1664d57f12e8..97b4ffaeeee9d7bedac385570c2383168c01d064 100644 --- a/src/FactSystem/ParameterManager.h +++ b/src/FactSystem/ParameterManager.h @@ -147,6 +147,7 @@ private: void _loadOfflineEditingParams(void); QString _logVehiclePrefix(int componentId = -1); void _setLoadProgress(double loadProgress); + bool _fillIndexBatchQueue(bool waitingParamTimeout); MAV_PARAM_TYPE _factTypeToMavType(FactMetaData::ValueType_t factType); FactMetaData::ValueType_t _mavTypeToFactType(MAV_PARAM_TYPE mavType); @@ -178,13 +179,15 @@ private: int _prevWaitingReadParamNameCount; int _prevWaitingWriteParamNameCount; - static const int _maxInitialRequestListRetry = 4; ///< Maximum retries for request list int _initialRequestRetryCount; ///< Current retry count for request list static const int _maxInitialLoadRetrySingleParam = 5; ///< Maximum retries for initial index based load of a single param static const int _maxReadWriteRetry = 5; ///< Maximum retries read/write bool _disableAllRetries; ///< true: Don't retry any requests (used for testing) + bool _indexBatchQueueActive; ///< true: we are actively batching re-requests for missing index base params, false: index based re-request has not yet started + QList _indexBatchQueue; ///< The current queue of index re-requests + QMap _paramCountMap; ///< Key: Component id, Value: count of parameters in this component QMap > _waitingReadParamIndexMap; ///< Key: Component id, Value: Map { Key: parameter index still waiting for, Value: retry count } QMap > _waitingReadParamNameMap; ///< Key: Component id, Value: Map { Key: parameter name still waiting for, Value: retry count }