diff --git a/qgcresources.qrc b/qgcresources.qrc
index 2bab64496172536bd32116a12e1d6c8a3166844c..db6dafefdb1a905492c039a90a1fd12b2683daba 100644
--- a/qgcresources.qrc
+++ b/qgcresources.qrc
@@ -63,6 +63,7 @@
src/AutoPilotPlugins/PX4/Images/LandModeCopter.svg
src/AutoPilotPlugins/PX4/Images/LowBattery.svg
src/AutoPilotPlugins/PX4/Images/LowBatteryLight.svg
+ src/AutoPilotPlugins/Common/MotorComponentIcon.png
src/AutoPilotPlugins/PX4/Images/PowerComponentBattery_01cell.svg
src/AutoPilotPlugins/PX4/Images/PowerComponentBattery_02cell.svg
src/AutoPilotPlugins/PX4/Images/PowerComponentBattery_03cell.svg
diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro
index 181d8c8bcf6ae907e8d79c27116f94a26176478a..657073d83defa01b2381f4efe714c6b90ae88e58 100644
--- a/qgroundcontrol.pro
+++ b/qgroundcontrol.pro
@@ -638,6 +638,7 @@ HEADERS+= \
src/AutoPilotPlugins/APM/APMSensorsComponent.h \
src/AutoPilotPlugins/APM/APMSensorsComponentController.h \
src/AutoPilotPlugins/APM/APMTuningComponent.h \
+ src/AutoPilotPlugins/Common/MotorComponent.h \
src/AutoPilotPlugins/Common/RadioComponentController.h \
src/AutoPilotPlugins/Common/ESP8266ComponentController.h \
src/AutoPilotPlugins/Common/ESP8266Component.h \
@@ -696,6 +697,7 @@ SOURCES += \
src/AutoPilotPlugins/APM/APMSensorsComponent.cc \
src/AutoPilotPlugins/APM/APMSensorsComponentController.cc \
src/AutoPilotPlugins/APM/APMTuningComponent.cc \
+ src/AutoPilotPlugins/Common/MotorComponent.cc \
src/AutoPilotPlugins/Common/RadioComponentController.cc \
src/AutoPilotPlugins/Common/ESP8266ComponentController.cc \
src/AutoPilotPlugins/Common/ESP8266Component.cc \
diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc
index 555e0dda80e13feda92f06db61d75314253d4130..0f6a054fd82e742c3fce791c4f65f68d7aa94ee0 100644
--- a/qgroundcontrol.qrc
+++ b/qgroundcontrol.qrc
@@ -39,6 +39,7 @@
src/ui/MainWindowNative.qml
src/ui/MainWindowLeftPanel.qml
src/MissionEditor/MissionEditor.qml
+ src/AutoPilotPlugins/Common/MotorComponent.qml
src/AutoPilotPlugins/PX4/PowerComponent.qml
src/AutoPilotPlugins/PX4/PowerComponentSummary.qml
src/VehicleSetup/PX4FlowSensor.qml
@@ -55,6 +56,8 @@
src/QmlControls/MissionItemIndexLabel.qml
src/MissionEditor/MissionItemStatus.qml
src/QmlControls/MissionCommandDialog.qml
+ src/QmlControls/MultiRotorMotorDisplay.qml
+ src/QmlControls/MultiRotorMotorDisplayLegend.qml
src/QmlControls/ModeSwitchDisplay.qml
src/QmlControls/ParameterEditor.qml
src/QmlControls/ParameterEditorDialog.qml
@@ -71,6 +74,7 @@
src/QmlControls/QGCMovableItem.qml
src/QmlControls/QGCPipable.qml
src/QmlControls/QGCRadioButton.qml
+ src/QmlControls/QGCSlider.qml
src/QmlControls/QGCTextField.qml
src/QmlControls/QGCToolBarButton.qml
src/QmlControls/QGCView.qml
@@ -78,6 +82,7 @@
src/QmlControls/QGCViewMessage.qml
src/QmlControls/QGCViewPanel.qml
src/QmlControls/RoundButton.qml
+ src/AutoPilotPlugins/Common/SetupPage.qml
src/ui/toolbar/SignalStrength.qml
src/QmlControls/SliderSwitch.qml
src/QmlControls/SubMenuButton.qml
@@ -113,7 +118,6 @@
src/FlightMap/Widgets/QGCInstrumentWidget.qml
src/FlightMap/Widgets/QGCInstrumentWidgetAlternate.qml
src/FlightMap/Widgets/QGCPitchIndicator.qml
- src/FlightMap/Widgets/QGCSlider.qml
src/FlightMap/QGCVideoBackground.qml
src/FlightMap/Widgets/ValuesWidget.qml
src/FlightMap/Widgets/VibrationWidget.qml
diff --git a/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc b/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc
index d9c2fce4f31b5c6c4ce50d951746d661d64abebd..4c4fb6a57f75874bad3b6afb3c3e5e171f07b128 100644
--- a/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc
+++ b/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc
@@ -25,6 +25,7 @@
#include "APMTuningComponent.h"
#include "APMSensorsComponent.h"
#include "APMPowerComponent.h"
+#include "MotorComponent.h"
#include "APMCameraComponent.h"
#include "ESP8266Component.h"
@@ -36,6 +37,7 @@ APMAutoPilotPlugin::APMAutoPilotPlugin(Vehicle* vehicle, QObject* parent)
, _cameraComponent(NULL)
, _flightModesComponent(NULL)
, _powerComponent(NULL)
+ , _motorComponent(NULL)
, _radioComponent(NULL)
, _safetyComponent(NULL)
, _sensorsComponent(NULL)
@@ -77,6 +79,12 @@ const QVariantList& APMAutoPilotPlugin::vehicleComponents(void)
_powerComponent->setupTriggerSignals();
_components.append(QVariant::fromValue((VehicleComponent*)_powerComponent));
+ if (_vehicle->multiRotor() || _vehicle->vtol()) {
+ _motorComponent = new MotorComponent(_vehicle, this);
+ _motorComponent->setupTriggerSignals();
+ _components.append(QVariant::fromValue((VehicleComponent*)_motorComponent));
+ }
+
_safetyComponent = new APMSafetyComponent(_vehicle, this);
_safetyComponent->setupTriggerSignals();
_components.append(QVariant::fromValue((VehicleComponent*)_safetyComponent));
diff --git a/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h b/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h
index 752098f79d64aa8d0f7ef7bdc3db6b3f8c5a2713..961d88aee174b31c3429db81db3494b48c9ae9f2 100644
--- a/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h
+++ b/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h
@@ -22,6 +22,7 @@ class APMTuningComponent;
class APMSafetyComponent;
class APMSensorsComponent;
class APMPowerComponent;
+class MotorComponent;
class APMCameraComponent;
class ESP8266Component;
@@ -41,6 +42,7 @@ public:
APMCameraComponent* cameraComponent (void) const { return _cameraComponent; }
APMFlightModesComponent* flightModesComponent(void) const { return _flightModesComponent; }
APMPowerComponent* powerComponent (void) const { return _powerComponent; }
+ MotorComponent* motorComponent (void) const { return _motorComponent; }
APMRadioComponent* radioComponent (void) const { return _radioComponent; }
APMSafetyComponent* safetyComponent (void) const { return _safetyComponent; }
APMSensorsComponent* sensorsComponent (void) const { return _sensorsComponent; }
@@ -59,6 +61,7 @@ private:
APMCameraComponent* _cameraComponent;
APMFlightModesComponent* _flightModesComponent;
APMPowerComponent* _powerComponent;
+ MotorComponent* _motorComponent;
APMRadioComponent* _radioComponent;
APMSafetyComponent* _safetyComponent;
APMSensorsComponent* _sensorsComponent;
diff --git a/src/AutoPilotPlugins/Common/MotorComponent.cc b/src/AutoPilotPlugins/Common/MotorComponent.cc
new file mode 100644
index 0000000000000000000000000000000000000000..bca1ed1bd0e95bec2adf4ab0a63fee8b575c597b
--- /dev/null
+++ b/src/AutoPilotPlugins/Common/MotorComponent.cc
@@ -0,0 +1,65 @@
+/****************************************************************************
+ *
+ * (c) 2009-2016 QGROUNDCONTROL PROJECT
+ *
+ * QGroundControl is licensed according to the terms in the file
+ * COPYING.md in the root of the source code directory.
+ *
+ ****************************************************************************/
+
+
+#include "MotorComponent.h"
+#include "APMAutoPilotPlugin.h"
+#include "APMAirframeComponent.h"
+
+MotorComponent::MotorComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent) :
+ VehicleComponent(vehicle, autopilot, parent),
+ _name(tr("Motors"))
+{
+
+}
+
+QString MotorComponent::name(void) const
+{
+ return _name;
+}
+
+QString MotorComponent::description(void) const
+{
+ return tr("Motors Setup is used to manually test motor control and direction.");
+}
+
+QString MotorComponent::iconResource(void) const
+{
+ return QStringLiteral("/qmlimages/MotorComponentIcon.png");
+}
+
+bool MotorComponent::requiresSetup(void) const
+{
+ return false;
+}
+
+bool MotorComponent::setupComplete(void) const
+{
+ return true;
+}
+
+QStringList MotorComponent::setupCompleteChangedTriggerList(void) const
+{
+ return QStringList();
+}
+
+QUrl MotorComponent::setupSource(void) const
+{
+ return QUrl::fromUserInput(QStringLiteral("qrc:/qml/MotorComponent.qml"));
+}
+
+QUrl MotorComponent::summaryQmlSource(void) const
+{
+ return QUrl();
+}
+
+QString MotorComponent::prerequisiteSetup(void) const
+{
+ return QString();
+}
diff --git a/src/AutoPilotPlugins/Common/MotorComponent.h b/src/AutoPilotPlugins/Common/MotorComponent.h
new file mode 100644
index 0000000000000000000000000000000000000000..c44d77c103120bd84c5b02bdda5cadf9f075954b
--- /dev/null
+++ b/src/AutoPilotPlugins/Common/MotorComponent.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+ *
+ * (c) 2009-2016 QGROUNDCONTROL PROJECT
+ *
+ * QGroundControl is licensed according to the terms in the file
+ * COPYING.md in the root of the source code directory.
+ *
+ ****************************************************************************/
+
+
+#ifndef MotorComponent_H
+#define MotorComponent_H
+
+#include "VehicleComponent.h"
+#include "Fact.h"
+
+class MotorComponent : public VehicleComponent
+{
+ Q_OBJECT
+
+public:
+ MotorComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent = NULL);
+
+ // Virtuals from VehicleComponent
+ QStringList setupCompleteChangedTriggerList(void) const final;
+
+ // Virtuals from VehicleComponent
+ QString name(void) const final;
+ QString description(void) const final;
+ QString iconResource(void) const final;
+ bool requiresSetup(void) const final;
+ bool setupComplete(void) const final;
+ QUrl setupSource(void) const final;
+ QUrl summaryQmlSource(void) const final;
+ QString prerequisiteSetup(void) const final;
+
+private:
+ const QString _name;
+};
+
+#endif
diff --git a/src/AutoPilotPlugins/Common/MotorComponent.qml b/src/AutoPilotPlugins/Common/MotorComponent.qml
new file mode 100644
index 0000000000000000000000000000000000000000..2c8c3c536f898ff0b8ed8f869d54b270f6ad96d8
--- /dev/null
+++ b/src/AutoPilotPlugins/Common/MotorComponent.qml
@@ -0,0 +1,145 @@
+/****************************************************************************
+ *
+ * (c) 2009-2016 QGROUNDCONTROL PROJECT
+ *
+ * QGroundControl is licensed according to the terms in the file
+ * COPYING.md in the root of the source code directory.
+ *
+ ****************************************************************************/
+
+import QtQuick 2.5
+import QtQuick.Controls 1.2
+import QtQuick.Dialogs 1.2
+
+import QGroundControl 1.0
+import QGroundControl.Controls 1.0
+import QGroundControl.FactSystem 1.0
+import QGroundControl.ScreenTools 1.0
+
+SetupPage {
+ id: motorPage
+ pageComponent: pageComponent
+
+ readonly property int _barHeight: 10
+ readonly property int _barWidth: 5
+ readonly property int _sliderHeight: 10
+
+ FactPanelController {
+ id: controller
+ factPanel: motorPage.viewPanel
+ }
+
+ Component {
+ id: pageComponent
+
+ Column {
+ spacing: 10
+
+ Row {
+ id: motorSliders
+ enabled: safetySwitch.checked
+ spacing: ScreenTools.defaultFontPixelWidth * 4
+
+ Repeater {
+ id: sliderRepeater
+ model: controller.vehicle.motorCount == -1 ? 8 : controller.vehicle.motorCount
+
+ Column {
+ property alias motorSlider: slider
+
+ Timer {
+ interval: 250
+ running: true
+ repeat: true
+
+ property real _lastValue: 0
+
+ onTriggered: {
+ if (_lastValue != slider.value) {
+ controller.vehicle.motorTest(index + 1, slider.value, 1)
+ }
+ }
+ }
+
+ QGCLabel {
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: index + 1
+ }
+
+ QGCSlider {
+ id: slider
+ height: ScreenTools.defaultFontPixelHeight * _sliderHeight
+ orientation: Qt.Vertical
+ maximumValue: 100
+ value: 0
+ }
+ } // Column
+ } // Repeater
+
+ Column {
+ QGCLabel {
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: qsTr("All")
+ }
+
+ QGCSlider {
+ id: allSlider
+ height: ScreenTools.defaultFontPixelHeight * _sliderHeight
+ orientation: Qt.Vertical
+ maximumValue: 100
+ value: 0
+
+ onValueChanged: {
+ for (var sliderIndex=0; sliderIndex
+ *
+ * QGroundControl is licensed according to the terms in the file
+ * COPYING.md in the root of the source code directory.
+ *
+ ****************************************************************************/
+
+import QtQuick 2.5
+import QtQuick.Controls 1.2
+import QtQuick.Dialogs 1.2
+
+import QGroundControl 1.0
+import QGroundControl.FactSystem 1.0
+import QGroundControl.FactControls 1.0
+import QGroundControl.Palette 1.0
+import QGroundControl.Controls 1.0
+import QGroundControl.ScreenTools 1.0
+import QGroundControl.Controllers 1.0
+
+/// Base view control for all Setup pages
+QGCView {
+ id: setupView
+ viewPanel: setupPanel
+
+ property alias pageComponent: pageLoader.sourceComponent
+
+ property real _margins: ScreenTools.defaultFontPixelHeight / 2
+
+ QGCPalette { id: qgcPal; colorGroupEnabled: setupPanel.enabled }
+
+ QGCViewPanel {
+ id: setupPanel
+ anchors.fill: parent
+
+ QGCFlickable {
+ anchors.fill: parent
+ contentWidth: pageLoader.item.x + pageLoader.item.width
+ contentHeight: pageLoader.item.y + pageLoader.item.height
+ clip: true
+
+ Column {
+ id: headingColumn
+ anchors.left: parent.left
+ anchors.right: parent.right
+ spacing: _margins
+
+ QGCLabel {
+ font.pointSize: ScreenTools.largeFontPointSize
+ text: vehicleComponent.name + " " + qsTr("Setup")
+ visible: !ScreenTools.isShortScreen
+ }
+
+ QGCLabel {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ wrapMode: Text.WordWrap
+ text: vehicleComponent.description
+ visible: !ScreenTools.isShortScreen
+ }
+ }
+
+ Loader {
+ anchors.topMargin: _margins
+ anchors.top: headingColumn.bottom
+ id: pageLoader
+ }
+ }
+ }
+}
diff --git a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc
index 97be4040f2094ae7d801f1255b657f716f5c9a4a..a2f91ec7961e56eb1623fa0198770d1779b0abf3 100644
--- a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc
+++ b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc
@@ -22,16 +22,17 @@
/// @brief This is the AutoPilotPlugin implementatin for the MAV_AUTOPILOT_PX4 type.
/// @author Don Gagne
-PX4AutoPilotPlugin::PX4AutoPilotPlugin(Vehicle* vehicle, QObject* parent) :
- AutoPilotPlugin(vehicle, parent),
- _airframeComponent(NULL),
- _radioComponent(NULL),
- _esp8266Component(NULL),
- _flightModesComponent(NULL),
- _sensorsComponent(NULL),
- _safetyComponent(NULL),
- _powerComponent(NULL),
- _incorrectParameterVersion(false)
+PX4AutoPilotPlugin::PX4AutoPilotPlugin(Vehicle* vehicle, QObject* parent)
+ : AutoPilotPlugin(vehicle, parent)
+ , _airframeComponent(NULL)
+ , _radioComponent(NULL)
+ , _esp8266Component(NULL)
+ , _flightModesComponent(NULL)
+ , _sensorsComponent(NULL)
+ , _safetyComponent(NULL)
+ , _powerComponent(NULL)
+ , _motorComponent(NULL)
+ , _incorrectParameterVersion(false)
{
Q_ASSERT(vehicle);
@@ -74,6 +75,13 @@ const QVariantList& PX4AutoPilotPlugin::vehicleComponents(void)
_powerComponent->setupTriggerSignals();
_components.append(QVariant::fromValue((VehicleComponent*)_powerComponent));
+#if 0
+ // Coming soon
+ _motorComponent = new MotorComponent(_vehicle, this);
+ _motorComponent->setupTriggerSignals();
+ _components.append(QVariant::fromValue((VehicleComponent*)_motorComponent));
+#endif
+
_safetyComponent = new SafetyComponent(_vehicle, this);
_safetyComponent->setupTriggerSignals();
_components.append(QVariant::fromValue((VehicleComponent*)_safetyComponent));
diff --git a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h
index a7053943feeb9118c06308cd07bd1f92c98ccada..9bb2737ad8a0bf3ae1bb08fddfa4288e038750e7 100644
--- a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h
+++ b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h
@@ -21,6 +21,7 @@
#include "SafetyComponent.h"
#include "CameraComponent.h"
#include "PowerComponent.h"
+#include "MotorComponent.h"
#include "PX4TuningComponent.h"
#include "Vehicle.h"
@@ -50,6 +51,7 @@ public:
SafetyComponent* safetyComponent(void) { return _safetyComponent; }
CameraComponent* cameraComponent(void) { return _cameraComponent; }
PowerComponent* powerComponent(void) { return _powerComponent; }
+ MotorComponent* motorComponent(void) { return _motorComponent; }
PX4TuningComponent* tuningComponent(void) { return _tuningComponent; }
public slots:
@@ -67,6 +69,7 @@ private:
SafetyComponent* _safetyComponent;
CameraComponent* _cameraComponent;
PowerComponent* _powerComponent;
+ MotorComponent* _motorComponent;
PX4TuningComponent* _tuningComponent;
bool _incorrectParameterVersion; ///< true: parameter version incorrect, setup not allowed
};
diff --git a/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc b/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc
index 66e4bc19f27e686fa63e7befc52f80a1d974d724..aceb859adbcf1b3c13b3c053379fc719583ba39d 100644
--- a/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc
+++ b/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc
@@ -122,7 +122,6 @@ APMCustomMode::APMCustomMode(uint32_t mode, bool settable) :
{
}
-
void APMCustomMode::setEnumToStringMapping(const QMap& enumToString)
{
_enumToString = enumToString;
@@ -138,8 +137,10 @@ QString APMCustomMode::modeString() const
}
APMFirmwarePlugin::APMFirmwarePlugin(void)
+ : _coaxialMotors(false)
+ , _textSeverityAdjustmentNeeded(false)
{
- _textSeverityAdjustmentNeeded = false;
+
}
bool APMFirmwarePlugin::isCapable(FirmwareCapabilities capabilities)
@@ -380,6 +381,15 @@ bool APMFirmwarePlugin::_handleStatusText(Vehicle* vehicle, mavlink_message_t* m
// Start TCP video handshake with ARTOO
_soloVideoHandshake(vehicle);
+ } else if (messageText.contains(APM_FRAME_REXP)) {
+ // We need to parse the Frame: message in order to determine whether the motors are coaxial or not
+ QRegExp frameTypeRegex("^Frame: (\\S*)");
+ if (frameTypeRegex.indexIn(messageText) != -1) {
+ QString frameType = frameTypeRegex.cap(1);
+ if (!frameType.isEmpty() && (frameType == QStringLiteral("Y6") || frameType == QStringLiteral("OCTA_QUAD") || frameType == QStringLiteral("COAX"))) {
+ _coaxialMotors = true;
+ }
+ }
}
if (messageText.startsWith("PreArm")) {
diff --git a/src/FirmwarePlugin/APM/APMFirmwarePlugin.h b/src/FirmwarePlugin/APM/APMFirmwarePlugin.h
index 04d7f8b494e2d11839d57f163c5821548fbe7c47..357189b7d70dcb062496292de2e45b06dee183af 100644
--- a/src/FirmwarePlugin/APM/APMFirmwarePlugin.h
+++ b/src/FirmwarePlugin/APM/APMFirmwarePlugin.h
@@ -99,6 +99,8 @@ protected:
APMFirmwarePlugin(void);
void setSupportedModes(QList supportedModes);
+ bool _coaxialMotors;
+
private slots:
void _artooSocketError(QAbstractSocket::SocketError socketError);
diff --git a/src/FirmwarePlugin/APM/ArduCopterFirmwarePlugin.cc b/src/FirmwarePlugin/APM/ArduCopterFirmwarePlugin.cc
index 12b72c11bce139cb83dcb051150a2da4b43e021d..070cd30ef17dc035d7f96d2d2bfc8b09abb26faa 100644
--- a/src/FirmwarePlugin/APM/ArduCopterFirmwarePlugin.cc
+++ b/src/FirmwarePlugin/APM/ArduCopterFirmwarePlugin.cc
@@ -197,3 +197,14 @@ void ArduCopterFirmwarePlugin::setGuidedMode(Vehicle* vehicle, bool guidedMode)
pauseVehicle(vehicle);
}
}
+
+bool ArduCopterFirmwarePlugin::multiRotorCoaxialMotors(Vehicle* vehicle)
+{
+ Q_UNUSED(vehicle);
+ return _coaxialMotors;
+}
+
+bool ArduCopterFirmwarePlugin::multiRotorXConfig(Vehicle* vehicle)
+{
+ return vehicle->autopilotPlugin()->getParameterFact(FactSystem::defaultComponentId, "FRAME")->rawValue().toInt() != 0;
+}
diff --git a/src/FirmwarePlugin/APM/ArduCopterFirmwarePlugin.h b/src/FirmwarePlugin/APM/ArduCopterFirmwarePlugin.h
index a43670033d24d20ad524d459a08f0de1172fb11d..10c7fae922f95528579338cf49cbfb0d157a7493 100644
--- a/src/FirmwarePlugin/APM/ArduCopterFirmwarePlugin.h
+++ b/src/FirmwarePlugin/APM/ArduCopterFirmwarePlugin.h
@@ -64,6 +64,8 @@ public:
void guidedModeChangeAltitude(Vehicle* vehicle, double altitudeRel) final;
const FirmwarePlugin::remapParamNameMajorVersionMap_t& paramNameRemapMajorVersionMap(void) const final { return _remapParamName; }
virtual int remapParamNameHigestMinorVersionNumber(int majorVersionNumber) const final;
+ virtual bool multiRotorCoaxialMotors(Vehicle* vehicle) final;
+ virtual bool multiRotorXConfig(Vehicle* vehicle) final;
private:
static bool _remapParamNameIntialized;
diff --git a/src/FirmwarePlugin/FirmwarePlugin.h b/src/FirmwarePlugin/FirmwarePlugin.h
index 393a690290d6e90b5177694fedd62eb781d38133..c64cbdc98ae7af9c35b9d7a7510022ca187af62d 100644
--- a/src/FirmwarePlugin/FirmwarePlugin.h
+++ b/src/FirmwarePlugin/FirmwarePlugin.h
@@ -181,6 +181,12 @@ public:
/// Returns the highest major version number that is known to the remap for this specified major version.
virtual int remapParamNameHigestMinorVersionNumber(int majorVersionNumber) const;
+
+ /// @return true: Motors are coaxial like an X8 config, false: Quadcopter for example
+ virtual bool multiRotorCoaxialMotors(Vehicle* vehicle) { Q_UNUSED(vehicle); return false; }
+
+ /// @return true: X confiuration, false: Plus configuration
+ virtual bool multiRotorXConfig(Vehicle* vehicle) { Q_UNUSED(vehicle); return false; }
};
#endif
diff --git a/src/FlightMap/Widgets/QGCSlider.qml b/src/FlightMap/Widgets/QGCSlider.qml
deleted file mode 100644
index 2a2b4244959c2a980b1e2c2339dbc8ee15f801e8..0000000000000000000000000000000000000000
--- a/src/FlightMap/Widgets/QGCSlider.qml
+++ /dev/null
@@ -1,122 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.1
-import QGroundControl.Controls 1.0
-import QGroundControl.ScreenTools 1.0
-
-Item {
- id: slider;
- height: 12
- property real value // value is read/write.
- property real minimum: 0
- property real maximum: 1
- property int length: width - handle.width
-
- Rectangle {
- anchors.fill: parent
- radius: ScreenTools.defaultFontPixelHeight * (0.5)
- color: Qt.rgba(0,0,0,0.65);
- }
-
- Rectangle {
- anchors.left: parent.left
- anchors.leftMargin: ScreenTools.defaultFontPixelHeight * (0.33)
- radius: ScreenTools.defaultFontPixelHeight * (0.33)
- height: ScreenTools.defaultFontPixelHeight * (0.33)
- width: handle.x - x
- color: "#69bb17"
- anchors.verticalCenter: parent.verticalCenter
- }
-
- Rectangle {
- id: labelRect
- width: label.width
- height: label.height + ScreenTools.defaultFontPixelHeight * (0.33)
- radius: ScreenTools.defaultFontPixelHeight * (0.33)
- smooth: true
- color: Qt.rgba(1,1,1,0.75);
- border.width: ScreenTools.defaultFontPixelHeight * (0.083)
- border.color: Qt.rgba(0,0,0,0.45);
- anchors.bottom: handle.top
- anchors.bottomMargin: ScreenTools.defaultFontPixelHeight * (0.33)
- visible: mouseRegion.pressed
- x: Math.max(Math.min(handle.x + (handle.width - width ) / 2, slider.width - width), 0)
- QGCLabel{
- id: label
- color: "black"
- text: slider.value.toFixed(2)
- width: font.pointSize * 3.5
- anchors.horizontalCenter: labelRect.horizontalCenter
- horizontalAlignment: Text.AlignHCenter
- anchors.verticalCenter: labelRect.verticalCenter
- }
- }
-
- Rectangle {
- id: handle;
- smooth: true
- width: ScreenTools.defaultFontPixelHeight * (2.16);
- y: (slider.height - height) / 2;
- x: (slider.value - slider.minimum) * slider.length / (slider.maximum - slider.minimum)
-
- height: width
- radius: width / 2
- gradient: normalGradient
- border.width: 2
- border.color: "white"
-
- Gradient {
- id: normalGradient
- GradientStop { position: 0.0; color: "#b0b0b0" }
- GradientStop { position: 0.66; color: "#909090" }
- GradientStop { position: 1.0; color: "#545454" }
- }
-
- MouseArea {
- id: mouseRegion
- hoverEnabled: false
- anchors.fill: parent; drag.target: parent
- drag.axis: Drag.XAxis; drag.minimumX: 0; drag.maximumX: slider.length
- preventStealing: true
- onPositionChanged: { slider.value = (slider.maximum - slider.minimum) * handle.x / slider.length + slider.minimum; }
- }
- }
-}
diff --git a/src/QmlControls/MultiRotorMotorDisplay.qml b/src/QmlControls/MultiRotorMotorDisplay.qml
new file mode 100644
index 0000000000000000000000000000000000000000..c1cd094816bda9e632c2e78dc83620356eb39bed
--- /dev/null
+++ b/src/QmlControls/MultiRotorMotorDisplay.qml
@@ -0,0 +1,156 @@
+import QtQuick 2.2
+
+import QGroundControl.Palette 1.0
+import QGroundControl.ScreenTools 1.0
+
+Item {
+ id: motorRoot
+
+ property int motorCount: 4 // Number of motors on vehicle
+ property bool xConfig: true // true: X configuration, false: Plus configuration
+ property bool coaxial: true // true: motors on top bottom of same arm, false: motors only on top of arm
+
+ property bool _unsupportedConfig: motorCount == 3 || (motorCount == 6 && coaxial) // Tricopters NYI
+ property var _qgcPal: QGCPalette { colorGroupEnabled: enabled }
+ property real _rotorRadius: motorRoot.height / 8
+ property int _motorsPerSide: motorCount / (coaxial ? 2 : 1)
+
+ readonly property string _cwColor: "green"
+ readonly property string _ccwColor: "blue"
+ readonly property var _motorColors4Plus: [ _ccwColor, _cwColor ]
+ readonly property var _motorColors4X: [ _cwColor, _ccwColor ]
+ readonly property var _motorColors6: [ _cwColor, _ccwColor ]
+ readonly property var _motorColors8: [ _cwColor, _ccwColor ]
+ readonly property var _motorColors4Top: [ _cwColor, _ccwColor ]
+ readonly property var _motorColors4Bottom: [ _ccwColor, _cwColor ]
+
+ readonly property var _motorNumbers4Plus: [ 1, 4, 2, 3 ]
+ readonly property var _motorNumbers4X: [ 4, 2, 3, 1 ]
+ readonly property var _motorNumbers6Plus: [ 6, 2, 3, 5, 1, 4 ]
+ readonly property var _motorNumbers6X: [ 1, 4, 6, 2, 3, 5 ]
+ readonly property var _motorNumbers8: [ 8, 4, 2, 6, 7, 5, 1, 3 ]
+ readonly property var _motorNumbers4Top: [ 4, 3, 2, 1 ]
+ readonly property var _motorNumbers4Bottom: [ 7, 8, 5, 6 ]
+
+ Component.onCompleted: {
+ if (coaxial) {
+ topMotors.motorNumbers = _motorNumbers4Top
+ bottomMotors.motorNumbers = _motorNumbers4Bottom
+ } else {
+ switch (motorCount) {
+ case 4:
+ topMotors.motorNumbers = xConfig ? _motorNumbers4X : _motorNumbers4Plus
+ topMotors.motorColors = xConfig ? _motorColors4X : _motorColors4Plus
+ break
+ case 6:
+ topMotors.motorNumbers = xConfig ? _motorNumbers6X : _motorNumbers6Plus
+ topMotors.motorColors = _motorColors6
+ break
+ default:
+ case 8:
+ topMotors.motorNumbers = _motorNumbers8
+ topMotors.motorColors = _motorColors8
+ break
+ }
+ bottomMotors.motorNumbers = _motorNumbers8
+ }
+ }
+
+ Component {
+ id: motorDisplayComponent
+
+ Repeater {
+ id: motorRepeater
+ model: _motorsPerSide
+
+ Item {
+ x: motorRepeater.width / 2 + _armXCenter - rotor.radius
+ y: motorRepeater.height / 2 + _armYCenter - rotor.radius
+ width: _rotorRadius * 2
+ height: _rotorRadius * 2
+
+ property real _armOffsetRadians: ((2 * Math.PI) / _motorsPerSide)
+ property real _armOffsetIndexRadians: (_armOffsetRadians * index) + ((xConfig && _motorsPerSide != 6) || (!xConfig && _motorsPerSide == 6) ? _armOffsetRadians / 2 : 0)
+ property real _armLength: (motorRepeater.height / 2) - (_rotorRadius * (xConfig && _motorsPerSide == 4 ? 0 : 1))
+ property real _armXCenter: Math.cos(_armOffsetIndexRadians) * _armLength // adjacent = cos * hypotenuse
+ property real _armYCenter: Math.sin(_armOffsetIndexRadians) * _armLength // opposite = sin * hypotenuse
+
+ Rectangle {id: rotor
+ anchors.fill: parent
+ radius: _rotorRadius
+ color: motorColors[index & 1]
+ opacity: topCoaxial ? 0.65 : 1.0
+ border.color: topCoaxial ? "black" : color
+
+ readonly property bool topCoaxial: topMotors && coaxial
+ }
+
+ Rectangle {
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+ width: radius *2
+ height: radius *2
+ radius: ScreenTools.defaultFontPixelHeight / 2
+ color: "white"
+ border.color: "black"
+
+ QGCLabel {
+ anchors.fill: parent
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ text: motorNumbers[index]
+ color: parent.border.color
+ }
+ }
+ } // Item
+ } // Repeater
+ } // Component - MotorDisplayComponent
+
+ Item {
+ anchors.fill: parent
+ visible: !_unsupportedConfig
+
+ Loader {
+ id: bottomMotors
+ anchors.topMargin: ScreenTools.defaultFontPixelHeight
+ anchors.fill: parent
+ sourceComponent: motorDisplayComponent
+ visible: coaxial
+
+ property bool topMotors: false
+ property var motorNumbers: _motorNumbers8
+ property var motorColors: _motorColors4Bottom
+ }
+
+ Loader {
+ id: topMotors
+ anchors.fill: parent
+ anchors.bottomMargin: coaxial ? ScreenTools.defaultFontPixelHeight : 0
+ sourceComponent: motorDisplayComponent
+
+ property bool topMotors: true
+ property var motorNumbers: _motorNumbers8
+ property var motorColors: _motorColors4Top
+ }
+
+ // Body direction
+ Canvas {
+ anchors.fill: parent
+
+ property real _centerX : width / 2
+ property real _centerY : height / 2
+
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.lineWidth = 3
+ ctx.strokeStyle = _qgcPal.text
+ ctx.translate(_centerX, _centerY)
+ ctx.moveTo(0, -_rotorRadius / 2);
+ ctx.lineTo(_rotorRadius / 2, _rotorRadius);
+ ctx.lineTo(-_rotorRadius / 2, _rotorRadius);
+ ctx.lineTo(0, -_rotorRadius / 2);
+ ctx.stroke();
+ }
+ }
+ } // Item
+} // Item
diff --git a/src/QmlControls/MultiRotorMotorDisplayLegend.qml b/src/QmlControls/MultiRotorMotorDisplayLegend.qml
new file mode 100644
index 0000000000000000000000000000000000000000..97f186cdc3e5f0de6574d06059789cf9eb0e487d
--- /dev/null
+++ b/src/QmlControls/MultiRotorMotorDisplayLegend.qml
@@ -0,0 +1,71 @@
+import QtQuick 2.2
+
+import QGroundControl.Palette 1.0
+import QGroundControl.ScreenTools 1.0
+
+Item {
+ id: legendRoot
+
+ property var _qgcPal: QGCPalette { colorGroupEnabled: enabled }
+ property real _rotorRadius: legendRoot.height / 16
+
+ readonly property string _cwColor: "green"
+ readonly property string _ccwColor: "blue"
+
+ Item {
+ id: cwItem
+ anchors.left: parent.left
+ anchors.right: parent.right
+ height: legendRoot.height / 2
+
+ Rectangle {
+ id: cwRotor
+ anchors.left: parent.left
+ anchors.verticalCenter: parent.verticalCenter
+ width: _rotorRadius * 2
+ height: _rotorRadius * 2
+ radius: _rotorRadius
+ color: _cwColor
+ }
+
+ QGCLabel {
+ anchors.leftMargin: ScreenTools.defaultFontPixelWidth
+ anchors.left: cwRotor.right
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ verticalAlignment: Text.AlignVCenter
+ wrapMode: Text.WordWrap
+ text: qsTr("Clockwise rotation, use pusher propellor")
+ }
+ }
+
+ Item {
+ id: ccwItem
+ anchors.top: cwItem.bottom
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ Rectangle {
+ id: ccwRotor
+ anchors.left: parent.left
+ anchors.verticalCenter: parent.verticalCenter
+ width: _rotorRadius * 2
+ height: _rotorRadius * 2
+ radius: _rotorRadius
+ color: _ccwColor
+ }
+
+ QGCLabel {
+ anchors.leftMargin: ScreenTools.defaultFontPixelWidth
+ anchors.left: ccwRotor.right
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ verticalAlignment: Text.AlignVCenter
+ wrapMode: Text.WordWrap
+ text: qsTr("Counter-Clockwise rotation, use normal propellor")
+ }
+ }
+} // Item
diff --git a/src/QmlControls/QGCSlider.qml b/src/QmlControls/QGCSlider.qml
new file mode 100644
index 0000000000000000000000000000000000000000..d08303982d5c862dd151ab2e9a7619a6ed6d9c1e
--- /dev/null
+++ b/src/QmlControls/QGCSlider.qml
@@ -0,0 +1,56 @@
+/****************************************************************************
+ *
+ * (c) 2009-2016 QGROUNDCONTROL PROJECT
+ *
+ * QGroundControl is licensed according to the terms in the file
+ * COPYING.md in the root of the source code directory.
+ *
+ ****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Styles 1.2
+import QtQuick.Controls.Private 1.0
+
+import QGroundControl.Palette 1.0
+import QGroundControl.ScreenTools 1.0
+
+Slider {
+ property var _qgcPal: QGCPalette { colorGroupEnabled: enabled }
+
+ style: SliderStyle {
+ groove: Item {
+ property color fillColor: "#49d"
+ anchors.verticalCenter: parent.verticalCenter
+ implicitWidth: Math.round(TextSingleton.implicitHeight * 4.5)
+ implicitHeight: Math.max(6, Math.round(TextSingleton.implicitHeight * 0.3))
+
+ Rectangle {
+ radius: height/2
+ anchors.fill: parent
+ border.width: 1
+ border.color: "#888"
+ gradient: Gradient {
+ GradientStop { color: "#bbb" ; position: 0 }
+ GradientStop { color: "#ccc" ; position: 0.6 }
+ GradientStop { color: "#ccc" ; position: 1 }
+ }
+ }
+
+ Item {
+ clip: true
+ width: styleData.handlePosition
+ height: parent.height
+ Rectangle {
+ anchors.fill: parent
+ border.color: Qt.darker(fillColor, 1.2)
+ radius: height/2
+ gradient: Gradient {
+ GradientStop {color: Qt.lighter(fillColor, 1.3) ; position: 0}
+ GradientStop {color: fillColor ; position: 1.4}
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/QmlControls/QGroundControl.Controls.qmldir b/src/QmlControls/QGroundControl.Controls.qmldir
index 5595c7f195e1680942d7451f754f39feebcd663a..6a9a1170cbdd2b320c370d2c82def990c55416dd 100644
--- a/src/QmlControls/QGroundControl.Controls.qmldir
+++ b/src/QmlControls/QGroundControl.Controls.qmldir
@@ -13,6 +13,8 @@ MissionItemEditor 1.0 MissionItemEditor.qml
MissionItemIndexLabel 1.0 MissionItemIndexLabel.qml
MissionItemStatus 1.0 MissionItemStatus.qml
ModeSwitchDisplay 1.0 ModeSwitchDisplay.qml
+MultiRotorMotorDisplay 1.0 MultiRotorMotorDisplay.qml
+MultiRotorMotorDisplayLegend 1.0 MultiRotorMotorDisplayLegend.qml
ParameterEditor 1.0 ParameterEditor.qml
ParameterEditorDialog 1.0 ParameterEditorDialog.qml
RCChannelMonitor 1.0 RCChannelMonitor.qml
@@ -26,6 +28,7 @@ QGCMobileFileDialog 1.0 QGCMobileFileDialog.qml
QGCMovableItem 1.0 QGCMovableItem.qml
QGCPipable 1.0 QGCPipable.qml
QGCRadioButton 1.0 QGCRadioButton.qml
+QGCSlider 1.0 QGCSlider.qml
QGCTextField 1.0 QGCTextField.qml
QGCToolBarButton 1.0 QGCToolBarButton.qml
QGCView 1.0 QGCView.qml
@@ -33,6 +36,7 @@ QGCViewDialog 1.0 QGCViewDialog.qml
QGCViewMessage 1.0 QGCViewMessage.qml
QGCViewPanel 1.0 QGCViewPanel.qml
RoundButton 1.0 RoundButton.qml
+SetupPage 1.0 SetupPage.qml
SignalStrength 1.0 SignalStrength.qml
SliderSwitch 1.0 SliderSwitch.qml
SubMenuButton 1.0 SubMenuButton.qml
diff --git a/src/Vehicle/Vehicle.cc b/src/Vehicle/Vehicle.cc
index 408023f57c2ac8482554cc3b5b0f6f04a5eb8211..230fb67b73f446fa11d9c7757afab2792fcd27fb 100644
--- a/src/Vehicle/Vehicle.cc
+++ b/src/Vehicle/Vehicle.cc
@@ -916,6 +916,37 @@ void Vehicle::_updateNavigationControllerData(UASInterface *uas, float, float, f
}
}
+int Vehicle::motorCount(void)
+{
+ switch (_vehicleType) {
+ case MAV_TYPE_HELICOPTER:
+ return 1;
+ case MAV_TYPE_VTOL_DUOROTOR:
+ return 2;
+ case MAV_TYPE_TRICOPTER:
+ return 3;
+ case MAV_TYPE_QUADROTOR:
+ case MAV_TYPE_VTOL_QUADROTOR:
+ return 4;
+ case MAV_TYPE_HEXAROTOR:
+ return 6;
+ case MAV_TYPE_OCTOROTOR:
+ return 8;
+ default:
+ return -1;
+ }
+}
+
+bool Vehicle::coaxialMotors(void)
+{
+ return _firmwarePlugin->multiRotorCoaxialMotors(this);
+}
+
+bool Vehicle::xConfigMotors(void)
+{
+ return _firmwarePlugin->multiRotorXConfig(this);
+}
+
/*
* Internal
*/
@@ -1738,6 +1769,11 @@ void Vehicle::setSoloFirmware(bool soloFirmware)
}
}
+void Vehicle::motorTest(int motor, int percent, int timeoutSecs)
+{
+ doCommandLong(defaultComponentId(), MAV_CMD_DO_MOTOR_TEST, motor, MOTOR_TEST_THROTTLE_PERCENT, percent, timeoutSecs);
+}
+
const char* VehicleGPSFactGroup::_hdopFactName = "hdop";
const char* VehicleGPSFactGroup::_vdopFactName = "vdop";
const char* VehicleGPSFactGroup::_courseOverGroundFactName = "courseOverGround";
diff --git a/src/Vehicle/Vehicle.h b/src/Vehicle/Vehicle.h
index ebc398bdff2ebd250318a9d5de73f62306726850..07a8f1bb118e5f744f680d5406d2430ede302350 100644
--- a/src/Vehicle/Vehicle.h
+++ b/src/Vehicle/Vehicle.h
@@ -277,6 +277,9 @@ public:
Q_PROPERTY(bool rover READ rover CONSTANT)
Q_PROPERTY(bool autoDisconnect MEMBER _autoDisconnect NOTIFY autoDisconnectChanged)
Q_PROPERTY(QString prearmError READ prearmError WRITE setPrearmError NOTIFY prearmErrorChanged)
+ Q_PROPERTY(int motorCount READ motorCount CONSTANT)
+ Q_PROPERTY(bool coaxialMotors READ coaxialMotors CONSTANT)
+ Q_PROPERTY(bool xConfigMotors READ xConfigMotors CONSTANT)
/// true: Vehicle is flying, false: Vehicle is on ground
Q_PROPERTY(bool flying READ flying WRITE setFlying NOTIFY flyingChanged)
@@ -362,6 +365,12 @@ public:
/// Clear Messages
Q_INVOKABLE void clearMessages();
+ /// Test motor
+ /// @param motor Motor number, 1-based
+ /// @param percent 0-no power, 100-full power
+ /// @param timeoutSecs Number of seconds for motor to run
+ Q_INVOKABLE void motorTest(int motor, int percent, int timeoutSecs);
+
bool guidedModeSupported(void) const;
bool pauseVehicleSupported(void) const;
@@ -438,7 +447,6 @@ public:
QString flightMode(void) const;
void setFlightMode(const QString& flightMode);
-
bool hilMode(void);
void setHilMode(bool hilMode);
@@ -535,6 +543,15 @@ public:
int defaultComponentId(void);
+ /// @return -1 = Unknown, Number of motors on vehicle
+ int motorCount(void);
+
+ /// @return true: Motors are coaxial like an X8 config, false: Quadcopter for example
+ bool coaxialMotors(void);
+
+ /// @return true: X confiuration, false: Plus configuration
+ bool xConfigMotors(void);
+
public slots:
void setLatitude(double latitude);
void setLongitude(double longitude);
diff --git a/src/VehicleSetup/SetupView.qml b/src/VehicleSetup/SetupView.qml
index d433694974dcb51d96270e3b07a2d75807bd7a2c..4901597da6b66bb51ee9d6d0736cb576ee610db1 100644
--- a/src/VehicleSetup/SetupView.qml
+++ b/src/VehicleSetup/SetupView.qml
@@ -97,6 +97,7 @@ Rectangle {
_messagePanelText = vehicleComponent.prerequisiteSetup + " setup must be completed prior to " + vehicleComponent.name + " setup."
panelLoader.sourceComponent = messagePanelComponent
} else {
+ panelLoader.vehicleComponent = vehicleComponent
panelLoader.source = vehicleComponent.setupSource
for(var i = 0; i < componentRepeater.count; i++) {
var obj = componentRepeater.itemAt(i);
@@ -324,5 +325,7 @@ Rectangle {
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
+
+ property var vehicleComponent
}
}