Commit 7a791d77 authored by Don Gagne's avatar Don Gagne

Merge pull request #2407 from DonLakeFlyer/BasicTuning

APM Copter Basic tuning
parents 15a060d6 f4880ad5
......@@ -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 \
......
......@@ -113,6 +113,9 @@
<file alias="APMSafetyComponentSummaryCopter.qml">src/AutoPilotPlugins/APM/APMSafetyComponentSummaryCopter.qml</file>
<file alias="APMSafetyComponentSummaryPlane.qml">src/AutoPilotPlugins/APM/APMSafetyComponentSummaryPlane.qml</file>
<file alias="APMSafetyComponentSummaryRover.qml">src/AutoPilotPlugins/APM/APMSafetyComponentSummaryRover.qml</file>
<file alias="APMTuningComponentCopter.qml">src/AutoPilotPlugins/APM/APMTuningComponentCopter.qml</file>
<file alias="APMTuningComponentPlane.qml">src/AutoPilotPlugins/APM/APMTuningComponentPlane.qml</file>
<file alias="APMTuningComponentRover.qml">src/AutoPilotPlugins/APM/APMTuningComponentRover.qml</file>
<file alias="SafetyComponent.qml">src/AutoPilotPlugins/PX4/SafetyComponent.qml</file>
<file alias="SafetyComponentSummary.qml">src/AutoPilotPlugins/PX4/SafetyComponentSummary.qml</file>
<file alias="SensorsComponent.qml">src/AutoPilotPlugins/PX4/SensorsComponent.qml</file>
......
......@@ -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";
}
......
......@@ -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
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
#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<APMAutoPilotPlugin*>(_autopilot);
Q_ASSERT(plugin);
if (!plugin->airframeComponent()->setupComplete()) {
return plugin->airframeComponent()->name();
}
return QString();
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
#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
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
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
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
import QtQuick 2.5
import QGroundControl.Controls 1.0
QGCLabel {
anchors.fill: parent
text: "Not supported"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
import QtQuick 2.5
import QGroundControl.Controls 1.0
QGCLabel {
anchors.fill: parent
text: "Not supported"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
......@@ -253,6 +253,8 @@ void ParameterLoader::_parameterUpdate(int uasId, int componentId, QString param
connect(fact, &Fact::_containerRawValueChanged, this, &ParameterLoader::_valueUpdated);
}
_dataMutex.unlock();
Q_ASSERT(_mapParameterName2Variant[componentId].contains(parameterName));
Fact* fact = _mapParameterName2Variant[componentId][parameterName].value<Fact*>();
......@@ -263,8 +265,6 @@ void ParameterLoader::_parameterUpdate(int uasId, int componentId, QString param
_vehicle->firmwarePlugin()->addMetaDataToFact(fact, _vehicle->vehicleType());
}
_dataMutex.unlock();
if (waitingParamCount == 0) {
// Now that we know vehicle is up to date persist
_saveToEEPROM();
......
......@@ -109,9 +109,10 @@ Rectangle {
// Outer summary item rectangle
Rectangle {
width: _summaryBoxWidth
height: ScreenTools.defaultFontPixelHeight * 13
color: qgcPal.window
width: _summaryBoxWidth
height: ScreenTools.defaultFontPixelHeight * 13
color: qgcPal.window
visible: modelData.summaryQmlSource.toString() != ""
readonly property real titleHeight: ScreenTools.defaultFontPixelHeight * 2
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment