15 changed files with 453 additions and 199 deletions
@ -1,49 +0,0 @@
@@ -1,49 +0,0 @@
|
||||
/**************************************************************************** |
||||
* |
||||
* (c) 2009-2020 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.3 |
||||
import QtQuick.Layouts 1.2 |
||||
|
||||
import QGroundControl 1.0 |
||||
import QGroundControl.Controls 1.0 |
||||
import QGroundControl.ScreenTools 1.0 |
||||
|
||||
/// Health page for Instrument Panel PageWidget |
||||
Column { |
||||
width: pageWidth |
||||
|
||||
property bool showSettingsIcon: false |
||||
|
||||
property var _unhealthySensors: QGroundControl.multiVehicleManager.activeVehicle ? QGroundControl.multiVehicleManager.activeVehicle.unhealthySensors : [ ] |
||||
|
||||
QGCLabel { |
||||
width: parent.width |
||||
horizontalAlignment: Text.AlignHCenter |
||||
text: qsTr("All systems healthy") |
||||
visible: healthRepeater.count == 0 |
||||
} |
||||
|
||||
Repeater { |
||||
id: healthRepeater |
||||
model: _unhealthySensors |
||||
|
||||
Row { |
||||
Image { |
||||
source: "/qmlimages/Yield.svg" |
||||
height: ScreenTools.defaultFontPixelHeight |
||||
sourceSize.height: height |
||||
fillMode: Image.PreserveAspectFit |
||||
} |
||||
|
||||
QGCLabel { |
||||
text: modelData |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,124 @@
@@ -0,0 +1,124 @@
|
||||
/****************************************************************************
|
||||
* |
||||
* (c) 2009-2020 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. |
||||
* |
||||
****************************************************************************/ |
||||
|
||||
#include "SysStatusSensorInfo.h" |
||||
|
||||
#include <QDebug> |
||||
|
||||
SysStatusSensorInfo::SysStatusSensorInfo(QObject* parent) |
||||
: QObject(parent) |
||||
{ |
||||
|
||||
} |
||||
|
||||
void SysStatusSensorInfo::update(const mavlink_sys_status_t& sysStatus) |
||||
{ |
||||
bool dirty = false; |
||||
|
||||
// Walk the bits
|
||||
for (int bitPosition=0; bitPosition<32; bitPosition++) { |
||||
MAV_SYS_STATUS_SENSOR sensorBitMask = static_cast<MAV_SYS_STATUS_SENSOR>(1 << bitPosition); |
||||
if (sysStatus.onboard_control_sensors_present & sensorBitMask) { |
||||
if (_sensorInfoMap.contains(sensorBitMask)) { |
||||
SensorInfo_t& sensorInfo = _sensorInfoMap[sensorBitMask]; |
||||
|
||||
bool newEnabled = sysStatus.onboard_control_sensors_enabled & sensorBitMask; |
||||
if (sensorInfo.enabled != newEnabled) { |
||||
dirty = true; |
||||
sensorInfo.enabled = newEnabled; |
||||
} |
||||
|
||||
bool newHealthy = sysStatus.onboard_control_sensors_health & sensorBitMask; |
||||
if (sensorInfo.healthy != newHealthy) { |
||||
dirty = true; |
||||
sensorInfo.healthy = newHealthy; |
||||
} |
||||
} else { |
||||
dirty = true; |
||||
SensorInfo_t sensorInfo = { !!(sysStatus.onboard_control_sensors_enabled & sensorBitMask), !!(sysStatus.onboard_control_sensors_health & sensorBitMask) }; |
||||
_sensorInfoMap[sensorBitMask] = sensorInfo; |
||||
} |
||||
} else { |
||||
if (_sensorInfoMap.contains(sensorBitMask)) { |
||||
dirty = true; |
||||
_sensorInfoMap.remove(sensorBitMask); |
||||
} |
||||
} |
||||
} |
||||
|
||||
if (dirty) { |
||||
emit sensorInfoChanged(); |
||||
} |
||||
} |
||||
|
||||
QStringList SysStatusSensorInfo::sensorNames (void) const |
||||
{ |
||||
QStringList rgNames; |
||||
|
||||
// List ordering is unhealthy, healthy, disabled
|
||||
for (int i=0; i<_sensorInfoMap.keys().count(); i++) { |
||||
const MAV_SYS_STATUS_SENSOR sensorBitMask = _sensorInfoMap.keys()[i]; |
||||
const SensorInfo_t& sensorInfo = _sensorInfoMap[sensorBitMask]; |
||||
|
||||
if (sensorInfo.enabled && !sensorInfo.healthy) { |
||||
rgNames.append(QGCMAVLink::mavSysStatusSensorToString(sensorBitMask)); |
||||
} |
||||
} |
||||
for (int i=0; i<_sensorInfoMap.keys().count(); i++) { |
||||
const MAV_SYS_STATUS_SENSOR sensorBitMask = _sensorInfoMap.keys()[i]; |
||||
const SensorInfo_t& sensorInfo = _sensorInfoMap[sensorBitMask]; |
||||
|
||||
if (sensorInfo.enabled && sensorInfo.healthy) { |
||||
rgNames.append(QGCMAVLink::mavSysStatusSensorToString(sensorBitMask)); |
||||
} |
||||
} |
||||
for (int i=0; i<_sensorInfoMap.keys().count(); i++) { |
||||
const MAV_SYS_STATUS_SENSOR sensorBitMask = _sensorInfoMap.keys()[i]; |
||||
const SensorInfo_t& sensorInfo = _sensorInfoMap[sensorBitMask]; |
||||
|
||||
if (!sensorInfo.enabled) { |
||||
rgNames.append(QGCMAVLink::mavSysStatusSensorToString(sensorBitMask)); |
||||
} |
||||
} |
||||
|
||||
return rgNames; |
||||
} |
||||
|
||||
QStringList SysStatusSensorInfo::sensorStatus(void) const |
||||
{ |
||||
QStringList rgStatus; |
||||
|
||||
// List ordering is unhealthy, healthy, disabled
|
||||
for (int i=0; i<_sensorInfoMap.keys().count(); i++) { |
||||
const MAV_SYS_STATUS_SENSOR sensorBitMask = _sensorInfoMap.keys()[i]; |
||||
const SensorInfo_t& sensorInfo = _sensorInfoMap[sensorBitMask]; |
||||
|
||||
if (sensorInfo.enabled && !sensorInfo.healthy) { |
||||
rgStatus.append(tr("Error")); |
||||
} |
||||
} |
||||
for (int i=0; i<_sensorInfoMap.keys().count(); i++) { |
||||
const MAV_SYS_STATUS_SENSOR sensorBitMask = _sensorInfoMap.keys()[i]; |
||||
const SensorInfo_t& sensorInfo = _sensorInfoMap[sensorBitMask]; |
||||
|
||||
if (sensorInfo.enabled && sensorInfo.healthy) { |
||||
rgStatus.append(tr("Normal")); |
||||
} |
||||
} |
||||
for (int i=0; i<_sensorInfoMap.keys().count(); i++) { |
||||
const MAV_SYS_STATUS_SENSOR sensorBitMask = _sensorInfoMap.keys()[i]; |
||||
const SensorInfo_t& sensorInfo = _sensorInfoMap[sensorBitMask]; |
||||
|
||||
if (!sensorInfo.enabled) { |
||||
rgStatus.append(tr("Disabled")); |
||||
} |
||||
} |
||||
|
||||
return rgStatus; |
||||
} |
@ -0,0 +1,42 @@
@@ -0,0 +1,42 @@
|
||||
/****************************************************************************
|
||||
* |
||||
* (c) 2009-2020 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. |
||||
* |
||||
****************************************************************************/ |
||||
|
||||
#pragma once |
||||
|
||||
#include "QGCMAVLink.h" |
||||
#include "QmlObjectListModel.h" |
||||
|
||||
#include <QObject> |
||||
|
||||
/// Class which represents sensor info from the SYS_STATUS mavlink message
|
||||
class SysStatusSensorInfo : public QObject |
||||
{ |
||||
Q_OBJECT |
||||
|
||||
public: |
||||
SysStatusSensorInfo(QObject* parent = nullptr); |
||||
|
||||
Q_PROPERTY(QStringList sensorNames READ sensorNames NOTIFY sensorInfoChanged) |
||||
Q_PROPERTY(QStringList sensorStatus READ sensorStatus NOTIFY sensorInfoChanged) |
||||
|
||||
void update (const mavlink_sys_status_t& sysStatus); |
||||
QStringList sensorNames (void) const; |
||||
QStringList sensorStatus(void) const; |
||||
|
||||
signals: |
||||
void sensorInfoChanged(void); |
||||
|
||||
private: |
||||
typedef struct { |
||||
bool enabled; |
||||
bool healthy; |
||||
} SensorInfo_t; |
||||
|
||||
QMap<MAV_SYS_STATUS_SENSOR, SensorInfo_t> _sensorInfoMap; |
||||
}; |
@ -0,0 +1,131 @@
@@ -0,0 +1,131 @@
|
||||
/**************************************************************************** |
||||
* |
||||
* (c) 2009-2020 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.Layouts 1.11 |
||||
|
||||
import QGroundControl 1.0 |
||||
import QGroundControl.Controls 1.0 |
||||
import QGroundControl.MultiVehicleManager 1.0 |
||||
import QGroundControl.ScreenTools 1.0 |
||||
import QGroundControl.Palette 1.0 |
||||
|
||||
Item { |
||||
id: _root |
||||
Layout.preferredWidth: mainStatusLabel.contentWidth + ScreenTools.defaultFontPixelWidth |
||||
|
||||
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle |
||||
property real _margins: ScreenTools.defaultFontPixelWidth |
||||
|
||||
Component { |
||||
id: mainStatusInfo |
||||
|
||||
Rectangle { |
||||
width: mainLayout.width + (_margins * 2) |
||||
height: mainLayout.height + (_margins * 2) |
||||
radius: ScreenTools.defaultFontPixelHeight * 0.5 |
||||
color: qgcPal.window |
||||
border.color: qgcPal.text |
||||
|
||||
GridLayout { |
||||
id: mainLayout |
||||
anchors.margins: _margins |
||||
anchors.top: parent.top |
||||
anchors.left: parent.left |
||||
rowSpacing: ScreenTools.defaultFontPixelWidth / 2 |
||||
columnSpacing: rowSpacing |
||||
rows: _activeVehicle.sysStatusSensorInfo.sensorNames.length |
||||
flow: GridLayout.TopToBottom |
||||
|
||||
Repeater { |
||||
model: _activeVehicle.sysStatusSensorInfo.sensorNames |
||||
|
||||
QGCLabel { |
||||
text: modelData |
||||
} |
||||
} |
||||
|
||||
Repeater { |
||||
model: _activeVehicle.sysStatusSensorInfo.sensorStatus |
||||
|
||||
QGCLabel { |
||||
text: modelData |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
QGCLabel { |
||||
id: mainStatusLabel |
||||
text: mainStatusText() |
||||
font.pointSize: ScreenTools.largeFontPointSize |
||||
anchors.verticalCenter: parent.verticalCenter |
||||
|
||||
property string _commLostText: qsTr("Communication Lost") |
||||
property string _readyToFlyText: qsTr("Ready To Fly") |
||||
property string _notReadyToFlyText: qsTr("Not Ready") |
||||
property string _disconnectedText: qsTr("Disconnected") |
||||
property string _armedText: qsTr("Armed") |
||||
property string _flyingText: qsTr("Flying") |
||||
property string _landingText: qsTr("Landing") |
||||
|
||||
function mainStatusText() { |
||||
var statusText |
||||
if (_activeVehicle) { |
||||
if (_communicationLost) { |
||||
_mainStatusBGColor = "red" |
||||
return mainStatusLabel._commLostText |
||||
} |
||||
if (_activeVehicle.armed) { |
||||
if (_activeVehicle.flying) { |
||||
_mainStatusBGColor = qgcPal.brandingPurple |
||||
return mainStatusLabel._flyingText |
||||
} else if (_activeVehicle.landing) { |
||||
_mainStatusBGColor = qgcPal.brandingPurple |
||||
return mainStatusLabel._landingText |
||||
} else { |
||||
_mainStatusBGColor = qgcPal.brandingPurple |
||||
return mainStatusLabel._armedText |
||||
} |
||||
} else { |
||||
if (_activeVehicle.readyToFlyAvailable) { |
||||
if (_activeVehicle.readyToFly) { |
||||
_mainStatusBGColor = "green" |
||||
return mainStatusLabel._readyToFlyText |
||||
} else { |
||||
_mainStatusBGColor = "yellow" |
||||
return mainStatusLabel._notReadyToFlyText |
||||
} |
||||
} else { |
||||
// Best we can do is determine readiness based on AutoPilot component setup and health indicators from SYS_STATUS |
||||
if (_activeVehicle.allSensorsHealthy && _activeVehicle.autopilot.setupComplete) { |
||||
_mainStatusBGColor = "green" |
||||
return mainStatusLabel._readyToFlyText |
||||
} else { |
||||
_mainStatusBGColor = "yellow" |
||||
return mainStatusLabel._notReadyToFlyText |
||||
} |
||||
} |
||||
} |
||||
} else { |
||||
_mainStatusBGColor = qgcPal.brandingPurple |
||||
return mainStatusLabel._disconnectedText |
||||
} |
||||
} |
||||
} |
||||
|
||||
MouseArea { |
||||
anchors.fill: parent |
||||
enabled: _activeVehicle |
||||
onClicked: { |
||||
mainWindow.showPopUp(_root, mainStatusInfo) |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue