Commit f991dd2e authored by Lorenz Meier's avatar Lorenz Meier

Added support for stream rate config to MAVLink inspector. Allows to configure...

Added support for stream rate config to MAVLink inspector. Allows to configure the update rate per message
parent fda0d238
...@@ -12,6 +12,7 @@ const unsigned int QGCMAVLinkInspector::updateInterval = 1000U; ...@@ -12,6 +12,7 @@ const unsigned int QGCMAVLinkInspector::updateInterval = 1000U;
QGCMAVLinkInspector::QGCMAVLinkInspector(MAVLinkProtocol* protocol, QWidget *parent) : QGCMAVLinkInspector::QGCMAVLinkInspector(MAVLinkProtocol* protocol, QWidget *parent) :
QWidget(parent), QWidget(parent),
_protocol(protocol),
selectedSystemID(0), selectedSystemID(0),
selectedComponentID(0), selectedComponentID(0),
ui(new Ui::QGCMAVLinkInspector) ui(new Ui::QGCMAVLinkInspector)
...@@ -36,13 +37,23 @@ QGCMAVLinkInspector::QGCMAVLinkInspector(MAVLinkProtocol* protocol, QWidget *par ...@@ -36,13 +37,23 @@ QGCMAVLinkInspector::QGCMAVLinkInspector(MAVLinkProtocol* protocol, QWidget *par
header << tr("Type"); header << tr("Type");
ui->treeWidget->setHeaderLabels(header); ui->treeWidget->setHeaderLabels(header);
// Set up the column headers for the rate listing
QStringList rateHeader;
rateHeader << tr("Name");
rateHeader << tr("#ID");
rateHeader << tr("Rate");
ui->rateTreeWidget->setHeaderLabels(rateHeader);
connect(ui->rateTreeWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
this, SLOT(rateTreeItemChanged(QTreeWidgetItem*,int)));
ui->rateTreeWidget->hide();
// Connect the UI // Connect the UI
connect(ui->systemComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(selectDropDownMenuSystem(int))); connect(ui->systemComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(selectDropDownMenuSystem(int)));
connect(ui->componentComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(selectDropDownMenuComponent(int))); connect(ui->componentComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(selectDropDownMenuComponent(int)));
connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clearView())); connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clearView()));
// Connect external connections // Connect external connections
connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(addSystem(UASInterface*))); // connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(addSystem(UASInterface*)));
connect(protocol, SIGNAL(messageReceived(LinkInterface*,mavlink_message_t)), this, SLOT(receiveMessage(LinkInterface*,mavlink_message_t))); connect(protocol, SIGNAL(messageReceived(LinkInterface*,mavlink_message_t)), this, SLOT(receiveMessage(LinkInterface*,mavlink_message_t)));
// Attach the UI's refresh rate to a timer. // Attach the UI's refresh rate to a timer.
...@@ -59,29 +70,44 @@ void QGCMAVLinkInspector::selectDropDownMenuSystem(int dropdownid) ...@@ -59,29 +70,44 @@ void QGCMAVLinkInspector::selectDropDownMenuSystem(int dropdownid)
{ {
selectedSystemID = ui->systemComboBox->itemData(dropdownid).toInt(); selectedSystemID = ui->systemComboBox->itemData(dropdownid).toInt();
rebuildComponentList(); rebuildComponentList();
if (selectedSystemID != 0 && selectedComponentID != 0) {
ui->rateTreeWidget->show();
} else {
ui->rateTreeWidget->hide();
}
} }
void QGCMAVLinkInspector::selectDropDownMenuComponent(int dropdownid) void QGCMAVLinkInspector::selectDropDownMenuComponent(int dropdownid)
{ {
selectedComponentID = ui->componentComboBox->itemData(dropdownid).toInt(); selectedComponentID = ui->componentComboBox->itemData(dropdownid).toInt();
if (selectedSystemID != 0 && selectedComponentID != 0) {
ui->rateTreeWidget->show();
} else {
ui->rateTreeWidget->hide();
}
} }
void QGCMAVLinkInspector::rebuildComponentList() void QGCMAVLinkInspector::rebuildComponentList()
{ {
ui->componentComboBox->clear(); ui->componentComboBox->clear();
components.clear();
// Fill ui->componentComboBox->addItem(tr("All"), 0);
UASInterface* uas = UASManager::instance()->getUASForId(selectedSystemID);
if (uas)
{
QMap<int, QString> components = uas->getComponents();
foreach (int id, components.keys()) // // Fill
{ // UASInterface* uas = UASManager::instance()->getUASForId(selectedSystemID);
QString name = components.value(id); // if (uas)
ui->componentComboBox->addItem(name, id); // {
} // QMap<int, QString> components = uas->getComponents();
}
// foreach (int id, components.keys())
// {
// QString name = components.value(id);
// ui->componentComboBox->addItem(name, id);
// }
// }
} }
void QGCMAVLinkInspector::addComponent(int uas, int component, const QString& name) void QGCMAVLinkInspector::addComponent(int uas, int component, const QString& name)
...@@ -100,10 +126,12 @@ void QGCMAVLinkInspector::addComponent(int uas, int component, const QString& na ...@@ -100,10 +126,12 @@ void QGCMAVLinkInspector::addComponent(int uas, int component, const QString& na
void QGCMAVLinkInspector::clearView() void QGCMAVLinkInspector::clearView()
{ {
memset(receivedMessages, 0xFF, sizeof(mavlink_message_t)*256); memset(receivedMessages, 0xFF, sizeof(mavlink_message_t)*256);
onboardMessageInterval.clear();
lastMessageUpdate.clear(); lastMessageUpdate.clear();
messagesHz.clear(); messagesHz.clear();
treeWidgetItems.clear(); treeWidgetItems.clear();
ui->treeWidget->clear(); ui->treeWidget->clear();
ui->rateTreeWidget->clear();
} }
void QGCMAVLinkInspector::refreshView() void QGCMAVLinkInspector::refreshView()
...@@ -145,6 +173,45 @@ void QGCMAVLinkInspector::refreshView() ...@@ -145,6 +173,45 @@ void QGCMAVLinkInspector::refreshView()
updateField(msg->msgid, i, message->child(i)); updateField(msg->msgid, i, message->child(i));
} }
} }
if (selectedSystemID == 0 || selectedComponentID == 0)
{
return;
}
for (int i = 0; i < 256; ++i)//mavlink_message_t msg, receivedMessages)
{
const char* msgname = messageInfo[i].name;
int namelen = strnlen(msgname, 5);
if (namelen < 3) {
continue;
}
if (!strcmp(msgname, "EMPTY")) {
continue;
}
// Update the tree view
QString messageName("%1");
messageName = messageName.arg(msgname);
if (!rateTreeWidgetItems.contains(i))
{
QStringList fields;
fields << messageName;
fields << QString("%1").arg(i);
fields << "OFF / --- Hz";
QTreeWidgetItem* widget = new QTreeWidgetItem(fields);
widget->setFlags(widget->flags() | Qt::ItemIsEditable);
rateTreeWidgetItems.insert(i, widget);
ui->rateTreeWidget->addTopLevelItem(widget);
}
// Set Hz
//QTreeWidgetItem* message = rateTreeWidgetItems.value(i);
//message->setData(0, Qt::DisplayRole, QVariant(messageName));
}
} }
void QGCMAVLinkInspector::receiveMessage(LinkInterface* link,mavlink_message_t message) void QGCMAVLinkInspector::receiveMessage(LinkInterface* link,mavlink_message_t message)
...@@ -155,6 +222,17 @@ void QGCMAVLinkInspector::receiveMessage(LinkInterface* link,mavlink_message_t m ...@@ -155,6 +222,17 @@ void QGCMAVLinkInspector::receiveMessage(LinkInterface* link,mavlink_message_t m
// Only overwrite if system filter is set // Only overwrite if system filter is set
memcpy(receivedMessages+message.msgid, &message, sizeof(mavlink_message_t)); memcpy(receivedMessages+message.msgid, &message, sizeof(mavlink_message_t));
// Add not yet seen systems / components
if (!systems.contains(message.sysid)) {
systems.insert(message.sysid, message.sysid);
ui->systemComboBox->addItem(tr("MAV%1").arg(message.sysid), message.sysid);
}
if (!components.contains(message.compid)) {
components.insert(message.compid, message.compid);
ui->componentComboBox->addItem(tr("COMP%1").arg(message.compid), message.compid);
}
quint64 receiveTime = QGC::groundTimeMilliseconds(); quint64 receiveTime = QGC::groundTimeMilliseconds();
if (lastMessageUpdate.contains(message.msgid)) if (lastMessageUpdate.contains(message.msgid))
{ {
...@@ -163,6 +241,54 @@ void QGCMAVLinkInspector::receiveMessage(LinkInterface* link,mavlink_message_t m ...@@ -163,6 +241,54 @@ void QGCMAVLinkInspector::receiveMessage(LinkInterface* link,mavlink_message_t m
} }
lastMessageUpdate.insert(message.msgid, receiveTime); lastMessageUpdate.insert(message.msgid, receiveTime);
if (selectedSystemID == 0 || selectedComponentID == 0) {
return;
}
switch (message.msgid) {
case MAVLINK_MSG_ID_DATA_STREAM:
{
mavlink_data_stream_t stream;
mavlink_msg_data_stream_decode(&message, &stream);
onboardMessageInterval.insert(stream.stream_id, stream.message_rate);
}
break;
}
}
void QGCMAVLinkInspector::changeStreamInterval(int msgid, int interval) {
//REQUEST_DATA_STREAM
if (selectedSystemID == 0 || selectedComponentID == 0) {
return;
}
mavlink_request_data_stream_t stream;
stream.target_system = selectedSystemID;
stream.target_component = selectedComponentID;
stream.req_stream_id = msgid;
stream.req_message_rate = interval;
stream.start_stop = (interval > 0);
mavlink_message_t msg;
mavlink_msg_request_data_stream_encode(_protocol->getSystemId(), _protocol->getComponentId(), &msg, &stream);
_protocol->sendMessage(msg);
}
void QGCMAVLinkInspector::rateTreeItemChanged(QTreeWidgetItem* paramItem, int column)
{
if (paramItem && column > 0) {
int key = paramItem->data(1, Qt::DisplayRole).toInt();
QVariant value = paramItem->data(2, Qt::DisplayRole);
float interval = 1000 / value.toFloat();
qDebug() << "Stream " << key << "interval" << interval;
changeStreamInterval(key, interval);
}
} }
QGCMAVLinkInspector::~QGCMAVLinkInspector() QGCMAVLinkInspector::~QGCMAVLinkInspector()
......
...@@ -35,14 +35,21 @@ public slots: ...@@ -35,14 +35,21 @@ public slots:
/** @Brief Select a component through the drop down menu */ /** @Brief Select a component through the drop down menu */
void selectDropDownMenuComponent(int dropdownid); void selectDropDownMenuComponent(int dropdownid);
void rateTreeItemChanged(QTreeWidgetItem* paramItem, int column);
protected: protected:
MAVLinkProtocol *_protocol; ///< MAVLink instance
int selectedSystemID; ///< Currently selected system int selectedSystemID; ///< Currently selected system
int selectedComponentID; ///< Currently selected component int selectedComponentID; ///< Currently selected component
QMap<int, int> systems; ///< Already observed systems
QMap<int, int> components; ///< Already observed components
QMap<int, quint64> lastMessageUpdate; ///< Used to switch between highlight and non-highlighting color QMap<int, quint64> lastMessageUpdate; ///< Used to switch between highlight and non-highlighting color
QMap<int, float> messagesHz; ///< Used to store update rate in Hz QMap<int, float> messagesHz; ///< Used to store update rate in Hz
QMap<int, float> onboardMessageInterval; ///< Stores the onboard selected data rate
QMap<int, unsigned int> messageCount; ///< Used to store the message count QMap<int, unsigned int> messageCount; ///< Used to store the message count
mavlink_message_t receivedMessages[256]; ///< Available / known messages mavlink_message_t receivedMessages[256]; ///< Available / known messages
QMap<int, QTreeWidgetItem*> treeWidgetItems; ///< Available tree widget items QMap<int, QTreeWidgetItem*> treeWidgetItems; ///< Available tree widget items
QMap<int, QTreeWidgetItem*> rateTreeWidgetItems; ///< Available rate tree widget items
QTimer updateTimer; ///< Only update at 1 Hz to not overload the GUI QTimer updateTimer; ///< Only update at 1 Hz to not overload the GUI
mavlink_message_info_t messageInfo[256]; // Store the metadata for all available MAVLink messages. mavlink_message_info_t messageInfo[256]; // Store the metadata for all available MAVLink messages.
...@@ -50,6 +57,8 @@ protected: ...@@ -50,6 +57,8 @@ protected:
void updateField(int msgid, int fieldid, QTreeWidgetItem* item); void updateField(int msgid, int fieldid, QTreeWidgetItem* item);
/** @brief Rebuild the list of components */ /** @brief Rebuild the list of components */
void rebuildComponentList(); void rebuildComponentList();
/** @brief Change the stream interval */
void changeStreamInterval(int msgid, int interval);
static const unsigned int updateInterval; static const unsigned int updateInterval;
static const float updateHzLowpass; static const float updateHzLowpass;
......
...@@ -6,30 +6,33 @@ ...@@ -6,30 +6,33 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>400</width> <width>658</width>
<height>300</height> <height>300</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>Form</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout" columnstretch="2,8,0,0,0"> <layout class="QGridLayout" name="gridLayout" columnstretch="2,8,2,8,3">
<property name="margin"> <property name="leftMargin">
<number>6</number> <number>6</number>
</property> </property>
<item row="0" column="0"> <property name="topMargin">
<widget class="QLabel" name="label"> <number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="4">
<widget class="QPushButton" name="clearButton">
<property name="text"> <property name="text">
<string>System</string> <string>Clear</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1">
<widget class="QComboBox" name="systemComboBox"/>
</item>
<item row="0" column="3">
<widget class="QComboBox" name="componentComboBox"/>
</item>
<item row="0" column="2"> <item row="0" column="2">
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_2">
<property name="text"> <property name="text">
...@@ -37,10 +40,10 @@ ...@@ -37,10 +40,10 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="4"> <item row="0" column="0">
<widget class="QPushButton" name="clearButton"> <widget class="QLabel" name="label">
<property name="text"> <property name="text">
<string>Clear</string> <string>System</string>
</property> </property>
</widget> </widget>
</item> </item>
...@@ -53,6 +56,21 @@ ...@@ -53,6 +56,21 @@
</column> </column>
</widget> </widget>
</item> </item>
<item row="3" column="0" colspan="5">
<widget class="QTreeWidget" name="rateTreeWidget">
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="systemComboBox"/>
</item>
<item row="0" column="3">
<widget class="QComboBox" name="componentComboBox"/>
</item>
</layout> </layout>
</widget> </widget>
<resources/> <resources/>
......
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