Commit 2eac0e2e authored by tstellanova's avatar tstellanova

Refactoring comms code

parent 79e10356
......@@ -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<int> readKeys = transmissionMissingPackets.keys();
foreach (int component, readKeys) {
missingReadCount += transmissionMissingPackets.value(component)->count();
transmissionMissingPackets.value(component)->clear();
}
// Empty write retransmission list
int missingWriteCount = 0;
QList<int> 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<int, QMap<QString, QVariant>*>::iterator i;
QMap<int, QMap<QString, QVariant>*> 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<int> * 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<int> writeKeys = transmissionMissingWriteAckPackets.keys();
foreach (int component, writeKeys) {
int count = 0;
QMap <QString, QVariant>* 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);
}
}
......@@ -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;
};
......
......@@ -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::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<int> readKeys = transmissionMissingPackets.keys();
foreach (int component, readKeys) {
missingReadCount += transmissionMissingPackets.value(component)->count();
transmissionMissingPackets.value(component)->clear();
void QGCParamWidget::requestParameterListUpdate()
{
if (!mav) {
return;
}
// Empty write retransmission list
int missingWriteCount = 0;
QList<int> 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));
}
// 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();
}
/**
* The .. signal is emitted
*/
void QGCParamWidget::requestParameterUpdate(int component, const QString& parameter)
{
if (mav) mav->requestParameter(component, parameter);
}
// Re-request at maximum retransmissionBurstRequestSize parameters at once
// to prevent link flooding
/**
* 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<int, QMap<QString, QVariant>*> changedValues = paramDataModel->getPendingParameters();
QMap<int, QMap<QString, QVariant>*>::iterator i;
QMap<int, QMap<QString, QVariant>*> onboardParams = paramDataModel->getOnboardParameters();
for (i = onboardParams.begin(); i != onboardParams.end(); ++i) {
for (i = changedValues.begin(); i != changedValues.end(); ++i) {
// Iterate through the parameters of the component
int component = i.key();
// Request n parameters from this component (at maximum)
QList<int> * 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;
}
int compid = i.key();
QMap<QString, QVariant>* comp = i.value();
{
QMap<QString, QVariant>::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<int> writeKeys = transmissionMissingWriteAckPackets.keys();
foreach (int component, writeKeys) {
int count = 0;
QMap <QString, QVariant>* 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:
// 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)
{
QVariant fixedValue(value.toUInt());
emit parameterChanged(component, key, fixedValue);
transmissionTimeout += parametersSent*rewriteTimeout;
}
break;
case QMetaType::Float:
else
{
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;
}
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<int, QMap<QString, QVariant>*>::iterator i;
QMap<int, QMap<QString, QVariant>*> changedValues = paramDataModel->getPendingParameters();
for (i = changedValues.begin(); i != changedValues.end() , (0 == changedParamCount); ++i)
{
// Iterate through the parameters of the component
QMap<QString, QVariant>* comp = i.value();
QMap<QString, QVariant>::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 (<TRANSMIT>) or update them with the onboard values (<REFRESH>) 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<int, QMap<QString, QVariant>*> changedValues = paramDataModel->getPendingParameters();
QMap<int, QMap<QString, QVariant>*>::iterator i;
for (i = changedValues.begin(); i != changedValues.end(); ++i) {
// Iterate through the parameters of the component
int compid = i.key();
QMap<QString, QVariant>* comp = i.value();
{
QMap<QString, QVariant>::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<int, QMap<QString, QVariant>*>::iterator i;
QMap<int, QMap<QString, QVariant>*> changedValues = paramDataModel->getPendingParameters();
for (i = changedValues.begin(); i != changedValues.end() , (0 == changedParamCount); ++i)
{
// Iterate through the parameters of the component
QMap<QString, QVariant>* comp = i.value();
QMap<QString, QVariant>::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 (<TRANSMIT>) or update them with the onboard values (<REFRESH>) before storing onboard from RAM to ROM."));
msgBox.exec();
}
else
{
if (!mav) return;
mav->writeParametersToStorage();
}
}
void QGCParamWidget::readParameters()
{
if (!mav) return;
......
......@@ -60,13 +60,13 @@ public:
QString getParamInfo(const QString& param) { return paramToolTips.value(param, ""); }
void setParamInfo(const QMap<QString,QString>& 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<QString, double> paramDefault; ///< Default param values
QMap<QString, double> paramMax; ///< Minimum param values
/** @brief Activate / deactivate parameter retransmission */
void setRetransmissionGuardEnabled(bool enabled);
/** @brief Load settings */
void loadSettings();
/** @brief Load meta information from CSV */
......
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