Commit 690ae21b authored by Don Gagne's avatar Don Gagne

APM Flight Mode Config

parent bb902798
......@@ -553,6 +553,7 @@ SOURCES += \
INCLUDEPATH += \
src/AutoPilotPlugins/Common \
src/AutoPilotPlugins/PX4 \
src/AutoPilotPlugins/APM \
src/FirmwarePlugin \
src/Vehicle \
src/VehicleSetup \
......@@ -564,6 +565,8 @@ HEADERS+= \
src/AutoPilotPlugins/APM/APMAirframeComponent.h \
src/AutoPilotPlugins/APM/APMComponent.h \
src/AutoPilotPlugins/APM/APMRadioComponent.h \
src/AutoPilotPlugins/APM/APMFlightModesComponent.h \
src/AutoPilotPlugins/APM/APMFlightModesComponentController.h \
src/AutoPilotPlugins/Common/RadioComponentController.h \
src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.h \
src/AutoPilotPlugins/PX4/AirframeComponent.h \
......@@ -609,6 +612,8 @@ SOURCES += \
src/AutoPilotPlugins/APM/APMAirframeComponent.cc \
src/AutoPilotPlugins/APM/APMComponent.cc \
src/AutoPilotPlugins/APM/APMRadioComponent.cc \
src/AutoPilotPlugins/APM/APMFlightModesComponent.cc \
src/AutoPilotPlugins/APM/APMFlightModesComponentController.cc \
src/AutoPilotPlugins/Common/RadioComponentController.cc \
src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.cc \
src/AutoPilotPlugins/PX4/AirframeComponent.cc \
......
......@@ -15,6 +15,8 @@
<file alias="FlightDisplayView.qml">src/FlightDisplay/FlightDisplayView.qml</file>
<file alias="FlightModesComponent.qml">src/AutoPilotPlugins/PX4/FlightModesComponent.qml</file>
<file alias="FlightModesComponentSummary.qml">src/AutoPilotPlugins/PX4/FlightModesComponentSummary.qml</file>
<file alias="APMFlightModesComponent.qml">src/AutoPilotPlugins/APM/APMFlightModesComponent.qml</file>
<file alias="APMFlightModesComponentSummary.qml">src/AutoPilotPlugins/APM/APMFlightModesComponentSummary.qml</file>
<file alias="BluetoothSettings.qml">src/ui/preferences/BluetoothSettings.qml</file>
<file alias="DebugWindow.qml">src/ui/preferences/DebugWindow.qml</file>
......
......@@ -33,6 +33,8 @@ APMAutoPilotPlugin::APMAutoPilotPlugin(Vehicle* vehicle, QObject* parent)
: AutoPilotPlugin(vehicle, parent)
, _incorrectParameterVersion(false)
, _airframeComponent(NULL)
, _flightModesComponent(NULL)
, _radioComponent(NULL)
{
Q_ASSERT(vehicle);
}
......@@ -53,6 +55,11 @@ const QVariantList& APMAutoPilotPlugin::vehicleComponents(void)
_airframeComponent->setupTriggerSignals();
_components.append(QVariant::fromValue((VehicleComponent*)_airframeComponent));
_flightModesComponent = new APMFlightModesComponent(_vehicle, this);
Q_CHECK_PTR(_flightModesComponent);
_flightModesComponent->setupTriggerSignals();
_components.append(QVariant::fromValue((VehicleComponent*)_flightModesComponent));
_radioComponent = new APMRadioComponent(_vehicle, this);
Q_CHECK_PTR(_radioComponent);
_radioComponent->setupTriggerSignals();
......
......@@ -28,6 +28,7 @@
#include "Vehicle.h"
#include "APMAirframeComponent.h"
#include "APMRadioComponent.h"
#include "APMFlightModesComponent.h"
/// This is the APM specific implementation of the AutoPilot class.
class APMAutoPilotPlugin : public AutoPilotPlugin
......@@ -41,8 +42,9 @@ public:
// Overrides from AutoPilotPlugin
virtual const QVariantList& vehicleComponents(void);
APMAirframeComponent* airframeComponent(void) { return _airframeComponent; }
APMRadioComponent* radioComponent(void) { return _radioComponent; }
APMAirframeComponent* airframeComponent (void) { return _airframeComponent; }
APMFlightModesComponent* flightModesComponent(void) { return _flightModesComponent; }
APMRadioComponent* radioComponent (void) { return _radioComponent; }
public slots:
// FIXME: This is public until we restructure AutoPilotPlugin/FirmwarePlugin/Vehicle
......@@ -51,8 +53,10 @@ public slots:
private:
bool _incorrectParameterVersion; ///< true: parameter version incorrect, setup not allowed
QVariantList _components;
APMAirframeComponent* _airframeComponent;
APMRadioComponent* _radioComponent;
APMAirframeComponent* _airframeComponent;
APMFlightModesComponent* _flightModesComponent;
APMRadioComponent* _radioComponent;
};
#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 "APMFlightModesComponent.h"
#include "APMAutoPilotPlugin.h"
APMFlightModesComponent::APMFlightModesComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent) :
APMComponent(vehicle, autopilot, parent),
_name(tr("Flight Modes"))
{
}
QString APMFlightModesComponent::name(void) const
{
return _name;
}
QString APMFlightModesComponent::description(void) const
{
return QString("The Flight Modes Component is used to assign FLight Modes to Channel 5.");
}
QString APMFlightModesComponent::iconResource(void) const
{
return "/qmlimages/FlightModesComponentIcon.png";
}
bool APMFlightModesComponent::requiresSetup(void) const
{
return true;
}
bool APMFlightModesComponent::setupComplete(void) const
{
return true;
}
QString APMFlightModesComponent::setupStateDescription(void) const
{
const char* stateDescription;
if (requiresSetup()) {
stateDescription = "Requires calibration";
} else {
stateDescription = "Calibrated";
}
return QString(stateDescription);
}
QStringList APMFlightModesComponent::setupCompleteChangedTriggerList(void) const
{
return QStringList();
}
QStringList APMFlightModesComponent::paramFilterList(void) const
{
return QStringList();
}
QUrl APMFlightModesComponent::setupSource(void) const
{
return QUrl::fromUserInput("qrc:/qml/APMFlightModesComponent.qml");
}
QUrl APMFlightModesComponent::summaryQmlSource(void) const
{
return QUrl::fromUserInput("qrc:/qml/APMFlightModesComponentSummary.qml");
}
QString APMFlightModesComponent::prerequisiteSetup(void) const
{
APMAutoPilotPlugin* plugin = dynamic_cast<APMAutoPilotPlugin*>(_autopilot);
Q_ASSERT(plugin);
if (!plugin->airframeComponent()->setupComplete()) {
return plugin->airframeComponent()->name();
} else if (!plugin->radioComponent()->setupComplete()) {
return plugin->radioComponent()->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 APMFlightModesComponent_H
#define APMFlightModesComponent_H
#include "APMComponent.h"
class APMFlightModesComponent : public APMComponent
{
Q_OBJECT
public:
APMFlightModesComponent(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 QString setupStateDescription(void) const;
virtual QUrl setupSource(void) const;
virtual QStringList paramFilterList(void) const;
virtual QUrl summaryQmlSource(void) const;
virtual QString prerequisiteSetup(void) const;
private:
const QString _name;
};
#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.2
import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Palette 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Controllers 1.0
import QGroundControl.ScreenTools 1.0
QGCView {
id: rootQGCView
viewPanel: panel
QGCPalette { id: qgcPal; colorGroupEnabled: panel.enabled }
APMFlightModesComponentController {
id: controller
factPanel: panel
}
QGCViewPanel {
id: panel
anchors.fill: parent
Flickable {
anchors.fill: parent
Column {
width: parent.width
spacing: ScreenTools.defaultFontPixelHeight
QGCLabel {
text: "Channel 5 Flight Mode Settings"
font.weight: Font.DemiBold
}
Rectangle {
width: parent.width
height: flightModeColumn.height + ScreenTools.defaultFontPixelHeight
color: qgcPal.windowShade
Column {
id: flightModeColumn
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
spacing: ScreenTools.defaultFontPixelHeight
Repeater {
model: 6
Row {
spacing: ScreenTools.defaultFontPixelWidth
property int index: modelData + 1
QGCLabel {
anchors.baseline: modeCombo.baseline
text: "Flight Mode " + index + ":"
}
FactComboBox {
id: modeCombo
width: ScreenTools.defaultFontPixelWidth * 15
fact: controller.getParameterFact(-1, "FLTMODE" + index)
indexModel: false
}
QGCCheckBox {
id: simple
anchors.baseline: modeCombo.baseline
text: "Simple Mode"
visible: !controller.fixedWing
checked: isChecked()
onClicked: {
var simpleFact = controller.getParameterFact(-1, "SIMPLE")
if (checked) {
simpleFact.value |= 1 << modelData
} else {
simpleFact.value &= ~modelData
}
}
function isChecked() {
if (simple.visible) {
var simpleFact = controller.getParameterFact(-1, "SIMPLE")
return simpleFact.value & (1 << modelData)
} else {
return false;
}
}
}
QGCCheckBox {
id: superSimple
anchors.baseline: modeCombo.baseline
text: "Super Simple Mode"
visible: !controller.fixedWing
checked: isChecked()
onClicked: {
var simpleFact = controller.getParameterFact(-1, "SUPER_SIMPLE")
if (checked) {
simpleFact.value |= 1 << modelData
} else {
simpleFact.value &= ~modelData
}
}
function isChecked() {
if (superSimple.visible) {
var simpleFact = controller.getParameterFact(-1, "SUPER_SIMPLE")
return simpleFact.value & (1 << modelData)
} else {
return false;
}
}
}
}
} // Repeater - Flight Modes
} // Column - Flight Modes
} // Rectangle - Flight Modes
QGCLabel {
text: "Channel Options"
font.weight: Font.DemiBold
}
Rectangle {
width: parent.width
height: channelOptColumn.height + ScreenTools.defaultFontPixelHeight
color: qgcPal.windowShade
Column {
id: channelOptColumn
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
spacing: ScreenTools.defaultFontPixelHeight
Repeater {
model: 6
Row {
spacing: ScreenTools.defaultFontPixelWidth
property int index: modelData + 7
QGCLabel {
anchors.baseline: optCombo.baseline
text: "Channel option " + index + ":"
}
FactComboBox {
id: optCombo
width: ScreenTools.defaultFontPixelWidth * 15
fact: controller.getParameterFact(-1, "CH" + index + "_OPT")
indexModel: false
}
}
} // Repeater -- Channel options
} // Column - Channel options
} // Rectangle - Channel options
} // Column
} // 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/>.
======================================================================*/
#include "APMFlightModesComponentController.h"
#include "QGCMAVLink.h"
#include "AutoPilotPluginManager.h"
#include <QVariant>
#include <QQmlProperty>
APMFlightModesComponentController::APMFlightModesComponentController(void)
: _channelCount(Vehicle::cMaxRcChannels)
{
QStringList usedParams;
usedParams << "FLTMODE1" << "FLTMODE2" << "FLTMODE3" << "FLTMODE4" << "FLTMODE5" << "FLTMODE6";
if (!_allParametersExists(FactSystem::defaultComponentId, usedParams)) {
return;
}
_init();
_validateConfiguration();
connect(_vehicle, &Vehicle::rcChannelsChanged, this, &APMFlightModesComponentController::_rcChannelsChanged);
}
void APMFlightModesComponentController::_init(void)
{
_fixedWing = _vehicle->vehicleType() == MAV_TYPE_FIXED_WING;
}
/// This will look for parameter settings which would cause the config to not run correctly.
/// It will set _validConfiguration and _configurationErrors as needed.
void APMFlightModesComponentController::_validateConfiguration(void)
{
_validConfiguration = true;
#if 0
// Make sure switches are valid and within channel range
QStringList switchParams;
QList<int> switchMappings;
switchParams << "RC_MAP_MODE_SW" << "RC_MAP_ACRO_SW" << "RC_MAP_POSCTL_SW" << "RC_MAP_LOITER_SW" << "RC_MAP_RETURN_SW" << "RC_MAP_OFFB_SW";
for(int i=0; i<switchParams.count(); i++) {
int map = getParameterFact(FactSystem::defaultComponentId, switchParams[i])->rawValue().toInt();
switchMappings << map;
if (map < 0 || map > _channelCount) {
_validConfiguration = false;
_configurationErrors += QString("%1 is set to %2. Mapping must between 0 and %3 (inclusive).\n").arg(switchParams[i]).arg(map).arg(_channelCount);
}
}
// Make sure mode switches are not double-mapped
QStringList attitudeParams;
attitudeParams << "RC_MAP_THROTTLE" << "RC_MAP_YAW" << "RC_MAP_PITCH" << "RC_MAP_ROLL" << "RC_MAP_FLAPS" << "RC_MAP_AUX1" << "RC_MAP_AUX2";
for (int i=0; i<attitudeParams.count(); i++) {
int map = getParameterFact(FactSystem::defaultComponentId, attitudeParams[i])->rawValue().toInt();
for (int j=0; j<switchParams.count(); j++) {
if (map != 0 && map == switchMappings[j]) {
_validConfiguration = false;
_configurationErrors += QString("%1 is set to same channel as %2.\n").arg(switchParams[j]).arg(attitudeParams[i]);
}
}
}
// Validate thresholds within range
QStringList thresholdParams;
thresholdParams << "RC_ASSIST_TH" << "RC_AUTO_TH" << "RC_ACRO_TH" << "RC_POSCTL_TH" << "RC_LOITER_TH" << "RC_RETURN_TH" << "RC_OFFB_TH";
foreach(QString thresholdParam, thresholdParams) {
float threshold = getParameterFact(-1, thresholdParam)->rawValue().toFloat();
if (threshold < 0.0f || threshold > 1.0f) {
_validConfiguration = false;
_configurationErrors += QString("%1 is set to %2. Threshold must between 0.0 and 1.0 (inclusive).\n").arg(thresholdParam).arg(threshold);
}
}
#endif
}
/// Connected to Vehicle::rcChannelsChanged signal
void APMFlightModesComponentController::_rcChannelsChanged(int channelCount, int pwmValues[Vehicle::cMaxRcChannels])
{
for (int channel=0; channel<channelCount; channel++) {
_rcValues[channel] = pwmValues[channel];
}
}
/*=====================================================================
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/>.
======================================================================*/
#ifndef APMFlightModesComponentController_H
#define APMFlightModesComponentController_H
#include <QObject>
#include <QQuickItem>
#include <QList>
#include <QStringList>
#include "UASInterface.h"
#include "AutoPilotPlugin.h"
#include "FactPanelController.h"
#include "Vehicle.h"
/// MVC Controller for FlightModesComponent.qml.
class APMFlightModesComponentController : public FactPanelController
{
Q_OBJECT
public:
APMFlightModesComponentController(void);
Q_PROPERTY(int channelCount MEMBER _channelCount CONSTANT)
Q_PROPERTY(bool fixedWing MEMBER _fixedWing CONSTANT)
Q_PROPERTY(QString reservedChannels MEMBER _reservedChannels CONSTANT)
private slots:
void _rcChannelsChanged(int channelCount, int pwmValues[Vehicle::cMaxRcChannels]);
private:
void _init(void);
void _validateConfiguration(void);
bool _fixedWing;
int _rcValues[Vehicle::cMaxRcChannels];
bool _validConfiguration;
QString _configurationErrors;
int _channelCount;
QString _reservedChannels;
};
#endif
import QtQuick 2.5
import QtQuick.Controls 1.2
import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Palette 1.0
FactPanel {
id: panel
anchors.fill: parent
color: qgcPal.windowShadeDark
QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
FactPanelController { id: controller; factPanel: panel }
property Fact flightMode1: controller.getParameterFact(-1, "FLTMODE1")
property Fact flightMode2: controller.getParameterFact(-1, "FLTMODE2")
property Fact flightMode3: controller.getParameterFact(-1, "FLTMODE3")
property Fact flightMode4: controller.getParameterFact(-1, "FLTMODE4")
property Fact flightMode5: controller.getParameterFact(-1, "FLTMODE5")
property Fact flightMode6: controller.getParameterFact(-1, "FLTMODE6")
Column {
anchors.fill: parent
anchors.margins: 8
VehicleSummaryRow {
labelText: "Flight Mode 1:"
valueText: flightMode1.enumStringValue
}
VehicleSummaryRow {
labelText: "Flight Mode 2:"
valueText: flightMode2.enumStringValue
}
VehicleSummaryRow {
labelText: "Flight Mode 3:"
valueText: flightMode3.enumStringValue
}
VehicleSummaryRow {
labelText: "Flight Mode 4:"
valueText: flightMode4.enumStringValue
}
VehicleSummaryRow {
labelText: "Flight Mode 5:"
valueText: flightMode5.enumStringValue
}
VehicleSummaryRow {
labelText: "Flight Mode 6:"
valueText: flightMode6.enumStringValue
}
}
}
......@@ -62,6 +62,7 @@
#include "ParameterEditorController.h"
#include "CustomCommandWidgetController.h"
#include "FlightModesComponentController.h"
#include "APMFlightModesComponentController.h"
#include "AirframeComponentController.h"
#include "SensorsComponentController.h"
#include "PowerComponentController.h"
......@@ -354,16 +355,17 @@ void QGCApplication::_initCommon(void)
qmlRegisterUncreatableType<JoystickManager> ("QGroundControl.JoystickManager", 1, 0, "JoystickManager", "Reference only");
qmlRegisterUncreatableType<Joystick> ("QGroundControl.JoystickManager", 1, 0, "Joystick", "Reference only");
qmlRegisterType<ParameterEditorController> ("QGroundControl.Controllers", 1, 0, "ParameterEditorController");
qmlRegisterType<FlightModesComponentController> ("QGroundControl.Controllers", 1, 0, "FlightModesComponentController");
qmlRegisterType<AirframeComponentController> ("QGroundControl.Controllers", 1, 0, "AirframeComponentController");
qmlRegisterType<SensorsComponentController> ("QGroundControl.Controllers", 1, 0, "SensorsComponentController");
qmlRegisterType<PowerComponentController> ("QGroundControl.Controllers", 1, 0, "PowerComponentController");
qmlRegisterType<RadioComponentController> ("QGroundControl.Controllers", 1, 0, "RadioComponentController");
qmlRegisterType<ScreenToolsController> ("QGroundControl.Controllers", 1, 0, "ScreenToolsController");
qmlRegisterType<MainToolBarController> ("QGroundControl.Controllers", 1, 0, "MainToolBarController");
qmlRegisterType<MissionController> ("QGroundControl.Controllers", 1, 0, "MissionController");
qmlRegisterType<FlightDisplayViewController> ("QGroundControl.Controllers", 1, 0, "FlightDisplayViewController");
qmlRegisterType<ParameterEditorController> ("QGroundControl.Controllers", 1, 0, "ParameterEditorController");
qmlRegisterType<APMFlightModesComponentController> ("QGroundControl.Controllers", 1, 0, "APMFlightModesComponentController");
qmlRegisterType<FlightModesComponentController> ("QGroundControl.Controllers", 1, 0, "FlightModesComponentController");
qmlRegisterType<AirframeComponentController> ("QGroundControl.Controllers", 1, 0, "AirframeComponentController");
qmlRegisterType<SensorsComponentController> ("QGroundControl.Controllers", 1, 0, "SensorsComponentController");