diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro
index 0e69320..4156b72 100644
--- a/qgroundcontrol.pro
+++ b/qgroundcontrol.pro
@@ -557,6 +557,7 @@ HEADERS+= \
src/AutoPilotPlugins/APM/APMSafetyComponent.h \
src/AutoPilotPlugins/APM/APMSensorsComponent.h \
src/AutoPilotPlugins/APM/APMSensorsComponentController.h \
+ src/AutoPilotPlugins/APM/APMTuningComponent.h \
src/AutoPilotPlugins/Common/RadioComponentController.h \
src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.h \
src/AutoPilotPlugins/PX4/AirframeComponent.h \
@@ -607,6 +608,7 @@ SOURCES += \
src/AutoPilotPlugins/APM/APMSafetyComponent.cc \
src/AutoPilotPlugins/APM/APMSensorsComponent.cc \
src/AutoPilotPlugins/APM/APMSensorsComponentController.cc \
+ src/AutoPilotPlugins/APM/APMTuningComponent.cc \
src/AutoPilotPlugins/Common/RadioComponentController.cc \
src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.cc \
src/AutoPilotPlugins/PX4/AirframeComponent.cc \
diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc
index adfbf59..61848f0 100644
--- a/qgroundcontrol.qrc
+++ b/qgroundcontrol.qrc
@@ -113,6 +113,9 @@
src/AutoPilotPlugins/APM/APMSafetyComponentSummaryCopter.qml
src/AutoPilotPlugins/APM/APMSafetyComponentSummaryPlane.qml
src/AutoPilotPlugins/APM/APMSafetyComponentSummaryRover.qml
+ src/AutoPilotPlugins/APM/APMTuningComponentCopter.qml
+ src/AutoPilotPlugins/APM/APMTuningComponentPlane.qml
+ src/AutoPilotPlugins/APM/APMTuningComponentRover.qml
src/AutoPilotPlugins/PX4/SafetyComponent.qml
src/AutoPilotPlugins/PX4/SafetyComponentSummary.qml
src/AutoPilotPlugins/PX4/SensorsComponent.qml
diff --git a/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc b/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc
index 13bbce5..b04d522 100644
--- a/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc
+++ b/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc
@@ -36,6 +36,7 @@ APMAutoPilotPlugin::APMAutoPilotPlugin(Vehicle* vehicle, QObject* parent)
, _radioComponent(NULL)
, _safetyComponent(NULL)
, _sensorsComponent(NULL)
+ , _tuningComponent(NULL)
{
Q_ASSERT(vehicle);
}
@@ -90,6 +91,14 @@ const QVariantList& APMAutoPilotPlugin::vehicleComponents(void)
} else {
qWarning() << "new APMSafetyComponent failed";
}
+
+ _tuningComponent = new APMTuningComponent(_vehicle, this);
+ if (_tuningComponent) {
+ _tuningComponent->setupTriggerSignals();
+ _components.append(QVariant::fromValue((VehicleComponent*)_tuningComponent));
+ } else {
+ qWarning() << "new APMTuningComponent failed";
+ }
} else {
qWarning() << "Call to vehicleCompenents prior to parametersReady";
}
diff --git a/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h b/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h
index 41f081c..c26dee7 100644
--- a/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h
+++ b/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h
@@ -31,6 +31,7 @@
#include "APMRadioComponent.h"
#include "APMSafetyComponent.h"
#include "APMSensorsComponent.h"
+#include "APMTuningComponent.h"
/// This is the APM specific implementation of the AutoPilot class.
class APMAutoPilotPlugin : public AutoPilotPlugin
@@ -49,6 +50,7 @@ public:
APMRadioComponent* radioComponent (void) { return _radioComponent; }
APMSafetyComponent* safetyComponent (void) { return _safetyComponent; }
APMSensorsComponent* sensorsComponent (void) { return _sensorsComponent; }
+ APMTuningComponent* tuningComponent (void) { return _tuningComponent; }
public slots:
// FIXME: This is public until we restructure AutoPilotPlugin/FirmwarePlugin/Vehicle
@@ -63,6 +65,7 @@ private:
APMRadioComponent* _radioComponent;
APMSafetyComponent* _safetyComponent;
APMSensorsComponent* _sensorsComponent;
+ APMTuningComponent* _tuningComponent;
};
#endif
diff --git a/src/AutoPilotPlugins/APM/APMTuningComponent.cc b/src/AutoPilotPlugins/APM/APMTuningComponent.cc
new file mode 100644
index 0000000..ca61ec1
--- /dev/null
+++ b/src/AutoPilotPlugins/APM/APMTuningComponent.cc
@@ -0,0 +1,105 @@
+/*=====================================================================
+
+ 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 .
+
+ ======================================================================*/
+
+#include "APMTuningComponent.h"
+#include "APMAutoPilotPlugin.h"
+
+APMTuningComponent::APMTuningComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent)
+ : APMComponent(vehicle, autopilot, parent)
+ , _name("Tuning")
+{
+}
+
+QString APMTuningComponent::name(void) const
+{
+ return _name;
+}
+
+QString APMTuningComponent::description(void) const
+{
+ return tr("The Tuning Component is used to tune the flight characteristics of the Vehicle.");
+}
+
+QString APMTuningComponent::iconResource(void) const
+{
+ return "/qmlimages/subMenuButtonImage.png";
+}
+
+bool APMTuningComponent::requiresSetup(void) const
+{
+ return false;
+}
+
+bool APMTuningComponent::setupComplete(void) const
+{
+ return true;
+}
+
+QStringList APMTuningComponent::setupCompleteChangedTriggerList(void) const
+{
+ return QStringList();
+}
+
+QUrl APMTuningComponent::setupSource(void) const
+{
+ QString qmlFile;
+
+ switch (_vehicle->vehicleType()) {
+ case MAV_TYPE_FIXED_WING:
+ qmlFile = "qrc:/qml/APMTuningComponentPlane.qml";
+ break;
+ case MAV_TYPE_QUADROTOR:
+ case MAV_TYPE_COAXIAL:
+ case MAV_TYPE_HELICOPTER:
+ case MAV_TYPE_HEXAROTOR:
+ case MAV_TYPE_OCTOROTOR:
+ case MAV_TYPE_TRICOPTER:
+ qmlFile = "qrc:/qml/APMTuningComponentCopter.qml";
+ break;
+ case MAV_TYPE_GROUND_ROVER:
+ qmlFile = "qrc:/qml/APMTuningComponentRover.qml";
+ break;
+ default:
+ qmlFile = "qrc:/qml/APMNotSupported.qml";
+ break;
+ }
+
+ return QUrl::fromUserInput(qmlFile);
+}
+
+QUrl APMTuningComponent::summaryQmlSource(void) const
+{
+ return QUrl();
+}
+
+QString APMTuningComponent::prerequisiteSetup(void) const
+{
+ APMAutoPilotPlugin* plugin = dynamic_cast(_autopilot);
+ Q_ASSERT(plugin);
+
+ if (!plugin->airframeComponent()->setupComplete()) {
+ return plugin->airframeComponent()->name();
+ }
+
+ return QString();
+}
diff --git a/src/AutoPilotPlugins/APM/APMTuningComponent.h b/src/AutoPilotPlugins/APM/APMTuningComponent.h
new file mode 100644
index 0000000..4ad2359
--- /dev/null
+++ b/src/AutoPilotPlugins/APM/APMTuningComponent.h
@@ -0,0 +1,54 @@
+/*=====================================================================
+
+ 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 APMTuningComponent_H
+#define APMTuningComponent_H
+
+#include "APMComponent.h"
+
+class APMTuningComponent : public APMComponent
+{
+ Q_OBJECT
+
+public:
+ APMTuningComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent = NULL);
+
+ // Virtuals from PX4Component
+ virtual QStringList setupCompleteChangedTriggerList(void) const;
+
+ // Virtuals from VehicleComponent
+ virtual QString name(void) const;
+ virtual QString description(void) const;
+ virtual QString iconResource(void) const;
+ virtual bool requiresSetup(void) const;
+ virtual bool setupComplete(void) const;
+ virtual QUrl setupSource(void) const;
+ virtual QUrl summaryQmlSource(void) const;
+ virtual QString prerequisiteSetup(void) const;
+
+private:
+ const QString _name;
+ QVariantList _summaryItems;
+};
+
+#endif
diff --git a/src/AutoPilotPlugins/APM/APMTuningComponentCopter.qml b/src/AutoPilotPlugins/APM/APMTuningComponentCopter.qml
new file mode 100644
index 0000000..1e7d628
--- /dev/null
+++ b/src/AutoPilotPlugins/APM/APMTuningComponentCopter.qml
@@ -0,0 +1,234 @@
+/*=====================================================================
+
+ 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 .
+
+ ======================================================================*/
+
+import QtQuick 2.5
+import QtQuick.Controls 1.4
+
+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
+
+QGCView {
+ id: _safetyView
+ viewPanel: panel
+ anchors.fill: parent
+
+ FactPanelController { id: controller; factPanel: panel }
+
+ QGCPalette { id: palette; colorGroupEnabled: enabled }
+
+ property Fact _throttleMid: controller.getParameterFact(-1, "THR_MID")
+ property Fact _rcFeel: controller.getParameterFact(-1, "RC_FEEL_RP")
+ property Fact _rateRollP: controller.getParameterFact(-1, "RATE_RLL_P")
+ property Fact _rateRollI: controller.getParameterFact(-1, "RATE_RLL_I")
+ property Fact _ratePitchP: controller.getParameterFact(-1, "RATE_PIT_P")
+ property Fact _ratePitchI: controller.getParameterFact(-1, "RATE_PIT_I")
+ property Fact _rateClimbP: controller.getParameterFact(-1, "ACCEL_Z_P")
+ property Fact _rateClimbI: controller.getParameterFact(-1, "ACCEL_Z_I")
+
+ property real _margins: ScreenTools.defaultFontPixelHeight
+
+ property bool _loadComplete: false
+
+ ExclusiveGroup { id: fenceActionRadioGroup }
+ ExclusiveGroup { id: landLoiterRadioGroup }
+ ExclusiveGroup { id: returnAltRadioGroup }
+
+ Component.onCompleted: {
+ // Qml Sliders have a strange behavior in which they first set Slider::value to some internal
+ // setting and then set Slider::value to the bound properties value. If you have an onValueChanged
+ // handler which updates your property with the new value, this first value change will trash
+ // your bound values. In order to work around this we don't set the values into the Sliders until
+ // after Qml load is done. We also don't track value changes until Qml load completes.
+ throttleHover.value = _throttleMid.value
+ rollPitch.value = _rateRollP.value
+ climb.value = _rateClimbP.value
+ rcFeel.value = _rcFeel.value
+ _loadComplete = true
+ }
+
+ QGCViewPanel {
+ id: panel
+ anchors.fill: parent
+
+ Flickable {
+ clip: true
+ anchors.fill: parent
+ boundsBehavior: Flickable.StopAtBounds
+ contentHeight: basicTuning.y + basicTuning.height
+ flickableDirection: Flickable.VerticalFlick
+
+ QGCLabel {
+ id: basicLabel
+ text: "Basic Tuning"
+ font.weight: Font.DemiBold
+ }
+
+ Rectangle {
+ id: basicTuning
+ anchors.topMargin: _margins / 2
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.top: basicLabel.bottom
+ height: basicTuningColumn.y + basicTuningColumn.height + _margins
+ color: palette.windowShade
+
+ Column {
+ id: basicTuningColumn
+ anchors.margins: _margins
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.top: parent.top
+ spacing: _margins
+
+ Column {
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ QGCLabel {
+ text: "Throttle Hover"
+ font.weight: Font.DemiBold
+ }
+
+ QGCLabel {
+ text: "How much throttle is needed to maintain a steady hover"
+ }
+
+ Slider {
+ id: throttleHover
+ anchors.left: parent.left
+ anchors.right: parent.right
+ minimumValue: 200
+ maximumValue: 800
+ stepSize: 10.0
+ tickmarksEnabled: true
+
+ onValueChanged: {
+ if (_loadComplete) {
+ _throttleMid.value = value
+ }
+ }
+ }
+ }
+
+ Column {
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ QGCLabel {
+ text: "Roll/Pitch Sensitivity"
+ font.weight: Font.DemiBold
+ }
+
+ QGCLabel {
+ text: "Slide to the right if the copter is sluggish or slide to the left if the copter is twitchy"
+ }
+
+ Slider {
+ id: rollPitch
+ anchors.left: parent.left
+ anchors.right: parent.right
+ minimumValue: 0.08
+ maximumValue: 0.4
+ stepSize: 0.01
+ tickmarksEnabled: true
+
+ onValueChanged: {
+ if (_loadComplete) {
+ _rateRollP.value = value
+ _rateRollI.value = value
+ _ratePitchP.value = value
+ _ratePitchI.value = value
+ }
+ }
+ }
+ }
+
+ Column {
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ QGCLabel {
+ text: "Climb Sensitivity"
+ font.weight: Font.DemiBold
+ }
+
+ QGCLabel {
+ text: "Slide to the right to climb more aggressively or slide to the left to climb more gently"
+ }
+
+ Slider {
+ id: climb
+ anchors.left: parent.left
+ anchors.right: parent.right
+ minimumValue: 0.3
+ maximumValue: 1.0
+ stepSize: 0.02
+ tickmarksEnabled: true
+ value: _rateClimbP.value
+
+ onValueChanged: {
+ if (_loadComplete) {
+ _rateClimbP.value = value
+ _rateClimbI.value = value * 2
+ }
+ }
+ }
+ }
+
+ Column {
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ QGCLabel {
+ text: "RC Roll/Pitch Feel"
+ font.weight: Font.DemiBold
+ }
+
+ QGCLabel {
+ text: "Slide to the left for soft control, slide to the right for crisp control"
+ }
+
+ Slider {
+ id: rcFeel
+ anchors.left: parent.left
+ anchors.right: parent.right
+ minimumValue: 0
+ maximumValue: 100
+ stepSize: 5.0
+ tickmarksEnabled: true
+
+ onValueChanged: {
+ if (_loadComplete) {
+ _rcFeel.value = value
+ }
+ }
+ }
+ }
+ }
+ } // Rectangle - Basic tuning
+ } // Flickable
+ } // QGCViewPanel
+} // QGCView
diff --git a/src/AutoPilotPlugins/APM/APMTuningComponentPlane.qml b/src/AutoPilotPlugins/APM/APMTuningComponentPlane.qml
new file mode 100644
index 0000000..ace3b3a
--- /dev/null
+++ b/src/AutoPilotPlugins/APM/APMTuningComponentPlane.qml
@@ -0,0 +1,33 @@
+/*=====================================================================
+
+ 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 .
+
+ ======================================================================*/
+
+import QtQuick 2.5
+
+import QGroundControl.Controls 1.0
+
+QGCLabel {
+ anchors.fill: parent
+ text: "Not supported"
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+}
diff --git a/src/AutoPilotPlugins/APM/APMTuningComponentRover.qml b/src/AutoPilotPlugins/APM/APMTuningComponentRover.qml
new file mode 100644
index 0000000..ace3b3a
--- /dev/null
+++ b/src/AutoPilotPlugins/APM/APMTuningComponentRover.qml
@@ -0,0 +1,33 @@
+/*=====================================================================
+
+ 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 .
+
+ ======================================================================*/
+
+import QtQuick 2.5
+
+import QGroundControl.Controls 1.0
+
+QGCLabel {
+ anchors.fill: parent
+ text: "Not supported"
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+}