Commit fa54c814 authored by Don Gagne's avatar Don Gagne

Merge pull request #1392 from DonLakeFlyer/DisconnectReally

Disconnect really
parents bb3a268d 869fa09a
......@@ -264,7 +264,8 @@
<file alias="QGroundControl/Controls/arrow-down.png">src/QmlControls/arrow-down.png</file>
<file alias="octo_x.png">files/images/px4/airframes/octo_x.png</file>
<file alias="px4fmu_2.x.png">files/images/px4/boards/px4fmu_2.x.png</file>
<file alias="SetupViewButtons.qml">src/VehicleSetup/SetupViewButtons.qml</file>
<file alias="SetupViewButtonsConnected.qml">src/VehicleSetup/SetupViewButtonsConnected.qml</file>
<file alias="SetupViewButtonsDisconnected.qml">src/VehicleSetup/SetupViewButtonsDisconnected.qml</file>
<file alias="VehicleSummary.qml">src/VehicleSetup/VehicleSummary.qml</file>
<file alias="FirmwareUpgrade.qml">src/VehicleSetup/FirmwareUpgrade.qml</file>
<file alias="SafetyComponent.qml">src/AutoPilotPlugins/PX4/SafetyComponent.qml</file>
......
......@@ -28,7 +28,8 @@
AutoPilotPlugin::AutoPilotPlugin(UASInterface* uas, QObject* parent) :
QObject(parent),
_uas(uas)
_uas(uas),
_pluginReady(false)
{
Q_ASSERT(_uas);
}
......
......@@ -50,6 +50,8 @@ class AutoPilotPlugin : public QObject
public:
AutoPilotPlugin(UASInterface* uas, QObject* parent);
Q_PROPERTY(bool pluginReady READ pluginReady NOTIFY pluginReadyChanged)
Q_PROPERTY(QVariantList components READ components CONSTANT)
Q_PROPERTY(QUrl setupBackgroundImage READ setupBackgroundImage CONSTANT)
......@@ -71,23 +73,23 @@ public:
virtual const QVariantMap& parameters(void) = 0;
virtual QUrl setupBackgroundImage(void) = 0;
/// Returns true if the plugin is ready for use
virtual bool pluginIsReady(void) const = 0;
/// FIXME: Kind of hacky
static void clearStaticData(void);
UASInterface* uas(void) { return _uas; }
bool pluginReady(void) { return _pluginReady; }
signals:
/// Signalled when plugin is ready for use
void pluginReady(void);
void pluginReadyChanged(bool pluginReady);
protected:
/// All access to AutoPilotPugin objects is through getInstanceForAutoPilotPlugin
AutoPilotPlugin(QObject* parent = NULL) : QObject(parent) { }
UASInterface* _uas;
UASInterface* _uas;
bool _pluginReady;
};
#endif
......@@ -34,8 +34,7 @@ GenericAutoPilotPlugin::GenericAutoPilotPlugin(UASInterface* uas, QObject* paren
_parameterFacts = new GenericParameterFacts(uas, this);
Q_CHECK_PTR(_parameterFacts);
connect(_parameterFacts, &GenericParameterFacts::factsReady, this, &GenericAutoPilotPlugin::pluginReady);
connect(_parameterFacts, &GenericParameterFacts::factsReady, this, &GenericAutoPilotPlugin::_factsReady);
}
QList<AutoPilotPluginManager::FullMode_t> GenericAutoPilotPlugin::getModes(void)
......@@ -104,3 +103,9 @@ QUrl GenericAutoPilotPlugin::setupBackgroundImage(void)
{
return QUrl::fromUserInput("qrc:/qml/px4fmu_2.x.png");
}
void GenericAutoPilotPlugin::_factsReady(void)
{
_pluginReady = true;
emit pluginReadyChanged(_pluginReady);
}
......@@ -41,7 +41,6 @@ public:
GenericAutoPilotPlugin(UASInterface* uas, QObject* parent = NULL);
// Overrides from AutoPilotPlugin
virtual bool pluginIsReady(void) const { return _parameterFacts->factsAreReady(); }
virtual QUrl setupBackgroundImage(void);
virtual const QVariantList& components(void);
virtual const QVariantMap& parameters(void);
......@@ -50,6 +49,9 @@ public:
static QString getShortModeText(uint8_t baseMode, uint32_t customMode);
static void clearStaticData(void);
private slots:
void _factsReady(void);
private:
GenericParameterFacts* _parameterFacts;
};
......
......@@ -44,7 +44,7 @@ FlightModesComponentController::FlightModesComponentController(QObject* parent)
_autoPilotPlugin = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_uas);
Q_ASSERT(_autoPilotPlugin);
Q_ASSERT(_autoPilotPlugin->pluginIsReady());
Q_ASSERT(_autoPilotPlugin->pluginReady());
_initRcValues();
_validateConfiguration();
......
......@@ -189,11 +189,6 @@ void PX4AutoPilotPlugin::clearStaticData(void)
PX4ParameterFacts::clearStaticData();
}
bool PX4AutoPilotPlugin::pluginIsReady(void) const
{
return _parameterFacts->factsAreReady();
}
const QVariantList& PX4AutoPilotPlugin::components(void)
{
if (_components.count() == 0 && !_incorrectParameterVersion) {
......@@ -261,5 +256,6 @@ void PX4AutoPilotPlugin::_pluginReadyPreChecks(void)
}
}
emit pluginReady();
_pluginReady = true;
emit pluginReadyChanged(_pluginReady);
}
......@@ -50,7 +50,6 @@ public:
~PX4AutoPilotPlugin();
// Overrides from AutoPilotPlugin
virtual bool pluginIsReady(void) const;
virtual const QVariantList& components(void);
virtual const QVariantMap& parameters(void);
virtual QUrl setupBackgroundImage(void);
......
......@@ -38,7 +38,7 @@ FactBinder::FactBinder(void) :
_autopilotPlugin = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(uas);
Q_ASSERT(_autopilotPlugin);
Q_ASSERT(_autopilotPlugin->pluginIsReady());
Q_ASSERT(_autopilotPlugin->pluginReady());
}
QString FactBinder::name(void) const
......
......@@ -72,11 +72,11 @@ void FactSystemTestBase::_init(MAV_AUTOPILOT autopilot)
// Wait for the plugin to be ready
QSignalSpy spyPlugin(_plugin, SIGNAL(pluginReady()));
if (!_plugin->pluginIsReady()) {
QSignalSpy spyPlugin(_plugin, SIGNAL(pluginReadyChanged(bool)));
if (!_plugin->pluginReady()) {
QCOMPARE(spyPlugin.wait(5000), true);
}
Q_ASSERT(_plugin->pluginIsReady());
Q_ASSERT(_plugin->pluginReady());
}
void FactSystemTestBase::_cleanup(void)
......
......@@ -54,12 +54,11 @@ SetupView::SetupView(QWidget* parent) :
Q_UNUSED(fSucceeded);
Q_ASSERT(fSucceeded);
_ui->buttonHolder->setAutoPilot(NULL);
_ui->buttonHolder->setSource(QUrl::fromUserInput("qrc:/qml/SetupViewButtons.qml"));
qmlRegisterType<FirmwareUpgradeController>("QGroundControl.FirmwareUpgradeController", 1, 0, "FirmwareUpgradeController");
_ui->buttonHolder->rootContext()->setContextProperty("controller", this);
qmlRegisterType<FirmwareUpgradeController>("QGroundControl.FirmwareUpgradeController", 1, 0, "FirmwareUpgradeController");
_ui->buttonHolder->setAutoPilot(NULL);
_ui->buttonHolder->setSource(QUrl::fromUserInput("qrc:/qml/SetupViewButtonsDisconnected.qml"));
_setActiveUAS(UASManager::instance()->getActiveUAS());
}
......@@ -73,35 +72,37 @@ void SetupView::_setActiveUAS(UASInterface* uas)
{
if (_uasCurrent) {
Q_ASSERT(_autoPilotPlugin);
disconnect(_autoPilotPlugin, &AutoPilotPlugin::pluginReady, this, &SetupView::_pluginReady);
disconnect(_autoPilotPlugin, &AutoPilotPlugin::pluginReadyChanged, this, &SetupView::_pluginReadyChanged);
}
_autoPilotPlugin = NULL;
_ui->buttonHolder->setAutoPilot(NULL);
firmwareButtonClicked();
QObject* button = _ui->buttonHolder->rootObject()->findChild<QObject*>("firmwareButton");
Q_ASSERT(button);
button->setProperty("checked", true);
_pluginReadyChanged(false);
_uasCurrent = uas;
if (_uasCurrent) {
_autoPilotPlugin = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_uasCurrent);
connect(_autoPilotPlugin, &AutoPilotPlugin::pluginReady, this, &SetupView::_pluginReady);
if (_autoPilotPlugin->pluginIsReady()) {
_pluginReady();
}
_pluginReadyChanged(_autoPilotPlugin->pluginReady());
connect(_autoPilotPlugin, &AutoPilotPlugin::pluginReadyChanged, this, &SetupView::_pluginReadyChanged);
}
}
void SetupView::_pluginReady(void)
void SetupView::_pluginReadyChanged(bool pluginReady)
{
_ui->buttonHolder->setAutoPilot(_autoPilotPlugin);
summaryButtonClicked();
QObject* button = _ui->buttonHolder->rootObject()->findChild<QObject*>("summaryButton");
Q_ASSERT(button);
button->setProperty("checked", true);
if (pluginReady) {
_ui->buttonHolder->setAutoPilot(_autoPilotPlugin);
_ui->buttonHolder->setSource(QUrl::fromUserInput("qrc:/qml/SetupViewButtonsConnected.qml"));
summaryButtonClicked();
QObject* button = _ui->buttonHolder->rootObject()->findChild<QObject*>("summaryButton");
Q_ASSERT(button);
button->setProperty("checked", true);
} else {
_ui->buttonHolder->setSource(QUrl::fromUserInput("qrc:/qml/SetupViewButtonsDisconnected.qml"));
_ui->buttonHolder->setAutoPilot(NULL);
firmwareButtonClicked();
QObject* button = _ui->buttonHolder->rootObject()->findChild<QObject*>("firmwareButton");
Q_ASSERT(button);
button->setProperty("checked", true);
}
}
void SetupView::_changeSetupWidget(QWidget* newWidget)
......
......@@ -54,7 +54,7 @@ public:
private slots:
void _setActiveUAS(UASInterface* uas);
void _pluginReady(void);
void _pluginReadyChanged(bool pluginReady);
private:
void _changeSetupWidget(QWidget* newWidget);
......
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QtGraphicalEffects 1.0
import QGroundControl.FactSystem 1.0
import QGroundControl.Palette 1.0
import QGroundControl.Controls 1.0
Rectangle {
id: topLevel
QGCPalette { id: palette; colorGroupEnabled: true }
color: palette.window
ExclusiveGroup { id: setupButtonGroup }
Component {
id: disconnectedButtons
Column {
anchors.fill: parent
SubMenuButton {
id: firmwareButton; objectName: "firmwareButton"
width: parent.width
text: "FIRMWARE"
imageResource: "FirmwareUpgradeIcon.png"
setupIndicator: false
exclusiveGroup: setupButtonGroup
onClicked: controller.firmwareButtonClicked()
}
Item { width: parent.width; height: 10 } // spacer
QGCLabel {
width: parent.width
text: "Full setup options are only available when connected to vehicle and full parameter list has completed downloading."
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
}
}
}
Component {
id: connectedButtons
Column {
anchors.fill: parent
SubMenuButton {
id: summaryButton; objectName: "summaryButton"
width: parent.width
text: "SUMMARY"
imageResource: "VehicleSummaryIcon.png"
setupIndicator: false
exclusiveGroup: setupButtonGroup
onClicked: controller.summaryButtonClicked()
}
SubMenuButton {
id: firmwareButton; objectName: "firmwareButton"
width: parent.width
text: "FIRMWARE"
imageResource: "FirmwareUpgradeIcon.png"
setupIndicator: false
exclusiveGroup: setupButtonGroup
onClicked: controller.firmwareButtonClicked()
}
Repeater {
model: autopilot.components
SubMenuButton {
width: parent.width
text: modelData.name.toUpperCase()
imageResource: modelData.iconResource
setupComplete: modelData.setupComplete
exclusiveGroup: setupButtonGroup
onClicked: controller.setupButtonClicked(modelData)
}
}
SubMenuButton {
width: parent.width
text: "PARAMETERS"
setupIndicator: false
exclusiveGroup: setupButtonGroup
onClicked: controller.parametersButtonClicked()
}
}
}
Loader {
anchors.fill: parent
sourceComponent: autopilot ? connectedButtons : disconnectedButtons
}
}
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QtGraphicalEffects 1.0
import QGroundControl.FactSystem 1.0
import QGroundControl.Palette 1.0
import QGroundControl.Controls 1.0
Rectangle {
id: topLevel
QGCPalette { id: palette; colorGroupEnabled: true }
color: palette.window
ExclusiveGroup { id: setupButtonGroup }
Column {
anchors.fill: parent
SubMenuButton {
id: summaryButton; objectName: "summaryButton"
width: parent.width
text: "SUMMARY"
imageResource: "VehicleSummaryIcon.png"
setupIndicator: false
exclusiveGroup: setupButtonGroup
onClicked: controller.summaryButtonClicked()
}
SubMenuButton {
id: firmwareButton; objectName: "firmwareButton"
width: parent.width
text: "FIRMWARE"
imageResource: "FirmwareUpgradeIcon.png"
setupIndicator: false
exclusiveGroup: setupButtonGroup
onClicked: controller.firmwareButtonClicked()
}
Repeater {
model: autopilot ? autopilot.components : 0
SubMenuButton {
width: parent.width
text: modelData.name.toUpperCase()
imageResource: modelData.iconResource
setupComplete: modelData.setupComplete
exclusiveGroup: setupButtonGroup
onClicked: controller.setupButtonClicked(modelData)
}
}
SubMenuButton {
width: parent.width
text: "PARAMETERS"
setupIndicator: false
exclusiveGroup: setupButtonGroup
onClicked: controller.parametersButtonClicked()
}
}
}
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QtGraphicalEffects 1.0
import QGroundControl.FactSystem 1.0
import QGroundControl.Palette 1.0
import QGroundControl.Controls 1.0
Rectangle {
id: topLevel
QGCPalette { id: palette; colorGroupEnabled: true }
color: palette.window
ExclusiveGroup { id: setupButtonGroup }
Column {
anchors.fill: parent
SubMenuButton {
id: firmwareButton; objectName: "firmwareButton"
width: parent.width
text: "FIRMWARE"
imageResource: "FirmwareUpgradeIcon.png"
setupIndicator: false
exclusiveGroup: setupButtonGroup
onClicked: controller.firmwareButtonClicked()
}
Item { width: parent.width; height: 10 } // spacer
QGCLabel {
width: parent.width
text: "Full setup options are only available when connected to vehicle and full parameter list has completed downloading."
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
}
}
}
......@@ -83,7 +83,6 @@ public:
virtual const QString& getShortMode() const { Q_ASSERT(false); return _bogusString; };
virtual QString getShortModeTextFor(uint8_t base_mode, uint32_t custom_mode) const { Q_UNUSED(base_mode); Q_UNUSED(custom_mode); Q_ASSERT(false); return _bogusStaticString; };
virtual quint64 getUptime() const { Q_ASSERT(false); return 0; };
virtual int getCommunicationStatus() const { Q_ASSERT(false); return 0; };
virtual double getLocalX() const { Q_ASSERT(false); return std::numeric_limits<double>::quiet_NaN(); };
virtual double getLocalY() const { Q_ASSERT(false); return std::numeric_limits<double>::quiet_NaN(); };
virtual double getLocalZ() const { Q_ASSERT(false); return std::numeric_limits<double>::quiet_NaN(); };
......
......@@ -71,12 +71,6 @@ void UASUnitTest::getUpTime_test()
delete uas2;
}
void UASUnitTest::getCommunicationStatus_test()
{
// Verify that upon construction the Comm status is disconnected
QCOMPARE(_uas->getCommunicationStatus(), static_cast<int>(UASInterface::COMM_DISCONNECTED));
}
void UASUnitTest::filterVoltage_test()
{
float verificar=_uas->filterVoltage(0.4f);
......
......@@ -27,7 +27,6 @@ private slots:
void getUASID_test(void);
void getUASName_test(void);
void getUpTime_test(void);
void getCommunicationStatus_test(void);
void filterVoltage_test(void);
void getAutopilotType_test(void);
void setAutopilotType_test(void);
......
......@@ -50,7 +50,6 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(),
uasId(id),
unknownPackets(),
mavlink(protocol),
commStatus(COMM_DISCONNECTED),
receiveDropRate(0),
sendDropRate(0),
......@@ -1911,11 +1910,6 @@ quint64 UAS::getUptime() const
}
}
int UAS::getCommunicationStatus() const
{
return commStatus;
}
void UAS::writeParametersToStorage()
{
mavlink_message_t msg;
......@@ -3247,23 +3241,26 @@ void UAS::addLink(LinkInterface* link)
{
_links.append(LinkManager::instance()->sharedPointerForLink(link));
qCDebug(UASLog) << "addLink:" << QString("%1").arg((ulong)link, 0, 16);
connect(link, SIGNAL(destroyed(QObject*)), this, SLOT(removeLink(QObject*)));
connect(LinkManager::instance(), &LinkManager::linkDisconnected, this, &UAS::_linkDisconnected);
}
}
void UAS::removeLink(QObject* object)
void UAS::_linkDisconnected(LinkInterface* link)
{
qCDebug(UASLog) << "removeLink:" << QString("%1").arg((ulong)object, 0, 16);
qCDebug(UASLog) << "_linkDisconnected:" << link->getName();
qCDebug(UASLog) << "link count:" << _links.count();
LinkInterface* link = dynamic_cast<LinkInterface*>(object);
for (int i=0; i<_links.count(); i++) {
if (_links[i].data() == link) {
_links.removeAt(i);
break;
}
}
if (_links.count() == 0) {
// Remove the UAS when all links to it close
UASManager::instance()->removeUAS(this);
}
}
/**
......
......@@ -87,8 +87,6 @@ public:
/** @brief The time interval the robot is switched on */
quint64 getUptime() const;
/** @brief Get the status flag for the communication */
int getCommunicationStatus() const;
/** @brief Add one measurement and get low-passed voltage */
float filterVoltage(float value) const;
/** @brief Get the links associated with this robot */
......@@ -348,7 +346,6 @@ protected: //COMMENTS FOR TEST UNIT
QList<int> unknownPackets; ///< Packet IDs which are unknown and have been received
MAVLinkProtocol* mavlink; ///< Reference to the MAVLink instance
CommStatus commStatus; ///< Communication status
float receiveDropRate; ///< Percentage of packets that were dropped on the MAV's receiving link (from GCS and other MAVs)
float sendDropRate; ///< Percentage of packets that were not received from the MAV by the GCS
quint64 lastHeartbeat; ///< Time of the last heartbeat message
......@@ -800,8 +797,6 @@ public slots:
/** @brief Add a link associated with this robot */
void addLink(LinkInterface* link);
/** @brief Remove a link associated with this robot */
void removeLink(QObject* object);
/** @brief Receive a message from one of the communication links. */
virtual void receiveMessage(LinkInterface* link, mavlink_message_t message);
......@@ -953,6 +948,9 @@ protected slots:
/** @brief Read settings from disk */
void readSettings();
private slots:
void _linkDisconnected(LinkInterface* link);
private:
bool _containsLink(LinkInterface* link);
};
......
......@@ -108,8 +108,6 @@ public:
virtual int getUASID() const = 0; ///< Get the ID of the connected UAS
/** @brief The time interval the robot is switched on **/
virtual quint64 getUptime() const = 0;
/** @brief Get the status flag for the communication **/
virtual int getCommunicationStatus() const = 0;
virtual double getLocalX() const = 0;
virtual double getLocalY() const = 0;
......@@ -146,21 +144,6 @@ public:
/** @brief Send a message over all links this UAS can be reached with (!= all links) */
virtual void sendMessage(mavlink_message_t message) = 0;
/* COMMUNICATION FLAGS */
enum CommStatus {
/** Unit is disconnected, no failure state reached so far **/
COMM_DISCONNECTED = 0,
/** The communication is established **/
COMM_CONNECTING = 1,
/** The communication link is up **/
COMM_CONNECTED = 2,
/** The connection is closed **/
COMM_DISCONNECTING = 3,
COMM_FAIL = 4,
COMM_TIMEDOUT = 5///< Communication link failed
};
enum Airframe {
QGC_AIRFRAME_GENERIC = 0,
QGC_AIRFRAME_EASYSTAR,
......@@ -471,8 +454,6 @@ signals:
void armingChanged(int sysId, QString armingState);
/** @brief A command has been issued **/
void commandSent(int command);
/** @brief The connection status has changed **/
void connectionChanged(CommStatus connectionFlag);
/** @brief The robot is connecting **/
void connecting();
/** @brief The robot is connected **/
......
......@@ -181,7 +181,7 @@ void DebugConsole::addLink(LinkInterface* link)
// Register for name changes
connect(link, SIGNAL(nameChanged(QString)), this, SLOT(updateLinkName(QString)), Qt::UniqueConnection);
connect(LinkManager::instance(), &LinkManager::linkDeleted, this, &DebugConsole::removeLink, Qt::UniqueConnection);
connect(LinkManager::instance(), &LinkManager::linkDisconnected, this, &DebugConsole::removeLink, Qt::UniqueConnection);
}
void DebugConsole::removeLink(LinkInterface* const linkInterface)
......
......@@ -219,10 +219,11 @@ void PrimaryFlightDisplay::forgetUAS(UASInterface* uas)
disconnect(this->uas, SIGNAL(attitudeChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateAttitude(UASInterface*, double, double, double, quint64)));
disconnect(this->uas, SIGNAL(attitudeChanged(UASInterface*,int,double,double,double,quint64)), this, SLOT(updateAttitude(UASInterface*,int,double, double, double, quint64)));
disconnect(this->uas, SIGNAL(speedChanged(UASInterface*, double, double, quint64)), this, SLOT(updateSpeed(UASInterface*, double, double, quint64)));
disconnect(this->uas, SIGNAL(altitudeChanged(UASInterface*, double, double, double, double, quint64)), this, SLOT(updateAltitude(UASInterface*, double, double, double, quint64)));
disconnect(this->uas, SIGNAL(altitudeChanged(UASInterface*, double, double, double, double, quint64)), this, SLOT(updateAltitude(UASInterface*, double, double, double, double, quint64)));
disconnect(this->uas, SIGNAL(navigationControllerErrorsChanged(UASInterface*, double, double, double)), this, SLOT(updateNavigationControllerErrors(UASInterface*, double, double, double)));
disconnect(this->uas, &UASInterface::NavigationControllerDataChanged, this, &PrimaryFlightDisplay::UpdateNavigationControllerData);
}
this->uas = NULL;
}
/**
......
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