diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index ef55857..bb3bf78 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -1149,6 +1149,7 @@ PX4FirmwarePlugin { src/AutoPilotPlugins/PX4/PX4AdvancedFlightModesController.h \ src/AutoPilotPlugins/PX4/PX4AirframeLoader.h \ src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h \ + src/AutoPilotPlugins/PX4/PX4FlightBehavior.h \ src/AutoPilotPlugins/PX4/PX4RadioComponent.h \ src/AutoPilotPlugins/PX4/PX4SimpleFlightModesController.h \ src/AutoPilotPlugins/PX4/PX4TuningComponent.h \ @@ -1169,6 +1170,7 @@ PX4FirmwarePlugin { src/AutoPilotPlugins/PX4/PX4AdvancedFlightModesController.cc \ src/AutoPilotPlugins/PX4/PX4AirframeLoader.cc \ src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc \ + src/AutoPilotPlugins/PX4/PX4FlightBehavior.cc \ src/AutoPilotPlugins/PX4/PX4RadioComponent.cc \ src/AutoPilotPlugins/PX4/PX4SimpleFlightModesController.cc \ src/AutoPilotPlugins/PX4/PX4TuningComponent.cc \ diff --git a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc index 30b8315..1f49489 100644 --- a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc +++ b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc @@ -39,6 +39,7 @@ PX4AutoPilotPlugin::PX4AutoPilotPlugin(Vehicle* vehicle, QObject* parent) , _powerComponent(nullptr) , _motorComponent(nullptr) , _tuningComponent(nullptr) + , _flightBehavior(nullptr) , _syslinkComponent(nullptr) { if (!vehicle) { @@ -94,6 +95,12 @@ const QVariantList& PX4AutoPilotPlugin::vehicleComponents(void) _tuningComponent->setupTriggerSignals(); _components.append(QVariant::fromValue((VehicleComponent*)_tuningComponent)); + if(_vehicle->parameterManager()->parameterExists(_vehicle->id(), "SYS_VEHICLE_RESP")) { + _flightBehavior = new PX4FlightBehavior(_vehicle, this); + _flightBehavior->setupTriggerSignals(); + _components.append(QVariant::fromValue((VehicleComponent*)_flightBehavior)); + } + //-- Is there support for cameras? if(_vehicle->parameterManager()->parameterExists(_vehicle->id(), "TRIG_MODE")) { _cameraComponent = new CameraComponent(_vehicle, this); diff --git a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h index 9d0d5f8..0fe01bc 100644 --- a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h +++ b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h @@ -23,6 +23,7 @@ #include "PowerComponent.h" #include "MotorComponent.h" #include "PX4TuningComponent.h" +#include "PX4FlightBehavior.h" #include "SyslinkComponent.h" #include "Vehicle.h" @@ -58,6 +59,7 @@ protected: PowerComponent* _powerComponent; MotorComponent* _motorComponent; PX4TuningComponent* _tuningComponent; + PX4FlightBehavior* _flightBehavior; SyslinkComponent* _syslinkComponent; private: diff --git a/src/AutoPilotPlugins/PX4/PX4FlightBehavior.cc b/src/AutoPilotPlugins/PX4/PX4FlightBehavior.cc new file mode 100644 index 0000000..50c6a19 --- /dev/null +++ b/src/AutoPilotPlugins/PX4/PX4FlightBehavior.cc @@ -0,0 +1,86 @@ +/**************************************************************************** + * + * (c) 2009-2020 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + + +#include "PX4FlightBehavior.h" +#include "PX4AutoPilotPlugin.h" +#include "AirframeComponent.h" + +PX4FlightBehavior::PX4FlightBehavior(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent) + : VehicleComponent(vehicle, autopilot, parent) + , _name(tr("Flight Behavior")) +{ +} + +QString PX4FlightBehavior::name() const +{ + return _name; +} + +QString PX4FlightBehavior::description() const +{ + return tr("Flight Behavior is used to configure flight characteristics."); +} + +QString PX4FlightBehavior::iconResource() const +{ + return "/qmlimages/TuningComponentIcon.png"; +} + +bool PX4FlightBehavior::requiresSetup() const +{ + return false; +} + +bool PX4FlightBehavior::setupComplete() const +{ + return true; +} + +QStringList PX4FlightBehavior::setupCompleteChangedTriggerList() const +{ + return QStringList(); +} + +QUrl PX4FlightBehavior::setupSource() const +{ + QString qmlFile; + + switch (_vehicle->vehicleType()) { + case MAV_TYPE_FIXED_WING: + qmlFile = ""; + 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/PX4FlightBehaviorCopter.qml"; + break; + case MAV_TYPE_VTOL_DUOROTOR: + case MAV_TYPE_VTOL_QUADROTOR: + case MAV_TYPE_VTOL_TILTROTOR: + case MAV_TYPE_VTOL_RESERVED2: + case MAV_TYPE_VTOL_RESERVED3: + case MAV_TYPE_VTOL_RESERVED4: + case MAV_TYPE_VTOL_RESERVED5: + qmlFile = ""; + break; + default: + break; + } + + return QUrl::fromUserInput(qmlFile); +} + +QUrl PX4FlightBehavior::summaryQmlSource() const +{ + return QUrl(); +} diff --git a/src/AutoPilotPlugins/PX4/PX4FlightBehavior.h b/src/AutoPilotPlugins/PX4/PX4FlightBehavior.h new file mode 100644 index 0000000..0f39405 --- /dev/null +++ b/src/AutoPilotPlugins/PX4/PX4FlightBehavior.h @@ -0,0 +1,38 @@ +/**************************************************************************** + * + * (c) 2021 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + + +#pragma once + +#include "VehicleComponent.h" + +class PX4FlightBehavior : public VehicleComponent +{ + Q_OBJECT + +public: + PX4FlightBehavior(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent = nullptr); + + // Virtuals from VehicleComponent + QStringList setupCompleteChangedTriggerList() const final; + + // Virtuals from VehicleComponent + QString name() const final; + QString description() const final; + QString iconResource() const final; + bool requiresSetup() const final; + bool setupComplete() const final; + QUrl setupSource() const final; + QUrl summaryQmlSource() const final; + bool allowSetupWhileArmed() const final { return true; } + bool allowSetupWhileFlying() const final { return true; } + +private: + const QString _name; +}; diff --git a/src/AutoPilotPlugins/PX4/PX4FlightBehaviorCopter.qml b/src/AutoPilotPlugins/PX4/PX4FlightBehaviorCopter.qml new file mode 100644 index 0000000..24df968 --- /dev/null +++ b/src/AutoPilotPlugins/PX4/PX4FlightBehaviorCopter.qml @@ -0,0 +1,155 @@ +/**************************************************************************** + * + * (c) 2021 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.3 +import QtQuick.Controls 1.2 +import QtQuick.Layouts 1.2 + +import QGroundControl 1.0 +import QGroundControl.FactSystem 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.Palette 1.0 +import QGroundControl.ScreenTools 1.0 + +SetupPage { + id: flightBehavior + pageComponent: pageComponent + property real _margins: ScreenTools.defaultFontPixelHeight + + FactPanelController { + id: controller + } + + QGCPalette { + id: qgcPal + } + + property Fact _sys_vehicle_resp: controller.getParameterFact(-1, "SYS_VEHICLE_RESP", false) + property Fact _mpc_xy_vel_all: controller.getParameterFact(-1, "MPC_XY_VEL_ALL", false) + property Fact _mpc_z_vel_all: controller.getParameterFact(-1, "MPC_Z_VEL_ALL", false) + + Component { + id: pageComponent + + Column { + + spacing: _margins + + Column { + visible: _sys_vehicle_resp + + QGCCheckBox { + id: responsivenessCheckbox + text: qsTr("Enable responsiveness slider (if enabled, acceleration limit parameters and others are automatically set)") + checked: _sys_vehicle_resp && _sys_vehicle_resp.value >= 0 + onClicked: { + if (checked) { + _sys_vehicle_resp.value = Math.abs(_sys_vehicle_resp.value) + } else { + _sys_vehicle_resp.value = -Math.abs(_sys_vehicle_resp.value) + } + } + } + + FactSliderPanel { + width: availableWidth + enabled: responsivenessCheckbox.checked + + sliderModel: ListModel { + id: responsivenessSlider + + ListElement { + title: qsTr("Responsiveness") + description: qsTr("A higher value makes the vehicle react faster. Be aware that this affects braking as well, and a combination of slow responsiveness with high maximum velocity will lead to long braking distances.") + param: "SYS_VEHICLE_RESP" + min: 0.01 + max: 1 + step: 0.01 + } + } + } + QGCLabel { + visible: _sys_vehicle_resp && _sys_vehicle_resp.value > 0.8 + color: qgcPal.warningText + text: "Warning: a high responsiveness requires a vehicle with large thrust-to-weight ratio. The vehicle might lose altitude otherwise." + } + } + + Column { + visible: _mpc_xy_vel_all + + QGCCheckBox { + id: xyVelCheckbox + text: qsTr("Enable horizontal velocity slider (if enabled, individual velocity limit parameters are automatically set)") + checked: _mpc_xy_vel_all ? (_mpc_xy_vel_all.value >= 0) : false + onClicked: { + if (checked) { + _mpc_xy_vel_all.value = Math.abs(_mpc_xy_vel_all.value) + } else { + _mpc_xy_vel_all.value = -Math.abs(_mpc_xy_vel_all.value) + } + } + } + + FactSliderPanel { + width: availableWidth + enabled: xyVelCheckbox.checked + + sliderModel: ListModel { + id: xyVelSlider + + ListElement { + title: qsTr("Horizontal velocity (m/s)") + description: qsTr("Limit the horizonal velocity (applies to all modes).") + param: "MPC_XY_VEL_ALL" + min: 0.5 + max: 20 + step: 0.5 + } + } + } + } + + Column { + visible: _mpc_z_vel_all + + QGCCheckBox { + id: zVelCheckbox + text: qsTr("Enable vertical velocity slider (if enabled, individual velocity limit parameters are automatically set)") + checked: _mpc_z_vel_all && _mpc_z_vel_all.value >= 0 + onClicked: { + if (checked) { + _mpc_z_vel_all.value = Math.abs(_mpc_z_vel_all.value) + } else { + _mpc_z_vel_all.value = -Math.abs(_mpc_z_vel_all.value) + } + } + } + + FactSliderPanel { + width: availableWidth + enabled: zVelCheckbox.checked + + sliderModel: ListModel { + id: zVelSlider + + ListElement { + title: qsTr("Vertial velocity (m/s)") + description: qsTr("Limit the vertical velocity (applies to all modes).") + param: "MPC_Z_VEL_ALL" + min: 0.2 + max: 8 + step: 0.2 + } + } + } + } + } // Column + } // Component - pageComponent +} // SetupPage diff --git a/src/AutoPilotPlugins/PX4/PX4TuningComponent.cc b/src/AutoPilotPlugins/PX4/PX4TuningComponent.cc index 13b388b..1ea706e 100644 --- a/src/AutoPilotPlugins/PX4/PX4TuningComponent.cc +++ b/src/AutoPilotPlugins/PX4/PX4TuningComponent.cc @@ -40,7 +40,7 @@ QString PX4TuningComponent::name(void) const QString PX4TuningComponent::description(void) const { - return tr("Tuning Setup is used to tune the flight characteristics of the Vehicle."); + return tr("Tuning Setup is used to tune the flight controllers."); } QString PX4TuningComponent::iconResource(void) const diff --git a/src/FirmwarePlugin/PX4/PX4Resources.qrc b/src/FirmwarePlugin/PX4/PX4Resources.qrc index 1e9cb17..5a8f17d 100644 --- a/src/FirmwarePlugin/PX4/PX4Resources.qrc +++ b/src/FirmwarePlugin/PX4/PX4Resources.qrc @@ -11,6 +11,7 @@ ../../AutoPilotPlugins/PX4/PX4FlightModes.qml ../../AutoPilotPlugins/PX4/PX4RadioComponentSummary.qml ../../AutoPilotPlugins/PX4/PX4SimpleFlightModes.qml + ../../AutoPilotPlugins/PX4/PX4FlightBehaviorCopter.qml ../../AutoPilotPlugins/PX4/PX4TuningComponentCopter.qml ../../AutoPilotPlugins/PX4/PX4TuningComponentPlane.qml ../../AutoPilotPlugins/PX4/PX4TuningComponentVTOL.qml diff --git a/src/QmlControls/FactSliderPanel.qml b/src/QmlControls/FactSliderPanel.qml index 22b7622..610b056 100644 --- a/src/QmlControls/FactSliderPanel.qml +++ b/src/QmlControls/FactSliderPanel.qml @@ -89,7 +89,7 @@ Column { property Fact _fact: controller.getParameterFact(-1, param) onValueChanged: { - if (_loadComplete) { + if (_loadComplete && enabled) { _fact.value = value } }