Commit 6f98185c authored by Bryant's avatar Bryant

The details on the success/errors for the MAVLink protocols are now shown for...

The details on the success/errors for the MAVLink protocols are now shown for each link as tooltips that are updated every 5s. Values are currently wrong and unsure why as of yet.
parent 1858a52c
...@@ -107,6 +107,10 @@ QList<LinkInterface*> LinkManager::getLinksForProtocol(ProtocolInterface* protoc ...@@ -107,6 +107,10 @@ QList<LinkInterface*> LinkManager::getLinksForProtocol(ProtocolInterface* protoc
return protocolLinks.values(protocol); return protocolLinks.values(protocol);
} }
ProtocolInterface* LinkManager::getProtocolForLink(LinkInterface* link)
{
return protocolLinks.key(link);
}
bool LinkManager::connectAll() bool LinkManager::connectAll()
{ {
......
...@@ -56,6 +56,8 @@ public: ...@@ -56,6 +56,8 @@ public:
QList<LinkInterface*> getLinksForProtocol(ProtocolInterface* protocol); QList<LinkInterface*> getLinksForProtocol(ProtocolInterface* protocol);
ProtocolInterface* getProtocolForLink(LinkInterface* link);
/** @brief Get the link for this id */ /** @brief Get the link for this id */
LinkInterface* getLinkForId(int id); LinkInterface* getLinkForId(int id);
......
...@@ -63,10 +63,14 @@ MAVLinkProtocol::MAVLinkProtocol() : ...@@ -63,10 +63,14 @@ MAVLinkProtocol::MAVLinkProtocol() :
// Start heartbeat timer, emitting a heartbeat at the configured rate // Start heartbeat timer, emitting a heartbeat at the configured rate
connect(heartbeatTimer, SIGNAL(timeout()), this, SLOT(sendHeartbeat())); connect(heartbeatTimer, SIGNAL(timeout()), this, SLOT(sendHeartbeat()));
heartbeatTimer->start(1000/heartbeatRate); heartbeatTimer->start(1000/heartbeatRate);
totalReceiveCounter = 0; for (int i = 0; i < MAVLINK_COMM_NUM_BUFFERS; i++)
totalLossCounter = 0; {
currReceiveCounter = 0; totalReceiveCounter[i] = 0;
currLossCounter = 0; totalLossCounter[i] = 0;
totalErrorCounter[i] = 0;
currReceiveCounter[i] = 0;
currLossCounter[i] = 0;
}
for (int i = 0; i < 256; i++) for (int i = 0; i < 256; i++)
{ {
for (int j = 0; j < 256; j++) for (int j = 0; j < 256; j++)
...@@ -214,12 +218,16 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b) ...@@ -214,12 +218,16 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b)
mavlink_message_t message; mavlink_message_t message;
mavlink_status_t status; mavlink_status_t status;
// Cache the link ID for common use.
int linkId = link->getId();
static int mavlink09Count = 0; static int mavlink09Count = 0;
static bool decodedFirstPacket = false; static bool decodedFirstPacket = false;
static bool warnedUser = false; static bool warnedUser = false;
// FIXME: Add check for if link->getId() >= MAVLINK_COMM_NUM_BUFFERS
for (int position = 0; position < b.size(); position++) { for (int position = 0; position < b.size(); position++) {
unsigned int decodeState = mavlink_parse_char(link->getId(), (uint8_t)(b[position]), &message, &status); unsigned int decodeState = mavlink_parse_char(linkId, (uint8_t)(b[position]), &message, &status);
if ((uint8_t)b[position] == 0x55) mavlink09Count++; if ((uint8_t)b[position] == 0x55) mavlink09Count++;
if ((mavlink09Count > 100) && !decodedFirstPacket && !warnedUser) if ((mavlink09Count > 100) && !decodedFirstPacket && !warnedUser)
...@@ -230,6 +238,9 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b) ...@@ -230,6 +238,9 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b)
emit protocolStatusMessage("MAVLink Version or Baud Rate Mismatch", "Your MAVLink device seems to use the deprecated version 0.9, while QGroundControl only supports version 1.0+. Please upgrade the MAVLink version of your autopilot. If your autopilot is using version 1.0, check if the baud rates of QGroundControl and your autopilot are the same."); emit protocolStatusMessage("MAVLink Version or Baud Rate Mismatch", "Your MAVLink device seems to use the deprecated version 0.9, while QGroundControl only supports version 1.0+. Please upgrade the MAVLink version of your autopilot. If your autopilot is using version 1.0, check if the baud rates of QGroundControl and your autopilot are the same.");
} }
// Count parser errors as well.
totalErrorCounter[linkId] += status.packet_rx_drop_count;
if (decodeState == 1) if (decodeState == 1)
{ {
decodedFirstPacket = true; decodedFirstPacket = true;
...@@ -391,8 +402,8 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b) ...@@ -391,8 +402,8 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b)
{ {
// Increase receive counter // Increase receive counter
totalReceiveCounter++; totalReceiveCounter[linkId]++;
currReceiveCounter++; currReceiveCounter[linkId]++;
// Update last message sequence ID // Update last message sequence ID
uint8_t expectedIndex; uint8_t expectedIndex;
...@@ -412,7 +423,7 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b) ...@@ -412,7 +423,7 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b)
if (message.seq != expectedIndex) if (message.seq != expectedIndex)
{ {
// Determine how many messages were skipped accounting for 0-wraparound // Determine how many messages were skipped accounting for 0-wraparound
int16_t lostMessages = message.seq - expectedIndex; int16_t lostMessages = message.seq - expectedIndex;
if (lostMessages < 0) if (lostMessages < 0)
{ {
// Usually, this happens in the case of an out-of order packet // Usually, this happens in the case of an out-of order packet
...@@ -423,22 +434,22 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b) ...@@ -423,22 +434,22 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b)
// Console generates excessive load at high loss rates, needs better GUI visualization // Console generates excessive load at high loss rates, needs better GUI visualization
//qDebug() << QString("Lost %1 messages for comp %4: expected sequence ID %2 but received %3.").arg(lostMessages).arg(expectedIndex).arg(message.seq).arg(message.compid); //qDebug() << QString("Lost %1 messages for comp %4: expected sequence ID %2 but received %3.").arg(lostMessages).arg(expectedIndex).arg(message.seq).arg(message.compid);
} }
totalLossCounter += lostMessages; totalLossCounter[linkId] += lostMessages;
currLossCounter += lostMessages; currLossCounter[linkId] += lostMessages;
} }
// Update the last sequence ID // Update the last sequence ID
lastIndex[message.sysid][message.compid] = message.seq; lastIndex[message.sysid][message.compid] = message.seq;
// Update on every 32th packet // Update on every 32th packet
if (totalReceiveCounter % 32 == 0) if (totalReceiveCounter[linkId] % 32 == 0)
{ {
// Calculate new loss ratio // Calculate new loss ratio
// Receive loss // Receive loss
float receiveLoss = (double)currLossCounter/(double)(currReceiveCounter+currLossCounter); float receiveLoss = (double)currLossCounter[linkId]/(double)(currReceiveCounter[linkId]+currLossCounter[linkId]);
receiveLoss *= 100.0f; receiveLoss *= 100.0f;
currLossCounter = 0; currLossCounter[linkId] = 0;
currReceiveCounter = 0; currReceiveCounter[linkId] = 0;
emit receiveLossChanged(message.sysid, receiveLoss); emit receiveLossChanged(message.sysid, receiveLoss);
} }
......
...@@ -124,6 +124,27 @@ public: ...@@ -124,6 +124,27 @@ public:
int getActionRetransmissionTimeout() { int getActionRetransmissionTimeout() {
return m_actionRetransmissionTimeout; return m_actionRetransmissionTimeout;
} }
/**
* Retrieve a total of all successfully parsed packets for the specified link.
* @returns -1 if this is not available for this protocol, # of packets otherwise.
*/
qint32 getReceivedPacketCount(LinkInterface *link) const {
return totalReceiveCounter[link->getId()];
}
/**
* Retrieve a total of all parsing errors for the specified link.
* @returns -1 if this is not available for this protocol, # of errors otherwise.
*/
qint32 getParsingErrorCount(LinkInterface *link) const {
return totalErrorCounter[link->getId()];
}
/**
* Retrieve a total of all dropped packets for the specified link.
* @returns -1 if this is not available for this protocol, # of packets otherwise.
*/
qint32 getDroppedPacketCount(LinkInterface *link) const {
return totalLossCounter[link->getId()];
}
public slots: public slots:
/** @brief Receive bytes from a communication interface */ /** @brief Receive bytes from a communication interface */
...@@ -201,12 +222,13 @@ protected: ...@@ -201,12 +222,13 @@ protected:
bool m_paramGuardEnabled; ///< Parameter retransmission/rewrite enabled bool m_paramGuardEnabled; ///< Parameter retransmission/rewrite enabled
bool m_actionGuardEnabled; ///< Action request retransmission enabled bool m_actionGuardEnabled; ///< Action request retransmission enabled
int m_actionRetransmissionTimeout; ///< Timeout for parameter retransmission int m_actionRetransmissionTimeout; ///< Timeout for parameter retransmission
QMutex receiveMutex; ///< Mutex to protect receiveBytes function QMutex receiveMutex; ///< Mutex to protect receiveBytes function
int lastIndex[256][256]; ///< Store the last received sequence ID for each system/componenet pair int lastIndex[256][256]; ///< Store the last received sequence ID for each system/componenet pair
int totalReceiveCounter; int totalReceiveCounter[MAVLINK_COMM_NUM_BUFFERS]; ///< The total number of successfully received messages
int totalLossCounter; int totalLossCounter[MAVLINK_COMM_NUM_BUFFERS]; ///< Total messages lost during transmission.
int currReceiveCounter; int totalErrorCounter[MAVLINK_COMM_NUM_BUFFERS]; ///< Total count of all parsing errors. Generally <= totalLossCounter.
int currLossCounter; int currReceiveCounter[MAVLINK_COMM_NUM_BUFFERS]; ///< Received messages during this sample time window. Used for calculating loss %.
int currLossCounter[MAVLINK_COMM_NUM_BUFFERS]; ///< Lost messages during this sample time window. Used for calculating loss %.
bool versionMismatchIgnore; bool versionMismatchIgnore;
int systemId; int systemId;
#if defined(QGC_PROTOBUF_ENABLED) && defined(QGC_USE_PIXHAWK_MESSAGES) #if defined(QGC_PROTOBUF_ENABLED) && defined(QGC_USE_PIXHAWK_MESSAGES)
......
...@@ -50,8 +50,26 @@ class ProtocolInterface : public QObject ...@@ -50,8 +50,26 @@ class ProtocolInterface : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
//virtual ~ProtocolInterface() {}; virtual ~ProtocolInterface () {}
virtual QString getName() = 0; virtual QString getName() = 0;
/**
* Retrieve a total of all successfully parsed packets for the specified link.
* @param link The link to return metadata about.
* @returns -1 if this is not available for this protocol, # of packets otherwise.
*/
virtual qint32 getReceivedPacketCount(LinkInterface *link) const = 0;
/**
* Retrieve a total of all parsing errors for the specified link.
* @param link The link to return metadata about.
* @returns -1 if this is not available for this protocol, # of errors otherwise.
*/
virtual qint32 getParsingErrorCount(LinkInterface *link) const = 0;
/**
* Retrieve a total of all dropped packets for the specified link.
* @param link The link to return metadata about.
* @returns -1 if this is not available for this protocol, # of packets otherwise.
*/
virtual qint32 getDroppedPacketCount(LinkInterface *link) const = 0;
public slots: public slots:
virtual void receiveBytes(LinkInterface *link, QByteArray b) = 0; virtual void receiveBytes(LinkInterface *link, QByteArray b) = 0;
......
...@@ -73,6 +73,10 @@ UASListWidget::UASListWidget(QWidget *parent) : QWidget(parent), ...@@ -73,6 +73,10 @@ UASListWidget::UASListWidget(QWidget *parent) : QWidget(parent),
{ {
addUAS(uas); addUAS(uas);
} }
// Use a timer to update the link health display.
updateTimer = new QTimer(this);
connect(updateTimer,SIGNAL(timeout()),this,SLOT(updateStatus()));
} }
UASListWidget::~UASListWidget() UASListWidget::~UASListWidget()
...@@ -93,14 +97,48 @@ void UASListWidget::changeEvent(QEvent *e) ...@@ -93,14 +97,48 @@ void UASListWidget::changeEvent(QEvent *e)
} }
} }
void UASListWidget::updateStatus()
{
QMapIterator<LinkInterface*, QGroupBox*> i(linkToBoxMapping);
while (i.hasNext()) {
i.next();
LinkInterface* link = i.key();
ProtocolInterface* p = LinkManager::instance()->getProtocolForLink(link);
// Build the tooltip out of the protocol parsing data: received, dropped, and parsing errors.
QString displayString("");
int c;
if ((c = p->getReceivedPacketCount(link)) != -1)
{
displayString += QString(tr("<br/>Received: %2")).arg(QString::number(c));
}
if ((c = p->getDroppedPacketCount(link)) != -1)
{
displayString += QString(tr("<br/>Dropped: %2")).arg(QString::number(c));
}
if ((c = p->getParsingErrorCount(link)) != -1)
{
displayString += QString(tr("<br/>Errors: %2")).arg(QString::number(c));
}
if (!displayString.isEmpty())
{
displayString = QString("<b>%1</b>").arg(i.key()->getName()) + displayString;
}
qDebug() << p << ": " + displayString;
i.value()->setToolTip(displayString);
}
}
void UASListWidget::addUAS(UASInterface* uas) void UASListWidget::addUAS(UASInterface* uas)
{ {
// If the list was empty, remove the unconnected widget and start the update timer.
if (uasViews.isEmpty()) if (uasViews.isEmpty())
{ {
m_ui->verticalLayout->removeWidget(uWidget); m_ui->verticalLayout->removeWidget(uWidget);
uWidget->deleteLater(); uWidget->deleteLater();
uWidget = NULL; uWidget = NULL;
updateTimer->start(5000);
} }
if (!uasViews.contains(uas)) if (!uasViews.contains(uas))
...@@ -125,6 +163,7 @@ void UASListWidget::addUAS(UASInterface* uas) ...@@ -125,6 +163,7 @@ void UASListWidget::addUAS(UASInterface* uas)
newBox->setLayout(boxLayout); newBox->setLayout(boxLayout);
m_ui->verticalLayout->addWidget(newBox); m_ui->verticalLayout->addWidget(newBox);
linkToBoxMapping[li] = newBox; linkToBoxMapping[li] = newBox;
updateStatus(); // Update the link status for this GroupBox.
} }
// And add the new UAS to the UASList // And add the new UAS to the UASList
...@@ -186,6 +225,7 @@ void UASListWidget::removeUAS(UASInterface* uas) ...@@ -186,6 +225,7 @@ void UASListWidget::removeUAS(UASInterface* uas)
box->deleteLater(); box->deleteLater();
// And if no other QGroupBoxes are left, put the initial widget back. // And if no other QGroupBoxes are left, put the initial widget back.
// We also stop the update timer as there's nothing to update at this point.
int otherBoxes = 0; int otherBoxes = 0;
foreach (const QGroupBox* otherBox, findChildren<QGroupBox*>()) foreach (const QGroupBox* otherBox, findChildren<QGroupBox*>())
{ {
...@@ -198,6 +238,7 @@ void UASListWidget::removeUAS(UASInterface* uas) ...@@ -198,6 +238,7 @@ void UASListWidget::removeUAS(UASInterface* uas)
{ {
uWidget = new QGCUnconnectedInfoWidget(this); uWidget = new QGCUnconnectedInfoWidget(this);
m_ui->verticalLayout->addWidget(uWidget); m_ui->verticalLayout->addWidget(uWidget);
updateTimer->stop();
} }
} }
} }
...@@ -62,10 +62,14 @@ protected: ...@@ -62,10 +62,14 @@ protected:
// Tie each view to their UAS object so they can be removed easily. // Tie each view to their UAS object so they can be removed easily.
QMap<UASInterface*, UASView*> uasViews; QMap<UASInterface*, UASView*> uasViews;
QGCUnconnectedInfoWidget* uWidget; QGCUnconnectedInfoWidget* uWidget;
QTimer* updateTimer;
void changeEvent(QEvent *e); void changeEvent(QEvent *e);
private: private:
Ui::UASList* m_ui; Ui::UASList* m_ui;
private slots:
void updateStatus();
}; };
#endif // _UASLISTWIDGET_H_ #endif // _UASLISTWIDGET_H_
...@@ -79,6 +79,7 @@ UASView::UASView(UASInterface* uas, QWidget *parent) : ...@@ -79,6 +79,7 @@ UASView::UASView(UASInterface* uas, QWidget *parent) :
m_ui(new Ui::UASView) m_ui(new Ui::UASView)
{ {
m_ui->setupUi(this); m_ui->setupUi(this);
setToolTip(""); // Make sure the QGroupBox's tooltip doesn't seep through.
// FIXME XXX // FIXME XXX
lowPowerModeEnabled = MainWindow::instance()->lowPowerModeEnabled(); lowPowerModeEnabled = MainWindow::instance()->lowPowerModeEnabled();
......
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