From f4880ad5d375d5d8f68d5a520f52d277e91e6545 Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Tue, 15 Dec 2015 10:38:04 -0800 Subject: [PATCH] APM Copter basic tuning --- qgroundcontrol.pro | 2 + qgroundcontrol.qrc | 3 + .../APM/APMAutoPilotPlugin.cc | 9 + src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h | 3 + .../APM/APMTuningComponent.cc | 105 ++++++++ src/AutoPilotPlugins/APM/APMTuningComponent.h | 54 ++++ .../APM/APMTuningComponentCopter.qml | 234 ++++++++++++++++++ .../APM/APMTuningComponentPlane.qml | 33 +++ .../APM/APMTuningComponentRover.qml | 33 +++ 9 files changed, 476 insertions(+) create mode 100644 src/AutoPilotPlugins/APM/APMTuningComponent.cc create mode 100644 src/AutoPilotPlugins/APM/APMTuningComponent.h create mode 100644 src/AutoPilotPlugins/APM/APMTuningComponentCopter.qml create mode 100644 src/AutoPilotPlugins/APM/APMTuningComponentPlane.qml create mode 100644 src/AutoPilotPlugins/APM/APMTuningComponentRover.qml diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 0e69320ad..4156b7222 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 adfbf599b..61848f026 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 13bbce599..b04d522c8 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 41f081c56..c26dee7c0 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 000000000..ca61ec1d5 --- /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 000000000..4ad235979 --- /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 000000000..1e7d62858 --- /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 000000000..ace3b3a1d --- /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 000000000..ace3b3a1d --- /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 +} -- 2.22.0