diff --git a/qgcresources.qrc b/qgcresources.qrc index 9c9b04fa7ac3349bfca45a6612267bdbd2596fe0..c75675999204de85af8158ca7b2317a300045cb1 100644 --- a/qgcresources.qrc +++ b/qgcresources.qrc @@ -48,6 +48,7 @@ src/QmlControls/arrow-down.png src/VehicleSetup/FirmwareUpgradeIcon.png src/AutoPilotPlugins/PX4/Images/FlightModesComponentIcon.png + src/AutoPilotPlugins/PX4/Images/CameraTrigger.svg src/AutoPilotPlugins/PX4/Images/CameraComponentIcon.png src/AutoPilotPlugins/PX4/Images/DatalinkLoss.svg src/AutoPilotPlugins/PX4/Images/DatalinkLossLight.svg diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 355946c28c8dc048699112d2247056c83aa046cc..68a33709c8289347f9805c2bc9c822ea77e6162c 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -651,6 +651,7 @@ HEADERS+= \ src/AutoPilotPlugins/PX4/PowerComponentController.h \ src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h \ src/AutoPilotPlugins/PX4/PX4RadioComponent.h \ + src/AutoPilotPlugins/PX4/CameraComponent.h \ src/AutoPilotPlugins/PX4/SafetyComponent.h \ src/AutoPilotPlugins/PX4/SensorsComponent.h \ src/AutoPilotPlugins/PX4/SensorsComponentController.h \ @@ -708,6 +709,7 @@ SOURCES += \ src/AutoPilotPlugins/PX4/PowerComponentController.cc \ src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc \ src/AutoPilotPlugins/PX4/PX4RadioComponent.cc \ + src/AutoPilotPlugins/PX4/CameraComponent.cc \ src/AutoPilotPlugins/PX4/SafetyComponent.cc \ src/AutoPilotPlugins/PX4/SensorsComponent.cc \ src/AutoPilotPlugins/PX4/SensorsComponentController.cc \ diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 5e7fde828e46446289b9d7491ffef40235614aa1..fb344ce8a932ce998ac6256a9ac3b1fe8034d56f 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -148,6 +148,8 @@ src/AutoPilotPlugins/APM/APMSafetyComponentSummaryPlane.qml src/AutoPilotPlugins/APM/APMSafetyComponentSummaryRover.qml src/AutoPilotPlugins/APM/APMTuningComponentCopter.qml + src/AutoPilotPlugins/PX4/CameraComponent.qml + src/AutoPilotPlugins/PX4/CameraComponentSummary.qml src/AutoPilotPlugins/PX4/SafetyComponent.qml src/AutoPilotPlugins/PX4/SafetyComponentSummary.qml src/AutoPilotPlugins/PX4/SensorsComponent.qml diff --git a/src/AutoPilotPlugins/PX4/CameraComponent.cc b/src/AutoPilotPlugins/PX4/CameraComponent.cc new file mode 100644 index 0000000000000000000000000000000000000000..5f7d3d8c8984362bc632a60ea324789881b0d30c --- /dev/null +++ b/src/AutoPilotPlugins/PX4/CameraComponent.cc @@ -0,0 +1,81 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2016 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 . + + ======================================================================*/ + +/// @file +/// @brief The Camera VehicleComponent is used to setup the camera modes and hardware +/// configuration to use it. +/// @author Gus Grubba + +#include "CameraComponent.h" +#include "PX4AutoPilotPlugin.h" + +CameraComponent::CameraComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent) : + VehicleComponent(vehicle, autopilot, parent), + _name(tr("Camera")) +{ +} + +QString CameraComponent::name(void) const +{ + return _name; +} + +QString CameraComponent::description(void) const +{ + return tr("The Camera is used to setup the camera modes and hardware configuration to use it."); +} + +QString CameraComponent::iconResource(void) const +{ + return "/qmlimages/CameraComponentIcon.png"; +} + +bool CameraComponent::requiresSetup(void) const +{ + return false; +} + +bool CameraComponent::setupComplete(void) const +{ + return true; +} + +QStringList CameraComponent::setupCompleteChangedTriggerList(void) const +{ + return QStringList(); +} + +QUrl CameraComponent::setupSource(void) const +{ + return QUrl::fromUserInput("qrc:/qml/CameraComponent.qml"); +} + +QUrl CameraComponent::summaryQmlSource(void) const +{ + return QUrl::fromUserInput("qrc:/qml/CameraComponentSummary.qml"); +} + +QString CameraComponent::prerequisiteSetup(void) const +{ + return QString(); +} diff --git a/src/AutoPilotPlugins/PX4/CameraComponent.h b/src/AutoPilotPlugins/PX4/CameraComponent.h new file mode 100644 index 0000000000000000000000000000000000000000..3b9cf6a8f6ef2d31d474a82a5de2e51007a1dcb4 --- /dev/null +++ b/src/AutoPilotPlugins/PX4/CameraComponent.h @@ -0,0 +1,60 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2016 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 CameraComponent_H +#define CameraComponent_H + +#include "VehicleComponent.h" + +/// @file +/// @brief The Camera VehicleComponent is used to setup the camera modes and hardware +/// configuration to use it. +/// @author Gus Grubba + +class CameraComponent : public VehicleComponent +{ + Q_OBJECT + +public: + CameraComponent (Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent = NULL); + + // Virtuals from VehicleComponent + QStringList setupCompleteChangedTriggerList (void) const; + + // Virtuals from VehicleComponent + QString name (void) const final; + QString description (void) const final; + QString iconResource (void) const final; + bool requiresSetup (void) const final; + bool setupComplete (void) const final; + QUrl setupSource (void) const final; + QUrl summaryQmlSource (void) const final; + QString prerequisiteSetup (void) const final; + bool allowSetupWhileArmed (void) const final { return false; } + +private: + const QString _name; + QVariantList _summaryItems; +}; + +#endif diff --git a/src/AutoPilotPlugins/PX4/CameraComponent.qml b/src/AutoPilotPlugins/PX4/CameraComponent.qml new file mode 100644 index 0000000000000000000000000000000000000000..dfd079cad96193b3280ccb9321c11ba219da9a00 --- /dev/null +++ b/src/AutoPilotPlugins/PX4/CameraComponent.qml @@ -0,0 +1,326 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2016 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.2 +import QtQuick.Controls.Styles 1.2 +import QtQuick.Layouts 1.2 +import QtGraphicalEffects 1.0 + +import QGroundControl 1.0 +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: _cameraView + viewPanel: panel + anchors.fill: parent + + FactPanelController { id: controller; factPanel: panel } + + QGCPalette { id: palette; colorGroupEnabled: enabled } + + property real _margins: ScreenTools.defaultFontPixelHeight + property real _middleRowWidth: ScreenTools.defaultFontPixelWidth * 22 + property real _editFieldWidth: ScreenTools.defaultFontPixelWidth * 18 + + property Fact _camTriggerMode: controller.getParameterFact(-1, "TRIG_MODE") + + property bool _hasFacts: false + property bool _rebooting: false + property var _auxChannels: [ 0, 0, 0, 0, 0, 0] + + function clearAuxArray() { + for(var i = 0; i < 6; i++) { + _auxChannels[i] = 0 + } + } + + function setAuxPins() { + var values = [] + for(var i = 0; i < 6; i++) { + if(_auxChannels[i]) { + values.push((i+1).toString()) + } + } + var auxFact = controller.getParameterFact(-1, "TRIG_PINS") + auxFact.value = parseInt(values) + console.log(values) + } + + Component.onCompleted: { + _hasFacts = _camTriggerMode.value > 0 + if(_hasFacts) { + clearAuxArray() + var auxFact = controller.getParameterFact(-1, "TRIG_PINS") + var values = auxFact.value.toString() + console.log(values) + for(var i = 0; i < values.length; i++) { + var b = parseInt(values[i]) - 1 + if(b >= 0 && b < 6) { + console.log(b) + _auxChannels[b] = 1 + } + } + } + } + + QGCViewPanel { + id: panel + anchors.fill: parent + Item { + id: applyAndRestart + visible: false + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 10 + anchors.rightMargin: ScreenTools.defaultFontPixelWidth * 10 + height: applyButton.height + QGCLabel { + anchors.left: parent.left + text: qsTr("Vehicle must be restarted for changes to take effect. ") + } + QGCButton { + id: applyButton + anchors.right: parent.right + text: qsTr("Apply and Restart") + onClicked: { + QGroundControl.multiVehicleManager.activeVehicle.rebootVehicle() + applyAndRestart.visible = false + _rebooting = true + } + } + } + QGCFlickable { + clip: true + anchors.top: applyAndRestart.visible ? applyAndRestart.bottom : parent.top + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + width: mainCol.width + contentHeight: mainCol.height + contentWidth: mainCol.width + flickableDirection: Flickable.VerticalFlick + Column { + id: mainCol + spacing: _margins + /* + **** Camera Trigger **** + */ + QGCLabel { + text: qsTr("Camera Trigger Settings") + font.weight: Font.DemiBold + } + Rectangle { + id: camTrigRect + color: palette.windowShade + width: camTrigRow.width + _margins * 2 + height: camTrigRow.height + _margins * 2 + Row { + id: camTrigRow + spacing: _margins + anchors.verticalCenter: parent.verticalCenter + Item { width: _margins * 0.5; height: 1; } + QGCColoredImage { + color: palette.text + height: ScreenTools.defaultFontPixelWidth * 10 + width: ScreenTools.defaultFontPixelWidth * 20 + mipmap: true + fillMode: Image.PreserveAspectFit + source: "/qmlimages/CameraTrigger.svg" + anchors.verticalCenter: parent.verticalCenter + } + Item { width: _margins * 0.5; height: 1; } + Column { + spacing: _margins * 0.5 + anchors.verticalCenter: parent.verticalCenter + Row { + visible: !controller.fixedWing + QGCLabel { + anchors.baseline: camTrigCombo.baseline + width: _middleRowWidth + text: qsTr("Trigger mode:") + } + FactComboBox { + id: camTrigCombo + width: _editFieldWidth + fact: _camTriggerMode + indexModel: false + enabled: !_rebooting + onActivated: { + applyAndRestart.visible = true + } + } + } + Row { + QGCLabel { + text: qsTr("Time Interval") + width: _middleRowWidth + anchors.baseline: timeIntervalField.baseline + color: palette.text + } + FactTextField { + id: timeIntervalField + fact: _hasFacts ? controller.getParameterFact(-1, "TRIG_INTERVAL") : null + showUnits: true + width: _editFieldWidth + enabled: _hasFacts && _camTriggerMode.value === 2 + } + } + Row { + QGCLabel { + text: qsTr("Distance Interval") + width: _middleRowWidth + anchors.baseline: trigDistField.baseline + color: palette.text + } + FactTextField { + id: trigDistField + fact: _hasFacts ? controller.getParameterFact(-1, "TRIG_DISTANCE") : null + showUnits: true + width: _editFieldWidth + enabled: _hasFacts && _camTriggerMode.value === 3 + } + } + } + } + } + /* + **** Camera Hardware **** + */ + Item { width: 1; height: _margins * 0.5; } + QGCLabel { + text: qsTr("Hardware Settings") + font.weight: Font.DemiBold + visible: _hasFacts + } + Rectangle { + color: palette.windowShade + width: camTrigRect.width + height: camHardwareRow.height + _margins * 2 + visible: _hasFacts + Row { + id: camHardwareRow + spacing: _margins + anchors.verticalCenter: parent.verticalCenter + + property Fact _camTriggerPol: controller.getParameterFact(-1, "TRIG_POLARITY") + + Item { width: _margins * 0.5; height: 1; } + Item { + height: ScreenTools.defaultFontPixelWidth * 10 + width: ScreenTools.defaultFontPixelWidth * 20 + Column { + spacing: ScreenTools.defaultFontPixelHeight + anchors.centerIn: parent + QGCLabel { + text: "AUX Pin Assignment" + anchors.horizontalCenter: parent.horizontalCenter + } + Row { + spacing: ScreenTools.defaultFontPixelWidth + anchors.horizontalCenter: parent.horizontalCenter + Repeater { + model: _auxChannels + Column { + spacing: ScreenTools.defaultFontPixelWidth * 0.5 + QGCLabel { + text: model.index + 1 + color: palette.text + anchors.horizontalCenter: parent.horizontalCenter + } + Rectangle { + id: auxPin + width: ScreenTools.defaultFontPixelWidth * 2 + height: ScreenTools.defaultFontPixelWidth * 2 + border.color: palette.text + color: _auxChannels[model.index] ? "green" : palette.windowShadeDark + MouseArea { + anchors.fill: parent + onClicked: { + _auxChannels[model.index] = 1 - _auxChannels[model.index] + auxPin.color = _auxChannels[model.index] ? "green" : palette.windowShadeDark + console.log(model.index + " " + _auxChannels[model.index]) + setAuxPins() + } + } + } + } + } + } + } + } + Item { width: _margins * 0.5; height: 1; } + Column { + spacing: _margins * 0.5 + anchors.verticalCenter: parent.verticalCenter + QGCLabel { + id: returnHomeLabel + text: "Trigger Pin Polarity:" + } + Row { + Item { height: 1; width: _margins; } + Column { + spacing: _margins * 0.5 + ExclusiveGroup { id: polarityGroup } + QGCRadioButton { + checked: _hasFacts && camHardwareRow._camTriggerPol.value === 0 + exclusiveGroup: polarityGroup + text: "Low (0V)" + onClicked: _camTriggerPol.value = 0 + } + QGCRadioButton { + checked: _hasFacts && camHardwareRow._camTriggerPol.value > 0 + exclusiveGroup: polarityGroup + text: "High (3.3V)" + onClicked: _camTriggerPol.value = 1 + } + } + } + Item { width: 1; height: _margins; } + Row { + QGCLabel { + text: qsTr("Trigger Period") + width: _middleRowWidth + anchors.baseline: trigPeriodField.baseline + color: palette.text + } + FactTextField { + id: trigPeriodField + fact: controller.getParameterFact(-1, "TRIG_ACT_TIME") + showUnits: true + width: _editFieldWidth + } + } + } + } + } + } + } + } +} + diff --git a/src/AutoPilotPlugins/PX4/CameraComponentSummary.qml b/src/AutoPilotPlugins/PX4/CameraComponentSummary.qml new file mode 100644 index 0000000000000000000000000000000000000000..3d3765f1344959c840be8d1b1a6e05cb1968c811 --- /dev/null +++ b/src/AutoPilotPlugins/PX4/CameraComponentSummary.qml @@ -0,0 +1,29 @@ +import QtQuick 2.2 +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 _camTriggerMode: controller.getParameterFact(-1, "TRIG_MODE") + + Column { + anchors.fill: parent + anchors.margins: 8 + + VehicleSummaryRow { + labelText: qsTr("Camera Trigger Mode:") + valueText: _camTriggerMode ? _camTriggerMode.enumStringValue : "" + } + + } +} diff --git a/src/AutoPilotPlugins/PX4/Images/CameraTrigger.svg b/src/AutoPilotPlugins/PX4/Images/CameraTrigger.svg new file mode 100644 index 0000000000000000000000000000000000000000..f83aa8158943474d60075f5c9a0453dcdf34d13e --- /dev/null +++ b/src/AutoPilotPlugins/PX4/Images/CameraTrigger.svg @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc index f35d80eeed99d0fdd7f32b47d03938e603a0904a..ee5fad3d5952001f11e4012a3cb038d06ea9ac16 100644 --- a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc +++ b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc @@ -126,6 +126,10 @@ const QVariantList& PX4AutoPilotPlugin::vehicleComponents(void) _tuningComponent->setupTriggerSignals(); _components.append(QVariant::fromValue((VehicleComponent*)_tuningComponent)); + _cameraComponent = new CameraComponent(_vehicle, this); + _cameraComponent->setupTriggerSignals(); + _components.append(QVariant::fromValue((VehicleComponent*)_cameraComponent)); + //-- Is there an ESP8266 Connected? if(factExists(FactSystem::ParameterProvider, MAV_COMP_ID_UDP_BRIDGE, "SW_VER")) { _esp8266Component = new ESP8266Component(_vehicle, this); diff --git a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h index 134fd4761d91d6e13d27a7d8f8f76b0cf9412446..9b12f55e40dd325ae8cff84c24adec9deb4ed7ae 100644 --- a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h +++ b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h @@ -1,24 +1,24 @@ /*===================================================================== - + 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 PX4AUTOPILOT_H @@ -32,6 +32,7 @@ #include "FlightModesComponent.h" #include "SensorsComponent.h" #include "SafetyComponent.h" +#include "CameraComponent.h" #include "PowerComponent.h" #include "PX4TuningComponent.h" #include "Vehicle.h" @@ -60,13 +61,14 @@ public: FlightModesComponent* flightModesComponent(void) { return _flightModesComponent; } SensorsComponent* sensorsComponent(void) { return _sensorsComponent; } SafetyComponent* safetyComponent(void) { return _safetyComponent; } + CameraComponent* cameraComponent(void) { return _cameraComponent; } PowerComponent* powerComponent(void) { return _powerComponent; } PX4TuningComponent* tuningComponent(void) { return _tuningComponent; } public slots: // FIXME: This is public until we restructure AutoPilotPlugin/FirmwarePlugin/Vehicle void _parametersReadyPreChecks(bool missingParameters); - + private: PX4AirframeLoader* _airframeFacts; QVariantList _components; @@ -76,6 +78,7 @@ private: FlightModesComponent* _flightModesComponent; SensorsComponent* _sensorsComponent; SafetyComponent* _safetyComponent; + CameraComponent* _cameraComponent; PowerComponent* _powerComponent; PX4TuningComponent* _tuningComponent; bool _incorrectParameterVersion; ///< true: parameter version incorrect, setup not allowed diff --git a/src/Vehicle/Vehicle.cc b/src/Vehicle/Vehicle.cc index bf0910082b2e0c61e9e8d22b427fbbe547c33a0b..e9962e193cdf825a90968c82ca718375ba9a5936 100644 --- a/src/Vehicle/Vehicle.cc +++ b/src/Vehicle/Vehicle.cc @@ -1636,6 +1636,11 @@ void Vehicle::setFirmwareVersion(int majorVersion, int minorVersion, int patchVe _firmwarePatchVersion = patchVersion; } +void Vehicle::rebootVehicle() +{ + doCommandLong(id(), MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); +} + const char* VehicleGPSFactGroup::_hdopFactName = "hdop"; const char* VehicleGPSFactGroup::_vdopFactName = "vdop"; const char* VehicleGPSFactGroup::_courseOverGroundFactName = "courseOverGround"; diff --git a/src/Vehicle/Vehicle.h b/src/Vehicle/Vehicle.h index afcb078e0cd5af71507e8e10b5a0c0ff1a09a6d9..2f82e24985f6a266e3900322b80fb59c5c3c62b4 100644 --- a/src/Vehicle/Vehicle.h +++ b/src/Vehicle/Vehicle.h @@ -360,6 +360,9 @@ public: /// Alter the current mission item on the vehicle Q_INVOKABLE void setCurrentMissionSequence(int seq); + /// Reboot vehicle + Q_INVOKABLE void rebootVehicle(); + bool guidedModeSupported(void) const; bool pauseVehicleSupported(void) const;