Commit af2a3970 authored by Gus Grubba's avatar Gus Grubba

Implement MAVLink Inspector (WIP)

parent f1aa7947
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
<file alias="LogReplaySettings.qml">src/ui/preferences/LogReplaySettings.qml</file> <file alias="LogReplaySettings.qml">src/ui/preferences/LogReplaySettings.qml</file>
<file alias="MainRootWindow.qml">src/ui/MainRootWindow.qml</file> <file alias="MainRootWindow.qml">src/ui/MainRootWindow.qml</file>
<file alias="MavlinkConsolePage.qml">src/AnalyzeView/MavlinkConsolePage.qml</file> <file alias="MavlinkConsolePage.qml">src/AnalyzeView/MavlinkConsolePage.qml</file>
<file alias="MAVLinkInspectorPage.qml">src/AnalyzeView/MAVLinkInspectorPage.qml</file>
<file alias="MavlinkSettings.qml">src/ui/preferences/MavlinkSettings.qml</file> <file alias="MavlinkSettings.qml">src/ui/preferences/MavlinkSettings.qml</file>
<file alias="MicrohardSettings.qml">src/Microhard/MicrohardSettings.qml</file> <file alias="MicrohardSettings.qml">src/Microhard/MicrohardSettings.qml</file>
<file alias="MissionSettingsEditor.qml">src/PlanView/MissionSettingsEditor.qml</file> <file alias="MissionSettingsEditor.qml">src/PlanView/MissionSettingsEditor.qml</file>
......
...@@ -23,7 +23,7 @@ Item { ...@@ -23,7 +23,7 @@ Item {
property alias pageComponent: pageLoader.sourceComponent property alias pageComponent: pageLoader.sourceComponent
property alias pageName: pageNameLabel.text property alias pageName: pageNameLabel.text
property alias pageDescription: pageDescriptionLabel.text property alias pageDescription: pageDescriptionLabel.text
property real availableWidth: width - pageLoader.x property real availableWidth: width - pageLoader.x
property real availableHeight: height - pageLoader.y property real availableHeight: height - pageLoader.y
property real _margins: ScreenTools.defaultFontPixelHeight * 0.5 property real _margins: ScreenTools.defaultFontPixelHeight * 0.5
......
...@@ -26,8 +26,6 @@ Rectangle { ...@@ -26,8 +26,6 @@ Rectangle {
color: qgcPal.window color: qgcPal.window
z: QGroundControl.zOrderTopMost z: QGroundControl.zOrderTopMost
QGCPalette { id: qgcPal; colorGroupEnabled: true }
ExclusiveGroup { id: setupButtonGroup } ExclusiveGroup { id: setupButtonGroup }
readonly property real _defaultTextHeight: ScreenTools.defaultFontPixelHeight readonly property real _defaultTextHeight: ScreenTools.defaultFontPixelHeight
...@@ -106,9 +104,14 @@ Rectangle { ...@@ -106,9 +104,14 @@ Rectangle {
} }
ListElement { ListElement {
buttonImage: "/qmlimages/MavlinkConsoleIcon" buttonImage: "/qmlimages/MavlinkConsoleIcon"
buttonText: qsTr("Mavlink Console") buttonText: qsTr("MAVLink Console")
pageSource: "MavlinkConsolePage.qml" pageSource: "MavlinkConsolePage.qml"
} }
ListElement {
buttonImage: "/qmlimages/MavlinkConsoleIcon"
buttonText: qsTr("MAVLink Inspector")
pageSource: "MAVLinkInspectorPage.qml"
}
} }
Component.onCompleted: itemAt(0).checked = true Component.onCompleted: itemAt(0).checked = true
......
...@@ -40,7 +40,7 @@ public: ...@@ -40,7 +40,7 @@ public:
ObjectRole = Qt::UserRole + 1 ObjectRole = Qt::UserRole + 1
}; };
QGCLogModel(QObject *parent = 0); QGCLogModel(QObject *parent = nullptr);
Q_PROPERTY(int count READ count NOTIFY countChanged) Q_PROPERTY(int count READ count NOTIFY countChanged)
Q_INVOKABLE QGCLogEntry* get(int index); Q_INVOKABLE QGCLogEntry* get(int index);
......
...@@ -15,7 +15,90 @@ ...@@ -15,7 +15,90 @@
#include <QObject> #include <QObject>
#include <QString> #include <QString>
#include <QDebug> #include <QDebug>
#include <QAbstractListModel>
Q_DECLARE_LOGGING_CATEGORY(MAVLinkInspectorLog)
//-----------------------------------------------------------------------------
class QGCMAVLinkMessageField : public QObject {
Q_OBJECT
Q_PROPERTY(QString name READ name CONSTANT)
Q_PROPERTY(QString type READ type CONSTANT)
Q_PROPERTY(QString value READ value NOTIFY valueChanged)
public:
QGCMAVLinkMessageField(QObject* parent, QString name, QString type);
QString name () { return _name; }
QString type () { return _type; }
QString value () { return _value; }
void updateValue (QString newValue) { _value = newValue; emit valueChanged(); }
signals:
void valueChanged ();
private:
QString _type;
QString _name;
QString _value;
};
//-----------------------------------------------------------------------------
class QGCMAVLinkMessage : public QObject {
Q_OBJECT
Q_PROPERTY(quint32 id READ id CONSTANT)
Q_PROPERTY(QString name READ name CONSTANT)
Q_PROPERTY(quint64 messageHz READ messageHz NOTIFY messageChanged)
Q_PROPERTY(quint64 count READ count NOTIFY messageChanged)
Q_PROPERTY(QmlObjectListModel* fields READ fields CONSTANT)
public:
QGCMAVLinkMessage(QObject* parent, mavlink_message_t* message);
quint32 id () { return _message.msgid; }
QString name () { return _name; }
quint64 messageHz () { return _messageHz; }
quint64 count () { return _count; }
QmlObjectListModel* fields () { return &_fields; }
void update (mavlink_message_t* message);
signals:
void messageChanged ();
private:
QmlObjectListModel _fields;
QString _name;
uint64_t _messageHz = 0;
uint64_t _count = 0;
mavlink_message_t _message; //-- List of QGCMAVLinkMessageField
};
//-----------------------------------------------------------------------------
class QGCMAVLinkVehicle : public QObject {
Q_OBJECT
Q_PROPERTY(quint8 id READ id CONSTANT)
Q_PROPERTY(QmlObjectListModel* messages READ messages NOTIFY messagesChanged)
public:
QGCMAVLinkVehicle(QObject* parent, quint8 id);
quint8 id () { return _id; }
QmlObjectListModel* messages () { return &_messages; }
QGCMAVLinkMessage* findMessage (uint32_t id);
void append (QGCMAVLinkMessage* message);
signals:
void messagesChanged ();
private:
quint8 _id;
QmlObjectListModel _messages; //-- List of QGCMAVLinkMessage
};
//-----------------------------------------------------------------------------
class MAVLinkInspectorController : public QObject class MAVLinkInspectorController : public QObject
{ {
Q_OBJECT Q_OBJECT
...@@ -23,20 +106,29 @@ public: ...@@ -23,20 +106,29 @@ public:
MAVLinkInspectorController(); MAVLinkInspectorController();
~MAVLinkInspectorController(); ~MAVLinkInspectorController();
Q_PROPERTY(QStringList vehicleNames READ vehicleNames NOTIFY vehiclesChanged)
Q_PROPERTY(QmlObjectListModel* vehicles READ vehicles NOTIFY vehiclesChanged)
QmlObjectListModel* vehicles () { return &_vehicles; }
QStringList vehicleNames () { return _vehicleNames; }
signals:
void vehiclesChanged ();
private slots: private slots:
void _receiveMessage (LinkInterface* link, mavlink_message_t message); void _receiveMessage (LinkInterface* link, mavlink_message_t message);
void _vehicleAdded (Vehicle* vehicle); void _vehicleAdded (Vehicle* vehicle);
void _vehicleRemoved (Vehicle* vehicle); void _vehicleRemoved (Vehicle* vehicle);
private: private:
void _reset (); void _reset ();
QGCMAVLinkVehicle* _findVehicle (uint8_t id);
private: private:
int _selectedSystemID = 0; ///< Currently selected system int _selectedSystemID = 0; ///< Currently selected system
int _selectedComponentID = 0; ///< Currently selected component int _selectedComponentID = 0; ///< Currently selected component
QList<int> _vehicleIDs;
QMap<int, mavlink_message_t*> _uasMessageStorage; ///< Stores the messages for every UAS QStringList _vehicleNames;
QMap<int, QMap<int, quint64>*> _uasLastMessageUpdate; ///< Stores the time of the last message for each message of each UAS QmlObjectListModel _vehicles; //-- List of QGCMAVLinkVehicle
QMap<int, QMap<int, float>*> _uasMessageHz; ///< Stores the frequency of each message of each UAS
QMap<int, QMap<int, unsigned int>*> _uasMessageCount; ///< Stores the message count of each message of each UAS
}; };
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
import QtQuick 2.11
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.11
import QtQuick.Dialogs 1.3
import QGroundControl 1.0
import QGroundControl.Palette 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Controllers 1.0
import QGroundControl.ScreenTools 1.0
Item {
anchors.fill: parent
anchors.margins: ScreenTools.defaultFontPixelWidth
readonly property real _butttonWidth: ScreenTools.defaultFontPixelWidth * 30
property int curVehicleIndex: 0
property var curVehicle: controller.vehicles.count > 0 ? controller.vehicles.get(curVehicleIndex) : null
property int curMessageIndex: 0
property var curMessage: curVehicle && curVehicle.messages.count ? curVehicle.messages.get(curMessageIndex) : null
MAVLinkInspectorController {
id: controller
}
DeadMouseArea {
anchors.fill: parent
}
//-- Header
ColumnLayout {
id: header
width: parent.width
spacing: ScreenTools.defaultFontPixelHeight
QGCLabel {
text: qsTr("Analyze real time MAVLink messages.")
}
RowLayout {
Layout.fillWidth: true
spacing: ScreenTools.defaultFontPixelWidth
QGCLabel {
text: qsTr("Vehicle:")
}
QGCComboBox {
id: vehicleSelector
model: controller.vehicleNames
enabled: controller.vehicles.count > 0
onActivated: curVehicleIndex = index
Layout.minimumWidth: ScreenTools.defaultFontPixelWidth * 16
}
}
Item {
height: ScreenTools.defaultFontPixelHeight
width: 1
}
}
//-- Messages
QGCFlickable {
id: buttonGrid
anchors.top: header.bottom
anchors.bottom: parent.bottom
anchors.left: parent.left
width: ScreenTools.defaultFontPixelWidth * 32
contentWidth: buttonCol.width
contentHeight: buttonCol.height
ColumnLayout {
id: buttonCol
spacing: ScreenTools.defaultFontPixelHeight * 0.25
Repeater {
model: curVehicle ? curVehicle.messages : []
delegate: QGCButton {
text: object.name
onClicked: curMessageIndex = index
Layout.minimumWidth: _butttonWidth
}
}
}
}
//-- Message Data
QGCFlickable {
id: messageGrid
anchors.top: header.bottom
anchors.bottom: parent.bottom
anchors.left: buttonGrid.right
anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 2
anchors.right: parent.right
contentWidth: messageCol.width
contentHeight: messageCol.height
Column {
id: messageCol
spacing: ScreenTools.defaultFontPixelHeight
GridLayout {
columns: 2
columnSpacing: ScreenTools.defaultFontPixelWidth
rowSpacing: ScreenTools.defaultFontPixelHeight * 0.25
QGCLabel {
text: qsTr("Message:")
Layout.minimumWidth: ScreenTools.defaultFontPixelWidth * 20
}
QGCLabel {
color: qgcPal.buttonHighlight
text: curMessage ? curMessage.name : ""
}
QGCLabel {
text: qsTr("Count:")
}
QGCLabel {
text: curMessage ? curMessage.count : ""
}
QGCLabel {
text: qsTr("Frequency:")
}
QGCLabel {
text: curMessage ? curMessage.messageHz + 'Hz' : ""
}
}
GridLayout {
columns: 3
columnSpacing: ScreenTools.defaultFontPixelWidth
rowSpacing: ScreenTools.defaultFontPixelHeight * 0.25
Repeater {
model: curMessage ? curMessage.fields : []
delegate: QGCLabel {
Layout.row: index
Layout.column: 0
Layout.minimumWidth: ScreenTools.defaultFontPixelWidth * 20
text: object.name
}
}
Repeater {
model: curMessage ? curMessage.fields : []
delegate: QGCLabel {
Layout.row: index
Layout.column: 1
Layout.minimumWidth: ScreenTools.defaultFontPixelWidth * 30
Layout.maximumWidth: ScreenTools.defaultFontPixelWidth * 30
wrapMode: Text.WordWrap
text: object.value
}
}
Repeater {
model: curMessage ? curMessage.fields : []
delegate: QGCLabel {
Layout.row: index
Layout.column: 2
text: object.type
}
}
}
}
}
}
...@@ -77,6 +77,7 @@ ...@@ -77,6 +77,7 @@
#include "VideoSurface.h" #include "VideoSurface.h"
#include "VideoReceiver.h" #include "VideoReceiver.h"
#include "LogDownloadController.h" #include "LogDownloadController.h"
#include "MAVLinkInspectorController.h"
#include "ValuesWidgetController.h" #include "ValuesWidgetController.h"
#include "AppMessages.h" #include "AppMessages.h"
#include "SimulatedPosition.h" #include "SimulatedPosition.h"
...@@ -452,6 +453,7 @@ void QGCApplication::_initCommon() ...@@ -452,6 +453,7 @@ void QGCApplication::_initCommon()
qmlRegisterType<RCChannelMonitorController> (kQGCControllers, 1, 0, "RCChannelMonitorController"); qmlRegisterType<RCChannelMonitorController> (kQGCControllers, 1, 0, "RCChannelMonitorController");
qmlRegisterType<JoystickConfigController> (kQGCControllers, 1, 0, "JoystickConfigController"); qmlRegisterType<JoystickConfigController> (kQGCControllers, 1, 0, "JoystickConfigController");
qmlRegisterType<LogDownloadController> (kQGCControllers, 1, 0, "LogDownloadController"); qmlRegisterType<LogDownloadController> (kQGCControllers, 1, 0, "LogDownloadController");
qmlRegisterType<MAVLinkInspectorController> (kQGCControllers, 1, 0, "MAVLinkInspectorController");
qmlRegisterType<SyslinkComponentController> (kQGCControllers, 1, 0, "SyslinkComponentController"); qmlRegisterType<SyslinkComponentController> (kQGCControllers, 1, 0, "SyslinkComponentController");
qmlRegisterType<EditPositionDialogController> (kQGCControllers, 1, 0, "EditPositionDialogController"); qmlRegisterType<EditPositionDialogController> (kQGCControllers, 1, 0, "EditPositionDialogController");
......
...@@ -10,8 +10,6 @@ Flickable { ...@@ -10,8 +10,6 @@ Flickable {
property color indicatorColor: qgcPal.text property color indicatorColor: qgcPal.text
QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
Component.onCompleted: { Component.onCompleted: {
var indicatorComponent = Qt.createComponent("QGCFlickableVerticalIndicator.qml") var indicatorComponent = Qt.createComponent("QGCFlickableVerticalIndicator.qml")
indicatorComponent.createObject(root) indicatorComponent.createObject(root)
......
...@@ -119,7 +119,7 @@ bool QmlObjectListModel::removeRows(int position, int rows, const QModelIndex& p ...@@ -119,7 +119,7 @@ bool QmlObjectListModel::removeRows(int position, int rows, const QModelIndex& p
QObject* QmlObjectListModel::operator[](int index) QObject* QmlObjectListModel::operator[](int index)
{ {
if (index < 0 || index >= _objectList.count()) { if (index < 0 || index >= _objectList.count()) {
return NULL; return nullptr;
} }
return _objectList[index]; return _objectList[index];
} }
...@@ -127,7 +127,7 @@ QObject* QmlObjectListModel::operator[](int index) ...@@ -127,7 +127,7 @@ QObject* QmlObjectListModel::operator[](int index)
const QObject* QmlObjectListModel::operator[](int index) const const QObject* QmlObjectListModel::operator[](int index) const
{ {
if (index < 0 || index >= _objectList.count()) { if (index < 0 || index >= _objectList.count()) {
return NULL; return nullptr;
} }
return _objectList[index]; return _objectList[index];
} }
......
...@@ -18,8 +18,8 @@ class QmlObjectListModel : public QAbstractListModel ...@@ -18,8 +18,8 @@ class QmlObjectListModel : public QAbstractListModel
Q_OBJECT Q_OBJECT
public: public:
QmlObjectListModel(QObject* parent = NULL); QmlObjectListModel(QObject* parent = nullptr);
~QmlObjectListModel(); ~QmlObjectListModel() override;
Q_PROPERTY(int count READ count NOTIFY countChanged) Q_PROPERTY(int count READ count NOTIFY countChanged)
......
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