diff --git a/.travis.yml b/.travis.yml index 1f16c4ad409655bf9270862bb511fbf0be126faa..c05108adae188bd83b86ee0f6bf444169f022235 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,20 +13,20 @@ matrix: include: - os: linux env: SPEC=linux-g++-64 CONFIG=debug - sudo: true + sudo: false - os: linux env: SPEC=linux-g++-64 CONFIG=installer - sudo: true + sudo: false - os: osx osx_image: xcode7 env: SPEC=macx-clang CONFIG=debug - os: osx osx_image: xcode7 env: SPEC=macx-clang CONFIG=installer - - os: android - language: android - env: SPEC=android-g++ CONFIG=debug - sudo: false +# - os: android +# language: android +# env: SPEC=android-g++ CONFIG=debug +# sudo: false - os: android language: android env: SPEC=android-g++ CONFIG=installer @@ -38,8 +38,25 @@ android: - build-tools-21.1.1 - android-21 +addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - ccache + - espeak + - g++-4.8 + - gcc-4.8 + - libc6-i386 + - libespeak-dev + - libopenscenegraph-dev + - libsdl1.2-dev + - libudev-dev + cache: - - apt + directories: + - $HOME/.ccache + before_install: - cd ${TRAVIS_BUILD_DIR} && git fetch --unshallow && git fetch --tags @@ -49,10 +66,7 @@ before_install: install: - if [ "${TRAVIS_OS_NAME}" = "linux" ]; then - sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test - && sudo apt-get -qq update - && sudo apt-get -qq install g++-4.8 espeak libespeak-dev libopenscenegraph-dev libsdl1.2-dev libudev-dev - && wget https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/Qt5.5.1-linux.tar.bz2 + wget https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/Qt5.5.1-linux.tar.bz2 && tar jxf Qt5.5.1-linux.tar.bz2 -C /tmp && export PATH=/tmp/Qt/5.5/gcc_64/bin:$PATH && export CXX="g++-4.8" @@ -80,6 +94,13 @@ install: before_script: +# setup ccache + - mkdir -p ~/bin + - ln -s /usr/bin/ccache ~/bin/g++ + - ln -s /usr/bin/ccache ~/bin/g++-4.8 + - ln -s /usr/bin/ccache ~/bin/gcc + - ln -s /usr/bin/ccache ~/bin/gcc-4.8 + - export PATH=~/bin:$PATH - if [[ "${TRAVIS_OS_NAME}" = "android" && "${CONFIG}" = "installer" && -z ${ANDROID_STOREPASS} ]]; then export CONFIG=release; fi - qmake -r qgroundcontrol.pro CONFIG+=${CONFIG} CONFIG+=WarningsAsErrorsOn -spec ${SPEC} diff --git a/QGCApplication.pro b/QGCApplication.pro index 3333a762abca306413a9698149f852da026978fd..fd7169337d6905499d64fabdb885c3637af6830c 100644 --- a/QGCApplication.pro +++ b/QGCApplication.pro @@ -507,8 +507,8 @@ INCLUDEPATH += \ HEADERS+= \ src/AutoPilotPlugins/AutoPilotPlugin.h \ src/AutoPilotPlugins/AutoPilotPluginManager.h \ + src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h \ src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.h \ - src/AutoPilotPlugins/Generic/GenericParameterFacts.h \ src/AutoPilotPlugins/PX4/AirframeComponent.h \ src/AutoPilotPlugins/PX4/AirframeComponentAirframes.h \ src/AutoPilotPlugins/PX4/AirframeComponentController.h \ @@ -518,7 +518,6 @@ HEADERS+= \ src/AutoPilotPlugins/PX4/PowerComponentController.h \ src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h \ src/AutoPilotPlugins/PX4/PX4Component.h \ - src/AutoPilotPlugins/PX4/PX4ParameterLoader.h \ src/AutoPilotPlugins/PX4/RadioComponent.h \ src/AutoPilotPlugins/PX4/RadioComponentController.h \ src/AutoPilotPlugins/PX4/SafetyComponent.h \ @@ -527,11 +526,14 @@ HEADERS+= \ src/FirmwarePlugin/FirmwarePluginManager.h \ src/FirmwarePlugin/FirmwarePlugin.h \ src/FirmwarePlugin/APM/APMFirmwarePlugin.h \ + src/FirmwarePlugin/APM/APMParameterLoader.h \ src/FirmwarePlugin/APM/ArduCopterFirmwarePlugin.h \ src/FirmwarePlugin/APM/ArduPlaneFirmwarePlugin.h \ src/FirmwarePlugin/APM/ArduRoverFirmwarePlugin.h \ src/FirmwarePlugin/Generic/GenericFirmwarePlugin.h \ + src/FirmwarePlugin/Generic/GenericParameterLoader.h \ src/FirmwarePlugin/PX4/PX4FirmwarePlugin.h \ + src/FirmwarePlugin/PX4/PX4ParameterLoader.h \ src/Vehicle/MultiVehicleManager.h \ src/Vehicle/Vehicle.h \ src/VehicleSetup/VehicleComponent.h \ @@ -548,8 +550,8 @@ HEADERS += \ SOURCES += \ src/AutoPilotPlugins/AutoPilotPlugin.cc \ src/AutoPilotPlugins/AutoPilotPluginManager.cc \ + src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc \ src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.cc \ - src/AutoPilotPlugins/Generic/GenericParameterFacts.cc \ src/AutoPilotPlugins/PX4/AirframeComponent.cc \ src/AutoPilotPlugins/PX4/AirframeComponentAirframes.cc \ src/AutoPilotPlugins/PX4/AirframeComponentController.cc \ @@ -559,19 +561,21 @@ SOURCES += \ src/AutoPilotPlugins/PX4/PowerComponentController.cc \ src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc \ src/AutoPilotPlugins/PX4/PX4Component.cc \ - src/AutoPilotPlugins/PX4/PX4ParameterLoader.cc \ src/AutoPilotPlugins/PX4/RadioComponent.cc \ src/AutoPilotPlugins/PX4/RadioComponentController.cc \ src/AutoPilotPlugins/PX4/SafetyComponent.cc \ src/AutoPilotPlugins/PX4/SensorsComponent.cc \ src/AutoPilotPlugins/PX4/SensorsComponentController.cc \ src/FirmwarePlugin/APM/APMFirmwarePlugin.cc \ + src/FirmwarePlugin/APM/APMParameterLoader.cc \ src/FirmwarePlugin/APM/ArduCopterFirmwarePlugin.cc \ src/FirmwarePlugin/APM/ArduPlaneFirmwarePlugin.cc \ src/FirmwarePlugin/APM/ArduRoverFirmwarePlugin.cc \ src/FirmwarePlugin/FirmwarePluginManager.cc \ src/FirmwarePlugin/Generic/GenericFirmwarePlugin.cc \ + src/FirmwarePlugin/Generic/GenericParameterLoader.cc \ src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc \ + src/FirmwarePlugin/PX4/PX4ParameterLoader.cc \ src/Vehicle/MultiVehicleManager.cc \ src/Vehicle/Vehicle.cc \ src/VehicleSetup/VehicleComponent.cc \ diff --git a/QGCCommon.pri b/QGCCommon.pri index 975040af32d39bb2c7ce33218eaf675fe48ee825..f67098d4b0e1127e79b77333c65f0abf69f3a77c 100644 --- a/QGCCommon.pri +++ b/QGCCommon.pri @@ -73,6 +73,7 @@ MobileBuild { exists ($$PWD/.git) { GIT_DESCRIBE = $$system(git --git-dir $$PWD/.git --work-tree $$PWD describe --always --tags) + message(QGroundControl version $${GIT_DESCRIBE}) } else { GIT_DESCRIBE = None } diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index d3f51b430ffe221bd6ca668b9d153a1034ab98b5..6b503613c92fc568dd42382d089ed71f1baf41cc 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index ba89c959fc476b18d30a67fa0320e404e4391b5e..6928aadf96b2ef13c0e8365a3b6c38315f2aa07e 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -30,6 +30,3 @@ message(Qt version $$[QT_VERSION]) error("Unsupported Qt version, 5.4+ is required") } -message(QGroundControl version $${GIT_DESCRIBE}) -git_ver.commands = $$QGC_GIT_VER -QMAKE_EXTRA_TARGETS += git_ver diff --git a/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc b/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc new file mode 100644 index 0000000000000000000000000000000000000000..0eb799c7c0e6937360cf6efbaf89093284006591 --- /dev/null +++ b/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc @@ -0,0 +1,79 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2015 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +#include "APMAutoPilotPlugin.h" +#include "AutoPilotPluginManager.h" +#include "QGCMessageBox.h" +#include "UAS.h" +#include "FirmwarePlugin/APM/APMParameterLoader.h" // FIXME: Hack +#include "FirmwarePlugin/APM/APMFirmwarePlugin.h" // FIXME: Hack + +/// This is the AutoPilotPlugin implementatin for the MAV_AUTOPILOT_ARDUPILOT type. +APMAutoPilotPlugin::APMAutoPilotPlugin(Vehicle* vehicle, QObject* parent) : + AutoPilotPlugin(vehicle, parent), + _incorrectParameterVersion(false) +{ + Q_ASSERT(vehicle); + + // This kicks off parameter load + _firmwarePlugin->getParameterLoader(this, vehicle); +} + +APMAutoPilotPlugin::~APMAutoPilotPlugin() +{ + +} + +void APMAutoPilotPlugin::clearStaticData(void) +{ + APMParameterLoader::clearStaticData(); +} + +const QVariantList& APMAutoPilotPlugin::vehicleComponents(void) +{ + static const QVariantList emptyList; + + return emptyList; +} + +/// This will perform various checks prior to signalling that the plug in ready +void APMAutoPilotPlugin::_parametersReadyPreChecks(bool missingParameters) +{ +#if 0 + I believe APM has parameter version stamp, we should check that + + // Check for older parameter version set + // FIXME: Firmware is moving to version stamp parameter set. Once that is complete the version stamp + // should be used instead. + if (parameterExists(FactSystem::defaultComponentId, "SENS_GYRO_XOFF")) { + _incorrectParameterVersion = true; + QGCMessageBox::warning("Setup", "This version of GroundControl can only perform vehicle setup on a newer version of firmware. " + "Please perform a Firmware Upgrade if you wish to use Vehicle Setup."); + } +#endif + + _parametersReady = true; + _missingParameters = missingParameters; + emit missingParametersChanged(_missingParameters); + emit parametersReadyChanged(_parametersReady); +} diff --git a/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h b/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h new file mode 100644 index 0000000000000000000000000000000000000000..4ebacf88efc4c8d31e44cc6b139ecbee7909baff --- /dev/null +++ b/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h @@ -0,0 +1,52 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2015 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +#ifndef APMAutoPilotPlugin_H +#define APMAutoPilotPlugin_H + +#include "AutoPilotPlugin.h" +#include "Vehicle.h" + +/// This is the APM specific implementation of the AutoPilot class. +class APMAutoPilotPlugin : public AutoPilotPlugin +{ + Q_OBJECT + +public: + APMAutoPilotPlugin(Vehicle* vehicle, QObject* parent); + ~APMAutoPilotPlugin(); + + // Overrides from AutoPilotPlugin + virtual const QVariantList& vehicleComponents(void); + + static void clearStaticData(void); + +public slots: + // FIXME: This is public until we restructure AutoPilotPlugin/FirmwarePlugin/Vehicle + void _parametersReadyPreChecks(bool missingParameters); + +private: + bool _incorrectParameterVersion; ///< true: parameter version incorrect, setup not allowed +}; + +#endif diff --git a/src/AutoPilotPlugins/AutoPilotPlugin.cc b/src/AutoPilotPlugins/AutoPilotPlugin.cc index 1613dd2acbb7c2f1790e526587e3e013aa02cb87..eb2b9c723558145ba97a6c2a8c9999bcae7624c4 100644 --- a/src/AutoPilotPlugins/AutoPilotPlugin.cc +++ b/src/AutoPilotPlugins/AutoPilotPlugin.cc @@ -30,10 +30,12 @@ #include "MainWindow.h" #include "ParameterLoader.h" #include "UAS.h" +#include "FirmwarePlugin.h" AutoPilotPlugin::AutoPilotPlugin(Vehicle* vehicle, QObject* parent) : QObject(parent) , _vehicle(vehicle) + , _firmwarePlugin(vehicle->firmwarePlugin()) , _parametersReady(false) , _missingParameters(false) , _setupComplete(false) @@ -107,34 +109,34 @@ void AutoPilotPlugin::resetAllParametersToDefaults(void) void AutoPilotPlugin::refreshAllParameters(void) { - _getParameterLoader()->refreshAllParameters(); + _firmwarePlugin->getParameterLoader(this, _vehicle)->refreshAllParameters(); } void AutoPilotPlugin::refreshParameter(int componentId, const QString& name) { - _getParameterLoader()->refreshParameter(componentId, name); + _firmwarePlugin->getParameterLoader(this, _vehicle)->refreshParameter(componentId, name); } void AutoPilotPlugin::refreshParametersPrefix(int componentId, const QString& namePrefix) { - _getParameterLoader()->refreshParametersPrefix(componentId, namePrefix); + _firmwarePlugin->getParameterLoader(this, _vehicle)->refreshParametersPrefix(componentId, namePrefix); } bool AutoPilotPlugin::parameterExists(int componentId, const QString& name) { - return _getParameterLoader()->parameterExists(componentId, name); + return _firmwarePlugin->getParameterLoader(this, _vehicle)->parameterExists(componentId, name); } Fact* AutoPilotPlugin::getParameterFact(int componentId, const QString& name) { - return _getParameterLoader()->getFact(componentId, name); + return _firmwarePlugin->getParameterLoader(this, _vehicle)->getFact(componentId, name); } bool AutoPilotPlugin::factExists(FactSystem::Provider_t provider, int componentId, const QString& name) { switch (provider) { case FactSystem::ParameterProvider: - return _getParameterLoader()->parameterExists(componentId, name); + return _firmwarePlugin->getParameterLoader(this, _vehicle)->parameterExists(componentId, name); // Other providers will go here once they come online } @@ -147,7 +149,7 @@ Fact* AutoPilotPlugin::getFact(FactSystem::Provider_t provider, int componentId, { switch (provider) { case FactSystem::ParameterProvider: - return _getParameterLoader()->getFact(componentId, name); + return _firmwarePlugin->getParameterLoader(this, _vehicle)->getFact(componentId, name); // Other providers will go here once they come online } @@ -158,20 +160,20 @@ Fact* AutoPilotPlugin::getFact(FactSystem::Provider_t provider, int componentId, QStringList AutoPilotPlugin::parameterNames(int componentId) { - return _getParameterLoader()->parameterNames(componentId); + return _firmwarePlugin->getParameterLoader(this, _vehicle)->parameterNames(componentId); } const QMap >& AutoPilotPlugin::getGroupMap(void) { - return _getParameterLoader()->getGroupMap(); + return _firmwarePlugin->getParameterLoader(this, _vehicle)->getGroupMap(); } void AutoPilotPlugin::writeParametersToStream(QTextStream &stream) { - _getParameterLoader()->writeParametersToStream(stream, _vehicle->uas()->getUASName()); + _firmwarePlugin->getParameterLoader(this, _vehicle)->writeParametersToStream(stream, _vehicle->uas()->getUASName()); } QString AutoPilotPlugin::readParametersFromStream(QTextStream &stream) { - return _getParameterLoader()->readParametersFromStream(stream); + return _firmwarePlugin->getParameterLoader(this, _vehicle)->readParametersFromStream(stream); } diff --git a/src/AutoPilotPlugins/AutoPilotPlugin.h b/src/AutoPilotPlugins/AutoPilotPlugin.h index 6fb88039a8b9c2b543c11088269c049bcd3132e1..654d5aa2787761af86c8b29e4bc37f05e3d533ea 100644 --- a/src/AutoPilotPlugins/AutoPilotPlugin.h +++ b/src/AutoPilotPlugins/AutoPilotPlugin.h @@ -38,6 +38,7 @@ class ParameterLoader; class Vehicle; +class FirmwarePlugin; /// This is the base class for AutoPilot plugins /// @@ -132,20 +133,18 @@ protected: /// All access to AutoPilotPugin objects is through getInstanceForAutoPilotPlugin AutoPilotPlugin(QObject* parent = NULL) : QObject(parent) { } - /// Returns the ParameterLoader - virtual ParameterLoader* _getParameterLoader(void) = 0; - - Vehicle* _vehicle; - bool _parametersReady; - bool _missingParameters; - bool _setupComplete; + Vehicle* _vehicle; + FirmwarePlugin* _firmwarePlugin; + bool _parametersReady; + bool _missingParameters; + bool _setupComplete; private slots: void _uasDisconnected(void); void _parametersReadyChanged(bool parametersReady); private: - void _recalcSetupComplete(void); + void _recalcSetupComplete(void); }; #endif diff --git a/src/AutoPilotPlugins/AutoPilotPluginManager.cc b/src/AutoPilotPlugins/AutoPilotPluginManager.cc index 245d0641b8d1ea25eba4e71830ebcd4009378b5a..88435dfc8588c30d9730fea3199009ef27a0de86 100644 --- a/src/AutoPilotPlugins/AutoPilotPluginManager.cc +++ b/src/AutoPilotPlugins/AutoPilotPluginManager.cc @@ -26,6 +26,7 @@ #include "AutoPilotPluginManager.h" #include "PX4/PX4AutoPilotPlugin.h" +#include "APM/APMAutoPilotPlugin.h" #include "Generic/GenericAutoPilotPlugin.h" IMPLEMENT_QGC_SINGLETON(AutoPilotPluginManager, AutoPilotPluginManager) @@ -44,9 +45,12 @@ AutoPilotPluginManager::~AutoPilotPluginManager() AutoPilotPlugin* AutoPilotPluginManager::newAutopilotPluginForVehicle(Vehicle* vehicle) { - if (vehicle->firmwareType() == MAV_AUTOPILOT_PX4) { - return new PX4AutoPilotPlugin(vehicle, vehicle); - } else { - return new GenericAutoPilotPlugin(vehicle, vehicle); + switch (vehicle->firmwareType()) { + case MAV_AUTOPILOT_PX4: + return new PX4AutoPilotPlugin(vehicle, vehicle); + case MAV_AUTOPILOT_ARDUPILOTMEGA: + return new APMAutoPilotPlugin(vehicle, vehicle); + default: + return new GenericAutoPilotPlugin(vehicle, vehicle); } } diff --git a/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.cc b/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.cc index 8dee503983cedec5a940b38fd95b9489a84ab2c1..21ddf364e2b799b294b06bea79afed7500df774f 100644 --- a/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.cc +++ b/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.cc @@ -25,17 +25,15 @@ /// @author Don Gagne #include "GenericAutoPilotPlugin.h" +#include "FirmwarePlugin/Generic/GenericFirmwarePlugin.h" // FIXME: Hack GenericAutoPilotPlugin::GenericAutoPilotPlugin(Vehicle* vehicle, QObject* parent) : AutoPilotPlugin(vehicle, parent) { Q_ASSERT(vehicle); - - _parameterFacts = new GenericParameterFacts(this, vehicle, this); - Q_CHECK_PTR(_parameterFacts); - - connect(_parameterFacts, &GenericParameterFacts::parametersReady, this, &GenericAutoPilotPlugin::_parametersReadySlot); - connect(_parameterFacts, &GenericParameterFacts::parameterListProgress, this, &GenericAutoPilotPlugin::parameterListProgress); + + // This kicks off parameter load + _firmwarePlugin->getParameterLoader(this, vehicle); } void GenericAutoPilotPlugin::clearStaticData(void) @@ -50,7 +48,8 @@ const QVariantList& GenericAutoPilotPlugin::vehicleComponents(void) return emptyList; } -void GenericAutoPilotPlugin::_parametersReadySlot(bool missingParameters) +/// This will perform various checks prior to signalling that the plug in ready +void GenericAutoPilotPlugin::_parametersReadyPreChecks(bool missingParameters) { _parametersReady = true; _missingParameters = missingParameters; diff --git a/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.h b/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.h index 827a68ee9923d193b58a2ee9795b17d0a89b7416..161280c849ec25c2f3b06dbf36db0ce104bb18a1 100644 --- a/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.h +++ b/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.h @@ -25,7 +25,6 @@ #define GENERICAUTOPILOT_H #include "AutoPilotPlugin.h" -#include "GenericParameterFacts.h" /// @file /// @brief This is the generic implementation of the AutoPilotPlugin class for mavs @@ -44,14 +43,9 @@ public: static void clearStaticData(void); -private slots: - void _parametersReadySlot(bool missingParameters); - -private: - // Overrides from AutoPilotPlugin - virtual ParameterLoader* _getParameterLoader(void) { return _parameterFacts; } - - GenericParameterFacts* _parameterFacts; +public slots: + // FIXME: This is public until we restructure AutoPilotPlugin/FirmwarePlugin/Vehicle + void _parametersReadyPreChecks(bool missingParameters); }; #endif diff --git a/src/AutoPilotPlugins/PX4/FlightModesComponent.qml b/src/AutoPilotPlugins/PX4/FlightModesComponent.qml index 5178b1ca699c1c49bbad8301f4f6f66cc6e19cc1..d34f6ea2d0a5b13628c7b64bcac0b7beb4fee4f7 100644 --- a/src/AutoPilotPlugins/PX4/FlightModesComponent.qml +++ b/src/AutoPilotPlugins/PX4/FlightModesComponent.qml @@ -260,7 +260,7 @@ QGCView { thresholdValue: controller.manualModeThreshold thresholdDragEnabled: false - onModeChannelIndexChanged: controller.manualModeChannelIndex = modeChannelIndex + onModeChannelIndexSelected: controller.manualModeChannelIndex = index } ModeSwitchDisplay { @@ -308,7 +308,7 @@ QGCView { thresholdValue: controller.acroModeThreshold thresholdDragEnabled: true - onModeChannelIndexChanged: controller.acroModeChannelIndex = modeChannelIndex + onModeChannelIndexSelected: controller.acroModeChannelIndex = index onThresholdValueChanged: controller.acroModeThreshold = thresholdValue Behavior on y { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 1000 } } @@ -341,7 +341,7 @@ QGCView { thresholdValue: controller.posCtlModeThreshold thresholdDragEnabled: true - onModeChannelIndexChanged: controller.posCtlModeChannelIndex = modeChannelIndex + onModeChannelIndexSelected: controller.posCtlModeChannelIndex = index onThresholdValueChanged: controller.posCtlModeThreshold = thresholdValue Behavior on y { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 1000 } } @@ -374,7 +374,7 @@ QGCView { thresholdValue: controller.loiterModeThreshold thresholdDragEnabled: true - onModeChannelIndexChanged: controller.loiterModeChannelIndex = modeChannelIndex + onModeChannelIndexSelected: controller.loiterModeChannelIndex = index onThresholdValueChanged: controller.loiterModeThreshold = thresholdValue Behavior on y { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 1000 } } @@ -391,7 +391,7 @@ QGCView { thresholdValue: controller.returnModeThreshold thresholdDragEnabled: true - onModeChannelIndexChanged: controller.returnModeChannelIndex = modeChannelIndex + onModeChannelIndexSelected: controller.returnModeChannelIndex = index onThresholdValueChanged: controller.returnModeThreshold = thresholdValue Behavior on y { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 1000 } } @@ -408,7 +408,7 @@ QGCView { thresholdValue: controller.offboardModeThreshold thresholdDragEnabled: true - onModeChannelIndexChanged: controller.offboardModeChannelIndex = modeChannelIndex + onModeChannelIndexSelected: controller.offboardModeChannelIndex = index onThresholdValueChanged: controller.offboardModeThreshold = thresholdValue Behavior on y { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 1000 } } diff --git a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc index 2507d349226ee6778e29f803a07b816611ab2a16..c4bc00e73f8a323a1bbcb8ccedf3ef1e7de63de3 100644 --- a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc +++ b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc @@ -23,12 +23,13 @@ #include "PX4AutoPilotPlugin.h" #include "AutoPilotPluginManager.h" -#include "PX4ParameterLoader.h" #include "PX4AirframeLoader.h" #include "FlightModesComponentController.h" #include "AirframeComponentController.h" #include "QGCMessageBox.h" #include "UAS.h" +#include "FirmwarePlugin/PX4/PX4ParameterLoader.h" // FIXME: Hack +#include "FirmwarePlugin/PX4/PX4FirmwarePlugin.h" // FIXME: Hack /// @file /// @brief This is the AutoPilotPlugin implementatin for the MAV_AUTOPILOT_PX4 type. @@ -66,7 +67,6 @@ union px4_custom_mode { PX4AutoPilotPlugin::PX4AutoPilotPlugin(Vehicle* vehicle, QObject* parent) : AutoPilotPlugin(vehicle, parent), - _parameterFacts(NULL), _airframeComponent(NULL), _radioComponent(NULL), _flightModesComponent(NULL), @@ -77,22 +77,17 @@ PX4AutoPilotPlugin::PX4AutoPilotPlugin(Vehicle* vehicle, QObject* parent) : { Q_ASSERT(vehicle); - _parameterFacts = new PX4ParameterLoader(this, vehicle, this); - Q_CHECK_PTR(_parameterFacts); - - connect(_parameterFacts, &PX4ParameterLoader::parametersReady, this, &PX4AutoPilotPlugin::_parametersReadyPreChecks); - connect(_parameterFacts, &PX4ParameterLoader::parameterListProgress, this, &PX4AutoPilotPlugin::parameterListProgress); - _airframeFacts = new PX4AirframeLoader(this, _vehicle->uas(), this); Q_CHECK_PTR(_airframeFacts); - PX4ParameterLoader::loadParameterFactMetaData(); PX4AirframeLoader::loadAirframeFactMetaData(); + + // This kicks off parameter load + _firmwarePlugin->getParameterLoader(this, vehicle); } PX4AutoPilotPlugin::~PX4AutoPilotPlugin() { - delete _parameterFacts; delete _airframeFacts; } diff --git a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h index cf90463746d108bf7e98d3f305b5baef6e3165bc..09b2ea8fed1e688a045a65cbf02e64b5be96f1b3 100644 --- a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h +++ b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h @@ -25,7 +25,6 @@ #define PX4AUTOPILOT_H #include "AutoPilotPlugin.h" -#include "PX4ParameterLoader.h" #include "PX4AirframeLoader.h" #include "AirframeComponent.h" #include "RadioComponent.h" @@ -62,14 +61,11 @@ public: SafetyComponent* safetyComponent(void) { return _safetyComponent; } PowerComponent* powerComponent(void) { return _powerComponent; } -private slots: +public slots: + // FIXME: This is public until we restructure AutoPilotPlugin/FirmwarePlugin/Vehicle void _parametersReadyPreChecks(bool missingParameters); private: - // Overrides from AutoPilotPlugin - virtual ParameterLoader* _getParameterLoader(void) { return _parameterFacts; } - - PX4ParameterLoader* _parameterFacts; PX4AirframeLoader* _airframeFacts; QVariantList _components; AirframeComponent* _airframeComponent; diff --git a/src/FactSystem/Fact.cc b/src/FactSystem/Fact.cc index a69b25831813093008c547a51e3f297f7fe245f3..09441f6e8a3eeccee84ea691b7d41650e4b7a6cb 100644 --- a/src/FactSystem/Fact.cc +++ b/src/FactSystem/Fact.cc @@ -131,7 +131,22 @@ QVariant Fact::value(void) const QString Fact::valueString(void) const { - return _value.toString(); + QString valueString; + + switch (type()) { + case FactMetaData::valueTypeFloat: + qDebug() << name() << value() << decimalPlaces(); + valueString = QString("%1").arg(value().toFloat(), 0, 'g', decimalPlaces()); + break; + case FactMetaData::valueTypeDouble: + valueString = QString("%1").arg(value().toDouble(), 0, 'g', decimalPlaces()); + break; + default: + valueString = value().toString(); + break; + } + + return valueString; } QVariant Fact::defaultValue(void) const @@ -222,6 +237,16 @@ bool Fact::maxIsDefaultForType(void) const } } +int Fact::decimalPlaces(void) const +{ + if (_metaData) { + return _metaData->decimalPlaces(); + } else { + qWarning() << "Meta data pointer missing"; + return FactMetaData::defaultDecimalPlaces; + } +} + QString Fact::group(void) const { if (_metaData) { diff --git a/src/FactSystem/Fact.h b/src/FactSystem/Fact.h index da8a85efebd290f8e8ffc5f1ea16ce1085354358..c946b198362dad272bd2d15903a657eddfdae593 100644 --- a/src/FactSystem/Fact.h +++ b/src/FactSystem/Fact.h @@ -46,22 +46,23 @@ public: const Fact& operator=(const Fact& other); - Q_PROPERTY(int componentId READ componentId CONSTANT) - Q_PROPERTY(QString name READ name CONSTANT) - Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged USER true) - Q_PROPERTY(QVariant valueString READ valueString NOTIFY valueChanged) - Q_PROPERTY(QString units READ units CONSTANT) - Q_PROPERTY(QVariant defaultValue READ defaultValue CONSTANT) - Q_PROPERTY(bool defaultValueAvailable READ defaultValueAvailable CONSTANT) - Q_PROPERTY(bool valueEqualsDefault READ valueEqualsDefault NOTIFY valueChanged) - Q_PROPERTY(FactMetaData::ValueType_t type READ type CONSTANT) - Q_PROPERTY(QString shortDescription READ shortDescription CONSTANT) - Q_PROPERTY(QString longDescription READ longDescription CONSTANT) - Q_PROPERTY(QVariant min READ min CONSTANT) - Q_PROPERTY(bool minIsDefaultForType READ minIsDefaultForType CONSTANT) - Q_PROPERTY(QVariant max READ max CONSTANT) - Q_PROPERTY(bool maxIsDefaultForType READ maxIsDefaultForType CONSTANT) - Q_PROPERTY(QString group READ group CONSTANT) + Q_PROPERTY(int componentId READ componentId CONSTANT) + Q_PROPERTY(QString group READ group CONSTANT) + Q_PROPERTY(QString name READ name CONSTANT) + Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged USER true) + Q_PROPERTY(QVariant valueString READ valueString NOTIFY valueChanged) + Q_PROPERTY(QString units READ units CONSTANT) + Q_PROPERTY(QVariant defaultValue READ defaultValue CONSTANT) + Q_PROPERTY(bool defaultValueAvailable READ defaultValueAvailable CONSTANT) + Q_PROPERTY(bool valueEqualsDefault READ valueEqualsDefault NOTIFY valueChanged) + Q_PROPERTY(FactMetaData::ValueType_t type READ type CONSTANT) + Q_PROPERTY(QString shortDescription READ shortDescription CONSTANT) + Q_PROPERTY(QString longDescription READ longDescription CONSTANT) + Q_PROPERTY(QVariant min READ min CONSTANT) + Q_PROPERTY(bool minIsDefaultForType READ minIsDefaultForType CONSTANT) + Q_PROPERTY(QVariant max READ max CONSTANT) + Q_PROPERTY(bool maxIsDefaultForType READ maxIsDefaultForType CONSTANT) + Q_PROPERTY(int decimalPlaces READ decimalPlaces CONSTANT) /// Convert and validate value /// @param convertOnly true: validate type conversion only, false: validate against meta data as well @@ -86,6 +87,7 @@ public: QVariant max(void) const; bool maxIsDefaultForType(void) const; QString group(void) const; + int decimalPlaces(void) const; /// Sets and sends new value to vehicle even if value is the same void forceSetValue(const QVariant& value); diff --git a/src/FactSystem/FactMetaData.cc b/src/FactSystem/FactMetaData.cc index 7360e65a7912a0417476a8d8dbc59c8bf2d7704a..942d4e35af262a976c8c94ff2d0f4d6557b80e18 100644 --- a/src/FactSystem/FactMetaData.cc +++ b/src/FactSystem/FactMetaData.cc @@ -32,30 +32,32 @@ #include -FactMetaData::FactMetaData(QObject* parent) : - QObject(parent), - _group("*Default Group"), - _type(valueTypeInt32), - _defaultValue(0), - _defaultValueAvailable(false), - _min(_minForType()), - _max(_maxForType()), - _minIsDefaultForType(true), - _maxIsDefaultForType(true) +FactMetaData::FactMetaData(QObject* parent) + : QObject(parent) + , _group("*Default Group") + , _type(valueTypeInt32) + , _defaultValue(0) + , _defaultValueAvailable(false) + , _min(_minForType()) + , _max(_maxForType()) + , _minIsDefaultForType(true) + , _maxIsDefaultForType(true) + , _decimalPlaces(defaultDecimalPlaces) { } -FactMetaData::FactMetaData(ValueType_t type, QObject* parent) : - QObject(parent), - _group("*Default Group"), - _type(type), - _defaultValue(0), - _defaultValueAvailable(false), - _min(_minForType()), - _max(_maxForType()), - _minIsDefaultForType(true), - _maxIsDefaultForType(true) +FactMetaData::FactMetaData(ValueType_t type, QObject* parent) + : QObject(parent) + , _group("*Default Group") + , _type(type) + , _defaultValue(0) + , _defaultValueAvailable(false) + , _min(_minForType()) + , _max(_maxForType()) + , _minIsDefaultForType(true) + , _maxIsDefaultForType(true) + , _decimalPlaces(defaultDecimalPlaces) { } @@ -76,6 +78,7 @@ const FactMetaData& FactMetaData::operator=(const FactMetaData& other) _max = other._max; _minIsDefaultForType = other._minIsDefaultForType; _maxIsDefaultForType = other._maxIsDefaultForType; + _decimalPlaces = other._decimalPlaces; return *this; } diff --git a/src/FactSystem/FactMetaData.h b/src/FactSystem/FactMetaData.h index 49c72d8784332c2a3e4ad27ac79f2af15a7cbe86..03c78d2f87642f7a213de8d455e6bc61198d6d1e 100644 --- a/src/FactSystem/FactMetaData.h +++ b/src/FactSystem/FactMetaData.h @@ -59,18 +59,19 @@ public: const FactMetaData& operator=(const FactMetaData& other); // Property accessors - QString name(void) const { return _name; } - QString group(void) const { return _group; } - ValueType_t type(void) const { return _type; } + QString name(void) const { return _name; } + QString group(void) const { return _group; } + ValueType_t type(void) const { return _type; } QVariant defaultValue(void) const; - bool defaultValueAvailable(void) const { return _defaultValueAvailable; } - QString shortDescription(void) const { return _shortDescription; } - QString longDescription(void) const { return _longDescription;} - QString units(void) const { return _units; } - QVariant min(void) const { return _min; } - QVariant max(void) const { return _max; } - bool minIsDefaultForType(void) const { return _minIsDefaultForType; } - bool maxIsDefaultForType(void) const { return _maxIsDefaultForType; } + bool defaultValueAvailable(void) const { return _defaultValueAvailable; } + QString shortDescription(void) const { return _shortDescription; } + QString longDescription(void) const { return _longDescription;} + QString units(void) const { return _units; } + QVariant min(void) const { return _min; } + QVariant max(void) const { return _max; } + bool minIsDefaultForType(void) const { return _minIsDefaultForType; } + bool maxIsDefaultForType(void) const { return _maxIsDefaultForType; } + int decimalPlaces(void) const { return _decimalPlaces; } // Property setters void setName(const QString& name) { _name = name; } @@ -81,6 +82,7 @@ public: void setUnits(const QString& units) { _units = units; } void setMin(const QVariant& max); void setMax(const QVariant& max); + void setDecimalPlaces(int decimalPlaces) { _decimalPlaces = decimalPlaces; } /// Converts the specified value, validating against meta data /// @param value Value to convert, can be string @@ -90,6 +92,8 @@ public: /// @returns false: Convert failed, errorString set bool convertAndValidate(const QVariant& value, bool convertOnly, QVariant& typedValue, QString& errorString); + static const int defaultDecimalPlaces = 3; + private: QVariant _minForType(void) const; QVariant _maxForType(void) const; @@ -106,6 +110,7 @@ private: QVariant _max; bool _minIsDefaultForType; bool _maxIsDefaultForType; + int _decimalPlaces; }; #endif diff --git a/src/FactSystem/ParameterLoader.h b/src/FactSystem/ParameterLoader.h index 9502e901dba40d05fcddf4799a0316da59f94f6d..14f4a6cd7432fae2fb6637d077a100d4878a6e47 100644 --- a/src/FactSystem/ParameterLoader.h +++ b/src/FactSystem/ParameterLoader.h @@ -105,6 +105,10 @@ protected: /// Base implementation adds generic meta data based on variant type. Derived class can override to provide /// more details meta data. virtual void _addMetaDataToFact(Fact* fact); + + AutoPilotPlugin* _autopilot; + Vehicle* _vehicle; + MAVLinkProtocol* _mavlink; private slots: void _parameterUpdate(int uasId, int componentId, QString parameterName, int parameterCount, int parameterId, int mavType, QVariant value); @@ -128,10 +132,6 @@ private: void _saveToEEPROM(void); void _checkInitialLoadComplete(void); - AutoPilotPlugin* _autopilot; - Vehicle* _vehicle; - MAVLinkProtocol* _mavlink; - /// First mapping is by component id /// Second mapping is parameter name, to Fact* in QVariant QMap _mapParameterName2Variant; diff --git a/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc b/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc index f2cfa3ed80ff7bf10221b26e1291cbb1ad1e5b46..4b4f7f4ed5b1c72aacb5bc1218d95fbb07e92c21 100644 --- a/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc +++ b/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc @@ -26,6 +26,7 @@ #include "APMFirmwarePlugin.h" #include "Generic/GenericFirmwarePlugin.h" +#include "AutoPilotPlugins/APM/APMAutoPilotPlugin.h" // FIXME: Hack #include "QGCMAVLink.h" QGC_LOGGING_CATEGORY(APMFirmwarePluginLog, "APMFirmwarePluginLog") @@ -138,8 +139,9 @@ QString APMCustomMode::modeString() const return mode; } -APMFirmwarePlugin::APMFirmwarePlugin(QObject* parent) : - FirmwarePlugin(parent) +APMFirmwarePlugin::APMFirmwarePlugin(QObject* parent) + : FirmwarePlugin(parent) + , _parameterLoader(NULL) { _textSeverityAdjustmentNeeded = false; } @@ -384,3 +386,19 @@ bool APMFirmwarePlugin::sendHomePositionToVehicle(void) // APM stack wants the home position sent in the first position return true; } + +ParameterLoader* APMFirmwarePlugin::getParameterLoader(AutoPilotPlugin* autopilotPlugin, Vehicle* vehicle) +{ + if (!_parameterLoader) { + _parameterLoader = new APMParameterLoader(autopilotPlugin, vehicle, this); + Q_CHECK_PTR(_parameterLoader); + + // FIXME: Why do I need SIGNAL/SLOT to make this work + connect(_parameterLoader, SIGNAL(parametersReady(bool)), autopilotPlugin, SLOT(_parametersReadyPreChecks(bool))); + connect(_parameterLoader, &APMParameterLoader::parameterListProgress, autopilotPlugin, &APMAutoPilotPlugin::parameterListProgress); + + _parameterLoader->loadParameterFactMetaData(); + } + + return _parameterLoader; +} diff --git a/src/FirmwarePlugin/APM/APMFirmwarePlugin.h b/src/FirmwarePlugin/APM/APMFirmwarePlugin.h index 6d92ab778e7d27f570845f9fd27a34a8f7556deb..2a7370b852ab1b0b2d16b1cffc9792fa24c5f44e 100644 --- a/src/FirmwarePlugin/APM/APMFirmwarePlugin.h +++ b/src/FirmwarePlugin/APM/APMFirmwarePlugin.h @@ -29,6 +29,7 @@ #include "FirmwarePlugin.h" #include "QGCLoggingCategory.h" +#include "APMParameterLoader.h" Q_DECLARE_LOGGING_CATEGORY(APMFirmwarePluginLog) @@ -88,6 +89,7 @@ public: virtual void adjustMavlinkMessage(mavlink_message_t* message); virtual void initializeVehicle(Vehicle* vehicle); virtual bool sendHomePositionToVehicle(void); + virtual ParameterLoader* getParameterLoader(AutoPilotPlugin *autopilotPlugin, Vehicle* vehicle); protected: /// All access to singleton is through stack specific implementation @@ -101,7 +103,7 @@ private: APMFirmwareVersion _firmwareVersion; bool _textSeverityAdjustmentNeeded; QList _supportedModes; - + APMParameterLoader* _parameterLoader; }; #endif diff --git a/src/FirmwarePlugin/APM/APMParameterLoader.cc b/src/FirmwarePlugin/APM/APMParameterLoader.cc new file mode 100644 index 0000000000000000000000000000000000000000..c24acf32fb4091d4c068788084ec0226b086cf33 --- /dev/null +++ b/src/FirmwarePlugin/APM/APMParameterLoader.cc @@ -0,0 +1,113 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2014 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +/// @file +/// @author Don Gagne + +#include "APMParameterLoader.h" +#include "QGCApplication.h" +#include "QGCLoggingCategory.h" + +#include +#include +#include +#include + +QGC_LOGGING_CATEGORY(APMParameterLoaderLog, "APMParameterLoaderLog") + +bool APMParameterLoader::_parameterMetaDataLoaded = false; +QMap APMParameterLoader::_mapParameterName2FactMetaData; + +APMParameterLoader::APMParameterLoader(AutoPilotPlugin* autopilot, Vehicle* vehicle, QObject* parent) : + ParameterLoader(autopilot, vehicle, parent) +{ + Q_ASSERT(vehicle); +} + +/// Converts a string to a typed QVariant +/// @param string String to convert +/// @param type Type for Fact which dictates the QVariant type as well +/// @param convertOk Returned: true: conversion success, false: conversion failure +/// @return Returns the correctly type QVariant +QVariant APMParameterLoader::_stringToTypedVariant(const QString& string, FactMetaData::ValueType_t type, bool* convertOk) +{ + QVariant var(string); + + int convertTo = QVariant::Int; // keep compiler warning happy + switch (type) { + case FactMetaData::valueTypeUint8: + case FactMetaData::valueTypeUint16: + case FactMetaData::valueTypeUint32: + convertTo = QVariant::UInt; + break; + case FactMetaData::valueTypeInt8: + case FactMetaData::valueTypeInt16: + case FactMetaData::valueTypeInt32: + convertTo = QVariant::Int; + break; + case FactMetaData::valueTypeFloat: + convertTo = QMetaType::Float; + break; + case FactMetaData::valueTypeDouble: + convertTo = QVariant::Double; + break; + } + + *convertOk = var.convert(convertTo); + + return var; +} + +/// Load Parameter Fact meta data +/// +/// The meta data comes from firmware parameters.xml file. +void APMParameterLoader::loadParameterFactMetaData(void) +{ + if (_parameterMetaDataLoaded) { + return; + } + _parameterMetaDataLoaded = true; + + // FIXME: NYI + + // Static meta data should load all MAV_TYPEs from single meta data file in such a way that the loader + // has multiple sets of static meta data +} + +void APMParameterLoader::clearStaticData(void) +{ + foreach(QString parameterName, _mapParameterName2FactMetaData.keys()) { + delete _mapParameterName2FactMetaData[parameterName]; + } + _mapParameterName2FactMetaData.clear(); + _parameterMetaDataLoaded = false; +} + +/// Override from FactLoad which connects the meta data to the fact +void APMParameterLoader::_addMetaDataToFact(Fact* fact) +{ + // FIXME: Will need to switch here based on _vehicle->firmwareType() to pull right set of meta data + + // Use generic meta data + ParameterLoader::_addMetaDataToFact(fact); +} diff --git a/src/FirmwarePlugin/APM/APMParameterLoader.h b/src/FirmwarePlugin/APM/APMParameterLoader.h new file mode 100644 index 0000000000000000000000000000000000000000..4853b8aadf13a41111eae43f72de1d3a7308d901 --- /dev/null +++ b/src/FirmwarePlugin/APM/APMParameterLoader.h @@ -0,0 +1,78 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2014 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +#ifndef APMParameterLoader_H +#define APMParameterLoader_H + +#include +#include +#include +#include + +#include "ParameterLoader.h" +#include "FactSystem.h" +#include "AutoPilotPlugin.h" +#include "Vehicle.h" + +/// @file +/// @author Don Gagne + +Q_DECLARE_LOGGING_CATEGORY(APMParameterLoaderLog) + +/// Collection of Parameter Facts for PX4 AutoPilot + +class APMParameterLoader : public ParameterLoader +{ + Q_OBJECT + +public: + /// @param uas Uas which this set of facts is associated with + APMParameterLoader(AutoPilotPlugin* autopilot, Vehicle* vehicle, QObject* parent = NULL); + + /// Override from ParameterLoader + virtual QString getDefaultComponentIdParam(void) const { return QString("SYSID_SW_TYPE"); } + + static void loadParameterFactMetaData(void); + static void clearStaticData(void); + +private: + enum { + XmlStateNone, + XmlStateFoundParameters, + XmlStateFoundVersion, + XmlStateFoundGroup, + XmlStateFoundParameter, + XmlStateDone + }; + + // Overrides from ParameterLoader + virtual void _addMetaDataToFact(Fact* fact); + + // Class methods + static QVariant _stringToTypedVariant(const QString& string, FactMetaData::ValueType_t type, bool* convertOk); + + static bool _parameterMetaDataLoaded; ///< true: parameter meta data already loaded + static QMap _mapParameterName2FactMetaData; ///< Maps from a parameter name to FactMetaData +}; + +#endif diff --git a/src/FirmwarePlugin/FirmwarePlugin.h b/src/FirmwarePlugin/FirmwarePlugin.h index eacd29ebbacf66a7755ae1513356da1c73c8f3e2..a6a0b0a7f38baa0bf90356358423528a85136dcd 100644 --- a/src/FirmwarePlugin/FirmwarePlugin.h +++ b/src/FirmwarePlugin/FirmwarePlugin.h @@ -105,6 +105,9 @@ public: /// false: Do not send first item to vehicle, sequence numbers must be adjusted virtual bool sendHomePositionToVehicle(void) = 0; + /// Returns the ParameterLoader + virtual ParameterLoader* getParameterLoader(AutoPilotPlugin* autopilotPlugin, Vehicle* vehicle) = 0; + protected: FirmwarePlugin(QObject* parent = NULL) : QGCSingleton(parent) { } }; diff --git a/src/FirmwarePlugin/Generic/GenericFirmwarePlugin.cc b/src/FirmwarePlugin/Generic/GenericFirmwarePlugin.cc index 0971990949e46093c0acd390a6c5137ec7405d3e..a7036270f15ba4f21a74fdc87bec730bfe66b4b9 100644 --- a/src/FirmwarePlugin/Generic/GenericFirmwarePlugin.cc +++ b/src/FirmwarePlugin/Generic/GenericFirmwarePlugin.cc @@ -25,13 +25,15 @@ /// @author Don Gagne #include "GenericFirmwarePlugin.h" +#include "AutoPilotPlugins/Generic/GenericAutoPilotPlugin.h" // FIXME: Hack #include IMPLEMENT_QGC_SINGLETON(GenericFirmwarePlugin, FirmwarePlugin) -GenericFirmwarePlugin::GenericFirmwarePlugin(QObject* parent) : - FirmwarePlugin(parent) +GenericFirmwarePlugin::GenericFirmwarePlugin(QObject* parent) + : FirmwarePlugin(parent) + , _parameterLoader(NULL) { } @@ -118,3 +120,17 @@ bool GenericFirmwarePlugin::sendHomePositionToVehicle(void) // This is the mavlink spec default. return false; } + +ParameterLoader* GenericFirmwarePlugin::getParameterLoader(AutoPilotPlugin* autopilotPlugin, Vehicle* vehicle) +{ + if (!_parameterLoader) { + _parameterLoader = new GenericParameterLoader(autopilotPlugin, vehicle, this); + Q_CHECK_PTR(_parameterLoader); + + // FIXME: Why do I need SIGNAL/SLOT to make this work + connect(_parameterLoader, SIGNAL(parametersReady(bool)), autopilotPlugin, SLOT(_parametersReadyPreChecks(bool))); + connect(_parameterLoader, &GenericParameterLoader::parameterListProgress, autopilotPlugin, &GenericAutoPilotPlugin::parameterListProgress); + } + + return _parameterLoader; +} diff --git a/src/FirmwarePlugin/Generic/GenericFirmwarePlugin.h b/src/FirmwarePlugin/Generic/GenericFirmwarePlugin.h index abeb96e773863ec62385326edd706236f6df4972..afc8c8df2c6f20e85ea28b5164f810fda636ea19 100644 --- a/src/FirmwarePlugin/Generic/GenericFirmwarePlugin.h +++ b/src/FirmwarePlugin/Generic/GenericFirmwarePlugin.h @@ -28,6 +28,7 @@ #define GenericFirmwarePlugin_H #include "FirmwarePlugin.h" +#include "GenericParameterLoader.h" class GenericFirmwarePlugin : public FirmwarePlugin { @@ -47,10 +48,13 @@ public: virtual void adjustMavlinkMessage(mavlink_message_t* message); virtual void initializeVehicle(Vehicle* vehicle); virtual bool sendHomePositionToVehicle(void); + virtual ParameterLoader* getParameterLoader(AutoPilotPlugin *autopilotPlugin, Vehicle* vehicle); private: /// All access to singleton is through AutoPilotPluginManager::instance GenericFirmwarePlugin(QObject* parent = NULL); + + GenericParameterLoader* _parameterLoader; }; #endif diff --git a/src/AutoPilotPlugins/Generic/GenericParameterFacts.cc b/src/FirmwarePlugin/Generic/GenericParameterLoader.cc similarity index 74% rename from src/AutoPilotPlugins/Generic/GenericParameterFacts.cc rename to src/FirmwarePlugin/Generic/GenericParameterLoader.cc index 24831fcaac358e148ce2071ed1ac013efb1eff18..20439ea226c78c35e367b81e4884cbcd493bafa6 100644 --- a/src/AutoPilotPlugins/Generic/GenericParameterFacts.cc +++ b/src/FirmwarePlugin/Generic/GenericParameterLoader.cc @@ -21,15 +21,17 @@ ======================================================================*/ -/// @file -/// @author Don Gagne +#include "GenericParameterLoader.h" -#include "GenericParameterFacts.h" - -#include - -GenericParameterFacts::GenericParameterFacts(AutoPilotPlugin* autopilot, Vehicle* vehicle, QObject* parent) : +GenericParameterLoader::GenericParameterLoader(AutoPilotPlugin* autopilot, Vehicle* vehicle, QObject* parent) : ParameterLoader(autopilot, vehicle, parent) { Q_ASSERT(vehicle); } + +/// Override from ParameterLoader which connects the meta data to the fact +void GenericParameterLoader::_addMetaDataToFact(Fact* fact) +{ + // Use generic meta data + ParameterLoader::_addMetaDataToFact(fact); +} diff --git a/src/AutoPilotPlugins/Generic/GenericParameterFacts.h b/src/FirmwarePlugin/Generic/GenericParameterLoader.h similarity index 76% rename from src/AutoPilotPlugins/Generic/GenericParameterFacts.h rename to src/FirmwarePlugin/Generic/GenericParameterLoader.h index c7a90c60c90db47de6f7882efeed739ba960c807..98aa7f2cda6bf9ba9db31f7258f898a0e26939ba 100644 --- a/src/AutoPilotPlugins/Generic/GenericParameterFacts.h +++ b/src/FirmwarePlugin/Generic/GenericParameterLoader.h @@ -21,30 +21,28 @@ ======================================================================*/ -#ifndef GenericParameterFacts_h -#define GenericParameterFacts_h - -#include +#ifndef GenericParameterLoader_H +#define GenericParameterLoader_H #include "ParameterLoader.h" -#include "UASInterface.h" +#include "FactSystem.h" #include "AutoPilotPlugin.h" +#include "Vehicle.h" -/// @file -/// @author Don Gagne - -/// Collection of Parameter Facts for Generic AutoPilot - -class GenericParameterFacts : public ParameterLoader +class GenericParameterLoader : public ParameterLoader { Q_OBJECT public: /// @param uas Uas which this set of facts is associated with - GenericParameterFacts(AutoPilotPlugin* autopilot, Vehicle* vehicle, QObject* parent = NULL); - + GenericParameterLoader(AutoPilotPlugin* autopilot, Vehicle* vehicle, QObject* parent = NULL); + /// Override from ParameterLoader virtual QString getDefaultComponentIdParam(void) const { return QString(); } + +private: + // Overrides from ParameterLoader + virtual void _addMetaDataToFact(Fact* fact); }; -#endif \ No newline at end of file +#endif diff --git a/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc b/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc index d78c1914c7b1daf12d62cc1b9bab1e58a14f22c1..80d3acecbcc2edc410aea02c5fc361caf8adb483 100644 --- a/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc +++ b/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc @@ -25,6 +25,7 @@ /// @author Don Gagne #include "PX4FirmwarePlugin.h" +#include "AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h" // FIXME: Hack #include @@ -85,8 +86,9 @@ static const struct Modes2Name rgModes2Name[] = { }; -PX4FirmwarePlugin::PX4FirmwarePlugin(QObject* parent) : - FirmwarePlugin(parent) +PX4FirmwarePlugin::PX4FirmwarePlugin(QObject* parent) + : FirmwarePlugin(parent) + , _parameterLoader(NULL) { } @@ -207,3 +209,19 @@ bool PX4FirmwarePlugin::sendHomePositionToVehicle(void) // Subsequent sequence numbers must be adjusted. return false; } + +ParameterLoader* PX4FirmwarePlugin::getParameterLoader(AutoPilotPlugin* autopilotPlugin, Vehicle* vehicle) +{ + if (!_parameterLoader) { + _parameterLoader = new PX4ParameterLoader(autopilotPlugin, vehicle, this); + Q_CHECK_PTR(_parameterLoader); + + // FIXME: Why do I need SIGNAL/SLOT to make this work + connect(_parameterLoader, SIGNAL(parametersReady(bool)), autopilotPlugin, SLOT(_parametersReadyPreChecks(bool))); + connect(_parameterLoader, &PX4ParameterLoader::parameterListProgress, autopilotPlugin, &PX4AutoPilotPlugin::parameterListProgress); + + _parameterLoader->loadParameterFactMetaData(); + } + + return _parameterLoader; +} diff --git a/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.h b/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.h index ebbd49ebb1780ba67744dc6e3d2f5730c5ea199a..a78693a3a871797b30331b3b1eb5451772fe09f4 100644 --- a/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.h +++ b/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.h @@ -28,6 +28,7 @@ #define PX4FirmwarePlugin_H #include "FirmwarePlugin.h" +#include "PX4ParameterLoader.h" class PX4FirmwarePlugin : public FirmwarePlugin { @@ -47,10 +48,13 @@ public: virtual void adjustMavlinkMessage(mavlink_message_t* message); virtual void initializeVehicle(Vehicle* vehicle); virtual bool sendHomePositionToVehicle(void); + virtual ParameterLoader* getParameterLoader(AutoPilotPlugin *autopilotPlugin, Vehicle* vehicle); private: /// All access to singleton is through AutoPilotPluginManager::instance PX4FirmwarePlugin(QObject* parent = NULL); + + PX4ParameterLoader* _parameterLoader; }; #endif diff --git a/src/AutoPilotPlugins/PX4/PX4ParameterLoader.cc b/src/FirmwarePlugin/PX4/PX4ParameterLoader.cc similarity index 95% rename from src/AutoPilotPlugins/PX4/PX4ParameterLoader.cc rename to src/FirmwarePlugin/PX4/PX4ParameterLoader.cc index aea72c11f4e4ddd93139dd04a864c7fc6c662b59..c7d989dd263e2fa1ac238860336992dd9c3caeb8 100644 --- a/src/AutoPilotPlugins/PX4/PX4ParameterLoader.cc +++ b/src/FirmwarePlugin/PX4/PX4ParameterLoader.cc @@ -299,6 +299,19 @@ void PX4ParameterLoader::loadParameterFactMetaData(void) qCDebug(PX4ParameterLoaderLog) << "Unit:" << text; metaData->setUnits(text); + } else if (elementName == "decimal") { + Q_ASSERT(metaData); + QString text = xml.readElementText(); + qCDebug(PX4ParameterLoaderLog) << "Decimal:" << text; + + bool convertOk; + QVariant varDecimals = QVariant(text).toUInt(&convertOk); + if (convertOk) { + metaData->setDecimalPlaces(varDecimals.toInt()); + } else { + qCWarning(PX4ParameterLoaderLog) << "Invalid decimals value, name:" << metaData->name() << " type:" << metaData->type() << " decimals:" << text << " error: invalid number"; + } + } else { qDebug() << "Unknown element in XML: " << elementName; } diff --git a/src/AutoPilotPlugins/PX4/PX4ParameterLoader.h b/src/FirmwarePlugin/PX4/PX4ParameterLoader.h similarity index 100% rename from src/AutoPilotPlugins/PX4/PX4ParameterLoader.h rename to src/FirmwarePlugin/PX4/PX4ParameterLoader.h diff --git a/src/MissionEditor/MissionEditor.qml b/src/MissionEditor/MissionEditor.qml index 83f00d560089e0e560767450b31c027a87f11617..a7e92f5b428091a442be0480676709cbfa2d6860 100644 --- a/src/MissionEditor/MissionEditor.qml +++ b/src/MissionEditor/MissionEditor.qml @@ -322,8 +322,6 @@ QGCView { // Move to the new position editorMap.latitude = object.coordinate.latitude editorMap.longitude = object.coordinate.longitude - } else { - itemDragger.clearItem() } } } diff --git a/src/MissionItem.cc b/src/MissionItem.cc index 0d0943eaa7722a1f4d397f8671897e0a1b3e782c..4e3f9d147f2ea994e310c035fdb56604db0257e2 100644 --- a/src/MissionItem.cc +++ b/src/MissionItem.cc @@ -20,15 +20,6 @@ This file is part of the QGROUNDCONTROL project ======================================================================*/ -/** - * @file - * @brief MissionItem class - * - * @author Benjamin Knecht - * @author Petri Tanskanen - * - */ - #include #include @@ -115,10 +106,12 @@ MissionItem::MissionItem(QObject* parent, FactMetaData* latitudeMetaData = new FactMetaData(FactMetaData::valueTypeDouble, _latitudeFact); latitudeMetaData->setUnits("deg"); - + latitudeMetaData->setDecimalPlaces(7); + FactMetaData* longitudeMetaData = new FactMetaData(FactMetaData::valueTypeDouble, _longitudeFact); longitudeMetaData->setUnits("deg"); - + longitudeMetaData->setDecimalPlaces(7); + FactMetaData* altitudeMetaData = new FactMetaData(FactMetaData::valueTypeDouble, _altitudeFact); altitudeMetaData->setUnits("meters"); diff --git a/src/MissionManager/MissionController.cc b/src/MissionManager/MissionController.cc index bad302403de79d96753a11d9180de2442f971baf..01f9be44d28268ca1be793e7571a5e09cfcabb64 100644 --- a/src/MissionManager/MissionController.cc +++ b/src/MissionManager/MissionController.cc @@ -66,21 +66,23 @@ void MissionController::start(bool editMode) connect(multiVehicleMgr, &MultiVehicleManager::activeVehicleChanged, this, &MissionController::_activeVehicleChanged); - _setupMissionItems(true /* fromVehicle */, true /* force */); + _setupMissionItems(true /* loadFromVehicle */, true /* forceLoad */); + _setupActiveVehicle(multiVehicleMgr->activeVehicle(), true /* forceLoadFromVehicle */); } void MissionController::_newMissionItemsAvailableFromVehicle(void) { qCDebug(MissionControllerLog) << "_newMissionItemsAvailableFromVehicle"; - _setupMissionItems(true /* fromVehicle */, false /* force */); + _setupMissionItems(true /* loadFromVehicle */, false /* forceLoad */); } -/// @param fromVehicle true: load items from vehicle -/// @param force true: disregard any flags which may prevent load -void MissionController::_setupMissionItems(bool fromVehicle, bool force) +/// @param loadFromVehicle true: load items from vehicle +/// @param forceLoad true: disregard any flags which may prevent load +void MissionController::_setupMissionItems(bool loadFromVehicle, bool forceLoad) { - qCDebug(MissionControllerLog) << "_setupMissionItems fromVehicle:force:_editMode:_firstItemsFromVehicle" << fromVehicle << force << _editMode << _firstItemsFromVehicle; + qCDebug(MissionControllerLog) << "_setupMissionItems loadFromVehicle:forceLoad:_editMode:_firstItemsFromVehicle" + << loadFromVehicle << forceLoad << _editMode << _firstItemsFromVehicle; MissionManager* missionManager = NULL; if (_activeVehicle) { @@ -89,8 +91,8 @@ void MissionController::_setupMissionItems(bool fromVehicle, bool force) qCDebug(MissionControllerLog) << "running offline"; } - if (!force) { - if (_editMode && fromVehicle) { + if (!forceLoad) { + if (_editMode && loadFromVehicle) { if (_firstItemsFromVehicle) { if (missionManager) { if (missionManager->inProgress()) { @@ -126,7 +128,7 @@ void MissionController::_setupMissionItems(bool fromVehicle, bool force) _missionItems->deleteLater(); } - if (!missionManager || !fromVehicle || missionManager->inProgress()) { + if (!missionManager || !loadFromVehicle || missionManager->inProgress()) { _canEdit = true; _missionItems = new QmlObjectListModel(this); qCDebug(MissionControllerLog) << "creating empty set"; @@ -440,10 +442,22 @@ void MissionController::_activeVehicleChanged(Vehicle* activeVehicle) _activeVehicle = NULL; // When the active vehicle goes away we toss the editor items - _setupMissionItems(false /* fromVehicle */, true /* force */); + _setupMissionItems(false /* loadFromVehicle */, true /* forceLoad */); _activeVehicleHomePositionAvailableChanged(false); } + _setupActiveVehicle(activeVehicle, false /* forceLoadFromVehicle */); +} + +void MissionController::_setupActiveVehicle(Vehicle* activeVehicle, bool forceLoadFromVehicle) +{ + qCDebug(MissionControllerLog) << "_setupActiveVehicle activeVehicle:forceLoadFromVehicle" + << activeVehicle << forceLoadFromVehicle; + + if (_activeVehicle) { + qCWarning(MissionControllerLog) << "_activeVehicle != NULL"; + } + _activeVehicle = activeVehicle; if (_activeVehicle) { @@ -455,7 +469,7 @@ void MissionController::_activeVehicleChanged(Vehicle* activeVehicle) connect(_activeVehicle, &Vehicle::homePositionChanged, this, &MissionController::_activeVehicleHomePositionChanged); _firstItemsFromVehicle = true; - _setupMissionItems(true /* fromVehicle */, false /* force */); + _setupMissionItems(true /* fromVehicle */, forceLoadFromVehicle); _activeVehicleHomePositionChanged(_activeVehicle->homePosition()); _activeVehicleHomePositionAvailableChanged(_activeVehicle->homePositionAvailable()); @@ -464,20 +478,15 @@ void MissionController::_activeVehicleChanged(Vehicle* activeVehicle) void MissionController::_activeVehicleHomePositionAvailableChanged(bool homePositionAvailable) { - MissionItem* homeItem = qobject_cast(_missionItems->get(0)); - - if (homePositionAvailable) { - homeItem->setCoordinate(_liveHomePosition); - } - homeItem->setHomePositionValid(homePositionAvailable); - _liveHomePositionAvailable = homePositionAvailable; + qobject_cast(_missionItems->get(0))->setHomePositionValid(homePositionAvailable); emit liveHomePositionAvailableChanged(_liveHomePositionAvailable); } void MissionController::_activeVehicleHomePositionChanged(const QGeoCoordinate& homePosition) { _liveHomePosition = homePosition; + qobject_cast(_missionItems->get(0))->setCoordinate(_liveHomePosition); emit liveHomePositionChanged(_liveHomePosition); } diff --git a/src/MissionManager/MissionController.h b/src/MissionManager/MissionController.h index 50078c912f6d3e201435e5a117bc4d94fe846220..2913268ded8b3f6135c506bfbf104d7303f3b30f 100644 --- a/src/MissionManager/MissionController.h +++ b/src/MissionManager/MissionController.h @@ -94,7 +94,8 @@ private: void _initMissionItem(MissionItem* item); void _deinitMissionItem(MissionItem* item); void _autoSyncSend(void); - void _setupMissionItems(bool fromVehicle, bool force); + void _setupMissionItems(bool loadFromVehicle, bool forceLoad); + void _setupActiveVehicle(Vehicle* activeVehicle, bool forceLoadFromVehicle); private: bool _editMode; diff --git a/src/QmlControls/ModeSwitchDisplay.qml b/src/QmlControls/ModeSwitchDisplay.qml index 126fd7b25618fd637026090938193f03b2f86c6c..9e09759252093826802a262b2f8b1e8c72706bfc 100644 --- a/src/QmlControls/ModeSwitchDisplay.qml +++ b/src/QmlControls/ModeSwitchDisplay.qml @@ -45,6 +45,8 @@ Rectangle { height: column.height + (ScreenTools.defaultFontPixelWidth * 2) color: _qgcPal.window + signal modeChannelIndexSelected(int index) + QGCPalette { id: _qgcPal; colorGroupEnabled: enabled } Item { @@ -63,7 +65,7 @@ Rectangle { Rectangle { width: modeLabel.width height: modeLabel.contentHeight - color: modeSelected ? _qgcPal.buttonHighlight : _qgcPal.windowShade + color: modeSelected ? _qgcPal.buttonHighlight : _qgcPal.button QGCLabel { id: modeLabel @@ -82,7 +84,7 @@ Rectangle { currentIndex: modeChannelIndex enabled: modeChannelEnabled - onActivated: modeChannelIndex = index + onActivated: modeChannelIndexSelected(index) } QGCLabel { diff --git a/src/Vehicle/Vehicle.cc b/src/Vehicle/Vehicle.cc index 1991995eaf436af9d14e187aa32c02ea457359a5..f97a7ed5052b7f2c557bb9968b0019ad5fcc6378 100644 --- a/src/Vehicle/Vehicle.cc +++ b/src/Vehicle/Vehicle.cc @@ -202,17 +202,32 @@ void Vehicle::_mavlinkMessageReceived(LinkInterface* link, mavlink_message_t mes void Vehicle::_handleHomePosition(mavlink_message_t& message) { + bool emitHomePositionChanged = false; + bool emitHomePositionAvailableChanged = false; + mavlink_home_position_t homePos; mavlink_msg_home_position_decode(&message, &homePos); - - _homePosition.setLatitude(homePos.latitude / 10000000.0); - _homePosition.setLongitude(homePos.longitude / 10000000.0); - _homePosition.setAltitude(homePos.altitude / 1000.0); + + QGeoCoordinate newHomePosition (homePos.latitude / 10000000.0, + homePos.longitude / 10000000.0, + homePos.altitude / 1000.0); + if (newHomePosition != _homePosition) { + emitHomePositionChanged = true; + _homePosition = newHomePosition; + } + + if (!_homePositionAvailable) { + emitHomePositionAvailableChanged = true; + } _homePositionAvailable = true; - - emit homePositionChanged(_homePosition); - emit homePositionAvailableChanged(true); + + if (emitHomePositionChanged) { + emit homePositionChanged(_homePosition); + } + if (emitHomePositionAvailableChanged) { + emit homePositionAvailableChanged(true); + } } void Vehicle::_handleHeartbeat(mavlink_message_t& message)