Commit d33852c5 authored by dogmaphobic's avatar dogmaphobic

PX4FLOW Sensor Support.

parent a4742fdc
......@@ -271,7 +271,7 @@ HEADERS += \
src/ui/uas/UASMessageView.h \
src/MissionItem.h \
src/AutoPilotPlugins/PX4/PX4AirframeLoader.h \
src/QGCSettings.h
src/QmlControls/QGCImageProvider.h \
WindowsBuild {
PRECOMPILED_HEADER += src/stable_headers.h
......@@ -383,7 +383,7 @@ SOURCES += \
src/ui/uas/UASMessageView.cc \
src/MissionItem.cc \
src/AutoPilotPlugins/PX4/PX4AirframeLoader.cc \
src/QGCSettings.cpp
src/QmlControls/QGCImageProvider.cc \
!iOSBuild {
SOURCES += \
......
This diff is collapsed.
......@@ -69,6 +69,12 @@ QQuickItem* QGCQmlWidgetHolder::getRootObject(void)
return _ui.qmlWidget->rootObject();
}
QQmlEngine* QGCQmlWidgetHolder::getEngine()
{
return _ui.qmlWidget->engine();
}
void QGCQmlWidgetHolder::setResizeMode(QQuickWidget::ResizeMode resizeMode)
{
_ui.qmlWidget->setResizeMode(resizeMode);
......
......@@ -59,6 +59,9 @@ public:
/// Get Root Object
QQuickItem* getRootObject(void);
/// Get QML Engine
QQmlEngine* getEngine();
/// Sets the QML into the control. Will display errors message box if error occurs loading source.
/// @return true: source loaded, false: source not loaded, errors occured
bool setSource(const QUrl& qmlUrl);
......
......@@ -32,6 +32,7 @@
#include "AutoPilotPluginManager.h"
#include "UASMessageHandler.h"
#include "FactSystem.h"
#include "QGCImageProvider.h"
QGCToolbox::QGCToolbox(QGCApplication* app)
: _firmwarePluginManager(NULL)
......@@ -45,6 +46,7 @@ QGCToolbox::QGCToolbox(QGCApplication* app)
, _audioOutput(NULL)
, _uasMessageHandler(NULL)
, _factSystem(NULL)
, _imageProvider(NULL)
{
_firmwarePluginManager = new FirmwarePluginManager(app);
_autopilotPluginManager = new AutoPilotPluginManager(app);
......@@ -57,6 +59,7 @@ QGCToolbox::QGCToolbox(QGCApplication* app)
_joystickManager = new JoystickManager(app);
_audioOutput = new GAudioOutput(app);
_uasMessageHandler = new UASMessageHandler(app);
_imageProvider = new QGCImageProvider(app);
_firmwarePluginManager->setToolbox(this);
_autopilotPluginManager->setToolbox(this);
......@@ -69,6 +72,7 @@ QGCToolbox::QGCToolbox(QGCApplication* app)
_joystickManager->setToolbox(this);
_audioOutput->setToolbox(this);
_uasMessageHandler->setToolbox(this);
_imageProvider->setToolbox(this);
}
QGCToolbox::~QGCToolbox()
......
......@@ -38,6 +38,7 @@ class GAudioOutput;
class FirmwarePluginManager;
class AutoPilotPluginManager;
class FactSystem;
class QGCImageProvider;
/// This is used to manage all of our top level services/tools
class QGCToolbox {
......@@ -56,6 +57,7 @@ public:
GAudioOutput* audioOutput(void) { return _audioOutput; }
FirmwarePluginManager* firmwarePluginManager(void) { return _firmwarePluginManager; }
AutoPilotPluginManager* autopilotPluginManager(void) { return _autopilotPluginManager; }
QGCImageProvider* imageProvider() { return _imageProvider; }
private:
FirmwarePluginManager* _firmwarePluginManager;
......@@ -69,6 +71,7 @@ private:
GAudioOutput* _audioOutput;
UASMessageHandler* _uasMessageHandler;
FactSystem* _factSystem;
QGCImageProvider* _imageProvider;
};
/// This is the base class for all tools
......
......@@ -23,17 +23,75 @@ along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
/**
* @file
* @brief Implementation of class QGCSettings
* @brief Image Provider
*
* @author Gus Grubba <mavlink@grubba.com>
*
*/
#include "QGCSettings.h"
#include "QGCImageProvider.h"
QGCSettings::QGCSettings(QObject *parent) : QObject(parent)
#include <QPainter>
#include <qFont>
QGCImageProvider::QGCImageProvider(QGCApplication *app)
: QGCTool(app)
, QQuickImageProvider(QQmlImageProviderBase::Image)
{
}
QGCImageProvider::~QGCImageProvider()
{
}
void QGCImageProvider::setToolbox(QGCToolbox *toolbox)
{
QGCTool::setToolbox(toolbox);
//-- Dummy temporary image until something comes along
_pImage = QImage(320, 240, QImage::Format_RGBA8888);
_pImage.fill(Qt::black);
QPainter painter(&_pImage);
QFont f = painter.font();
f.setPixelSize(20);
painter.setFont(f);
painter.setPen(Qt::white);
painter.drawText(QRectF(0, 0, 320, 240), Qt::AlignCenter, "Waiting...");
}
QImage QGCImageProvider::requestImage(const QString & /* image url with vehicle id*/, QSize *, const QSize &)
{
/*
The QML side will request an image using a special URL, which we've registered as QGCImages.
The URL follows this format (or anything you want to make out of it after the "QGCImages" part):
"image://QGCImages/vvv/iii"
Where:
vvv: Some vehicle id
iii: An auto incremented index (which forces the Item to reload the image)
The image index is incremented each time a new image arrives. A signal is emitted and the QML side
updates its contents automatically.
Image {
source: "image://QGCImages/" + _activeVehicle.id + "/" + _activeVehicle.flowImageIndex
width: parent.width * 0.5
height: width * 0.75
cache: false
anchors.centerIn: parent
fillMode: Image.PreserveAspectFit
}
For now, we don't even look at the URL. This will have to be fixed if we're to support multiple
vehicles transmitting flow images.
*/
return _pImage;
}
void QGCImageProvider::setImage(QImage* pImage, int /* vehicle id*/)
{
_pImage = pImage->mirrored();
}
......@@ -23,28 +23,37 @@
/**
* @file
* @brief Definition of main class
* @brief Image Provider
*
* @author Gus Grubba <mavlink@grubba.com>
* @author Gus Grubba <mavlink@grubba.com>
*
*/
#ifndef QGCSETTINGS_H
#define QGCSETTINGS_H
#ifndef QGCIMAGEPROVIDER_H
#define QGCIMAGEPROVIDER_H
#include <QObject>
#include <QQmlListProperty>
#include <QQuickImageProvider>
class QGCSettings : public QObject
#include "QGCToolbox.h"
class QGCImageProvider : public QGCTool, public QQuickImageProvider
{
Q_OBJECT
public:
explicit QGCSettings(QObject *parent = 0);
signals:
public slots:
QGCImageProvider (QGCApplication* app);
~QGCImageProvider ();
QImage requestImage (const QString & id, QSize * size, const QSize & requestedSize);
void setImage (QImage* pImage, int id = 0);
void setToolbox (QGCToolbox *toolbox);
private:
//-- TODO: For now this is holding a single image. If you happen to have two
// or more vehicles with flow, it will not work. To properly manage that condition
// this should be a map between each vehicle and its image. The URL provided
// for the image request would contain the vehicle identification.
QImage _pImage;
};
#endif // QGCSETTINGS_H
#endif // QGCIMAGEPROVIDER_H
......@@ -39,6 +39,7 @@ Button {
verticalAlignment: TextEdit.AlignVCenter
horizontalAlignment: TextEdit.AlignHCenter
color: showHighlight ? qgcPal.buttonHighlightText : qgcPal.buttonText
font.pixelSize: ScreenTools.isMobile ? ScreenTools.defaultFontPixelSize * 0.65 : ScreenTools.defaultFontPixelSize
text: control.text
Rectangle {
......
......@@ -56,6 +56,7 @@ void MultiVehicleManager::setToolbox(QGCToolbox *toolbox)
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
qmlRegisterUncreatableType<MultiVehicleManager>("QGroundControl.MultiVehicleManager", 1, 0, "MultiVehicleManager", "Reference only");
}
bool MultiVehicleManager::notifyHeartbeatInfo(LinkInterface* link, int vehicleId, mavlink_heartbeat_t& heartbeat)
......@@ -256,3 +257,5 @@ QList<Vehicle*> MultiVehicleManager::vehicles(void)
return list;
}
......@@ -119,6 +119,7 @@ private:
AutoPilotPluginManager* _autopilotPluginManager;
JoystickManager* _joystickManager;
MAVLinkProtocol* _mavlinkProtocol;
};
#endif
......@@ -34,6 +34,7 @@
#include "CoordinateVector.h"
#include "ParameterLoader.h"
#include "QGCApplication.h"
#include "QGCImageProvider.h"
QGC_LOGGING_CATEGORY(VehicleLog, "VehicleLog")
......@@ -104,6 +105,7 @@ Vehicle::Vehicle(LinkInterface* link,
, _firmwarePluginManager(firmwarePluginManager)
, _autopilotPluginManager(autopilotPluginManager)
, _joystickManager(joystickManager)
, _flowImageIndex(0)
{
_addLink(link);
......@@ -119,6 +121,7 @@ Vehicle::Vehicle(LinkInterface* link,
connect(_uas, &UAS::latitudeChanged, this, &Vehicle::setLatitude);
connect(_uas, &UAS::longitudeChanged, this, &Vehicle::setLongitude);
connect(_uas, &UAS::imageReady, this, &Vehicle::_imageReady);
_firmwarePlugin = _firmwarePluginManager->firmwarePluginForAutopilot(_firmwareType, _vehicleType);
_autopilotPlugin = _autopilotPluginManager->newAutopilotPluginForVehicle(this);
......@@ -191,6 +194,7 @@ Vehicle::~Vehicle()
delete _mav;
_mav = NULL;
}
void Vehicle::_mavlinkMessageReceived(LinkInterface* link, mavlink_message_t message)
......@@ -1043,3 +1047,14 @@ ParameterLoader* Vehicle::getParameterLoader(void)
{
return _parameterLoader;
}
void Vehicle::_imageReady(UASInterface*)
{
if(_uas)
{
QImage img = _uas->getImage();
qgcApp()->toolbox()->imageProvider()->setImage(&img, _id);
_flowImageIndex++;
emit flowImageIndexChanged();
}
}
......@@ -29,7 +29,6 @@
#include <QObject>
#include <QGeoCoordinate>
#include <QQmlListProperty>
#include "LinkInterface.h"
#include "QGCMAVLink.h"
......@@ -107,6 +106,7 @@ public:
Q_PROPERTY(QStringList joystickModes READ joystickModes CONSTANT)
Q_PROPERTY(bool joystickEnabled READ joystickEnabled WRITE setJoystickEnabled NOTIFY joystickEnabledChanged)
Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
Q_PROPERTY(int flowImageIndex READ flowImageIndex NOTIFY flowImageIndexChanged)
/// Returns the number of buttons which are reserved for firmware use in the MANUAL_CONTROL mavlink
/// message. For example PX4 Flight Stack reserves the first 8 buttons to simulate rc switches.
......@@ -188,6 +188,8 @@ public:
QmlObjectListModel* trajectoryPoints(void) { return &_mapTrajectoryList; }
int flowImageIndex() { return _flowImageIndex; }
/// Requests the specified data stream from the vehicle
/// @param stream Stream which is being requested
/// @param rate Rate at which to send stream in Hz
......@@ -290,6 +292,7 @@ signals:
void satelliteCountChanged ();
void currentStateChanged ();
void satelliteLockChanged ();
void flowImageIndexChanged ();
private slots:
void _mavlinkMessageReceived(LinkInterface* link, mavlink_message_t message);
......@@ -316,6 +319,8 @@ private slots:
void _heartbeatTimeout (bool timeout, unsigned int ms);
void _setSatelliteCount (double val, QString name);
void _setSatLoc (UASInterface* uas, int fix);
/** @brief A new camera image has arrived */
void _imageReady (UASInterface* uas);
private:
bool _containsLink(LinkInterface* link);
......@@ -427,6 +432,8 @@ private:
AutoPilotPluginManager* _autopilotPluginManager;
JoystickManager* _joystickManager;
int _flowImageIndex;
// Settings keys
static const char* _settingsGroup;
static const char* _joystickModeSettingsKey;
......
/*=====================================================================
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.3
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QtQuick.Dialogs 1.2
import QGroundControl.Controls 1.0
import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Palette 1.0
import QGroundControl.Controllers 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.MultiVehicleManager 1.0
QGCView {
id: qgcView
viewPanel: panel
property var _activeVehicle: multiVehicleManager.activeVehicle
QGCPalette { id: qgcPal; colorGroupEnabled: panel.enabled }
QGCViewPanel {
id: panel
anchors.fill: parent
QGCLabel {
id: titleLabel
text: "PX4Flow Camera"
font.pixelSize: ScreenTools.mediumFontPixelSize
}
Image {
source: _activeVehicle ? "image://QGCImages/" + _activeVehicle.id + "/" + _activeVehicle.flowImageIndex : ""
width: parent.width * 0.5
height: width * 0.75
cache: false
anchors.centerIn: parent
fillMode: Image.PreserveAspectFit
}
}
}
......@@ -94,6 +94,11 @@ Rectangle {
panelLoader.source = "SetupParameterEditor.qml";
}
function showPX4FlowPanel()
{
panelLoader.source = "PX4FlowSensor.qml";
}
function showVehicleComponentPanel(vehicleComponent)
{
if (multiVehicleManager.activeVehicle.armed) {
......@@ -247,6 +252,16 @@ Rectangle {
onClicked: showFirmwarePanel()
}
SubMenuButton {
id: px4FlowButton
width: mainWindow.menuButtonWidth
exclusiveGroup: setupButtonGroup
visible: _fullParameterVehicleAvailable
setupIndicator: false
text: "PX4FLOW"
onClicked: showPX4FlowPanel()
}
SubMenuButton {
id: joystickButton
width: mainWindow.menuButtonWidth
......
......@@ -70,7 +70,7 @@ union px4_custom_mode {
float MockLink::_vehicleLatitude = 47.633033f;
float MockLink::_vehicleLongitude = -122.08794f;
float MockLink::_vehicleAltitude = 2.5f;
float MockLink::_vehicleAltitude = 9872.5f;
const char* MockConfiguration::_firmwareTypeKey = "FirmwareType";
const char* MockConfiguration::_vehicleTypeKey = "VehicleType";
......
......@@ -53,6 +53,7 @@ This file is part of the QGROUNDCONTROL project
#include "HomePositionManager.h"
#include "LogCompressor.h"
#include "UAS.h"
#include "QGCImageProvider.h"
#ifndef __mobile__
#include "QGCDataPlot2D.h"
......@@ -166,6 +167,10 @@ MainWindow::MainWindow()
_mainQmlWidgetHolder->setContextPropertyObject("controller", this);
_mainQmlWidgetHolder->setSource(QUrl::fromUserInput("qrc:qml/MainWindow.qml"));
// Image provider
QQuickImageProvider* pImgProvider = dynamic_cast<QQuickImageProvider*>(qgcApp()->toolbox()->imageProvider());
_mainQmlWidgetHolder->getEngine()->addImageProvider(QLatin1String("QGCImages"), pImgProvider);
// Set dock options
setDockOptions(0);
// Setup corners
......@@ -309,6 +314,7 @@ MainWindow::MainWindow()
MainWindow::~MainWindow()
{
_mainQmlWidgetHolder->getEngine()->removeImageProvider(QLatin1String("QGCImages"));
_instance = NULL;
}
......@@ -465,6 +471,8 @@ void MainWindow::closeEvent(QCloseEvent *event)
// We have to pull out the QmlWidget from the main window and delete it here, before
// the MainWindow ends up getting deleted. Otherwise the Qml has a reference to MainWindow
// inside it which in turn causes a shutdown crash.
// Remove image provider
_mainQmlWidgetHolder->getEngine()->removeImageProvider(QLatin1String("QGCImages"));
_centralLayout->removeWidget(_mainQmlWidgetHolder);
delete _mainQmlWidgetHolder;
_mainQmlWidgetHolder = NULL;
......@@ -474,7 +482,10 @@ void MainWindow::closeEvent(QCloseEvent *event)
event->accept();
//-- TODO: This effectively causes the QGCApplication destructor to not being able
// to access the pointer it is trying to delete.
_instance = NULL;
emit mainWindowClosed();
}
......
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