Unverified Commit 3b4a9ca9 authored by Don Gagne's avatar Don Gagne Committed by GitHub

Merge pull request #8005 from DonLakeFlyer/ParamProgress

Param progress bar and other stuff
parents afcc3fb6 d9bbe9bd
...@@ -94,6 +94,63 @@ ParameterManager::~ParameterManager() ...@@ -94,6 +94,63 @@ ParameterManager::~ParameterManager()
delete _parameterMetaData; 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. /// 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) 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 ...@@ -262,17 +319,8 @@ void ParameterManager::_parameterUpdate(int vehicleId, int componentId, QString
qCDebug(ParameterManagerVerbose1Log) << _logVehiclePrefix(-1) << "Not restarting _waitingParamTimeoutTimer (all requests satisfied)"; qCDebug(ParameterManagerVerbose1Log) << _logVehiclePrefix(-1) << "Not restarting _waitingParamTimeoutTimer (all requests satisfied)";
} }
} }
\
// Update progress bar for waiting reads _updateProgressBar();
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);
}
// Get parameter set version // Get parameter set version
if (!_versionParam.isEmpty() && _versionParam == parameterName) { if (!_versionParam.isEmpty() && _versionParam == parameterName) {
...@@ -389,8 +437,13 @@ void ParameterManager::_valueUpdated(const QVariant& value) ...@@ -389,8 +437,13 @@ void ParameterManager::_valueUpdated(const QVariant& value)
_dataMutex.lock(); _dataMutex.lock();
if (_waitingWriteParamNameMap.contains(componentId)) { if (_waitingWriteParamNameMap.contains(componentId)) {
_waitingWriteParamNameMap[componentId].remove(name); // Remove any old entry if (_waitingWriteParamNameMap[componentId].contains(name)) {
_waitingWriteParamNameMap[componentId][name] = 0; // Add new entry and set retry count _waitingWriteParamNameMap[componentId].remove(name);
} else {
_waitingWriteParamBatchCount++;
}
_waitingWriteParamNameMap[componentId][name] = 0; // Add new entry and set retry count
_updateProgressBar();
_waitingParamTimeoutTimer.start(); _waitingParamTimeoutTimer.start();
_saveRequired = true; _saveRequired = true;
} else { } else {
...@@ -466,8 +519,13 @@ void ParameterManager::refreshParameter(int componentId, const QString& name) ...@@ -466,8 +519,13 @@ void ParameterManager::refreshParameter(int componentId, const QString& name)
if (_waitingReadParamNameMap.contains(componentId)) { if (_waitingReadParamNameMap.contains(componentId)) {
QString mappedParamName = _remapParamNameToVersion(name); 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 _waitingReadParamNameMap[componentId][mappedParamName] = 0; // Add new wait entry and update retry count
_updateProgressBar();
qCDebug(ParameterManagerLog) << _logVehiclePrefix(componentId) << "restarting _waitingParamTimeout"; qCDebug(ParameterManagerLog) << _logVehiclePrefix(componentId) << "restarting _waitingParamTimeout";
_waitingParamTimeoutTimer.start(); _waitingParamTimeoutTimer.start();
} else { } else {
...@@ -896,7 +954,8 @@ void ParameterManager::_tryCacheHashLoad(int vehicleId, int componentId, QVarian ...@@ -896,7 +954,8 @@ void ParameterManager::_tryCacheHashLoad(int vehicleId, int componentId, QVarian
QString ParameterManager::readParametersFromStream(QTextStream& stream) QString ParameterManager::readParametersFromStream(QTextStream& stream)
{ {
QString errors; QString missingErrors;
QString typeErrors;
while (!stream.atEnd()) { while (!stream.atEnd()) {
QString line = stream.readLine(); QString line = stream.readLine();
...@@ -915,18 +974,18 @@ QString ParameterManager::readParametersFromStream(QTextStream& stream) ...@@ -915,18 +974,18 @@ QString ParameterManager::readParametersFromStream(QTextStream& stream)
if (!parameterExists(componentId, paramName)) { if (!parameterExists(componentId, paramName)) {
QString error; QString error;
error = QString("Skipped parameter %1:%2 - does not exist on this vehicle\n").arg(componentId).arg(paramName); error += QStringLiteral("%1:%2 ").arg(componentId).arg(paramName);
errors += error; missingErrors += error;
qCDebug(ParameterManagerLog) << error; qCDebug(ParameterManagerLog) << QStringLiteral("Skipped due to missing: %1").arg(error);
continue; continue;
} }
Fact* fact = getParameter(componentId, paramName); Fact* fact = getParameter(componentId, paramName);
if (fact->type() != _mavTypeToFactType((MAV_PARAM_TYPE)mavType)) { if (fact->type() != _mavTypeToFactType((MAV_PARAM_TYPE)mavType)) {
QString error; 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)); error = QStringLiteral("%1:%2 ").arg(componentId).arg(paramName);
errors += error; typeErrors += error;
qCDebug(ParameterManagerLog) << error; qCDebug(ParameterManagerLog) << QStringLiteral("Skipped due to type mismatch: %1").arg(error);
continue; continue;
} }
...@@ -936,6 +995,16 @@ QString ParameterManager::readParametersFromStream(QTextStream& stream) ...@@ -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; return errors;
} }
...@@ -1579,11 +1648,24 @@ QString ParameterManager::_logVehiclePrefix(int componentId) ...@@ -1579,11 +1648,24 @@ QString ParameterManager::_logVehiclePrefix(int componentId)
void ParameterManager::_setLoadProgress(double loadProgress) void ParameterManager::_setLoadProgress(double loadProgress)
{ {
_loadProgress = loadProgress; if (_loadProgress != loadProgress) {
emit loadProgressChanged(static_cast<float>(loadProgress)); _loadProgress = loadProgress;
emit loadProgressChanged(static_cast<float>(loadProgress));
}
} }
QList<int> ParameterManager::componentIds(void) QList<int> ParameterManager::componentIds(void)
{ {
return _paramCountMap.keys(); return _paramCountMap.keys();
} }
bool ParameterManager::pendingWrites(void)
{
for (int compId: _waitingWriteParamNameMap.keys()) {
if (_waitingWriteParamNameMap[compId].count()) {
return true;
}
}
return false;
}
...@@ -39,6 +39,7 @@ public: ...@@ -39,6 +39,7 @@ public:
Q_PROPERTY(bool parametersReady READ parametersReady NOTIFY parametersReadyChanged) ///< true: Parameters are ready for use 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(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(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 parametersReady (void) const { return _parametersReady; }
bool missingParameters (void) const { return _missingParameters; } bool missingParameters (void) const { return _missingParameters; }
...@@ -111,12 +112,15 @@ public: ...@@ -111,12 +112,15 @@ public:
/// @return true: success, false: failure (errorString set) /// @return true: success, false: failure (errorString set)
bool loadFromJson(const QJsonObject& json, bool required, QString& errorString); bool loadFromJson(const QJsonObject& json, bool required, QString& errorString);
bool pendingWrites(void);
Vehicle* vehicle(void) { return _vehicle; } Vehicle* vehicle(void) { return _vehicle; }
signals: signals:
void parametersReadyChanged(bool parametersReady); void parametersReadyChanged (bool parametersReady);
void missingParametersChanged(bool missingParameters); void missingParametersChanged (bool missingParameters);
void loadProgressChanged(float value); void loadProgressChanged (float value);
void pendingWritesChanged (bool pendingWrites);
protected: protected:
Vehicle* _vehicle; Vehicle* _vehicle;
...@@ -146,6 +150,7 @@ private: ...@@ -146,6 +150,7 @@ private:
QString _logVehiclePrefix(int componentId); QString _logVehiclePrefix(int componentId);
void _setLoadProgress(double loadProgress); void _setLoadProgress(double loadProgress);
bool _fillIndexBatchQueue(bool waitingParamTimeout); bool _fillIndexBatchQueue(bool waitingParamTimeout);
void _updateProgressBar(void);
MAV_PARAM_TYPE _factTypeToMavType(FactMetaData::ValueType_t factType); MAV_PARAM_TYPE _factTypeToMavType(FactMetaData::ValueType_t factType);
FactMetaData::ValueType_t _mavTypeToFactType(MAV_PARAM_TYPE mavType); FactMetaData::ValueType_t _mavTypeToFactType(MAV_PARAM_TYPE mavType);
...@@ -178,9 +183,13 @@ private: ...@@ -178,9 +183,13 @@ private:
QMap<int /* component id */, QMap<QString /* param name */, bool /* seen */>> _debugCacheParamSeen; QMap<int /* component id */, QMap<QString /* param name */, bool /* seen */>> _debugCacheParamSeen;
// Wait counts from previous parameter update cycle // Wait counts from previous parameter update cycle
int _prevWaitingReadParamIndexCount; int _prevWaitingReadParamIndexCount;
int _prevWaitingReadParamNameCount; int _prevWaitingReadParamNameCount;
int _prevWaitingWriteParamNameCount; int _prevWaitingWriteParamNameCount;
bool _readParamIndexProgressActive = false;
bool _readParamNameProgressActive = false;
bool _writeParamProgressActive = false;
static const int _maxInitialRequestListRetry = 4; ///< Maximum retries for request list static const int _maxInitialRequestListRetry = 4; ///< Maximum retries for request list
int _initialRequestRetryCount; ///< Current retry count for request list int _initialRequestRetryCount; ///< Current retry count for request list
...@@ -197,7 +206,9 @@ private: ...@@ -197,7 +206,9 @@ private:
QMap<int, QMap<QString, int> > _waitingWriteParamNameMap; ///< Key: Component id, Value: Map { Key: parameter name still waiting for, Value: retry count } QMap<int, QMap<QString, int> > _waitingWriteParamNameMap; ///< Key: Component id, Value: Map { Key: parameter name still waiting for, Value: retry count }
QMap<int, QList<int> > _failedReadParamIndexMap; ///< Key: Component id, Value: failed parameter index QMap<int, QList<int> > _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 _initialRequestTimeoutTimer;
QTimer _waitingParamTimeoutTimer; QTimer _waitingParamTimeoutTimer;
......
...@@ -158,12 +158,8 @@ static QObject* shapeFileHelperSingletonFactory(QQmlEngine*, QJSEngine*) ...@@ -158,12 +158,8 @@ static QObject* shapeFileHelperSingletonFactory(QQmlEngine*, QJSEngine*)
} }
QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting) QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting)
#if defined(__mobile__) : QGuiApplication (argc, argv)
: QGuiApplication (argc, argv) , _runningUnitTests (unitTesting)
#else
: QApplication (argc, argv)
#endif
, _runningUnitTests (unitTesting)
{ {
_app = this; _app = this;
_msecsElapsedTime.start(); _msecsElapsedTime.start();
......
...@@ -7,17 +7,7 @@ ...@@ -7,17 +7,7 @@
* *
****************************************************************************/ ****************************************************************************/
#pragma once
/**
* @file
* @brief Definition of main class
*
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
*/
#ifndef QGCAPPLICATION_H
#define QGCAPPLICATION_H
#include <QApplication> #include <QApplication>
#include <QTimer> #include <QTimer>
...@@ -45,21 +35,7 @@ class QGCSingleton; ...@@ -45,21 +35,7 @@ class QGCSingleton;
class QGCToolbox; class QGCToolbox;
class QGCFileDownload; class QGCFileDownload;
/** class QGCApplication : public QGuiApplication
* @brief The main application and management class.
*
* This class is started by the main method and provides
* the central management unit of the groundstation application.
*
* Needs QApplication base to support QtCharts drawing module and
* avoid application crashing on 5.12. Enforce no widget on mobile
**/
class QGCApplication :
#if defined(__mobile__)
public QGuiApplication
#else
public QApplication
#endif
{ {
Q_OBJECT Q_OBJECT
...@@ -214,5 +190,3 @@ private: ...@@ -214,5 +190,3 @@ private:
/// @brief Returns the QGCApplication object singleton. /// @brief Returns the QGCApplication object singleton.
QGCApplication* qgcApp(void); QGCApplication* qgcApp(void);
#endif
...@@ -32,10 +32,8 @@ Item { ...@@ -32,10 +32,8 @@ Item {
property var _appSettings: QGroundControl.settingsManager.appSettings property var _appSettings: QGroundControl.settingsManager.appSettings
ParameterEditorController { ParameterEditorController {
id: controller; id: controller
onShowErrorMessage: { onShowErrorMessage: mainWindow.showMessageDialog(qsTr("Parameter Load Errors"), errorMsg)
mainWindow.showMessageDialog(qsTr("Parameter Editor"), qsTr("Parameter Load Errors"))
}
} }
ExclusiveGroup { id: sectionGroup } ExclusiveGroup { id: sectionGroup }
......
...@@ -196,47 +196,66 @@ ApplicationWindow { ...@@ -196,47 +196,66 @@ ApplicationWindow {
mainWindow.close() mainWindow.close()
} }
// On attempting an application close we check for:
// Unsaved missions - then
// Pending parameter writes - then
// Active connections
onClosing: {
if (!_forceClose) {
unsavedMissionCloseDialog.check()
close.accepted = false
}
}
MessageDialog { MessageDialog {
id: activeConnectionsCloseDialog id: unsavedMissionCloseDialog
title: qsTr("%1 close").arg(QGroundControl.appName) title: qsTr("%1 close").arg(QGroundControl.appName)
text: qsTr("There are still active connections to vehicles. Are you sure you want to exit?") text: qsTr("You have a mission edit in progress which has not been saved/sent. If you close you will lose changes. Are you sure you want to close?")
standardButtons: StandardButton.Yes | StandardButton.Cancel standardButtons: StandardButton.Yes | StandardButton.No
modality: Qt.ApplicationModal modality: Qt.ApplicationModal
visible: false visible: false
onYes: finishCloseProcess() onYes: pendingParameterWritesCloseDialog.check()
function check() { function check() {
if (QGroundControl.multiVehicleManager.activeVehicle) { if (planMasterControllerPlan && planMasterControllerPlan.dirty) {
activeConnectionsCloseDialog.open() unsavedMissionCloseDialog.open()
} else { } else {
finishCloseProcess() pendingParameterWritesCloseDialog.check()
} }
} }
} }
//------------------------------------------------------------------------- MessageDialog {
//-- Check for unsaved missions id: pendingParameterWritesCloseDialog
title: qsTr("%1 close").arg(QGroundControl.appName)
onClosing: { text: qsTr("You have pending parameter updates to a vehicle. If you close you will lose changes. Are you sure you want to close?")
// Check first for unsaved missions and active connections standardButtons: StandardButton.Yes | StandardButton.No
if (!_forceClose) { modality: Qt.ApplicationModal
unsavedMissionCloseDialog.check() visible: false
close.accepted = false onYes: activeConnectionsCloseDialog.check()
function check() {
for (var index=0; index<QGroundControl.multiVehicleManager.vehicles.count; index++) {
if (QGroundControl.multiVehicleManager.vehicles.get(index).parameterManager.pendingWrites) {
pendingParameterWritesCloseDialog.open()
return
}
}
activeConnectionsCloseDialog.check()
} }
} }
MessageDialog { MessageDialog {
id: unsavedMissionCloseDialog id: activeConnectionsCloseDialog
title: qsTr("%1 close").arg(QGroundControl.appName) title: qsTr("%1 close").arg(QGroundControl.appName)
text: qsTr("You have a mission edit in progress which has not been saved/sent. If you close you will lose changes. Are you sure you want to close?") text: qsTr("There are still active connections to vehicles. Are you sure you want to exit?")
standardButtons: StandardButton.Yes | StandardButton.No standardButtons: StandardButton.Yes | StandardButton.Cancel
modality: Qt.ApplicationModal modality: Qt.ApplicationModal
visible: false visible: false
onYes: activeConnectionsCloseDialog.check() onYes: finishCloseProcess()
function check() { function check() {
if (planMasterControllerPlan && planMasterControllerPlan.dirty) { if (QGroundControl.multiVehicleManager.activeVehicle) {
unsavedMissionCloseDialog.open() activeConnectionsCloseDialog.open()
} else { } else {
activeConnectionsCloseDialog.check() finishCloseProcess()
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment